aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorreparo_liu <reparo_liu@realsil.com.cn>2023-05-18 11:23:40 +0800
committerreparo_liu <reparo_liu@realsil.com.cn>2023-05-19 09:18:25 +0800
commit64889cda2e397915ee6c3800d4acafb1c34e2ef3 (patch)
treef9d61cfc074d3297dff0d97ff1443617bc330bd2
parent151cf392d25c5de46a4cdaaa78dfc46448a1f8c3 (diff)
downloadrealtek-master.tar.gz
Google RTK SDKHEADmastermain
upload project and readme file BYPASS_INCLUSIVE_LANGUAGE_REASON=false positive bug: Change-Id: Ibc24ce136cb2c838214643d90017530996589b37 test: manual
-rw-r--r--board/evb/google_rcu/board.h358
-rw-r--r--board/evb/google_rcu/flash map.ini68
-rw-r--r--board/evb/google_rcu/flash_map.h132
-rw-r--r--board/evb/google_rcu/gcc/Makefile293
-rw-r--r--board/evb/google_rcu/gcc/app.ld105
-rw-r--r--board/evb/google_rcu/gcc/mem_define.ld6
-rw-r--r--board/evb/google_rcu/mdk/Listings/app.map4851
-rw-r--r--board/evb/google_rcu/mdk/Listings/startup_rtl876x.lst1642
-rw-r--r--board/evb/google_rcu/mdk/after_build_special.bat2
-rw-r--r--board/evb/google_rcu/mdk/app.sct126
-rw-r--r--board/evb/google_rcu/mdk/before_build_special.bat2
-rw-r--r--board/evb/google_rcu/mdk/google_rcu.uvguix.reparo_liu3664
-rw-r--r--board/evb/google_rcu/mdk/google_rcu.uvoptx1272
-rw-r--r--board/evb/google_rcu/mdk/google_rcu.uvprojx925
-rw-r--r--board/evb/google_rcu/mem_config.h81
-rw-r--r--board/evb/google_rcu/mp.ini51
-rw-r--r--board/evb/google_rcu/otp_config.h135
-rw-r--r--board/evb/google_rcu/platform_autoconf.h46
-rw-r--r--board/evb/google_rcu/version.h21
-rw-r--r--inc/app/app_msg.h226
-rw-r--r--inc/app/dfu_api.h179
-rw-r--r--inc/app/readme0
-rw-r--r--inc/bluetooth/gap/bt_types.h752
-rw-r--r--inc/bluetooth/gap/gap.h644
-rw-r--r--inc/bluetooth/gap/gap_adv.h482
-rw-r--r--inc/bluetooth/gap/gap_aox.h375
-rw-r--r--inc/bluetooth/gap/gap_aox_conn.h374
-rw-r--r--inc/bluetooth/gap/gap_aox_connless_receiver.h108
-rw-r--r--inc/bluetooth/gap/gap_aox_connless_transmitter.h143
-rw-r--r--inc/bluetooth/gap/gap_bond_le.h852
-rw-r--r--inc/bluetooth/gap/gap_callback_le.h901
-rw-r--r--inc/bluetooth/gap/gap_conn_le.h1000
-rw-r--r--inc/bluetooth/gap/gap_credit_based_conn.h155
-rw-r--r--inc/bluetooth/gap/gap_dtm.h560
-rw-r--r--inc/bluetooth/gap/gap_ext_adv.h857
-rw-r--r--inc/bluetooth/gap/gap_ext_scan.h447
-rw-r--r--inc/bluetooth/gap/gap_fix_chann_conn.h28
-rw-r--r--inc/bluetooth/gap/gap_le.h527
-rw-r--r--inc/bluetooth/gap/gap_le_rf.h656
-rw-r--r--inc/bluetooth/gap/gap_le_types.h486
-rw-r--r--inc/bluetooth/gap/gap_lib/gap_config.h280
-rw-r--r--inc/bluetooth/gap/gap_lib/gap_vendor.h499
-rw-r--r--inc/bluetooth/gap/gap_lib/readme0
-rw-r--r--inc/bluetooth/gap/gap_msg.h271
-rw-r--r--inc/bluetooth/gap/gap_pa_adv.h157
-rw-r--r--inc/bluetooth/gap/gap_pa_sync.h181
-rw-r--r--inc/bluetooth/gap/gap_past_recipient.h101
-rw-r--r--inc/bluetooth/gap/gap_past_sender.h105
-rw-r--r--inc/bluetooth/gap/gap_ping_le.h193
-rw-r--r--inc/bluetooth/gap/gap_privacy.h271
-rw-r--r--inc/bluetooth/gap/gap_scan.h307
-rw-r--r--inc/bluetooth/gap/gap_storage_le.h708
-rw-r--r--inc/bluetooth/leaudio/bap.h127
-rw-r--r--inc/bluetooth/leaudio/base_data_parse.h53
-rw-r--r--inc/bluetooth/leaudio/bass_client.h80
-rw-r--r--inc/bluetooth/leaudio/bass_def.h154
-rw-r--r--inc/bluetooth/leaudio/ble_audio.h85
-rw-r--r--inc/bluetooth/leaudio/ble_audio_def.h80
-rw-r--r--inc/bluetooth/leaudio/ble_audio_flags.h56
-rw-r--r--inc/bluetooth/leaudio/ble_audio_group.h89
-rw-r--r--inc/bluetooth/leaudio/ble_audio_sync.h126
-rw-r--r--inc/bluetooth/leaudio/bt_bond_mgr.h51
-rw-r--r--inc/bluetooth/leaudio/bt_gatt_client.h192
-rw-r--r--inc/bluetooth/leaudio/cap.h86
-rw-r--r--inc/bluetooth/leaudio/codec_def.h122
-rw-r--r--inc/bluetooth/leaudio/codec_qos.h101
-rw-r--r--inc/bluetooth/leaudio/csis_def.h49
-rw-r--r--inc/bluetooth/leaudio/csis_rsi.h24
-rw-r--r--inc/bluetooth/leaudio/metadata_def.h54
-rw-r--r--inc/bluetooth/leaudio/pacs_client.h102
-rw-r--r--inc/bluetooth/leaudio/set_coordinator_client.h132
-rw-r--r--inc/bluetooth/profile/client/ams_client.h419
-rw-r--r--inc/bluetooth/profile/client/ancs_client.h300
-rw-r--r--inc/bluetooth/profile/client/bas_client.h337
-rw-r--r--inc/bluetooth/profile/client/dfu_client.h319
-rw-r--r--inc/bluetooth/profile/client/dis_client.h304
-rw-r--r--inc/bluetooth/profile/client/gaps_client.h276
-rw-r--r--inc/bluetooth/profile/client/gatts_client.h276
-rw-r--r--inc/bluetooth/profile/client/gcs_client.h626
-rw-r--r--inc/bluetooth/profile/client/hids_client.h355
-rw-r--r--inc/bluetooth/profile/client/ias_client.h284
-rw-r--r--inc/bluetooth/profile/client/ipss_client.h74
-rw-r--r--inc/bluetooth/profile/client/kns_client.h289
-rw-r--r--inc/bluetooth/profile/client/lls_client.h279
-rw-r--r--inc/bluetooth/profile/client/ota_client.h254
-rw-r--r--inc/bluetooth/profile/client/simple_ble_client.h292
-rw-r--r--inc/bluetooth/profile/client/tps_client.h273
-rw-r--r--inc/bluetooth/profile/gatt.h275
-rw-r--r--inc/bluetooth/profile/gatt_builtin_services.h276
-rw-r--r--inc/bluetooth/profile/profile_client.h611
-rw-r--r--inc/bluetooth/profile/profile_server.h452
-rw-r--r--inc/bluetooth/profile/server/atvv_service.h227
-rw-r--r--inc/bluetooth/profile/server/bas.h230
-rw-r--r--inc/bluetooth/profile/server/bas_config.h39
-rw-r--r--inc/bluetooth/profile/server/cscs.h433
-rw-r--r--inc/bluetooth/profile/server/cscs_config.h40
-rw-r--r--inc/bluetooth/profile/server/dfu_service.h117
-rw-r--r--inc/bluetooth/profile/server/dis.h228
-rw-r--r--inc/bluetooth/profile/server/dis_config.h155
-rw-r--r--inc/bluetooth/profile/server/gls.h638
-rw-r--r--inc/bluetooth/profile/server/gls_config.h102
-rw-r--r--inc/bluetooth/profile/server/hids.h283
-rw-r--r--inc/bluetooth/profile/server/hids_kb.h281
-rw-r--r--inc/bluetooth/profile/server/hids_ms.h280
-rw-r--r--inc/bluetooth/profile/server/hids_mulkb.h284
-rw-r--r--inc/bluetooth/profile/server/hids_rmc.h252
-rw-r--r--inc/bluetooth/profile/server/hrs.h296
-rw-r--r--inc/bluetooth/profile/server/hts.h349
-rw-r--r--inc/bluetooth/profile/server/ias.h102
-rw-r--r--inc/bluetooth/profile/server/ipss.h77
-rw-r--r--inc/bluetooth/profile/server/lls.h159
-rw-r--r--inc/bluetooth/profile/server/lns.h484
-rw-r--r--inc/bluetooth/profile/server/ota_service.h142
-rw-r--r--inc/bluetooth/profile/server/plxs.h401
-rw-r--r--inc/bluetooth/profile/server/plxs_config.h128
-rw-r--r--inc/bluetooth/profile/server/rcu_dfu_service.h256
-rw-r--r--inc/bluetooth/profile/server/rcu_ota_service.h153
-rw-r--r--inc/bluetooth/profile/server/rscs.h446
-rw-r--r--inc/bluetooth/profile/server/simple_ble_config.h63
-rw-r--r--inc/bluetooth/profile/server/simple_ble_service.h205
-rw-r--r--inc/bluetooth/profile/server/sps.h219
-rw-r--r--inc/bluetooth/profile/server/sps_config.h35
-rw-r--r--inc/bluetooth/profile/server/tps.h158
-rw-r--r--inc/bluetooth/profile/server/vendor_service.h80
-rw-r--r--inc/bluetooth/profile/server/voice_service.h155
-rw-r--r--inc/bluetooth/profile/server/wss.h303
-rw-r--r--inc/os/os_mem.h281
-rw-r--r--inc/os/os_msg.h432
-rw-r--r--inc/os/os_pool.h362
-rw-r--r--inc/os/os_queue.h311
-rw-r--r--inc/os/os_sched.h314
-rw-r--r--inc/os/os_sync.h475
-rw-r--r--inc/os/os_task.h566
-rw-r--r--inc/os/os_timer.h517
-rw-r--r--inc/os/readme0
-rw-r--r--inc/os/system_trace/system_trace.h41
-rw-r--r--inc/os/system_trace/trace_common.h55
-rw-r--r--inc/os/system_trace/trace_config.h41
-rw-r--r--inc/os/system_trace/trace_cpu_loading.h27
-rw-r--r--inc/os/system_trace/trace_dlps.h32
-rw-r--r--inc/os/system_trace/trace_hardfault.h123
-rw-r--r--inc/os/system_trace/trace_heap.h44
-rw-r--r--inc/os/system_trace/trace_port_config.h66
-rw-r--r--inc/os/system_trace/trace_queue.h38
-rw-r--r--inc/os/system_trace/trace_stack.h44
-rw-r--r--inc/os/system_trace/trace_task_hang.h29
-rw-r--r--inc/os/system_trace/trace_task_schedule.h27
-rw-r--r--inc/os/system_trace/trace_timer.h36
-rw-r--r--inc/os/system_trace/trace_wdg_timeout.h47
-rw-r--r--inc/peripheral/readme0
-rw-r--r--inc/peripheral/rtl876x_3wire_spi.h566
-rw-r--r--inc/peripheral/rtl876x_adc.h926
-rw-r--r--inc/peripheral/rtl876x_alias.h145
-rw-r--r--inc/peripheral/rtl876x_aon_wdg.h131
-rw-r--r--inc/peripheral/rtl876x_bitfields.h523
-rw-r--r--inc/peripheral/rtl876x_captouch.h895
-rw-r--r--inc/peripheral/rtl876x_codec.h713
-rw-r--r--inc/peripheral/rtl876x_enh_tim.h883
-rw-r--r--inc/peripheral/rtl876x_gdma.h970
-rw-r--r--inc/peripheral/rtl876x_gpio.h805
-rw-r--r--inc/peripheral/rtl876x_hw_aes.h181
-rw-r--r--inc/peripheral/rtl876x_i2c.h876
-rw-r--r--inc/peripheral/rtl876x_i2s.h1112
-rw-r--r--inc/peripheral/rtl876x_io_dlps.h109
-rw-r--r--inc/peripheral/rtl876x_ir.h1314
-rw-r--r--inc/peripheral/rtl876x_keyscan.h627
-rw-r--r--inc/peripheral/rtl876x_lpc.h749
-rw-r--r--inc/peripheral/rtl876x_nvic.h98
-rw-r--r--inc/peripheral/rtl876x_pinmux.h965
-rw-r--r--inc/peripheral/rtl876x_qdec.h597
-rw-r--r--inc/peripheral/rtl876x_rcc.h470
-rw-r--r--inc/peripheral/rtl876x_rtc.h1036
-rw-r--r--inc/peripheral/rtl876x_spi.h931
-rw-r--r--inc/peripheral/rtl876x_tim.h641
-rw-r--r--inc/peripheral/rtl876x_trng.h162
-rw-r--r--inc/peripheral/rtl876x_uart.h896
-rw-r--r--inc/peripheral/rtl876x_wdg.h152
-rw-r--r--inc/platform/adc_lib.h47
-rw-r--r--inc/platform/aes_api.h409
-rw-r--r--inc/platform/app_define.h84
-rw-r--r--inc/platform/app_section.h64
-rw-r--r--inc/platform/auto_k_rf.h107
-rw-r--r--inc/platform/auto_k_rf_bonding_dut.h38
-rw-r--r--inc/platform/auto_k_rf_bonding_golden.h57
-rw-r--r--inc/platform/bee2_adc_lib.h33
-rw-r--r--inc/platform/cmsis_armcc.h867
-rw-r--r--inc/platform/cmsis_gcc.h2097
-rw-r--r--inc/platform/core_cm0plus.h969
-rw-r--r--inc/platform/core_cmFunc.h87
-rw-r--r--inc/platform/core_cmInstr.h87
-rw-r--r--inc/platform/core_cmSimd.h96
-rw-r--r--inc/platform/cp.h259
-rw-r--r--inc/platform/crc16btx.h75
-rw-r--r--inc/platform/crc8ets.h48
-rw-r--r--inc/platform/dfu_flash.h199
-rw-r--r--inc/platform/dlps.h360
-rw-r--r--inc/platform/flash_adv_cfg.h154
-rw-r--r--inc/platform/flash_device.h430
-rw-r--r--inc/platform/ftl.h159
-rw-r--r--inc/platform/hw_aes.h139
-rw-r--r--inc/platform/log_uart_dma.h86
-rw-r--r--inc/platform/mem_types.h49
-rw-r--r--inc/platform/otp.h281
-rw-r--r--inc/platform/overlay_mgr.h95
-rw-r--r--inc/platform/patch_header_check.h330
-rw-r--r--inc/platform/pingpong_buffer.h85
-rw-r--r--inc/platform/platform_autoconf.h48
-rw-r--r--inc/platform/platform_utils.h110
-rw-r--r--inc/platform/psram_platform.h27
-rw-r--r--inc/platform/qspi_lcd_platform.h17
-rw-r--r--inc/platform/readme0
-rw-r--r--inc/platform/rom_uuid.h4
-rw-r--r--inc/platform/rtl876x.h3593
-rw-r--r--inc/platform/rtl876x_ic_type.h33
-rw-r--r--inc/platform/rtl876x_lib_platform.h247
-rw-r--r--inc/platform/sha256.h92
-rw-r--r--inc/platform/system_rtl876x.h238
-rw-r--r--inc/platform/test_mode.h162
-rw-r--r--inc/platform/trace.h2015
-rw-r--r--inc/platform/version.h21
-rw-r--r--inc/rcu/ima_adpcm_enc.h29
-rw-r--r--inc/rcu/opus_inc/config.h64
-rw-r--r--inc/rcu/opus_inc/opus.h994
-rw-r--r--inc/rcu/opus_inc/opus_custom.h345
-rw-r--r--inc/rcu/opus_inc/opus_defines.h753
-rw-r--r--inc/rcu/opus_inc/opus_multistream.h662
-rw-r--r--inc/rcu/opus_inc/opus_types.h159
-rw-r--r--inc/rcu/sbc.h67
-rw-r--r--license201
-rw-r--r--readme105
-rw-r--r--src/app/google_rcu/address_module/rcu_link_mgr.c171
-rw-r--r--src/app/google_rcu/address_module/rcu_link_mgr.h87
-rw-r--r--src/app/google_rcu/app_task.c204
-rw-r--r--src/app/google_rcu/app_task.h24
-rw-r--r--src/app/google_rcu/bat_module/battery_driver.c620
-rw-r--r--src/app/google_rcu/bat_module/battery_driver.h96
-rw-r--r--src/app/google_rcu/bibuffer.c94
-rw-r--r--src/app/google_rcu/bibuffer.h83
-rw-r--r--src/app/google_rcu/buzzer_module/buzzer_driver.c247
-rw-r--r--src/app/google_rcu/buzzer_module/buzzer_driver.h86
-rw-r--r--src/app/google_rcu/buzzer_module/fms_service_handle.c403
-rw-r--r--src/app/google_rcu/buzzer_module/fms_service_handle.h57
-rw-r--r--src/app/google_rcu/dtm_module/rcu_dtm_app.c473
-rw-r--r--src/app/google_rcu/dtm_module/rcu_gap_dtm.h563
-rw-r--r--src/app/google_rcu/frm_vpk/frm_define.h58
-rw-r--r--src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_hal_sflash.c109
-rw-r--r--src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_hal_sflash.h19
-rw-r--r--src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_log.c65
-rw-r--r--src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_log.h20
-rw-r--r--src/app/google_rcu/frm_vpk/src/app_custom.c596
-rw-r--r--src/app/google_rcu/frm_vpk/src/app_custom.h46
-rw-r--r--src/app/google_rcu/frm_vpk/src/app_flash_write.c277
-rw-r--r--src/app/google_rcu/frm_vpk/src/app_flash_write.h62
-rw-r--r--src/app/google_rcu/ir_module/ir_protocol_nec.c485
-rw-r--r--src/app/google_rcu/ir_module/ir_protocol_nec.h63
-rw-r--r--src/app/google_rcu/ir_module/ir_send_driver.c541
-rw-r--r--src/app/google_rcu/ir_module/ir_send_driver.h119
-rw-r--r--src/app/google_rcu/ir_module/ir_send_handle.c388
-rw-r--r--src/app/google_rcu/ir_module/ir_send_handle.h46
-rw-r--r--src/app/google_rcu/ir_module/ir_service_handle.c851
-rw-r--r--src/app/google_rcu/ir_module/ir_service_handle.h130
-rw-r--r--src/app/google_rcu/key_module/key_handle.c1527
-rw-r--r--src/app/google_rcu/key_module/key_handle.h359
-rw-r--r--src/app/google_rcu/key_module/keyscan_driver.c483
-rw-r--r--src/app/google_rcu/key_module/keyscan_driver.h94
-rw-r--r--src/app/google_rcu/led_module/led_driver.c331
-rw-r--r--src/app/google_rcu/led_module/led_driver.h206
-rw-r--r--src/app/google_rcu/led_module/led_pwm_driver.c246
-rw-r--r--src/app/google_rcu/led_module/led_pwm_driver.h57
-rw-r--r--src/app/google_rcu/loop_queue.c418
-rw-r--r--src/app/google_rcu/loop_queue.h71
-rw-r--r--src/app/google_rcu/main.c606
-rw-r--r--src/app/google_rcu/mp_config.c343
-rw-r--r--src/app/google_rcu/mp_config.h41
-rw-r--r--src/app/google_rcu/opus/config.h64
-rw-r--r--src/app/google_rcu/opus/opus.h994
-rw-r--r--src/app/google_rcu/opus/opus_custom.h345
-rw-r--r--src/app/google_rcu/opus/opus_defines.h753
-rw-r--r--src/app/google_rcu/opus/opus_multistream.h662
-rw-r--r--src/app/google_rcu/opus/opus_types.h159
-rw-r--r--src/app/google_rcu/profile_module/dfu_api.h183
-rw-r--r--src/app/google_rcu/profile_module/dfu_service.c1188
-rw-r--r--src/app/google_rcu/profile_module/dfu_service.h117
-rw-r--r--src/app/google_rcu/profile_module/fms.c292
-rw-r--r--src/app/google_rcu/profile_module/fms.h103
-rw-r--r--src/app/google_rcu/profile_module/hids_rmc.c670
-rw-r--r--src/app/google_rcu/profile_module/hids_rmc.h227
-rw-r--r--src/app/google_rcu/profile_module/ir_service.c342
-rw-r--r--src/app/google_rcu/profile_module/ir_service.h101
-rw-r--r--src/app/google_rcu/profile_module/ota_service.c842
-rw-r--r--src/app/google_rcu/profile_module/ota_service.h142
-rw-r--r--src/app/google_rcu/rcu_application.c1722
-rw-r--r--src/app/google_rcu/rcu_application.h253
-rw-r--r--src/app/google_rcu/rcu_gap.c804
-rw-r--r--src/app/google_rcu/rcu_gap.h38
-rw-r--r--src/app/google_rcu/reset_watch_dog_timer.c108
-rw-r--r--src/app/google_rcu/rtc_module/rtc_driver.c206
-rw-r--r--src/app/google_rcu/rtc_module/rtc_driver.h51
-rw-r--r--src/app/google_rcu/swtimer.c319
-rw-r--r--src/app/google_rcu/swtimer.h74
-rw-r--r--src/app/google_rcu/test_module/data_uart_test.c1347
-rw-r--r--src/app/google_rcu/test_module/data_uart_test.h198
-rw-r--r--src/app/google_rcu/test_module/mp_test.c442
-rw-r--r--src/app/google_rcu/test_module/mp_test.h53
-rw-r--r--src/app/google_rcu/test_module/single_tone.c232
-rw-r--r--src/app/google_rcu/test_module/single_tone.h57
-rw-r--r--src/app/google_rcu/test_module/uart_transport.c463
-rw-r--r--src/app/google_rcu/test_module/uart_transport.h77
-rw-r--r--src/app/google_rcu/voice_module/voice.c1081
-rw-r--r--src/app/google_rcu/voice_module/voice.h86
-rw-r--r--src/app/google_rcu/voice_module/voice_driver.c555
-rw-r--r--src/app/google_rcu/voice_module/voice_driver.h126
-rw-r--r--src/ble/privacy/privacy_mgnt.c578
-rw-r--r--src/ble/privacy/privacy_mgnt.h492
-rw-r--r--src/ble/profile/client/ams_client.c536
-rw-r--r--src/ble/profile/client/ancs_client.c681
-rw-r--r--src/ble/profile/client/bas_client.c613
-rw-r--r--src/ble/profile/client/dfu_client.c1344
-rw-r--r--src/ble/profile/client/dis_client.c825
-rw-r--r--src/ble/profile/client/gaps_client.c500
-rw-r--r--src/ble/profile/client/gatts_client.c479
-rw-r--r--src/ble/profile/client/gcs_client.c417
-rw-r--r--src/ble/profile/client/hids_client.c1139
-rw-r--r--src/ble/profile/client/ias_client.c533
-rw-r--r--src/ble/profile/client/ipss_client.c102
-rw-r--r--src/ble/profile/client/kns_client.c653
-rw-r--r--src/ble/profile/client/lls_client.c623
-rw-r--r--src/ble/profile/client/ota_client.c644
-rw-r--r--src/ble/profile/client/simple_ble_client.c725
-rw-r--r--src/ble/profile/client/tps_client.c469
-rw-r--r--src/ble/profile/server/atvv_service.c392
-rw-r--r--src/ble/profile/server/bas.c374
-rw-r--r--src/ble/profile/server/cscs.c956
-rw-r--r--src/ble/profile/server/dfu_service.c1154
-rw-r--r--src/ble/profile/server/dis.c699
-rw-r--r--src/ble/profile/server/gls.c2016
-rw-r--r--src/ble/profile/server/hids.c772
-rw-r--r--src/ble/profile/server/hids_kb.c851
-rw-r--r--src/ble/profile/server/hids_ms.c861
-rw-r--r--src/ble/profile/server/hids_mulkb.c985
-rw-r--r--src/ble/profile/server/hids_rmc.c863
-rw-r--r--src/ble/profile/server/hrs.c639
-rw-r--r--src/ble/profile/server/hts.c724
-rw-r--r--src/ble/profile/server/ias.c175
-rw-r--r--src/ble/profile/server/ipss.c75
-rw-r--r--src/ble/profile/server/lls.c255
-rw-r--r--src/ble/profile/server/lns.c1712
-rw-r--r--src/ble/profile/server/ota_service.c830
-rw-r--r--src/ble/profile/server/plxs.c1971
-rw-r--r--src/ble/profile/server/rscs.c1012
-rw-r--r--src/ble/profile/server/simple_ble_service.c478
-rw-r--r--src/ble/profile/server/sps.c337
-rw-r--r--src/ble/profile/server/tps.c210
-rw-r--r--src/ble/profile/server/vendor_service.c282
-rw-r--r--src/ble/profile/server/voice_service.c327
-rw-r--r--src/ble/profile/server/wss.c502
-rw-r--r--src/ble/sample/ams.c142
-rw-r--r--src/ble/sample/ams.h33
-rw-r--r--src/ble/upperstack_lib.c9970
-rw-r--r--src/ble/upperstack_lib.h10
-rw-r--r--src/dfu/dfu_application.c617
-rw-r--r--src/dfu/dfu_application.h33
-rw-r--r--src/dfu/dfu_main.c303
-rw-r--r--src/dfu/dfu_main.h37
-rw-r--r--src/dfu/dfu_task.c104
-rw-r--r--src/dfu/dfu_task.h21
-rw-r--r--src/mcu/module/data_uart_cmd/data_uart.c278
-rw-r--r--src/mcu/module/data_uart_cmd/data_uart.h100
-rw-r--r--src/mcu/module/data_uart_cmd/data_uart_dlps.c61
-rw-r--r--src/mcu/module/data_uart_cmd/data_uart_dlps.h91
-rw-r--r--src/mcu/module/data_uart_cmd/user_cmd_parse.c642
-rw-r--r--src/mcu/module/data_uart_cmd/user_cmd_parse.h202
-rw-r--r--src/mcu/peripheral/readme0
-rw-r--r--src/mcu/peripheral/rtl876x_3wire_spi.c301
-rw-r--r--src/mcu/peripheral/rtl876x_adc.c575
-rw-r--r--src/mcu/peripheral/rtl876x_aon_wdg.c152
-rw-r--r--src/mcu/peripheral/rtl876x_captouch.c352
-rw-r--r--src/mcu/peripheral/rtl876x_codec.c329
-rw-r--r--src/mcu/peripheral/rtl876x_enh_tim.c424
-rw-r--r--src/mcu/peripheral/rtl876x_gdma.c403
-rw-r--r--src/mcu/peripheral/rtl876x_gpio.c311
-rw-r--r--src/mcu/peripheral/rtl876x_i2c.c622
-rw-r--r--src/mcu/peripheral/rtl876x_i2s.c226
-rw-r--r--src/mcu/peripheral/rtl876x_io_dlps.c1627
-rw-r--r--src/mcu/peripheral/rtl876x_ir.c596
-rw-r--r--src/mcu/peripheral/rtl876x_keyscan.c266
-rw-r--r--src/mcu/peripheral/rtl876x_lpc.c379
-rw-r--r--src/mcu/peripheral/rtl876x_nvic.c64
-rw-r--r--src/mcu/peripheral/rtl876x_pinmux.c501
-rw-r--r--src/mcu/peripheral/rtl876x_qdec.c315
-rw-r--r--src/mcu/peripheral/rtl876x_rcc.c462
-rw-r--r--src/mcu/peripheral/rtl876x_rtc.c419
-rw-r--r--src/mcu/peripheral/rtl876x_spi.c352
-rw-r--r--src/mcu/peripheral/rtl876x_tim.c320
-rw-r--r--src/mcu/peripheral/rtl876x_uart.c425
-rw-r--r--src/mcu/rtl876x/arm/startup_rtl876x.s280
-rw-r--r--src/mcu/rtl876x/arm/startup_rtl876x_gcc.s371
-rw-r--r--src/mcu/rtl876x/overlay_mgr.c163
-rw-r--r--src/mcu/rtl876x/system_rtl876x.c1466
-rw-r--r--src/platform/dfu_flash.c1121
-rw-r--r--src/platform/psram_platform.c513
-rw-r--r--src/platform/qspi_lcd_platform.c46
-rw-r--r--src/platform/retarget.c188
-rw-r--r--src/platform/system_trace.c171
-rw-r--r--src/sample/ble_audio_ba/app_flags.h36
-rw-r--r--src/sample/ble_audio_ba/app_task.c108
-rw-r--r--src/sample/ble_audio_ba/app_task.h30
-rw-r--r--src/sample/ble_audio_ba/ble_audio_ba_app.c540
-rw-r--r--src/sample/ble_audio_ba/ble_audio_ba_app.h53
-rw-r--r--src/sample/ble_audio_ba/ble_audio_ba_role.c610
-rw-r--r--src/sample/ble_audio_ba/ble_audio_ba_role.h37
-rw-r--r--src/sample/ble_audio_ba/link_mgr.c182
-rw-r--r--src/sample/ble_audio_ba/link_mgr.h115
-rw-r--r--src/sample/ble_audio_ba/main.c162
-rw-r--r--src/sample/ble_audio_ba/user_cmd.c454
-rw-r--r--src/sample/ble_audio_ba/user_cmd.h31
-rw-r--r--src/sample/ble_broadcaster/app_flags.h33
-rw-r--r--src/sample/ble_broadcaster/app_task.c103
-rw-r--r--src/sample/ble_broadcaster/app_task.h27
-rw-r--r--src/sample/ble_broadcaster/broadcaster_app.c138
-rw-r--r--src/sample/ble_broadcaster/broadcaster_app.h53
-rw-r--r--src/sample/ble_broadcaster/main.c178
-rw-r--r--src/sample/ble_bt5_central/app_flags.h36
-rw-r--r--src/sample/ble_bt5_central/app_task.c108
-rw-r--r--src/sample/ble_bt5_central/app_task.h27
-rw-r--r--src/sample/ble_bt5_central/bt5_central_app.c693
-rw-r--r--src/sample/ble_bt5_central/bt5_central_app.h53
-rw-r--r--src/sample/ble_bt5_central/link_mgr.c88
-rw-r--r--src/sample/ble_bt5_central/link_mgr.h104
-rw-r--r--src/sample/ble_bt5_central/main.c163
-rw-r--r--src/sample/ble_bt5_central/user_cmd.c430
-rw-r--r--src/sample/ble_bt5_central/user_cmd.h31
-rw-r--r--src/sample/ble_bt5_peripheral/app_flags.h37
-rw-r--r--src/sample/ble_bt5_peripheral/app_task.c100
-rw-r--r--src/sample/ble_bt5_peripheral/app_task.h27
-rw-r--r--src/sample/ble_bt5_peripheral/bt5_peripheral_app.c507
-rw-r--r--src/sample/ble_bt5_peripheral/bt5_peripheral_app.h54
-rw-r--r--src/sample/ble_bt5_peripheral/bt5_peripheral_stack_api.c428
-rw-r--r--src/sample/ble_bt5_peripheral/bt5_peripheral_stack_api.h136
-rw-r--r--src/sample/ble_bt5_peripheral/main.c180
-rw-r--r--src/sample/ble_central/app_flags.h38
-rw-r--r--src/sample/ble_central/app_task.c109
-rw-r--r--src/sample/ble_central/app_task.h27
-rw-r--r--src/sample/ble_central/central_app.c928
-rw-r--r--src/sample/ble_central/central_app.h69
-rw-r--r--src/sample/ble_central/link_mgr.c139
-rw-r--r--src/sample/ble_central/link_mgr.h111
-rw-r--r--src/sample/ble_central/main.c178
-rw-r--r--src/sample/ble_central/user_cmd.c1066
-rw-r--r--src/sample/ble_central/user_cmd.h31
-rw-r--r--src/sample/ble_observer/app_flags.h33
-rw-r--r--src/sample/ble_observer/app_task.c102
-rw-r--r--src/sample/ble_observer/app_task.h27
-rw-r--r--src/sample/ble_observer/main.c149
-rw-r--r--src/sample/ble_observer/observer_app.c315
-rw-r--r--src/sample/ble_observer/observer_app.h54
-rw-r--r--src/sample/ble_peripheral/ancs.c662
-rw-r--r--src/sample/ble_peripheral/ancs.h262
-rw-r--r--src/sample/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/ble_peripheral/app_task.c103
-rw-r--r--src/sample/ble_peripheral/app_task.h39
-rw-r--r--src/sample/ble_peripheral/main.c248
-rw-r--r--src/sample/ble_peripheral/peripheral_app.c594
-rw-r--r--src/sample/ble_peripheral/peripheral_app.h85
-rw-r--r--src/sample/ble_peripheral_privacy/app_flags.h42
-rw-r--r--src/sample/ble_peripheral_privacy/app_task.c110
-rw-r--r--src/sample/ble_peripheral_privacy/app_task.h27
-rw-r--r--src/sample/ble_peripheral_privacy/main.c220
-rw-r--r--src/sample/ble_peripheral_privacy/peripheral_privacy_app.c710
-rw-r--r--src/sample/ble_peripheral_privacy/peripheral_privacy_app.h97
-rw-r--r--src/sample/ble_peripheral_privacy/user_cmd.c110
-rw-r--r--src/sample/ble_peripheral_privacy/user_cmd.h31
-rw-r--r--src/sample/ble_scatternet/app_flags.h40
-rw-r--r--src/sample/ble_scatternet/app_task.c111
-rw-r--r--src/sample/ble_scatternet/app_task.h27
-rw-r--r--src/sample/ble_scatternet/link_mgr.c137
-rw-r--r--src/sample/ble_scatternet/link_mgr.h87
-rw-r--r--src/sample/ble_scatternet/main.c297
-rw-r--r--src/sample/ble_scatternet/scatternet_app.c1205
-rw-r--r--src/sample/ble_scatternet/scatternet_app.h77
-rw-r--r--src/sample/ble_scatternet/user_cmd.c1968
-rw-r--r--src/sample/ble_scatternet/user_cmd.h31
-rw-r--r--src/sample/dtm/app_flags.h31
-rw-r--r--src/sample/dtm/app_task.c96
-rw-r--r--src/sample/dtm/app_task.h27
-rw-r--r--src/sample/dtm/dtm_app.c377
-rw-r--r--src/sample/dtm/dtm_app.h44
-rw-r--r--src/sample/dtm/main.c54
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app.c613
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app_task.c124
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/main.c242
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode+GDMA/io_adc.c358
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode+GDMA/io_adc.h78
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app.c608
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/main.c241
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode/io_adc.c200
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode/io_adc.h77
-rw-r--r--src/sample/io_sample/ADC/DLPS/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/ADC/DLPS/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/ADC/DLPS/ble_peripheral/app.c613
-rw-r--r--src/sample/io_sample/ADC/DLPS/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/ADC/DLPS/ble_peripheral/app_flags.h39
-rw-r--r--src/sample/io_sample/ADC/DLPS/ble_peripheral/app_task.c124
-rw-r--r--src/sample/io_sample/ADC/DLPS/ble_peripheral/app_task.h46
-rw-r--r--src/sample/io_sample/ADC/DLPS/ble_peripheral/main.c308
-rw-r--r--src/sample/io_sample/ADC/DLPS/io_adc.c269
-rw-r--r--src/sample/io_sample/ADC/DLPS/io_adc.h78
-rw-r--r--src/sample/io_sample/ADC/OneShotMode+GDMA/main.c300
-rw-r--r--src/sample/io_sample/ADC/OneShotMode/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/ADC/OneShotMode/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app.c609
-rw-r--r--src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/ADC/OneShotMode/ble_peripheral/main.c248
-rw-r--r--src/sample/io_sample/ADC/OneShotMode/io_adc.c248
-rw-r--r--src/sample/io_sample/ADC/OneShotMode/io_adc.h121
-rw-r--r--src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app.c608
-rw-r--r--src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/main.c249
-rw-r--r--src/sample/io_sample/ADC/OneShotMode_DifferentialMode/io_adc.c216
-rw-r--r--src/sample/io_sample/ADC/OneShotMode_DifferentialMode/io_adc.h100
-rw-r--r--src/sample/io_sample/ADC/OneShotMode_Polling/main.c209
-rw-r--r--src/sample/io_sample/CAPTOUCH/Touch/main.c199
-rw-r--r--src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app.c608
-rw-r--r--src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app_task.c133
-rw-r--r--src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app_task.h46
-rw-r--r--src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/main.c332
-rw-r--r--src/sample/io_sample/CAPTOUCH/Touch_DLPS/io_cap_touch.h53
-rw-r--r--src/sample/io_sample/CAPTOUCH/Touch_DLPS/io_cap_tpuch.c249
-rw-r--r--src/sample/io_sample/CODEC/AMIC/main.c235
-rw-r--r--src/sample/io_sample/CODEC/DMIC/main.c248
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app.c610
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/main.c234
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_multi_block/io_gdma.c230
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_multi_block/io_gdma.h70
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app.c610
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/main.c234
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_single_block/io_gdma.c116
-rw-r--r--src/sample/io_sample/GDMA/Mem2Mem_single_block/io_gdma.h51
-rw-r--r--src/sample/io_sample/GPIO/Input_key/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/GPIO/Input_key/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/GPIO/Input_key/ble_peripheral/app.c607
-rw-r--r--src/sample/io_sample/GPIO/Input_key/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/GPIO/Input_key/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/GPIO/Input_key/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/GPIO/Input_key/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/GPIO/Input_key/ble_peripheral/main.c235
-rw-r--r--src/sample/io_sample/GPIO/Input_key/io_gpio.c91
-rw-r--r--src/sample/io_sample/GPIO/Input_key/io_gpio.h39
-rw-r--r--src/sample/io_sample/GPIO/Input_polling/main.c94
-rw-r--r--src/sample/io_sample/GPIO/Output_led/main.c93
-rw-r--r--src/sample/io_sample/GPIO/Output_led/xiaomi_gpio_test.c322
-rw-r--r--src/sample/io_sample/GPIO/Output_led/xiaomi_gpio_test.h38
-rw-r--r--src/sample/io_sample/I2C/GDMA_Master_Rx_Slave_Tx/main.c418
-rw-r--r--src/sample/io_sample/I2C/GDMA_Master_Tx_Slave_Rx/main.c314
-rw-r--r--src/sample/io_sample/I2C/I2C_EEPROM/main.c165
-rw-r--r--src/sample/io_sample/I2C/STK8321/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/I2C/STK8321/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/I2C/STK8321/ble_peripheral/app.c609
-rw-r--r--src/sample/io_sample/I2C/STK8321/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/I2C/STK8321/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/I2C/STK8321/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/I2C/STK8321/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/I2C/STK8321/ble_peripheral/main.c245
-rw-r--r--src/sample/io_sample/I2C/STK8321/io_i2c.c151
-rw-r--r--src/sample/io_sample/I2C/STK8321/io_i2c.h43
-rw-r--r--src/sample/io_sample/I2C/STK8321/stk8321.c33
-rw-r--r--src/sample/io_sample/I2C/STK8321/stk8321.h58
-rw-r--r--src/sample/io_sample/I2C/Self_Test/main.c351
-rw-r--r--src/sample/io_sample/I2S/I2S_Slave_Recv/main.c140
-rw-r--r--src/sample/io_sample/I2S/I2S_Slave_Recv_GDMA/main.c229
-rw-r--r--src/sample/io_sample/I2S/Tx_polling/main.c130
-rw-r--r--src/sample/io_sample/IR/Learn/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/IR/Learn/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/IR/Learn/ble_peripheral/app.c619
-rw-r--r--src/sample/io_sample/IR/Learn/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/IR/Learn/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/IR/Learn/ble_peripheral/app_task.c124
-rw-r--r--src/sample/io_sample/IR/Learn/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/IR/Learn/ble_peripheral/main.c261
-rw-r--r--src/sample/io_sample/IR/Learn/ir_learn.c340
-rw-r--r--src/sample/io_sample/IR/Learn/ir_learn.h99
-rw-r--r--src/sample/io_sample/IR/Learn/ir_learn_app.c199
-rw-r--r--src/sample/io_sample/IR/Learn/ir_learn_app.h38
-rw-r--r--src/sample/io_sample/IR/Learn/ir_learn_config.h54
-rw-r--r--src/sample/io_sample/IR/Learn/led/ir_led.c78
-rw-r--r--src/sample/io_sample/IR/Learn/led/ir_led.h51
-rw-r--r--src/sample/io_sample/IR/Learn/trans/ir_driver_rx.c166
-rw-r--r--src/sample/io_sample/IR/Learn/trans/ir_driver_rx.h64
-rw-r--r--src/sample/io_sample/IR/Learn/trans/ir_rx_loop_queue.c234
-rw-r--r--src/sample/io_sample/IR/Learn/trans/ir_rx_loop_queue.h76
-rw-r--r--src/sample/io_sample/IR/Learn/trans/ir_trans_rx.c153
-rw-r--r--src/sample/io_sample/IR/Learn/trans/ir_trans_rx.h43
-rw-r--r--src/sample/io_sample/IR/Rx+GDMA/main.c233
-rw-r--r--src/sample/io_sample/IR/Rx/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/IR/Rx/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/IR/Rx/ble_peripheral/app.c610
-rw-r--r--src/sample/io_sample/IR/Rx/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/IR/Rx/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/IR/Rx/ble_peripheral/app_task.c124
-rw-r--r--src/sample/io_sample/IR/Rx/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/IR/Rx/ble_peripheral/main.c248
-rw-r--r--src/sample/io_sample/IR/Rx/ble_peripheral/maincc.c249
-rw-r--r--src/sample/io_sample/IR/Rx/io_ir.c167
-rw-r--r--src/sample/io_sample/IR/Rx/io_ir.h67
-rw-r--r--src/sample/io_sample/IR/SendCode/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/IR/SendCode/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/IR/SendCode/ble_peripheral/app.c633
-rw-r--r--src/sample/io_sample/IR/SendCode/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/IR/SendCode/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/IR/SendCode/ble_peripheral/app_task.c126
-rw-r--r--src/sample/io_sample/IR/SendCode/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/IR/SendCode/ble_peripheral/main.c249
-rw-r--r--src/sample/io_sample/IR/SendCode/config/ir_protocol_config.h205
-rw-r--r--src/sample/io_sample/IR/SendCode/encode/ir_encode.c226
-rw-r--r--src/sample/io_sample/IR/SendCode/encode/ir_encode.h98
-rw-r--r--src/sample/io_sample/IR/SendCode/ir_app.c782
-rw-r--r--src/sample/io_sample/IR/SendCode/ir_app.h41
-rw-r--r--src/sample/io_sample/IR/SendCode/led/ir_led.c74
-rw-r--r--src/sample/io_sample/IR/SendCode/led/ir_led.h40
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/dvb_40bit_prot.c96
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/dvb_40bit_prot.h46
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/dvb_prot.c56
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/dvb_prot.h43
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/konica_prot.c80
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/konica_prot.h44
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/lc7464m_prot.c56
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/lc7464m_prot.h43
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/mitc8d8_prot.c72
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/mitc8d8_prot.h43
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/nec_prot.c83
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/nec_prot.h44
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/pioneer_prot.c56
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/pioneer_prot.h43
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/raw_pack_prot.c46
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/raw_pack_prot.h38
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/rc5_prot.c141
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/rc5_prot.h43
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/rc6_prot.c125
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/rc6_prot.h46
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/sharp_prot.c49
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/sharp_prot.h43
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/sony6124_prot.c55
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/sony6124_prot.h43
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/tc9012_prot.c108
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/tc9012_prot.h44
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/victorc8d8_prot.c53
-rw-r--r--src/sample/io_sample/IR/SendCode/protocol/victorc8d8_prot.h44
-rw-r--r--src/sample/io_sample/IR/SendCode/trans/ir_trans.c928
-rw-r--r--src/sample/io_sample/IR/SendCode/trans/ir_trans.h191
-rw-r--r--src/sample/io_sample/IR/Tx+GDMA/main.c188
-rw-r--r--src/sample/io_sample/IR/Tx/main.c202
-rw-r--r--src/sample/io_sample/KEYSCAN/Keyscan_Manual/app_timer.c23
-rw-r--r--src/sample/io_sample/KEYSCAN/Keyscan_Manual/app_timer.h43
-rw-r--r--src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app.c608
-rw-r--r--src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/main.c248
-rw-r--r--src/sample/io_sample/KEYSCAN/Keyscan_Manual/io_keyscan.c234
-rw-r--r--src/sample/io_sample/KEYSCAN/Keyscan_Manual/io_keyscan.h63
-rw-r--r--src/sample/io_sample/LPC/Comparator/main.c174
-rw-r--r--src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app.c610
-rw-r--r--src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app_task.c124
-rw-r--r--src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/main.c286
-rw-r--r--src/sample/io_sample/LPC/LPC_DLPS/io_lpc.c168
-rw-r--r--src/sample/io_sample/LPC/LPC_DLPS/io_lpc.h69
-rw-r--r--src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app.c609
-rw-r--r--src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/main.c232
-rw-r--r--src/sample/io_sample/LPC/VoltageDetection/io_lpc.c87
-rw-r--r--src/sample/io_sample/LPC/VoltageDetection/io_lpc.h54
-rw-r--r--src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app.c611
-rw-r--r--src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/main.c318
-rw-r--r--src/sample/io_sample/QDEC/QDEC _DLPS/io_qdec.c170
-rw-r--r--src/sample/io_sample/QDEC/QDEC _DLPS/io_qdec.h61
-rw-r--r--src/sample/io_sample/QDEC/QDEC/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/QDEC/QDEC/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/QDEC/QDEC/ble_peripheral/app.c611
-rw-r--r--src/sample/io_sample/QDEC/QDEC/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/QDEC/QDEC/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/QDEC/QDEC/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/QDEC/QDEC/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/QDEC/QDEC/ble_peripheral/main.c245
-rw-r--r--src/sample/io_sample/QDEC/QDEC/io_qdec.c119
-rw-r--r--src/sample/io_sample/QDEC/QDEC/io_qdec.h54
-rw-r--r--src/sample/io_sample/RTC/Comparator/main.c116
-rw-r--r--src/sample/io_sample/RTC/Overflow/main.c107
-rw-r--r--src/sample/io_sample/RTC/Pre_comp3/main.c132
-rw-r--r--src/sample/io_sample/RTC/Tick/main.c104
-rw-r--r--src/sample/io_sample/SPI/Flash/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/SPI/Flash/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/SPI/Flash/ble_peripheral/app.c608
-rw-r--r--src/sample/io_sample/SPI/Flash/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/SPI/Flash/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/SPI/Flash/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/SPI/Flash/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/SPI/Flash/ble_peripheral/main.c245
-rw-r--r--src/sample/io_sample/SPI/Flash/io_spi.c124
-rw-r--r--src/sample/io_sample/SPI/Flash/io_spi.h41
-rw-r--r--src/sample/io_sample/SPI/Flash/spi_flash.c303
-rw-r--r--src/sample/io_sample/SPI/Flash/spi_flash.h68
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app.c613
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/main.c247
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/io_gdma.c172
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/io_gdma.h44
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/io_spi.c64
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/io_spi.h43
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/io_uart.c84
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/io_uart.h37
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/spi_flash.c310
-rw-r--r--src/sample/io_sample/SPI/GDMA_Multiblock/spi_flash.h73
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app.c613
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/main.c247
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/io_gdma.c128
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/io_gdma.h44
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/io_spi.c64
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/io_spi.h43
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/io_uart.c84
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/io_uart.h37
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/spi_flash.c310
-rw-r--r--src/sample/io_sample/SPI/GDMA_Singleblock/spi_flash.h73
-rw-r--r--src/sample/io_sample/SPI/Interrupt/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/SPI/Interrupt/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/SPI/Interrupt/ble_peripheral/app.c609
-rw-r--r--src/sample/io_sample/SPI/Interrupt/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/SPI/Interrupt/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/SPI/Interrupt/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/SPI/Interrupt/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/SPI/Interrupt/ble_peripheral/main.c245
-rw-r--r--src/sample/io_sample/SPI/Interrupt/io_spi.c165
-rw-r--r--src/sample/io_sample/SPI/Interrupt/io_spi.h42
-rw-r--r--src/sample/io_sample/SPI/Interrupt/spi_flash.c67
-rw-r--r--src/sample/io_sample/SPI/Interrupt/spi_flash.h70
-rw-r--r--src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app.c608
-rw-r--r--src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/main.c245
-rw-r--r--src/sample/io_sample/SPI/Polling_eeprom/io_spi.c102
-rw-r--r--src/sample/io_sample/SPI/Polling_eeprom/io_spi.h42
-rw-r--r--src/sample/io_sample/SPI/Polling_eeprom/spi_flash.c84
-rw-r--r--src/sample/io_sample/SPI/Polling_eeprom/spi_flash.h67
-rw-r--r--src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app.c608
-rw-r--r--src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/main.c245
-rw-r--r--src/sample/io_sample/SPI/Polling_fullduplex/io_spi.c107
-rw-r--r--src/sample/io_sample/SPI/Polling_fullduplex/io_spi.h42
-rw-r--r--src/sample/io_sample/SPI/Polling_fullduplex/spi_flash.c87
-rw-r--r--src/sample/io_sample/SPI/Polling_fullduplex/spi_flash.h67
-rw-r--r--src/sample/io_sample/SPI/Psram/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/SPI/Psram/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/SPI/Psram/ble_peripheral/app.c609
-rw-r--r--src/sample/io_sample/SPI/Psram/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/SPI/Psram/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/SPI/Psram/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/SPI/Psram/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/SPI/Psram/ble_peripheral/main.c245
-rw-r--r--src/sample/io_sample/SPI/Psram/io_spi.c251
-rw-r--r--src/sample/io_sample/SPI/Psram/io_spi.h53
-rw-r--r--src/sample/io_sample/SPI/Psram/io_uart.c84
-rw-r--r--src/sample/io_sample/SPI/Psram/io_uart.h37
-rw-r--r--src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app.c608
-rw-r--r--src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app_task.c123
-rw-r--r--src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/main.c245
-rw-r--r--src/sample/io_sample/SPI/SPI_Software_CS/io_spi.c113
-rw-r--r--src/sample/io_sample/SPI/SPI_Software_CS/io_spi.h41
-rw-r--r--src/sample/io_sample/SPI/SPI_Software_CS/spi_flash.c338
-rw-r--r--src/sample/io_sample/SPI/SPI_Software_CS/spi_flash.h69
-rw-r--r--src/sample/io_sample/SPI/SelfTest/main.c213
-rw-r--r--src/sample/io_sample/SPI3WIRE/Polling/main.c238
-rw-r--r--src/sample/io_sample/TIM/GDMA+PWM+GPIO/main.c268
-rw-r--r--src/sample/io_sample/TIM/PWM/main.c174
-rw-r--r--src/sample/io_sample/TIM/Timer_interrupt/main.c176
-rw-r--r--src/sample/io_sample/TIM_ENHANCE/Latch_GPIO/main.c222
-rw-r--r--src/sample/io_sample/UART/DLPS/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/UART/DLPS/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/UART/DLPS/ble_peripheral/app.c608
-rw-r--r--src/sample/io_sample/UART/DLPS/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/UART/DLPS/ble_peripheral/app_flags.h40
-rw-r--r--src/sample/io_sample/UART/DLPS/ble_peripheral/app_task.c133
-rw-r--r--src/sample/io_sample/UART/DLPS/ble_peripheral/app_task.h46
-rw-r--r--src/sample/io_sample/UART/DLPS/ble_peripheral/main.c323
-rw-r--r--src/sample/io_sample/UART/DLPS/io_uart.c239
-rw-r--r--src/sample/io_sample/UART/DLPS/io_uart.h51
-rw-r--r--src/sample/io_sample/UART/DMA_UnFixedLen/main.c373
-rw-r--r--src/sample/io_sample/UART/GDMA/ble_peripheral/ancs.c662
-rw-r--r--src/sample/io_sample/UART/GDMA/ble_peripheral/ancs.h259
-rw-r--r--src/sample/io_sample/UART/GDMA/ble_peripheral/app.c613
-rw-r--r--src/sample/io_sample/UART/GDMA/ble_peripheral/app.h72
-rw-r--r--src/sample/io_sample/UART/GDMA/ble_peripheral/app_flags.h39
-rw-r--r--src/sample/io_sample/UART/GDMA/ble_peripheral/app_task.c124
-rw-r--r--src/sample/io_sample/UART/GDMA/ble_peripheral/app_task.h47
-rw-r--r--src/sample/io_sample/UART/GDMA/ble_peripheral/main.c240
-rw-r--r--src/sample/io_sample/UART/GDMA/io_uart.c376
-rw-r--r--src/sample/io_sample/UART/GDMA/io_uart.h76
-rw-r--r--src/sample/io_sample/UART/Interrupt/main.c250
-rw-r--r--src/sample/io_sample/UART/Log_uart_multiplexing/main.c353
-rw-r--r--src/sample/io_sample/UART/Polling/main.c213
877 files changed, 264334 insertions, 0 deletions
diff --git a/board/evb/google_rcu/board.h b/board/evb/google_rcu/board.h
new file mode 100644
index 0000000..aa1c3bd
--- /dev/null
+++ b/board/evb/google_rcu/board.h
@@ -0,0 +1,358 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file board.h
+* @brief header file of Keypad demo.
+* @details
+* @author chenjie_jin
+* @date 2020-02-24
+* @version v1.3
+* *********************************************************************************************************
+*/
+
+
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+#include "otp_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define REMOTE_G10 1
+#define REMOTE_G20 2
+
+/*******************************************************
+* Log Config
+*******************************************************/
+#define IS_RELEASE_VERSION 0 /* 1: close log 0: open log */
+
+/*******************************************************
+* GAP Parameter Config
+*******************************************************/
+#define VID 0x005D
+#define PID 0x0302
+
+/*******************************************************
+* OTA Config
+*******************************************************/
+#define SUPPORT_TEMP_COMBINED_OTA 1 /* set 1 to support temp combined OTA */
+#define SUPPORT_SILENT_OTA 1 /* set 1 to enable silent OTA */
+#define SUPPORT_NORMAL_OTA 0 /* set 1 to enable normal OTA */
+
+#define DFU_BUFFER_CHECK_ENABLE 1 /* set 1 to enable buffer check feature */
+#define DFU_TEMP_BUFFER_SIZE 2048 /* dfu max buffer size */
+
+#define SUPPORT_OTA_PROTOCOL_TYPE_CHARACTERISTIC 1
+
+#define OTA_AES_FLAG_EN 1
+
+/*******************************************************
+* RCU Feature Config
+*******************************************************/
+#define FEAUTRE_SUPPORT_FLASH_2_BIT_MODE 1 /* set 1 to enable flash 2-bit mode */
+
+#define FEATURE_SUPPORT_REPORT_MULTIPLE_HID_KEY_CODES 1 /* set 1 to support to report multiple HID key codes */
+
+#define FEATURE_SUPPORT_NO_ACTION_DISCONN 0 /* set 1 to enable NO_ACTION_DISCONN after timeout */
+
+#define FEATURE_SUPPORT_REMOVE_LINK_KEY_BEFORE_PAIRING 0 /* set 1 to enable remove link key before paring */
+
+#define FEATURE_SUPPORT_MP_TEST_MODE 0 /* set 1 to enable MP test */
+
+#define FEATURE_SUPPORT_PRIVACY 1 /* set 1 to enable privacy feature */
+
+#define FEATURE_SUPPORT_DATA_LENGTH_EXTENSION 1 /* set 1 to enable data length extension feature */
+
+#define FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ 0 /* set 1 to enable HIDS char authentication request */
+
+#define FEATURE_SUPPORT_KEY_LONG_PRESS_PROTECT 1 /*set 1 to stop scan when press one key too long*/
+
+#define FEAUTRE_SUPPORT_IR_OVER_BLE 1 /* set 1 to support IR over BLE feature */
+
+/*******************************************************
+* FTL Address Config
+*******************************************************/
+/*note: if the FTL size is 16K, the range of FTL address here should be less than 3056*/
+#define FTL_MP_TEST_PARAMS_BASE_ADDR 0
+#define FTL_MP_TEST_PARAMS_MAX_LEN 12
+
+#define FTL_WAKEUP_KEY_COUNT_ADDR 24
+#define FTL_WAKEUP_KEY_COUNT_LEN 4
+
+#define APP_STATIC_RANDOM_ADDR_OFFSET 32
+#define FTL_RPA_LEN 8
+
+#define FTL_IR_TABLE_BASE_ADDR 256
+#define FTL_IR_TABLE_ITEM_MAX_LEN 512
+#define FTL_IR_TABLE_ITEM_HEADER_LEN 4
+
+#define FTL_IR_TABLE_SEC_0_ADDR (FTL_IR_TABLE_BASE_ADDR + FTL_IR_TABLE_ITEM_MAX_LEN * 0)
+#define FTL_IR_TABLE_SEC_1_ADDR (FTL_IR_TABLE_BASE_ADDR + FTL_IR_TABLE_ITEM_MAX_LEN * 1)
+#define FTL_IR_TABLE_SEC_2_ADDR (FTL_IR_TABLE_BASE_ADDR + FTL_IR_TABLE_ITEM_MAX_LEN * 2)
+#define FTL_IR_TABLE_SEC_3_ADDR (FTL_IR_TABLE_BASE_ADDR + FTL_IR_TABLE_ITEM_MAX_LEN * 3)
+#define FTL_IR_TABLE_SEC_4_ADDR (FTL_IR_TABLE_BASE_ADDR + FTL_IR_TABLE_ITEM_MAX_LEN * 4)
+/*******************************************************
+* MP Test Config
+*******************************************************/
+
+#if FEATURE_SUPPORT_MP_TEST_MODE
+
+#define MP_TEST_FTL_PARAMS_TEST_MODE_FLG_OFFSET (FTL_MP_TEST_PARAMS_BASE_ADDR)
+#define MP_TEST_FTL_PARAMS_TEST_MODE_FLG_LEN 4
+
+#define MP_TEST_FTL_PARAMS_LOCAL_BD_ADDR_OFFSET (MP_TEST_FTL_PARAMS_TEST_MODE_FLG_OFFSET + MP_TEST_FTL_PARAMS_TEST_MODE_FLG_LEN)
+#define MP_TEST_FTL_PARAMS_LOCAL_BD_ADDR_LEN 8
+
+#define MP_TEST_MODE_SUPPORT_HCI_UART_TEST 1 /* set 1 to support HCI Uart Test Mode */
+#define MP_TEST_MODE_SUPPORT_DATA_UART_TEST 1 /* set 1 to support Data Uart Test Mode */
+#define MP_TEST_MODE_SUPPORT_SINGLE_TONE_TEST 1 /* set 1 to support SingleTone Test Mode */
+#define MP_TEST_MODE_SUPPORT_FAST_PAIR_TEST 1 /* set 1 to support Fast Pair Test */
+#define MP_TEST_MODE_SUPPORT_AUTO_K_RF 0 /* set 1 to support Auto K RF */
+#define MP_TEST_MODE_SUPPORT_DATA_UART_DOWNLOAD 0 /* set 1 to support Data UART download */
+
+#define MP_TEST_MODE_TRIG_BY_GPIO 0x0001 /* GPIO signal while power on to trigger MP test mode */
+#define MP_TEST_MODE_TRIG_BY_COMBINE_KEYS 0x0002 /* Combine keys to trigger MP test mode */
+
+#define MP_TEST_MODE_TRIG_SEL (MP_TEST_MODE_TRIG_BY_GPIO | MP_TEST_MODE_TRIG_BY_COMBINE_KEYS)
+
+#if (MP_TEST_MODE_TRIG_SEL & MP_TEST_MODE_TRIG_BY_GPIO)
+
+#define MP_TEST_TRIG_PIN_1 P0_6
+#define MP_TEST_TRIG_PIN_2 P3_3
+
+#endif
+
+#if MP_TEST_MODE_SUPPORT_DATA_UART_TEST
+#define MP_TEST_UART_TX_PIN P3_0
+#define MP_TEST_UART_RX_PIN P3_1
+#endif
+
+#endif
+
+/*******************************************************
+* Voice Module Config
+*******************************************************/
+#define SUPPORT_VOICE_FEATURE 1 /* set 1 to support voice feature */
+
+#if SUPPORT_VOICE_FEATURE
+
+#define SUPPORT_MIC_BIAS_OUTPUT 1 /* set 1 to enable MIC bias output */
+
+#define SUPPORT_SW_EQ 1 /* set 1 to support software equalizer */
+
+#define SUPPORT_UART_DUMP_FEATURE 0 /* set 1 to support UART dump PCM data */
+
+#if SUPPORT_UART_DUMP_FEATURE
+#define VOICE_UART_TEST_TX P0_0
+#endif
+
+/* mic type definitions */
+#define AMIC_TYPE 0 /* Analog MIC */
+#define DMIC_TYPE 1 /* digital MIC */
+
+/* amic input type definitions */
+#define AMIC_INPUT_TYPE_DIFF 0 /* differential analog input */
+#define AMIC_INPUT_TYPE_SINGLE 1 /* single-end analog input */
+
+/* dmic data latch type definitions */
+#define DMIC_DATA_LATCH_FALLING_EDGE 0 /* falling clock edge */
+#define DMIC_DATA_LATCH_RISING_EDGE 1 /* rising clock edge */
+
+/* codec sample rate type definitions */
+#define CODEC_SAMPLE_RATE_8KHz 1 /* 8KHz codec sample rate */
+#define CODEC_SAMPLE_RATE_16KHz 2 /* 16KHz codec sample rate */
+
+#define CODEC_SAMPLE_RATE_SEL CODEC_SAMPLE_RATE_16KHz
+
+/* single MIC configuration */
+#define VOICE_MIC0_TYPE AMIC_TYPE
+
+#if (VOICE_MIC0_TYPE == AMIC_TYPE)
+#define AMIC_MIC_N_PIN P2_6 /* MIC_N is fixed to P2_6 */
+#define AMIC_MIC_P_PIN P2_7 /* MIC_P is fixed to P2_7 */
+#define AMIC_MIC_BIAS_PIN H_0 /* MICBIAS is fixed to H_0 */
+#define AMIC_INPUT_TYPE_SEL AMIC_INPUT_TYPE_DIFF
+#elif (VOICE_MIC0_TYPE == DMIC_TYPE)
+#define DMIC_CLK_PIN P2_0 /* DMIC clock PIN, support PINMUX */
+#define DMIC_DATA_PIN P2_1 /* DMIC data PIN, support PINMUX */
+#define DMIC0_DATA_LATCH_TYPE DMIC_DATA_LATCH_FALLING_EDGE
+#endif
+
+
+#define VOICE_FLOW_SEL ATV_GOOGLE_VOICE_FLOW
+
+/* voice encode type */
+#define SW_IMA_ADPCM_ENC 1 /* software IMA/DVI adpcm encode */
+
+
+/* ATV_GOOGLE_VOICE_FLOW must use SW_IMA_ADPCM_ENC */
+#define VOICE_ENC_TYPE SW_IMA_ADPCM_ENC
+
+
+/* ATV Google voice version type */
+#define ATV_VERSION_0_4 1 /* v0.4 */
+#define ATV_VERSION_1_0 2 /* v1.0 */
+
+/* ATV Google voice assistant interaction type */
+#define ATV_INTERACTION_MODEL_ON_REQUEST 1 /* on request */
+#define ATV_INTERACTION_MODEL_PRESS_TO_TALK 2 /* PTT */
+#define ATV_INTERACTION_MODEL_HOLD_TO_TALK 3 /* HTT */
+
+#define ATV_VOICE_VERSION ATV_VERSION_1_0 /* default version is v1.0 */
+#define ATV_VOICE_INTERACTION_MODEL ATV_INTERACTION_MODEL_HOLD_TO_TALK /* default assistant interaction */
+
+#endif
+
+/*******************************************************
+* DTM Config
+*******************************************************/
+#define DATA_UART_TX_PIN P3_0
+#define DATA_UART_RX_PIN P3_1
+
+#define MODE_PIN P4_1
+
+/*******************************************************
+* RCU Keyscan Config
+*******************************************************/
+/* if set KEYSCAN_FIFO_LIMIT larger than 3, need to caution ghost key issue */
+#define KEYSCAN_FIFO_LIMIT 3 /* value range from 1 to 8 */
+
+/* keypad row and column */
+#define KEYPAD_MAX_ROW_SIZE 6
+#define KEYPAD_MAX_COLUMN_SIZE 7
+
+#define KEYPAD_MAX_ROW_SIZE_G20 6
+#define KEYPAD_MAX_COLUMN_SIZE_G20 7
+
+#define KEYPAD_MAX_ROW_SIZE_G10 4
+#define KEYPAD_MAX_COLUMN_SIZE_G10 7
+
+#define ROW0 P0_4
+#define ROW1 P3_3
+#define ROW2 P4_3
+#define ROW3 P0_2
+#define ROW4 P0_1
+#define ROW5 P0_0
+
+#define COLUMN0 P2_2
+#define COLUMN1 P5_2
+#define COLUMN2 P5_1
+#define COLUMN3 P3_2
+#define COLUMN4 P0_5
+#define COLUMN5 P0_6
+#define COLUMN6 P4_0
+
+/*******************************************************
+* IR Module Config
+*******************************************************/
+#define SUPPORT_IR_TX_FEATURE 1
+
+#if SUPPORT_IR_TX_FEATURE
+
+#define IR_SEND_PIN P2_3
+
+#endif
+
+/*******************************************************
+* LED Module Config
+*******************************************************/
+#define SUPPORT_LED_INDICATION_FEATURE 1
+
+#if SUPPORT_LED_INDICATION_FEATURE
+
+#define LED_PWM_CTRL_FEATURE
+
+#define LED_R_PIN P2_4
+#define LED_G_PIN P2_5
+
+#define LED_ACTIVE_LEVEL 1 /* 0: low level active, 1: high level active */
+
+#endif
+
+/*******************************************************
+* Battery Module Config
+*******************************************************/
+#define SUPPORT_BAT_DETECT_FEATURE 1 /* set 1 to enable batttery detect feature */
+
+#if SUPPORT_BAT_DETECT_FEATURE
+
+#define SUPPORT_BAT_KEY_PRESS_DETECT_FEATURE 1 /* set 1 to enable key press battery detect feature */
+
+#define SUPPORT_BAT_PERIODIC_DETECT_FEATURE 0 /* set 1 to enable periodic battery detect feature */
+
+/* Note: make sure BAT_ENTER_NORMAL_MODE_THRESHOLD > BAT_ENTER_NORMAL_MODE_THRESHOLD */
+#define BAT_ENTER_LOW_POWER_THRESHOLD 2000 /* enter low power mode threshold, unit: mV */
+#define BAT_ENTER_NORMAL_MODE_THRESHOLD 2200 /* enter normal mode threshold, unit: mV */
+#define BAT_ENTER_OTA_MODE_THRESHOLD 2500 /* enter ota mode threshold, unit: mV. 2.5v = 30%*/
+
+#define SUPPORT_BAT_LPC_FEATURE 1 /* set 1 to enable LPC */
+#if SUPPORT_BAT_LPC_FEATURE
+#define BAT_LPC_COMP_VALUE LPC_1840_mV /* lpc detect bat threshold value */
+#endif
+
+#endif
+
+/*******************************************************
+* Buzzer Module Config
+*******************************************************/
+#define SUPPORT_BUZZER_FEATURE 1 /* set 1 to enable buzzer feature */
+
+#if SUPPORT_BUZZER_FEATURE
+#define BUZZER_PWM_OUTPUT_PIN P4_2
+#endif
+
+/*******************************************************
+* DLPS Module Config
+*******************************************************/
+#define DLPS_EN 1
+
+/** @defgroup IO Driver Config
+ * @note user must config it firstly!! Do not change macro names!!
+ * @{
+ */
+/* if use user define dlps enter/dlps exit callback function */
+#define USE_USER_DEFINE_DLPS_EXIT_CB 1
+#define USE_USER_DEFINE_DLPS_ENTER_CB 1
+
+/* if use any peripherals below, #define it 1 */
+#define USE_I2C0_DLPS 0
+#define USE_I2C1_DLPS 0
+#if (ROM_WATCH_DOG_ENABLE == 1)
+#define USE_TIM_DLPS 1 //must be 1 if enable watch dog
+#else
+#define USE_TIM_DLPS 0
+#endif
+#define USE_QDECODER_DLPS 0
+#define USE_IR_DLPS 1
+#define USE_ADC_DLPS 0
+#define USE_CTC_DLPS 0
+#define USE_SPI0_DLPS 0
+#define USE_SPI1_DLPS 0
+#define USE_SPI2W_DLPS 0
+#define USE_KEYSCAN_DLPS 1
+#define USE_GPIO_DLPS 1
+#define USE_CODEC_DLPS 0
+#define USE_I2S0_DLPS 0
+#define USE_ENHTIM_DLPS 0
+#define USE_UART0_DLPS 0
+#define USE_UART1_DLPS 0
+
+/* do not modify USE_IO_DRIVER_DLPS macro */
+#define USE_IO_DRIVER_DLPS (USE_I2C0_DLPS | USE_I2C1_DLPS | USE_TIM_DLPS | USE_QDECODER_DLPS\
+ | USE_IR_DLPS | USE_ADC_DLPS | USE_CTC_DLPS | USE_SPI0_DLPS\
+ | USE_SPI1_DLPS | USE_SPI2W_DLPS | USE_KEYSCAN_DLPS\
+ | USE_GPIO_DLPS | USE_CODEC_DLPS | USE_I2S0_DLPS\
+ | USE_ENHTIM_DLPS | USE_UART0_DLPS | USE_UART1_DLPS\
+ | USE_USER_DEFINE_DLPS_ENTER_CB\
+ | USE_USER_DEFINE_DLPS_EXIT_CB)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BOARD_H_ */
+
diff --git a/board/evb/google_rcu/flash map.ini b/board/evb/google_rcu/flash map.ini
new file mode 100644
index 0000000..eee4098
--- /dev/null
+++ b/board/evb/google_rcu/flash map.ini
@@ -0,0 +1,68 @@
+[Property]
+IC_TYPE=554542
+FLASH_SIZE=512
+OTA_SWITCH=Disable
+IMG_HDR_SIZE=1024
+[HighLevel]
+OEM_CFG_ADDR=0x00801000
+OEM_CFG_SIZE=0x00001000
+OTA_BANK0_ADDR=0x00802000
+OTA_BANK0_SIZE=0x00049000
+OTA_BANK1_ADDR=0x0084B000
+OTA_BANK1_SIZE=0x00000000
+FTL_ADDR=0x0084B000
+FTL_SIZE=0x00006000
+OTA_TMP_ADDR=0x00851000
+OTA_TMP_SIZE=0x00024000
+APP_DS_ADDR=0x00875000
+APP_DS_SIZE=0x0000B000
+[OTABank]
+BANK0_OTA_HDR_ADDR=0x00802000
+BANK0_OTA_HDR_SIZE=0x00001000
+BANK0_FSBL_ADDR=0x0080D000
+BANK0_FSBL_SIZE=0x00001000
+BANK0_ROM_PATCH_ADDR=0x00803000
+BANK0_ROM_PATCH_SIZE=0x0000A000
+BANK0_UPPERSTACK_ADDR=0x0080E000
+BANK0_UPPERSTACK_SIZE=0x00024000
+BANK0_APP_ADDR=0x00832000
+BANK0_APP_SIZE=0x00019000
+BANK0_APP_DATA1_ADDR=0x0084B000
+BANK0_APP_DATA1_SIZE=0x00000000
+BANK0_APP_DATA2_ADDR=0x0084B000
+BANK0_APP_DATA2_SIZE=0x00000000
+BANK0_APP_DATA3_ADDR=0x0084B000
+BANK0_APP_DATA3_SIZE=0x00000000
+BANK0_APP_DATA4_ADDR=0x0084B000
+BANK0_APP_DATA4_SIZE=0x00000000
+BANK0_APP_DATA5_ADDR=0x0084B000
+BANK0_APP_DATA5_SIZE=0x00000000
+BANK0_APP_DATA6_ADDR=0x0084B000
+BANK0_APP_DATA6_SIZE=0x00000000
+BANK1_OTA_HDR_ADDR=0x00000000
+BANK1_OTA_HDR_SIZE=0x00000000
+BANK1_FSBL_ADDR=0x00000000
+BANK1_FSBL_SIZE=0x00000000
+BANK1_ROM_PATCH_ADDR=0x00000000
+BANK1_ROM_PATCH_SIZE=0x00000000
+BANK1_UPPERSTACK_ADDR=0x00000000
+BANK1_UPPERSTACK_SIZE=0x00000000
+BANK1_APP_ADDR=0x00000000
+BANK1_APP_SIZE=0x00000000
+BANK1_APP_DATA1_ADDR=0x00000000
+BANK1_APP_DATA1_SIZE=0x00000000
+BANK1_APP_DATA2_ADDR=0x00000000
+BANK1_APP_DATA2_SIZE=0x00000000
+BANK1_APP_DATA3_ADDR=0x00000000
+BANK1_APP_DATA3_SIZE=0x00000000
+BANK1_APP_DATA4_ADDR=0x00000000
+BANK1_APP_DATA4_SIZE=0x00000000
+BANK1_APP_DATA5_ADDR=0x00000000
+BANK1_APP_DATA5_SIZE=0x00000000
+BANK1_APP_DATA6_ADDR=0x00000000
+BANK1_APP_DATA6_SIZE=0x00000000
+[OTAHeader]
+OTA_BIN_VER1=1
+OTA_BIN_VER2=0
+OTA_BIN_VER3=0
+OTA_BIN_VER4=1
diff --git a/board/evb/google_rcu/flash_map.h b/board/evb/google_rcu/flash_map.h
new file mode 100644
index 0000000..cd1fe9f
--- /dev/null
+++ b/board/evb/google_rcu/flash_map.h
@@ -0,0 +1,132 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file flash_map.h
+* @brief Flash Layout Configuration, and flash layout must be changed with config file!
+* @note flash_map.h must be generated by FlashMapGenerateTool!
+* *************************************************************************************
+*/
+
+#ifndef _FLASH_MAP_H_
+#define _FLASH_MAP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*============================================================================*
+* Flash Layout
+*============================================================================*/
+/* Flash total size 512KB
+example:
+ 1) Reaerved: 4K (0x00800000)
+ 2) OEM Header: 4K (0x00801000)
+ 3) OTA Bank0: 292K (0x00802000)
+ a) OTA Header 4K (0x00802000)
+ b) Secure boot loader 4K (0x0080D000)
+ c) Patch code 40K (0x00803000)
+ d) Upperstack Code 144K (0x0080E000)
+ e) APP code 100K (0x00832000)
+ f) APP data1 0K (0x0084B000)
+ g) APP data2 0K (0x0084B000)
+ h) APP data3 0K (0x0084B000)
+ i) APP data4 0K (0x0084B000)
+ j) APP data5 0K (0x0084B000)
+ k) APP data6 0K (0x0084B000)
+ 4) OTA Bank1: 0K (0x0084B000)
+ a) OTA Header 0K (0x00000000)
+ b) Secure boot loader 0K (0x00000000)
+ c) Patch code 0K (0x00000000)
+ d) Upperstack Code 0K (0x00000000)
+ e) APP code 0K (0x00000000)
+ f) APP data1 0K (0x00000000)
+ g) APP data2 0K (0x00000000)
+ h) APP data3 0K (0x00000000)
+ i) APP data4 0K (0x00000000)
+ j) APP data5 0K (0x00000000)
+ k) APP data6 0K (0x00000000)
+ 5) FTL: 24K (0x0084B000)
+ 6) OTA Tmp: 144K (0x00851000)
+ 7) APP Defined Section: 44K (0x00875000)
+*/
+
+/*============================================================================*
+* Flash Layout Configuration (Generated by FlashMapGenerateTool)
+*============================================================================*/
+
+#define FLASH_ADDR 0x00800000 //Fixed
+#define FLASH_SIZE 0x00080000 //512K Bytes
+
+/* ========== High Level Flash Layout Configuration ========== */
+#define RESERVED_ADDR 0x00800000
+#define RESERVED_SIZE 0x00001000 //4K Bytes
+#define OEM_CFG_ADDR 0x00801000
+#define OEM_CFG_SIZE 0x00001000 //4K Bytes
+#define OTA_BANK0_ADDR 0x00802000
+#define OTA_BANK0_SIZE 0x00049000 //292K Bytes
+#define OTA_BANK1_ADDR 0x0084B000
+#define OTA_BANK1_SIZE 0x00000000 //0K Bytes
+#define FTL_ADDR 0x0084B000
+#define FTL_SIZE 0x00006000 //24K Bytes
+#define OTA_TMP_ADDR 0x00851000
+#define OTA_TMP_SIZE 0x00024000 //144K Bytes
+#define BKP_DATA1_ADDR 0x00875000
+#define BKP_DATA1_SIZE 0x0000B000 //44K Bytes
+#define BKP_DATA2_ADDR 0x00000000
+#define BKP_DATA2_SIZE 0x00000000 //0K Bytes
+
+/* ========== OTA Bank0 Flash Layout Configuration ========== */
+#define BANK0_OTA_HEADER_ADDR 0x00802000
+#define BANK0_OTA_HEADER_SIZE 0x00001000 //4K Bytes
+#define BANK0_SECURE_BOOT_ADDR 0x0080D000
+#define BANK0_SECURE_BOOT_SIZE 0x00001000 //4K Bytes
+#define BANK0_ROM_PATCH_ADDR 0x00803000
+#define BANK0_ROM_PATCH_SIZE 0x0000A000 //40K Bytes
+#define BANK0_UPPERSTACK_ADDR 0x0080E000
+#define BANK0_UPPERSTACK_SIZE 0x00024000 //144K Bytes
+#define BANK0_APP_ADDR 0x00832000
+#define BANK0_APP_SIZE 0x00019000 //100K Bytes
+#define BANK0_APP_DATA1_ADDR 0x0084B000
+#define BANK0_APP_DATA1_SIZE 0x00000000 //0K Bytes
+#define BANK0_APP_DATA2_ADDR 0x0084B000
+#define BANK0_APP_DATA2_SIZE 0x00000000 //0K Bytes
+#define BANK0_APP_DATA3_ADDR 0x0084B000
+#define BANK0_APP_DATA3_SIZE 0x00000000 //0K Bytes
+#define BANK0_APP_DATA4_ADDR 0x0084B000
+#define BANK0_APP_DATA4_SIZE 0x00000000 //0K Bytes
+#define BANK0_APP_DATA5_ADDR 0x0084B000
+#define BANK0_APP_DATA5_SIZE 0x00000000 //0K Bytes
+#define BANK0_APP_DATA6_ADDR 0x0084B000
+#define BANK0_APP_DATA6_SIZE 0x00000000 //0K Bytes
+
+/* ========== OTA Bank1 Flash Layout Configuration ========== */
+#define BANK1_OTA_HEADER_ADDR 0x00000000
+#define BANK1_OTA_HEADER_SIZE 0x00000000 //0K Bytes
+#define BANK1_SECURE_BOOT_ADDR 0x00000000
+#define BANK1_SECURE_BOOT_SIZE 0x00000000 //0K Bytes
+#define BANK1_ROM_PATCH_ADDR 0x00000000
+#define BANK1_ROM_PATCH_SIZE 0x00000000 //0K Bytes
+#define BANK1_UPPERSTACK_ADDR 0x00000000
+#define BANK1_UPPERSTACK_SIZE 0x00000000 //0K Bytes
+#define BANK1_APP_ADDR 0x00000000
+#define BANK1_APP_SIZE 0x00000000 //0K Bytes
+#define BANK1_APP_DATA1_ADDR 0x00000000
+#define BANK1_APP_DATA1_SIZE 0x00000000 //0K Bytes
+#define BANK1_APP_DATA2_ADDR 0x00000000
+#define BANK1_APP_DATA2_SIZE 0x00000000 //0K Bytes
+#define BANK1_APP_DATA3_ADDR 0x00000000
+#define BANK1_APP_DATA3_SIZE 0x00000000 //0K Bytes
+#define BANK1_APP_DATA4_ADDR 0x00000000
+#define BANK1_APP_DATA4_SIZE 0x00000000 //0K Bytes
+#define BANK1_APP_DATA5_ADDR 0x00000000
+#define BANK1_APP_DATA5_SIZE 0x00000000 //0K Bytes
+#define BANK1_APP_DATA6_ADDR 0x00000000
+#define BANK1_APP_DATA6_SIZE 0x00000000 //0K Bytes
+
+
+#ifdef __cplusplus
+}
+#endif
+/** @} */ /* _FLASH_MAP_H_ */
+#endif
diff --git a/board/evb/google_rcu/gcc/Makefile b/board/evb/google_rcu/gcc/Makefile
new file mode 100644
index 0000000..673ad30
--- /dev/null
+++ b/board/evb/google_rcu/gcc/Makefile
@@ -0,0 +1,293 @@
+##########################################################################################################################
+# File automatically-generated by tool: [projectgenerator] version: [3.5.2] date: [Fri Nov 29 15:56:19 CST 2019]
+##########################################################################################################################
+# ------------------------------------------------
+# Generic Makefile (based on gcc)
+#
+# ChangeLog :
+# 2019-02-01 - first version
+# ------------------------------------------------
+######################################
+# target
+######################################
+TARGET = google_rcu
+ENCRYPTION = 0
+######################################
+# building variables
+######################################
+# debug build?
+DEBUG = 0
+# optimization
+#OPT = -Og
+OPT = -O1
+#######################################
+# paths
+#######################################
+# Build path
+BUILD_DIR = build
+BIN_DIR = bin
+######################################
+# source
+######################################
+# C sources
+C_SOURCES = \
+../../../../src/app/google_rcu/profile_module/hids_rmc.c \
+../../../../src/mcu/rtl876x/system_rtl876x.c \
+../../../../src/mcu/peripheral/rtl876x_io_dlps.c \
+../../../../src/mcu/peripheral/rtl876x_gpio.c \
+../../../../src/mcu/peripheral/rtl876x_ir.c \
+../../../../src/mcu/peripheral/rtl876x_keyscan.c \
+../../../../src/mcu/peripheral/rtl876x_rtc.c \
+../../../../src/mcu/peripheral/rtl876x_codec.c \
+../../../../src/mcu/peripheral/rtl876x_i2s.c \
+../../../../src/mcu/peripheral/rtl876x_pinmux.c \
+../../../../src/mcu/peripheral/rtl876x_nvic.c \
+../../../../src/mcu/peripheral/rtl876x_rcc.c \
+../../../../src/mcu/peripheral/rtl876x_tim.c \
+../../../../src/mcu/peripheral/rtl876x_gdma.c \
+../../../../src/mcu/peripheral/rtl876x_uart.c \
+../../../../src/mcu/peripheral/rtl876x_adc.c \
+../../../../src/mcu/peripheral/rtl876x_lpc.c \
+../../../../src/mcu/peripheral/rtl876x_aon_wdg.c \
+../../../../src/ble/profile/server/dis.c \
+../../../../src/ble/profile/server/bas.c \
+../../../../src/ble/profile/server/vendor_service.c \
+../../../../src/ble/profile/server/voice_service.c \
+../../../../src/ble/profile/server/atvv_service.c \
+../../../../src/app/google_rcu/profile_module/ir_service.c \
+../../../../src/app/google_rcu/profile_module/dfu_service.c \
+../../../../src/app/google_rcu/profile_module/ota_service.c \
+../../../../src/app/google_rcu/profile_module/fms.c \
+../../../../src/app/google_rcu/main.c \
+../../../../src/app/google_rcu/rcu_application.c \
+../../../../src/app/google_rcu/rcu_gap.c \
+../../../../src/app/google_rcu/swtimer.c \
+../../../../src/app/google_rcu/app_task.c \
+../../../../src/app/google_rcu/reset_watch_dog_timer.c \
+../../../../src/ble/privacy/privacy_mgnt.c \
+../../../../src/mcu/rtl876x/overlay_mgr.c \
+../../../../src/app/google_rcu/loop_queue.c \
+../../../../src/app/google_rcu/rtc_module/rtc_driver.c \
+../../../../src/dfu/dfu_main.c \
+../../../../src/dfu/dfu_task.c \
+../../../../src/dfu/dfu_application.c \
+../../../../src/platform/dfu_flash.c \
+../../../../src/app/google_rcu/key_module/keyscan_driver.c \
+../../../../src/app/google_rcu/key_module/key_handle.c \
+../../../../src/app/google_rcu/voice_module/voice_driver.c \
+../../../../src/app/google_rcu/voice_module/voice.c \
+../../../../src/app/google_rcu/ir_module/ir_send_driver.c \
+../../../../src/app/google_rcu/ir_module/ir_send_handle.c \
+../../../../src/app/google_rcu/ir_module/ir_protocol_nec.c \
+../../../../src/app/google_rcu/ir_module/ir_service_handle.c \
+../../../../src/app/google_rcu/led_module/led_driver.c \
+../../../../src/app/google_rcu/led_module/led_pwm_driver.c \
+../../../../src/app/google_rcu/buzzer_module/buzzer_driver.c \
+../../../../src/app/google_rcu/buzzer_module/fms_service_handle.c \
+../../../../src/app/google_rcu/bat_module/battery_driver.c \
+../../../../src/app/google_rcu/test_module/data_uart_test.c \
+../../../../src/app/google_rcu/test_module/mp_test.c \
+../../../../src/app/google_rcu/test_module/single_tone.c \
+../../../../src/app/google_rcu/test_module/uart_transport.c \
+../../../../src/app/google_rcu/frm_vpk/src/app_flash_write.c \
+../../../../src/app/google_rcu/frm_vpk/src/app_custom.c \
+../../../../src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_hal_sflash.c \
+../../../../src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_log.c \
+../../../../src/app/google_rcu/dtm_module/rcu_dtm_app.c \
+../../../../src/app/google_rcu/address_module/rcu_link_mgr.c \
+# sources END
+# ASM sources
+ASM_SOURCES = ../../../../src/mcu/rtl876x/arm/startup_rtl876x_gcc.s
+#startup_rtl8762c_ARMCC.s
+#######################################
+# binaries
+#######################################
+PREFIX = arm-none-eabi-
+# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx)
+# either it can be added to the PATH environment variable.
+ifdef GCC_PATH
+CC = $(GCC_PATH)/$(PREFIX)gcc
+AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
+CP = $(GCC_PATH)/$(PREFIX)objcopy
+SZ = $(GCC_PATH)/$(PREFIX)size
+else
+CC = $(PREFIX)gcc
+AS = $(PREFIX)gcc -x assembler-with-cpp
+CP = $(PREFIX)objcopy
+SZ = $(PREFIX)size
+OD = $(PREFIX)objdump
+endif
+HEX = $(CP) -O ihex
+BIN = $(CP) -O binary -S
+#######################################
+# CFLAGS
+#######################################
+# cpu
+CPU = -mcpu=cortex-m0plus
+
+# fpu
+FPU =
+
+# float-abi
+#FLOAT-ABI = -mfloat-abi=hard
+FLOAT-ABI = -mfloat-abi=soft
+
+# mcu
+MCU = $(CPU) -mthumb $(FLOAT-ABI)
+
+# macros for gcc
+# AS defines
+AS_DEFS =
+
+# C defines
+C_DEFS =
+
+
+# AS includes
+AS_INCLUDES = \
+
+# C includes
+
+C_INCLUDES = \
+-I../../../../bin/upperstack_img/upperstack_0_0 \
+-I../../google_rcu \
+-I../../../../src/app/google_rcu \
+-I../../../../src/app/google_rcu/bat_module \
+-I../../../../src/app/google_rcu/ir_module \
+-I../../../../src/app/google_rcu/key_module \
+-I../../../../src/app/google_rcu/led_module \
+-I../../../../src/app/google_rcu/voice_module \
+-I../../../../src/app/google_rcu/test_module \
+-I../../../../src/app/google_rcu/rtc_module \
+-I../../../../src/app/google_rcu/buzzer_module \
+-I../../../../src/app/google_rcu/opus \
+-I../../../../src/app/google_rcu/profile_module \
+-I../../../../src/ble \
+-I../../../../src/ble/privacy \
+-I../../../../src/dfu \
+-I../../../../inc/app \
+-I../../../../inc/bluetooth/gap \
+-I../../../../inc/bluetooth/gap/gap_lib \
+-I../../../../inc/bluetooth/profile \
+-I../../../../inc/bluetooth/profile/server \
+-I../../../../inc/platform \
+-I../../../../inc/peripheral \
+-I../../../../inc/os \
+-I../../../../inc/rcu \
+-I../../../../inc/rcu/opus_inc \
+-I../../../../../bluetooth/crypto \
+-I../../../../../patch/inc \
+-I../../../../src/app/google_rcu/frm_vpk/src \
+-I../../../../src/app/google_rcu/frm_vpk/frm_vpk_api \
+-I../../../../src/app/google_rcu/frm_vpk \
+-I../../../../src/app/google_rcu/dtm_module \
+-I../../../../src/app/google_rcu/address_module \
+# includes END
+#C_PRE_INCLUDES
+
+PER_INCLUDE= \
+#PRE_INCLUDES END
+
+#C_PER_DEFINE
+
+PER_DEFINE= \
+-D SUPPORT_ALONE_UPPERSTACK_IMG \
+#PER_DEFINE END
+
+# compile gcc flags
+ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
+
+CFLAGS = $(MCU) -specs=nano.specs $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
+
+ifeq ($(DEBUG), 1)
+CFLAGS += -g -gdwarf-2
+endif
+
+CFLAGS += -std=c99
+# Generate dependency information
+CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
+# perinclude
+ifneq ($(PER_INCLUDE), )
+CFLAGS +=$(PER_INCLUDE)
+endif
+ifneq ($(PER_DEFINE), )
+CFLAGS +=$(PER_DEFINE)
+endif
+#######################################
+# LDFLAGS
+#######################################
+# link script
+ifeq ($(ENCRYPTION),0)
+ LDSCRIPT = app.ld
+else
+ LDSCRIPT = app-ENCRYPTION.ld
+endif
+
+
+LIBS = -lc -lm -lnosys
+# libraries
+
+LIBDIR = \
+../../../../bin/gcc/rom_symbol_gcc.axf \
+../../../../bin/gcc/gap_utils.a \
+../../../../bin/gcc/adc.a \
+../../../../bin/gcc/ima_adpcm_lib.a \
+../../../../bin/gcc/bee3_sdk.a \
+# lib_end
+
+LDFLAGS = $(MCU) -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections -specs=nano.specs
+
+# default action: build all
+.PHONY : all
+all:mem_define.ld $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex
+ -mkdir bin
+ ../../../../tool/hex2bin/Hex2Bin build/$(TARGET).hex bin/$(TARGET).bin
+ ../../../../tool/prepend_header/prepend_header -t app_code -p bin/$(TARGET).bin -m 1 -i ../mp.ini -c sha256 -a ../../../../tool/key.json
+ ../../../../tool/md5/md5 bin/$(TARGET)_MP.bin
+ $(OD) -D -S build/$(TARGET).elf > bin/$(TARGET).dis
+# $(CC) -o all $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
+mem_define.ld :
+ ../../../../tool/memory_icf/MemDefine ../ gcc ./
+
+#######################################
+# build the application
+#######################################
+# list of objects
+OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
+#vpath %.c $(sort $(dir $(C_SOURCES)))
+vpath %.c $(dir $(C_SOURCES))
+# list of ASM program objects
+OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
+vpath %.s $(sort $(dir $(ASM_SOURCES)))
+$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
+ $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
+
+$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
+ $(AS) -c $(CFLAGS) $< -o $@
+
+$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
+ $(CC) $(OBJECTS) $(LDFLAGS) -o $@
+ $(SZ) $@
+
+$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
+ $(HEX) $< $@
+
+$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
+ $(BIN) $< $@
+
+$(BUILD_DIR):
+ mkdir $@
+
+#######################################
+# clean up
+#######################################
+clean:
+ -rm -fR $(BUILD_DIR)
+ -rm -fR $(BIN_DIR)
+ -rm mem_define.ld
+#######################################
+# dependencies
+#######################################
+-include $(wildcard $(BUILD_DIR)/*.d)
+
+# *** EOF *** \ No newline at end of file
diff --git a/board/evb/google_rcu/gcc/app.ld b/board/evb/google_rcu/gcc/app.ld
new file mode 100644
index 0000000..132b25e
--- /dev/null
+++ b/board/evb/google_rcu/gcc/app.ld
@@ -0,0 +1,105 @@
+/* Entry Point */
+ENTRY(Reset_Handler)
+INPUT(mem_define.ld)
+
+MEMORY
+{
+APP_DATA_ON (rwx) : ORIGIN = 0x00207C00, LENGTH = APP_GLOBAL_SIZE
+HEAP_DATA_ON (rwx) : ORIGIN = (0x00207C00 + APP_GLOBAL_SIZE) , LENGTH = (65*1024) - APP_GLOBAL_SIZE
+CACHE_DATA_ON (rwx) : ORIGIN = 0x0021C000, LENGTH = SHARE_CACHE_RAM_SIZE
+APP_FLASH (r) : ORIGIN = APP_ADDR, LENGTH = APP_SIZE
+APP_TRACE (r): ORIGIN = 0x08800000, LENGTH = 4096k
+}
+
+/* Define output sections */
+SECTIONS
+{
+ . = APP_ADDR;
+ app.bin APP_ADDR :
+ {
+ KEEP(* (.app.flash.header))
+ KEEP(* (.app.flash.header.auth))
+ }AT > APP_FLASH
+ APP_FLASH_HEADER_EXT :
+ {
+ KEEP(* (.app.flash.header_ext))
+ }AT > APP_FLASH
+
+ FLASH_START_ADDR :
+ {
+ build/startup_rtl876x_gcc.o(RESET)
+ . = ALIGN(4);
+ __flash_start_load_ad__ = LOADADDR(FLASH_START_ADDR);
+ __flash_start_exe_ad__ = ADDR(FLASH_START_ADDR);
+ }AT > APP_FLASH
+
+ FLASH_TEXT :
+ {
+ *(.text*)
+ . = ALIGN(4);
+ *(.rodata*)
+ . = ALIGN(4);
+ *(.app.flash.text)
+ *(.app.flash.rodata)
+ }AT > APP_FLASH
+ RAM_VECTOR_TABLE 0x00200000:
+ {
+ __ram_vector_table_start__ = .;
+ KEEP(*(VECTOR))
+ __ram_vector_table_end__ = .;
+ }AT > APP_FLASH
+ __ram_vector_load_ad__ = LOADADDR(RAM_VECTOR_TABLE);
+ __ram_vector_table_length__ = __ram_vector_table_end__ - __ram_vector_table_start__;
+ RAM_DATA_ON :
+ {
+ __ram_dataon_ro_start__ = .;
+ * (.app.data_ram.text)
+ . = ALIGN(4);
+ __ram_dataon_ro_end__ = .;
+ __ram_dataon_rw_start__ = .;
+ *(.data*)
+ * (.ram.dataon.data)
+ __ram_dataon_rw_end__ = .;
+ . = ALIGN(4);
+ } > APP_DATA_ON AT > APP_FLASH
+ BSS (NOLOAD):
+ {
+ . = ALIGN(4);
+ __ram_dataon_zi_start__ = .;
+ * (.ram.dataon.bss*)
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(4);
+ __ram_dataon_zi_end__ = .;
+ } > APP_DATA_ON AT > APP_FLASH
+ __ram_ro_load_ad__ = LOADADDR(RAM_DATA_ON);
+ __ram_dataon_ro_length__ = __ram_dataon_ro_end__ - __ram_dataon_ro_start__;
+ __ram_dataon_rw_length__ = __ram_dataon_rw_end__ - __ram_dataon_rw_start__;
+ __ram_dataon_zi_length__ = __ram_dataon_zi_end__ - __ram_dataon_zi_start__;
+ __ram_rw_load_ad__ = LOADADDR(RAM_DATA_ON)+__ram_dataon_ro_length__;
+ HEAP_DATA_ON :
+ {
+ __heap_start__ = .;
+ end = __heap_start__;
+ _end = end;
+ __end = end;
+ KEEP(*(.heap))
+ __heap_end__ = .;
+ __HeapLimit = __heap_end__;
+ } > HEAP_DATA_ON AT > APP_FLASH
+
+ CACHE_DATA_ON (OVERLAY):
+ {
+ __cache_dataon_start__ = . ;
+ *(.ram.sharecacheram.text)
+ __cache_dataon_end__ = .;
+ }>CACHE_DATA_ON AT> APP_FLASH
+ __cache_dataon_length__ = __cache_dataon_end__ - __cache_dataon_start__;
+ __cache_data_load_ad__ = LOADADDR(RAM_DATA_ON);
+ App.trace 0x08800000:
+ {
+ *(.TRACE*)
+ }>APP_TRACE
+
+}
+
diff --git a/board/evb/google_rcu/gcc/mem_define.ld b/board/evb/google_rcu/gcc/mem_define.ld
new file mode 100644
index 0000000..855f6be
--- /dev/null
+++ b/board/evb/google_rcu/gcc/mem_define.ld
@@ -0,0 +1,6 @@
+APP_ADDR = 0x832000;
+APP_SIZE = 0x19000;
+APP_GLOBAL_SIZE = 0x5000;
+APP_GLOBAL_ADDR = 0x207c00;
+UPPERSTACK_GLOBAL_SIZE = 0x800;
+SHARE_CACHE_RAM_SIZE = 0x0;
diff --git a/board/evb/google_rcu/mdk/Listings/app.map b/board/evb/google_rcu/mdk/Listings/app.map
new file mode 100644
index 0000000..47c0aaf
--- /dev/null
+++ b/board/evb/google_rcu/mdk/Listings/app.map
@@ -0,0 +1,4851 @@
+Component: ARM Compiler 5.06 update 7 (build 960) Tool: armlink [4d3601]
+
+==============================================================================
+
+Section Cross References
+
+ startup_rtl876x.o(VECTOR) refers to startup_rtl876x.o(RESET) for Reset_Handler
+ startup_rtl876x.o(VECTOR) refers to startup_rtl876x.o(.text) for NMI_Handler
+ startup_rtl876x.o(VECTOR) refers to main.o(.app.data_ram.text) for System_Handler
+ startup_rtl876x.o(VECTOR) refers to rcu_dtm_app.o(.text) for UART0_Handler
+ startup_rtl876x.o(VECTOR) refers to rtc_driver.o(.app.data_ram.text) for RTC_Handler
+ startup_rtl876x.o(VECTOR) refers to voice_driver.o(.app.data_ram.text) for GDMA0_Channel0_Handler
+ startup_rtl876x.o(VECTOR) refers to ir_send_driver.o(.app.data_ram.text) for GDMA0_Channel1_Handler
+ startup_rtl876x.o(VECTOR) refers to system_rtl876x.o(.app.data_ram.text) for GPIO_Group3_Handler
+ startup_rtl876x.o(VECTOR) refers to reset_watch_dog_timer.o(.app.data_ram.text) for Timer5_Handler
+ startup_rtl876x.o(VECTOR) refers to keyscan_driver.o(.app.data_ram.text) for Keyscan_Handler
+ startup_rtl876x.o(RESET) refers to system_rtl876x.o(.app.flash.text) for SystemInit
+ system_rtl876x.o(.app.data_ram.text) refers to startup_rtl876x.o(.text) for GPIO3_Handler
+ system_rtl876x.o(.app.flash.text) refers to overlay_mgr.o(.text) for load_overlay
+ system_rtl876x.o(.app.flash.text) refers to system_rtl876x.o(.app.overlay_a) for AppUpdateVectorTable
+ system_rtl876x.o(.app.flash.text) refers to system_rtl876x.o(.bss) for user_wdg_cb
+ system_rtl876x.o(.app.flash.text) refers to system_rtl876x.o(.TRACE) for .TRACE
+ system_rtl876x.o(.app.flash.text) refers to main.o(.data) for app_pre_main_cb
+ system_rtl876x.o(.app.flash.text) refers to system_rtl876x.o(.text) for common_main
+ system_rtl876x.o(.app.overlay_a) refers to system_rtl876x.o(.constdata) for .constdata
+ system_rtl876x.o(.app.overlay_a) refers to startup_rtl876x.o(.text) for Default_Handler
+ system_rtl876x.o(.app.overlay_a) refers to system_rtl876x.o(.TRACE) for .TRACE
+ system_rtl876x.o(.text) refers to aeabi_sdiv.o(.text) for __aeabi_uidivmod
+ system_rtl876x.o(.text) refers to __main.o(!!!main) for __main
+ system_rtl876x.o(.text) refers to system_rtl876x.o(.bss) for .bss
+ system_rtl876x.o(.text) refers to system_rtl876x.o(.constdata) for .constdata
+ system_rtl876x.o(.app.flash.header) refers to system_rtl876x.o(.constdata) for app_cb_table
+ system_rtl876x.o(.constdata) refers to system_rtl876x.o(.conststring) for .conststring
+ rtl876x_io_dlps.o(.app.data_ram.text) refers to rtl876x_pinmux.o(.text) for Pad_Config
+ rtl876x_io_dlps.o(.app.data_ram.text) refers to rtl876x_nvic.o(.text) for NVIC_Init
+ rtl876x_io_dlps.o(.app.data_ram.text) refers to rtl876x_io_dlps.o(.bss) for .bss
+ rtl876x_io_dlps.o(.app.data_ram.text) refers to rtl876x_io_dlps.o(.TRACE) for .TRACE
+ rtl876x_io_dlps.o(.text) refers to rtl876x_io_dlps.o(.app.data_ram.text) for DLPS_IO_EnterDlpsCb
+ rtl876x_gpio.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ rtl876x_ir.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ rtl876x_ir.o(.text) refers to aeabi_sdiv.o(.text) for __aeabi_uidivmod
+ rtl876x_ir.o(.text) refers to f2d.o(.text) for __aeabi_f2d
+ rtl876x_ir.o(.text) refers to dflti.o(.text) for __aeabi_ui2d
+ rtl876x_ir.o(.text) refers to daddsub.o(.text) for __aeabi_dadd
+ rtl876x_ir.o(.text) refers to ddiv.o(.text) for __aeabi_ddiv
+ rtl876x_ir.o(.text) refers to dfixui.o(.text) for __aeabi_d2uiz
+ rtl876x_keyscan.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ rtl876x_rtc.o(.text) refers to rtl876x_rtc.o(.bss) for .bss
+ rtl876x_codec.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ rtl876x_i2s.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ rtl876x_pinmux.o(.text) refers to rtl876x_pinmux.o(.constdata) for .constdata
+ rtl876x_tim.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ rtl876x_tim.o(.text) refers to aeabi_sdiv.o(.text) for __aeabi_uidivmod
+ rtl876x_gdma.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ rtl876x_uart.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ rtl876x_adc.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ rtl876x_lpc.o(.text) refers to rtl876x_lpc.o(.bss) for .bss
+ rtl876x_aon_wdg.o(.text) refers to rtl876x_aon_wdg.o(.bss) for .bss
+ dis.o(.text) refers to dis.o(i.__ARM_common_switch8) for __ARM_common_switch8
+ dis.o(.text) refers to gap_lib_system_call.o(.text) for server_add_service
+ dis.o(.text) refers to dis.o(.bss) for .bss
+ dis.o(.text) refers to dis.o(.TRACE) for .TRACE
+ dis.o(.text) refers to dis.o(.data) for .data
+ dis.o(.text) refers to dis.o(.constdata) for .constdata
+ dis.o(.constdata) refers to dis.o(.text) for dis_attr_read_cb
+ bas.o(.text) refers to gap_lib_system_call.o(.text) for server_send_data
+ bas.o(.text) refers to bas.o(.TRACE) for .TRACE
+ bas.o(.text) refers to bas.o(.bss) for .bss
+ bas.o(.text) refers to bas.o(.constdata) for .constdata
+ bas.o(.constdata) refers to bas.o(.text) for bas_attr_read_cb
+ hids_rmc.o(.text) refers to gap_lib_system_call.o(.text) for server_add_service
+ hids_rmc.o(.text) refers to hids_rmc.o(.bss) for .bss
+ hids_rmc.o(.text) refers to hids_rmc.o(.data) for .data
+ hids_rmc.o(.text) refers to hids_rmc.o(.TRACE) for .TRACE
+ hids_rmc.o(.text) refers to hids_rmc.o(.constdata) for .constdata
+ hids_rmc.o(.constdata) refers to hids_rmc.o(.text) for hids_attr_read_cb
+ vendor_service.o(.text) refers to gap_lib_system_call.o(.text) for server_add_service
+ vendor_service.o(.text) refers to vendor_service.o(.TRACE) for .TRACE
+ vendor_service.o(.text) refers to vendor_service.o(.bss) for .bss
+ vendor_service.o(.text) refers to vendor_service.o(.constdata) for .constdata
+ vendor_service.o(.constdata) refers to vendor_service.o(.constdata) for GATT_UUID_VENDOR_SERVICE
+ vendor_service.o(.constdata) refers to vendor_service.o(.text) for vendor_svc_attr_write_cb
+ voice_service.o(.text) refers to gap_lib_system_call.o(.text) for server_add_service
+ voice_service.o(.text) refers to voice_service.o(.TRACE) for .TRACE
+ voice_service.o(.text) refers to voice_service.o(.bss) for .bss
+ voice_service.o(.text) refers to voice_service.o(.constdata) for .constdata
+ voice_service.o(.constdata) refers to voice_service.o(.constdata) for GATT_UUID128_VOICE_SRV
+ voice_service.o(.constdata) refers to voice_service.o(.text) for voice_attr_read_cb
+ atvv_service.o(.text) refers to gap_lib_system_call.o(.text) for server_add_service
+ atvv_service.o(.text) refers to atvv_service.o(.TRACE) for .TRACE
+ atvv_service.o(.text) refers to atvv_service.o(.bss) for .bss
+ atvv_service.o(.text) refers to atvv_service.o(.constdata) for .constdata
+ atvv_service.o(.constdata) refers to atvv_service.o(.constdata) for GATT_UUID_ATVV_SERVICE
+ atvv_service.o(.constdata) refers to atvv_service.o(.text) for attv_attr_read_cb
+ ir_service.o(.text) refers to gap_lib_system_call.o(.text) for server_add_service
+ ir_service.o(.text) refers to ir_service.o(.TRACE) for .TRACE
+ ir_service.o(.text) refers to ir_service.o(.bss) for .bss
+ ir_service.o(.text) refers to ir_service.o(.constdata) for .constdata
+ ir_service.o(.constdata) refers to ir_service.o(.constdata) for GATT_UUID_IR_SERVICE
+ ir_service.o(.constdata) refers to ir_service.o(.text) for ir_svc_attr_write_cb
+ dfu_service.o(.text) refers to dfu_flash.o(.text) for dfu_check_buf_crc
+ dfu_service.o(.text) refers to gap_lib_system_call.o(.text) for server_send_data
+ dfu_service.o(.text) refers to dfu_service.o(.bss) for .bss
+ dfu_service.o(.text) refers to dfu_service.o(.TRACE) for .TRACE
+ dfu_service.o(.text) refers to dis.o(i.__ARM_common_switch8) for __ARM_common_switch8
+ dfu_service.o(.text) refers to dfu_service.o(.conststring) for .conststring
+ dfu_service.o(.text) refers to dfu_service.o(.constdata) for .constdata
+ dfu_service.o(.text) refers to dfu_service.o(.data) for .data
+ dfu_service.o(.constdata) refers to dfu_service.o(.text) for dfu_attr_write_cb
+ dfu_service.o(.data) refers to dfu_service.o(.constdata) for SILENCE_GATT_UUID128_DFU_SERVICE
+ ota_service.o(.text) refers to gap_lib_system_call.o(.text) for gap_get_param
+ ota_service.o(.text) refers to rcu_application.o(.text) for app_set_latency_status
+ ota_service.o(.text) refers to ota_service.o(.bss) for .bss
+ ota_service.o(.text) refers to ota_service.o(.TRACE) for .TRACE
+ ota_service.o(.text) refers to swtimer.o(.bss) for temp_off_latency_timer
+ ota_service.o(.text) refers to ota_service.o(.constdata) for .constdata
+ ota_service.o(.constdata) refers to ota_service.o(.constdata) for GATT_UUID_OTA_SERVICE
+ ota_service.o(.constdata) refers to ota_service.o(.text) for ota_attr_read_cb
+ fms.o(.text) refers to fms_service_handle.o(.text) for fms_handle_get_current_mode
+ fms.o(.text) refers to gap_lib_system_call.o(.text) for server_add_service
+ fms.o(.text) refers to fms.o(.TRACE) for .TRACE
+ fms.o(.text) refers to fms.o(.bss) for .bss
+ fms.o(.text) refers to fms.o(.constdata) for .constdata
+ fms.o(.constdata) refers to fms.o(.constdata) for GATT_UUID_FMS_SERVICE
+ fms.o(.constdata) refers to fms.o(.text) for fms_attr_read_cb
+ main.o(.app.data_ram.text) refers to keyscan_driver.o(.app.data_ram.text) for keyscan_enter_dlps_config
+ main.o(.app.data_ram.text) refers to battery_driver.o(.app.data_ram.text) for bat_enter_dlps_config
+ main.o(.app.data_ram.text) refers to ir_send_driver.o(.app.data_ram.text) for ir_send_enter_dlps_config
+ main.o(.app.data_ram.text) refers to rtl876x_aon_wdg.o(.text) for AON_WDG_Enable
+ main.o(.app.data_ram.text) refers to voice_driver.o(.app.data_ram.text) for voice_driver_dlps_check
+ main.o(.app.data_ram.text) refers to led_driver.o(.text) for led_driver_dlps_check
+ main.o(.app.data_ram.text) refers to rtl876x_pinmux.o(.text) for System_DebounceWakeupStatus
+ main.o(.app.data_ram.text) refers to rcu_application.o(.bss) for app_global_data
+ main.o(.app.data_ram.text) refers to main.o(.TRACE) for .TRACE
+ main.o(.app.data_ram.text) refers to keyscan_driver.o(.bss) for keyscan_global_data
+ main.o(.text) refers to rcu_application.o(.text) for app_init_global_data
+ main.o(.text) refers to key_handle.o(.text) for key_handle_init_data
+ main.o(.text) refers to keyscan_driver.o(.app.data_ram.text) for keyscan_init_data
+ main.o(.text) refers to app_custom.o(.text) for app_custom_init
+ main.o(.text) refers to rcu_gap.o(.text) for rcu_update_adv_rsp_data
+ main.o(.text) refers to ir_service_handle.o(.text) for ir_service_handle_init_data
+ main.o(.text) refers to voice_driver.o(.text) for voice_driver_init_data
+ main.o(.text) refers to voice.o(.text) for voice_handle_atvv_init_data
+ main.o(.text) refers to battery_driver.o(.text) for bat_init_data
+ main.o(.text) refers to fms_service_handle.o(.text) for fms_handle_init_data
+ main.o(.text) refers to rcu_dtm_app.o(.text) for gpio_dtm_pad_config
+ main.o(.text) refers to rtl876x_gpio.o(.text) for GPIO_GetPin
+ main.o(.text) refers to keyscan_driver.o(.text) for keyscan_nvic_config
+ main.o(.text) refers to rtc_driver.o(.text) for rtc_driver_init
+ main.o(.text) refers to rand.o(.text) for srand
+ main.o(.text) refers to gap_lib_system_call.o(.text) for le_register_app_cb
+ main.o(.text) refers to app_task.o(.text) for dtm_task_init
+ main.o(.text) refers to led_driver.o(.text) for led_module_init
+ main.o(.text) refers to buzzer_driver.o(.text) for buzzer_deinit_pad_config
+ main.o(.text) refers to rtl876x_io_dlps.o(.text) for DLPS_IORegister
+ main.o(.text) refers to swtimer.o(.text) for sw_timer_init
+ main.o(.text) refers to bas.o(.text) for bas_add_service
+ main.o(.text) refers to dis.o(.text) for dis_add_service
+ main.o(.text) refers to hids_rmc.o(.text) for hids_add_service
+ main.o(.text) refers to atvv_service.o(.text) for atvv_add_service
+ main.o(.text) refers to ir_service.o(.text) for ir_svc_add_service
+ main.o(.text) refers to ota_service.o(.text) for ota_add_service
+ main.o(.text) refers to dfu_service.o(.text) for dfu_add_service
+ main.o(.text) refers to vendor_service.o(.text) for vendor_svc_add_service
+ main.o(.text) refers to fms.o(.text) for fms_add_service
+ main.o(.text) refers to rcu_application.o(.bss) for app_global_data
+ main.o(.text) refers to main.o(.TRACE) for .TRACE
+ main.o(.text) refers to key_handle.o(.constdata) for KEY_MAPPING_TABLE_G20
+ main.o(.text) refers to key_handle.o(.bss) for key_handle_global_data
+ main.o(.text) refers to system_rtl876x.o(.bss) for random_seed_value
+ main.o(.text) refers to main.o(.app.data_ram.text) for app_dlps_check_cb
+ main.o(.text) refers to rtl876x_io_dlps.o(.bss) for User_IO_EnterDlpsCB
+ main.o(.data) refers to main.o(.text) for set_dfu_config
+ rcu_application.o(.app.data_ram.text) refers to voice.o(.text) for voice_handle_messages
+ rcu_application.o(.app.data_ram.text) refers to ir_service_handle.o(.text) for ir_service_handle_flash_save_event
+ rcu_application.o(.app.data_ram.text) refers to rcu_application.o(.text) for periph_handle_gap_msg
+ rcu_application.o(.app.data_ram.text) refers to led_driver.o(.text) for led_blink_exit
+ rcu_application.o(.app.data_ram.text) refers to key_handle.o(.text) for key_handle_pressed_event
+ rcu_application.o(.app.data_ram.text) refers to ir_send_handle.o(.text) for ir_send_msg_proc
+ rcu_application.o(.app.data_ram.text) refers to battery_driver.o(.text) for bat_msg_handle
+ rcu_application.o(.app.data_ram.text) refers to dfu_service.o(.text) for dfu_service_handle_valid_fw
+ rcu_application.o(.app.data_ram.text) refers to rcu_application.o(.TRACE) for .TRACE
+ rcu_application.o(.app.data_ram.text) refers to key_handle.o(.bss) for key_handle_global_data
+ rcu_application.o(.text) refers to dis.o(i.__ARM_common_switch8) for __ARM_common_switch8
+ rcu_application.o(.text) refers to rcu_gap.o(.text) for rcu_start_adv
+ rcu_application.o(.text) refers to key_handle.o(.text) for key_handle_reset_key_pressed_cache_fifo
+ rcu_application.o(.text) refers to led_driver.o(.text) for led_blink_exit
+ rcu_application.o(.text) refers to dfu_flash.o(.text) for dfu_fw_reboot
+ rcu_application.o(.text) refers to gap_lib_system_call.o(.text) for le_disable_slave_latency
+ rcu_application.o(.text) refers to dis.o(.text) for dis_set_parameter
+ rcu_application.o(.text) refers to battery_driver.o(.text) for bat_update_battery_info
+ rcu_application.o(.text) refers to app_task.o(.app.data_ram.text) for app_send_msg_to_apptask
+ rcu_application.o(.text) refers to rcu_application.o(.bss) for .bss
+ rcu_application.o(.text) refers to rcu_application.o(.TRACE) for .TRACE
+ rcu_application.o(.text) refers to rcu_application.o(.constdata) for .constdata
+ rcu_application.o(.text) refers to swtimer.o(.bss) for temp_off_latency_timer
+ rcu_application.o(.text) refers to privacy_mgnt.o(.text) for privacy_handle_resolv_list
+ rcu_application.o(.text) refers to main.o(.text) for app_nvic_config
+ rcu_application.o(.text) refers to ir_service_handle.o(.text) for ir_service_handle_disconnect_event
+ rcu_application.o(.text) refers to fms_service_handle.o(.text) for fms_handle_disconnect_event
+ rcu_application.o(.text) refers to voice.o(.text) for voice_handle_stop_mic
+ rcu_application.o(.text) refers to voice_driver.o(.bss) for voice_driver_global_data
+ rcu_application.o(.text) refers to voice.o(.bss) for voice_global_data
+ rcu_application.o(.text) refers to key_handle.o(.bss) for notify_key_data_after_reconn_timer
+ rcu_application.o(.text) refers to bas.o(.text) for bas_set_parameter
+ rcu_application.o(.text) refers to vendor_service.o(.bss) for vendor_svc_handshake_values
+ rcu_gap.o(.text) refers to gap_lib_system_call.o(.text) for le_adv_set_param
+ rcu_gap.o(.text) refers to privacy_mgnt.o(.text) for privacy_init
+ rcu_gap.o(.text) refers to dis.o(i.__ARM_common_switch8) for __ARM_common_switch8
+ rcu_gap.o(.text) refers to rcu_application.o(.bss) for app_global_data
+ rcu_gap.o(.text) refers to rcu_gap.o(.data) for .data
+ rcu_gap.o(.text) refers to rcu_gap.o(.bss) for .bss
+ rcu_gap.o(.text) refers to rcu_gap.o(.constdata) for .constdata
+ rcu_gap.o(.text) refers to rcu_application.o(.text) for app_gap_callback
+ rcu_gap.o(.text) refers to rcu_gap.o(.TRACE) for .TRACE
+ rcu_gap.o(.text) refers to app_custom.o(.text) for app_custom_wakeupkey_packet_index
+ rcu_gap.o(.text) refers to battery_driver.o(.text) for bat_get_current_mode
+ rcu_gap.o(.text) refers to swtimer.o(.bss) for adv_change_data_timer
+ rcu_gap.o(.text) refers to led_driver.o(.text) for led_blink_start
+ rcu_gap.o(.text) refers to aeabi_sdiv.o(.text) for __aeabi_uidivmod
+ swtimer.o(.app.data_ram.text) refers to rcu_application.o(.text) for app_set_latency_status
+ swtimer.o(.app.data_ram.text) refers to rcu_gap.o(.text) for rcu_stop_adv
+ swtimer.o(.app.data_ram.text) refers to swtimer.o(.TRACE) for .TRACE
+ swtimer.o(.app.data_ram.text) refers to rcu_application.o(.bss) for app_global_data
+ swtimer.o(.app.data_ram.text) refers to voice_driver.o(.bss) for voice_driver_global_data
+ swtimer.o(.app.data_ram.text) refers to swtimer.o(.bss) for .bss
+ swtimer.o(.text) refers to keyscan_driver.o(.text) for keyscan_init_timer
+ swtimer.o(.text) refers to key_handle.o(.text) for key_handle_init_timer
+ swtimer.o(.text) refers to fms_service_handle.o(.text) for fms_handle_init_timer
+ swtimer.o(.text) refers to swtimer.o(.app.data_ram.text) for back_key_pressed_when_HW_reset_timer_cb
+ swtimer.o(.text) refers to swtimer.o(.bss) for .bss
+ swtimer.o(.text) refers to swtimer.o(.TRACE) for .TRACE
+ app_task.o(.app.data_ram.text) refers to gap_lib_system_call.o(.text) for gap_start_bt_stack
+ app_task.o(.app.data_ram.text) refers to reset_watch_dog_timer.o(.text) for reset_watch_dog_timer_enable
+ app_task.o(.app.data_ram.text) refers to rtl876x_aon_wdg.o(.text) for AON_WDG_Config
+ app_task.o(.app.data_ram.text) refers to rcu_application.o(.app.data_ram.text) for app_handle_io_msg
+ app_task.o(.app.data_ram.text) refers to rcu_dtm_app.o(.text) for dtm_uart_init
+ app_task.o(.app.data_ram.text) refers to app_task.o(.constdata) for .constdata
+ app_task.o(.app.data_ram.text) refers to app_task.o(.bss) for .bss
+ app_task.o(.app.data_ram.text) refers to app_task.o(.TRACE) for .TRACE
+ app_task.o(.text) refers to app_task.o(.app.data_ram.text) for app_main_task
+ app_task.o(.text) refers to app_task.o(.bss) for .bss
+ reset_watch_dog_timer.o(.app.data_ram.text) refers to rtl876x_tim.o(.text) for TIM_Cmd
+ reset_watch_dog_timer.o(.app.data_ram.text) refers to app_task.o(.app.data_ram.text) for app_send_msg_to_apptask
+ reset_watch_dog_timer.o(.app.data_ram.text) refers to reset_watch_dog_timer.o(.TRACE) for .TRACE
+ reset_watch_dog_timer.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ reset_watch_dog_timer.o(.text) refers to rtl876x_tim.o(.text) for TIM_StructInit
+ reset_watch_dog_timer.o(.text) refers to rtl876x_nvic.o(.text) for NVIC_Init
+ privacy_mgnt.o(.text) refers to gap_lib_system_call.o(.text) for le_get_max_le_paired_device_num
+ privacy_mgnt.o(.text) refers to privacy_mgnt.o(.bss) for .bss
+ privacy_mgnt.o(.text) refers to privacy_mgnt.o(.TRACE) for .TRACE
+ privacy_mgnt.o(.text) refers to privacy_mgnt.o(.data) for .data
+ privacy_mgnt.o(.text) refers to dis.o(i.__ARM_common_switch8) for __ARM_common_switch8
+ privacy_mgnt.o(.text) refers to privacy_mgnt.o(.constdata) for .constdata
+ overlay_mgr.o(.text) refers to overlay_mgr.o(.data) for .data
+ overlay_mgr.o(.text) refers to overlay_mgr.o(.bss) for .bss
+ overlay_mgr.o(.data) refers to overlay_mgr.o(.conststring) for .conststring
+ loop_queue.o(.app.data_ram.text) refers to aeabi_sdiv.o(.text) for __aeabi_idivmod
+ loop_queue.o(.text) refers to loop_queue.o(.constdata) for .constdata
+ rcu_dtm_app.o(.text) refers to rtl876x_pinmux.o(.text) for Pinmux_Config
+ rcu_dtm_app.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ rcu_dtm_app.o(.text) refers to rtl876x_uart.o(.text) for UART_StructInit
+ rcu_dtm_app.o(.text) refers to rtl876x_nvic.o(.text) for NVIC_Init
+ rcu_dtm_app.o(.text) refers to gap_lib_system_call.o(.text) for le_dtm_test_end
+ rcu_dtm_app.o(.text) refers to dis.o(i.__ARM_common_switch8) for __ARM_common_switch8
+ rcu_dtm_app.o(.text) refers to rtl876x_gpio.o(.text) for GPIO_StructInit
+ rcu_dtm_app.o(.text) refers to rcu_dtm_app.o(.data) for .data
+ rcu_dtm_app.o(.text) refers to rcu_dtm_app.o(.bss) for .bss
+ rcu_dtm_app.o(.text) refers to rcu_dtm_app.o(.TRACE) for .TRACE
+ rcu_link_mgr.o(.text) refers to gap_lib_system_call.o(.text) for le_gen_rand_addr
+ rcu_link_mgr.o(.text) refers to rcu_link_mgr.o(.bss) for .bss
+ rcu_link_mgr.o(.text) refers to rcu_link_mgr.o(.TRACE) for .TRACE
+ rtc_driver.o(.app.data_ram.text) refers to rtl876x_rtc.o(.text) for RTC_GetINTStatus
+ rtc_driver.o(.app.data_ram.text) refers to rtc_driver.o(.text) for rtc_driver_clear_comp_0
+ rtc_driver.o(.app.data_ram.text) refers to rtc_driver.o(.bss) for .bss
+ rtc_driver.o(.app.data_ram.text) refers to rtc_driver.o(.TRACE) for .TRACE
+ rtc_driver.o(.text) refers to rtl876x_rtc.o(.text) for RTC_DeInit
+ rtc_driver.o(.text) refers to rtl876x_nvic.o(.text) for NVIC_Init
+ rtc_driver.o(.text) refers to llmul.o(.text) for __aeabi_lmul
+ rtc_driver.o(.text) refers to lludiv.o(.text) for __aeabi_uldivmod
+ rtc_driver.o(.text) refers to rtc_driver.o(.TRACE) for .TRACE
+ rtc_driver.o(.text) refers to rtc_driver.o(.bss) for .bss
+ dfu_flash.o(.text) refers to dfu_flash.o(.TRACE) for .TRACE
+ dfu_flash.o(.text) refers to dfu_flash.o(.data) for .data
+ dfu_flash.o(.text) refers to dfu_flash.o(.bss) for .bss
+ keyscan_driver.o(.app.data_ram.text) refers to rtl876x_pinmux.o(.text) for Pad_Config
+ keyscan_driver.o(.app.data_ram.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ keyscan_driver.o(.app.data_ram.text) refers to rtl876x_keyscan.o(.text) for KeyScan_StructInit
+ keyscan_driver.o(.app.data_ram.text) refers to keyscan_driver.o(.text) for keyscan_disable_wakeup_config
+ keyscan_driver.o(.app.data_ram.text) refers to app_task.o(.app.data_ram.text) for app_send_msg_to_apptask
+ keyscan_driver.o(.app.data_ram.text) refers to keyscan_driver.o(.data) for .data
+ keyscan_driver.o(.app.data_ram.text) refers to key_handle.o(.bss) for key_handle_global_data
+ keyscan_driver.o(.app.data_ram.text) refers to keyscan_driver.o(.bss) for .bss
+ keyscan_driver.o(.app.data_ram.text) refers to keyscan_driver.o(.TRACE) for .TRACE
+ keyscan_driver.o(.text) refers to rtl876x_nvic.o(.text) for NVIC_Init
+ keyscan_driver.o(.text) refers to rtl876x_pinmux.o(.text) for Pinmux_Config
+ keyscan_driver.o(.text) refers to key_handle.o(.bss) for key_handle_global_data
+ keyscan_driver.o(.text) refers to keyscan_driver.o(.data) for .data
+ keyscan_driver.o(.text) refers to keyscan_driver.o(.app.data_ram.text) for keyscan_timer_callback
+ keyscan_driver.o(.text) refers to keyscan_driver.o(.bss) for .bss
+ keyscan_driver.o(.text) refers to keyscan_driver.o(.TRACE) for .TRACE
+ key_handle.o(.app.data_ram.text) refers to led_driver.o(.text) for led_blink_exit
+ key_handle.o(.app.data_ram.text) refers to key_handle.o(.text) for key_handle_process_factory_reset_event
+ key_handle.o(.app.data_ram.text) refers to ir_service_handle.o(.text) for ir_service_handle_is_key_suppressed
+ key_handle.o(.app.data_ram.text) refers to key_handle.o(.bss) for .bss
+ key_handle.o(.app.data_ram.text) refers to key_handle.o(.TRACE) for .TRACE
+ key_handle.o(.app.data_ram.text) refers to rcu_application.o(.bss) for app_global_data
+ key_handle.o(.text) refers to gap_lib_system_call.o(.text) for server_send_data
+ key_handle.o(.text) refers to ir_send_driver.o(.text) for ir_send_is_working
+ key_handle.o(.text) refers to ir_send_handle.o(.text) for ir_send_key_release_handle
+ key_handle.o(.text) refers to ir_service_handle.o(.text) for ir_service_handle_notify_ir_key_event
+ key_handle.o(.text) refers to voice.o(.text) for voice_handle_mic_key_released
+ key_handle.o(.text) refers to battery_driver.o(.text) for bat_get_current_mode
+ key_handle.o(.text) refers to rcu_application.o(.text) for app_save_wakeup_key_cnt
+ key_handle.o(.text) refers to led_driver.o(.text) for led_blink_start
+ key_handle.o(.text) refers to key_handle.o(.bss) for .bss
+ key_handle.o(.text) refers to key_handle.o(.TRACE) for .TRACE
+ key_handle.o(.text) refers to rcu_application.o(.bss) for app_global_data
+ key_handle.o(.text) refers to atvv_service.o(.bss) for atvv_global_data
+ key_handle.o(.text) refers to voice_driver.o(.bss) for voice_driver_global_data
+ key_handle.o(.text) refers to swtimer.o(.bss) for system_rest_timer
+ key_handle.o(.text) refers to rcu_gap.o(.text) for rcu_stop_adv
+ key_handle.o(.text) refers to app_custom.o(.text) for app_custom_is_wakeup_key
+ key_handle.o(.text) refers to keyscan_driver.o(.bss) for keyscan_global_data
+ key_handle.o(.text) refers to key_handle.o(.constdata) for .constdata
+ key_handle.o(.text) refers to key_handle.o(.app.data_ram.text) for key_handle_comb_keys_timer_cb
+ key_handle.o(.text) refers to buzzer_driver.o(.text) for buzzer_is_working_check
+ key_handle.o(.text) refers to fms_service_handle.o(.text) for fms_handle_notify_status
+ voice_driver.o(.app.data_ram.text) refers to rtl876x_gdma.o(.text) for GDMA_ClearINTPendingBit
+ voice_driver.o(.app.data_ram.text) refers to app_task.o(.app.data_ram.text) for app_send_msg_to_apptask
+ voice_driver.o(.app.data_ram.text) refers to voice_driver.o(.bss) for .bss
+ voice_driver.o(.app.data_ram.text) refers to voice_driver.o(.TRACE) for .TRACE
+ voice_driver.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ voice_driver.o(.text) refers to rtl876x_gdma.o(.text) for GDMA_StructInit
+ voice_driver.o(.text) refers to rtl876x_nvic.o(.text) for NVIC_Init
+ voice_driver.o(.text) refers to rtl876x_pinmux.o(.text) for Pad_Config
+ voice_driver.o(.text) refers to rtl876x_i2s.o(.text) for I2S_DeInit
+ voice_driver.o(.text) refers to rtl876x_codec.o(.text) for CODEC_DeInit
+ voice_driver.o(.text) refers to voice_driver.o(.bss) for .bss
+ voice_driver.o(.text) refers to voice_driver.o(.TRACE) for .TRACE
+ voice.o(.app.data_ram.text) refers to voice.o(.text) for voice_handle_atvv_mic_open_error
+ voice.o(.app.data_ram.text) refers to rcu_application.o(.text) for app_set_latency_status
+ voice.o(.app.data_ram.text) refers to voice_driver.o(.bss) for voice_driver_global_data
+ voice.o(.app.data_ram.text) refers to voice.o(.TRACE) for .TRACE
+ voice.o(.text) refers to gap_lib_system_call.o(.text) for le_get_gap_param
+ voice.o(.text) refers to loop_queue.o(.app.data_ram.text) for loop_queue_is_empty
+ voice.o(.text) refers to aeabi_sdiv.o(.text) for __aeabi_uidivmod
+ voice.o(.text) refers to led_driver.o(.text) for led_blink_exit
+ voice.o(.text) refers to voice_driver.o(.text) for voice_driver_deinit
+ voice.o(.text) refers to loop_queue.o(.text) for loop_queue_deinit
+ voice.o(.text) refers to rcu_application.o(.text) for app_set_latency_status
+ voice.o(.text) refers to system_rtl876x.o(.text) for malloc
+ voice.o(.text) refers to atvv_service.o(.bss) for atvv_global_data
+ voice.o(.text) refers to voice.o(.bss) for .bss
+ voice.o(.text) refers to voice.o(.TRACE) for .TRACE
+ voice.o(.text) refers to rcu_application.o(.bss) for app_global_data
+ voice.o(.text) refers to voice.o(.constdata) for .constdata
+ voice.o(.text) refers to voice_driver.o(.bss) for voice_driver_global_data
+ voice.o(.text) refers to ima_adpcm_enc.o(.bss) for ima_adpcm_global_state
+ voice.o(.text) refers to key_handle.o(.text) for key_handle_notify_hid_key_event_by_index
+ voice.o(.text) refers to voice.o(.app.data_ram.text) for voice_handle_exception_timer_cb
+ voice.o(.text) refers to swtimer.o(.bss) for temp_off_latency_timer
+ voice.o(.text) refers to ima_adpcm_enc.o(i.ima_adpcm_encode) for ima_adpcm_encode
+ ir_send_driver.o(.app.data_ram.text) refers to rtl876x_ir.o(.text) for IR_GetINTStatus
+ ir_send_driver.o(.app.data_ram.text) refers to app_task.o(.app.data_ram.text) for app_send_msg_to_apptask
+ ir_send_driver.o(.app.data_ram.text) refers to rtl876x_gdma.o(.text) for GDMA_ClearINTPendingBit
+ ir_send_driver.o(.app.data_ram.text) refers to rtl876x_pinmux.o(.text) for Pad_Config
+ ir_send_driver.o(.app.data_ram.text) refers to ir_send_driver.o(.TRACE) for .TRACE
+ ir_send_driver.o(.app.data_ram.text) refers to ir_send_driver.o(.bss) for .bss
+ ir_send_driver.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ ir_send_driver.o(.text) refers to rtl876x_gdma.o(.text) for GDMA_StructInit
+ ir_send_driver.o(.text) refers to rtl876x_nvic.o(.text) for NVIC_Init
+ ir_send_driver.o(.text) refers to rtl876x_ir.o(.text) for IR_Cmd
+ ir_send_driver.o(.text) refers to rtc_driver.o(.text) for rtc_driver_set_comp_0_params
+ ir_send_driver.o(.text) refers to aeabi_sdiv.o(.text) for __aeabi_uidivmod
+ ir_send_driver.o(.text) refers to rtl876x_pinmux.o(.text) for Pad_Config
+ ir_send_driver.o(.text) refers to dis.o(i.__ARM_common_switch8) for __ARM_common_switch8
+ ir_send_driver.o(.text) refers to key_handle.o(.text) for key_handle_get_key_pressed_count
+ ir_send_driver.o(.text) refers to ffixui.o(.text) for __aeabi_f2uiz
+ ir_send_driver.o(.text) refers to ir_send_driver.o(.bss) for .bss
+ ir_send_driver.o(.text) refers to ir_send_driver.o(.TRACE) for .TRACE
+ ir_send_driver.o(.text) refers to ir_send_driver.o(.app.data_ram.text) for ir_send_rtc_handler
+ ir_send_handle.o(.text) refers to ir_protocol_nec.o(.text) for ir_protocol_nec_repeat_code_encode
+ ir_send_handle.o(.text) refers to ir_service_handle.o(.text) for ir_service_handle_get_key_code_by_key_id
+ ir_send_handle.o(.text) refers to fflti.o(.text) for __aeabi_ui2f
+ ir_send_handle.o(.text) refers to fdiv.o(.text) for __aeabi_fdiv
+ ir_send_handle.o(.text) refers to aeabi_sdiv.o(.text) for __aeabi_uidivmod
+ ir_send_handle.o(.text) refers to ir_send_driver.o(.text) for ir_send_get_current_state
+ ir_send_handle.o(.text) refers to key_handle.o(.text) for key_handle_get_ir_key_code_by_index
+ ir_send_handle.o(.text) refers to ir_send_handle.o(.bss) for .bss
+ ir_send_handle.o(.text) refers to ir_send_handle.o(.TRACE) for .TRACE
+ ir_send_handle.o(.text) refers to ir_send_handle.o(.data) for .data
+ ir_protocol_nec.o(.text) refers to fdiv.o(.text) for __aeabi_fdiv
+ ir_protocol_nec.o(.text) refers to ffixui.o(.text) for __aeabi_f2uiz
+ ir_protocol_nec.o(.text) refers to ir_send_driver.o(.text) for ir_send_convert_to_carrier_cycle
+ ir_protocol_nec.o(.text) refers to fflti.o(.text) for __aeabi_ui2f
+ ir_protocol_nec.o(.text) refers to ir_protocol_nec.o(.constdata) for .constdata
+ ir_service_handle.o(.text) refers to key_handle.o(.text) for key_handle_set_key_type_prog_by_id
+ ir_service_handle.o(.text) refers to rcu_application.o(.text) for app_set_latency_status
+ ir_service_handle.o(.text) refers to app_task.o(.app.data_ram.text) for app_send_msg_to_apptask
+ ir_service_handle.o(.text) refers to ir_service_handle.o(.bss) for .bss
+ ir_service_handle.o(.text) refers to ir_service_handle.o(.TRACE) for .TRACE
+ ir_service_handle.o(.text) refers to ir_service_handle.o(.data) for .data
+ ir_service_handle.o(.text) refers to rcu_application.o(.bss) for app_global_data
+ ir_service_handle.o(.text) refers to ir_service_handle.o(.constdata) for .constdata
+ ir_service_handle.o(.text) refers to gap_lib_system_call.o(.text) for server_send_data
+ led_driver.o(.app.data_ram.text) refers to aeabi_sdiv.o(.text) for __aeabi_uidivmod
+ led_driver.o(.app.data_ram.text) refers to led_driver.o(.text) for get_led_brightness_duty
+ led_driver.o(.app.data_ram.text) refers to led_pwm_driver.o(.text) for led_module_pwm_start
+ led_driver.o(.app.data_ram.text) refers to led_driver.o(.bss) for .bss
+ led_driver.o(.app.data_ram.text) refers to led_driver.o(.constdata) for .constdata
+ led_driver.o(.text) refers to led_pwm_driver.o(.text) for led_pwm_init
+ led_driver.o(.text) refers to aeabi_sdiv.o(.text) for __aeabi_uidivmod
+ led_driver.o(.text) refers to led_driver.o(.app.data_ram.text) for led_ctrl_timer_cb
+ led_driver.o(.text) refers to led_driver.o(.constdata) for .constdata
+ led_driver.o(.text) refers to led_driver.o(.bss) for .bss
+ led_driver.o(.text) refers to led_driver.o(.TRACE) for .TRACE
+ led_pwm_driver.o(.text) refers to rtl876x_tim.o(.text) for TIM_Cmd
+ led_pwm_driver.o(.text) refers to rtl876x_pinmux.o(.text) for Pad_Config
+ led_pwm_driver.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ led_pwm_driver.o(.text) refers to led_pwm_driver.o(.bss) for .bss
+ led_pwm_driver.o(.text) refers to led_pwm_driver.o(.constdata) for .constdata
+ buzzer_driver.o(.text) refers to rtl876x_pinmux.o(.text) for Pinmux_Config
+ buzzer_driver.o(.text) refers to rtl876x_tim.o(.text) for TIM_Cmd
+ buzzer_driver.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ buzzer_driver.o(.text) refers to aeabi_sdiv.o(.text) for __aeabi_uidivmod
+ buzzer_driver.o(.text) refers to buzzer_driver.o(.TRACE) for .TRACE
+ buzzer_driver.o(.text) refers to buzzer_driver.o(.bss) for .bss
+ fms_service_handle.o(.app.data_ram.text) refers to rcu_gap.o(.text) for rcu_start_adv
+ fms_service_handle.o(.app.data_ram.text) refers to rcu_application.o(.bss) for app_global_data
+ fms_service_handle.o(.app.data_ram.text) refers to fms_service_handle.o(.bss) for .bss
+ fms_service_handle.o(.text) refers to gap_lib_system_call.o(.text) for server_send_data
+ fms_service_handle.o(.text) refers to buzzer_driver.o(.text) for buzzer_stop_pwm_output
+ fms_service_handle.o(.text) refers to rcu_application.o(.bss) for app_global_data
+ fms_service_handle.o(.text) refers to fms_service_handle.o(.bss) for .bss
+ fms_service_handle.o(.text) refers to fms_service_handle.o(.TRACE) for .TRACE
+ fms_service_handle.o(.text) refers to fms_service_handle.o(.data) for .data
+ fms_service_handle.o(.text) refers to fms_service_handle.o(.app.data_ram.text) for fms_periodical_conn_callback
+ battery_driver.o(.app.data_ram.text) refers to rtl876x_lpc.o(.text) for LPC_GetFlagStatus
+ battery_driver.o(.app.data_ram.text) refers to battery_driver.o(.text) for bat_init_driver
+ battery_driver.o(.text) refers to adc_lib.o(.text) for ADC_GetVoltage
+ battery_driver.o(.text) refers to dflti.o(.text) for __aeabi_ui2d
+ battery_driver.o(.text) refers to dmul.o(.text) for __aeabi_dmul
+ battery_driver.o(.text) refers to fflti.o(.text) for __aeabi_i2f
+ battery_driver.o(.text) refers to fdiv.o(.text) for __aeabi_fdiv
+ battery_driver.o(.text) refers to fmul.o(x$fpl$fmul) for __aeabi_fmul
+ battery_driver.o(.text) refers to f2d.o(.text) for __aeabi_f2d
+ battery_driver.o(.text) refers to daddsub.o(.text) for __aeabi_dadd
+ battery_driver.o(.text) refers to d2f.o(.text) for __aeabi_d2f
+ battery_driver.o(.text) refers to ffixui.o(.text) for __aeabi_f2uiz
+ battery_driver.o(.text) refers to rtl876x_lpc.o(.text) for LPC_StructInit
+ battery_driver.o(.text) refers to rtl876x_nvic.o(.text) for NVIC_Init
+ battery_driver.o(.text) refers to rtl876x_adc.o(.text) for ADC_INTConfig
+ battery_driver.o(.text) refers to app_task.o(.app.data_ram.text) for app_send_msg_to_apptask
+ battery_driver.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd
+ battery_driver.o(.text) refers to rcu_gap.o(.text) for rcu_stop_adv
+ battery_driver.o(.text) refers to aeabi_sdiv.o(.text) for __aeabi_idivmod
+ battery_driver.o(.text) refers to battery_driver.o(.bss) for .bss
+ battery_driver.o(.text) refers to battery_driver.o(.TRACE) for .TRACE
+ battery_driver.o(.text) refers to battery_driver.o(.app.data_ram.text) for bat_lpc_handler
+ battery_driver.o(.text) refers to rcu_application.o(.bss) for app_global_data
+ app_flash_write.o(.text) refers to aeabi_sdiv.o(.text) for __aeabi_uidivmod
+ app_flash_write.o(.text) refers to frm_vpk_hal_sflash.o(.text) for frm_vpk_flash_read_page
+ app_custom.o(.text) refers to frm_vpk_log.o(.app.data_ram.text) for frm_vpk_print
+ app_custom.o(.text) refers to aeabi_sdiv.o(.text) for __aeabi_uidivmod
+ app_custom.o(.text) refers to frm_vpk_hal_sflash.o(.text) for frm_vpk_flash_read_page
+ app_custom.o(.text) refers to rcu_application.o(.bss) for app_global_data
+ app_custom.o(.text) refers to key_handle.o(.bss) for key_handle_global_data
+ app_custom.o(.text) refers to key_handle.o(.constdata) for Kb_Map_devicelayout_Correspend_Index_G20
+ app_custom.o(.text) refers to key_handle.o(.constdata) for Ir_Table_Correspend_Index_G20
+ app_custom.o(.text) refers to key_handle.o(.constdata) for Kb_Map_devicelayout_Correspend_Index_G10
+ app_custom.o(.text) refers to key_handle.o(.constdata) for Ir_Table_Correspend_Index_G10
+ app_custom.o(.text) refers to key_handle.o(.data) for Ir_Override_Table_Index_G10
+ app_custom.o(.text) refers to key_handle.o(.data) for Ir_Override_Table_Index_G20
+ app_custom.o(.text) refers to key_handle.o(.constdata) for KEY_MAPPING_TABLE_G10
+ app_custom.o(.text) refers to key_handle.o(.constdata) for KEY_MAPPING_TABLE_G20
+ app_custom.o(.text) refers to key_handle.o(.constdata) for Wakeup_Map_Correspend_Index_G20
+ app_custom.o(.text) refers to key_handle.o(.constdata) for Wakeup_Map_Correspend_Index_G10
+ app_custom.o(.text) refers to app_custom.o(.data) for .data
+ app_custom.o(.text) refers to app_custom.o(.constdata) for .constdata
+ app_custom.o(.data) refers to app_custom.o(.conststring) for .conststring
+ app_custom.o(.data) refers to app_custom.o(.conststring) for .conststring
+ frm_vpk_hal_sflash.o(.text) refers to frm_vpk_log.o(.app.data_ram.text) for frm_vpk_print
+ frm_vpk_hal_sflash.o(.text) refers to dfu_flash.o(.text) for unlock_flash_bp_all
+ frm_vpk_hal_sflash.o(.text) refers to frm_vpk_hal_sflash.o(.conststring) for .conststring
+ frm_vpk_log.o(.app.data_ram.text) refers to vsprintf.o(.text) for vsprintf
+ frm_vpk_log.o(.app.data_ram.text) refers to frm_vpk_log.o(.TRACE) for .TRACE
+ gap_lib_system_call.o(.text) refers to gap_lib_system_call.o(.bss) for .bss
+ adc_lib.o(.text) refers to fflti.o(.text) for __aeabi_i2f
+ adc_lib.o(.text) refers to fdiv.o(.text) for __aeabi_fdiv
+ adc_lib.o(.text) refers to fmul.o(x$fpl$fmul) for __aeabi_fmul
+ adc_lib.o(.text) refers to faddsub.o(x$fpl$fadd) for __aeabi_fadd
+ adc_lib.o(.text) refers to adc_lib.o(.data) for .data
+ adc_lib.o(.text) refers to adc_lib.o(.bss) for .bss
+ ima_adpcm_enc.o(i.ima_adpcm_encode) refers to ima_adpcm_enc.o(.data) for .data
+ vsprintf.o(.text) refers (Special) to _printf_a.o(.ARM.Collect$$_printf_percent$$00000006) for _printf_a
+ vsprintf.o(.text) refers (Special) to _printf_c.o(.ARM.Collect$$_printf_percent$$00000013) for _printf_c
+ vsprintf.o(.text) refers (Special) to _printf_charcount.o(.text) for _printf_charcount
+ vsprintf.o(.text) refers (Special) to _printf_d.o(.ARM.Collect$$_printf_percent$$00000009) for _printf_d
+ vsprintf.o(.text) refers (Special) to _printf_e.o(.ARM.Collect$$_printf_percent$$00000004) for _printf_e
+ vsprintf.o(.text) refers (Special) to _printf_f.o(.ARM.Collect$$_printf_percent$$00000003) for _printf_f
+ vsprintf.o(.text) refers (Special) to printf1.o(x$fpl$printf1) for _printf_fp_dec
+ vsprintf.o(.text) refers (Special) to printf2.o(x$fpl$printf2) for _printf_fp_hex
+ vsprintf.o(.text) refers (Special) to _printf_g.o(.ARM.Collect$$_printf_percent$$00000005) for _printf_g
+ vsprintf.o(.text) refers (Special) to _printf_i.o(.ARM.Collect$$_printf_percent$$00000008) for _printf_i
+ vsprintf.o(.text) refers (Special) to _printf_dec.o(.text) for _printf_int_dec
+ vsprintf.o(.text) refers (Special) to _printf_l.o(.ARM.Collect$$_printf_percent$$00000012) for _printf_l
+ vsprintf.o(.text) refers (Special) to _printf_lc.o(.ARM.Collect$$_printf_percent$$00000015) for _printf_lc
+ vsprintf.o(.text) refers (Special) to _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007) for _printf_ll
+ vsprintf.o(.text) refers (Special) to _printf_lld.o(.ARM.Collect$$_printf_percent$$0000000E) for _printf_lld
+ vsprintf.o(.text) refers (Special) to _printf_lli.o(.ARM.Collect$$_printf_percent$$0000000D) for _printf_lli
+ vsprintf.o(.text) refers (Special) to _printf_llo.o(.ARM.Collect$$_printf_percent$$00000010) for _printf_llo
+ vsprintf.o(.text) refers (Special) to _printf_llu.o(.ARM.Collect$$_printf_percent$$0000000F) for _printf_llu
+ vsprintf.o(.text) refers (Special) to _printf_llx.o(.ARM.Collect$$_printf_percent$$00000011) for _printf_llx
+ vsprintf.o(.text) refers (Special) to _printf_longlong_dec.o(.text) for _printf_longlong_dec
+ vsprintf.o(.text) refers (Special) to _printf_hex_int_ll_ptr.o(.text) for _printf_longlong_hex
+ vsprintf.o(.text) refers (Special) to _printf_oct_int_ll.o(.text) for _printf_longlong_oct
+ vsprintf.o(.text) refers (Special) to _printf_ls.o(.ARM.Collect$$_printf_percent$$00000016) for _printf_ls
+ vsprintf.o(.text) refers (Special) to _printf_n.o(.ARM.Collect$$_printf_percent$$00000001) for _printf_n
+ vsprintf.o(.text) refers (Special) to _printf_o.o(.ARM.Collect$$_printf_percent$$0000000B) for _printf_o
+ vsprintf.o(.text) refers (Special) to _printf_p.o(.ARM.Collect$$_printf_percent$$00000002) for _printf_p
+ vsprintf.o(.text) refers (Special) to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent
+ vsprintf.o(.text) refers (Special) to _printf_pad.o(.text) for _printf_post_padding
+ vsprintf.o(.text) refers (Special) to _printf_s.o(.ARM.Collect$$_printf_percent$$00000014) for _printf_s
+ vsprintf.o(.text) refers (Special) to _printf_str.o(.text) for _printf_str
+ vsprintf.o(.text) refers (Special) to _printf_truncate.o(.text) for _printf_truncate_signed
+ vsprintf.o(.text) refers (Special) to _printf_u.o(.ARM.Collect$$_printf_percent$$0000000A) for _printf_u
+ vsprintf.o(.text) refers (Special) to _printf_wctomb.o(.text) for _printf_wctomb
+ vsprintf.o(.text) refers (Special) to _printf_x.o(.ARM.Collect$$_printf_percent$$0000000C) for _printf_x
+ vsprintf.o(.text) refers to _printf_char_common.o(.text) for _printf_char_common
+ vsprintf.o(.text) refers to _sputc.o(.text) for _sputc
+ rand.o(.emb_text) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000000D) for __rt_lib_init_rand_2
+ rand.o(.emb_text) refers to rand.o(.text) for _rand_init
+ rand.o(.emb_text) refers to rand.o(.bss) for _random_number_data
+ rand.o(.text) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000000D) for __rt_lib_init_rand_2
+ rand.o(.text) refers to rand.o(.bss) for .bss
+ rand.o(.bss) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000000D) for __rt_lib_init_rand_2
+ __main.o(!!!main) refers to __rtentry.o(.ARM.Collect$$rtentry$$00000000) for __rt_entry
+ d2f.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ daddsub.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ ddiv.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ ddiv.o(.text) refers to ddiv.o(.constdata) for .constdata
+ ddiv.o(.constdata) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ dfixui.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ dflti.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ dmul.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ f2d.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ faddsub.o(x$fpl$fadd) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ faddsub.o(x$fpl$fadd) refers to faddsub.o(x$fpl$fsub) for _fsub1
+ faddsub.o(x$fpl$frsb) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ faddsub.o(x$fpl$frsb) refers to faddsub.o(x$fpl$fsub) for _fsub1
+ faddsub.o(x$fpl$frsb) refers to faddsub.o(x$fpl$fadd) for _fadd1
+ faddsub.o(x$fpl$fsub) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ faddsub.o(x$fpl$fsub) refers to faddsub.o(x$fpl$fadd) for _fadd1
+ fdiv.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ fdiv.o(.text) refers to fdiv.o(.constdata) for .constdata
+ fdiv.o(.constdata) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ ffixui.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ fflti.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ fmul.o(x$fpl$fmul) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry2.o(.ARM.Collect$$rtentry$$0000000A) for __rt_entry_li
+ __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry2.o(.ARM.Collect$$rtentry$$0000000D) for __rt_entry_main
+ __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry2.o(.ARM.Collect$$rtentry$$0000000C) for __rt_entry_postli_1
+ __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry2.o(.ARM.Collect$$rtentry$$00000009) for __rt_entry_postsh_1
+ __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry2.o(.ARM.Collect$$rtentry$$00000002) for __rt_entry_presh_1
+ __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry5.o(.ARM.Collect$$rtentry$$00000005) for __rt_entry_sh
+ aeabi_idiv0_sigfpe.o(.text) refers to rt_div0.o(.text) for __rt_div0
+ aeabi_ldiv0_sigfpe.o(.text) refers to rt_div0.o(.text) for __rt_div0
+ __printf.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent
+ _printf_str.o(.text) refers (Special) to _printf_char.o(.text) for _printf_cs_common
+ _printf_str.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding
+ _printf_str.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_post_padding
+ _printf_dec.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_signed
+ _printf_dec.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_unsigned
+ _printf_dec.o(.text) refers to rtudiv10.o(.text) for __rt_udiv10
+ _printf_dec.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common
+ _printf_char_common.o(.text) refers to __printf_flags_ss_wp.o(.text) for __printf
+ _printf_wctomb.o(.text) refers (Special) to _printf_wchar.o(.text) for _printf_lcs_common
+ _printf_wctomb.o(.text) refers to _wcrtomb.o(.text) for _wcrtomb
+ _printf_wctomb.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding
+ _printf_wctomb.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_post_padding
+ _printf_wctomb.o(.text) refers to _printf_wctomb.o(.constdata) for .constdata
+ _printf_wctomb.o(.constdata) refers (Special) to _printf_wchar.o(.text) for _printf_lcs_common
+ _printf_longlong_dec.o(.text) refers to lludiv10.o(.text) for _ll_udiv10
+ _printf_longlong_dec.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common
+ _printf_oct_ll.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common
+ _printf_oct_int.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_unsigned
+ _printf_oct_int.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common
+ _printf_oct_int_ll.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common
+ _printf_oct_int_ll.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_unsigned
+ _printf_hex_ll.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common
+ _printf_hex_ll.o(.text) refers to _printf_hex_ll.o(.constdata) for .constdata
+ _printf_hex_int.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_unsigned
+ _printf_hex_int.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common
+ _printf_hex_int.o(.text) refers to _printf_hex_int.o(.constdata) for .constdata
+ _printf_hex_int_ll.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common
+ _printf_hex_int_ll.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_unsigned
+ _printf_hex_int_ll.o(.text) refers to _printf_hex_int_ll.o(.constdata) for .constdata
+ _printf_hex_ptr.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common
+ _printf_hex_ptr.o(.text) refers to _printf_hex_ptr.o(.constdata) for .constdata
+ _printf_hex_int_ptr.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common
+ _printf_hex_int_ptr.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_unsigned
+ _printf_hex_int_ptr.o(.text) refers to _printf_hex_int_ptr.o(.constdata) for .constdata
+ _printf_hex_ll_ptr.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common
+ _printf_hex_ll_ptr.o(.text) refers to _printf_hex_ll_ptr.o(.constdata) for .constdata
+ _printf_hex_int_ll_ptr.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common
+ _printf_hex_int_ll_ptr.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_unsigned
+ _printf_hex_int_ll_ptr.o(.text) refers to _printf_hex_int_ll_ptr.o(.constdata) for .constdata
+ __printf_flags.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent
+ __printf_flags.o(.text) refers to __printf_flags.o(.constdata) for .constdata
+ __printf_ss.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent
+ __printf_flags_ss.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent
+ __printf_flags_ss.o(.text) refers to __printf_flags_ss.o(.constdata) for .constdata
+ __printf_wp.o(.text) refers to __printf_wp.o(i._is_digit) for _is_digit
+ __printf_wp.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent
+ __printf_flags_wp.o(.text) refers to __printf_wp.o(i._is_digit) for _is_digit
+ __printf_flags_wp.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent
+ __printf_flags_wp.o(.text) refers to __printf_flags_wp.o(.constdata) for .constdata
+ __printf_ss_wp.o(.text) refers to __printf_wp.o(i._is_digit) for _is_digit
+ __printf_ss_wp.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent
+ __printf_flags_ss_wp.o(.text) refers to __printf_wp.o(i._is_digit) for _is_digit
+ __printf_flags_ss_wp.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent
+ __printf_flags_ss_wp.o(.text) refers to __printf_flags_ss_wp.o(.constdata) for .constdata
+ _printf_c.o(.ARM.Collect$$_printf_percent$$00000013) refers (Weak) to _printf_char.o(.text) for _printf_char
+ _printf_s.o(.ARM.Collect$$_printf_percent$$00000014) refers (Weak) to _printf_char.o(.text) for _printf_string
+ _printf_n.o(.ARM.Collect$$_printf_percent$$00000001) refers (Weak) to _printf_charcount.o(.text) for _printf_charcount
+ _printf_x.o(.ARM.Collect$$_printf_percent$$0000000C) refers (Weak) to _printf_hex_int_ll_ptr.o(.text) for _printf_int_hex
+ _printf_p.o(.ARM.Collect$$_printf_percent$$00000002) refers (Weak) to _printf_hex_int_ll_ptr.o(.text) for _printf_hex_ptr
+ _printf_o.o(.ARM.Collect$$_printf_percent$$0000000B) refers (Weak) to _printf_oct_int_ll.o(.text) for _printf_int_oct
+ _printf_i.o(.ARM.Collect$$_printf_percent$$00000008) refers (Weak) to _printf_dec.o(.text) for _printf_int_dec
+ _printf_d.o(.ARM.Collect$$_printf_percent$$00000009) refers (Weak) to _printf_dec.o(.text) for _printf_int_dec
+ _printf_u.o(.ARM.Collect$$_printf_percent$$0000000A) refers (Weak) to _printf_dec.o(.text) for _printf_int_dec
+ _printf_f.o(.ARM.Collect$$_printf_percent$$00000003) refers (Weak) to printf1.o(x$fpl$printf1) for _printf_fp_dec
+ _printf_e.o(.ARM.Collect$$_printf_percent$$00000004) refers (Weak) to printf1.o(x$fpl$printf1) for _printf_fp_dec
+ _printf_g.o(.ARM.Collect$$_printf_percent$$00000005) refers (Weak) to printf1.o(x$fpl$printf1) for _printf_fp_dec
+ _printf_a.o(.ARM.Collect$$_printf_percent$$00000006) refers (Weak) to printf2.o(x$fpl$printf2) for _printf_fp_hex
+ _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) refers (Special) to _printf_percent_end.o(.ARM.Collect$$_printf_percent$$00000017) for _printf_percent_end
+ _printf_lli.o(.ARM.Collect$$_printf_percent$$0000000D) refers (Special) to _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007) for _printf_ll
+ _printf_lli.o(.ARM.Collect$$_printf_percent$$0000000D) refers (Weak) to _printf_longlong_dec.o(.text) for _printf_longlong_dec
+ _printf_lld.o(.ARM.Collect$$_printf_percent$$0000000E) refers (Special) to _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007) for _printf_ll
+ _printf_lld.o(.ARM.Collect$$_printf_percent$$0000000E) refers (Weak) to _printf_longlong_dec.o(.text) for _printf_longlong_dec
+ _printf_llu.o(.ARM.Collect$$_printf_percent$$0000000F) refers (Special) to _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007) for _printf_ll
+ _printf_llu.o(.ARM.Collect$$_printf_percent$$0000000F) refers (Weak) to _printf_longlong_dec.o(.text) for _printf_longlong_dec
+ _printf_lc.o(.ARM.Collect$$_printf_percent$$00000015) refers (Special) to _printf_l.o(.ARM.Collect$$_printf_percent$$00000012) for _printf_l
+ _printf_lc.o(.ARM.Collect$$_printf_percent$$00000015) refers (Weak) to _printf_wchar.o(.text) for _printf_wchar
+ _printf_ls.o(.ARM.Collect$$_printf_percent$$00000016) refers (Special) to _printf_l.o(.ARM.Collect$$_printf_percent$$00000012) for _printf_l
+ _printf_ls.o(.ARM.Collect$$_printf_percent$$00000016) refers (Weak) to _printf_wchar.o(.text) for _printf_wstring
+ _printf_llo.o(.ARM.Collect$$_printf_percent$$00000010) refers (Special) to _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007) for _printf_ll
+ _printf_llo.o(.ARM.Collect$$_printf_percent$$00000010) refers (Weak) to _printf_oct_int_ll.o(.text) for _printf_ll_oct
+ _printf_llx.o(.ARM.Collect$$_printf_percent$$00000011) refers (Special) to _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007) for _printf_ll
+ _printf_llx.o(.ARM.Collect$$_printf_percent$$00000011) refers (Weak) to _printf_hex_int_ll_ptr.o(.text) for _printf_ll_hex
+ libinit2.o(.ARM.Collect$$libinit$$0000000D) refers (Weak) to rand.o(.text) for _rand_init
+ libinit2.o(.ARM.Collect$$libinit$$0000000F) refers (Weak) to rt_locale.o(.text) for __rt_locale
+ libinit2.o(.ARM.Collect$$libinit$$00000010) refers to libinit2.o(.ARM.Collect$$libinit$$0000000F) for .ARM.Collect$$libinit$$0000000F
+ libinit2.o(.ARM.Collect$$libinit$$00000012) refers to libinit2.o(.ARM.Collect$$libinit$$0000000F) for .ARM.Collect$$libinit$$0000000F
+ libinit2.o(.ARM.Collect$$libinit$$00000012) refers (Weak) to lc_ctype_c.o(locale$$code) for _get_lc_ctype
+ libinit2.o(.ARM.Collect$$libinit$$00000014) refers to libinit2.o(.ARM.Collect$$libinit$$0000000F) for .ARM.Collect$$libinit$$0000000F
+ libinit2.o(.ARM.Collect$$libinit$$00000016) refers to libinit2.o(.ARM.Collect$$libinit$$0000000F) for .ARM.Collect$$libinit$$0000000F
+ libinit2.o(.ARM.Collect$$libinit$$00000016) refers (Weak) to lc_numeric_c.o(locale$$code) for _get_lc_numeric
+ libinit2.o(.ARM.Collect$$libinit$$00000018) refers to libinit2.o(.ARM.Collect$$libinit$$0000000F) for .ARM.Collect$$libinit$$0000000F
+ libinit2.o(.ARM.Collect$$libinit$$00000026) refers to argv_veneer.o(.text) for __ARM_argv_veneer
+ libinit2.o(.ARM.Collect$$libinit$$00000027) refers to argv_veneer.o(.text) for __ARM_argv_veneer
+ printf1.o(x$fpl$printf1) refers to _printf_fp_dec.o(.text) for _printf_fp_dec_real
+ printf2.o(x$fpl$printf2) refers to _printf_fp_hex.o(.text) for _printf_fp_hex_real
+ printf2b.o(x$fpl$printf2) refers to _printf_fp_hex.o(.text) for _printf_fp_hex_real
+ __rtentry2.o(.ARM.Collect$$rtentry$$00000008) refers to boardinit2.o(.text) for _platform_post_stackheap_init
+ __rtentry2.o(.ARM.Collect$$rtentry$$0000000A) refers to libinit.o(.ARM.Collect$$libinit$$00000000) for __rt_lib_init
+ __rtentry2.o(.ARM.Collect$$rtentry$$0000000B) refers to boardinit3.o(.text) for _platform_post_lib_init
+ __rtentry2.o(.ARM.Collect$$rtentry$$0000000D) refers to main.o(.text) for main
+ __rtentry2.o(.ARM.exidx) refers to __rtentry2.o(.ARM.Collect$$rtentry$$00000001) for .ARM.Collect$$rtentry$$00000001
+ __rtentry2.o(.ARM.exidx) refers to __rtentry2.o(.ARM.Collect$$rtentry$$00000008) for .ARM.Collect$$rtentry$$00000008
+ __rtentry2.o(.ARM.exidx) refers to __rtentry2.o(.ARM.Collect$$rtentry$$0000000A) for .ARM.Collect$$rtentry$$0000000A
+ __rtentry2.o(.ARM.exidx) refers to __rtentry2.o(.ARM.Collect$$rtentry$$0000000B) for .ARM.Collect$$rtentry$$0000000B
+ __rtentry2.o(.ARM.exidx) refers to __rtentry2.o(.ARM.Collect$$rtentry$$0000000D) for .ARM.Collect$$rtentry$$0000000D
+ __rtentry4.o(.ARM.Collect$$rtentry$$00000004) refers to startup_rtl876x.o(.text) for __user_setup_stackheap
+ __rtentry4.o(.ARM.exidx) refers to __rtentry4.o(.ARM.Collect$$rtentry$$00000004) for .ARM.Collect$$rtentry$$00000004
+ __rtentry5.o(.ARM.Collect$$rtentry$$00000005) refers to __rtentry5.o(.ARM.Collect$$rtentry$$00002716) for __lit__00000000
+ __rtentry5.o(__vectab_stack_and_reset_sym_area) refers to __main.o(!!!main) for __main
+ __rtentry5.o(.ARM.exidx) refers to __rtentry5.o(.ARM.Collect$$rtentry$$00000005) for .ARM.Collect$$rtentry$$00000005
+ __rtentry5.o(.ARM.exidx) refers to __rtentry5.o(.ARM.Collect$$rtentry$$00002716) for .ARM.Collect$$rtentry$$00002716
+ rt_div0.o(.text) refers to defsig_fpe_outer.o(.text) for __rt_SIGFPE
+ _printf_intcommon.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding
+ _printf_intcommon.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding
+ _printf_intcommon.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_post_padding
+ _printf_fp_dec.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ _printf_fp_dec.o(.text) refers (Special) to lc_numeric_c.o(locale$$code) for _get_lc_numeric
+ _printf_fp_dec.o(.text) refers to bigflt0.o(.text) for _btod_etento
+ _printf_fp_dec.o(.text) refers to btod.o(.text) for _btod_d2e
+ _printf_fp_dec.o(.text) refers to lludiv10.o(.text) for _ll_udiv10
+ _printf_fp_dec.o(.text) refers to fpclassify.o(i.__ARM_fpclassify) for __ARM_fpclassify
+ _printf_fp_dec.o(.text) refers to _printf_fp_infnan.o(.text) for _printf_fp_infnan
+ _printf_fp_dec.o(.text) refers to rtudiv10.o(.text) for __rt_udiv10
+ _printf_fp_dec.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding
+ _printf_fp_dec.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding
+ _printf_fp_dec.o(.text) refers to rt_locale.o(.text) for __rt_locale
+ _printf_fp_dec.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_post_padding
+ _printf_fp_hex.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ _printf_fp_hex.o(.text) refers to fpclassify.o(i.__ARM_fpclassify) for __ARM_fpclassify
+ _printf_fp_hex.o(.text) refers to _printf_fp_infnan.o(.text) for _printf_fp_infnan
+ _printf_fp_hex.o(.text) refers to aeabi_sdiv.o(.text) for __aeabi_idivmod
+ _printf_fp_hex.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding
+ _printf_fp_hex.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding
+ _printf_fp_hex.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_post_padding
+ _printf_fp_hex.o(.text) refers to _printf_fp_hex.o(.constdata) for .constdata
+ _printf_fp_hex.o(.constdata) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ _printf_char.o(.text) refers (Weak) to _printf_str.o(.text) for _printf_str
+ _printf_wchar.o(.text) refers (Weak) to _printf_wctomb.o(.text) for _printf_wctomb
+ _wcrtomb.o(.text) refers to rt_ctype_table.o(.text) for __rt_ctype_table
+ rt_ctype_table.o(.text) refers to rt_locale.o(.text) for __rt_locale
+ rt_ctype_table.o(.text) refers to lc_ctype_c.o(locale$$code) for _get_lc_ctype
+ rt_locale.o(.text) refers to rt_locale.o(.bss) for __rt_locale_data
+ rt_locale_intlibspace.o(.text) refers to libspace.o(.bss) for __libspace_start
+ _printf_fp_infnan.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding
+ _printf_fp_infnan.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_post_padding
+ bigflt0.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ bigflt0.o(.text) refers to aeabi_sdiv.o(.text) for __aeabi_idivmod
+ bigflt0.o(.text) refers to btod.o(.text) for _btod_emul
+ bigflt0.o(.text) refers to bigflt0.o(.constdata) for .constdata
+ bigflt0.o(.constdata) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ btod.o(.text) refers to btod.o(i.__ARM_common_ll_muluu) for __ARM_common_ll_muluu
+ lc_numeric_c.o(locale$$data) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000016) for __rt_lib_init_lc_numeric_2
+ lc_numeric_c.o(locale$$code) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000016) for __rt_lib_init_lc_numeric_2
+ lc_numeric_c.o(locale$$code) refers to strcmp.o(.text) for strcmp
+ lc_numeric_c.o(locale$$code) refers to lc_numeric_c.o(locale$$data) for __lcnum_c_name
+ defsig_fpe_outer.o(.text) refers to defsig_fpe_inner.o(.text) for __rt_SIGFPE_inner
+ defsig_fpe_outer.o(.text) refers to defsig_exit.o(.text) for __sig_exit
+ defsig_fpe_formal.o(.text) refers to rt_raise.o(.text) for __rt_raise
+ _get_argv_nomalloc.o(.text) refers (Special) to hrguard.o(.text) for __heap_region$guard
+ _get_argv_nomalloc.o(.text) refers to defsig_rtmem_outer.o(.text) for __rt_SIGRTMEM
+ _get_argv_nomalloc.o(.text) refers to sys_command.o(.text) for _sys_command_string
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000002E) for __rt_lib_init_alloca_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000002C) for __rt_lib_init_argv_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000001B) for __rt_lib_init_atexit_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000021) for __rt_lib_init_clock_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000032) for __rt_lib_init_cpp_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000030) for __rt_lib_init_exceptions_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000002) for __rt_lib_init_fp_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000001F) for __rt_lib_init_fp_trap_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000023) for __rt_lib_init_getenv_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000000A) for __rt_lib_init_heap_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000011) for __rt_lib_init_lc_collate_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000013) for __rt_lib_init_lc_ctype_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000015) for __rt_lib_init_lc_monetary_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000017) for __rt_lib_init_lc_numeric_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000019) for __rt_lib_init_lc_time_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000004) for __rt_lib_init_preinit_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000000E) for __rt_lib_init_rand_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000033) for __rt_lib_init_return
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000001D) for __rt_lib_init_signal_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000025) for __rt_lib_init_stdio_1
+ libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000000C) for __rt_lib_init_user_alloc_1
+ ieee_status.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ fpclassify.o(i.__ARM_fpclassify) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp
+ sys_command.o(.text) refers (Special) to use_no_semi.o(.text) for __I$use$semihosting
+ sys_command.o(.text) refers (Special) to indicate_semi.o(.text) for __semihosting_library_function
+ libspace.o(.text) refers to libspace.o(.bss) for __libspace_start
+ rt_raise.o(.text) refers to __raise.o(.text) for __raise
+ rt_raise.o(.text) refers to sys_exit.o(.text) for _sys_exit
+ lc_ctype_c.o(locale$$data) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000012) for __rt_lib_init_lc_ctype_2
+ lc_ctype_c.o(locale$$code) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000012) for __rt_lib_init_lc_ctype_2
+ lc_ctype_c.o(locale$$code) refers to strcmp.o(.text) for strcmp
+ lc_ctype_c.o(locale$$code) refers to lc_ctype_c.o(locale$$data) for __lcctype_c_name
+ defsig_exit.o(.text) refers to sys_exit.o(.text) for _sys_exit
+ defsig_fpe_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display
+ defsig_rtmem_outer.o(.text) refers to defsig_rtmem_inner.o(.text) for __rt_SIGRTMEM_inner
+ defsig_rtmem_outer.o(.text) refers to defsig_exit.o(.text) for __sig_exit
+ defsig_rtmem_formal.o(.text) refers to rt_raise.o(.text) for __rt_raise
+ sys_exit.o(.text) refers (Special) to use_no_semi.o(.text) for __I$use$semihosting
+ sys_exit.o(.text) refers (Special) to indicate_semi.o(.text) for __semihosting_library_function
+ __raise.o(.text) refers to defsig.o(CL$$defsig) for __default_signal_handler
+ defsig_general.o(.text) refers to sys_wrch.o(.text) for _ttywrch
+ defsig_rtmem_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display
+ sys_wrch.o(.text) refers (Special) to use_no_semi.o(.text) for __I$use$semihosting
+ sys_wrch.o(.text) refers (Special) to indicate_semi.o(.text) for __semihosting_library_function
+ defsig.o(CL$$defsig) refers to defsig_fpe_inner.o(.text) for __rt_SIGFPE_inner
+ defsig.o(CL$$defsig) refers to defsig_rtmem_inner.o(.text) for __rt_SIGRTMEM_inner
+ defsig_abrt_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display
+ defsig_rtred_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display
+ defsig_stak_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display
+ defsig_pvfn_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display
+ defsig_cppl_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display
+ defsig_segv_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display
+ defsig_other.o(.text) refers to defsig_general.o(.text) for __default_signal_display
+
+
+==============================================================================
+
+Removing Unused input sections from the image.
+
+ Removing system_rtl876x.o(.rev16_text), (4 bytes).
+ Removing system_rtl876x.o(.revsh_text), (4 bytes).
+ Removing rtl876x_io_dlps.o(.rev16_text), (4 bytes).
+ Removing rtl876x_io_dlps.o(.revsh_text), (4 bytes).
+ Removing rtl876x_gpio.o(.rev16_text), (4 bytes).
+ Removing rtl876x_gpio.o(.revsh_text), (4 bytes).
+ Removing rtl876x_ir.o(.rev16_text), (4 bytes).
+ Removing rtl876x_ir.o(.revsh_text), (4 bytes).
+ Removing rtl876x_keyscan.o(.rev16_text), (4 bytes).
+ Removing rtl876x_keyscan.o(.revsh_text), (4 bytes).
+ Removing rtl876x_rtc.o(.rev16_text), (4 bytes).
+ Removing rtl876x_rtc.o(.revsh_text), (4 bytes).
+ Removing rtl876x_codec.o(.rev16_text), (4 bytes).
+ Removing rtl876x_codec.o(.revsh_text), (4 bytes).
+ Removing rtl876x_i2s.o(.rev16_text), (4 bytes).
+ Removing rtl876x_i2s.o(.revsh_text), (4 bytes).
+ Removing rtl876x_pinmux.o(.rev16_text), (4 bytes).
+ Removing rtl876x_pinmux.o(.revsh_text), (4 bytes).
+ Removing rtl876x_nvic.o(.rev16_text), (4 bytes).
+ Removing rtl876x_nvic.o(.revsh_text), (4 bytes).
+ Removing rtl876x_rcc.o(.rev16_text), (4 bytes).
+ Removing rtl876x_rcc.o(.revsh_text), (4 bytes).
+ Removing rtl876x_tim.o(.rev16_text), (4 bytes).
+ Removing rtl876x_tim.o(.revsh_text), (4 bytes).
+ Removing rtl876x_gdma.o(.rev16_text), (4 bytes).
+ Removing rtl876x_gdma.o(.revsh_text), (4 bytes).
+ Removing rtl876x_uart.o(.rev16_text), (4 bytes).
+ Removing rtl876x_uart.o(.revsh_text), (4 bytes).
+ Removing rtl876x_adc.o(.rev16_text), (4 bytes).
+ Removing rtl876x_adc.o(.revsh_text), (4 bytes).
+ Removing rtl876x_lpc.o(.rev16_text), (4 bytes).
+ Removing rtl876x_lpc.o(.revsh_text), (4 bytes).
+ Removing rtl876x_aon_wdg.o(.rev16_text), (4 bytes).
+ Removing rtl876x_aon_wdg.o(.revsh_text), (4 bytes).
+ Removing dis.o(.rev16_text), (4 bytes).
+ Removing dis.o(.revsh_text), (4 bytes).
+ Removing dis.o(.constdata), (2 bytes).
+ Removing bas.o(.rev16_text), (4 bytes).
+ Removing bas.o(.revsh_text), (4 bytes).
+ Removing hids_rmc.o(.rev16_text), (4 bytes).
+ Removing hids_rmc.o(.revsh_text), (4 bytes).
+ Removing vendor_service.o(.rev16_text), (4 bytes).
+ Removing vendor_service.o(.revsh_text), (4 bytes).
+ Removing voice_service.o(.rev16_text), (4 bytes).
+ Removing voice_service.o(.revsh_text), (4 bytes).
+ Removing voice_service.o(.text), (284 bytes).
+ Removing voice_service.o(.bss), (4 bytes).
+ Removing voice_service.o(.constdata), (16 bytes).
+ Removing voice_service.o(.constdata), (264 bytes).
+ Removing atvv_service.o(.rev16_text), (4 bytes).
+ Removing atvv_service.o(.revsh_text), (4 bytes).
+ Removing atvv_service.o(.constdata), (4 bytes).
+ Removing ir_service.o(.rev16_text), (4 bytes).
+ Removing ir_service.o(.revsh_text), (4 bytes).
+ Removing ir_service.o(.bss), (16 bytes).
+ Removing dfu_service.o(.rev16_text), (4 bytes).
+ Removing dfu_service.o(.revsh_text), (4 bytes).
+ Removing ota_service.o(.rev16_text), (4 bytes).
+ Removing ota_service.o(.revsh_text), (4 bytes).
+ Removing ota_service.o(.bss), (4 bytes).
+ Removing fms.o(.rev16_text), (4 bytes).
+ Removing fms.o(.revsh_text), (4 bytes).
+ Removing main.o(.rev16_text), (4 bytes).
+ Removing main.o(.revsh_text), (4 bytes).
+ Removing rcu_application.o(.rev16_text), (4 bytes).
+ Removing rcu_application.o(.revsh_text), (4 bytes).
+ Removing rcu_gap.o(.rev16_text), (4 bytes).
+ Removing rcu_gap.o(.revsh_text), (4 bytes).
+ Removing swtimer.o(.rev16_text), (4 bytes).
+ Removing swtimer.o(.revsh_text), (4 bytes).
+ Removing app_task.o(.rev16_text), (4 bytes).
+ Removing app_task.o(.revsh_text), (4 bytes).
+ Removing reset_watch_dog_timer.o(.rev16_text), (4 bytes).
+ Removing reset_watch_dog_timer.o(.revsh_text), (4 bytes).
+ Removing privacy_mgnt.o(.rev16_text), (4 bytes).
+ Removing privacy_mgnt.o(.revsh_text), (4 bytes).
+ Removing loop_queue.o(.rev16_text), (4 bytes).
+ Removing loop_queue.o(.revsh_text), (4 bytes).
+ Removing rcu_dtm_app.o(.rev16_text), (4 bytes).
+ Removing rcu_dtm_app.o(.revsh_text), (4 bytes).
+ Removing rcu_link_mgr.o(.rev16_text), (4 bytes).
+ Removing rcu_link_mgr.o(.revsh_text), (4 bytes).
+ Removing rcu_link_mgr.o(.text), (256 bytes).
+ Removing rcu_link_mgr.o(.bss), (43 bytes).
+ Removing rtc_driver.o(.rev16_text), (4 bytes).
+ Removing rtc_driver.o(.revsh_text), (4 bytes).
+ Removing dfu_main.o(.rev16_text), (4 bytes).
+ Removing dfu_main.o(.revsh_text), (4 bytes).
+ Removing dfu_task.o(.rev16_text), (4 bytes).
+ Removing dfu_task.o(.revsh_text), (4 bytes).
+ Removing dfu_application.o(.rev16_text), (4 bytes).
+ Removing dfu_application.o(.revsh_text), (4 bytes).
+ Removing dfu_flash.o(.rev16_text), (4 bytes).
+ Removing dfu_flash.o(.revsh_text), (4 bytes).
+ Removing keyscan_driver.o(.rev16_text), (4 bytes).
+ Removing keyscan_driver.o(.revsh_text), (4 bytes).
+ Removing key_handle.o(.rev16_text), (4 bytes).
+ Removing key_handle.o(.revsh_text), (4 bytes).
+ Removing voice_driver.o(.rev16_text), (4 bytes).
+ Removing voice_driver.o(.revsh_text), (4 bytes).
+ Removing voice.o(.rev16_text), (4 bytes).
+ Removing voice.o(.revsh_text), (4 bytes).
+ Removing ir_send_driver.o(.rev16_text), (4 bytes).
+ Removing ir_send_driver.o(.revsh_text), (4 bytes).
+ Removing ir_send_handle.o(.rev16_text), (4 bytes).
+ Removing ir_send_handle.o(.revsh_text), (4 bytes).
+ Removing ir_protocol_nec.o(.rev16_text), (4 bytes).
+ Removing ir_protocol_nec.o(.revsh_text), (4 bytes).
+ Removing ir_service_handle.o(.rev16_text), (4 bytes).
+ Removing ir_service_handle.o(.revsh_text), (4 bytes).
+ Removing ir_service_handle.o(.data), (1 bytes).
+ Removing led_driver.o(.rev16_text), (4 bytes).
+ Removing led_driver.o(.revsh_text), (4 bytes).
+ Removing led_pwm_driver.o(.rev16_text), (4 bytes).
+ Removing led_pwm_driver.o(.revsh_text), (4 bytes).
+ Removing buzzer_driver.o(.rev16_text), (4 bytes).
+ Removing buzzer_driver.o(.revsh_text), (4 bytes).
+ Removing fms_service_handle.o(.rev16_text), (4 bytes).
+ Removing fms_service_handle.o(.revsh_text), (4 bytes).
+ Removing battery_driver.o(.rev16_text), (4 bytes).
+ Removing battery_driver.o(.revsh_text), (4 bytes).
+ Removing data_uart_test.o(.rev16_text), (4 bytes).
+ Removing data_uart_test.o(.revsh_text), (4 bytes).
+ Removing mp_test.o(.rev16_text), (4 bytes).
+ Removing mp_test.o(.revsh_text), (4 bytes).
+ Removing single_tone.o(.rev16_text), (4 bytes).
+ Removing single_tone.o(.revsh_text), (4 bytes).
+ Removing uart_transport.o(.rev16_text), (4 bytes).
+ Removing uart_transport.o(.revsh_text), (4 bytes).
+ Removing app_flash_write.o(.rev16_text), (4 bytes).
+ Removing app_flash_write.o(.revsh_text), (4 bytes).
+ Removing app_flash_write.o(.text), (556 bytes).
+ Removing app_flash_write.o(.bss), (1 bytes).
+ Removing app_flash_write.o(.bss), (6 bytes).
+ Removing app_custom.o(.rev16_text), (4 bytes).
+ Removing app_custom.o(.revsh_text), (4 bytes).
+ Removing app_custom.o(.conststring), (10 bytes).
+ Removing app_custom.o(.data), (4 bytes).
+ Removing frm_vpk_hal_sflash.o(.rev16_text), (4 bytes).
+ Removing frm_vpk_hal_sflash.o(.revsh_text), (4 bytes).
+ Removing frm_vpk_log.o(.rev16_text), (4 bytes).
+ Removing frm_vpk_log.o(.revsh_text), (4 bytes).
+
+142 unused section(s) (total 1975 bytes) removed from the image.
+
+==============================================================================
+
+Image Symbol Table
+
+ Local Symbols
+
+ Symbol Name Value Ov Type Size Object(Section)
+
+ ../clib/angel/boardlib.s 0x00000000 Number 0 boardinit2.o ABSOLUTE
+ ../clib/angel/boardlib.s 0x00000000 Number 0 boardinit3.o ABSOLUTE
+ ../clib/angel/boardlib.s 0x00000000 Number 0 boardinit1.o ABSOLUTE
+ ../clib/angel/kernel.s 0x00000000 Number 0 __rtentry4.o ABSOLUTE
+ ../clib/angel/kernel.s 0x00000000 Number 0 __rtentry.o ABSOLUTE
+ ../clib/angel/kernel.s 0x00000000 Number 0 __rtentry2.o ABSOLUTE
+ ../clib/angel/kernel.s 0x00000000 Number 0 __rtentry5.o ABSOLUTE
+ ../clib/angel/rt.s 0x00000000 Number 0 aeabi_idiv0.o ABSOLUTE
+ ../clib/angel/rt.s 0x00000000 Number 0 rt_ctype_table.o ABSOLUTE
+ ../clib/angel/rt.s 0x00000000 Number 0 rt_locale_intlibspace.o ABSOLUTE
+ ../clib/angel/rt.s 0x00000000 Number 0 rt_raise.o ABSOLUTE
+ ../clib/angel/rt.s 0x00000000 Number 0 rt_locale.o ABSOLUTE
+ ../clib/angel/rt.s 0x00000000 Number 0 aeabi_ldiv0_sigfpe.o ABSOLUTE
+ ../clib/angel/rt.s 0x00000000 Number 0 aeabi_ldiv0.o ABSOLUTE
+ ../clib/angel/rt.s 0x00000000 Number 0 aeabi_idiv0_sigfpe.o ABSOLUTE
+ ../clib/angel/rt.s 0x00000000 Number 0 rt_div0.o ABSOLUTE
+ ../clib/angel/startup.s 0x00000000 Number 0 __main.o ABSOLUTE
+ ../clib/angel/sys.s 0x00000000 Number 0 indicate_semi.o ABSOLUTE
+ ../clib/angel/sys.s 0x00000000 Number 0 use_no_semi.o ABSOLUTE
+ ../clib/angel/sys.s 0x00000000 Number 0 libspace.o ABSOLUTE
+ ../clib/angel/sysapp.c 0x00000000 Number 0 sys_exit.o ABSOLUTE
+ ../clib/angel/sysapp.c 0x00000000 Number 0 sys_command.o ABSOLUTE
+ ../clib/angel/sysapp.c 0x00000000 Number 0 sys_wrch.o ABSOLUTE
+ ../clib/armsys.c 0x00000000 Number 0 no_argv.o ABSOLUTE
+ ../clib/armsys.c 0x00000000 Number 0 _get_argv_nomalloc.o ABSOLUTE
+ ../clib/armsys.c 0x00000000 Number 0 argv_veneer.o ABSOLUTE
+ ../clib/bigflt.c 0x00000000 Number 0 bigflt0.o ABSOLUTE
+ ../clib/btod.c 0x00000000 Number 0 btod.o ABSOLUTE
+ ../clib/division.c 0x00000000 Number 0 lludiv.o ABSOLUTE
+ ../clib/division.c 0x00000000 Number 0 rtudiv10.o ABSOLUTE
+ ../clib/division.c 0x00000000 Number 0 lludiv10.o ABSOLUTE
+ ../clib/division.s 0x00000000 Number 0 aeabi_sdiv_div0.o ABSOLUTE
+ ../clib/division.s 0x00000000 Number 0 aeabi_sdiv.o ABSOLUTE
+ ../clib/heapalloc.c 0x00000000 Number 0 hrguard.o ABSOLUTE
+ ../clib/libinit.s 0x00000000 Number 0 libinit2.o ABSOLUTE
+ ../clib/libinit.s 0x00000000 Number 0 libinit.o ABSOLUTE
+ ../clib/locale.c 0x00000000 Number 0 _wcrtomb.o ABSOLUTE
+ ../clib/locale.s 0x00000000 Number 0 lc_ctype_c.o ABSOLUTE
+ ../clib/locale.s 0x00000000 Number 0 lc_numeric_c.o ABSOLUTE
+ ../clib/longlong.c 0x00000000 Number 0 llmul.o ABSOLUTE
+ ../clib/misc.s 0x00000000 Number 0 printf_stubs.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_char.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_wchar.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_hex_int_ll.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_fp_infnan.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 vsprintf.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_hex_ptr.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_hex_int.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 __printf_flags_ss_wp.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 __printf_ss_wp.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 __printf_flags_wp.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 __printf_wp.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 __printf_flags_ss.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 __printf_ss.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 __printf_flags.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_hex_int_ll_ptr.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_hex_ll_ptr.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 __printf.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_hex_int_ptr.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_pad.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_truncate.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_str.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_dec.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_charcount.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_char_common.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _sputc.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_wctomb.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_longlong_dec.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_oct_ll.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_oct_int.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_hex_ll.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_oct_int_ll.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_fp_dec.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_fp_hex.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 __printf_nopercent.o ABSOLUTE
+ ../clib/printf.c 0x00000000 Number 0 _printf_intcommon.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_f.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_u.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_lld.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_n.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_e.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_llu.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_g.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_a.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_ll.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_percent_end.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_x.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_percent.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_p.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_c.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_llx.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_l.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_lc.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_ls.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_llo.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_o.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_d.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_s.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_lli.o ABSOLUTE
+ ../clib/printf_percent.s 0x00000000 Number 0 _printf_i.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 defsig_abrt_inner.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 defsig_rtred_inner.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 defsig_stak_inner.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 defsig_fpe_outer.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 defsig_fpe_formal.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 defsig_exit.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 defsig_pvfn_inner.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 defsig_fpe_inner.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 defsig_cppl_inner.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 defsig_rtmem_outer.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 defsig_segv_inner.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 defsig_rtmem_formal.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 __raise.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 defsig_general.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 defsig_rtmem_inner.o ABSOLUTE
+ ../clib/signal.c 0x00000000 Number 0 defsig_other.o ABSOLUTE
+ ../clib/signal.s 0x00000000 Number 0 defsig.o ABSOLUTE
+ ../clib/stdlib.c 0x00000000 Number 0 rand.o ABSOLUTE
+ ../clib/stdlib.c 0x00000000 Number 0 rand.o ABSOLUTE
+ ../clib/string.c 0x00000000 Number 0 strcmp.o ABSOLUTE
+ ../fplib/cfplib/d2f.c 0x00000000 Number 0 d2f.o ABSOLUTE
+ ../fplib/cfplib/daddsub.c 0x00000000 Number 0 daddsub.o ABSOLUTE
+ ../fplib/cfplib/ddiv.c 0x00000000 Number 0 ddiv.o ABSOLUTE
+ ../fplib/cfplib/dmul.c 0x00000000 Number 0 dmul.o ABSOLUTE
+ ../fplib/cfplib/f2d.c 0x00000000 Number 0 f2d.o ABSOLUTE
+ ../fplib/cfplib/fdiv.c 0x00000000 Number 0 fdiv.o ABSOLUTE
+ ../fplib/cfplib/ffix.c 0x00000000 Number 0 dfixui.o ABSOLUTE
+ ../fplib/cfplib/ffix.c 0x00000000 Number 0 ffixui.o ABSOLUTE
+ ../fplib/cfplib/fflt.c 0x00000000 Number 0 dflti.o ABSOLUTE
+ ../fplib/cfplib/fflt.c 0x00000000 Number 0 fflti.o ABSOLUTE
+ ../fplib/cfplib/fpinit.c 0x00000000 Number 0 fpinit.o ABSOLUTE
+ ../fplib/cfplib/ieee_status.c 0x00000000 Number 0 ieee_status.o ABSOLUTE
+ ../fplib/faddsub6m.s 0x00000000 Number 0 faddsub.o ABSOLUTE
+ ../fplib/fmul6m.s 0x00000000 Number 0 fmul.o ABSOLUTE
+ ../fplib/printf1.s 0x00000000 Number 0 printf1.o ABSOLUTE
+ ../fplib/printf2.s 0x00000000 Number 0 printf2.o ABSOLUTE
+ ../fplib/printf2a.s 0x00000000 Number 0 printf2a.o ABSOLUTE
+ ../fplib/printf2b.s 0x00000000 Number 0 printf2b.o ABSOLUTE
+ ../fplib/usenofp.s 0x00000000 Number 0 usenofp.o ABSOLUTE
+ ../mathlib/fpclassify.c 0x00000000 Number 0 fpclassify.o ABSOLUTE
+ ..\..\..\..\src\app\adc_lib\adc_lib.c 0x00000000 Number 0 adc_lib.o ABSOLUTE
+ ..\..\..\..\src\app\gap_lib\systemcall\gap_lib_system_call.c 0x00000000 Number 0 gap_lib_system_call.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\address_module\rcu_link_mgr.c 0x00000000 Number 0 rcu_link_mgr.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\app_task.c 0x00000000 Number 0 app_task.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\bat_module\battery_driver.c 0x00000000 Number 0 battery_driver.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\buzzer_module\buzzer_driver.c 0x00000000 Number 0 buzzer_driver.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\buzzer_module\fms_service_handle.c 0x00000000 Number 0 fms_service_handle.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\dtm_module\rcu_dtm_app.c 0x00000000 Number 0 rcu_dtm_app.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\frm_vpk\frm_vpk_api\frm_vpk_hal_sflash.c 0x00000000 Number 0 frm_vpk_hal_sflash.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\frm_vpk\frm_vpk_api\frm_vpk_log.c 0x00000000 Number 0 frm_vpk_log.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\frm_vpk\src\app_custom.c 0x00000000 Number 0 app_custom.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\frm_vpk\src\app_flash_write.c 0x00000000 Number 0 app_flash_write.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\ir_module\ir_protocol_nec.c 0x00000000 Number 0 ir_protocol_nec.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\ir_module\ir_send_driver.c 0x00000000 Number 0 ir_send_driver.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\ir_module\ir_send_handle.c 0x00000000 Number 0 ir_send_handle.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\ir_module\ir_service_handle.c 0x00000000 Number 0 ir_service_handle.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\key_module\key_handle.c 0x00000000 Number 0 key_handle.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\key_module\keyscan_driver.c 0x00000000 Number 0 keyscan_driver.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\led_module\led_driver.c 0x00000000 Number 0 led_driver.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\led_module\led_pwm_driver.c 0x00000000 Number 0 led_pwm_driver.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\loop_queue.c 0x00000000 Number 0 loop_queue.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\main.c 0x00000000 Number 0 main.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\profile_module\dfu_service.c 0x00000000 Number 0 dfu_service.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\profile_module\fms.c 0x00000000 Number 0 fms.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\profile_module\hids_rmc.c 0x00000000 Number 0 hids_rmc.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\profile_module\ir_service.c 0x00000000 Number 0 ir_service.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\profile_module\ota_service.c 0x00000000 Number 0 ota_service.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\rcu_application.c 0x00000000 Number 0 rcu_application.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\rcu_gap.c 0x00000000 Number 0 rcu_gap.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\reset_watch_dog_timer.c 0x00000000 Number 0 reset_watch_dog_timer.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\rtc_module\rtc_driver.c 0x00000000 Number 0 rtc_driver.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\swtimer.c 0x00000000 Number 0 swtimer.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\test_module\data_uart_test.c 0x00000000 Number 0 data_uart_test.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\test_module\mp_test.c 0x00000000 Number 0 mp_test.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\test_module\single_tone.c 0x00000000 Number 0 single_tone.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\test_module\uart_transport.c 0x00000000 Number 0 uart_transport.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\voice_module\voice.c 0x00000000 Number 0 voice.o ABSOLUTE
+ ..\..\..\..\src\app\google_rcu\voice_module\voice_driver.c 0x00000000 Number 0 voice_driver.o ABSOLUTE
+ ..\..\..\..\src\ble\privacy\privacy_mgnt.c 0x00000000 Number 0 privacy_mgnt.o ABSOLUTE
+ ..\..\..\..\src\ble\profile\server\atvv_service.c 0x00000000 Number 0 atvv_service.o ABSOLUTE
+ ..\..\..\..\src\ble\profile\server\bas.c 0x00000000 Number 0 bas.o ABSOLUTE
+ ..\..\..\..\src\ble\profile\server\dis.c 0x00000000 Number 0 dis.o ABSOLUTE
+ ..\..\..\..\src\ble\profile\server\vendor_service.c 0x00000000 Number 0 vendor_service.o ABSOLUTE
+ ..\..\..\..\src\ble\profile\server\voice_service.c 0x00000000 Number 0 voice_service.o ABSOLUTE
+ ..\..\..\..\src\dfu\dfu_application.c 0x00000000 Number 0 dfu_application.o ABSOLUTE
+ ..\..\..\..\src\dfu\dfu_main.c 0x00000000 Number 0 dfu_main.o ABSOLUTE
+ ..\..\..\..\src\dfu\dfu_task.c 0x00000000 Number 0 dfu_task.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_adc.c 0x00000000 Number 0 rtl876x_adc.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_aon_wdg.c 0x00000000 Number 0 rtl876x_aon_wdg.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_codec.c 0x00000000 Number 0 rtl876x_codec.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_gdma.c 0x00000000 Number 0 rtl876x_gdma.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_gpio.c 0x00000000 Number 0 rtl876x_gpio.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_i2s.c 0x00000000 Number 0 rtl876x_i2s.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_io_dlps.c 0x00000000 Number 0 rtl876x_io_dlps.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_ir.c 0x00000000 Number 0 rtl876x_ir.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_keyscan.c 0x00000000 Number 0 rtl876x_keyscan.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_lpc.c 0x00000000 Number 0 rtl876x_lpc.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_nvic.c 0x00000000 Number 0 rtl876x_nvic.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_pinmux.c 0x00000000 Number 0 rtl876x_pinmux.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_rcc.c 0x00000000 Number 0 rtl876x_rcc.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_rtc.c 0x00000000 Number 0 rtl876x_rtc.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_tim.c 0x00000000 Number 0 rtl876x_tim.o ABSOLUTE
+ ..\..\..\..\src\mcu\peripheral\rtl876x_uart.c 0x00000000 Number 0 rtl876x_uart.o ABSOLUTE
+ ..\..\..\..\src\mcu\rtl876x\overlay_mgr.c 0x00000000 Number 0 overlay_mgr.o ABSOLUTE
+ ..\..\..\..\src\mcu\rtl876x\system_rtl876x.c 0x00000000 Number 0 system_rtl876x.o ABSOLUTE
+ ..\..\..\..\src\platform\dfu_flash.c 0x00000000 Number 0 dfu_flash.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\address_module\\rcu_link_mgr.c 0x00000000 Number 0 rcu_link_mgr.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\app_task.c 0x00000000 Number 0 app_task.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\bat_module\\battery_driver.c 0x00000000 Number 0 battery_driver.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\buzzer_module\\buzzer_driver.c 0x00000000 Number 0 buzzer_driver.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\buzzer_module\\fms_service_handle.c 0x00000000 Number 0 fms_service_handle.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\dtm_module\\rcu_dtm_app.c 0x00000000 Number 0 rcu_dtm_app.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\frm_vpk\\frm_vpk_api\\frm_vpk_hal_sflash.c 0x00000000 Number 0 frm_vpk_hal_sflash.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\frm_vpk\\frm_vpk_api\\frm_vpk_log.c 0x00000000 Number 0 frm_vpk_log.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\frm_vpk\\src\\app_custom.c 0x00000000 Number 0 app_custom.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\frm_vpk\\src\\app_flash_write.c 0x00000000 Number 0 app_flash_write.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\ir_module\\ir_protocol_nec.c 0x00000000 Number 0 ir_protocol_nec.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\ir_module\\ir_send_driver.c 0x00000000 Number 0 ir_send_driver.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\ir_module\\ir_send_handle.c 0x00000000 Number 0 ir_send_handle.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\ir_module\\ir_service_handle.c 0x00000000 Number 0 ir_service_handle.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\key_module\\key_handle.c 0x00000000 Number 0 key_handle.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\key_module\\keyscan_driver.c 0x00000000 Number 0 keyscan_driver.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\led_module\\led_driver.c 0x00000000 Number 0 led_driver.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\led_module\\led_pwm_driver.c 0x00000000 Number 0 led_pwm_driver.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\loop_queue.c 0x00000000 Number 0 loop_queue.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\main.c 0x00000000 Number 0 main.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\profile_module\\dfu_service.c 0x00000000 Number 0 dfu_service.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\profile_module\\fms.c 0x00000000 Number 0 fms.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\profile_module\\hids_rmc.c 0x00000000 Number 0 hids_rmc.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\profile_module\\ir_service.c 0x00000000 Number 0 ir_service.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\profile_module\\ota_service.c 0x00000000 Number 0 ota_service.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\rcu_application.c 0x00000000 Number 0 rcu_application.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\rcu_gap.c 0x00000000 Number 0 rcu_gap.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\reset_watch_dog_timer.c 0x00000000 Number 0 reset_watch_dog_timer.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\rtc_module\\rtc_driver.c 0x00000000 Number 0 rtc_driver.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\swtimer.c 0x00000000 Number 0 swtimer.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\test_module\\data_uart_test.c 0x00000000 Number 0 data_uart_test.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\test_module\\mp_test.c 0x00000000 Number 0 mp_test.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\test_module\\single_tone.c 0x00000000 Number 0 single_tone.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\test_module\\uart_transport.c 0x00000000 Number 0 uart_transport.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\voice_module\\voice.c 0x00000000 Number 0 voice.o ABSOLUTE
+ ..\\..\\..\\..\\src\\app\\google_rcu\\voice_module\\voice_driver.c 0x00000000 Number 0 voice_driver.o ABSOLUTE
+ ..\\..\\..\\..\\src\\ble\\privacy\\privacy_mgnt.c 0x00000000 Number 0 privacy_mgnt.o ABSOLUTE
+ ..\\..\\..\\..\\src\\ble\\profile\\server\\atvv_service.c 0x00000000 Number 0 atvv_service.o ABSOLUTE
+ ..\\..\\..\\..\\src\\ble\\profile\\server\\bas.c 0x00000000 Number 0 bas.o ABSOLUTE
+ ..\\..\\..\\..\\src\\ble\\profile\\server\\dis.c 0x00000000 Number 0 dis.o ABSOLUTE
+ ..\\..\\..\\..\\src\\ble\\profile\\server\\vendor_service.c 0x00000000 Number 0 vendor_service.o ABSOLUTE
+ ..\\..\\..\\..\\src\\ble\\profile\\server\\voice_service.c 0x00000000 Number 0 voice_service.o ABSOLUTE
+ ..\\..\\..\\..\\src\\dfu\\dfu_application.c 0x00000000 Number 0 dfu_application.o ABSOLUTE
+ ..\\..\\..\\..\\src\\dfu\\dfu_main.c 0x00000000 Number 0 dfu_main.o ABSOLUTE
+ ..\\..\\..\\..\\src\\dfu\\dfu_task.c 0x00000000 Number 0 dfu_task.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_adc.c 0x00000000 Number 0 rtl876x_adc.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_aon_wdg.c 0x00000000 Number 0 rtl876x_aon_wdg.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_codec.c 0x00000000 Number 0 rtl876x_codec.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_gdma.c 0x00000000 Number 0 rtl876x_gdma.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_gpio.c 0x00000000 Number 0 rtl876x_gpio.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_i2s.c 0x00000000 Number 0 rtl876x_i2s.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_io_dlps.c 0x00000000 Number 0 rtl876x_io_dlps.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_ir.c 0x00000000 Number 0 rtl876x_ir.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_keyscan.c 0x00000000 Number 0 rtl876x_keyscan.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_lpc.c 0x00000000 Number 0 rtl876x_lpc.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_nvic.c 0x00000000 Number 0 rtl876x_nvic.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_pinmux.c 0x00000000 Number 0 rtl876x_pinmux.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_rcc.c 0x00000000 Number 0 rtl876x_rcc.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_rtc.c 0x00000000 Number 0 rtl876x_rtc.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_tim.c 0x00000000 Number 0 rtl876x_tim.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_uart.c 0x00000000 Number 0 rtl876x_uart.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876x.s 0x00000000 Number 0 startup_rtl876x.o ABSOLUTE
+ ..\\..\\..\\..\\src\\mcu\\rtl876x\\system_rtl876x.c 0x00000000 Number 0 system_rtl876x.o ABSOLUTE
+ ..\\..\\..\\..\\src\\platform\\dfu_flash.c 0x00000000 Number 0 dfu_flash.o ABSOLUTE
+ source\ima_adpcm_enc.c 0x00000000 Number 0 ima_adpcm_enc.o ABSOLUTE
+ VECTOR 0x00200000 Section 232 startup_rtl876x.o(VECTOR)
+ .app.data_ram.text 0x00207c00 Section 0 system_rtl876x.o(.app.data_ram.text)
+ .app.data_ram.text 0x00207d14 Section 0 rtl876x_io_dlps.o(.app.data_ram.text)
+ TIM_DLPS_Enter 0x00207d15 Thumb Code 138 rtl876x_io_dlps.o(.app.data_ram.text)
+ GPIO_DLPS_Enter 0x00207fb7 Thumb Code 74 rtl876x_io_dlps.o(.app.data_ram.text)
+ GPIO_DLPS_Exit 0x00208001 Thumb Code 80 rtl876x_io_dlps.o(.app.data_ram.text)
+ KeyScan_DLPS_Exit 0x00208051 Thumb Code 90 rtl876x_io_dlps.o(.app.data_ram.text)
+ TIM_DLPS_Exit 0x002080ab Thumb Code 182 rtl876x_io_dlps.o(.app.data_ram.text)
+ .app.data_ram.text 0x00208164 Section 0 main.o(.app.data_ram.text)
+ app_enter_dlps_config 0x00208165 * Thumb Code 32 main.o(.app.data_ram.text)
+ app_exit_dlps_config 0x00208185 * Thumb Code 36 main.o(.app.data_ram.text)
+ app_dlps_check_cb 0x002081a9 * Thumb Code 42 main.o(.app.data_ram.text)
+ .app.data_ram.text 0x00208228 Section 0 rcu_application.o(.app.data_ram.text)
+ .app.data_ram.text 0x002082fc Section 0 swtimer.o(.app.data_ram.text)
+ back_key_pressed_when_HW_reset_timer_cb 0x002082fd * Thumb Code 20 swtimer.o(.app.data_ram.text)
+ temp_off_latency_timer_cb 0x00208311 * Thumb Code 22 swtimer.o(.app.data_ram.text)
+ adv_timer_callback 0x00208327 * Thumb Code 26 swtimer.o(.app.data_ram.text)
+ adv_change_data_timer_callback 0x00208341 * Thumb Code 20 swtimer.o(.app.data_ram.text)
+ next_state_timeout_timer_callback 0x00208355 * Thumb Code 32 swtimer.o(.app.data_ram.text)
+ update_conn_params_timer_cb 0x00208375 * Thumb Code 68 swtimer.o(.app.data_ram.text)
+ aon_watch_dog_wake_up_dlps_callback 0x002083b9 * Thumb Code 16 swtimer.o(.app.data_ram.text)
+ system_reset_timer_callback 0x002083c9 * Thumb Code 12 swtimer.o(.app.data_ram.text)
+ .app.data_ram.text 0x002083ec Section 0 app_task.o(.app.data_ram.text)
+ app_main_task 0x002083ed * Thumb Code 134 app_task.o(.app.data_ram.text)
+ .app.data_ram.text 0x00208550 Section 0 reset_watch_dog_timer.o(.app.data_ram.text)
+ .app.data_ram.text 0x00208594 Section 0 loop_queue.o(.app.data_ram.text)
+ .app.data_ram.text 0x0020883c Section 0 rtc_driver.o(.app.data_ram.text)
+ .app.data_ram.text 0x00208894 Section 0 keyscan_driver.o(.app.data_ram.text)
+ keyscan_row_pad_config 0x00208895 Thumb Code 44 keyscan_driver.o(.app.data_ram.text)
+ keyscan_column_pad_config 0x002088c1 Thumb Code 44 keyscan_driver.o(.app.data_ram.text)
+ keyscan_timer_callback 0x00208b3d * Thumb Code 10 keyscan_driver.o(.app.data_ram.text)
+ .app.data_ram.text 0x00208b68 Section 0 key_handle.o(.app.data_ram.text)
+ key_handle_comb_keys_timer_cb 0x00208b69 * Thumb Code 90 key_handle.o(.app.data_ram.text)
+ notify_key_data_timer_cb 0x00208bc3 * Thumb Code 138 key_handle.o(.app.data_ram.text)
+ long_press_key_detect_timer_cb 0x00208c4d * Thumb Code 26 key_handle.o(.app.data_ram.text)
+ .app.data_ram.text 0x00208c7c Section 0 voice_driver.o(.app.data_ram.text)
+ .app.data_ram.text 0x00208ce8 Section 0 voice.o(.app.data_ram.text)
+ voice_handle_exception_timer_cb 0x00208ce9 * Thumb Code 54 voice.o(.app.data_ram.text)
+ .app.data_ram.text 0x00208d30 Section 0 ir_send_driver.o(.app.data_ram.text)
+ ir_send_int_handler 0x00208d31 * Thumb Code 96 ir_send_driver.o(.app.data_ram.text)
+ ir_send_rtc_handler 0x00208d91 * Thumb Code 50 ir_send_driver.o(.app.data_ram.text)
+ .app.data_ram.text 0x00208e28 Section 0 led_driver.o(.app.data_ram.text)
+ led_ctrl_timer_cb 0x00208e29 * Thumb Code 230 led_driver.o(.app.data_ram.text)
+ .app.data_ram.text 0x00208f1c Section 0 fms_service_handle.o(.app.data_ram.text)
+ fms_periodical_conn_callback 0x00208f1d * Thumb Code 40 fms_service_handle.o(.app.data_ram.text)
+ .app.data_ram.text 0x00208f4c Section 0 battery_driver.o(.app.data_ram.text)
+ bat_lpc_handler 0x00208f4d * Thumb Code 70 battery_driver.o(.app.data_ram.text)
+ .app.data_ram.text 0x00209050 Section 0 frm_vpk_log.o(.app.data_ram.text)
+ .text 0x0020908c Section 0 rtl876x_io_dlps.o(.text)
+ .data 0x002090a8 Section 46 dis.o(.data)
+ dis_ieee_data_list_len 0x002090a8 Data 1 dis.o(.data)
+ dis_pnp_id 0x002090a9 Data 7 dis.o(.data)
+ dis_system_id 0x002090b0 Data 8 dis.o(.data)
+ dis_ieee_data_list 0x002090b8 Data 30 dis.o(.data)
+ .data 0x002090d6 Section 8 hids_rmc.o(.data)
+ hids_protocol_mode 0x002090d6 Data 1 hids_rmc.o(.data)
+ hids_info 0x002090da Data 4 hids_rmc.o(.data)
+ .data 0x002090e0 Section 168 dfu_service.o(.data)
+ .data 0x00209188 Section 4 main.o(.data)
+ .data 0x0020918c Section 14 rcu_gap.o(.data)
+ google_wake_adv_data_len 0x0020918c Data 1 rcu_gap.o(.data)
+ google_wake_adv_data 0x0020918d Data 13 rcu_gap.o(.data)
+ .data 0x0020919a Section 2 privacy_mgnt.o(.data)
+ .data 0x0020919c Section 108 overlay_mgr.o(.data)
+ overlay_sections 0x0020919c Data 108 overlay_mgr.o(.data)
+ .data 0x00209208 Section 1 rcu_dtm_app.o(.data)
+ phy 0x00209208 Data 1 rcu_dtm_app.o(.data)
+ .data 0x00209209 Section 1 dfu_flash.o(.data)
+ .data 0x0020920a Section 14 keyscan_driver.o(.data)
+ KeyScanRowPINs 0x0020920a Data 7 keyscan_driver.o(.data)
+ KeyScanColumnPINs 0x00209211 Data 7 keyscan_driver.o(.data)
+ .data 0x00209218 Section 24 key_handle.o(.data)
+ .data 0x00209230 Section 48 key_handle.o(.data)
+ .data 0x00209260 Section 1 ir_send_handle.o(.data)
+ ir_send_key_state 0x00209260 Data 1 ir_send_handle.o(.data)
+ .data 0x00209264 Section 20 ir_service_handle.o(.data)
+ IR_Table_FTL_Addr_Info 0x00209264 Data 20 ir_service_handle.o(.data)
+ .data 0x00209278 Section 2 fms_service_handle.o(.data)
+ Fms_Current_Mode 0x00209278 Data 2 fms_service_handle.o(.data)
+ .data 0x0020927c Section 4 app_custom.o(.data)
+ .data 0x00209280 Section 50 adc_lib.o(.data)
+ .data 0x002092b4 Section 420 ima_adpcm_enc.o(.data)
+ indexTable 0x002092b4 Data 64 ima_adpcm_enc.o(.data)
+ stepsizeTable 0x002092f4 Data 356 ima_adpcm_enc.o(.data)
+ .bss 0x00209458 Section 20 system_rtl876x.o(.bss)
+ .bss 0x0020946c Section 304 rtl876x_io_dlps.o(.bss)
+ .bss 0x0020959c Section 1 rtl876x_rtc.o(.bss)
+ is_called 0x0020959c Data 1 rtl876x_rtc.o(.bss)
+ .bss 0x0020959d Section 1 rtl876x_lpc.o(.bss)
+ is_called 0x0020959d Data 1 rtl876x_lpc.o(.bss)
+ .bss 0x0020959e Section 1 rtl876x_aon_wdg.o(.bss)
+ is_called 0x0020959e Data 1 rtl876x_aon_wdg.o(.bss)
+ .bss 0x002095a0 Section 132 dis.o(.bss)
+ dis_manufacturer_name_len 0x002095a0 Data 1 dis.o(.bss)
+ dis_model_number_len 0x002095a1 Data 1 dis.o(.bss)
+ dis_serial_number_len 0x002095a2 Data 1 dis.o(.bss)
+ dis_hardware_rev_len 0x002095a3 Data 1 dis.o(.bss)
+ dis_firmware_rev_len 0x002095a4 Data 1 dis.o(.bss)
+ dis_software_rev_len 0x002095a5 Data 1 dis.o(.bss)
+ pfn_dis_cb 0x002095a8 Data 4 dis.o(.bss)
+ dis_manufacturer_name 0x002095ac Data 20 dis.o(.bss)
+ dis_model_number 0x002095c0 Data 20 dis.o(.bss)
+ dis_serial_number 0x002095d4 Data 20 dis.o(.bss)
+ dis_hardware_rev 0x002095e8 Data 20 dis.o(.bss)
+ dis_firmware_rev 0x002095fc Data 20 dis.o(.bss)
+ dis_software_rev 0x00209610 Data 20 dis.o(.bss)
+ .bss 0x00209624 Section 8 bas.o(.bss)
+ battery_level 0x00209624 Data 1 bas.o(.bss)
+ bas_read_battery_level_pending 0x00209625 Data 1 bas.o(.bss)
+ pfn_bas_cb 0x00209628 Data 4 bas.o(.bss)
+ .bss 0x0020962c Section 12 hids_rmc.o(.bss)
+ hids_suspand_mode 0x0020962c Data 1 hids_rmc.o(.bss)
+ RmcDataLen 0x0020962e Data 2 hids_rmc.o(.bss)
+ pfn_hids_cb 0x00209630 Data 4 hids_rmc.o(.bss)
+ p_report_data 0x00209634 Data 4 hids_rmc.o(.bss)
+ .bss 0x00209638 Section 16 vendor_service.o(.bss)
+ .bss 0x00209648 Section 4 vendor_service.o(.bss)
+ pfn_vendor_svc_cb 0x00209648 Data 4 vendor_service.o(.bss)
+ .bss 0x0020964c Section 74 atvv_service.o(.bss)
+ pfn_atvv_cb 0x0020964c Data 4 atvv_service.o(.bss)
+ .bss 0x00209698 Section 4 ir_service.o(.bss)
+ pfn_ir_svc_cb 0x00209698 Data 4 ir_service.o(.bss)
+ .bss 0x0020969c Section 2220 dfu_service.o(.bss)
+ buffer_check_en 0x0020969d Data 1 dfu_service.o(.bss)
+ dfu_service_id 0x0020969e Data 1 dfu_service.o(.bss)
+ dfu_resend_offset 0x002096a4 Data 4 dfu_service.o(.bss)
+ .bss 0x00209f48 Section 88 ota_service.o(.bss)
+ image_version 0x00209f68 Data 44 ota_service.o(.bss)
+ DeviceInfo 0x00209f94 Data 12 ota_service.o(.bss)
+ .bss 0x00209fa0 Section 8 fms.o(.bss)
+ Fms_Ctl_mode 0x00209fa0 Data 2 fms.o(.bss)
+ pfn_fms_cb 0x00209fa4 Data 4 fms.o(.bss)
+ .bss 0x00209fa8 Section 180 rcu_application.o(.bss)
+ .bss 0x0020a05c Section 96 rcu_gap.o(.bss)
+ app_scan_rsp_data_len 0x0020a05c Data 1 rcu_gap.o(.bss)
+ app_pairing_adv_data_len 0x0020a05d Data 1 rcu_gap.o(.bss)
+ custom_wakeup_adv_data_len 0x0020a05e Data 1 rcu_gap.o(.bss)
+ app_scan_rsp_data 0x0020a05f Data 31 rcu_gap.o(.bss)
+ app_pairing_adv_data 0x0020a07e Data 31 rcu_gap.o(.bss)
+ custom_wakeup_adv_data 0x0020a09d Data 31 rcu_gap.o(.bss)
+ .bss 0x0020a0bc Section 32 swtimer.o(.bss)
+ .bss 0x0020a0dc Section 16 app_task.o(.bss)
+ .bss 0x0020a0ec Section 16 privacy_mgnt.o(.bss)
+ privacy_app_cb 0x0020a0f4 Data 4 privacy_mgnt.o(.bss)
+ .bss 0x0020a0fc Section 8 overlay_mgr.o(.bss)
+ .bss 0x0020a104 Section 10 rcu_dtm_app.o(.bss)
+ up_2_bits 0x0020a104 Data 1 rcu_dtm_app.o(.bss)
+ mod_idx 0x0020a105 Data 1 rcu_dtm_app.o(.bss)
+ lcl_feats 0x0020a106 Data 8 rcu_dtm_app.o(.bss)
+ .bss 0x0020a110 Section 8 rtc_driver.o(.bss)
+ rtc_ovf_cnt 0x0020a110 Data 4 rtc_driver.o(.bss)
+ rtc_driver_comp_0_cb 0x0020a114 Data 4 rtc_driver.o(.bss)
+ .bss 0x0020a118 Section 12 dfu_flash.o(.bss)
+ img_total_len 0x0020a118 Data 4 dfu_flash.o(.bss)
+ total_block_cnt 0x0020a11c Data 4 dfu_flash.o(.bss)
+ block_cnt 0x0020a120 Data 4 dfu_flash.o(.bss)
+ .bss 0x0020a124 Section 48 keyscan_driver.o(.bss)
+ keyscan_timer 0x0020a124 Data 4 keyscan_driver.o(.bss)
+ .bss 0x0020a154 Section 552 key_handle.o(.bss)
+ current_cache_fifo_items_cnt 0x0020a154 Data 1 key_handle.o(.bss)
+ cache_fifo_output_cnt 0x0020a155 Data 1 key_handle.o(.bss)
+ Key_Press_Cache_FIFO 0x0020a164 Data 22 key_handle.o(.bss)
+ .bss 0x0020a37c Section 1128 voice_driver.o(.bss)
+ voice_driver_gdma_link_list 0x0020a37c Data 40 voice_driver.o(.bss)
+ .bss 0x0020a7e4 Section 16 voice.o(.bss)
+ voice_exception_timer 0x0020a7e4 Data 4 voice.o(.bss)
+ p_voice_queue 0x0020a7e8 Data 4 voice.o(.bss)
+ .bss 0x0020a7f4 Section 8 ir_send_driver.o(.bss)
+ ir_send_struct 0x0020a7f4 Data 8 ir_send_driver.o(.bss)
+ .bss 0x0020a7fc Section 1628 ir_send_handle.o(.bss)
+ ir_send_parameters 0x0020a7fc Data 1628 ir_send_handle.o(.bss)
+ .bss 0x0020ae58 Section 2568 ir_service_handle.o(.bss)
+ ir_programing_timer 0x0020ae58 Data 4 ir_service_handle.o(.bss)
+ ir_table 0x0020ae5c Data 2540 ir_service_handle.o(.bss)
+ .bss 0x0020b860 Section 40 led_driver.o(.bss)
+ led_global_tick_cnt 0x0020b860 Data 4 led_driver.o(.bss)
+ led_ctrl_timer 0x0020b864 Data 4 led_driver.o(.bss)
+ led_ctrl_data 0x0020b868 Data 32 led_driver.o(.bss)
+ .bss 0x0020b888 Section 2 led_pwm_driver.o(.bss)
+ led_pwm_init_states 0x0020b888 Data 1 led_pwm_driver.o(.bss)
+ led_on_off_states 0x0020b889 Data 1 led_pwm_driver.o(.bss)
+ .bss 0x0020b88c Section 12 buzzer_driver.o(.bss)
+ .bss 0x0020b898 Section 8 fms_service_handle.o(.bss)
+ Fms_Handle_Notify_Flag 0x0020b898 Data 1 fms_service_handle.o(.bss)
+ Fms_Periodical_Conn_Timer 0x0020b89c Data 4 fms_service_handle.o(.bss)
+ .bss 0x0020b8a0 Section 6 battery_driver.o(.bss)
+ cur_bat_info 0x0020b8a0 Data 6 battery_driver.o(.bss)
+ .bss 0x0020b8a8 Section 8 gap_lib_system_call.o(.bss)
+ .bss 0x0020b8b0 Section 84 adc_lib.o(.bss)
+ .bss 0x0020b904 Section 6 ima_adpcm_enc.o(.bss)
+ .bss 0x0020b90c Section 228 rand.o(.bss)
+ .bss 0x0020b9f0 Section 20 rt_locale.o(.bss)
+ __rt_locale_data 0x0020b9f0 Data 20 rt_locale.o(.bss)
+ .app.overlay_a 0x0020ba04 Section 0 system_rtl876x.o(.app.overlay_a)
+ .app.flash.header 0x00832000 Section 1024 system_rtl876x.o(.app.flash.header)
+ __tagsym$$used 0x00832000 Number 0 system_rtl876x.o(.app.flash.header)
+ __tagsym$$used 0x008321e0 Number 0 system_rtl876x.o(.app.flash.header)
+ RESET 0x00832400 Section 8 startup_rtl876x.o(RESET)
+ !!!main 0x00832408 Section 8 __main.o(!!!main)
+ .ARM.Collect$$_printf_percent$$00000000 0x00832410 Section 2 _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000)
+ .ARM.Collect$$_printf_percent$$00000001 0x00832412 Section 10 _printf_n.o(.ARM.Collect$$_printf_percent$$00000001)
+ .ARM.Collect$$_printf_percent$$00000002 0x0083241c Section 10 _printf_p.o(.ARM.Collect$$_printf_percent$$00000002)
+ .ARM.Collect$$_printf_percent$$00000003 0x00832426 Section 10 _printf_f.o(.ARM.Collect$$_printf_percent$$00000003)
+ .ARM.Collect$$_printf_percent$$00000004 0x00832430 Section 10 _printf_e.o(.ARM.Collect$$_printf_percent$$00000004)
+ .ARM.Collect$$_printf_percent$$00000005 0x0083243a Section 10 _printf_g.o(.ARM.Collect$$_printf_percent$$00000005)
+ .ARM.Collect$$_printf_percent$$00000006 0x00832444 Section 10 _printf_a.o(.ARM.Collect$$_printf_percent$$00000006)
+ .ARM.Collect$$_printf_percent$$00000007 0x0083244e Section 10 _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007)
+ .ARM.Collect$$_printf_percent$$00000008 0x00832458 Section 10 _printf_i.o(.ARM.Collect$$_printf_percent$$00000008)
+ .ARM.Collect$$_printf_percent$$00000009 0x00832462 Section 10 _printf_d.o(.ARM.Collect$$_printf_percent$$00000009)
+ .ARM.Collect$$_printf_percent$$0000000A 0x0083246c Section 10 _printf_u.o(.ARM.Collect$$_printf_percent$$0000000A)
+ .ARM.Collect$$_printf_percent$$0000000B 0x00832476 Section 10 _printf_o.o(.ARM.Collect$$_printf_percent$$0000000B)
+ .ARM.Collect$$_printf_percent$$0000000C 0x00832480 Section 10 _printf_x.o(.ARM.Collect$$_printf_percent$$0000000C)
+ .ARM.Collect$$_printf_percent$$0000000D 0x0083248a Section 10 _printf_lli.o(.ARM.Collect$$_printf_percent$$0000000D)
+ .ARM.Collect$$_printf_percent$$0000000E 0x00832494 Section 10 _printf_lld.o(.ARM.Collect$$_printf_percent$$0000000E)
+ .ARM.Collect$$_printf_percent$$0000000F 0x0083249e Section 10 _printf_llu.o(.ARM.Collect$$_printf_percent$$0000000F)
+ .ARM.Collect$$_printf_percent$$00000010 0x008324a8 Section 10 _printf_llo.o(.ARM.Collect$$_printf_percent$$00000010)
+ .ARM.Collect$$_printf_percent$$00000011 0x008324b2 Section 10 _printf_llx.o(.ARM.Collect$$_printf_percent$$00000011)
+ .ARM.Collect$$_printf_percent$$00000012 0x008324bc Section 10 _printf_l.o(.ARM.Collect$$_printf_percent$$00000012)
+ .ARM.Collect$$_printf_percent$$00000013 0x008324c6 Section 10 _printf_c.o(.ARM.Collect$$_printf_percent$$00000013)
+ .ARM.Collect$$_printf_percent$$00000014 0x008324d0 Section 10 _printf_s.o(.ARM.Collect$$_printf_percent$$00000014)
+ .ARM.Collect$$_printf_percent$$00000015 0x008324da Section 10 _printf_lc.o(.ARM.Collect$$_printf_percent$$00000015)
+ .ARM.Collect$$_printf_percent$$00000016 0x008324e4 Section 10 _printf_ls.o(.ARM.Collect$$_printf_percent$$00000016)
+ .ARM.Collect$$_printf_percent$$00000017 0x008324ee Section 4 _printf_percent_end.o(.ARM.Collect$$_printf_percent$$00000017)
+ .ARM.Collect$$libinit$$00000000 0x008324f2 Section 2 libinit.o(.ARM.Collect$$libinit$$00000000)
+ .ARM.Collect$$libinit$$00000002 0x008324f4 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000002)
+ .ARM.Collect$$libinit$$00000004 0x008324f4 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000004)
+ .ARM.Collect$$libinit$$0000000A 0x008324f4 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000000A)
+ .ARM.Collect$$libinit$$0000000C 0x008324f4 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000000C)
+ .ARM.Collect$$libinit$$0000000D 0x008324f4 Section 4 libinit2.o(.ARM.Collect$$libinit$$0000000D)
+ .ARM.Collect$$libinit$$0000000E 0x008324f8 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000000E)
+ .ARM.Collect$$libinit$$0000000F 0x008324f8 Section 6 libinit2.o(.ARM.Collect$$libinit$$0000000F)
+ .ARM.Collect$$libinit$$00000011 0x008324fe Section 0 libinit2.o(.ARM.Collect$$libinit$$00000011)
+ .ARM.Collect$$libinit$$00000012 0x008324fe Section 12 libinit2.o(.ARM.Collect$$libinit$$00000012)
+ .ARM.Collect$$libinit$$00000013 0x0083250a Section 0 libinit2.o(.ARM.Collect$$libinit$$00000013)
+ .ARM.Collect$$libinit$$00000015 0x0083250a Section 0 libinit2.o(.ARM.Collect$$libinit$$00000015)
+ .ARM.Collect$$libinit$$00000016 0x0083250a Section 10 libinit2.o(.ARM.Collect$$libinit$$00000016)
+ .ARM.Collect$$libinit$$00000017 0x00832514 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000017)
+ .ARM.Collect$$libinit$$00000019 0x00832514 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000019)
+ .ARM.Collect$$libinit$$0000001B 0x00832514 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000001B)
+ .ARM.Collect$$libinit$$0000001D 0x00832514 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000001D)
+ .ARM.Collect$$libinit$$0000001F 0x00832514 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000001F)
+ .ARM.Collect$$libinit$$00000021 0x00832514 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000021)
+ .ARM.Collect$$libinit$$00000023 0x00832514 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000023)
+ .ARM.Collect$$libinit$$00000025 0x00832514 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000025)
+ .ARM.Collect$$libinit$$0000002C 0x00832514 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000002C)
+ .ARM.Collect$$libinit$$0000002E 0x00832514 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000002E)
+ .ARM.Collect$$libinit$$00000030 0x00832514 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000030)
+ .ARM.Collect$$libinit$$00000032 0x00832514 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000032)
+ .ARM.Collect$$libinit$$00000033 0x00832514 Section 2 libinit2.o(.ARM.Collect$$libinit$$00000033)
+ .ARM.Collect$$rtentry$$00000000 0x00832516 Section 0 __rtentry.o(.ARM.Collect$$rtentry$$00000000)
+ .ARM.Collect$$rtentry$$00000002 0x00832516 Section 0 __rtentry2.o(.ARM.Collect$$rtentry$$00000002)
+ .ARM.Collect$$rtentry$$00000005 0x00832516 Section 4 __rtentry5.o(.ARM.Collect$$rtentry$$00000005)
+ .ARM.Collect$$rtentry$$00000009 0x0083251a Section 0 __rtentry2.o(.ARM.Collect$$rtentry$$00000009)
+ .ARM.Collect$$rtentry$$0000000A 0x0083251a Section 4 __rtentry2.o(.ARM.Collect$$rtentry$$0000000A)
+ .ARM.Collect$$rtentry$$0000000C 0x0083251e Section 0 __rtentry2.o(.ARM.Collect$$rtentry$$0000000C)
+ .ARM.Collect$$rtentry$$0000000D 0x0083251e Section 8 __rtentry2.o(.ARM.Collect$$rtentry$$0000000D)
+ .ARM.Collect$$rtentry$$00002716 0x00832528 Section 4 __rtentry5.o(.ARM.Collect$$rtentry$$00002716)
+ __lit__00000000 0x00832528 Data 4 __rtentry5.o(.ARM.Collect$$rtentry$$00002716)
+ .app.flash.text 0x0083252c Section 0 system_rtl876x.o(.app.flash.text)
+ .text 0x00832904 Section 84 startup_rtl876x.o(.text)
+ DEFAULT_HANDLER_TXT 0x00832914 Data 0 startup_rtl876x.o(.text)
+ .text 0x00832958 Section 0 system_rtl876x.o(.text)
+ .text 0x00832b34 Section 0 rtl876x_gpio.o(.text)
+ .text 0x00832cc8 Section 0 rtl876x_ir.o(.text)
+ .text 0x00832fc0 Section 0 rtl876x_keyscan.o(.text)
+ .text 0x00833160 Section 0 rtl876x_rtc.o(.text)
+ .text 0x008333bc Section 0 rtl876x_codec.o(.text)
+ .text 0x00833700 Section 0 rtl876x_i2s.o(.text)
+ .text 0x00833830 Section 0 rtl876x_pinmux.o(.text)
+ .text 0x00833b98 Section 0 rtl876x_nvic.o(.text)
+ .text 0x00833c60 Section 0 rtl876x_rcc.o(.text)
+ .text 0x00833f70 Section 0 rtl876x_tim.o(.text)
+ .text 0x0083410c Section 0 rtl876x_gdma.o(.text)
+ GDMA_GetSuspendChannelStatus 0x0083441b Thumb Code 14 rtl876x_gdma.o(.text)
+ .text 0x00834440 Section 0 rtl876x_uart.o(.text)
+ .text 0x00834694 Section 0 rtl876x_adc.o(.text)
+ .text 0x008349a0 Section 0 rtl876x_lpc.o(.text)
+ .text 0x00834bec Section 0 rtl876x_aon_wdg.o(.text)
+ AON_WDG_WriteReg 0x00834bed Thumb Code 38 rtl876x_aon_wdg.o(.text)
+ .text 0x00834e14 Section 0 dis.o(.text)
+ .text 0x00835080 Section 0 bas.o(.text)
+ .text 0x008351ec Section 0 hids_rmc.o(.text)
+ .text 0x00835454 Section 0 vendor_service.o(.text)
+ .text 0x00835564 Section 0 atvv_service.o(.text)
+ .text 0x00835710 Section 0 ir_service.o(.text)
+ .text 0x00835814 Section 0 dfu_service.o(.text)
+ buf_swap 0x0083654f Thumb Code 32 dfu_service.o(.text)
+ .text 0x00836584 Section 0 ota_service.o(.text)
+ get_ota_active_bank_image_info 0x0083661d Thumb Code 108 ota_service.o(.text)
+ .text 0x00836a04 Section 0 fms.o(.text)
+ .text 0x00836b30 Section 0 main.o(.text)
+ global_data_init 0x00836b3d Thumb Code 348 main.o(.text)
+ app_normal_power_on_seq 0x00836dc9 Thumb Code 108 main.o(.text)
+ app_le_profile_init 0x00836e35 Thumb Code 100 main.o(.text)
+ .text 0x00836ee8 Section 0 rcu_application.o(.text)
+ app_stop_adv_reason_handler 0x00836ee9 Thumb Code 256 rcu_application.o(.text)
+ app_disconn_reason_handler 0x00836fe9 Thumb Code 150 rcu_application.o(.text)
+ app_dis_srv_cb 0x00837141 Thumb Code 200 rcu_application.o(.text)
+ app_dfu_srv_cb 0x00837209 Thumb Code 368 rcu_application.o(.text)
+ periph_handle_dev_state_evt 0x00837379 Thumb Code 350 rcu_application.o(.text)
+ periph_handle_conn_state_evt 0x008374d7 Thumb Code 314 rcu_application.o(.text)
+ periph_handle_authen_state_evt 0x00837611 Thumb Code 240 rcu_application.o(.text)
+ periph_conn_param_update_evt 0x00837701 Thumb Code 248 rcu_application.o(.text)
+ periph_handle_gap_msg 0x008377f9 Thumb Code 322 rcu_application.o(.text)
+ app_general_srv_cb 0x00837c39 Thumb Code 118 rcu_application.o(.text)
+ app_hid_srv_cb 0x00837caf Thumb Code 136 rcu_application.o(.text)
+ app_vendor_srv_cb 0x00837d37 Thumb Code 158 rcu_application.o(.text)
+ .text 0x00837df8 Section 0 rcu_gap.o(.text)
+ .text 0x008388f4 Section 0 swtimer.o(.text)
+ .text 0x00838b4c Section 0 app_task.o(.text)
+ .text 0x00838b9c Section 0 reset_watch_dog_timer.o(.text)
+ .text 0x00838bfc Section 0 privacy_mgnt.o(.text)
+ .text 0x00839308 Section 0 overlay_mgr.o(.text)
+ .text 0x00839384 Section 0 loop_queue.o(.text)
+ .text 0x00839418 Section 0 rcu_dtm_app.o(.text)
+ .text 0x0083984c Section 0 rtc_driver.o(.text)
+ .text 0x008399a8 Section 0 dfu_flash.o(.text)
+ dfu_write 0x008399c5 Thumb Code 180 dfu_flash.o(.text)
+ flash_erase_sector 0x00839f3f Thumb Code 32 dfu_flash.o(.text)
+ flash_erase_block 0x00839f5f Thumb Code 34 dfu_flash.o(.text)
+ dfu_flash_check_blank 0x00839f81 Thumb Code 136 dfu_flash.o(.text)
+ check_dfu_update_image_length 0x0083a009 Thumb Code 110 dfu_flash.o(.text)
+ .text 0x0083a0c4 Section 0 keyscan_driver.o(.text)
+ keyscan_disable_wakeup_config 0x0083a143 Thumb Code 28 keyscan_driver.o(.text)
+ .text 0x0083a188 Section 0 key_handle.o(.text)
+ key_handle_prepare_hid_usage_buffer 0x0083a1ad Thumb Code 140 key_handle.o(.text)
+ key_handle_notify_hid_usage_buffer 0x0083a239 Thumb Code 208 key_handle.o(.text)
+ key_handle_inqueue_key_pressed_cache_fifo 0x0083a331 Thumb Code 86 key_handle.o(.text)
+ key_handle_process_factory_reset_event 0x0083a4af Thumb Code 74 key_handle.o(.text)
+ key_handle_one_key_scenario 0x0083a4f9 Thumb Code 498 key_handle.o(.text)
+ key_handle_detect_special_keys 0x0083a7d5 Thumb Code 306 key_handle.o(.text)
+ key_handle_process_repairing_event 0x0083ac73 Thumb Code 90 key_handle.o(.text)
+ key_handle_check_navy_key 0x0083accd Thumb Code 54 key_handle.o(.text)
+ .text 0x0083ad54 Section 0 voice_driver.o(.text)
+ voice_driver_init_rx_gdma 0x0083ad55 Thumb Code 238 voice_driver.o(.text)
+ voice_driver_init_i2s 0x0083af2d Thumb Code 112 voice_driver.o(.text)
+ voice_driver_init_codec 0x0083af9d Thumb Code 102 voice_driver.o(.text)
+ .text 0x0083b030 Section 0 voice.o(.text)
+ voice_handle_notify_voice_data 0x0083b031 Thumb Code 316 voice.o(.text)
+ voice_handle_gdma_event 0x0083b253 Thumb Code 182 voice.o(.text)
+ voice_handle_atv_audio_sync 0x0083ba75 Thumb Code 98 voice.o(.text)
+ voice_handle_encode_raw_data 0x0083bad7 Thumb Code 74 voice.o(.text)
+ .text 0x0083bb54 Section 0 ir_send_driver.o(.text)
+ ir_driver_tx_gdma_init 0x0083bb55 Thumb Code 104 ir_send_driver.o(.text)
+ ir_send_driver_init 0x0083be09 Thumb Code 108 ir_send_driver.o(.text)
+ .text 0x0083beb0 Section 0 ir_send_handle.o(.text)
+ ir_send_command_encode 0x0083c2bf Thumb Code 62 ir_send_handle.o(.text)
+ .text 0x0083c2fc Section 0 ir_protocol_nec.o(.text)
+ ir_protocol_nec_command_set_tx_buf 0x0083c2fd Thumb Code 200 ir_protocol_nec.o(.text)
+ hl_time2_tx_buf_count 0x0083c46b Thumb Code 32 ir_protocol_nec.o(.text)
+ .text 0x0083c4a4 Section 0 ir_service_handle.o(.text)
+ ir_service_handle_activate_ir_table 0x0083c4c5 Thumb Code 56 ir_service_handle.o(.text)
+ ir_service_handle_write_prog_control_char 0x0083c59d Thumb Code 174 ir_service_handle.o(.text)
+ ir_service_handle_back_up_ftl_table 0x0083c66f Thumb Code 154 ir_service_handle.o(.text)
+ ir_service_handle_restore_ir_table_from_ftl 0x0083c709 Thumb Code 234 ir_service_handle.o(.text)
+ ir_service_handle_write_char_cb 0x0083ca79 Thumb Code 142 ir_service_handle.o(.text)
+ ir_service_handle_write_suppress_char 0x0083cb07 Thumb Code 86 ir_service_handle.o(.text)
+ ir_service_handle_write_code_char 0x0083cb5d Thumb Code 96 ir_service_handle.o(.text)
+ ir_service_handle_ir_table_add_item 0x0083cbbd Thumb Code 124 ir_service_handle.o(.text)
+ .text 0x0083cc64 Section 0 led_driver.o(.text)
+ .text 0x0083cd78 Section 0 led_pwm_driver.o(.text)
+ led_module_update_pwm_states 0x0083cd79 Thumb Code 26 led_pwm_driver.o(.text)
+ led_module_update_on_off_states 0x0083cd93 Thumb Code 26 led_pwm_driver.o(.text)
+ .text 0x0083ced8 Section 0 buzzer_driver.o(.text)
+ buzzer_init_driver 0x0083cfc3 Thumb Code 128 buzzer_driver.o(.text)
+ .text 0x0083d060 Section 0 fms_service_handle.o(.text)
+ fms_handle_write_char_cb 0x0083d1d5 Thumb Code 92 fms_service_handle.o(.text)
+ fms_handle_write_data_char 0x0083d231 Thumb Code 134 fms_service_handle.o(.text)
+ .text 0x0083d304 Section 0 battery_driver.o(.text)
+ bat_calibrate_voltage 0x0083d305 Thumb Code 122 battery_driver.o(.text)
+ bat_driver_lpc_init 0x0083d37f Thumb Code 106 battery_driver.o(.text)
+ bat_calculate_bat_level 0x0083d675 Thumb Code 224 battery_driver.o(.text)
+ bat_handle_key_pressed_event 0x0083d755 Thumb Code 72 battery_driver.o(.text)
+ .text 0x0083d7a8 Section 0 app_custom.o(.text)
+ .text 0x0083df14 Section 0 frm_vpk_hal_sflash.o(.text)
+ .text 0x0083dfc0 Section 0 gap_lib_system_call.o(.text)
+ .text 0x0083f08c Section 0 adc_lib.o(.text)
+ ADC_GetKValue 0x0083f08d Thumb Code 66 adc_lib.o(.text)
+ ADC_GetKVoltage 0x0083f0cf Thumb Code 82 adc_lib.o(.text)
+ .text 0x0083f398 Section 0 llmul.o(.text)
+ .text 0x0083f3c8 Section 0 lludiv.o(.text)
+ .text 0x0083f4cc Section 0 vsprintf.o(.text)
+ .text 0x0083f4f0 Section 0 rand.o(.text)
+ .text 0x0083f52c Section 346 aeabi_sdiv.o(.text)
+ .text 0x0083f688 Section 0 d2f.o(.text)
+ .text 0x0083f704 Section 0 daddsub.o(.text)
+ _dadd1 0x0083f705 Thumb Code 290 daddsub.o(.text)
+ _dsub1 0x0083f827 Thumb Code 470 daddsub.o(.text)
+ .text 0x0083fa5c Section 0 ddiv.o(.text)
+ .text 0x0083fea4 Section 0 dfixui.o(.text)
+ .text 0x0083feec Section 0 dflti.o(.text)
+ .text 0x0083ff44 Section 0 dmul.o(.text)
+ .text 0x0084018c Section 0 f2d.o(.text)
+ .text 0x008401e0 Section 0 fdiv.o(.text)
+ .text 0x00840340 Section 0 ffixui.o(.text)
+ .text 0x00840370 Section 0 fflti.o(.text)
+ .text 0x008403ce Section 0 _printf_pad.o(.text)
+ .text 0x0084041c Section 0 _printf_truncate.o(.text)
+ .text 0x00840440 Section 0 _printf_str.o(.text)
+ .text 0x00840494 Section 0 _printf_dec.o(.text)
+ .text 0x00840500 Section 0 _printf_charcount.o(.text)
+ .text 0x00840528 Section 0 _printf_char_common.o(.text)
+ _printf_input_char 0x00840529 Thumb Code 10 _printf_char_common.o(.text)
+ .text 0x00840558 Section 0 _sputc.o(.text)
+ .text 0x00840564 Section 0 _printf_wctomb.o(.text)
+ .text 0x00840620 Section 0 _printf_longlong_dec.o(.text)
+ .text 0x00840690 Section 0 _printf_oct_int_ll.o(.text)
+ _printf_longlong_oct_internal 0x00840691 Thumb Code 0 _printf_oct_int_ll.o(.text)
+ .text 0x00840700 Section 0 _printf_hex_int_ll_ptr.o(.text)
+ _printf_hex_common 0x00840701 Thumb Code 0 _printf_hex_int_ll_ptr.o(.text)
+ .text 0x00840798 Section 0 __printf_flags_ss_wp.o(.text)
+ .text 0x00840920 Section 0 lludiv10.o(.text)
+ .text 0x0084099a Section 0 _printf_intcommon.o(.text)
+ .text 0x00840a4c Section 0 _printf_fp_dec.o(.text)
+ _fp_digits 0x00840a4f Thumb Code 412 _printf_fp_dec.o(.text)
+ .text 0x00840e64 Section 0 _printf_fp_hex.o(.text)
+ .text 0x0084113c Section 0 _printf_char.o(.text)
+ .text 0x0084116a Section 0 _printf_wchar.o(.text)
+ .text 0x00841198 Section 0 _wcrtomb.o(.text)
+ .text 0x008411d8 Section 0 rtudiv10.o(.text)
+ .text 0x00841200 Section 16 rt_ctype_table.o(.text)
+ .text 0x00841210 Section 8 rt_locale.o(.text)
+ .text 0x00841218 Section 0 _printf_fp_infnan.o(.text)
+ .text 0x008412a0 Section 0 bigflt0.o(.text)
+ .text 0x00841378 Section 0 btod.o(.text)
+ btod_internal_mul 0x008413b9 Thumb Code 492 btod.o(.text)
+ btod_internal_div 0x008415a5 Thumb Code 520 btod.o(.text)
+ .text 0x008418f8 Section 0 strcmp.o(.text)
+ i.__ARM_common_ll_muluu 0x00841980 Section 0 btod.o(i.__ARM_common_ll_muluu)
+ i.__ARM_common_switch8 0x008419b0 Section 0 dis.o(i.__ARM_common_switch8)
+ i.__ARM_fpclassify 0x008419cc Section 0 fpclassify.o(i.__ARM_fpclassify)
+ i._is_digit 0x008419f8 Section 0 __printf_wp.o(i._is_digit)
+ i.ima_adpcm_encode 0x00841a08 Section 0 ima_adpcm_enc.o(i.ima_adpcm_encode)
+ locale$$code 0x00841b40 Section 44 lc_numeric_c.o(locale$$code)
+ locale$$code 0x00841b6c Section 44 lc_ctype_c.o(locale$$code)
+ x$fpl$fadd 0x00841b98 Section 140 faddsub.o(x$fpl$fadd)
+ _fadd1 0x00841ba5 Thumb Code 0 faddsub.o(x$fpl$fadd)
+ x$fpl$fmul 0x00841c24 Section 176 fmul.o(x$fpl$fmul)
+ x$fpl$fsub 0x00841cd4 Section 208 faddsub.o(x$fpl$fsub)
+ _fsub1 0x00841ce1 Thumb Code 0 faddsub.o(x$fpl$fsub)
+ x$fpl$printf1 0x00841da4 Section 16 printf1.o(x$fpl$printf1)
+ x$fpl$printf2 0x00841db4 Section 16 printf2.o(x$fpl$printf2)
+ .constdata 0x00841dc4 Section 12 system_rtl876x.o(.constdata)
+ x$fpl$usenofp 0x00841dc4 Section 0 usenofp.o(x$fpl$usenofp)
+ .constdata 0x00841dd0 Section 256 system_rtl876x.o(.constdata)
+ __func__ 0x00841dd0 Data 7 system_rtl876x.o(.constdata)
+ __func__ 0x00841dd7 Data 7 system_rtl876x.o(.constdata)
+ __func__ 0x00841dde Data 8 system_rtl876x.o(.constdata)
+ .constdata 0x00841ed0 Section 156 rtl876x_pinmux.o(.constdata)
+ .constdata 0x00841f6c Section 544 dis.o(.constdata)
+ dis_attr_tbl 0x00841f6c Data 532 dis.o(.constdata)
+ .constdata 0x0084218c Section 124 bas.o(.constdata)
+ bas_attr_tbl 0x0084218c Data 112 bas.o(.constdata)
+ .constdata 0x00842208 Section 544 hids_rmc.o(.constdata)
+ hids_report_descriptor 0x00842208 Data 55 hids_rmc.o(.constdata)
+ .constdata 0x00842428 Section 16 vendor_service.o(.constdata)
+ GATT_UUID_VENDOR_SERVICE 0x00842428 Data 16 vendor_service.o(.constdata)
+ .constdata 0x00842438 Section 180 vendor_service.o(.constdata)
+ .constdata 0x008424ec Section 16 atvv_service.o(.constdata)
+ .constdata 0x008424fc Section 264 atvv_service.o(.constdata)
+ .constdata 0x00842604 Section 16 ir_service.o(.constdata)
+ GATT_UUID_IR_SERVICE 0x00842604 Data 16 ir_service.o(.constdata)
+ .constdata 0x00842614 Section 348 ir_service.o(.constdata)
+ .constdata 0x00842770 Section 16 dfu_service.o(.constdata)
+ .constdata 0x00842780 Section 12 dfu_service.o(.constdata)
+ .constdata 0x0084278c Section 16 ota_service.o(.constdata)
+ .constdata 0x0084279c Section 712 ota_service.o(.constdata)
+ .constdata 0x00842a64 Section 16 fms.o(.constdata)
+ GATT_UUID_FMS_SERVICE 0x00842a64 Data 16 fms.o(.constdata)
+ .constdata 0x00842a74 Section 180 fms.o(.constdata)
+ .constdata 0x00842b28 Section 29 rcu_application.o(.constdata)
+ .constdata 0x00842b45 Section 13 rcu_gap.o(.constdata)
+ app_adv_data_fixed_part 0x00842b45 Data 13 rcu_gap.o(.constdata)
+ .constdata 0x00842b52 Section 47 app_task.o(.constdata)
+ __func__ 0x00842b52 Data 14 app_task.o(.constdata)
+ __func__ 0x00842b60 Data 24 app_task.o(.constdata)
+ __func__ 0x00842b78 Data 9 app_task.o(.constdata)
+ .constdata 0x00842b81 Section 13 privacy_mgnt.o(.constdata)
+ __func__ 0x00842b81 Data 13 privacy_mgnt.o(.constdata)
+ .constdata 0x00842b8e Section 16 loop_queue.o(.constdata)
+ __func__ 0x00842b8e Data 16 loop_queue.o(.constdata)
+ .constdata 0x00842ba0 Section 428 key_handle.o(.constdata)
+ .constdata 0x00842d4c Section 3 key_handle.o(.constdata)
+ .constdata 0x00842d4f Section 8 key_handle.o(.constdata)
+ .constdata 0x00842d57 Section 3 key_handle.o(.constdata)
+ .constdata 0x00842d5a Section 42 key_handle.o(.constdata)
+ .constdata 0x00842d84 Section 8 key_handle.o(.constdata)
+ .constdata 0x00842d8c Section 12 key_handle.o(.constdata)
+ .constdata 0x00842d98 Section 8 key_handle.o(.constdata)
+ .constdata 0x00842da0 Section 31 voice.o(.constdata)
+ __func__ 0x00842da0 Data 31 voice.o(.constdata)
+ .constdata 0x00842dc0 Section 112 ir_protocol_nec.o(.constdata)
+ .constdata 0x00842e30 Section 40 ir_service_handle.o(.constdata)
+ .constdata 0x00842e58 Section 208 led_driver.o(.constdata)
+ led_event_arr 0x00842e58 Data 208 led_driver.o(.constdata)
+ .constdata 0x00842f28 Section 16 led_pwm_driver.o(.constdata)
+ led_pwm_list 0x00842f28 Data 16 led_pwm_driver.o(.constdata)
+ .constdata 0x00842f38 Section 36 app_custom.o(.constdata)
+ .constdata 0x00842f5c Section 128 ddiv.o(.constdata)
+ ddiv_reciptbl 0x00842f5c Data 128 ddiv.o(.constdata)
+ .constdata 0x00842fdc Section 64 fdiv.o(.constdata)
+ fdiv_tab 0x00842fdc Data 64 fdiv.o(.constdata)
+ .constdata 0x0084301c Section 8 _printf_wctomb.o(.constdata)
+ initial_mbstate 0x0084301c Data 8 _printf_wctomb.o(.constdata)
+ .constdata 0x00843024 Section 40 _printf_hex_int_ll_ptr.o(.constdata)
+ uc_hextab 0x00843024 Data 20 _printf_hex_int_ll_ptr.o(.constdata)
+ lc_hextab 0x00843038 Data 20 _printf_hex_int_ll_ptr.o(.constdata)
+ .constdata 0x0084304c Section 17 __printf_flags_ss_wp.o(.constdata)
+ maptable 0x0084304c Data 17 __printf_flags_ss_wp.o(.constdata)
+ .constdata 0x0084305d Section 38 _printf_fp_hex.o(.constdata)
+ lc_hextab 0x0084305d Data 19 _printf_fp_hex.o(.constdata)
+ uc_hextab 0x00843070 Data 19 _printf_fp_hex.o(.constdata)
+ .constdata 0x00843084 Section 148 bigflt0.o(.constdata)
+ tenpwrs_x 0x00843084 Data 60 bigflt0.o(.constdata)
+ tenpwrs_i 0x008430c0 Data 64 bigflt0.o(.constdata)
+ .conststring 0x00843118 Section 512 system_rtl876x.o(.conststring)
+ .conststring 0x00843318 Section 103 dfu_service.o(.conststring)
+ .conststring 0x00843380 Section 25 overlay_mgr.o(.conststring)
+ .conststring 0x0084339c Section 10 app_custom.o(.conststring)
+ .conststring 0x008433a8 Section 134 frm_vpk_hal_sflash.o(.conststring)
+ locale$$data 0x00843430 Section 28 lc_numeric_c.o(locale$$data)
+ __lcnum_c_name 0x00843434 Data 2 lc_numeric_c.o(locale$$data)
+ __lcnum_c_start 0x0084343c Data 0 lc_numeric_c.o(locale$$data)
+ __lcnum_c_point 0x00843448 Data 0 lc_numeric_c.o(locale$$data)
+ __lcnum_c_thousands 0x0084344a Data 0 lc_numeric_c.o(locale$$data)
+ __lcnum_c_grouping 0x0084344b Data 0 lc_numeric_c.o(locale$$data)
+ locale$$data 0x0084344c Section 272 lc_ctype_c.o(locale$$data)
+ __lcnum_c_end 0x0084344c Data 0 lc_numeric_c.o(locale$$data)
+ __lcctype_c_name 0x00843450 Data 2 lc_ctype_c.o(locale$$data)
+ __lcctype_c_start 0x00843458 Data 0 lc_ctype_c.o(locale$$data)
+ __lcctype_c_end 0x0084355c Data 0 lc_ctype_c.o(locale$$data)
+ .TRACE 0x08800000 Section 274 system_rtl876x.o(.TRACE)
+ __tagsym$$used 0x08800000 Number 0 system_rtl876x.o(.TRACE)
+ format 0x08800000 Data 32 system_rtl876x.o(.TRACE)
+ __tagsym$$used 0x08800020 Number 0 system_rtl876x.o(.TRACE)
+ format 0x08800020 Data 43 system_rtl876x.o(.TRACE)
+ __tagsym$$used 0x0880004c Number 0 system_rtl876x.o(.TRACE)
+ format 0x0880004c Data 41 system_rtl876x.o(.TRACE)
+ __tagsym$$used 0x08800078 Number 0 system_rtl876x.o(.TRACE)
+ format 0x08800078 Data 45 system_rtl876x.o(.TRACE)
+ __tagsym$$used 0x088000a8 Number 0 system_rtl876x.o(.TRACE)
+ format 0x088000a8 Data 31 system_rtl876x.o(.TRACE)
+ __tagsym$$used 0x088000c8 Number 0 system_rtl876x.o(.TRACE)
+ format 0x088000c8 Data 34 system_rtl876x.o(.TRACE)
+ __tagsym$$used 0x088000ec Number 0 system_rtl876x.o(.TRACE)
+ format 0x088000ec Data 38 system_rtl876x.o(.TRACE)
+ .TRACE 0x08800114 Section 42 rtl876x_io_dlps.o(.TRACE)
+ __tagsym$$used 0x08800114 Number 0 rtl876x_io_dlps.o(.TRACE)
+ format 0x08800114 Data 42 rtl876x_io_dlps.o(.TRACE)
+ .TRACE 0x08800140 Section 174 dis.o(.TRACE)
+ __tagsym$$used 0x08800140 Number 0 dis.o(.TRACE)
+ format 0x08800140 Data 43 dis.o(.TRACE)
+ __tagsym$$used 0x0880016c Number 0 dis.o(.TRACE)
+ format 0x0880016c Data 37 dis.o(.TRACE)
+ __tagsym$$used 0x08800194 Number 0 dis.o(.TRACE)
+ format 0x08800194 Data 53 dis.o(.TRACE)
+ __tagsym$$used 0x088001cc Number 0 dis.o(.TRACE)
+ format 0x088001cc Data 34 dis.o(.TRACE)
+ .TRACE 0x088001f0 Section 222 bas.o(.TRACE)
+ __tagsym$$used 0x088001f0 Number 0 bas.o(.TRACE)
+ format 0x088001f0 Data 48 bas.o(.TRACE)
+ __tagsym$$used 0x08800220 Number 0 bas.o(.TRACE)
+ format 0x08800220 Data 47 bas.o(.TRACE)
+ __tagsym$$used 0x08800250 Number 0 bas.o(.TRACE)
+ format 0x08800250 Data 42 bas.o(.TRACE)
+ __tagsym$$used 0x0880027c Number 0 bas.o(.TRACE)
+ format 0x0880027c Data 48 bas.o(.TRACE)
+ __tagsym$$used 0x088002ac Number 0 bas.o(.TRACE)
+ format 0x088002ac Data 34 bas.o(.TRACE)
+ .TRACE 0x088002d0 Section 266 hids_rmc.o(.TRACE)
+ __tagsym$$used 0x088002d0 Number 0 hids_rmc.o(.TRACE)
+ format 0x088002d0 Data 49 hids_rmc.o(.TRACE)
+ __tagsym$$used 0x08800304 Number 0 hids_rmc.o(.TRACE)
+ format 0x08800304 Data 47 hids_rmc.o(.TRACE)
+ __tagsym$$used 0x08800334 Number 0 hids_rmc.o(.TRACE)
+ format 0x08800334 Data 41 hids_rmc.o(.TRACE)
+ __tagsym$$used 0x08800360 Number 0 hids_rmc.o(.TRACE)
+ format 0x08800360 Data 39 hids_rmc.o(.TRACE)
+ __tagsym$$used 0x08800388 Number 0 hids_rmc.o(.TRACE)
+ format 0x08800388 Data 46 hids_rmc.o(.TRACE)
+ __tagsym$$used 0x088003b8 Number 0 hids_rmc.o(.TRACE)
+ format 0x088003b8 Data 34 hids_rmc.o(.TRACE)
+ .TRACE 0x088003dc Section 149 vendor_service.o(.TRACE)
+ __tagsym$$used 0x088003dc Number 0 vendor_service.o(.TRACE)
+ format 0x088003dc Data 49 vendor_service.o(.TRACE)
+ __tagsym$$used 0x08800410 Number 0 vendor_service.o(.TRACE)
+ format 0x08800410 Data 55 vendor_service.o(.TRACE)
+ __tagsym$$used 0x08800448 Number 0 vendor_service.o(.TRACE)
+ format 0x08800448 Data 41 vendor_service.o(.TRACE)
+ .TRACE 0x08800474 Section 299 voice_service.o(.TRACE)
+ __tagsym$$used 0x08800474 Number 0 voice_service.o(.TRACE)
+ format 0x08800474 Data 50 voice_service.o(.TRACE)
+ __tagsym$$used 0x088004a8 Number 0 voice_service.o(.TRACE)
+ format 0x088004a8 Data 50 voice_service.o(.TRACE)
+ __tagsym$$used 0x088004dc Number 0 voice_service.o(.TRACE)
+ format 0x088004dc Data 41 voice_service.o(.TRACE)
+ __tagsym$$used 0x08800508 Number 0 voice_service.o(.TRACE)
+ format 0x08800508 Data 47 voice_service.o(.TRACE)
+ __tagsym$$used 0x08800538 Number 0 voice_service.o(.TRACE)
+ format 0x08800538 Data 54 voice_service.o(.TRACE)
+ __tagsym$$used 0x08800570 Number 0 voice_service.o(.TRACE)
+ format 0x08800570 Data 47 voice_service.o(.TRACE)
+ .TRACE 0x088005a0 Section 310 atvv_service.o(.TRACE)
+ __tagsym$$used 0x088005a0 Number 0 atvv_service.o(.TRACE)
+ format 0x088005a0 Data 48 atvv_service.o(.TRACE)
+ __tagsym$$used 0x088005d0 Number 0 atvv_service.o(.TRACE)
+ format 0x088005d0 Data 49 atvv_service.o(.TRACE)
+ __tagsym$$used 0x08800604 Number 0 atvv_service.o(.TRACE)
+ format 0x08800604 Data 85 atvv_service.o(.TRACE)
+ __tagsym$$used 0x0880065c Number 0 atvv_service.o(.TRACE)
+ format 0x0880065c Data 40 atvv_service.o(.TRACE)
+ __tagsym$$used 0x08800684 Number 0 atvv_service.o(.TRACE)
+ format 0x08800684 Data 46 atvv_service.o(.TRACE)
+ __tagsym$$used 0x088006b4 Number 0 atvv_service.o(.TRACE)
+ format 0x088006b4 Data 34 atvv_service.o(.TRACE)
+ .TRACE 0x088006d8 Section 137 ir_service.o(.TRACE)
+ __tagsym$$used 0x088006d8 Number 0 ir_service.o(.TRACE)
+ format 0x088006d8 Data 45 ir_service.o(.TRACE)
+ __tagsym$$used 0x08800708 Number 0 ir_service.o(.TRACE)
+ format 0x08800708 Data 51 ir_service.o(.TRACE)
+ __tagsym$$used 0x0880073c Number 0 ir_service.o(.TRACE)
+ format 0x0880073c Data 37 ir_service.o(.TRACE)
+ .TRACE 0x08800764 Section 2542 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800764 Number 0 dfu_service.o(.TRACE)
+ format 0x08800764 Data 81 dfu_service.o(.TRACE)
+ __tagsym$$used 0x088007b8 Number 0 dfu_service.o(.TRACE)
+ format 0x088007b8 Data 61 dfu_service.o(.TRACE)
+ __tagsym$$used 0x088007f8 Number 0 dfu_service.o(.TRACE)
+ format 0x088007f8 Data 88 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800850 Number 0 dfu_service.o(.TRACE)
+ format 0x08800850 Data 58 dfu_service.o(.TRACE)
+ __tagsym$$used 0x0880088c Number 0 dfu_service.o(.TRACE)
+ format 0x0880088c Data 72 dfu_service.o(.TRACE)
+ __tagsym$$used 0x088008d4 Number 0 dfu_service.o(.TRACE)
+ format 0x088008d4 Data 54 dfu_service.o(.TRACE)
+ __tagsym$$used 0x0880090c Number 0 dfu_service.o(.TRACE)
+ format 0x0880090c Data 72 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800954 Number 0 dfu_service.o(.TRACE)
+ format 0x08800954 Data 56 dfu_service.o(.TRACE)
+ __tagsym$$used 0x0880098c Number 0 dfu_service.o(.TRACE)
+ format 0x0880098c Data 112 dfu_service.o(.TRACE)
+ __tagsym$$used 0x088009fc Number 0 dfu_service.o(.TRACE)
+ format 0x088009fc Data 54 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800a34 Number 0 dfu_service.o(.TRACE)
+ format 0x08800a34 Data 70 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800a7c Number 0 dfu_service.o(.TRACE)
+ format 0x08800a7c Data 43 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800aa8 Number 0 dfu_service.o(.TRACE)
+ format 0x08800aa8 Data 64 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800ae8 Number 0 dfu_service.o(.TRACE)
+ format 0x08800ae8 Data 34 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800b0c Number 0 dfu_service.o(.TRACE)
+ format 0x08800b0c Data 33 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800b30 Number 0 dfu_service.o(.TRACE)
+ format 0x08800b30 Data 123 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800bac Number 0 dfu_service.o(.TRACE)
+ format 0x08800bac Data 89 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800c08 Number 0 dfu_service.o(.TRACE)
+ format 0x08800c08 Data 40 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800c30 Number 0 dfu_service.o(.TRACE)
+ format 0x08800c30 Data 46 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800c60 Number 0 dfu_service.o(.TRACE)
+ format 0x08800c60 Data 45 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800c90 Number 0 dfu_service.o(.TRACE)
+ format 0x08800c90 Data 94 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800cf0 Number 0 dfu_service.o(.TRACE)
+ format 0x08800cf0 Data 54 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800d28 Number 0 dfu_service.o(.TRACE)
+ format 0x08800d28 Data 35 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800d4c Number 0 dfu_service.o(.TRACE)
+ format 0x08800d4c Data 61 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800d8c Number 0 dfu_service.o(.TRACE)
+ format 0x08800d8c Data 41 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800db8 Number 0 dfu_service.o(.TRACE)
+ format 0x08800db8 Data 33 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800ddc Number 0 dfu_service.o(.TRACE)
+ format 0x08800ddc Data 85 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800e34 Number 0 dfu_service.o(.TRACE)
+ format 0x08800e34 Data 51 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800e68 Number 0 dfu_service.o(.TRACE)
+ format 0x08800e68 Data 61 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800ea8 Number 0 dfu_service.o(.TRACE)
+ format 0x08800ea8 Data 61 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800ee8 Number 0 dfu_service.o(.TRACE)
+ format 0x08800ee8 Data 44 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800f14 Number 0 dfu_service.o(.TRACE)
+ format 0x08800f14 Data 24 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800f2c Number 0 dfu_service.o(.TRACE)
+ format 0x08800f2c Data 42 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800f58 Number 0 dfu_service.o(.TRACE)
+ format 0x08800f58 Data 58 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08800f94 Number 0 dfu_service.o(.TRACE)
+ format 0x08800f94 Data 110 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08801004 Number 0 dfu_service.o(.TRACE)
+ format 0x08801004 Data 106 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08801070 Number 0 dfu_service.o(.TRACE)
+ format 0x08801070 Data 100 dfu_service.o(.TRACE)
+ __tagsym$$used 0x088010d4 Number 0 dfu_service.o(.TRACE)
+ format 0x088010d4 Data 43 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08801100 Number 0 dfu_service.o(.TRACE)
+ format 0x08801100 Data 47 dfu_service.o(.TRACE)
+ __tagsym$$used 0x08801130 Number 0 dfu_service.o(.TRACE)
+ format 0x08801130 Data 34 dfu_service.o(.TRACE)
+ .TRACE 0x08801154 Section 753 ota_service.o(.TRACE)
+ __tagsym$$used 0x08801154 Number 0 ota_service.o(.TRACE)
+ format 0x08801154 Data 65 ota_service.o(.TRACE)
+ __tagsym$$used 0x08801198 Number 0 ota_service.o(.TRACE)
+ format 0x08801198 Data 51 ota_service.o(.TRACE)
+ __tagsym$$used 0x088011cc Number 0 ota_service.o(.TRACE)
+ format 0x088011cc Data 51 ota_service.o(.TRACE)
+ __tagsym$$used 0x08801200 Number 0 ota_service.o(.TRACE)
+ format 0x08801200 Data 49 ota_service.o(.TRACE)
+ __tagsym$$used 0x08801234 Number 0 ota_service.o(.TRACE)
+ format 0x08801234 Data 87 ota_service.o(.TRACE)
+ __tagsym$$used 0x0880128c Number 0 ota_service.o(.TRACE)
+ format 0x0880128c Data 73 ota_service.o(.TRACE)
+ __tagsym$$used 0x088012d8 Number 0 ota_service.o(.TRACE)
+ format 0x088012d8 Data 95 ota_service.o(.TRACE)
+ __tagsym$$used 0x08801338 Number 0 ota_service.o(.TRACE)
+ format 0x08801338 Data 61 ota_service.o(.TRACE)
+ __tagsym$$used 0x08801378 Number 0 ota_service.o(.TRACE)
+ format 0x08801378 Data 35 ota_service.o(.TRACE)
+ __tagsym$$used 0x0880139c Number 0 ota_service.o(.TRACE)
+ format 0x0880139c Data 52 ota_service.o(.TRACE)
+ __tagsym$$used 0x088013d0 Number 0 ota_service.o(.TRACE)
+ format 0x088013d0 Data 52 ota_service.o(.TRACE)
+ __tagsym$$used 0x08801404 Number 0 ota_service.o(.TRACE)
+ format 0x08801404 Data 27 ota_service.o(.TRACE)
+ __tagsym$$used 0x08801420 Number 0 ota_service.o(.TRACE)
+ format 0x08801420 Data 37 ota_service.o(.TRACE)
+ .TRACE 0x08801448 Section 174 fms.o(.TRACE)
+ __tagsym$$used 0x08801448 Number 0 fms.o(.TRACE)
+ format 0x08801448 Data 48 fms.o(.TRACE)
+ __tagsym$$used 0x08801478 Number 0 fms.o(.TRACE)
+ format 0x08801478 Data 42 fms.o(.TRACE)
+ __tagsym$$used 0x088014a4 Number 0 fms.o(.TRACE)
+ format 0x088014a4 Data 48 fms.o(.TRACE)
+ __tagsym$$used 0x088014d4 Number 0 fms.o(.TRACE)
+ format 0x088014d4 Data 34 fms.o(.TRACE)
+ .TRACE 0x088014f8 Section 858 main.o(.TRACE)
+ __tagsym$$used 0x088014f8 Number 0 main.o(.TRACE)
+ format 0x088014f8 Data 39 main.o(.TRACE)
+ __tagsym$$used 0x08801520 Number 0 main.o(.TRACE)
+ format 0x08801520 Data 44 main.o(.TRACE)
+ __tagsym$$used 0x0880154c Number 0 main.o(.TRACE)
+ format 0x0880154c Data 38 main.o(.TRACE)
+ __tagsym$$used 0x08801574 Number 0 main.o(.TRACE)
+ format 0x08801574 Data 38 main.o(.TRACE)
+ __tagsym$$used 0x0880159c Number 0 main.o(.TRACE)
+ format 0x0880159c Data 34 main.o(.TRACE)
+ __tagsym$$used 0x088015c0 Number 0 main.o(.TRACE)
+ format 0x088015c0 Data 39 main.o(.TRACE)
+ __tagsym$$used 0x088015e8 Number 0 main.o(.TRACE)
+ format 0x088015e8 Data 45 main.o(.TRACE)
+ __tagsym$$used 0x08801618 Number 0 main.o(.TRACE)
+ format 0x08801618 Data 48 main.o(.TRACE)
+ __tagsym$$used 0x08801648 Number 0 main.o(.TRACE)
+ format 0x08801648 Data 49 main.o(.TRACE)
+ __tagsym$$used 0x0880167c Number 0 main.o(.TRACE)
+ format 0x0880167c Data 49 main.o(.TRACE)
+ __tagsym$$used 0x088016b0 Number 0 main.o(.TRACE)
+ format 0x088016b0 Data 58 main.o(.TRACE)
+ __tagsym$$used 0x088016ec Number 0 main.o(.TRACE)
+ format 0x088016ec Data 44 main.o(.TRACE)
+ __tagsym$$used 0x08801718 Number 0 main.o(.TRACE)
+ format 0x08801718 Data 44 main.o(.TRACE)
+ __tagsym$$used 0x08801744 Number 0 main.o(.TRACE)
+ format 0x08801744 Data 55 main.o(.TRACE)
+ __tagsym$$used 0x0880177c Number 0 main.o(.TRACE)
+ format 0x0880177c Data 57 main.o(.TRACE)
+ __tagsym$$used 0x088017b8 Number 0 main.o(.TRACE)
+ format 0x088017b8 Data 56 main.o(.TRACE)
+ __tagsym$$used 0x088017f0 Number 0 main.o(.TRACE)
+ format 0x088017f0 Data 30 main.o(.TRACE)
+ __tagsym$$used 0x08801810 Number 0 main.o(.TRACE)
+ format 0x08801810 Data 19 main.o(.TRACE)
+ __tagsym$$used 0x08801824 Number 0 main.o(.TRACE)
+ format 0x08801824 Data 27 main.o(.TRACE)
+ __tagsym$$used 0x08801840 Number 0 main.o(.TRACE)
+ format 0x08801840 Data 18 main.o(.TRACE)
+ .TRACE 0x08801854 Section 4517 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801854 Number 0 rcu_application.o(.TRACE)
+ format 0x08801854 Data 42 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801880 Number 0 rcu_application.o(.TRACE)
+ format 0x08801880 Data 30 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088018a0 Number 0 rcu_application.o(.TRACE)
+ format 0x088018a0 Data 28 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088018bc Number 0 rcu_application.o(.TRACE)
+ format 0x088018bc Data 28 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088018d8 Number 0 rcu_application.o(.TRACE)
+ format 0x088018d8 Data 28 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088018f4 Number 0 rcu_application.o(.TRACE)
+ format 0x088018f4 Data 29 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801914 Number 0 rcu_application.o(.TRACE)
+ format 0x08801914 Data 29 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801934 Number 0 rcu_application.o(.TRACE)
+ format 0x08801934 Data 25 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801950 Number 0 rcu_application.o(.TRACE)
+ format 0x08801950 Data 42 rcu_application.o(.TRACE)
+ __tagsym$$used 0x0880197c Number 0 rcu_application.o(.TRACE)
+ format 0x0880197c Data 31 rcu_application.o(.TRACE)
+ __tagsym$$used 0x0880199c Number 0 rcu_application.o(.TRACE)
+ format 0x0880199c Data 56 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088019d4 Number 0 rcu_application.o(.TRACE)
+ format 0x088019d4 Data 56 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801a0c Number 0 rcu_application.o(.TRACE)
+ format 0x08801a0c Data 60 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801a48 Number 0 rcu_application.o(.TRACE)
+ format 0x08801a48 Data 77 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801a98 Number 0 rcu_application.o(.TRACE)
+ format 0x08801a98 Data 58 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801ad4 Number 0 rcu_application.o(.TRACE)
+ format 0x08801ad4 Data 57 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801b10 Number 0 rcu_application.o(.TRACE)
+ format 0x08801b10 Data 52 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801b44 Number 0 rcu_application.o(.TRACE)
+ format 0x08801b44 Data 43 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801b70 Number 0 rcu_application.o(.TRACE)
+ format 0x08801b70 Data 104 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801bd8 Number 0 rcu_application.o(.TRACE)
+ format 0x08801bd8 Data 42 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801c04 Number 0 rcu_application.o(.TRACE)
+ format 0x08801c04 Data 41 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801c30 Number 0 rcu_application.o(.TRACE)
+ format 0x08801c30 Data 54 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801c68 Number 0 rcu_application.o(.TRACE)
+ format 0x08801c68 Data 55 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801ca0 Number 0 rcu_application.o(.TRACE)
+ format 0x08801ca0 Data 32 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801cc0 Number 0 rcu_application.o(.TRACE)
+ format 0x08801cc0 Data 50 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801cf4 Number 0 rcu_application.o(.TRACE)
+ format 0x08801cf4 Data 51 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801d28 Number 0 rcu_application.o(.TRACE)
+ format 0x08801d28 Data 53 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801d60 Number 0 rcu_application.o(.TRACE)
+ format 0x08801d60 Data 54 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801d98 Number 0 rcu_application.o(.TRACE)
+ format 0x08801d98 Data 43 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801dc4 Number 0 rcu_application.o(.TRACE)
+ format 0x08801dc4 Data 35 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801de8 Number 0 rcu_application.o(.TRACE)
+ format 0x08801de8 Data 44 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801e14 Number 0 rcu_application.o(.TRACE)
+ format 0x08801e14 Data 45 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801e44 Number 0 rcu_application.o(.TRACE)
+ format 0x08801e44 Data 62 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801e84 Number 0 rcu_application.o(.TRACE)
+ format 0x08801e84 Data 60 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801ec0 Number 0 rcu_application.o(.TRACE)
+ format 0x08801ec0 Data 73 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801f0c Number 0 rcu_application.o(.TRACE)
+ format 0x08801f0c Data 44 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801f38 Number 0 rcu_application.o(.TRACE)
+ format 0x08801f38 Data 27 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801f54 Number 0 rcu_application.o(.TRACE)
+ format 0x08801f54 Data 28 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801f70 Number 0 rcu_application.o(.TRACE)
+ format 0x08801f70 Data 87 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801fc8 Number 0 rcu_application.o(.TRACE)
+ format 0x08801fc8 Data 19 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08801fdc Number 0 rcu_application.o(.TRACE)
+ format 0x08801fdc Data 39 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802004 Number 0 rcu_application.o(.TRACE)
+ format 0x08802004 Data 50 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802038 Number 0 rcu_application.o(.TRACE)
+ format 0x08802038 Data 48 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802068 Number 0 rcu_application.o(.TRACE)
+ format 0x08802068 Data 17 rcu_application.o(.TRACE)
+ __tagsym$$used 0x0880207c Number 0 rcu_application.o(.TRACE)
+ format 0x0880207c Data 24 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802094 Number 0 rcu_application.o(.TRACE)
+ format 0x08802094 Data 76 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088020e0 Number 0 rcu_application.o(.TRACE)
+ format 0x088020e0 Data 55 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802118 Number 0 rcu_application.o(.TRACE)
+ format 0x08802118 Data 61 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802158 Number 0 rcu_application.o(.TRACE)
+ format 0x08802158 Data 132 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088021dc Number 0 rcu_application.o(.TRACE)
+ format 0x088021dc Data 45 rcu_application.o(.TRACE)
+ __tagsym$$used 0x0880220c Number 0 rcu_application.o(.TRACE)
+ format 0x0880220c Data 28 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802228 Number 0 rcu_application.o(.TRACE)
+ format 0x08802228 Data 47 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802258 Number 0 rcu_application.o(.TRACE)
+ format 0x08802258 Data 21 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802270 Number 0 rcu_application.o(.TRACE)
+ format 0x08802270 Data 43 rcu_application.o(.TRACE)
+ __tagsym$$used 0x0880229c Number 0 rcu_application.o(.TRACE)
+ format 0x0880229c Data 57 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088022d8 Number 0 rcu_application.o(.TRACE)
+ format 0x088022d8 Data 122 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802354 Number 0 rcu_application.o(.TRACE)
+ format 0x08802354 Data 51 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802388 Number 0 rcu_application.o(.TRACE)
+ format 0x08802388 Data 68 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088023cc Number 0 rcu_application.o(.TRACE)
+ format 0x088023cc Data 69 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802414 Number 0 rcu_application.o(.TRACE)
+ format 0x08802414 Data 40 rcu_application.o(.TRACE)
+ __tagsym$$used 0x0880243c Number 0 rcu_application.o(.TRACE)
+ format 0x0880243c Data 35 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802460 Number 0 rcu_application.o(.TRACE)
+ format 0x08802460 Data 29 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802480 Number 0 rcu_application.o(.TRACE)
+ format 0x08802480 Data 46 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088024b0 Number 0 rcu_application.o(.TRACE)
+ format 0x088024b0 Data 49 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088024e4 Number 0 rcu_application.o(.TRACE)
+ format 0x088024e4 Data 45 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802514 Number 0 rcu_application.o(.TRACE)
+ format 0x08802514 Data 29 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802534 Number 0 rcu_application.o(.TRACE)
+ format 0x08802534 Data 49 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802568 Number 0 rcu_application.o(.TRACE)
+ format 0x08802568 Data 45 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802598 Number 0 rcu_application.o(.TRACE)
+ format 0x08802598 Data 63 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088025d8 Number 0 rcu_application.o(.TRACE)
+ format 0x088025d8 Data 49 rcu_application.o(.TRACE)
+ __tagsym$$used 0x0880260c Number 0 rcu_application.o(.TRACE)
+ format 0x0880260c Data 55 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802644 Number 0 rcu_application.o(.TRACE)
+ format 0x08802644 Data 63 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802684 Number 0 rcu_application.o(.TRACE)
+ format 0x08802684 Data 64 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088026c4 Number 0 rcu_application.o(.TRACE)
+ format 0x088026c4 Data 93 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802724 Number 0 rcu_application.o(.TRACE)
+ format 0x08802724 Data 45 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802754 Number 0 rcu_application.o(.TRACE)
+ format 0x08802754 Data 38 rcu_application.o(.TRACE)
+ __tagsym$$used 0x0880277c Number 0 rcu_application.o(.TRACE)
+ format 0x0880277c Data 32 rcu_application.o(.TRACE)
+ __tagsym$$used 0x0880279c Number 0 rcu_application.o(.TRACE)
+ format 0x0880279c Data 30 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088027bc Number 0 rcu_application.o(.TRACE)
+ format 0x088027bc Data 81 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802810 Number 0 rcu_application.o(.TRACE)
+ format 0x08802810 Data 42 rcu_application.o(.TRACE)
+ __tagsym$$used 0x0880283c Number 0 rcu_application.o(.TRACE)
+ format 0x0880283c Data 58 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802878 Number 0 rcu_application.o(.TRACE)
+ format 0x08802878 Data 48 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088028a8 Number 0 rcu_application.o(.TRACE)
+ format 0x088028a8 Data 58 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088028e4 Number 0 rcu_application.o(.TRACE)
+ format 0x088028e4 Data 42 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802910 Number 0 rcu_application.o(.TRACE)
+ format 0x08802910 Data 44 rcu_application.o(.TRACE)
+ __tagsym$$used 0x0880293c Number 0 rcu_application.o(.TRACE)
+ format 0x0880293c Data 44 rcu_application.o(.TRACE)
+ __tagsym$$used 0x08802968 Number 0 rcu_application.o(.TRACE)
+ format 0x08802968 Data 33 rcu_application.o(.TRACE)
+ __tagsym$$used 0x0880298c Number 0 rcu_application.o(.TRACE)
+ format 0x0880298c Data 53 rcu_application.o(.TRACE)
+ __tagsym$$used 0x088029c4 Number 0 rcu_application.o(.TRACE)
+ format 0x088029c4 Data 53 rcu_application.o(.TRACE)
+ .TRACE 0x088029fc Section 1756 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x088029fc Number 0 rcu_gap.o(.TRACE)
+ format 0x088029fc Data 19 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802a10 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802a10 Data 52 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802a44 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802a44 Data 43 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802a70 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802a70 Data 47 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802aa0 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802aa0 Data 37 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802ac8 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802ac8 Data 34 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802aec Number 0 rcu_gap.o(.TRACE)
+ format 0x08802aec Data 43 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802b18 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802b18 Data 47 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802b48 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802b48 Data 37 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802b70 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802b70 Data 34 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802b94 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802b94 Data 43 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802bc0 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802bc0 Data 47 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802bf0 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802bf0 Data 40 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802c18 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802c18 Data 37 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802c40 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802c40 Data 43 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802c6c Number 0 rcu_gap.o(.TRACE)
+ format 0x08802c6c Data 45 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802c9c Number 0 rcu_gap.o(.TRACE)
+ format 0x08802c9c Data 42 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802cc8 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802cc8 Data 54 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802d00 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802d00 Data 43 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802d2c Number 0 rcu_gap.o(.TRACE)
+ format 0x08802d2c Data 47 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802d5c Number 0 rcu_gap.o(.TRACE)
+ format 0x08802d5c Data 66 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802da0 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802da0 Data 39 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802dc8 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802dc8 Data 52 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802dfc Number 0 rcu_gap.o(.TRACE)
+ format 0x08802dfc Data 37 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802e24 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802e24 Data 43 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802e50 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802e50 Data 40 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802e78 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802e78 Data 40 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802ea0 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802ea0 Data 46 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802ed0 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802ed0 Data 43 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802efc Number 0 rcu_gap.o(.TRACE)
+ format 0x08802efc Data 40 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802f24 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802f24 Data 53 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802f5c Number 0 rcu_gap.o(.TRACE)
+ format 0x08802f5c Data 47 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802f8c Number 0 rcu_gap.o(.TRACE)
+ format 0x08802f8c Data 41 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802fb8 Number 0 rcu_gap.o(.TRACE)
+ format 0x08802fb8 Data 66 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08802ffc Number 0 rcu_gap.o(.TRACE)
+ format 0x08802ffc Data 60 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08803038 Number 0 rcu_gap.o(.TRACE)
+ format 0x08803038 Data 53 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x08803070 Number 0 rcu_gap.o(.TRACE)
+ format 0x08803070 Data 51 rcu_gap.o(.TRACE)
+ __tagsym$$used 0x088030a4 Number 0 rcu_gap.o(.TRACE)
+ format 0x088030a4 Data 52 rcu_gap.o(.TRACE)
+ .TRACE 0x088030d8 Section 742 swtimer.o(.TRACE)
+ __tagsym$$used 0x088030d8 Number 0 swtimer.o(.TRACE)
+ format 0x088030d8 Data 43 swtimer.o(.TRACE)
+ __tagsym$$used 0x08803104 Number 0 swtimer.o(.TRACE)
+ format 0x08803104 Data 44 swtimer.o(.TRACE)
+ __tagsym$$used 0x08803130 Number 0 swtimer.o(.TRACE)
+ format 0x08803130 Data 46 swtimer.o(.TRACE)
+ __tagsym$$used 0x08803160 Number 0 swtimer.o(.TRACE)
+ format 0x08803160 Data 56 swtimer.o(.TRACE)
+ __tagsym$$used 0x08803198 Number 0 swtimer.o(.TRACE)
+ format 0x08803198 Data 48 swtimer.o(.TRACE)
+ __tagsym$$used 0x088031c8 Number 0 swtimer.o(.TRACE)
+ format 0x088031c8 Data 68 swtimer.o(.TRACE)
+ __tagsym$$used 0x0880320c Number 0 swtimer.o(.TRACE)
+ format 0x0880320c Data 41 swtimer.o(.TRACE)
+ __tagsym$$used 0x08803238 Number 0 swtimer.o(.TRACE)
+ format 0x08803238 Data 53 swtimer.o(.TRACE)
+ __tagsym$$used 0x08803270 Number 0 swtimer.o(.TRACE)
+ format 0x08803270 Data 55 swtimer.o(.TRACE)
+ __tagsym$$used 0x088032a8 Number 0 swtimer.o(.TRACE)
+ format 0x088032a8 Data 67 swtimer.o(.TRACE)
+ __tagsym$$used 0x088032ec Number 0 swtimer.o(.TRACE)
+ format 0x088032ec Data 46 swtimer.o(.TRACE)
+ __tagsym$$used 0x0880331c Number 0 swtimer.o(.TRACE)
+ format 0x0880331c Data 56 swtimer.o(.TRACE)
+ __tagsym$$used 0x08803354 Number 0 swtimer.o(.TRACE)
+ format 0x08803354 Data 49 swtimer.o(.TRACE)
+ __tagsym$$used 0x08803388 Number 0 swtimer.o(.TRACE)
+ format 0x08803388 Data 54 swtimer.o(.TRACE)
+ .TRACE 0x088033c0 Section 56 app_task.o(.TRACE)
+ __tagsym$$used 0x088033c0 Number 0 app_task.o(.TRACE)
+ format 0x088033c0 Data 27 app_task.o(.TRACE)
+ __tagsym$$used 0x088033dc Number 0 app_task.o(.TRACE)
+ format 0x088033dc Data 28 app_task.o(.TRACE)
+ .TRACE 0x088033f8 Section 58 reset_watch_dog_timer.o(.TRACE)
+ __tagsym$$used 0x088033f8 Number 0 reset_watch_dog_timer.o(.TRACE)
+ format 0x088033f8 Data 58 reset_watch_dog_timer.o(.TRACE)
+ .TRACE 0x08803434 Section 1455 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x08803434 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x08803434 Data 48 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x08803464 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x08803464 Data 40 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x0880348c Number 0 privacy_mgnt.o(.TRACE)
+ format 0x0880348c Data 22 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x088034a4 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x088034a4 Data 19 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x088034b8 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x088034b8 Data 36 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x088034dc Number 0 privacy_mgnt.o(.TRACE)
+ format 0x088034dc Data 40 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x08803504 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x08803504 Data 62 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x08803544 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x08803544 Data 39 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x0880356c Number 0 privacy_mgnt.o(.TRACE)
+ format 0x0880356c Data 42 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x08803598 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x08803598 Data 65 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x088035dc Number 0 privacy_mgnt.o(.TRACE)
+ format 0x088035dc Data 42 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x08803608 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x08803608 Data 50 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x0880363c Number 0 privacy_mgnt.o(.TRACE)
+ format 0x0880363c Data 55 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x08803674 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x08803674 Data 51 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x088036a8 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x088036a8 Data 59 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x088036e4 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x088036e4 Data 51 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x08803718 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x08803718 Data 59 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x08803754 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x08803754 Data 62 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x08803794 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x08803794 Data 50 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x088037c8 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x088037c8 Data 56 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x08803800 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x08803800 Data 76 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x0880384c Number 0 privacy_mgnt.o(.TRACE)
+ format 0x0880384c Data 91 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x088038a8 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x088038a8 Data 48 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x088038d8 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x088038d8 Data 53 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x08803910 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x08803910 Data 73 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x0880395c Number 0 privacy_mgnt.o(.TRACE)
+ format 0x0880395c Data 66 privacy_mgnt.o(.TRACE)
+ __tagsym$$used 0x088039a0 Number 0 privacy_mgnt.o(.TRACE)
+ format 0x088039a0 Data 67 privacy_mgnt.o(.TRACE)
+ .TRACE 0x088039e4 Section 757 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x088039e4 Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x088039e4 Data 32 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803a04 Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803a04 Data 56 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803a3c Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803a3c Data 57 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803a78 Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803a78 Data 52 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803aac Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803aac Data 71 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803af4 Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803af4 Data 55 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803b2c Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803b2c Data 29 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803b4c Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803b4c Data 34 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803b70 Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803b70 Data 20 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803b84 Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803b84 Data 20 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803b98 Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803b98 Data 32 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803bb8 Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803bb8 Data 45 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803be8 Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803be8 Data 45 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803c18 Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803c18 Data 45 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803c48 Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803c48 Data 45 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803c78 Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803c78 Data 51 rcu_dtm_app.o(.TRACE)
+ __tagsym$$used 0x08803cac Number 0 rcu_dtm_app.o(.TRACE)
+ format 0x08803cac Data 45 rcu_dtm_app.o(.TRACE)
+ .TRACE 0x08803cdc Section 83 rcu_link_mgr.o(.TRACE)
+ __tagsym$$used 0x08803cdc Number 0 rcu_link_mgr.o(.TRACE)
+ format 0x08803cdc Data 34 rcu_link_mgr.o(.TRACE)
+ __tagsym$$used 0x08803d00 Number 0 rcu_link_mgr.o(.TRACE)
+ format 0x08803d00 Data 47 rcu_link_mgr.o(.TRACE)
+ .TRACE 0x08803d30 Section 223 rtc_driver.o(.TRACE)
+ __tagsym$$used 0x08803d30 Number 0 rtc_driver.o(.TRACE)
+ format 0x08803d30 Data 30 rtc_driver.o(.TRACE)
+ __tagsym$$used 0x08803d50 Number 0 rtc_driver.o(.TRACE)
+ format 0x08803d50 Data 32 rtc_driver.o(.TRACE)
+ __tagsym$$used 0x08803d70 Number 0 rtc_driver.o(.TRACE)
+ format 0x08803d70 Data 35 rtc_driver.o(.TRACE)
+ __tagsym$$used 0x08803d94 Number 0 rtc_driver.o(.TRACE)
+ format 0x08803d94 Data 60 rtc_driver.o(.TRACE)
+ __tagsym$$used 0x08803dd0 Number 0 rtc_driver.o(.TRACE)
+ format 0x08803dd0 Data 29 rtc_driver.o(.TRACE)
+ __tagsym$$used 0x08803df0 Number 0 rtc_driver.o(.TRACE)
+ format 0x08803df0 Data 31 rtc_driver.o(.TRACE)
+ .TRACE 0x08803e10 Section 1004 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x08803e10 Number 0 dfu_flash.o(.TRACE)
+ format 0x08803e10 Data 60 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x08803e4c Number 0 dfu_flash.o(.TRACE)
+ format 0x08803e4c Data 59 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x08803e88 Number 0 dfu_flash.o(.TRACE)
+ format 0x08803e88 Data 72 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x08803ed0 Number 0 dfu_flash.o(.TRACE)
+ format 0x08803ed0 Data 78 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x08803f20 Number 0 dfu_flash.o(.TRACE)
+ format 0x08803f20 Data 41 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x08803f4c Number 0 dfu_flash.o(.TRACE)
+ format 0x08803f4c Data 33 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x08803f70 Number 0 dfu_flash.o(.TRACE)
+ format 0x08803f70 Data 30 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x08803f90 Number 0 dfu_flash.o(.TRACE)
+ format 0x08803f90 Data 34 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x08803fb4 Number 0 dfu_flash.o(.TRACE)
+ format 0x08803fb4 Data 43 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x08803fe0 Number 0 dfu_flash.o(.TRACE)
+ format 0x08803fe0 Data 43 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x0880400c Number 0 dfu_flash.o(.TRACE)
+ format 0x0880400c Data 77 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x0880405c Number 0 dfu_flash.o(.TRACE)
+ format 0x0880405c Data 37 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x08804084 Number 0 dfu_flash.o(.TRACE)
+ format 0x08804084 Data 45 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x088040b4 Number 0 dfu_flash.o(.TRACE)
+ format 0x088040b4 Data 49 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x088040e8 Number 0 dfu_flash.o(.TRACE)
+ format 0x088040e8 Data 41 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x08804114 Number 0 dfu_flash.o(.TRACE)
+ format 0x08804114 Data 54 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x0880414c Number 0 dfu_flash.o(.TRACE)
+ format 0x0880414c Data 72 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x08804194 Number 0 dfu_flash.o(.TRACE)
+ format 0x08804194 Data 28 dfu_flash.o(.TRACE)
+ __tagsym$$used 0x088041b0 Number 0 dfu_flash.o(.TRACE)
+ format 0x088041b0 Data 76 dfu_flash.o(.TRACE)
+ .TRACE 0x088041fc Section 312 keyscan_driver.o(.TRACE)
+ __tagsym$$used 0x088041fc Number 0 keyscan_driver.o(.TRACE)
+ format 0x088041fc Data 61 keyscan_driver.o(.TRACE)
+ __tagsym$$used 0x0880423c Number 0 keyscan_driver.o(.TRACE)
+ format 0x0880423c Data 74 keyscan_driver.o(.TRACE)
+ __tagsym$$used 0x08804288 Number 0 keyscan_driver.o(.TRACE)
+ format 0x08804288 Data 43 keyscan_driver.o(.TRACE)
+ __tagsym$$used 0x088042b4 Number 0 keyscan_driver.o(.TRACE)
+ format 0x088042b4 Data 81 keyscan_driver.o(.TRACE)
+ __tagsym$$used 0x08804308 Number 0 keyscan_driver.o(.TRACE)
+ format 0x08804308 Data 44 keyscan_driver.o(.TRACE)
+ .TRACE 0x08804334 Section 2640 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804334 Number 0 key_handle.o(.TRACE)
+ format 0x08804334 Data 71 key_handle.o(.TRACE)
+ __tagsym$$used 0x0880437c Number 0 key_handle.o(.TRACE)
+ format 0x0880437c Data 68 key_handle.o(.TRACE)
+ __tagsym$$used 0x088043c0 Number 0 key_handle.o(.TRACE)
+ format 0x088043c0 Data 71 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804408 Number 0 key_handle.o(.TRACE)
+ format 0x08804408 Data 59 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804444 Number 0 key_handle.o(.TRACE)
+ format 0x08804444 Data 62 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804484 Number 0 key_handle.o(.TRACE)
+ format 0x08804484 Data 74 key_handle.o(.TRACE)
+ __tagsym$$used 0x088044d0 Number 0 key_handle.o(.TRACE)
+ format 0x088044d0 Data 74 key_handle.o(.TRACE)
+ __tagsym$$used 0x0880451c Number 0 key_handle.o(.TRACE)
+ format 0x0880451c Data 58 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804558 Number 0 key_handle.o(.TRACE)
+ format 0x08804558 Data 85 key_handle.o(.TRACE)
+ __tagsym$$used 0x088045b0 Number 0 key_handle.o(.TRACE)
+ format 0x088045b0 Data 90 key_handle.o(.TRACE)
+ __tagsym$$used 0x0880460c Number 0 key_handle.o(.TRACE)
+ format 0x0880460c Data 80 key_handle.o(.TRACE)
+ __tagsym$$used 0x0880465c Number 0 key_handle.o(.TRACE)
+ format 0x0880465c Data 92 key_handle.o(.TRACE)
+ __tagsym$$used 0x088046b8 Number 0 key_handle.o(.TRACE)
+ format 0x088046b8 Data 69 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804700 Number 0 key_handle.o(.TRACE)
+ format 0x08804700 Data 47 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804730 Number 0 key_handle.o(.TRACE)
+ format 0x08804730 Data 53 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804768 Number 0 key_handle.o(.TRACE)
+ format 0x08804768 Data 26 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804784 Number 0 key_handle.o(.TRACE)
+ format 0x08804784 Data 25 key_handle.o(.TRACE)
+ __tagsym$$used 0x088047a0 Number 0 key_handle.o(.TRACE)
+ format 0x088047a0 Data 68 key_handle.o(.TRACE)
+ __tagsym$$used 0x088047e4 Number 0 key_handle.o(.TRACE)
+ format 0x088047e4 Data 84 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804838 Number 0 key_handle.o(.TRACE)
+ format 0x08804838 Data 66 key_handle.o(.TRACE)
+ __tagsym$$used 0x0880487c Number 0 key_handle.o(.TRACE)
+ format 0x0880487c Data 65 key_handle.o(.TRACE)
+ __tagsym$$used 0x088048c0 Number 0 key_handle.o(.TRACE)
+ format 0x088048c0 Data 73 key_handle.o(.TRACE)
+ __tagsym$$used 0x0880490c Number 0 key_handle.o(.TRACE)
+ format 0x0880490c Data 66 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804950 Number 0 key_handle.o(.TRACE)
+ format 0x08804950 Data 36 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804974 Number 0 key_handle.o(.TRACE)
+ format 0x08804974 Data 52 key_handle.o(.TRACE)
+ __tagsym$$used 0x088049a8 Number 0 key_handle.o(.TRACE)
+ format 0x088049a8 Data 48 key_handle.o(.TRACE)
+ __tagsym$$used 0x088049d8 Number 0 key_handle.o(.TRACE)
+ format 0x088049d8 Data 38 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804a00 Number 0 key_handle.o(.TRACE)
+ format 0x08804a00 Data 70 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804a48 Number 0 key_handle.o(.TRACE)
+ format 0x08804a48 Data 76 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804a94 Number 0 key_handle.o(.TRACE)
+ format 0x08804a94 Data 69 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804adc Number 0 key_handle.o(.TRACE)
+ format 0x08804adc Data 88 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804b34 Number 0 key_handle.o(.TRACE)
+ format 0x08804b34 Data 89 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804b90 Number 0 key_handle.o(.TRACE)
+ format 0x08804b90 Data 75 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804bdc Number 0 key_handle.o(.TRACE)
+ format 0x08804bdc Data 68 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804c20 Number 0 key_handle.o(.TRACE)
+ format 0x08804c20 Data 75 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804c6c Number 0 key_handle.o(.TRACE)
+ format 0x08804c6c Data 82 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804cc0 Number 0 key_handle.o(.TRACE)
+ format 0x08804cc0 Data 28 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804cdc Number 0 key_handle.o(.TRACE)
+ format 0x08804cdc Data 48 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804d0c Number 0 key_handle.o(.TRACE)
+ format 0x08804d0c Data 70 key_handle.o(.TRACE)
+ __tagsym$$used 0x08804d54 Number 0 key_handle.o(.TRACE)
+ format 0x08804d54 Data 48 key_handle.o(.TRACE)
+ .TRACE 0x08804d84 Section 270 voice_driver.o(.TRACE)
+ __tagsym$$used 0x08804d84 Number 0 voice_driver.o(.TRACE)
+ format 0x08804d84 Data 57 voice_driver.o(.TRACE)
+ __tagsym$$used 0x08804dc0 Number 0 voice_driver.o(.TRACE)
+ format 0x08804dc0 Data 38 voice_driver.o(.TRACE)
+ __tagsym$$used 0x08804de8 Number 0 voice_driver.o(.TRACE)
+ format 0x08804de8 Data 58 voice_driver.o(.TRACE)
+ __tagsym$$used 0x08804e24 Number 0 voice_driver.o(.TRACE)
+ format 0x08804e24 Data 48 voice_driver.o(.TRACE)
+ __tagsym$$used 0x08804e54 Number 0 voice_driver.o(.TRACE)
+ format 0x08804e54 Data 62 voice_driver.o(.TRACE)
+ .TRACE 0x08804e94 Section 3327 voice.o(.TRACE)
+ __tagsym$$used 0x08804e94 Number 0 voice.o(.TRACE)
+ format 0x08804e94 Data 38 voice.o(.TRACE)
+ __tagsym$$used 0x08804ebc Number 0 voice.o(.TRACE)
+ format 0x08804ebc Data 62 voice.o(.TRACE)
+ __tagsym$$used 0x08804efc Number 0 voice.o(.TRACE)
+ format 0x08804efc Data 50 voice.o(.TRACE)
+ __tagsym$$used 0x08804f30 Number 0 voice.o(.TRACE)
+ format 0x08804f30 Data 66 voice.o(.TRACE)
+ __tagsym$$used 0x08804f74 Number 0 voice.o(.TRACE)
+ format 0x08804f74 Data 89 voice.o(.TRACE)
+ __tagsym$$used 0x08804fd0 Number 0 voice.o(.TRACE)
+ format 0x08804fd0 Data 54 voice.o(.TRACE)
+ __tagsym$$used 0x08805008 Number 0 voice.o(.TRACE)
+ format 0x08805008 Data 62 voice.o(.TRACE)
+ __tagsym$$used 0x08805048 Number 0 voice.o(.TRACE)
+ format 0x08805048 Data 49 voice.o(.TRACE)
+ __tagsym$$used 0x0880507c Number 0 voice.o(.TRACE)
+ format 0x0880507c Data 56 voice.o(.TRACE)
+ __tagsym$$used 0x088050b4 Number 0 voice.o(.TRACE)
+ format 0x088050b4 Data 60 voice.o(.TRACE)
+ __tagsym$$used 0x088050f0 Number 0 voice.o(.TRACE)
+ format 0x088050f0 Data 59 voice.o(.TRACE)
+ __tagsym$$used 0x0880512c Number 0 voice.o(.TRACE)
+ format 0x0880512c Data 67 voice.o(.TRACE)
+ __tagsym$$used 0x08805170 Number 0 voice.o(.TRACE)
+ format 0x08805170 Data 45 voice.o(.TRACE)
+ __tagsym$$used 0x088051a0 Number 0 voice.o(.TRACE)
+ format 0x088051a0 Data 47 voice.o(.TRACE)
+ __tagsym$$used 0x088051d0 Number 0 voice.o(.TRACE)
+ format 0x088051d0 Data 43 voice.o(.TRACE)
+ __tagsym$$used 0x088051fc Number 0 voice.o(.TRACE)
+ format 0x088051fc Data 69 voice.o(.TRACE)
+ __tagsym$$used 0x08805244 Number 0 voice.o(.TRACE)
+ format 0x08805244 Data 83 voice.o(.TRACE)
+ __tagsym$$used 0x08805298 Number 0 voice.o(.TRACE)
+ format 0x08805298 Data 68 voice.o(.TRACE)
+ __tagsym$$used 0x088052dc Number 0 voice.o(.TRACE)
+ format 0x088052dc Data 70 voice.o(.TRACE)
+ __tagsym$$used 0x08805324 Number 0 voice.o(.TRACE)
+ format 0x08805324 Data 64 voice.o(.TRACE)
+ __tagsym$$used 0x08805364 Number 0 voice.o(.TRACE)
+ format 0x08805364 Data 43 voice.o(.TRACE)
+ __tagsym$$used 0x08805390 Number 0 voice.o(.TRACE)
+ format 0x08805390 Data 78 voice.o(.TRACE)
+ __tagsym$$used 0x088053e0 Number 0 voice.o(.TRACE)
+ format 0x088053e0 Data 57 voice.o(.TRACE)
+ __tagsym$$used 0x0880541c Number 0 voice.o(.TRACE)
+ format 0x0880541c Data 77 voice.o(.TRACE)
+ __tagsym$$used 0x0880546c Number 0 voice.o(.TRACE)
+ format 0x0880546c Data 70 voice.o(.TRACE)
+ __tagsym$$used 0x088054b4 Number 0 voice.o(.TRACE)
+ format 0x088054b4 Data 76 voice.o(.TRACE)
+ __tagsym$$used 0x08805500 Number 0 voice.o(.TRACE)
+ format 0x08805500 Data 75 voice.o(.TRACE)
+ __tagsym$$used 0x0880554c Number 0 voice.o(.TRACE)
+ format 0x0880554c Data 70 voice.o(.TRACE)
+ __tagsym$$used 0x08805594 Number 0 voice.o(.TRACE)
+ format 0x08805594 Data 83 voice.o(.TRACE)
+ __tagsym$$used 0x088055e8 Number 0 voice.o(.TRACE)
+ format 0x088055e8 Data 59 voice.o(.TRACE)
+ __tagsym$$used 0x08805624 Number 0 voice.o(.TRACE)
+ format 0x08805624 Data 74 voice.o(.TRACE)
+ __tagsym$$used 0x08805670 Number 0 voice.o(.TRACE)
+ format 0x08805670 Data 52 voice.o(.TRACE)
+ __tagsym$$used 0x088056a4 Number 0 voice.o(.TRACE)
+ format 0x088056a4 Data 76 voice.o(.TRACE)
+ __tagsym$$used 0x088056f0 Number 0 voice.o(.TRACE)
+ format 0x088056f0 Data 42 voice.o(.TRACE)
+ __tagsym$$used 0x0880571c Number 0 voice.o(.TRACE)
+ format 0x0880571c Data 45 voice.o(.TRACE)
+ __tagsym$$used 0x0880574c Number 0 voice.o(.TRACE)
+ format 0x0880574c Data 57 voice.o(.TRACE)
+ __tagsym$$used 0x08805788 Number 0 voice.o(.TRACE)
+ format 0x08805788 Data 58 voice.o(.TRACE)
+ __tagsym$$used 0x088057c4 Number 0 voice.o(.TRACE)
+ format 0x088057c4 Data 85 voice.o(.TRACE)
+ __tagsym$$used 0x0880581c Number 0 voice.o(.TRACE)
+ format 0x0880581c Data 47 voice.o(.TRACE)
+ __tagsym$$used 0x0880584c Number 0 voice.o(.TRACE)
+ format 0x0880584c Data 71 voice.o(.TRACE)
+ __tagsym$$used 0x08805894 Number 0 voice.o(.TRACE)
+ format 0x08805894 Data 68 voice.o(.TRACE)
+ __tagsym$$used 0x088058d8 Number 0 voice.o(.TRACE)
+ format 0x088058d8 Data 92 voice.o(.TRACE)
+ __tagsym$$used 0x08805934 Number 0 voice.o(.TRACE)
+ format 0x08805934 Data 68 voice.o(.TRACE)
+ __tagsym$$used 0x08805978 Number 0 voice.o(.TRACE)
+ format 0x08805978 Data 53 voice.o(.TRACE)
+ __tagsym$$used 0x088059b0 Number 0 voice.o(.TRACE)
+ format 0x088059b0 Data 112 voice.o(.TRACE)
+ __tagsym$$used 0x08805a20 Number 0 voice.o(.TRACE)
+ format 0x08805a20 Data 72 voice.o(.TRACE)
+ __tagsym$$used 0x08805a68 Number 0 voice.o(.TRACE)
+ format 0x08805a68 Data 54 voice.o(.TRACE)
+ __tagsym$$used 0x08805aa0 Number 0 voice.o(.TRACE)
+ format 0x08805aa0 Data 66 voice.o(.TRACE)
+ __tagsym$$used 0x08805ae4 Number 0 voice.o(.TRACE)
+ format 0x08805ae4 Data 51 voice.o(.TRACE)
+ __tagsym$$used 0x08805b18 Number 0 voice.o(.TRACE)
+ format 0x08805b18 Data 66 voice.o(.TRACE)
+ __tagsym$$used 0x08805b5c Number 0 voice.o(.TRACE)
+ format 0x08805b5c Data 55 voice.o(.TRACE)
+ .TRACE 0x08805b94 Section 830 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805b94 Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805b94 Data 24 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805bac Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805bac Data 61 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805bec Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805bec Data 36 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805c10 Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805c10 Data 61 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805c50 Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805c50 Data 70 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805c98 Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805c98 Data 31 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805cb8 Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805cb8 Data 55 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805cf0 Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805cf0 Data 48 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805d20 Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805d20 Data 35 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805d44 Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805d44 Data 40 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805d6c Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805d6c Data 58 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805da8 Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805da8 Data 68 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805dec Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805dec Data 57 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805e28 Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805e28 Data 37 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805e50 Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805e50 Data 50 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805e84 Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805e84 Data 54 ir_send_driver.o(.TRACE)
+ __tagsym$$used 0x08805ebc Number 0 ir_send_driver.o(.TRACE)
+ format 0x08805ebc Data 22 ir_send_driver.o(.TRACE)
+ .TRACE 0x08805ed4 Section 581 ir_send_handle.o(.TRACE)
+ __tagsym$$used 0x08805ed4 Number 0 ir_send_handle.o(.TRACE)
+ format 0x08805ed4 Data 53 ir_send_handle.o(.TRACE)
+ __tagsym$$used 0x08805f0c Number 0 ir_send_handle.o(.TRACE)
+ format 0x08805f0c Data 91 ir_send_handle.o(.TRACE)
+ __tagsym$$used 0x08805f68 Number 0 ir_send_handle.o(.TRACE)
+ format 0x08805f68 Data 87 ir_send_handle.o(.TRACE)
+ __tagsym$$used 0x08805fc0 Number 0 ir_send_handle.o(.TRACE)
+ format 0x08805fc0 Data 74 ir_send_handle.o(.TRACE)
+ __tagsym$$used 0x0880600c Number 0 ir_send_handle.o(.TRACE)
+ format 0x0880600c Data 56 ir_send_handle.o(.TRACE)
+ __tagsym$$used 0x08806044 Number 0 ir_send_handle.o(.TRACE)
+ format 0x08806044 Data 59 ir_send_handle.o(.TRACE)
+ __tagsym$$used 0x08806080 Number 0 ir_send_handle.o(.TRACE)
+ format 0x08806080 Data 60 ir_send_handle.o(.TRACE)
+ __tagsym$$used 0x088060bc Number 0 ir_send_handle.o(.TRACE)
+ format 0x088060bc Data 63 ir_send_handle.o(.TRACE)
+ __tagsym$$used 0x088060fc Number 0 ir_send_handle.o(.TRACE)
+ format 0x088060fc Data 29 ir_send_handle.o(.TRACE)
+ .TRACE 0x0880611c Section 2046 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x0880611c Number 0 ir_service_handle.o(.TRACE)
+ format 0x0880611c Data 54 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806154 Number 0 ir_service_handle.o(.TRACE)
+ format 0x08806154 Data 59 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806190 Number 0 ir_service_handle.o(.TRACE)
+ format 0x08806190 Data 93 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x088061f0 Number 0 ir_service_handle.o(.TRACE)
+ format 0x088061f0 Data 88 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806248 Number 0 ir_service_handle.o(.TRACE)
+ format 0x08806248 Data 80 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806298 Number 0 ir_service_handle.o(.TRACE)
+ format 0x08806298 Data 94 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x088062f8 Number 0 ir_service_handle.o(.TRACE)
+ format 0x088062f8 Data 90 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806354 Number 0 ir_service_handle.o(.TRACE)
+ format 0x08806354 Data 68 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806398 Number 0 ir_service_handle.o(.TRACE)
+ format 0x08806398 Data 90 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x088063f4 Number 0 ir_service_handle.o(.TRACE)
+ format 0x088063f4 Data 38 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x0880641c Number 0 ir_service_handle.o(.TRACE)
+ format 0x0880641c Data 53 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806454 Number 0 ir_service_handle.o(.TRACE)
+ format 0x08806454 Data 59 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806490 Number 0 ir_service_handle.o(.TRACE)
+ format 0x08806490 Data 104 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x088064f8 Number 0 ir_service_handle.o(.TRACE)
+ format 0x088064f8 Data 57 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806534 Number 0 ir_service_handle.o(.TRACE)
+ format 0x08806534 Data 66 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806578 Number 0 ir_service_handle.o(.TRACE)
+ format 0x08806578 Data 91 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x088065d4 Number 0 ir_service_handle.o(.TRACE)
+ format 0x088065d4 Data 90 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806630 Number 0 ir_service_handle.o(.TRACE)
+ format 0x08806630 Data 78 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806680 Number 0 ir_service_handle.o(.TRACE)
+ format 0x08806680 Data 86 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x088066d8 Number 0 ir_service_handle.o(.TRACE)
+ format 0x088066d8 Data 87 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806730 Number 0 ir_service_handle.o(.TRACE)
+ format 0x08806730 Data 43 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x0880675c Number 0 ir_service_handle.o(.TRACE)
+ format 0x0880675c Data 68 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x088067a0 Number 0 ir_service_handle.o(.TRACE)
+ format 0x088067a0 Data 43 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x088067cc Number 0 ir_service_handle.o(.TRACE)
+ format 0x088067cc Data 51 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806800 Number 0 ir_service_handle.o(.TRACE)
+ format 0x08806800 Data 54 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806838 Number 0 ir_service_handle.o(.TRACE)
+ format 0x08806838 Data 66 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x0880687c Number 0 ir_service_handle.o(.TRACE)
+ format 0x0880687c Data 71 ir_service_handle.o(.TRACE)
+ __tagsym$$used 0x088068c4 Number 0 ir_service_handle.o(.TRACE)
+ format 0x088068c4 Data 86 ir_service_handle.o(.TRACE)
+ .TRACE 0x0880691c Section 34 led_driver.o(.TRACE)
+ __tagsym$$used 0x0880691c Number 0 led_driver.o(.TRACE)
+ format 0x0880691c Data 34 led_driver.o(.TRACE)
+ .TRACE 0x08806940 Section 157 buzzer_driver.o(.TRACE)
+ __tagsym$$used 0x08806940 Number 0 buzzer_driver.o(.TRACE)
+ format 0x08806940 Data 32 buzzer_driver.o(.TRACE)
+ __tagsym$$used 0x08806960 Number 0 buzzer_driver.o(.TRACE)
+ format 0x08806960 Data 79 buzzer_driver.o(.TRACE)
+ __tagsym$$used 0x088069b0 Number 0 buzzer_driver.o(.TRACE)
+ format 0x088069b0 Data 45 buzzer_driver.o(.TRACE)
+ .TRACE 0x088069e0 Section 767 fms_service_handle.o(.TRACE)
+ __tagsym$$used 0x088069e0 Number 0 fms_service_handle.o(.TRACE)
+ format 0x088069e0 Data 47 fms_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806a10 Number 0 fms_service_handle.o(.TRACE)
+ format 0x08806a10 Data 52 fms_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806a44 Number 0 fms_service_handle.o(.TRACE)
+ format 0x08806a44 Data 86 fms_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806a9c Number 0 fms_service_handle.o(.TRACE)
+ format 0x08806a9c Data 77 fms_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806aec Number 0 fms_service_handle.o(.TRACE)
+ format 0x08806aec Data 69 fms_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806b34 Number 0 fms_service_handle.o(.TRACE)
+ format 0x08806b34 Data 36 fms_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806b58 Number 0 fms_service_handle.o(.TRACE)
+ format 0x08806b58 Data 36 fms_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806b7c Number 0 fms_service_handle.o(.TRACE)
+ format 0x08806b7c Data 44 fms_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806ba8 Number 0 fms_service_handle.o(.TRACE)
+ format 0x08806ba8 Data 78 fms_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806bf8 Number 0 fms_service_handle.o(.TRACE)
+ format 0x08806bf8 Data 41 fms_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806c24 Number 0 fms_service_handle.o(.TRACE)
+ format 0x08806c24 Data 80 fms_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806c74 Number 0 fms_service_handle.o(.TRACE)
+ format 0x08806c74 Data 38 fms_service_handle.o(.TRACE)
+ __tagsym$$used 0x08806c9c Number 0 fms_service_handle.o(.TRACE)
+ format 0x08806c9c Data 67 fms_service_handle.o(.TRACE)
+ .TRACE 0x08806ce0 Section 1197 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806ce0 Number 0 battery_driver.o(.TRACE)
+ format 0x08806ce0 Data 62 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806d20 Number 0 battery_driver.o(.TRACE)
+ format 0x08806d20 Data 41 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806d4c Number 0 battery_driver.o(.TRACE)
+ format 0x08806d4c Data 59 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806d88 Number 0 battery_driver.o(.TRACE)
+ format 0x08806d88 Data 55 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806dc0 Number 0 battery_driver.o(.TRACE)
+ format 0x08806dc0 Data 59 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806dfc Number 0 battery_driver.o(.TRACE)
+ format 0x08806dfc Data 54 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806e34 Number 0 battery_driver.o(.TRACE)
+ format 0x08806e34 Data 52 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806e68 Number 0 battery_driver.o(.TRACE)
+ format 0x08806e68 Data 57 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806ea4 Number 0 battery_driver.o(.TRACE)
+ format 0x08806ea4 Data 53 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806edc Number 0 battery_driver.o(.TRACE)
+ format 0x08806edc Data 54 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806f14 Number 0 battery_driver.o(.TRACE)
+ format 0x08806f14 Data 29 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806f34 Number 0 battery_driver.o(.TRACE)
+ format 0x08806f34 Data 46 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806f64 Number 0 battery_driver.o(.TRACE)
+ format 0x08806f64 Data 30 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806f84 Number 0 battery_driver.o(.TRACE)
+ format 0x08806f84 Data 55 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806fbc Number 0 battery_driver.o(.TRACE)
+ format 0x08806fbc Data 63 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08806ffc Number 0 battery_driver.o(.TRACE)
+ format 0x08806ffc Data 49 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08807030 Number 0 battery_driver.o(.TRACE)
+ format 0x08807030 Data 48 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08807060 Number 0 battery_driver.o(.TRACE)
+ format 0x08807060 Data 45 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08807090 Number 0 battery_driver.o(.TRACE)
+ format 0x08807090 Data 49 battery_driver.o(.TRACE)
+ __tagsym$$used 0x088070c4 Number 0 battery_driver.o(.TRACE)
+ format 0x088070c4 Data 110 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08807134 Number 0 battery_driver.o(.TRACE)
+ format 0x08807134 Data 47 battery_driver.o(.TRACE)
+ __tagsym$$used 0x08807164 Number 0 battery_driver.o(.TRACE)
+ format 0x08807164 Data 41 battery_driver.o(.TRACE)
+ .TRACE 0x08807190 Section 6 frm_vpk_log.o(.TRACE)
+ __tagsym$$used 0x08807190 Number 0 frm_vpk_log.o(.TRACE)
+ format 0x08807190 Data 6 frm_vpk_log.o(.TRACE)
+
+ Global Symbols
+
+ Symbol Name Value Ov Type Size Object(Section)
+
+ BuildAttributes$$THM_ISAv3M$S$PE$A:L22$X:L11$S22$IEEE1$IW$USESV6$~STKCKD$USESV7$~SHL$OTIME$ROPI$IEEEJ$EBA8$UX$STANDARDLIB$REQ8$PRES8$EABIv2 0x00000000 Number 0 anon$$obj.o ABSOLUTE
+ Image$$CACHE_DATA_ON$$RO$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE
+ Image$$CACHE_DATA_ON$$RW$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE
+ Image$$CACHE_DATA_ON$$ZI$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_A$$RW$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_A$$ZI$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_B$$RO$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_B$$RW$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_B$$ZI$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_C$$RO$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_C$$RW$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_C$$ZI$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE
+ __ARM_use_no_argv 0x00000000 Number 0 main.o ABSOLUTE
+ _printf_flags 0x00000000 Number 0 printf_stubs.o ABSOLUTE
+ _printf_return_value 0x00000000 Number 0 printf_stubs.o ABSOLUTE
+ _printf_sizespec 0x00000000 Number 0 printf_stubs.o ABSOLUTE
+ _printf_widthprec 0x00000000 Number 0 printf_stubs.o ABSOLUTE
+ __ARM_exceptions_init - Undefined Weak Reference
+ __alloca_initialize - Undefined Weak Reference
+ __arm_preinit_ - Undefined Weak Reference
+ __cpp_initialize__aeabi_ - Undefined Weak Reference
+ __scatterload - Undefined Weak Reference
+ __sigvec_lookup - Undefined Weak Reference
+ _atexit_init - Undefined Weak Reference
+ _clock_init - Undefined Weak Reference
+ _fp_trap_init - Undefined Weak Reference
+ _get_lc_collate - Undefined Weak Reference
+ _get_lc_monetary - Undefined Weak Reference
+ _get_lc_time - Undefined Weak Reference
+ _getenv_init - Undefined Weak Reference
+ _handle_redirection - Undefined Weak Reference
+ _init_alloc - Undefined Weak Reference
+ _init_user_alloc - Undefined Weak Reference
+ _initio - Undefined Weak Reference
+ _printf_mbtowc - Undefined Weak Reference
+ _printf_wc - Undefined Weak Reference
+ _signal_init - Undefined Weak Reference
+ Image$$OVERLAY_A$$RO$$Length 0x000000c8 Number 0 anon$$obj.o ABSOLUTE
+ Image$$RAM_VECTOR_TABLE$$RO$$Length 0x000000e8 Number 0 anon$$obj.o ABSOLUTE
+ __Vectors_Size 0x000000e8 Number 0 startup_rtl876x.o ABSOLUTE
+ vAssertHandler 0x00000209 Thumb Code 0 ROM.lib ABSOLUTE
+ WDG_SystemReset 0x0000029d Thumb Code 0 ROM.lib ABSOLUTE
+ __aeabi_memcpy4 0x000002a9 Thumb Code 0 ROM.lib ABSOLUTE
+ __aeabi_memcpy8 0x000002a9 Thumb Code 0 ROM.lib ABSOLUTE
+ Image$$RAM_DATA_ON$$RW$$Length 0x000003b0 Number 0 anon$$obj.o ABSOLUTE
+ Image$$RAM_DATA_ON$$RO$$Length 0x000014a8 Number 0 anon$$obj.o ABSOLUTE
+ Image$$RAM_DATA_ON$$ZI$$Length 0x000025ac Number 0 anon$$obj.o ABSOLUTE
+ RamVectorTableInit 0x000034d1 Thumb Code 0 ROM.lib ABSOLUTE
+ RamVectorTableUpdate 0x000034f7 Thumb Code 0 ROM.lib ABSOLUTE
+ LOGUARTDriverInit 0x000037ed Thumb Code 0 ROM.lib ABSOLUTE
+ DumpRawMemory 0x000043ab Thumb Code 0 ROM.lib ABSOLUTE
+ dump_raw_memory_all 0x00004519 Thumb Code 0 ROM.lib ABSOLUTE
+ hardfault_print_buffered_log 0x00004573 Thumb Code 0 ROM.lib ABSOLUTE
+ ROM_Default_Handler 0x000047e7 Thumb Code 0 ROM.lib ABSOLUTE
+ SystemCall 0x0000491b Thumb Code 0 ROM.lib ABSOLUTE
+ SystemCall_Stack 0x00004927 Thumb Code 0 ROM.lib ABSOLUTE
+ update_ram_layout 0x00004a79 Thumb Code 0 ROM.lib ABSOLUTE
+ get_active_ota_bank_addr 0x000053a5 Thumb Code 0 ROM.lib ABSOLUTE
+ btxfcs 0x000054ed Thumb Code 0 ROM.lib ABSOLUTE
+ PPB_BufSwitch 0x00005665 Thumb Code 0 ROM.lib ABSOLUTE
+ PPB_Init 0x00005689 Thumb Code 0 ROM.lib ABSOLUTE
+ PPB_Uninit 0x000056dd Thumb Code 0 ROM.lib ABSOLUTE
+ PPB_Init_DLPS_Restore 0x00005701 Thumb Code 0 ROM.lib ABSOLUTE
+ PPB_Write 0x00005709 Thumb Code 0 ROM.lib ABSOLUTE
+ PPB_ClearOutputBuffer 0x000057db Thumb Code 0 ROM.lib ABSOLUTE
+ LogUartTxChar 0x00005811 Thumb Code 0 ROM.lib ABSOLUTE
+ log_timestamp_get 0x00005853 Thumb Code 0 ROM.lib ABSOLUTE
+ log_direct 0x00005a07 Thumb Code 0 ROM.lib ABSOLUTE
+ log_buffer 0x00005aa9 Thumb Code 0 ROM.lib ABSOLUTE
+ log_index 0x00005bcd Thumb Code 0 ROM.lib ABSOLUTE
+ log_snoop 0x00005cdf Thumb Code 0 ROM.lib ABSOLUTE
+ trace_bdaddr 0x00005ddf Thumb Code 0 ROM.lib ABSOLUTE
+ trace_string 0x00005e6b Thumb Code 0 ROM.lib ABSOLUTE
+ trace_binary 0x00005f07 Thumb Code 0 ROM.lib ABSOLUTE
+ LogBufferLowerStack 0x00005f9f Thumb Code 0 ROM.lib ABSOLUTE
+ LogBufferLowerStackData 0x000060c5 Thumb Code 0 ROM.lib ABSOLUTE
+ log_module_trace_init 0x000061a3 Thumb Code 0 ROM.lib ABSOLUTE
+ log_module_trace_set 0x000061d3 Thumb Code 0 ROM.lib ABSOLUTE
+ log_module_bitmap_trace_set 0x0000621f Thumb Code 0 ROM.lib ABSOLUTE
+ LogUartDMAStart 0x00006323 Thumb Code 0 ROM.lib ABSOLUTE
+ LogDMA_SM_Dispatch 0x00006335 Thumb Code 0 ROM.lib ABSOLUTE
+ LogUartDMAInit 0x000063bd Thumb Code 0 ROM.lib ABSOLUTE
+ LogUartDMAIdleHook 0x000064b1 Thumb Code 0 ROM.lib ABSOLUTE
+ log_pm_check 0x0000651f Thumb Code 0 ROM.lib ABSOLUTE
+ hw_aes_encrypt128_use_dma 0x0000675d Thumb Code 0 ROM.lib ABSOLUTE
+ hw_aes_decrypt128_use_dma 0x000067a1 Thumb Code 0 ROM.lib ABSOLUTE
+ aes128_ecb_encrypt 0x000067e5 Thumb Code 0 ROM.lib ABSOLUTE
+ aes128_ecb_decrypt 0x00006841 Thumb Code 0 ROM.lib ABSOLUTE
+ aes128_ecb_encrypt_msb2lsb 0x0000689b Thumb Code 0 ROM.lib ABSOLUTE
+ aes128_ecb_decrypt_msb2lsb 0x000068b3 Thumb Code 0 ROM.lib ABSOLUTE
+ aes256_ecb_encrypt 0x000068cb Thumb Code 0 ROM.lib ABSOLUTE
+ aes256_ecb_decrypt 0x00006927 Thumb Code 0 ROM.lib ABSOLUTE
+ aes256_ecb_encrypt_msb2lsb 0x00006981 Thumb Code 0 ROM.lib ABSOLUTE
+ aes256_ecb_decrypt_msb2lsb 0x00006999 Thumb Code 0 ROM.lib ABSOLUTE
+ hw_aes_decrypt_16byte 0x000069ed Thumb Code 0 ROM.lib ABSOLUTE
+ ftl_ioctl 0x000075d3 Thumb Code 0 ROM.lib ABSOLUTE
+ ftl_load 0x00007b1f Thumb Code 0 ROM.lib ABSOLUTE
+ ftl_save 0x00007b33 Thumb Code 0 ROM.lib ABSOLUTE
+ ftl_init 0x00007c45 Thumb Code 0 ROM.lib ABSOLUTE
+ hardfault_dump 0x00007df1 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_dump_flash_info 0x0000805f Thumb Code 0 ROM.lib ABSOLUTE
+ flash_get_flash_exist 0x000080b3 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_get_bank_addr 0x000080b9 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_get_bank_size 0x0000813b Thumb Code 0 ROM.lib ABSOLUTE
+ flash_erase_locked 0x000081a1 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_ioctl 0x000081f7 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_write_locked 0x00008601 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_auto_write_locked 0x00008629 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_auto_write_buffer_locked 0x0000864b Thumb Code 0 ROM.lib ABSOLUTE
+ flash_read_locked 0x00008671 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_auto_read_locked 0x00008699 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_split_read_locked 0x000086b7 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_auto_dma_read_locked 0x000086e1 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_auto_seq_trans_dma_read_locked 0x00008709 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_try_high_speed 0x00008731 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_get_block_protect_locked 0x000088f1 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_set_block_protect_locked 0x00008917 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_sw_protect_unlock_by_addr_locked 0x0000893d Thumb Code 0 ROM.lib ABSOLUTE
+ crc8EtsGen 0x000089cd Thumb Code 0 ROM.lib ABSOLUTE
+ crc8EtsCheck 0x000089ed Thumb Code 0 ROM.lib ABSOLUTE
+ set_hci_mode_flag 0x00008a1d Thumb Code 0 ROM.lib ABSOLUTE
+ check_hci_mode_flag 0x00008a47 Thumb Code 0 ROM.lib ABSOLUTE
+ check_image_chksum 0x00008a5d Thumb Code 0 ROM.lib ABSOLUTE
+ check_header_valid 0x00008a83 Thumb Code 0 ROM.lib ABSOLUTE
+ get_header_addr_by_img_id 0x00008ae3 Thumb Code 0 ROM.lib ABSOLUTE
+ get_active_bank_image_size_by_img_id 0x00008b3f Thumb Code 0 ROM.lib ABSOLUTE
+ is_ota_support_bank_switch 0x00008b7b Thumb Code 0 ROM.lib ABSOLUTE
+ get_temp_ota_bank_addr_by_img_id 0x00008b95 Thumb Code 0 ROM.lib ABSOLUTE
+ get_temp_ota_bank_size_by_img_id 0x00008c07 Thumb Code 0 ROM.lib ABSOLUTE
+ get_active_bank_image_version 0x00008c73 Thumb Code 0 ROM.lib ABSOLUTE
+ platform_random 0x00008d3f Thumb Code 0 ROM.lib ABSOLUTE
+ flash_erase 0x00009fcf Thumb Code 0 ROM.lib ABSOLUTE
+ flash_set_bit 0x0000a559 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_get_bit 0x0000a561 Thumb Code 0 ROM.lib ABSOLUTE
+ flash_write 0x0000a56d Thumb Code 0 ROM.lib ABSOLUTE
+ flash_auto_write 0x0000a875 Thumb Code 0 ROM.lib ABSOLUTE
+ power_manager_suspend_all 0x0000d207 Thumb Code 0 ROM.lib ABSOLUTE
+ power_manager_resume_all 0x0000d211 Thumb Code 0 ROM.lib ABSOLUTE
+ platform_pm_set_power_mode 0x0000d755 Thumb Code 0 ROM.lib ABSOLUTE
+ platform_pm_get_power_mode 0x0000d769 Thumb Code 0 ROM.lib ABSOLUTE
+ platform_pm_get_error_code 0x0000d76f Thumb Code 0 ROM.lib ABSOLUTE
+ platform_pm_get_refuse_reason 0x0000d775 Thumb Code 0 ROM.lib ABSOLUTE
+ platform_pm_get_statistics 0x0000d78f Thumb Code 0 ROM.lib ABSOLUTE
+ platform_pm_get_wakeup_reason 0x0000d7b9 Thumb Code 0 ROM.lib ABSOLUTE
+ platform_pm_register_callback_func 0x0000d7c9 Thumb Code 0 ROM.lib ABSOLUTE
+ platform_pm_stop_all_non_excluded_timer 0x0000d8cb Thumb Code 0 ROM.lib ABSOLUTE
+ vTaskStatusDump 0x000105c9 Thumb Code 0 ROM.lib ABSOLUTE
+ vTimerCreateFailedHook 0x000111a7 Thumb Code 0 ROM.lib ABSOLUTE
+ hw_aes_init 0x00011dff Thumb Code 0 ROM.lib ABSOLUTE
+ hw_aes_cpu_operate 0x00011f6d Thumb Code 0 ROM.lib ABSOLUTE
+ hw_aes_set_dma_tx_done 0x00011f79 Thumb Code 0 ROM.lib ABSOLUTE
+ hw_aes_set_dma_rx_done 0x00011f7f Thumb Code 0 ROM.lib ABSOLUTE
+ hw_aes_dma_operate 0x00011f85 Thumb Code 0 ROM.lib ABSOLUTE
+ hw_aes_dma_interrupt_disable 0x0001210b Thumb Code 0 ROM.lib ABSOLUTE
+ hw_aes_is_dma_rx_done 0x000121af Thumb Code 0 ROM.lib ABSOLUTE
+ hw_aes_is_dma_tx_done 0x000121b5 Thumb Code 0 ROM.lib ABSOLUTE
+ hw_aes_dma_done 0x000121bb Thumb Code 0 ROM.lib ABSOLUTE
+ hw_aes_set_dma_move_src 0x000121c5 Thumb Code 0 ROM.lib ABSOLUTE
+ hw_aes_set_dma_move_dst 0x000121e5 Thumb Code 0 ROM.lib ABSOLUTE
+ hw_aes_set_dma_carry_size 0x000121eb Thumb Code 0 ROM.lib ABSOLUTE
+ aes_cmac_inverse 0x0001235f Thumb Code 0 ROM.lib ABSOLUTE
+ get_secure_reg_cfg_val 0x00012417 Thumb Code 0 ROM.lib ABSOLUTE
+ WDG_ClockEnable 0x00012959 Thumb Code 0 ROM.lib ABSOLUTE
+ WDG_Config 0x00012977 Thumb Code 0 ROM.lib ABSOLUTE
+ WDG_Enable 0x000129bb Thumb Code 0 ROM.lib ABSOLUTE
+ WDG_Disable 0x000129d5 Thumb Code 0 ROM.lib ABSOLUTE
+ WDG_Restart 0x000129ef Thumb Code 0 ROM.lib ABSOLUTE
+ reset_reason_get 0x00012b71 Thumb Code 0 ROM.lib ABSOLUTE
+ os_mem_alloc_intern 0x00012c31 Thumb Code 0 ROM.lib ABSOLUTE
+ os_mem_zalloc_intern 0x00012c8b Thumb Code 0 ROM.lib ABSOLUTE
+ os_mem_aligned_alloc_intern 0x00012ced Thumb Code 0 ROM.lib ABSOLUTE
+ os_mem_free 0x00012d4d Thumb Code 0 ROM.lib ABSOLUTE
+ os_mem_aligned_free 0x00012d69 Thumb Code 0 ROM.lib ABSOLUTE
+ os_mem_peek 0x00012d85 Thumb Code 0 ROM.lib ABSOLUTE
+ os_mem_check_heap_usage 0x00012da7 Thumb Code 0 ROM.lib ABSOLUTE
+ os_msg_queue_create_intern 0x00012de1 Thumb Code 0 ROM.lib ABSOLUTE
+ os_msg_queue_delete_intern 0x00012e39 Thumb Code 0 ROM.lib ABSOLUTE
+ os_msg_queue_peek_intern 0x00012e83 Thumb Code 0 ROM.lib ABSOLUTE
+ os_msg_send_intern 0x00012ed7 Thumb Code 0 ROM.lib ABSOLUTE
+ os_msg_recv_intern 0x00012f33 Thumb Code 0 ROM.lib ABSOLUTE
+ os_msg_peek_intern 0x00012f91 Thumb Code 0 ROM.lib ABSOLUTE
+ os_queue_init 0x00013011 Thumb Code 0 ROM.lib ABSOLUTE
+ os_queue_in 0x0001301b Thumb Code 0 ROM.lib ABSOLUTE
+ os_queue_out 0x0001304b Thumb Code 0 ROM.lib ABSOLUTE
+ os_queue_peek 0x0001307f Thumb Code 0 ROM.lib ABSOLUTE
+ os_queue_insert 0x00013083 Thumb Code 0 ROM.lib ABSOLUTE
+ os_queue_delete 0x000130c3 Thumb Code 0 ROM.lib ABSOLUTE
+ os_systick_handler 0x00013131 Thumb Code 0 ROM.lib ABSOLUTE
+ os_delay 0x00013147 Thumb Code 0 ROM.lib ABSOLUTE
+ os_sys_time_get 0x00013163 Thumb Code 0 ROM.lib ABSOLUTE
+ os_sys_tick_get 0x00013181 Thumb Code 0 ROM.lib ABSOLUTE
+ os_sys_tick_increase 0x0001319f Thumb Code 0 ROM.lib ABSOLUTE
+ os_sched_start 0x000131c3 Thumb Code 0 ROM.lib ABSOLUTE
+ os_sched_stop 0x000131e1 Thumb Code 0 ROM.lib ABSOLUTE
+ os_sched_suspend 0x000131ff Thumb Code 0 ROM.lib ABSOLUTE
+ os_sched_resume 0x0001321d Thumb Code 0 ROM.lib ABSOLUTE
+ os_sched_is_start 0x0001323b Thumb Code 0 ROM.lib ABSOLUTE
+ os_sched_state_get 0x00013259 Thumb Code 0 ROM.lib ABSOLUTE
+ os_vector_table_update 0x00013277 Thumb Code 0 ROM.lib ABSOLUTE
+ os_init 0x0001328d Thumb Code 0 ROM.lib ABSOLUTE
+ os_lock 0x000132d9 Thumb Code 0 ROM.lib ABSOLUTE
+ os_unlock 0x000132f5 Thumb Code 0 ROM.lib ABSOLUTE
+ os_sem_create 0x00013311 Thumb Code 0 ROM.lib ABSOLUTE
+ os_sem_delete 0x0001333d Thumb Code 0 ROM.lib ABSOLUTE
+ os_sem_take 0x00013361 Thumb Code 0 ROM.lib ABSOLUTE
+ os_sem_give 0x00013389 Thumb Code 0 ROM.lib ABSOLUTE
+ os_mutex_create 0x000133ad Thumb Code 0 ROM.lib ABSOLUTE
+ os_mutex_delete 0x000133d1 Thumb Code 0 ROM.lib ABSOLUTE
+ os_mutex_take 0x000133f5 Thumb Code 0 ROM.lib ABSOLUTE
+ os_mutex_give 0x0001341d Thumb Code 0 ROM.lib ABSOLUTE
+ os_task_create 0x00013469 Thumb Code 0 ROM.lib ABSOLUTE
+ os_task_delete 0x000134a5 Thumb Code 0 ROM.lib ABSOLUTE
+ os_task_suspend 0x000134c9 Thumb Code 0 ROM.lib ABSOLUTE
+ os_task_resume 0x000134ed Thumb Code 0 ROM.lib ABSOLUTE
+ os_task_yield 0x00013511 Thumb Code 0 ROM.lib ABSOLUTE
+ os_task_handle_get 0x0001352f Thumb Code 0 ROM.lib ABSOLUTE
+ os_task_priority_get 0x00013553 Thumb Code 0 ROM.lib ABSOLUTE
+ os_task_priority_set 0x0001357b Thumb Code 0 ROM.lib ABSOLUTE
+ os_task_status_dump 0x000135a3 Thumb Code 0 ROM.lib ABSOLUTE
+ os_task_dlps_return_idle_task 0x000135b9 Thumb Code 0 ROM.lib ABSOLUTE
+ os_timer_id_get 0x000135f9 Thumb Code 0 ROM.lib ABSOLUTE
+ os_timer_create 0x00013635 Thumb Code 0 ROM.lib ABSOLUTE
+ os_timer_start 0x00013671 Thumb Code 0 ROM.lib ABSOLUTE
+ os_timer_restart 0x00013695 Thumb Code 0 ROM.lib ABSOLUTE
+ os_timer_stop 0x000136bd Thumb Code 0 ROM.lib ABSOLUTE
+ os_timer_delete 0x000136e1 Thumb Code 0 ROM.lib ABSOLUTE
+ os_timer_dump 0x00013705 Thumb Code 0 ROM.lib ABSOLUTE
+ os_timer_state_get 0x00013723 Thumb Code 0 ROM.lib ABSOLUTE
+ os_timer_init 0x0001375f Thumb Code 0 ROM.lib ABSOLUTE
+ os_timer_number_get 0x00013775 Thumb Code 0 ROM.lib ABSOLUTE
+ os_timer_pendcall 0x0001379d Thumb Code 0 ROM.lib ABSOLUTE
+ os_timer_next_timeout_value_get 0x000137cb Thumb Code 0 ROM.lib ABSOLUTE
+ osif_timer_create 0x00013f9f Thumb Code 0 ROM.lib ABSOLUTE
+ rtk_write_modem_radio_reg 0x000184ad Thumb Code 0 ROM.lib ABSOLUTE
+ rtk_read_modem_radio_reg 0x00018515 Thumb Code 0 ROM.lib ABSOLUTE
+ hci_handle_le_receiver_test 0x0001a81b Thumb Code 0 ROM.lib ABSOLUTE
+ hci_handle_le_test_end 0x0001ac3b Thumb Code 0 ROM.lib ABSOLUTE
+ btaon_fast_read 0x00032f61 Thumb Code 0 ROM.lib ABSOLUTE
+ btaon_fast_read_8b 0x00032f75 Thumb Code 0 ROM.lib ABSOLUTE
+ btaon_fast_read_safe 0x00032f95 Thumb Code 0 ROM.lib ABSOLUTE
+ btaon_fast_read_safe_8b 0x00032fb1 Thumb Code 0 ROM.lib ABSOLUTE
+ btaon_fast_write 0x00032fdb Thumb Code 0 ROM.lib ABSOLUTE
+ btaon_fast_write_8b 0x00032ffb Thumb Code 0 ROM.lib ABSOLUTE
+ btaon_fast_write_safe 0x00033039 Thumb Code 0 ROM.lib ABSOLUTE
+ btaon_fast_write_safe_8b 0x00033063 Thumb Code 0 ROM.lib ABSOLUTE
+ btaon_fast_update 0x000330a9 Thumb Code 0 ROM.lib ABSOLUTE
+ btaon_fast_update_8b 0x000330c3 Thumb Code 0 ROM.lib ABSOLUTE
+ btaon_fast_update_safe 0x000330df Thumb Code 0 ROM.lib ABSOLUTE
+ btaon_fast_update_safe_8b 0x000330fb Thumb Code 0 ROM.lib ABSOLUTE
+ init_dft 0x0003d547 Thumb Code 0 ROM.lib ABSOLUTE
+ modem_dft 0x0003d66f Thumb Code 0 ROM.lib ABSOLUTE
+ deinit_dft 0x0003d751 Thumb Code 0 ROM.lib ABSOLUTE
+ btmac_pm_set_power_mode 0x0003df43 Thumb Code 0 ROM.lib ABSOLUTE
+ btmac_pm_get_error_code 0x0003df4f Thumb Code 0 ROM.lib ABSOLUTE
+ btmac_pm_get_wakeup_reason 0x0003df55 Thumb Code 0 ROM.lib ABSOLUTE
+ btmac_pm_get_statistics 0x0003df5b Thumb Code 0 ROM.lib ABSOLUTE
+ dfu_dump_header 0x0003ed01 Thumb Code 0 ROM.lib ABSOLUTE
+ dfu_set_ready 0x0003ed1b Thumb Code 0 ROM.lib ABSOLUTE
+ dfu_set_obsolete 0x0003ed25 Thumb Code 0 ROM.lib ABSOLUTE
+ dfu_check_ota_mode_flag 0x0003ed31 Thumb Code 0 ROM.lib ABSOLUTE
+ dfu_reset 0x0003ed45 Thumb Code 0 ROM.lib ABSOLUTE
+ dfu_process_crc 0x0003edc3 Thumb Code 0 ROM.lib ABSOLUTE
+ dfu_process_sha256 0x0003ee99 Thumb Code 0 ROM.lib ABSOLUTE
+ SHA256_Init 0x0003f4ad Thumb Code 0 ROM.lib ABSOLUTE
+ SHA256_Update 0x0003f4d7 Thumb Code 0 ROM.lib ABSOLUTE
+ SHA256_Final 0x0003f517 Thumb Code 0 ROM.lib ABSOLUTE
+ SHA256 0x0003f5d5 Thumb Code 0 ROM.lib ABSOLUTE
+ setlocale 0x0003f795 Thumb Code 0 ROM.lib ABSOLUTE
+ memcmp 0x0003f7a9 Thumb Code 0 ROM.lib ABSOLUTE
+ strlen 0x0003f805 Thumb Code 0 ROM.lib ABSOLUTE
+ __aeabi_memcpy 0x0003f849 Thumb Code 0 ROM.lib ABSOLUTE
+ __rt_memcpy 0x0003f849 Thumb Code 0 ROM.lib ABSOLUTE
+ __aeabi_memset 0x0003f8cb Thumb Code 0 ROM.lib ABSOLUTE
+ _memset_w 0x0003f8dd Thumb Code 0 ROM.lib ABSOLUTE
+ _memset 0x0003f8f7 Thumb Code 0 ROM.lib ABSOLUTE
+ __aeabi_memclr 0x0003f915 Thumb Code 0 ROM.lib ABSOLUTE
+ __rt_memclr 0x0003f915 Thumb Code 0 ROM.lib ABSOLUTE
+ __aeabi_memclr4 0x0003f919 Thumb Code 0 ROM.lib ABSOLUTE
+ __aeabi_memclr8 0x0003f919 Thumb Code 0 ROM.lib ABSOLUTE
+ __rt_memclr_w 0x0003f919 Thumb Code 0 ROM.lib ABSOLUTE
+ exit 0x000409b9 Thumb Code 0 ROM.lib ABSOLUTE
+ __Vectors 0x00200000 Data 4 startup_rtl876x.o(VECTOR)
+ __Vectors_End 0x002000e8 Data 0 startup_rtl876x.o(VECTOR)
+ pMCU_PPB 0x00200104 Data 0 ROM.lib ABSOLUTE
+ pLogDMA_SM 0x00200108 Data 0 ROM.lib ABSOLUTE
+ socv_ft_data 0x00200110 Data 0 ROM.lib ABSOLUTE
+ platform_delay_us 0x0020011c Data 0 ROM.lib ABSOLUTE
+ platform_delay_ms 0x00200120 Data 0 ROM.lib ABSOLUTE
+ otp 0x00200164 Data 0 ROM.lib ABSOLUTE
+ SystemCpuClock 0x00200524 Data 0 ROM.lib ABSOLUTE
+ init_true_random_generator 0x00200854 Data 0 ROM.lib ABSOLUTE
+ get_true_random_number 0x00200858 Data 0 ROM.lib ABSOLUTE
+ rtk_write_rfc_reg_pi 0x002008b0 Data 0 ROM.lib ABSOLUTE
+ rtk_read_modem_radio_reg_pi 0x002008b4 Data 0 ROM.lib ABSOLUTE
+ rtk_write_modem_radio_reg_pi 0x002008b8 Data 0 ROM.lib ABSOLUTE
+ rtk_ioq_read_rfc_reg 0x002008e0 Data 0 ROM.lib ABSOLUTE
+ rtk_update_rfc_reg_pi 0x002008e4 Data 0 ROM.lib ABSOLUTE
+ phy_auto_gated_on 0x00200ea0 Data 0 ROM.lib ABSOLUTE
+ phy_auto_gated_off 0x00200ea4 Data 0 ROM.lib ABSOLUTE
+ btmac_pm_system 0x002010d4 Data 0 ROM.lib ABSOLUTE
+ app_pre_main 0x002011d0 Data 0 ROM.lib ABSOLUTE
+ upperstack_entry 0x002011d4 Data 0 ROM.lib ABSOLUTE
+ app_main 0x002011d8 Data 0 ROM.lib ABSOLUTE
+ log_seq_num 0x002011e8 Data 0 ROM.lib ABSOLUTE
+ is_log_init 0x002011ea Data 0 ROM.lib ABSOLUTE
+ flash_sem 0x00201228 Data 0 ROM.lib ABSOLUTE
+ flash_device_info 0x00201258 Data 0 ROM.lib ABSOLUTE
+ pxCurrentTCB 0x00201340 Data 0 ROM.lib ABSOLUTE
+ xTickCount 0x0020134c Data 0 ROM.lib ABSOLUTE
+ pTaskHandleList 0x00201374 Data 0 ROM.lib ABSOLUTE
+ uxTimerCreateCount 0x00201474 Data 0 ROM.lib ABSOLUTE
+ uxTimerDeleteCount 0x00201476 Data 0 ROM.lib ABSOLUTE
+ xTimerQueue 0x00201478 Data 0 ROM.lib ABSOLUTE
+ pxTimerPool 0x00201488 Data 0 ROM.lib ABSOLUTE
+ puxUsedTimerPoolMask 0x0020148c Data 0 ROM.lib ABSOLUTE
+ xFreeBytesRemaining 0x002014d8 Data 0 ROM.lib ABSOLUTE
+ xMinimumEverFreeBytesRemaining 0x002014e0 Data 0 ROM.lib ABSOLUTE
+ xHeapTotalSize 0x002014e8 Data 0 ROM.lib ABSOLUTE
+ xStart 0x002014f0 Data 0 ROM.lib ABSOLUTE
+ app_cb_wdg_reset 0x00201514 Data 0 ROM.lib ABSOLUTE
+ patch_osif_os_sys_time_get 0x00201580 Data 0 ROM.lib ABSOLUTE
+ patch_osif_os_msg_send_intern 0x00201608 Data 0 ROM.lib ABSOLUTE
+ patch_osif_os_timer_create 0x00201644 Data 0 ROM.lib ABSOLUTE
+ Patch_Dump_CPU_Register_and_Memory 0x00201694 Data 0 ROM.lib ABSOLUTE
+ patch_vTaskSwitchContext 0x002016c0 Data 0 ROM.lib ABSOLUTE
+ patch_traceTaskSwitchIn 0x002016c4 Data 0 ROM.lib ABSOLUTE
+ patch_HardFaultRecord_TryToSave 0x0020182c Data 0 ROM.lib ABSOLUTE
+ low_task_handle 0x00201858 Data 0 ROM.lib ABSOLUTE
+ __initial_sp 0x00203800 Number 0 startup_rtl876x.o ABSOLUTE
+ GPIO_Group3_Handler 0x00207c01 * Thumb Code 72 system_rtl876x.o(.app.data_ram.text)
+ Image$$RAM_DATA_ON$$RO$$Base 0x00207c00 Number 0 anon$$obj.o ABSOLUTE
+ GPIO_Group2_Handler 0x00207c49 * Thumb Code 72 system_rtl876x.o(.app.data_ram.text)
+ GPIO_Group1_Handler 0x00207c91 * Thumb Code 64 system_rtl876x.o(.app.data_ram.text)
+ GPIO_Group0_Handler 0x00207cd1 * Thumb Code 64 system_rtl876x.o(.app.data_ram.text)
+ DLPS_IO_EnterDlpsCb 0x00207d9f Thumb Code 276 rtl876x_io_dlps.o(.app.data_ram.text)
+ DLPS_IO_ExitDlpsCb 0x00207eb3 Thumb Code 260 rtl876x_io_dlps.o(.app.data_ram.text)
+ System_Handler 0x002081d3 * Thumb Code 60 main.o(.app.data_ram.text)
+ app_handle_io_msg 0x00208229 Thumb Code 194 rcu_application.o(.app.data_ram.text)
+ app_send_msg_to_apptask 0x00208473 * Thumb Code 84 app_task.o(.app.data_ram.text)
+ dtm_task 0x002084c7 * Thumb Code 118 app_task.o(.app.data_ram.text)
+ Timer5_Handler 0x00208551 * Thumb Code 56 reset_watch_dog_timer.o(.app.data_ram.text)
+ loop_queue_get_vailid_data_size 0x00208595 * Thumb Code 58 loop_queue.o(.app.data_ram.text)
+ loop_queue_get_free_data_size 0x002085cf Thumb Code 58 loop_queue.o(.app.data_ram.text)
+ loop_queue_is_full 0x00208609 Thumb Code 44 loop_queue.o(.app.data_ram.text)
+ loop_queue_is_empty 0x00208635 * Thumb Code 26 loop_queue.o(.app.data_ram.text)
+ loop_queue_write_buf 0x0020864f * Thumb Code 186 loop_queue.o(.app.data_ram.text)
+ loop_queue_read_buf 0x00208709 * Thumb Code 154 loop_queue.o(.app.data_ram.text)
+ loop_queue_copy_buf 0x002087a3 * Thumb Code 152 loop_queue.o(.app.data_ram.text)
+ RTC_Handler 0x0020883d * Thumb Code 76 rtc_driver.o(.app.data_ram.text)
+ keyscan_init_data 0x002088ed * Thumb Code 20 keyscan_driver.o(.app.data_ram.text)
+ keyscan_init_pad_config 0x00208901 * Thumb Code 40 keyscan_driver.o(.app.data_ram.text)
+ keyscan_init_driver 0x00208929 * Thumb Code 142 keyscan_driver.o(.app.data_ram.text)
+ keyscan_enter_dlps_config 0x002089b7 Thumb Code 90 keyscan_driver.o(.app.data_ram.text)
+ keyscan_exit_dlps_config 0x00208a11 Thumb Code 30 keyscan_driver.o(.app.data_ram.text)
+ keyscan_check_dlps 0x00208a2f Thumb Code 6 keyscan_driver.o(.app.data_ram.text)
+ Keyscan_Handler 0x00208a35 * Thumb Code 264 keyscan_driver.o(.app.data_ram.text)
+ voice_driver_dlps_check 0x00208c7d Thumb Code 6 voice_driver.o(.app.data_ram.text)
+ GDMA0_Channel0_Handler 0x00208c83 * Thumb Code 86 voice_driver.o(.app.data_ram.text)
+ GDMA0_Channel1_Handler 0x00208dc3 * Thumb Code 22 ir_send_driver.o(.app.data_ram.text)
+ ir_send_check_dlps 0x00208dd9 Thumb Code 16 ir_send_driver.o(.app.data_ram.text)
+ ir_send_enter_dlps_config 0x00208de9 Thumb Code 22 ir_send_driver.o(.app.data_ram.text)
+ ir_send_exit_dlps_config 0x00208dff Thumb Code 24 ir_send_driver.o(.app.data_ram.text)
+ bat_enter_dlps_config 0x00208f93 Thumb Code 34 battery_driver.o(.app.data_ram.text)
+ bat_exit_dlps_config 0x00208fb5 Thumb Code 54 battery_driver.o(.app.data_ram.text)
+ frm_vpk_print 0x00209051 * Thumb Code 52 frm_vpk_log.o(.app.data_ram.text)
+ DLPS_IORegister 0x0020908d * Thumb Code 20 rtl876x_io_dlps.o(.text)
+ Image$$RAM_DATA_ON$$RW$$Base 0x002090a8 Number 0 anon$$obj.o ABSOLUTE
+ hids_attr_tbl_size 0x002090d8 Data 2 hids_rmc.o(.data)
+ gatt_dfu_service_table 0x002090e0 Data 168 dfu_service.o(.data)
+ app_pre_main_cb 0x00209188 Data 4 main.o(.data)
+ privacy_modify_resolv_list_idx 0x0020919a Data 1 privacy_mgnt.o(.data)
+ privacy_mode_manage 0x0020919b Data 1 privacy_mgnt.o(.data)
+ g_flash_old_bp_lv 0x00209209 Data 1 dfu_flash.o(.data)
+ Ir_Override_Table_Index_G10 0x00209218 Data 24 key_handle.o(.data)
+ Ir_Override_Table_Index_G20 0x00209230 Data 48 key_handle.o(.data)
+ pREMOTE_G20 0x0020927c Data 4 app_custom.o(.data)
+ SOC_Version 0x00209280 Data 1 adc_lib.o(.data)
+ ADC_K_Version 0x00209281 Data 1 adc_lib.o(.data)
+ SOC_Version_Table 0x00209282 Data 48 adc_lib.o(.data)
+ Image$$RAM_DATA_ON$$ZI$$Base 0x00209458 Number 0 anon$$obj.o ABSOLUTE
+ user_wdg_cb 0x00209458 Data 4 system_rtl876x.o(.bss)
+ os_patch 0x00209460 Data 4 system_rtl876x.o(.bss)
+ random_seed_value 0x00209464 Data 4 system_rtl876x.o(.bss)
+ active_timer_handle 0x00209468 Data 4 system_rtl876x.o(.bss)
+ User_IO_EnterDlpsCB 0x0020946c Data 4 rtl876x_io_dlps.o(.bss)
+ User_IO_ExitDlpsCB 0x00209470 Data 4 rtl876x_io_dlps.o(.bss)
+ PeriIntStoreReg 0x00209474 Data 4 rtl876x_io_dlps.o(.bss)
+ PWM2_StoreReg 0x00209478 Data 4 rtl876x_io_dlps.o(.bss)
+ Pinmux_StoreReg 0x0020947c Data 40 rtl876x_io_dlps.o(.bss)
+ GPIO_StoreReg 0x002094a4 Data 40 rtl876x_io_dlps.o(.bss)
+ IR_StoreReg 0x002094cc Data 24 rtl876x_io_dlps.o(.bss)
+ KeyScan_StoreReg 0x002094e4 Data 28 rtl876x_io_dlps.o(.bss)
+ TIM_StoreReg 0x00209500 Data 112 rtl876x_io_dlps.o(.bss)
+ CPU_StoreReg 0x00209570 Data 12 rtl876x_io_dlps.o(.bss)
+ CPU_StoreReg_IP 0x0020957c Data 32 rtl876x_io_dlps.o(.bss)
+ vendor_svc_handshake_values 0x00209638 Data 16 vendor_service.o(.bss)
+ atvv_global_data 0x00209650 Data 70 atvv_service.o(.bss)
+ temp_image_num 0x0020969c Data 1 dfu_service.o(.bss)
+ g_ota_tmp_buf_used_size 0x002096a0 Data 2 dfu_service.o(.bss)
+ pfn_dfu_service_cb 0x002096a8 Data 4 dfu_service.o(.bss)
+ p_ota_temp_buffer_head 0x002096ac Data 4 dfu_service.o(.bss)
+ g_dfu_para 0x002096b0 Data 32 dfu_service.o(.bss)
+ temp_image_info 0x002096d0 Data 120 dfu_service.o(.bss)
+ ota_temp_buffer_head 0x00209748 Data 2048 dfu_service.o(.bss)
+ protocol_type 0x00209f48 Data 2 ota_service.o(.bss)
+ pfn_ota_service_cb 0x00209f4c Data 4 ota_service.o(.bss)
+ patch_version 0x00209f50 Data 4 ota_service.o(.bss)
+ app_version 0x00209f54 Data 4 ota_service.o(.bss)
+ mac_addr 0x00209f58 Data 6 ota_service.o(.bss)
+ ota_active_bank_info 0x00209f60 Data 8 ota_service.o(.bss)
+ app_privacy_state 0x00209fa8 Data 1 rcu_application.o(.bss)
+ app_privacy_resolution_state 0x00209fa9 Data 1 rcu_application.o(.bss)
+ app_global_data 0x00209fac Data 176 rcu_application.o(.bss)
+ adv_change_data_timer 0x0020a0bc Data 4 swtimer.o(.bss)
+ adv_timer 0x0020a0c0 Data 4 swtimer.o(.bss)
+ temp_off_latency_timer 0x0020a0c4 Data 4 swtimer.o(.bss)
+ update_conn_params_timer 0x0020a0c8 Data 4 swtimer.o(.bss)
+ next_state_check_timer 0x0020a0cc Data 4 swtimer.o(.bss)
+ aon_watch_dog_wake_up_dlps_timer 0x0020a0d0 Data 4 swtimer.o(.bss)
+ system_rest_timer 0x0020a0d4 Data 4 swtimer.o(.bss)
+ back_key_pressed_when_HW_reset_timer 0x0020a0d8 Data 4 swtimer.o(.bss)
+ app_task_handle 0x0020a0dc Data 4 app_task.o(.bss)
+ evt_queue_handle 0x0020a0e0 Data 4 app_task.o(.bss)
+ io_queue_handle 0x0020a0e4 Data 4 app_task.o(.bss)
+ dtm_task_handle 0x0020a0e8 Data 4 app_task.o(.bss)
+ privacy_clear_pending 0x0020a0ec Data 1 privacy_mgnt.o(.bss)
+ privacy_modify_resolv_list_pending 0x0020a0ed Data 1 privacy_mgnt.o(.bss)
+ privacy_state 0x0020a0ee Data 1 privacy_mgnt.o(.bss)
+ privacy_resolution_status 0x0020a0ef Data 1 privacy_mgnt.o(.bss)
+ privacy_whitelist 0x0020a0f0 Data 1 privacy_mgnt.o(.bss)
+ privacy_table 0x0020a0f8 Data 4 privacy_mgnt.o(.bss)
+ scenario_name 0x0020a0fc Data 8 overlay_mgr.o(.bss)
+ keyscan_global_data 0x0020a128 Data 44 keyscan_driver.o(.bss)
+ combine_keys_detection_timer 0x0020a158 Data 4 key_handle.o(.bss)
+ notify_key_data_after_reconn_timer 0x0020a15c Data 4 key_handle.o(.bss)
+ long_press_key_detect_timer 0x0020a160 Data 4 key_handle.o(.bss)
+ key_handle_global_data 0x0020a17c Data 512 key_handle.o(.bss)
+ voice_driver_global_data 0x0020a3a4 Data 1028 voice_driver.o(.bss)
+ voice_driver_codec_params 0x0020a7a8 Data 60 voice_driver.o(.bss)
+ voice_global_data 0x0020a7ec Data 8 voice.o(.bss)
+ ir_svc_handle_global_data 0x0020b848 Data 24 ir_service_handle.o(.bss)
+ buzzer_local_data 0x0020b88c Data 12 buzzer_driver.o(.bss)
+ gap_app_cb 0x0020b8a8 Data 4 gap_lib_system_call.o(.bss)
+ gap_common_app_cb 0x0020b8ac Data 4 gap_lib_system_call.o(.bss)
+ ADC_Resistance_Value 0x0020b8b0 Data 2 adc_lib.o(.bss)
+ EFUSE_ADC_Read_Value 0x0020b8b2 Data 33 adc_lib.o(.bss)
+ ADC_Divide_Single_Value 0x0020b8d4 Data 12 adc_lib.o(.bss)
+ ADC_Bypass_Single_Value 0x0020b8e0 Data 12 adc_lib.o(.bss)
+ ADC_Divide_Diff_Value 0x0020b8ec Data 12 adc_lib.o(.bss)
+ ADC_Bypass_Diff_Value 0x0020b8f8 Data 12 adc_lib.o(.bss)
+ ima_adpcm_global_state 0x0020b904 Data 6 ima_adpcm_enc.o(.bss)
+ _random_number_data 0x0020b90c Data 228 rand.o(.bss)
+ AppUpdateVectorTable 0x0020ba05 * Thumb Code 168 system_rtl876x.o(.app.overlay_a)
+ Image$$OVERLAY_A$$RO$$Base 0x0020ba04 Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_B$$RO$$Base 0x0020ba04 Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_B$$RW$$Base 0x0020ba04 Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_B$$ZI$$Base 0x0020ba04 Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_C$$RO$$Base 0x0020ba04 Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_C$$RW$$Base 0x0020ba04 Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_C$$ZI$$Base 0x0020ba04 Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_A$$RW$$Base 0x0020bacc Number 0 anon$$obj.o ABSOLUTE
+ Image$$OVERLAY_A$$ZI$$Base 0x0020bacc Number 0 anon$$obj.o ABSOLUTE
+ Image$$CACHE_DATA_ON$$RO$$Base 0x00216000 Number 0 anon$$obj.o ABSOLUTE
+ Image$$CACHE_DATA_ON$$RW$$Base 0x00216000 Number 0 anon$$obj.o ABSOLUTE
+ Image$$CACHE_DATA_ON$$ZI$$Base 0x00216000 Number 0 anon$$obj.o ABSOLUTE
+ img_header 0x00832000 Data 480 system_rtl876x.o(.app.flash.header)
+ auth_header 0x008321e0 Data 544 system_rtl876x.o(.app.flash.header)
+ Image$$FLASH_START_ADDR$$RO$$Base 0x00832400 Number 0 anon$$obj.o ABSOLUTE
+ Load$$FLASH_START_ADDR$$RO$$Base 0x00832400 Number 0 anon$$obj.o ABSOLUTE
+ Reset_Handler 0x00832401 Thumb Code 4 startup_rtl876x.o(RESET)
+ __main 0x00832409 Thumb Code 8 __main.o(!!!main)
+ _printf_percent 0x00832411 Thumb Code 0 _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000)
+ _printf_n 0x00832413 Thumb Code 0 _printf_n.o(.ARM.Collect$$_printf_percent$$00000001)
+ _printf_p 0x0083241d Thumb Code 0 _printf_p.o(.ARM.Collect$$_printf_percent$$00000002)
+ _printf_f 0x00832427 Thumb Code 0 _printf_f.o(.ARM.Collect$$_printf_percent$$00000003)
+ _printf_e 0x00832431 Thumb Code 0 _printf_e.o(.ARM.Collect$$_printf_percent$$00000004)
+ _printf_g 0x0083243b Thumb Code 0 _printf_g.o(.ARM.Collect$$_printf_percent$$00000005)
+ _printf_a 0x00832445 Thumb Code 0 _printf_a.o(.ARM.Collect$$_printf_percent$$00000006)
+ _printf_ll 0x0083244f Thumb Code 0 _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007)
+ _printf_i 0x00832459 Thumb Code 0 _printf_i.o(.ARM.Collect$$_printf_percent$$00000008)
+ _printf_d 0x00832463 Thumb Code 0 _printf_d.o(.ARM.Collect$$_printf_percent$$00000009)
+ _printf_u 0x0083246d Thumb Code 0 _printf_u.o(.ARM.Collect$$_printf_percent$$0000000A)
+ _printf_o 0x00832477 Thumb Code 0 _printf_o.o(.ARM.Collect$$_printf_percent$$0000000B)
+ _printf_x 0x00832481 Thumb Code 0 _printf_x.o(.ARM.Collect$$_printf_percent$$0000000C)
+ _printf_lli 0x0083248b Thumb Code 0 _printf_lli.o(.ARM.Collect$$_printf_percent$$0000000D)
+ _printf_lld 0x00832495 Thumb Code 0 _printf_lld.o(.ARM.Collect$$_printf_percent$$0000000E)
+ _printf_llu 0x0083249f Thumb Code 0 _printf_llu.o(.ARM.Collect$$_printf_percent$$0000000F)
+ _printf_llo 0x008324a9 Thumb Code 0 _printf_llo.o(.ARM.Collect$$_printf_percent$$00000010)
+ _printf_llx 0x008324b3 Thumb Code 0 _printf_llx.o(.ARM.Collect$$_printf_percent$$00000011)
+ _printf_l 0x008324bd Thumb Code 0 _printf_l.o(.ARM.Collect$$_printf_percent$$00000012)
+ _printf_c 0x008324c7 Thumb Code 0 _printf_c.o(.ARM.Collect$$_printf_percent$$00000013)
+ _printf_s 0x008324d1 Thumb Code 0 _printf_s.o(.ARM.Collect$$_printf_percent$$00000014)
+ _printf_lc 0x008324db Thumb Code 0 _printf_lc.o(.ARM.Collect$$_printf_percent$$00000015)
+ _printf_ls 0x008324e5 Thumb Code 0 _printf_ls.o(.ARM.Collect$$_printf_percent$$00000016)
+ _printf_percent_end 0x008324ef Thumb Code 0 _printf_percent_end.o(.ARM.Collect$$_printf_percent$$00000017)
+ __rt_lib_init 0x008324f3 Thumb Code 0 libinit.o(.ARM.Collect$$libinit$$00000000)
+ __rt_lib_init_fp_1 0x008324f5 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000002)
+ __rt_lib_init_heap_1 0x008324f5 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000000A)
+ __rt_lib_init_preinit_1 0x008324f5 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000004)
+ __rt_lib_init_rand_2 0x008324f5 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000000D)
+ __rt_lib_init_user_alloc_1 0x008324f5 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000000C)
+ __rt_lib_init_lc_common 0x008324f9 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000000F)
+ __rt_lib_init_rand_1 0x008324f9 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000000E)
+ __rt_lib_init_lc_collate_1 0x008324ff Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000011)
+ __rt_lib_init_lc_ctype_2 0x008324ff Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000012)
+ __rt_lib_init_lc_ctype_1 0x0083250b Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000013)
+ __rt_lib_init_lc_monetary_1 0x0083250b Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000015)
+ __rt_lib_init_lc_numeric_2 0x0083250b Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000016)
+ __rt_lib_init_alloca_1 0x00832515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000002E)
+ __rt_lib_init_argv_1 0x00832515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000002C)
+ __rt_lib_init_atexit_1 0x00832515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000001B)
+ __rt_lib_init_clock_1 0x00832515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000021)
+ __rt_lib_init_cpp_1 0x00832515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000032)
+ __rt_lib_init_exceptions_1 0x00832515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000030)
+ __rt_lib_init_fp_trap_1 0x00832515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000001F)
+ __rt_lib_init_getenv_1 0x00832515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000023)
+ __rt_lib_init_lc_numeric_1 0x00832515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000017)
+ __rt_lib_init_lc_time_1 0x00832515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000019)
+ __rt_lib_init_return 0x00832515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000033)
+ __rt_lib_init_signal_1 0x00832515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000001D)
+ __rt_lib_init_stdio_1 0x00832515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000025)
+ __rt_entry 0x00832517 Thumb Code 0 __rtentry.o(.ARM.Collect$$rtentry$$00000000)
+ __rt_entry_presh_1 0x00832517 Thumb Code 0 __rtentry2.o(.ARM.Collect$$rtentry$$00000002)
+ __rt_entry_sh 0x00832517 Thumb Code 0 __rtentry5.o(.ARM.Collect$$rtentry$$00000005)
+ __rt_entry_li 0x0083251b Thumb Code 0 __rtentry2.o(.ARM.Collect$$rtentry$$0000000A)
+ __rt_entry_postsh_1 0x0083251b Thumb Code 0 __rtentry2.o(.ARM.Collect$$rtentry$$00000009)
+ __rt_entry_main 0x0083251f Thumb Code 0 __rtentry2.o(.ARM.Collect$$rtentry$$0000000D)
+ __rt_entry_postli_1 0x0083251f Thumb Code 0 __rtentry2.o(.ARM.Collect$$rtentry$$0000000C)
+ ram_init 0x0083252d Thumb Code 32 system_rtl876x.o(.app.flash.text)
+ ram_cache_init 0x0083254d Thumb Code 32 system_rtl876x.o(.app.flash.text)
+ get_image_entry_addr 0x0083256d Thumb Code 78 system_rtl876x.o(.app.flash.text)
+ set_os_clock 0x008325bb Thumb Code 40 system_rtl876x.o(.app.flash.text)
+ wdg_system_reset_app_cb 0x008325e3 Thumb Code 12 system_rtl876x.o(.app.flash.text)
+ print_reset_reason 0x008325ef Thumb Code 256 system_rtl876x.o(.app.flash.text)
+ pre_main 0x008326ef Thumb Code 82 system_rtl876x.o(.app.flash.text)
+ SystemInit 0x00832741 Thumb Code 220 system_rtl876x.o(.app.flash.text)
+ ADC_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ BTMAC_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ BusFault_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ CAP_Touch_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ Default_Handler 0x00832905 Thumb Code 14 startup_rtl876x.o(.text)
+ Enhanced_Timer0_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ Enhanced_Timer1_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GDMA0_Channel2_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GDMA0_Channel3_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO0_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO10_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO11_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO12_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO13_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO14_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO15_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO16_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO17_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO18_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO19_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO1_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO20_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO21_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO22_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO23_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO24_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO25_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO26_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO27_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO28_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO29_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO2_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO30_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO31_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO3_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO4_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO5_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO6_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO7_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO8_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ GPIO9_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ HardFault_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ I2C0_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ I2C1_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ I2S0_RX_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ I2S0_TX_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ IR_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ LPCOMP_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ MemManage_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ NMI_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ PTA_Mailbox_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ PendSV_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ Peripheral_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ Qdecode_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ SPI0_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ SPI1_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ SPI2W_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ SPI_Flash_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ SVC_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ SysTick_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ TRNG_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ Timer2_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ Timer3_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ Timer4_5_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ Timer4_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ UART1_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ UsageFault_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ WDG_Handler 0x00832905 Thumb Code 0 startup_rtl876x.o(.text)
+ __user_setup_stackheap 0x00832913 Thumb Code 2 startup_rtl876x.o(.text)
+ random_seed_init 0x00832959 Thumb Code 16 system_rtl876x.o(.text)
+ show_sdk_lib_version 0x00832969 Thumb Code 2 system_rtl876x.o(.text)
+ common_main 0x0083296b Thumb Code 88 system_rtl876x.o(.text)
+ malloc 0x008329c3 Thumb Code 16 system_rtl876x.o(.text)
+ calloc 0x008329d3 Thumb Code 20 system_rtl876x.o(.text)
+ realloc 0x008329e7 Thumb Code 136 system_rtl876x.o(.text)
+ free 0x00832a6f Thumb Code 8 system_rtl876x.o(.text)
+ get_cpu_clock 0x00832a77 Thumb Code 6 system_rtl876x.o(.text)
+ get_ic_type 0x00832a7d Thumb Code 6 system_rtl876x.o(.text)
+ set_active_timer_callback 0x00832a83 Thumb Code 24 system_rtl876x.o(.text)
+ set_boot_active_time 0x00832a9b Thumb Code 44 system_rtl876x.o(.text)
+ GPIO_DeInit 0x00832b35 Thumb Code 16 rtl876x_gpio.o(.text)
+ GPIO_Init 0x00832b45 Thumb Code 184 rtl876x_gpio.o(.text)
+ GPIO_StructInit 0x00832bfd Thumb Code 26 rtl876x_gpio.o(.text)
+ GPIO_INTConfig 0x00832c17 Thumb Code 18 rtl876x_gpio.o(.text)
+ GPIO_ClearINTPendingBit 0x00832c29 Thumb Code 8 rtl876x_gpio.o(.text)
+ GPIO_MaskINTConfig 0x00832c31 Thumb Code 18 rtl876x_gpio.o(.text)
+ GPIO_GetPin 0x00832c43 Thumb Code 54 rtl876x_gpio.o(.text)
+ GPIO_GetNum 0x00832c79 Thumb Code 42 rtl876x_gpio.o(.text)
+ GPIO_DBClkCmd 0x00832ca3 Thumb Code 20 rtl876x_gpio.o(.text)
+ IR_DeInit 0x00832cc9 Thumb Code 14 rtl876x_ir.o(.text)
+ IR_Init 0x00832cd7 Thumb Code 214 rtl876x_ir.o(.text)
+ IR_StructInit 0x00832dad Thumb Code 56 rtl876x_ir.o(.text)
+ IR_Cmd 0x00832de5 Thumb Code 50 rtl876x_ir.o(.text)
+ IR_MaskINTConfig 0x00832e17 Thumb Code 94 rtl876x_ir.o(.text)
+ IR_INTConfig 0x00832e75 Thumb Code 76 rtl876x_ir.o(.text)
+ IR_StartManualRxTrigger 0x00832ec1 Thumb Code 14 rtl876x_ir.o(.text)
+ IR_SetRxCounterThreshold 0x00832ecf Thumb Code 8 rtl876x_ir.o(.text)
+ IR_SendBuf 0x00832ed7 Thumb Code 34 rtl876x_ir.o(.text)
+ IR_SendCompenBuf 0x00832ef9 Thumb Code 60 rtl876x_ir.o(.text)
+ IR_ReceiveBuf 0x00832f35 Thumb Code 14 rtl876x_ir.o(.text)
+ IR_GetINTStatus 0x00832f43 Thumb Code 54 rtl876x_ir.o(.text)
+ IR_ClearINTPendingBit 0x00832f79 Thumb Code 40 rtl876x_ir.o(.text)
+ KeyScan_Init 0x00832fc1 Thumb Code 164 rtl876x_keyscan.o(.text)
+ KeyScan_DeInit 0x00833065 Thumb Code 14 rtl876x_keyscan.o(.text)
+ KeyScan_StructInit 0x00833073 Thumb Code 62 rtl876x_keyscan.o(.text)
+ KeyScan_INTConfig 0x008330b1 Thumb Code 16 rtl876x_keyscan.o(.text)
+ KeyScan_INTMask 0x008330c1 Thumb Code 16 rtl876x_keyscan.o(.text)
+ KeyScan_Read 0x008330d1 Thumb Code 22 rtl876x_keyscan.o(.text)
+ KeyScan_Cmd 0x008330e7 Thumb Code 44 rtl876x_keyscan.o(.text)
+ KeyScan_FilterDataConfig 0x00833113 Thumb Code 60 rtl876x_keyscan.o(.text)
+ RTC_WriteReg 0x00833161 Thumb Code 38 rtl876x_rtc.o(.text)
+ RTC_DeInit 0x00833187 Thumb Code 186 rtl876x_rtc.o(.text)
+ RTC_SetPrescaler 0x00833241 Thumb Code 10 rtl876x_rtc.o(.text)
+ RTC_Cmd 0x0083324b Thumb Code 24 rtl876x_rtc.o(.text)
+ RTC_INTConfig 0x00833263 Thumb Code 20 rtl876x_rtc.o(.text)
+ RTC_WKConfig 0x00833277 Thumb Code 20 rtl876x_rtc.o(.text)
+ RTC_NvCmd 0x0083328b Thumb Code 18 rtl876x_rtc.o(.text)
+ RTC_SystemWakeupConfig 0x0083329d Thumb Code 20 rtl876x_rtc.o(.text)
+ RTC_ResetCounter 0x008332b1 Thumb Code 32 rtl876x_rtc.o(.text)
+ RTC_ResetPrescalerCounter 0x008332d1 Thumb Code 32 rtl876x_rtc.o(.text)
+ RTC_GetINTStatus 0x008332f1 Thumb Code 18 rtl876x_rtc.o(.text)
+ RTC_ClearINTPendingBit 0x00833303 Thumb Code 28 rtl876x_rtc.o(.text)
+ RTC_GetWakeupStatus 0x0083331f Thumb Code 18 rtl876x_rtc.o(.text)
+ RTC_ClearWakeupStatusBit 0x00833331 Thumb Code 28 rtl876x_rtc.o(.text)
+ RTC_ClearCompINT 0x0083334d Thumb Code 32 rtl876x_rtc.o(.text)
+ RTC_ClearOverFlowINT 0x0083336d Thumb Code 28 rtl876x_rtc.o(.text)
+ RTC_ClearTickINT 0x00833389 Thumb Code 28 rtl876x_rtc.o(.text)
+ CODEC_AnalogCircuitInit 0x008333bd Thumb Code 24 rtl876x_codec.o(.text)
+ CODEC_AnalogCircuitDeInit 0x008333d5 Thumb Code 24 rtl876x_codec.o(.text)
+ CODEC_DeInit 0x008333ed Thumb Code 156 rtl876x_codec.o(.text)
+ CODEC_Init 0x00833489 Thumb Code 518 rtl876x_codec.o(.text)
+ CODEC_StructInit 0x0083368f Thumb Code 50 rtl876x_codec.o(.text)
+ CODEC_MICBIASCmd 0x008336c1 Thumb Code 44 rtl876x_codec.o(.text)
+ I2S_Init 0x00833701 Thumb Code 106 rtl876x_i2s.o(.text)
+ I2S_DeInit 0x0083376b Thumb Code 22 rtl876x_i2s.o(.text)
+ I2S_StructInit 0x00833781 Thumb Code 48 rtl876x_i2s.o(.text)
+ I2S_Cmd 0x008337b1 Thumb Code 66 rtl876x_i2s.o(.text)
+ I2S_INTConfig 0x008337f3 Thumb Code 16 rtl876x_i2s.o(.text)
+ I2S_GetINTStatus 0x00833803 Thumb Code 16 rtl876x_i2s.o(.text)
+ I2S_ClearINTPendingBit 0x00833813 Thumb Code 14 rtl876x_i2s.o(.text)
+ Pinmux_Reset 0x00833831 Thumb Code 22 rtl876x_pinmux.o(.text)
+ Pinmux_Deinit 0x00833847 Thumb Code 24 rtl876x_pinmux.o(.text)
+ Pinmux_Config 0x0083385f Thumb Code 30 rtl876x_pinmux.o(.text)
+ Pad_Config 0x0083387d Thumb Code 96 rtl876x_pinmux.o(.text)
+ Pad_WakeupEnableValue 0x008338dd Thumb Code 38 rtl876x_pinmux.o(.text)
+ Pad_WKDebounceConfig 0x00833903 Thumb Code 40 rtl876x_pinmux.o(.text)
+ Pad_WakeupPolarityValue 0x0083392b Thumb Code 38 rtl876x_pinmux.o(.text)
+ System_WakeUpPinEnable 0x00833951 Thumb Code 28 rtl876x_pinmux.o(.text)
+ System_WakeUpPinDisable 0x0083396d Thumb Code 4 rtl876x_pinmux.o(.text)
+ System_WakeUpDebounceTime 0x00833971 Thumb Code 36 rtl876x_pinmux.o(.text)
+ Pad_DebounceWakeupStatus 0x00833995 Thumb Code 32 rtl876x_pinmux.o(.text)
+ System_DebounceWakeupStatus 0x008339b5 Thumb Code 2 rtl876x_pinmux.o(.text)
+ Pad_WakeupInterruptValue 0x008339b7 Thumb Code 40 rtl876x_pinmux.o(.text)
+ System_WakeUpInterruptValue 0x008339df Thumb Code 2 rtl876x_pinmux.o(.text)
+ Pad_OutputControlValue 0x008339e1 Thumb Code 38 rtl876x_pinmux.o(.text)
+ Pad_OutputEnableValue 0x00833a07 Thumb Code 38 rtl876x_pinmux.o(.text)
+ Pad_PullEnableValue 0x00833a2d Thumb Code 38 rtl876x_pinmux.o(.text)
+ Pad_PullUpOrDownValue 0x00833a53 Thumb Code 38 rtl876x_pinmux.o(.text)
+ Pad_PullConfigValue 0x00833a79 Thumb Code 38 rtl876x_pinmux.o(.text)
+ Pad_PowerOrShutDownValue 0x00833a9f Thumb Code 40 rtl876x_pinmux.o(.text)
+ Pad_ControlSelectValue 0x00833ac7 Thumb Code 40 rtl876x_pinmux.o(.text)
+ Pad_ClearWakeupINTPendingBit 0x00833aef Thumb Code 40 rtl876x_pinmux.o(.text)
+ Pad_ClearAllWakeupINT 0x00833b17 Thumb Code 68 rtl876x_pinmux.o(.text)
+ Spic0_control 0x00833b5b Thumb Code 22 rtl876x_pinmux.o(.text)
+ Spic1_control 0x00833b71 Thumb Code 20 rtl876x_pinmux.o(.text)
+ NVIC_Init 0x00833b99 Thumb Code 180 rtl876x_nvic.o(.text)
+ RCC_PeriphClockCmd 0x00833c61 Thumb Code 252 rtl876x_rcc.o(.text)
+ RCC_PeriFunctionConfig 0x00833d5d Thumb Code 84 rtl876x_rcc.o(.text)
+ RCC_PeriClockConfig 0x00833db1 Thumb Code 100 rtl876x_rcc.o(.text)
+ RCC_I2CClkDivConfig 0x00833e15 Thumb Code 88 rtl876x_rcc.o(.text)
+ RCC_SPIClkDivConfig 0x00833e6d Thumb Code 78 rtl876x_rcc.o(.text)
+ RCC_TIMClkDivConfig 0x00833ebb Thumb Code 46 rtl876x_rcc.o(.text)
+ RCC_UARTClkDivConfig 0x00833ee9 Thumb Code 88 rtl876x_rcc.o(.text)
+ TIM_DeInit 0x00833f71 Thumb Code 16 rtl876x_tim.o(.text)
+ TIM_TimeBaseInit 0x00833f81 Thumb Code 218 rtl876x_tim.o(.text)
+ TIM_StructInit 0x0083405b Thumb Code 26 rtl876x_tim.o(.text)
+ TIM_Cmd 0x00834075 Thumb Code 20 rtl876x_tim.o(.text)
+ TIM_ChangePeriod 0x00834089 Thumb Code 4 rtl876x_tim.o(.text)
+ TIM_INTConfig 0x0083408d Thumb Code 18 rtl876x_tim.o(.text)
+ TIM_PWMChangeFreqAndDuty 0x0083409f Thumb Code 30 rtl876x_tim.o(.text)
+ TIM_PWMComplOutputEMCmd 0x008340bd Thumb Code 20 rtl876x_tim.o(.text)
+ TIM_PWMDZBypassCmd 0x008340d1 Thumb Code 20 rtl876x_tim.o(.text)
+ TIM_PWMChangeDZClockSrc 0x008340e5 Thumb Code 20 rtl876x_tim.o(.text)
+ GDMA_DeInit 0x0083410d Thumb Code 16 rtl876x_gdma.o(.text)
+ GDMA_Init 0x0083411d Thumb Code 422 rtl876x_gdma.o(.text)
+ GDMA_StructInit 0x008342c3 Thumb Code 48 rtl876x_gdma.o(.text)
+ GDMA_Cmd 0x008342f3 Thumb Code 146 rtl876x_gdma.o(.text)
+ GDMA_INTConfig 0x00834385 Thumb Code 108 rtl876x_gdma.o(.text)
+ GDMA_ClearINTPendingBit 0x008343f1 Thumb Code 42 rtl876x_gdma.o(.text)
+ UART_DeInit 0x00834441 Thumb Code 34 rtl876x_uart.o(.text)
+ UART_Init 0x00834463 Thumb Code 198 rtl876x_uart.o(.text)
+ UART_StructInit 0x00834529 Thumb Code 46 rtl876x_uart.o(.text)
+ UART_MaskINTConfig 0x00834557 Thumb Code 16 rtl876x_uart.o(.text)
+ UART_INTConfig 0x00834567 Thumb Code 92 rtl876x_uart.o(.text)
+ UART_SendData 0x008345c3 Thumb Code 20 rtl876x_uart.o(.text)
+ UART_ReceiveData 0x008345d7 Thumb Code 20 rtl876x_uart.o(.text)
+ UART_SetBaudRate 0x008345eb Thumb Code 58 rtl876x_uart.o(.text)
+ UART_SetParams 0x00834625 Thumb Code 8 rtl876x_uart.o(.text)
+ UART_LoopBackCmd 0x0083462d Thumb Code 18 rtl876x_uart.o(.text)
+ UART_GetFlagStatus 0x0083463f Thumb Code 56 rtl876x_uart.o(.text)
+ ADC_DeInit 0x00834695 Thumb Code 16 rtl876x_adc.o(.text)
+ ADC_Init 0x008346a5 Thumb Code 276 rtl876x_adc.o(.text)
+ ADC_StructInit 0x008347b9 Thumb Code 82 rtl876x_adc.o(.text)
+ ADC_Cmd 0x0083480b Thumb Code 144 rtl876x_adc.o(.text)
+ ADC_INTConfig 0x0083489b Thumb Code 16 rtl876x_adc.o(.text)
+ ADC_ReadRawData 0x008348ab Thumb Code 22 rtl876x_adc.o(.text)
+ ADC_ReadAvgRawData 0x008348c1 Thumb Code 6 rtl876x_adc.o(.text)
+ ADC_ReadFIFO 0x008348c7 Thumb Code 8 rtl876x_adc.o(.text)
+ ADC_ReadFIFOData 0x008348cf Thumb Code 20 rtl876x_adc.o(.text)
+ ADC_GetFIFODataLen 0x008348e3 Thumb Code 8 rtl876x_adc.o(.text)
+ ADC_SchIndexConfig 0x008348eb Thumb Code 22 rtl876x_adc.o(.text)
+ ADC_SchTableConfig 0x00834901 Thumb Code 22 rtl876x_adc.o(.text)
+ ADC_BitMapConfig 0x00834917 Thumb Code 16 rtl876x_adc.o(.text)
+ ADC_ManualPowerOnCmd 0x00834927 Thumb Code 20 rtl876x_adc.o(.text)
+ ADC_WriteFIFOCmd 0x0083493b Thumb Code 20 rtl876x_adc.o(.text)
+ ADC_BypassCmd 0x0083494f Thumb Code 46 rtl876x_adc.o(.text)
+ ADC_GetINTStatus 0x0083497d Thumb Code 16 rtl876x_adc.o(.text)
+ ADC_ClearINTPendingBit 0x0083498d Thumb Code 10 rtl876x_adc.o(.text)
+ LPC_WriteReg 0x008349a1 Thumb Code 38 rtl876x_lpc.o(.text)
+ LPC_DeInit 0x008349c7 Thumb Code 126 rtl876x_lpc.o(.text)
+ LPC_Init 0x00834a45 Thumb Code 92 rtl876x_lpc.o(.text)
+ LPC_StructInit 0x00834aa1 Thumb Code 12 rtl876x_lpc.o(.text)
+ LPC_Cmd 0x00834aad Thumb Code 38 rtl876x_lpc.o(.text)
+ LPC_CounterCmd 0x00834ad3 Thumb Code 22 rtl876x_lpc.o(.text)
+ LPC_INTConfig 0x00834ae9 Thumb Code 20 rtl876x_lpc.o(.text)
+ LPC_INTCmd 0x00834afd Thumb Code 18 rtl876x_lpc.o(.text)
+ LPC_WKCmd 0x00834b0f Thumb Code 18 rtl876x_lpc.o(.text)
+ LPC_SetCompValue 0x00834b21 Thumb Code 10 rtl876x_lpc.o(.text)
+ LPC_ResetCounter 0x00834b2b Thumb Code 34 rtl876x_lpc.o(.text)
+ LPC_GetFlagStatus 0x00834b4d Thumb Code 36 rtl876x_lpc.o(.text)
+ LPC_ClearFlag 0x00834b71 Thumb Code 38 rtl876x_lpc.o(.text)
+ LPC_GetINTStatus 0x00834b97 Thumb Code 22 rtl876x_lpc.o(.text)
+ LPC_ClearINTPendingBit 0x00834bad Thumb Code 38 rtl876x_lpc.o(.text)
+ AON_WDG_Config 0x00834c13 Thumb Code 92 rtl876x_aon_wdg.o(.text)
+ AON_WDG_ConfigResetLevel 0x00834c6f Thumb Code 62 rtl876x_aon_wdg.o(.text)
+ AON_WDG_ConfigComp 0x00834cad Thumb Code 62 rtl876x_aon_wdg.o(.text)
+ AON_WDG_ConfigCntCtl 0x00834ceb Thumb Code 62 rtl876x_aon_wdg.o(.text)
+ AON_WDG_ConfigCntReload 0x00834d29 Thumb Code 62 rtl876x_aon_wdg.o(.text)
+ AON_WDG_Enable 0x00834d67 Thumb Code 58 rtl876x_aon_wdg.o(.text)
+ AON_WDG_Disable 0x00834da1 Thumb Code 58 rtl876x_aon_wdg.o(.text)
+ AON_WDG_Restart 0x00834ddb Thumb Code 24 rtl876x_aon_wdg.o(.text)
+ AON_WDG_SystemReset 0x00834df3 Thumb Code 18 rtl876x_aon_wdg.o(.text)
+ dis_set_parameter 0x00834e15 Thumb Code 204 dis.o(.text)
+ dis_attr_read_cb 0x00834ee1 Thumb Code 322 dis.o(.text)
+ dis_add_service 0x00835023 Thumb Code 66 dis.o(.text)
+ bas_set_parameter 0x00835081 Thumb Code 42 bas.o(.text)
+ bas_battery_level_value_notify 0x008350ab Thumb Code 24 bas.o(.text)
+ bas_battery_level_value_read_confirm 0x008350c3 Thumb Code 36 bas.o(.text)
+ bas_attr_read_cb 0x008350e7 Thumb Code 90 bas.o(.text)
+ bas_cccd_update_cb 0x00835141 Thumb Code 82 bas.o(.text)
+ bas_add_service 0x00835193 Thumb Code 64 bas.o(.text)
+ hids_set_parameter 0x008351ed Thumb Code 64 hids_rmc.o(.text)
+ hids_attr_read_cb 0x0083522d Thumb Code 200 hids_rmc.o(.text)
+ hids_attr_write_cb 0x008352f5 Thumb Code 156 hids_rmc.o(.text)
+ hids_cccd_update_cb 0x00835391 Thumb Code 92 hids_rmc.o(.text)
+ hids_add_service 0x008353ed Thumb Code 70 hids_rmc.o(.text)
+ vendor_svc_attr_write_cb 0x00835455 Thumb Code 108 vendor_service.o(.text)
+ vendor_svc_cccd_update_cb 0x008354c1 Thumb Code 80 vendor_service.o(.text)
+ vendor_svc_add_service 0x00835511 Thumb Code 64 vendor_service.o(.text)
+ attv_attr_read_cb 0x00835565 Thumb Code 124 atvv_service.o(.text)
+ atvv_write_post_callback 0x008355e1 Thumb Code 68 atvv_service.o(.text)
+ atvv_attr_write_cb 0x00835625 Thumb Code 46 atvv_service.o(.text)
+ atvv_cccd_update_cb 0x00835653 Thumb Code 92 atvv_service.o(.text)
+ atvv_add_service 0x008356af Thumb Code 66 atvv_service.o(.text)
+ ir_svc_attr_write_cb 0x00835711 Thumb Code 98 ir_service.o(.text)
+ ir_svc_cccd_update_cb 0x00835773 Thumb Code 80 ir_service.o(.text)
+ ir_svc_add_service 0x008357c3 Thumb Code 66 ir_service.o(.text)
+ dfu_encrypt_handshake_data 0x00835815 Thumb Code 46 dfu_service.o(.text)
+ dfu_buffer_check_process 0x00835843 Thumb Code 624 dfu_service.o(.text)
+ dfu_notify_conn_para_update_req 0x00835ab3 Thumb Code 72 dfu_service.o(.text)
+ dfu_service_handle_valid_fw 0x00835afb Thumb Code 140 dfu_service.o(.text)
+ dfu_service_handle_active_image 0x00835b87 Thumb Code 76 dfu_service.o(.text)
+ dfu_service_handle_control_point_req 0x00835bd3 Thumb Code 1618 dfu_service.o(.text)
+ dfu_service_handle_packet_req 0x00836225 Thumb Code 454 dfu_service.o(.text)
+ dfu_attr_write_cb 0x008363eb Thumb Code 122 dfu_service.o(.text)
+ dfu_cccd_update_cb 0x00836465 Thumb Code 170 dfu_service.o(.text)
+ dfu_add_service 0x0083650f Thumb Code 64 dfu_service.o(.text)
+ ota_attr_write_cb 0x00836585 Thumb Code 152 ota_service.o(.text)
+ ota_attr_read_cb 0x00836689 Thumb Code 810 ota_service.o(.text)
+ ota_add_service 0x008369b3 Thumb Code 62 ota_service.o(.text)
+ fms_attr_read_cb 0x00836a05 Thumb Code 54 fms.o(.text)
+ fms_attr_write_cb 0x00836a3b Thumb Code 78 fms.o(.text)
+ fms_cccd_update_cb 0x00836a89 Thumb Code 80 fms.o(.text)
+ fms_add_service 0x00836ad9 Thumb Code 64 fms.o(.text)
+ set_dfu_config 0x00836b31 Thumb Code 12 main.o(.text)
+ enter_dtm 0x00836c99 Thumb Code 38 main.o(.text)
+ app_nvic_config 0x00836cbf Thumb Code 40 main.o(.text)
+ main 0x00836ce7 Thumb Code 226 main.o(.text)
+ app_set_latency_status 0x0083707f Thumb Code 194 rcu_application.o(.text)
+ app_load_wakeup_key_cnt 0x0083793b Thumb Code 46 rcu_application.o(.text)
+ app_init_global_data 0x00837969 Thumb Code 130 rcu_application.o(.text)
+ app_gap_callback 0x008379eb Thumb Code 230 rcu_application.o(.text)
+ app_privacy_callback 0x00837ad1 Thumb Code 44 rcu_application.o(.text)
+ app_profile_callback 0x00837afd Thumb Code 276 rcu_application.o(.text)
+ app_save_wakeup_key_cnt 0x00837c11 Thumb Code 40 rcu_application.o(.text)
+ app_change_wakeup_adv_data 0x00837df9 Thumb Code 34 rcu_gap.o(.text)
+ rcu_update_adv_rsp_data 0x00837e1b Thumb Code 96 rcu_gap.o(.text)
+ rcu_le_gap_init 0x00837e7b Thumb Code 414 rcu_gap.o(.text)
+ rcu_start_adv 0x00838019 Thumb Code 1956 rcu_gap.o(.text)
+ rcu_stop_adv 0x008387bd Thumb Code 76 rcu_gap.o(.text)
+ rcu_terminate_connection 0x00838809 Thumb Code 80 rcu_gap.o(.text)
+ rcu_update_conn_params 0x00838859 Thumb Code 94 rcu_gap.o(.text)
+ sw_timer_init 0x008388f5 Thumb Code 328 swtimer.o(.text)
+ app_task_init 0x00838b4d Thumb Code 24 app_task.o(.text)
+ dtm_task_init 0x00838b65 Thumb Code 26 app_task.o(.text)
+ reset_watch_dog_timer_enable 0x00838b9d Thumb Code 84 reset_watch_dog_timer.o(.text)
+ privacy_change_state 0x00838bfd Thumb Code 34 privacy_mgnt.o(.text)
+ privacy_modify_resolving_list 0x00838c1f Thumb Code 344 privacy_mgnt.o(.text)
+ privacy_add_device 0x00838d77 Thumb Code 112 privacy_mgnt.o(.text)
+ privacy_handle_resolv_list_int 0x00838de7 Thumb Code 424 privacy_mgnt.o(.text)
+ privacy_handle_resolv_list 0x00838f8f Thumb Code 46 privacy_mgnt.o(.text)
+ privacy_handle_le_privacy_modify_resolv_list_rsp 0x00838fbd Thumb Code 204 privacy_mgnt.o(.text)
+ privacy_handle_le_privacy_resolution_status_info 0x00839089 Thumb Code 42 privacy_mgnt.o(.text)
+ privacy_msg_callback 0x008390b3 Thumb Code 184 privacy_mgnt.o(.text)
+ privacy_init 0x0083916b Thumb Code 86 privacy_mgnt.o(.text)
+ privacy_handle_bond_modify_msg 0x008391c1 Thumb Code 92 privacy_mgnt.o(.text)
+ privacy_set_addr_resolution 0x0083921d Thumb Code 8 privacy_mgnt.o(.text)
+ privacy_read_peer_resolv_addr 0x00839225 Thumb Code 44 privacy_mgnt.o(.text)
+ privacy_read_local_resolv_addr 0x00839251 Thumb Code 44 privacy_mgnt.o(.text)
+ privacy_manage_mode 0x0083927d Thumb Code 6 privacy_mgnt.o(.text)
+ privacy_set_peer_mode 0x00839283 Thumb Code 56 privacy_mgnt.o(.text)
+ privacy_set_gen_priv_addr_interval 0x008392bb Thumb Code 40 privacy_mgnt.o(.text)
+ load_overlay 0x00839309 Thumb Code 74 overlay_mgr.o(.text)
+ get_current_scenario_index 0x00839353 Thumb Code 40 overlay_mgr.o(.text)
+ loop_queue_init 0x00839385 Thumb Code 104 loop_queue.o(.text)
+ loop_queue_deinit 0x008393ed Thumb Code 38 loop_queue.o(.text)
+ dtm_uart_init 0x00839419 Thumb Code 120 rcu_dtm_app.o(.text)
+ dtm_uart_send_bytes 0x00839491 Thumb Code 54 rcu_dtm_app.o(.text)
+ dtm_test_req 0x008394c7 Thumb Code 340 rcu_dtm_app.o(.text)
+ UART0_Handler 0x0083961b Thumb Code 116 rcu_dtm_app.o(.text)
+ dtm_interrupt 0x0083968f Thumb Code 116 rcu_dtm_app.o(.text)
+ dtm_gap_callback 0x00839703 Thumb Code 174 rcu_dtm_app.o(.text)
+ gpio_dtm_pad_config 0x008397b1 Thumb Code 22 rcu_dtm_app.o(.text)
+ gpio_dtm_pinmux_config 0x008397c7 Thumb Code 12 rcu_dtm_app.o(.text)
+ dtm_gpio_init 0x008397d3 Thumb Code 80 rcu_dtm_app.o(.text)
+ rtc_driver_init 0x0083984d Thumb Code 72 rtc_driver.o(.text)
+ rtc_driver_deinit 0x00839895 Thumb Code 20 rtc_driver.o(.text)
+ rtc_driver_get_us 0x008398a9 Thumb Code 104 rtc_driver.o(.text)
+ rtc_driver_get_ms 0x00839911 Thumb Code 18 rtc_driver.o(.text)
+ rtc_driver_get_seconds 0x00839923 Thumb Code 16 rtc_driver.o(.text)
+ rtc_driver_set_comp_0_params 0x00839933 Thumb Code 78 rtc_driver.o(.text)
+ rtc_driver_clear_comp_0 0x00839981 Thumb Code 20 rtc_driver.o(.text)
+ dfu_set_compressed_ready 0x008399a9 Thumb Code 28 dfu_flash.o(.text)
+ dfu_set_ota_mode_flag 0x00839a79 Thumb Code 60 dfu_flash.o(.text)
+ dfu_switch_to_ota_mode 0x00839ab5 Thumb Code 30 dfu_flash.o(.text)
+ dfu_fw_reboot 0x00839ad3 Thumb Code 38 dfu_flash.o(.text)
+ dfu_hw_aes_decrypt_image 0x00839af9 Thumb Code 48 dfu_flash.o(.text)
+ dfu_report_target_ic_type 0x00839b29 Thumb Code 66 dfu_flash.o(.text)
+ dfu_report_target_fw_info 0x00839b6b Thumb Code 120 dfu_flash.o(.text)
+ dfu_check_buf_crc 0x00839be3 Thumb Code 70 dfu_flash.o(.text)
+ unlock_flash_bp_all 0x00839c29 Thumb Code 50 dfu_flash.o(.text)
+ lock_flash_bp 0x00839c5b Thumb Code 16 dfu_flash.o(.text)
+ dfu_flash_erase_sector_with_retry 0x00839c6b Thumb Code 96 dfu_flash.o(.text)
+ dfu_update 0x00839ccb Thumb Code 506 dfu_flash.o(.text)
+ dfu_set_image_ready 0x00839ec5 Thumb Code 20 dfu_flash.o(.text)
+ dfu_check_checksum 0x00839ed9 Thumb Code 102 dfu_flash.o(.text)
+ keyscan_nvic_config 0x0083a0c5 Thumb Code 24 keyscan_driver.o(.text)
+ keyscan_pinmux_config 0x0083a0dd Thumb Code 64 keyscan_driver.o(.text)
+ keyscan_init_timer 0x0083a11d Thumb Code 38 keyscan_driver.o(.text)
+ key_handle_get_key_type_by_index 0x0083a189 Thumb Code 12 key_handle.o(.text)
+ key_handle_get_hid_usage_id_by_index 0x0083a195 Thumb Code 12 key_handle.o(.text)
+ key_handle_get_hid_usage_page_by_index 0x0083a1a1 Thumb Code 12 key_handle.o(.text)
+ key_handle_reset_key_pressed_cache_fifo 0x0083a309 Thumb Code 40 key_handle.o(.text)
+ key_handle_notify_hid_key_event_by_index 0x0083a387 Thumb Code 154 key_handle.o(.text)
+ key_handle_notify_hid_release_event 0x0083a421 Thumb Code 48 key_handle.o(.text)
+ key_handle_release_event 0x0083a451 Thumb Code 94 key_handle.o(.text)
+ key_handle_process_access_shortcut_event 0x0083a6eb Thumb Code 54 key_handle.o(.text)
+ key_handle_process_bug_report_event 0x0083a721 Thumb Code 34 key_handle.o(.text)
+ key_handle_process_ir_delay_tx_event 0x0083a743 Thumb Code 92 key_handle.o(.text)
+ key_handle_is_key_index_in_fifo 0x0083a79f Thumb Code 54 key_handle.o(.text)
+ key_handle_get_ir_key_code_by_index 0x0083a907 Thumb Code 10 key_handle.o(.text)
+ key_handle_init_data 0x0083a911 Thumb Code 68 key_handle.o(.text)
+ key_handle_set_key_type_prog_by_id 0x0083a955 Thumb Code 32 key_handle.o(.text)
+ key_handle_restore_key_type_id 0x0083a975 Thumb Code 36 key_handle.o(.text)
+ key_handle_init_timer 0x0083a999 Thumb Code 238 key_handle.o(.text)
+ key_handle_notify_hid_key_event_by_fifo 0x0083aa87 Thumb Code 150 key_handle.o(.text)
+ key_handle_pressed_event 0x0083ab1d Thumb Code 326 key_handle.o(.text)
+ key_handle_disconnect_event 0x0083ac63 Thumb Code 8 key_handle.o(.text)
+ key_handle_get_key_pressed_count 0x0083ac6b Thumb Code 8 key_handle.o(.text)
+ voice_driver_init_data 0x0083ae43 Thumb Code 32 voice_driver.o(.text)
+ voice_driver_init_codec_params 0x0083ae63 Thumb Code 76 voice_driver.o(.text)
+ voice_driver_init 0x0083aeaf Thumb Code 80 voice_driver.o(.text)
+ voice_driver_deinit 0x0083aeff Thumb Code 46 voice_driver.o(.text)
+ voice_handle_stop_mic 0x0083b16d Thumb Code 114 voice.o(.text)
+ voice_handle_atvv_audio_stop 0x0083b1df Thumb Code 116 voice.o(.text)
+ voice_handle_atvv_mic_open_error 0x0083b309 Thumb Code 88 voice.o(.text)
+ voice_handle_start_mic 0x0083b361 Thumb Code 96 voice.o(.text)
+ voice_handle_atvv_audio_start 0x0083b3c1 Thumb Code 314 voice.o(.text)
+ voice_handle_mic_key_pressed 0x0083b4fb Thumb Code 214 voice.o(.text)
+ voice_handle_mic_key_released 0x0083b5d1 Thumb Code 98 voice.o(.text)
+ voice_handle_atvv_init_data 0x0083b633 Thumb Code 42 voice.o(.text)
+ voice_handle_atv_dpad_select 0x0083b65d Thumb Code 106 voice.o(.text)
+ voice_handle_messages 0x0083b6c7 Thumb Code 76 voice.o(.text)
+ voice_handle_atvv_srv_cb 0x0083b713 Thumb Code 866 voice.o(.text)
+ ir_send_start_seq_1 0x0083bbbd Thumb Code 120 ir_send_driver.o(.text)
+ ir_send_start_seq_2 0x0083bc35 Thumb Code 140 ir_send_driver.o(.text)
+ ir_send_convert_to_carrier_cycle 0x0083bcc1 Thumb Code 24 ir_send_driver.o(.text)
+ ir_send_is_working 0x0083bcd9 Thumb Code 12 ir_send_driver.o(.text)
+ ir_send_get_current_state 0x0083bce5 Thumb Code 6 ir_send_driver.o(.text)
+ ir_send_module_init 0x0083bceb Thumb Code 112 ir_send_driver.o(.text)
+ ir_send_command_start 0x0083bd5b Thumb Code 64 ir_send_driver.o(.text)
+ ir_send_repeat_code_start 0x0083bd9b Thumb Code 66 ir_send_driver.o(.text)
+ ir_send_exit 0x0083bddd Thumb Code 44 ir_send_driver.o(.text)
+ ir_send_repeat_code_encode 0x0083beb1 Thumb Code 18 ir_send_handle.o(.text)
+ ir_send_raw_encode 0x0083bec3 Thumb Code 670 ir_send_handle.o(.text)
+ ir_send_msg_proc 0x0083c161 Thumb Code 68 ir_send_handle.o(.text)
+ ir_send_key_press_handle 0x0083c1a5 Thumb Code 114 ir_send_handle.o(.text)
+ ir_send_data_one_time_handle 0x0083c217 Thumb Code 116 ir_send_handle.o(.text)
+ ir_send_key_release_handle 0x0083c28b Thumb Code 52 ir_send_handle.o(.text)
+ ir_protocol_nec_command_encode 0x0083c3c5 Thumb Code 78 ir_protocol_nec.o(.text)
+ ir_protocol_nec_repeat_code_encode 0x0083c413 Thumb Code 88 ir_protocol_nec.o(.text)
+ ir_service_handle_get_item_id_from_atv_id 0x0083c4a5 Thumb Code 32 ir_service_handle.o(.text)
+ ir_service_handle_invalid_ftl_table 0x0083c4fd Thumb Code 94 ir_service_handle.o(.text)
+ ir_service_handle_reset_ir_table 0x0083c55b Thumb Code 66 ir_service_handle.o(.text)
+ ir_programming_timeoutcb 0x0083c64b Thumb Code 36 ir_service_handle.o(.text)
+ ir_service_handle_init_data 0x0083c7f3 Thumb Code 124 ir_service_handle.o(.text)
+ ir_service_handle_get_item_id_from_key_id 0x0083c86f Thumb Code 118 ir_service_handle.o(.text)
+ ir_service_handle_srv_cb 0x0083c8e5 Thumb Code 108 ir_service_handle.o(.text)
+ ir_service_handle_disconnect_event 0x0083c951 Thumb Code 38 ir_service_handle.o(.text)
+ ir_service_handle_flash_save_event 0x0083c977 Thumb Code 2 ir_service_handle.o(.text)
+ ir_service_handle_is_key_suppressed 0x0083c979 Thumb Code 62 ir_service_handle.o(.text)
+ ir_service_handle_get_key_code_by_key_id 0x0083c9b7 Thumb Code 108 ir_service_handle.o(.text)
+ ir_service_handle_notify_ir_key_event 0x0083ca23 Thumb Code 86 ir_service_handle.o(.text)
+ get_led_brightness_duty 0x0083cc65 Thumb Code 38 led_driver.o(.text)
+ led_module_init 0x0083cc8b Thumb Code 48 led_driver.o(.text)
+ led_driver_dlps_check 0x0083ccbb Thumb Code 8 led_driver.o(.text)
+ led_blink_start 0x0083ccc3 Thumb Code 90 led_driver.o(.text)
+ led_blink_exit 0x0083cd1d Thumb Code 54 led_driver.o(.text)
+ led_driver_disable_boost_power 0x0083cdad Thumb Code 2 led_pwm_driver.o(.text)
+ led_module_pwm_stop 0x0083cdaf Thumb Code 54 led_pwm_driver.o(.text)
+ led_pwm_init 0x0083cde5 Thumb Code 28 led_pwm_driver.o(.text)
+ led_pwm_driver_dlps_check 0x0083ce01 Thumb Code 16 led_pwm_driver.o(.text)
+ led_driver_enable_boost_power 0x0083ce11 Thumb Code 2 led_pwm_driver.o(.text)
+ led_module_pwm_start 0x0083ce13 Thumb Code 186 led_pwm_driver.o(.text)
+ buzzer_init_data 0x0083ced9 Thumb Code 38 buzzer_driver.o(.text)
+ buzzer_pinmux_config 0x0083ceff Thumb Code 12 buzzer_driver.o(.text)
+ buzzer_init_pad_config 0x0083cf0b Thumb Code 22 buzzer_driver.o(.text)
+ buzzer_deinit_pad_config 0x0083cf21 Thumb Code 22 buzzer_driver.o(.text)
+ buzzer_check_dlps_allowed 0x0083cf37 Thumb Code 6 buzzer_driver.o(.text)
+ buzzer_start_pwm_output 0x0083cf3d Thumb Code 60 buzzer_driver.o(.text)
+ buzzer_stop_pwm_output 0x0083cf79 Thumb Code 44 buzzer_driver.o(.text)
+ buzzer_set_frequency 0x0083cfa5 Thumb Code 6 buzzer_driver.o(.text)
+ buzzer_set_duty_cycle 0x0083cfab Thumb Code 6 buzzer_driver.o(.text)
+ buzzer_get_frequency 0x0083cfb1 Thumb Code 6 buzzer_driver.o(.text)
+ buzzer_get_duty_cycle 0x0083cfb7 Thumb Code 6 buzzer_driver.o(.text)
+ buzzer_is_working_check 0x0083cfbd Thumb Code 6 buzzer_driver.o(.text)
+ fms_handle_notify_status 0x0083d061 Thumb Code 82 fms_service_handle.o(.text)
+ fms_handle_init_data 0x0083d0b3 Thumb Code 30 fms_service_handle.o(.text)
+ fms_handle_srv_cb 0x0083d0d1 Thumb Code 110 fms_service_handle.o(.text)
+ fms_handle_disconnect_event 0x0083d13f Thumb Code 64 fms_service_handle.o(.text)
+ fms_handle_connect_event 0x0083d17f Thumb Code 24 fms_service_handle.o(.text)
+ fms_handle_get_current_mode 0x0083d197 Thumb Code 6 fms_service_handle.o(.text)
+ fms_handle_init_timer 0x0083d19d Thumb Code 56 fms_service_handle.o(.text)
+ bat_update_battery_info 0x0083d3e9 Thumb Code 296 battery_driver.o(.text)
+ bat_init_driver 0x0083d511 Thumb Code 70 battery_driver.o(.text)
+ bat_init_data 0x0083d557 Thumb Code 50 battery_driver.o(.text)
+ bat_get_current_mode 0x0083d589 Thumb Code 6 battery_driver.o(.text)
+ bat_get_current_voltage_value 0x0083d58f Thumb Code 6 battery_driver.o(.text)
+ bat_get_current_voltage_level 0x0083d595 Thumb Code 6 battery_driver.o(.text)
+ bat_nvic_config 0x0083d59b Thumb Code 42 battery_driver.o(.text)
+ bat_msg_handle 0x0083d5c5 Thumb Code 176 battery_driver.o(.text)
+ app_custom_ui_layout 0x0083d7a9 Thumb Code 570 app_custom.o(.text)
+ app_custom_set_new_ir_table 0x0083d9e3 Thumb Code 130 app_custom.o(.text)
+ app_custom_param_init 0x0083da65 Thumb Code 64 app_custom.o(.text)
+ app_custom_wakeup_key_load 0x0083daa5 Thumb Code 104 app_custom.o(.text)
+ app_custom_init 0x0083db0d Thumb Code 628 app_custom.o(.text)
+ app_custom_is_wakeup_key 0x0083dd81 Thumb Code 46 app_custom.o(.text)
+ app_custom_is_enable_wakeup_key 0x0083ddaf Thumb Code 30 app_custom.o(.text)
+ app_custom_wakeupkey_packet_index 0x0083ddcd Thumb Code 38 app_custom.o(.text)
+ app_custom_test 0x0083ddf3 Thumb Code 200 app_custom.o(.text)
+ frm_vpk_flash_read_page 0x0083df15 Thumb Code 32 frm_vpk_hal_sflash.o(.text)
+ frm_vpk_flash_write_page 0x0083df35 Thumb Code 46 frm_vpk_hal_sflash.o(.text)
+ frm_vpk_flash_erase_sector 0x0083df63 Thumb Code 24 frm_vpk_hal_sflash.o(.text)
+ btif_vendor_cmd_req 0x0083dfc1 Thumb Code 26 gap_lib_system_call.o(.text)
+ btif_sw_reset_req 0x0083dfdb Thumb Code 18 gap_lib_system_call.o(.text)
+ BTIF_VendorGetResponse 0x0083dfed Thumb Code 20 gap_lib_system_call.o(.text)
+ btif_send_event 0x0083e001 Thumb Code 20 gap_lib_system_call.o(.text)
+ hci_if_open 0x0083e015 Thumb Code 18 gap_lib_system_call.o(.text)
+ hci_if_close 0x0083e027 Thumb Code 16 gap_lib_system_call.o(.text)
+ hci_if_write 0x0083e037 Thumb Code 20 gap_lib_system_call.o(.text)
+ hci_if_confirm 0x0083e04b Thumb Code 18 gap_lib_system_call.o(.text)
+ gap_start_bt_stack 0x0083e05d Thumb Code 28 gap_lib_system_call.o(.text)
+ gap_register_app_cb 0x0083e079 Thumb Code 18 gap_lib_system_call.o(.text)
+ gap_set_param 0x0083e08b Thumb Code 28 gap_lib_system_call.o(.text)
+ gap_get_param 0x0083e0a7 Thumb Code 22 gap_lib_system_call.o(.text)
+ gap_set_pairable_mode 0x0083e0bd Thumb Code 18 gap_lib_system_call.o(.text)
+ gap_write_airplan_mode 0x0083e0cf Thumb Code 20 gap_lib_system_call.o(.text)
+ gap_read_airplan_mode 0x0083e0e3 Thumb Code 18 gap_lib_system_call.o(.text)
+ gap_handle_msg 0x0083e0f5 Thumb Code 14 gap_lib_system_call.o(.text)
+ gap_buffer_free 0x0083e103 Thumb Code 20 gap_lib_system_call.o(.text)
+ gap_register_extend_cb 0x0083e117 Thumb Code 14 gap_lib_system_call.o(.text)
+ gap_send_dev_state 0x0083e125 Thumb Code 14 gap_lib_system_call.o(.text)
+ le_gap_init 0x0083e133 Thumb Code 18 gap_lib_system_call.o(.text)
+ le_gap_msg_info_way 0x0083e145 Thumb Code 14 gap_lib_system_call.o(.text)
+ le_get_max_link_num 0x0083e153 Thumb Code 18 gap_lib_system_call.o(.text)
+ le_register_app_cb 0x0083e165 Thumb Code 18 gap_lib_system_call.o(.text)
+ le_set_gap_param 0x0083e177 Thumb Code 28 gap_lib_system_call.o(.text)
+ le_get_gap_param 0x0083e193 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_modify_white_list 0x0083e1a9 Thumb Code 28 gap_lib_system_call.o(.text)
+ le_gen_rand_addr 0x0083e1c5 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_set_rand_addr 0x0083e1db Thumb Code 20 gap_lib_system_call.o(.text)
+ le_cfg_local_identity_address 0x0083e1ef Thumb Code 22 gap_lib_system_call.o(.text)
+ le_set_host_chann_classif 0x0083e205 Thumb Code 20 gap_lib_system_call.o(.text)
+ le_write_default_data_len 0x0083e219 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_vendor_set_rem_min_sca 0x0083e22f Thumb Code 20 gap_lib_system_call.o(.text)
+ server_init 0x0083e243 Thumb Code 14 gap_lib_system_call.o(.text)
+ server_builtin_service_reg 0x0083e251 Thumb Code 12 gap_lib_system_call.o(.text)
+ server_add_service 0x0083e25d Thumb Code 44 gap_lib_system_call.o(.text)
+ server_add_service_by_start_handle 0x0083e289 Thumb Code 44 gap_lib_system_call.o(.text)
+ server_register_app_cb 0x0083e2b5 Thumb Code 14 gap_lib_system_call.o(.text)
+ server_attr_read_confirm 0x0083e2c3 Thumb Code 42 gap_lib_system_call.o(.text)
+ server_exec_write_confirm 0x0083e2ed Thumb Code 28 gap_lib_system_call.o(.text)
+ server_attr_write_confirm 0x0083e309 Thumb Code 30 gap_lib_system_call.o(.text)
+ server_send_data 0x0083e327 Thumb Code 42 gap_lib_system_call.o(.text)
+ server_get_write_cmd_data_buffer 0x0083e351 Thumb Code 28 gap_lib_system_call.o(.text)
+ server_get_start_handle 0x0083e36d Thumb Code 20 gap_lib_system_call.o(.text)
+ client_init 0x0083e381 Thumb Code 14 gap_lib_system_call.o(.text)
+ client_register_general_client_cb 0x0083e38f Thumb Code 12 gap_lib_system_call.o(.text)
+ client_register_spec_client_cb 0x0083e39b Thumb Code 22 gap_lib_system_call.o(.text)
+ client_all_primary_srv_discovery 0x0083e3b1 Thumb Code 22 gap_lib_system_call.o(.text)
+ client_by_uuid_srv_discovery 0x0083e3c7 Thumb Code 28 gap_lib_system_call.o(.text)
+ client_by_uuid128_srv_discovery 0x0083e3e3 Thumb Code 28 gap_lib_system_call.o(.text)
+ client_relationship_discovery 0x0083e3ff Thumb Code 30 gap_lib_system_call.o(.text)
+ client_all_char_discovery 0x0083e41d Thumb Code 30 gap_lib_system_call.o(.text)
+ client_by_uuid_char_discovery 0x0083e43b Thumb Code 54 gap_lib_system_call.o(.text)
+ client_by_uuid128_char_discovery 0x0083e471 Thumb Code 32 gap_lib_system_call.o(.text)
+ client_all_char_descriptor_discovery 0x0083e491 Thumb Code 30 gap_lib_system_call.o(.text)
+ client_attr_read 0x0083e4af Thumb Code 28 gap_lib_system_call.o(.text)
+ client_attr_read_using_uuid 0x0083e4cb Thumb Code 42 gap_lib_system_call.o(.text)
+ client_attr_write 0x0083e4f5 Thumb Code 42 gap_lib_system_call.o(.text)
+ client_attr_ind_confirm 0x0083e51f Thumb Code 20 gap_lib_system_call.o(.text)
+ client_get_notify_data_buffer 0x0083e533 Thumb Code 34 gap_lib_system_call.o(.text)
+ client_send_exchange_mtu_req 0x0083e555 Thumb Code 20 gap_lib_system_call.o(.text)
+ le_adv_set_param 0x0083e569 Thumb Code 28 gap_lib_system_call.o(.text)
+ le_adv_get_param 0x0083e585 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_adv_start 0x0083e59b Thumb Code 18 gap_lib_system_call.o(.text)
+ le_adv_stop 0x0083e5ad Thumb Code 18 gap_lib_system_call.o(.text)
+ le_adv_update_param 0x0083e5bf Thumb Code 18 gap_lib_system_call.o(.text)
+ le_adv_read_tx_power 0x0083e5d1 Thumb Code 18 gap_lib_system_call.o(.text)
+ le_adv_set_tx_power 0x0083e5e3 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_vendor_one_shot_adv 0x0083e5f9 Thumb Code 28 gap_lib_system_call.o(.text)
+ le_scan_set_param 0x0083e615 Thumb Code 28 gap_lib_system_call.o(.text)
+ le_scan_get_param 0x0083e631 Thumb Code 20 gap_lib_system_call.o(.text)
+ le_scan_start 0x0083e645 Thumb Code 18 gap_lib_system_call.o(.text)
+ le_scan_stop 0x0083e657 Thumb Code 18 gap_lib_system_call.o(.text)
+ le_get_conn_param 0x0083e669 Thumb Code 28 gap_lib_system_call.o(.text)
+ le_get_conn_info 0x0083e685 Thumb Code 26 gap_lib_system_call.o(.text)
+ le_get_conn_addr 0x0083e69f Thumb Code 28 gap_lib_system_call.o(.text)
+ le_get_conn_id 0x0083e6bb Thumb Code 28 gap_lib_system_call.o(.text)
+ le_get_active_link_num 0x0083e6d7 Thumb Code 18 gap_lib_system_call.o(.text)
+ le_get_idle_link_num 0x0083e6e9 Thumb Code 18 gap_lib_system_call.o(.text)
+ le_disconnect 0x0083e6fb Thumb Code 20 gap_lib_system_call.o(.text)
+ le_read_remote_version 0x0083e70f Thumb Code 20 gap_lib_system_call.o(.text)
+ le_write_authen_payload_timeout 0x0083e723 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_read_rssi 0x0083e739 Thumb Code 20 gap_lib_system_call.o(.text)
+ le_read_chann_map 0x0083e74d Thumb Code 20 gap_lib_system_call.o(.text)
+ le_set_data_len 0x0083e761 Thumb Code 28 gap_lib_system_call.o(.text)
+ le_set_phy 0x0083e77d Thumb Code 34 gap_lib_system_call.o(.text)
+ le_disable_slave_latency 0x0083e79f Thumb Code 22 gap_lib_system_call.o(.text)
+ le_update_passed_chann_map 0x0083e7b5 Thumb Code 20 gap_lib_system_call.o(.text)
+ le_set_conn_param 0x0083e7c9 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_connect 0x0083e7df Thumb Code 34 gap_lib_system_call.o(.text)
+ le_update_conn_param 0x0083e801 Thumb Code 42 gap_lib_system_call.o(.text)
+ le_set_conn_tx_power 0x0083e82b Thumb Code 28 gap_lib_system_call.o(.text)
+ le_get_conn_local_addr_by_conn_id 0x0083e847 Thumb Code 42 gap_lib_system_call.o(.text)
+ le_bond_set_param 0x0083e871 Thumb Code 28 gap_lib_system_call.o(.text)
+ le_bond_get_param 0x0083e88d Thumb Code 20 gap_lib_system_call.o(.text)
+ le_bond_pair 0x0083e8a1 Thumb Code 20 gap_lib_system_call.o(.text)
+ le_bond_get_display_key 0x0083e8b5 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_bond_passkey_input_confirm 0x0083e8cb Thumb Code 28 gap_lib_system_call.o(.text)
+ le_bond_oob_input_confirm 0x0083e8e7 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_bond_just_work_confirm 0x0083e8fd Thumb Code 22 gap_lib_system_call.o(.text)
+ le_bond_passkey_display_confirm 0x0083e913 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_bond_user_confirm 0x0083e929 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_bond_keypress_notify 0x0083e93f Thumb Code 22 gap_lib_system_call.o(.text)
+ le_bond_cfg_local_key_distribute 0x0083e955 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_bond_clear_all_keys 0x0083e96b Thumb Code 12 gap_lib_system_call.o(.text)
+ le_bond_delete_by_idx 0x0083e977 Thumb Code 20 gap_lib_system_call.o(.text)
+ le_bond_delete_by_bd 0x0083e98b Thumb Code 22 gap_lib_system_call.o(.text)
+ le_bond_get_sec_level 0x0083e9a1 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_link_check_conn_id_internal 0x0083e9b7 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_get_conn_id_by_handle 0x0083e9cd Thumb Code 22 gap_lib_system_call.o(.text)
+ flash_save_local_name 0x0083e9e3 Thumb Code 18 gap_lib_system_call.o(.text)
+ flash_load_local_name 0x0083e9f5 Thumb Code 16 gap_lib_system_call.o(.text)
+ flash_save_local_appearance 0x0083ea05 Thumb Code 18 gap_lib_system_call.o(.text)
+ flash_load_local_appearance 0x0083ea17 Thumb Code 18 gap_lib_system_call.o(.text)
+ flash_save_local_irk 0x0083ea29 Thumb Code 18 gap_lib_system_call.o(.text)
+ flash_load_local_irk 0x0083ea3b Thumb Code 18 gap_lib_system_call.o(.text)
+ le_find_key_entry 0x0083ea4d Thumb Code 20 gap_lib_system_call.o(.text)
+ le_find_key_entry_by_idx 0x0083ea61 Thumb Code 18 gap_lib_system_call.o(.text)
+ le_get_bond_dev_num 0x0083ea73 Thumb Code 18 gap_lib_system_call.o(.text)
+ le_get_low_priority_bond 0x0083ea85 Thumb Code 16 gap_lib_system_call.o(.text)
+ le_get_high_priority_bond 0x0083ea95 Thumb Code 16 gap_lib_system_call.o(.text)
+ le_set_high_priority_bond 0x0083eaa5 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_resolve_random_address 0x0083eabb Thumb Code 28 gap_lib_system_call.o(.text)
+ le_get_cccd_data 0x0083ead7 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_gen_bond_dev 0x0083eaed Thumb Code 42 gap_lib_system_call.o(.text)
+ le_set_privacy_info 0x0083eb17 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_get_privacy_info 0x0083eb2d Thumb Code 22 gap_lib_system_call.o(.text)
+ le_check_privacy_bond 0x0083eb43 Thumb Code 20 gap_lib_system_call.o(.text)
+ le_get_max_le_paired_device_num 0x0083eb57 Thumb Code 18 gap_lib_system_call.o(.text)
+ le_get_dev_bond_info_len 0x0083eb69 Thumb Code 18 gap_lib_system_call.o(.text)
+ le_get_dev_bond_info 0x0083eb7b Thumb Code 22 gap_lib_system_call.o(.text)
+ le_set_dev_bond_info 0x0083eb91 Thumb Code 26 gap_lib_system_call.o(.text)
+ le_get_dev_info 0x0083ebab Thumb Code 26 gap_lib_system_call.o(.text)
+ le_set_local_ltk 0x0083ebc5 Thumb Code 32 gap_lib_system_call.o(.text)
+ le_privacy_set_param 0x0083ebe5 Thumb Code 28 gap_lib_system_call.o(.text)
+ le_privacy_get_param 0x0083ec01 Thumb Code 20 gap_lib_system_call.o(.text)
+ le_privacy_register_cb 0x0083ec15 Thumb Code 14 gap_lib_system_call.o(.text)
+ le_privacy_set_addr_resolution 0x0083ec23 Thumb Code 20 gap_lib_system_call.o(.text)
+ le_privacy_read_peer_resolv_addr 0x0083ec37 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_privacy_read_local_resolv_addr 0x0083ec4d Thumb Code 22 gap_lib_system_call.o(.text)
+ le_privacy_set_resolv_priv_addr_timeout 0x0083ec63 Thumb Code 30 gap_lib_system_call.o(.text)
+ le_privacy_modify_resolv_list 0x0083ec81 Thumb Code 26 gap_lib_system_call.o(.text)
+ le_privacy_set_mode 0x0083ec9b Thumb Code 28 gap_lib_system_call.o(.text)
+ le_privacy_convert_addr_type 0x0083ecb7 Thumb Code 20 gap_lib_system_call.o(.text)
+ le_ext_adv_init 0x0083eccb Thumb Code 20 gap_lib_system_call.o(.text)
+ le_ext_adv_get_param 0x0083ecdf Thumb Code 22 gap_lib_system_call.o(.text)
+ le_ext_adv_create_adv_handle 0x0083ecf5 Thumb Code 18 gap_lib_system_call.o(.text)
+ le_ext_adv_get_conn_id_by_adv_handle 0x0083ed07 Thumb Code 20 gap_lib_system_call.o(.text)
+ le_ext_adv_get_adv_handle_by_conn_id 0x0083ed1b Thumb Code 20 gap_lib_system_call.o(.text)
+ le_ext_adv_set_adv_param 0x0083ed2f Thumb Code 64 gap_lib_system_call.o(.text)
+ le_ext_adv_set_adv_data 0x0083ed6f Thumb Code 28 gap_lib_system_call.o(.text)
+ le_ext_adv_set_scan_response_data 0x0083ed8b Thumb Code 26 gap_lib_system_call.o(.text)
+ le_ext_adv_set_random 0x0083eda5 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_ext_adv_start_setting 0x0083edbb Thumb Code 22 gap_lib_system_call.o(.text)
+ le_ext_adv_set_adv_enable_param 0x0083edd1 Thumb Code 28 gap_lib_system_call.o(.text)
+ le_ext_adv_enable 0x0083eded Thumb Code 22 gap_lib_system_call.o(.text)
+ le_ext_adv_disable 0x0083ee03 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_ext_adv_clear_set 0x0083ee19 Thumb Code 18 gap_lib_system_call.o(.text)
+ le_ext_adv_remove_set 0x0083ee2b Thumb Code 20 gap_lib_system_call.o(.text)
+ le_ext_adv_gap_msg_info_way 0x0083ee3f Thumb Code 14 gap_lib_system_call.o(.text)
+ le_ext_scan_set_param 0x0083ee4d Thumb Code 28 gap_lib_system_call.o(.text)
+ le_ext_scan_get_param 0x0083ee69 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_ext_scan_set_phy_param 0x0083ee7f Thumb Code 16 gap_lib_system_call.o(.text)
+ le_ext_scan_start 0x0083ee8f Thumb Code 18 gap_lib_system_call.o(.text)
+ le_ext_scan_stop 0x0083eea1 Thumb Code 18 gap_lib_system_call.o(.text)
+ le_ext_scan_gap_msg_info_way 0x0083eeb3 Thumb Code 14 gap_lib_system_call.o(.text)
+ le_dtm_receiver_test 0x0083eec1 Thumb Code 20 gap_lib_system_call.o(.text)
+ le_dtm_transmitter_test 0x0083eed5 Thumb Code 26 gap_lib_system_call.o(.text)
+ le_dtm_test_end 0x0083eeef Thumb Code 18 gap_lib_system_call.o(.text)
+ le_dtm_enhanced_receiver_test 0x0083ef01 Thumb Code 28 gap_lib_system_call.o(.text)
+ le_dtm_enhanced_transmitter_test 0x0083ef1d Thumb Code 30 gap_lib_system_call.o(.text)
+ le_dtm_transmitter_test_v4 0x0083ef3b Thumb Code 52 gap_lib_system_call.o(.text)
+ gatt_register_callback 0x0083ef6f Thumb Code 12 gap_lib_system_call.o(.text)
+ gaps_set_parameter 0x0083ef7b Thumb Code 28 gap_lib_system_call.o(.text)
+ gaps_set_peripheral_preferred_conn_param 0x0083ef97 Thumb Code 20 gap_lib_system_call.o(.text)
+ gatts_service_changed_indicate 0x0083efab Thumb Code 28 gap_lib_system_call.o(.text)
+ le_rf_read_rf_path_compensation 0x0083efc7 Thumb Code 16 gap_lib_system_call.o(.text)
+ le_rf_write_rf_path_compensation 0x0083efd7 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_rf_enhanced_read_transmit_power_level 0x0083efed Thumb Code 22 gap_lib_system_call.o(.text)
+ le_rf_read_remote_transmit_power_level 0x0083f003 Thumb Code 22 gap_lib_system_call.o(.text)
+ le_rf_set_transmit_power_reporting_enable 0x0083f019 Thumb Code 28 gap_lib_system_call.o(.text)
+ le_rf_set_path_loss_reporting_params 0x0083f035 Thumb Code 44 gap_lib_system_call.o(.text)
+ le_rf_set_path_loss_reporting_enable 0x0083f061 Thumb Code 44 gap_lib_system_call.o(.text)
+ ADC_CalibrationInit 0x0083f121 Thumb Code 456 adc_lib.o(.text)
+ ADC_GetVoltage 0x0083f2e9 Thumb Code 132 adc_lib.o(.text)
+ ADC_GetResistance 0x0083f36d Thumb Code 20 adc_lib.o(.text)
+ __aeabi_lmul 0x0083f399 Thumb Code 48 llmul.o(.text)
+ _ll_mul 0x0083f399 Thumb Code 0 llmul.o(.text)
+ __aeabi_uldivmod 0x0083f3c9 Thumb Code 258 lludiv.o(.text)
+ _ll_udiv 0x0083f3c9 Thumb Code 0 lludiv.o(.text)
+ vsprintf 0x0083f4cd Thumb Code 32 vsprintf.o(.text)
+ srand 0x0083f4f1 Thumb Code 44 rand.o(.text)
+ _rand_init 0x0083f51d Thumb Code 4 rand.o(.text)
+ __aeabi_uidiv 0x0083f52d Thumb Code 0 aeabi_sdiv.o(.text)
+ __aeabi_uidivmod 0x0083f52d Thumb Code 20 aeabi_sdiv.o(.text)
+ __aeabi_idiv 0x0083f541 Thumb Code 0 aeabi_sdiv.o(.text)
+ __aeabi_idivmod 0x0083f541 Thumb Code 326 aeabi_sdiv.o(.text)
+ __aeabi_d2f 0x0083f689 Thumb Code 0 d2f.o(.text)
+ _d2f 0x0083f689 Thumb Code 120 d2f.o(.text)
+ __aeabi_dadd 0x0083f9fd Thumb Code 0 daddsub.o(.text)
+ _dadd 0x0083f9fd Thumb Code 26 daddsub.o(.text)
+ __aeabi_dsub 0x0083fa17 Thumb Code 0 daddsub.o(.text)
+ _dsub 0x0083fa17 Thumb Code 22 daddsub.o(.text)
+ __aeabi_drsub 0x0083fa2d Thumb Code 0 daddsub.o(.text)
+ _drsb 0x0083fa2d Thumb Code 28 daddsub.o(.text)
+ __aeabi_ddiv 0x0083fa5d Thumb Code 0 ddiv.o(.text)
+ _ddiv 0x0083fa5d Thumb Code 1072 ddiv.o(.text)
+ _drdiv 0x0083fe8d Thumb Code 20 ddiv.o(.text)
+ __aeabi_d2uiz 0x0083fea5 Thumb Code 0 dfixui.o(.text)
+ _dfixu 0x0083fea5 Thumb Code 68 dfixui.o(.text)
+ __aeabi_i2d_normalise 0x0083feed Thumb Code 66 dflti.o(.text)
+ __aeabi_i2d 0x0083ff2f Thumb Code 16 dflti.o(.text)
+ _dflt 0x0083ff2f Thumb Code 0 dflti.o(.text)
+ __aeabi_ui2d 0x0083ff3f Thumb Code 6 dflti.o(.text)
+ _dfltu 0x0083ff3f Thumb Code 0 dflti.o(.text)
+ __aeabi_dmul 0x0083ff45 Thumb Code 0 dmul.o(.text)
+ _dmul 0x0083ff45 Thumb Code 558 dmul.o(.text)
+ __aeabi_f2d 0x0084018d Thumb Code 0 f2d.o(.text)
+ _f2d 0x0084018d Thumb Code 80 f2d.o(.text)
+ __aeabi_fdiv 0x008401e1 Thumb Code 0 fdiv.o(.text)
+ _fdiv 0x008401e1 Thumb Code 334 fdiv.o(.text)
+ _frdiv 0x0084032f Thumb Code 8 fdiv.o(.text)
+ __aeabi_f2uiz 0x00840341 Thumb Code 0 ffixui.o(.text)
+ _ffixu 0x00840341 Thumb Code 48 ffixui.o(.text)
+ __aeabi_i2f_normalise 0x00840371 Thumb Code 72 fflti.o(.text)
+ __aeabi_i2f 0x008403b9 Thumb Code 16 fflti.o(.text)
+ _fflt 0x008403b9 Thumb Code 0 fflti.o(.text)
+ __aeabi_ui2f 0x008403c9 Thumb Code 6 fflti.o(.text)
+ _ffltu 0x008403c9 Thumb Code 0 fflti.o(.text)
+ _printf_pre_padding 0x008403cf Thumb Code 44 _printf_pad.o(.text)
+ _printf_post_padding 0x008403fb Thumb Code 34 _printf_pad.o(.text)
+ _printf_truncate_signed 0x0084041d Thumb Code 18 _printf_truncate.o(.text)
+ _printf_truncate_unsigned 0x0084042f Thumb Code 18 _printf_truncate.o(.text)
+ _printf_str 0x00840441 Thumb Code 82 _printf_str.o(.text)
+ _printf_int_dec 0x00840495 Thumb Code 90 _printf_dec.o(.text)
+ _printf_charcount 0x00840501 Thumb Code 38 _printf_charcount.o(.text)
+ _printf_char_common 0x00840533 Thumb Code 32 _printf_char_common.o(.text)
+ _sputc 0x00840559 Thumb Code 10 _sputc.o(.text)
+ _printf_wctomb 0x00840565 Thumb Code 182 _printf_wctomb.o(.text)
+ _printf_longlong_dec 0x00840621 Thumb Code 94 _printf_longlong_dec.o(.text)
+ _printf_longlong_oct 0x00840691 Thumb Code 68 _printf_oct_int_ll.o(.text)
+ _printf_int_oct 0x008406d5 Thumb Code 24 _printf_oct_int_ll.o(.text)
+ _printf_ll_oct 0x008406ed Thumb Code 10 _printf_oct_int_ll.o(.text)
+ _printf_longlong_hex 0x00840701 Thumb Code 88 _printf_hex_int_ll_ptr.o(.text)
+ _printf_int_hex 0x00840759 Thumb Code 28 _printf_hex_int_ll_ptr.o(.text)
+ _printf_ll_hex 0x00840775 Thumb Code 10 _printf_hex_int_ll_ptr.o(.text)
+ _printf_hex_ptr 0x0084077f Thumb Code 22 _printf_hex_int_ll_ptr.o(.text)
+ __printf 0x00840799 Thumb Code 386 __printf_flags_ss_wp.o(.text)
+ _ll_udiv10 0x00840921 Thumb Code 122 lludiv10.o(.text)
+ _printf_int_common 0x0084099b Thumb Code 176 _printf_intcommon.o(.text)
+ __lib_sel_fp_printf 0x00840a4d Thumb Code 2 _printf_fp_dec.o(.text)
+ _printf_fp_dec_real 0x00840beb Thumb Code 620 _printf_fp_dec.o(.text)
+ _printf_fp_hex_real 0x00840e65 Thumb Code 718 _printf_fp_hex.o(.text)
+ _printf_cs_common 0x0084113d Thumb Code 22 _printf_char.o(.text)
+ _printf_char 0x00841153 Thumb Code 16 _printf_char.o(.text)
+ _printf_string 0x00841163 Thumb Code 8 _printf_char.o(.text)
+ _printf_lcs_common 0x0084116b Thumb Code 22 _printf_wchar.o(.text)
+ _printf_wchar 0x00841181 Thumb Code 16 _printf_wchar.o(.text)
+ _printf_wstring 0x00841191 Thumb Code 8 _printf_wchar.o(.text)
+ _wcrtomb 0x00841199 Thumb Code 64 _wcrtomb.o(.text)
+ __rt_udiv10 0x008411d9 Thumb Code 40 rtudiv10.o(.text)
+ __rt_ctype_table 0x00841201 Thumb Code 16 rt_ctype_table.o(.text)
+ __rt_locale 0x00841211 Thumb Code 8 rt_locale.o(.text)
+ _printf_fp_infnan 0x00841219 Thumb Code 120 _printf_fp_infnan.o(.text)
+ _btod_etento 0x008412a1 Thumb Code 210 bigflt0.o(.text)
+ _btod_d2e 0x00841379 Thumb Code 64 btod.o(.text)
+ _btod_emul 0x008417ad Thumb Code 28 btod.o(.text)
+ _btod_emuld 0x008417c9 Thumb Code 144 btod.o(.text)
+ _btod_ediv 0x00841859 Thumb Code 26 btod.o(.text)
+ _btod_edivd 0x00841873 Thumb Code 124 btod.o(.text)
+ strcmp 0x008418f9 Thumb Code 132 strcmp.o(.text)
+ __ARM_common_ll_muluu 0x00841981 Thumb Code 48 btod.o(i.__ARM_common_ll_muluu)
+ __ARM_common_switch8 0x008419b1 Thumb Code 26 dis.o(i.__ARM_common_switch8)
+ __ARM_fpclassify 0x008419cd Thumb Code 40 fpclassify.o(i.__ARM_fpclassify)
+ _is_digit 0x008419f9 Thumb Code 14 __printf_wp.o(i._is_digit)
+ ima_adpcm_encode 0x00841a09 Thumb Code 304 ima_adpcm_enc.o(i.ima_adpcm_encode)
+ _get_lc_numeric 0x00841b41 Thumb Code 44 lc_numeric_c.o(locale$$code)
+ _get_lc_ctype 0x00841b6d Thumb Code 44 lc_ctype_c.o(locale$$code)
+ __aeabi_fadd 0x00841b99 Thumb Code 0 faddsub.o(x$fpl$fadd)
+ _fadd 0x00841b99 Thumb Code 134 faddsub.o(x$fpl$fadd)
+ __aeabi_fmul 0x00841c25 Thumb Code 0 fmul.o(x$fpl$fmul)
+ _fmul 0x00841c25 Thumb Code 172 fmul.o(x$fpl$fmul)
+ __aeabi_fsub 0x00841cd5 Thumb Code 0 faddsub.o(x$fpl$fsub)
+ _fsub 0x00841cd5 Thumb Code 204 faddsub.o(x$fpl$fsub)
+ _printf_fp_dec 0x00841da5 Thumb Code 16 printf1.o(x$fpl$printf1)
+ _printf_fp_hex 0x00841db5 Thumb Code 16 printf2.o(x$fpl$printf2)
+ __I$use$fp 0x00841dc4 Number 0 usenofp.o(x$fpl$usenofp)
+ app_cb_table 0x00841dc4 Data 12 system_rtl876x.o(.constdata)
+ PINADDR_TABLE 0x00841ed0 Data 78 rtl876x_pinmux.o(.constdata)
+ WKSTATUS_TABLE 0x00841f1e Data 78 rtl876x_pinmux.o(.constdata)
+ dis_cbs 0x00842180 Data 12 dis.o(.constdata)
+ bas_cbs 0x008421fc Data 12 bas.o(.constdata)
+ hids_attr_table 0x00842240 Data 476 hids_rmc.o(.constdata)
+ hids_cbs 0x0084241c Data 12 hids_rmc.o(.constdata)
+ vendor_svc_bas_attr_tbl 0x00842438 Data 168 vendor_service.o(.constdata)
+ vendor_svc_cbs 0x008424e0 Data 12 vendor_service.o(.constdata)
+ GATT_UUID_ATVV_SERVICE 0x008424ec Data 16 atvv_service.o(.constdata)
+ atvv_attr_tbl 0x008424fc Data 252 atvv_service.o(.constdata)
+ atvv_cbs 0x008425f8 Data 12 atvv_service.o(.constdata)
+ ir_svc_attr_tbl 0x00842614 Data 336 ir_service.o(.constdata)
+ ir_svc_cbs 0x00842764 Data 12 ir_service.o(.constdata)
+ SILENCE_GATT_UUID128_DFU_SERVICE 0x00842770 Data 16 dfu_service.o(.constdata)
+ DfuServiceCBs 0x00842780 Data 12 dfu_service.o(.constdata)
+ GATT_UUID_OTA_SERVICE 0x0084278c Data 16 ota_service.o(.constdata)
+ gatt_Ota_service_table 0x0084279c Data 700 ota_service.o(.constdata)
+ ota_service_cbs 0x00842a58 Data 12 ota_service.o(.constdata)
+ fms_svc_attr_tbl 0x00842a74 Data 168 fms.o(.constdata)
+ fms_cbs 0x00842b1c Data 12 fms.o(.constdata)
+ Default_HW_Rev 0x00842b28 Data 4 rcu_application.o(.constdata)
+ Default_SW_Rev 0x00842b2c Data 5 rcu_application.o(.constdata)
+ Default_FW_Rev 0x00842b31 Data 6 rcu_application.o(.constdata)
+ Default_PnP_ID 0x00842b37 Data 7 rcu_application.o(.constdata)
+ Default_Manu_Name 0x00842b3e Data 7 rcu_application.o(.constdata)
+ KEY_MAPPING_TABLE_G10 0x00842ba0 Data 28 key_handle.o(.constdata)
+ KEY_CODE_TABLE 0x00842bbc Data 400 key_handle.o(.constdata)
+ Kb_Map_devicelayout_Correspend_Index_G10 0x00842d4c Data 3 key_handle.o(.constdata)
+ Wakeup_Map_Correspend_Index_G10 0x00842d4f Data 8 key_handle.o(.constdata)
+ Ir_Table_Correspend_Index_G10 0x00842d57 Data 3 key_handle.o(.constdata)
+ KEY_MAPPING_TABLE_G20 0x00842d5a Data 42 key_handle.o(.constdata)
+ Kb_Map_devicelayout_Correspend_Index_G20 0x00842d84 Data 8 key_handle.o(.constdata)
+ Wakeup_Map_Correspend_Index_G20 0x00842d8c Data 12 key_handle.o(.constdata)
+ Ir_Table_Correspend_Index_G20 0x00842d98 Data 8 key_handle.o(.constdata)
+ NEC_SPEC 0x00842dc0 Data 96 ir_protocol_nec.o(.constdata)
+ NEC_REPEAT_CODE_SPEC 0x00842e20 Data 16 ir_protocol_nec.o(.constdata)
+ key_button_map_g10 0x00842e30 Data 20 ir_service_handle.o(.constdata)
+ key_button_map_g20 0x00842e44 Data 20 ir_service_handle.o(.constdata)
+ __ctype 0x00843459 Data 0 lc_ctype_c.o(locale$$data)
+ Load$$RAM_VECTOR_TABLE$$RO$$Base 0x0084355c Number 0 anon$$obj.o ABSOLUTE
+ Load$$RAM_DATA_ON$$RO$$Base 0x00843644 Number 0 anon$$obj.o ABSOLUTE
+ Load$$RAM_DATA_ON$$RW$$Base 0x00844aec Number 0 anon$$obj.o ABSOLUTE
+ Load$$OVERLAY_A$$RO$$Base 0x00844e9c Number 0 anon$$obj.o ABSOLUTE
+ Load$$CACHE_DATA_ON$$RO$$Base 0x00844f64 Number 0 anon$$obj.o ABSOLUTE
+ Load$$CACHE_DATA_ON$$RW$$Base 0x00844f64 Number 0 anon$$obj.o ABSOLUTE
+ Load$$OVERLAY_A$$RW$$Base 0x00844f64 Number 0 anon$$obj.o ABSOLUTE
+ Load$$OVERLAY_B$$RO$$Base 0x00844f64 Number 0 anon$$obj.o ABSOLUTE
+ Load$$OVERLAY_B$$RW$$Base 0x00844f64 Number 0 anon$$obj.o ABSOLUTE
+ Load$$OVERLAY_C$$RO$$Base 0x00844f64 Number 0 anon$$obj.o ABSOLUTE
+ Load$$OVERLAY_C$$RW$$Base 0x00844f64 Number 0 anon$$obj.o ABSOLUTE
+
+
+
+==============================================================================
+
+Memory Map of the image
+
+ Image Entry point : 0x00832409
+
+ Load Region LOAD_FLASH (Base: 0x00832000, Size: 0x00012f64, Max: 0x00019000, ABSOLUTE)
+
+ Execution Region RAM_VECTOR_TABLE (Exec base: 0x00200000, Load base: 0x0084355c, Size: 0x000000e8, Max: 0x000000e8, OVERLAY)
+
+ Exec Addr Load Addr Size Type Attr Idx E Section Name Object
+
+ 0x00200000 0x0084355c 0x000000e8 Data RO 1 VECTOR startup_rtl876x.o
+
+
+ Execution Region RAM_DATA_ON (Exec base: 0x00207c00, Load base: 0x00843644, Size: 0x00003e04, Max: 0x00005000, OVERLAY)
+
+ Exec Addr Load Addr Size Type Attr Idx E Section Name Object
+
+ 0x00207c00 0x00843644 0x00000114 Code RO 14 .app.data_ram.text system_rtl876x.o
+ 0x00207d14 0x00843758 0x00000450 Code RO 200 .app.data_ram.text rtl876x_io_dlps.o
+ 0x00208164 0x00843ba8 0x000000c4 Code RO 982 .app.data_ram.text main.o
+ 0x00208228 0x00843c6c 0x000000d4 Code RO 1112 .app.data_ram.text rcu_application.o
+ 0x002082fc 0x00843d40 0x000000f0 Code RO 1199 .app.data_ram.text swtimer.o
+ 0x002083ec 0x00843e30 0x00000164 Code RO 1235 .app.data_ram.text app_task.o
+ 0x00208550 0x00843f94 0x00000044 Code RO 1278 .app.data_ram.text reset_watch_dog_timer.o
+ 0x00208594 0x00843fd8 0x000002a6 Code RO 1359 .app.data_ram.text loop_queue.o
+ 0x0020883a 0x0084427e 0x00000002 PAD
+ 0x0020883c 0x00844280 0x00000058 Code RO 1443 .app.data_ram.text rtc_driver.o
+ 0x00208894 0x008442d8 0x000002d4 Code RO 1568 .app.data_ram.text keyscan_driver.o
+ 0x00208b68 0x008445ac 0x00000114 Code RO 1610 .app.data_ram.text key_handle.o
+ 0x00208c7c 0x008446c0 0x0000006c Code RO 1657 .app.data_ram.text voice_driver.o
+ 0x00208ce8 0x0084472c 0x00000048 Code RO 1694 .app.data_ram.text voice.o
+ 0x00208d30 0x00844774 0x000000f8 Code RO 1739 .app.data_ram.text ir_send_driver.o
+ 0x00208e28 0x0084486c 0x000000f4 Code RO 1866 .app.data_ram.text led_driver.o
+ 0x00208f1c 0x00844960 0x00000030 Code RO 1950 .app.data_ram.text fms_service_handle.o
+ 0x00208f4c 0x00844990 0x00000104 Code RO 1982 .app.data_ram.text battery_driver.o
+ 0x00209050 0x00844a94 0x0000003c Code RO 2169 .app.data_ram.text frm_vpk_log.o
+ 0x0020908c 0x00844ad0 0x0000001c Code RO 201 .text rtl876x_io_dlps.o
+ 0x002090a8 0x00844aec 0x0000002e Data RW 618 .data dis.o
+ 0x002090d6 0x00844b1a 0x00000008 Data RW 710 .data hids_rmc.o
+ 0x002090de 0x00844b22 0x00000002 PAD
+ 0x002090e0 0x00844b24 0x000000a8 Data RW 869 .data dfu_service.o
+ 0x00209188 0x00844bcc 0x00000004 Data RW 985 .data main.o
+ 0x0020918c 0x00844bd0 0x0000000e Data RW 1175 .data rcu_gap.o
+ 0x0020919a 0x00844bde 0x00000002 Data RW 1312 .data privacy_mgnt.o
+ 0x0020919c 0x00844be0 0x0000006c Data RW 1336 .data overlay_mgr.o
+ 0x00209208 0x00844c4c 0x00000001 Data RW 1392 .data rcu_dtm_app.o
+ 0x00209209 0x00844c4d 0x00000001 Data RW 1542 .data dfu_flash.o
+ 0x0020920a 0x00844c4e 0x0000000e Data RW 1572 .data keyscan_driver.o
+ 0x00209218 0x00844c5c 0x00000018 Data RW 1622 .data key_handle.o
+ 0x00209230 0x00844c74 0x00000030 Data RW 1623 .data key_handle.o
+ 0x00209260 0x00844ca4 0x00000001 Data RW 1771 .data ir_send_handle.o
+ 0x00209261 0x00844ca5 0x00000003 PAD
+ 0x00209264 0x00844ca8 0x00000014 Data RW 1836 .data ir_service_handle.o
+ 0x00209278 0x00844cbc 0x00000002 Data RW 1954 .data fms_service_handle.o
+ 0x0020927a 0x00844cbe 0x00000002 PAD
+ 0x0020927c 0x00844cc0 0x00000004 Data RW 2116 .data app_custom.o
+ 0x00209280 0x00844cc4 0x00000032 Data RW 2197 .data adc.lib(adc_lib.o)
+ 0x002092b2 0x00844cf6 0x00000002 PAD
+ 0x002092b4 0x00844cf8 0x000001a4 Data RW 2226 .data ima_adpcm_lib.lib(ima_adpcm_enc.o)
+ 0x00209458 - 0x00000014 Zero RW 20 .bss system_rtl876x.o
+ 0x0020946c - 0x00000130 Zero RW 203 .bss rtl876x_io_dlps.o
+ 0x0020959c - 0x00000001 Zero RW 332 .bss rtl876x_rtc.o
+ 0x0020959d - 0x00000001 Zero RW 566 .bss rtl876x_lpc.o
+ 0x0020959e - 0x00000001 Zero RW 590 .bss rtl876x_aon_wdg.o
+ 0x0020959f 0x00844e9c 0x00000001 PAD
+ 0x002095a0 - 0x00000084 Zero RW 615 .bss dis.o
+ 0x00209624 - 0x00000008 Zero RW 677 .bss bas.o
+ 0x0020962c - 0x0000000c Zero RW 708 .bss hids_rmc.o
+ 0x00209638 - 0x00000010 Zero RW 737 .bss vendor_service.o
+ 0x00209648 - 0x00000004 Zero RW 738 .bss vendor_service.o
+ 0x0020964c - 0x0000004a Zero RW 805 .bss atvv_service.o
+ 0x00209696 0x00844e9c 0x00000002 PAD
+ 0x00209698 - 0x00000004 Zero RW 835 .bss ir_service.o
+ 0x0020969c - 0x000008ac Zero RW 865 .bss dfu_service.o
+ 0x00209f48 - 0x00000058 Zero RW 902 .bss ota_service.o
+ 0x00209fa0 - 0x00000008 Zero RW 949 .bss fms.o
+ 0x00209fa8 - 0x000000b4 Zero RW 1115 .bss rcu_application.o
+ 0x0020a05c - 0x00000060 Zero RW 1173 .bss rcu_gap.o
+ 0x0020a0bc - 0x00000020 Zero RW 1202 .bss swtimer.o
+ 0x0020a0dc - 0x00000010 Zero RW 1238 .bss app_task.o
+ 0x0020a0ec - 0x00000010 Zero RW 1310 .bss privacy_mgnt.o
+ 0x0020a0fc - 0x00000008 Zero RW 1334 .bss overlay_mgr.o
+ 0x0020a104 - 0x0000000a Zero RW 1391 .bss rcu_dtm_app.o
+ 0x0020a10e 0x00844e9c 0x00000002 PAD
+ 0x0020a110 - 0x00000008 Zero RW 1446 .bss rtc_driver.o
+ 0x0020a118 - 0x0000000c Zero RW 1541 .bss dfu_flash.o
+ 0x0020a124 - 0x00000030 Zero RW 1571 .bss keyscan_driver.o
+ 0x0020a154 - 0x00000228 Zero RW 1613 .bss key_handle.o
+ 0x0020a37c - 0x00000468 Zero RW 1660 .bss voice_driver.o
+ 0x0020a7e4 - 0x00000010 Zero RW 1697 .bss voice.o
+ 0x0020a7f4 - 0x00000008 Zero RW 1742 .bss ir_send_driver.o
+ 0x0020a7fc - 0x0000065c Zero RW 1770 .bss ir_send_handle.o
+ 0x0020ae58 - 0x00000a08 Zero RW 1834 .bss ir_service_handle.o
+ 0x0020b860 - 0x00000028 Zero RW 1869 .bss led_driver.o
+ 0x0020b888 - 0x00000002 Zero RW 1899 .bss led_pwm_driver.o
+ 0x0020b88a 0x00844e9c 0x00000002 PAD
+ 0x0020b88c - 0x0000000c Zero RW 1924 .bss buzzer_driver.o
+ 0x0020b898 - 0x00000008 Zero RW 1953 .bss fms_service_handle.o
+ 0x0020b8a0 - 0x00000006 Zero RW 1985 .bss battery_driver.o
+ 0x0020b8a6 0x00844e9c 0x00000002 PAD
+ 0x0020b8a8 - 0x00000008 Zero RW 2193 .bss gap_utils.lib(gap_lib_system_call.o)
+ 0x0020b8b0 - 0x00000054 Zero RW 2196 .bss adc.lib(adc_lib.o)
+ 0x0020b904 - 0x00000006 Zero RW 2225 .bss ima_adpcm_lib.lib(ima_adpcm_enc.o)
+ 0x0020b90a 0x00844e9c 0x00000002 PAD
+ 0x0020b90c - 0x000000e4 Zero RW 2236 .bss c_p.l(rand.o)
+ 0x0020b9f0 - 0x00000014 Zero RW 2478 .bss c_p.l(rt_locale.o)
+
+
+ Execution Region OVERLAY_A (Exec base: 0x0020ba04, Load base: 0x00844e9c, Size: 0x000000c8, Max: 0xffffffff, OVERLAY)
+
+ Exec Addr Load Addr Size Type Attr Idx E Section Name Object
+
+ 0x0020ba04 0x00844e9c 0x000000c8 Code RO 16 .app.overlay_a system_rtl876x.o
+
+
+ Execution Region OVERLAY_B (Exec base: 0x0020ba04, Load base: 0x00844f64, Size: 0x00000000, Max: 0xffffffff, OVERLAY)
+
+ **** No section assigned to this execution region ****
+
+
+ Execution Region OVERLAY_C (Exec base: 0x0020ba04, Load base: 0x00844f64, Size: 0x00000000, Max: 0xffffffff, OVERLAY)
+
+ **** No section assigned to this execution region ****
+
+
+ Execution Region CACHE_DATA_ON (Exec base: 0x00216000, Load base: 0x00844f64, Size: 0x00000000, Max: 0x00000000, OVERLAY)
+
+ **** No section assigned to this execution region ****
+
+
+ Execution Region app.bin (Exec base: 0x00832000, Load base: 0x00832000, Size: 0x00000400, Max: 0xffffffff, ABSOLUTE)
+
+ Exec Addr Load Addr Size Type Attr Idx E Section Name Object
+
+ 0x00832000 0x00832000 0x00000400 Data RO 19 .app.flash.header system_rtl876x.o
+
+
+ Execution Region APP_FLASH_HEADER_EXT (Exec base: 0x00832400, Load base: 0x00832400, Size: 0x00000000, Max: 0xffffffff, ABSOLUTE)
+
+ **** No section assigned to this execution region ****
+
+
+ Execution Region FLASH_START_ADDR (Exec base: 0x00832400, Load base: 0x00832400, Size: 0x00000008, Max: 0xffffffff, ABSOLUTE)
+
+ Exec Addr Load Addr Size Type Attr Idx E Section Name Object
+
+ 0x00832400 0x00832400 0x00000008 Code RO 2 RESET startup_rtl876x.o
+
+
+ Execution Region FLASH_TEXT (Exec base: 0x00832408, Load base: 0x00832408, Size: 0x00011154, Max: 0xffffffff, ABSOLUTE)
+
+ Exec Addr Load Addr Size Type Attr Idx E Section Name Object
+
+ 0x00832408 0x00832408 0x00000008 Code RO 2243 * !!!main c_p.l(__main.o)
+ 0x00832410 0x00832410 0x00000002 Code RO 2365 .ARM.Collect$$_printf_percent$$00000000 c_p.l(_printf_percent.o)
+ 0x00832412 0x00832412 0x0000000a Code RO 2354 .ARM.Collect$$_printf_percent$$00000001 c_p.l(_printf_n.o)
+ 0x0083241c 0x0083241c 0x0000000a Code RO 2356 .ARM.Collect$$_printf_percent$$00000002 c_p.l(_printf_p.o)
+ 0x00832426 0x00832426 0x0000000a Code RO 2361 .ARM.Collect$$_printf_percent$$00000003 c_p.l(_printf_f.o)
+ 0x00832430 0x00832430 0x0000000a Code RO 2362 .ARM.Collect$$_printf_percent$$00000004 c_p.l(_printf_e.o)
+ 0x0083243a 0x0083243a 0x0000000a Code RO 2363 .ARM.Collect$$_printf_percent$$00000005 c_p.l(_printf_g.o)
+ 0x00832444 0x00832444 0x0000000a Code RO 2364 .ARM.Collect$$_printf_percent$$00000006 c_p.l(_printf_a.o)
+ 0x0083244e 0x0083244e 0x0000000a Code RO 2369 .ARM.Collect$$_printf_percent$$00000007 c_p.l(_printf_ll.o)
+ 0x00832458 0x00832458 0x0000000a Code RO 2358 .ARM.Collect$$_printf_percent$$00000008 c_p.l(_printf_i.o)
+ 0x00832462 0x00832462 0x0000000a Code RO 2359 .ARM.Collect$$_printf_percent$$00000009 c_p.l(_printf_d.o)
+ 0x0083246c 0x0083246c 0x0000000a Code RO 2360 .ARM.Collect$$_printf_percent$$0000000A c_p.l(_printf_u.o)
+ 0x00832476 0x00832476 0x0000000a Code RO 2357 .ARM.Collect$$_printf_percent$$0000000B c_p.l(_printf_o.o)
+ 0x00832480 0x00832480 0x0000000a Code RO 2355 .ARM.Collect$$_printf_percent$$0000000C c_p.l(_printf_x.o)
+ 0x0083248a 0x0083248a 0x0000000a Code RO 2366 .ARM.Collect$$_printf_percent$$0000000D c_p.l(_printf_lli.o)
+ 0x00832494 0x00832494 0x0000000a Code RO 2367 .ARM.Collect$$_printf_percent$$0000000E c_p.l(_printf_lld.o)
+ 0x0083249e 0x0083249e 0x0000000a Code RO 2368 .ARM.Collect$$_printf_percent$$0000000F c_p.l(_printf_llu.o)
+ 0x008324a8 0x008324a8 0x0000000a Code RO 2373 .ARM.Collect$$_printf_percent$$00000010 c_p.l(_printf_llo.o)
+ 0x008324b2 0x008324b2 0x0000000a Code RO 2374 .ARM.Collect$$_printf_percent$$00000011 c_p.l(_printf_llx.o)
+ 0x008324bc 0x008324bc 0x0000000a Code RO 2370 .ARM.Collect$$_printf_percent$$00000012 c_p.l(_printf_l.o)
+ 0x008324c6 0x008324c6 0x0000000a Code RO 2352 .ARM.Collect$$_printf_percent$$00000013 c_p.l(_printf_c.o)
+ 0x008324d0 0x008324d0 0x0000000a Code RO 2353 .ARM.Collect$$_printf_percent$$00000014 c_p.l(_printf_s.o)
+ 0x008324da 0x008324da 0x0000000a Code RO 2371 .ARM.Collect$$_printf_percent$$00000015 c_p.l(_printf_lc.o)
+ 0x008324e4 0x008324e4 0x0000000a Code RO 2372 .ARM.Collect$$_printf_percent$$00000016 c_p.l(_printf_ls.o)
+ 0x008324ee 0x008324ee 0x00000004 Code RO 2466 .ARM.Collect$$_printf_percent$$00000017 c_p.l(_printf_percent_end.o)
+ 0x008324f2 0x008324f2 0x00000002 Code RO 2507 .ARM.Collect$$libinit$$00000000 c_p.l(libinit.o)
+ 0x008324f4 0x008324f4 0x00000000 Code RO 2376 .ARM.Collect$$libinit$$00000002 c_p.l(libinit2.o)
+ 0x008324f4 0x008324f4 0x00000000 Code RO 2378 .ARM.Collect$$libinit$$00000004 c_p.l(libinit2.o)
+ 0x008324f4 0x008324f4 0x00000000 Code RO 2381 .ARM.Collect$$libinit$$0000000A c_p.l(libinit2.o)
+ 0x008324f4 0x008324f4 0x00000000 Code RO 2383 .ARM.Collect$$libinit$$0000000C c_p.l(libinit2.o)
+ 0x008324f4 0x008324f4 0x00000004 Code RO 2384 .ARM.Collect$$libinit$$0000000D c_p.l(libinit2.o)
+ 0x008324f8 0x008324f8 0x00000000 Code RO 2385 .ARM.Collect$$libinit$$0000000E c_p.l(libinit2.o)
+ 0x008324f8 0x008324f8 0x00000006 Code RO 2386 .ARM.Collect$$libinit$$0000000F c_p.l(libinit2.o)
+ 0x008324fe 0x008324fe 0x00000000 Code RO 2388 .ARM.Collect$$libinit$$00000011 c_p.l(libinit2.o)
+ 0x008324fe 0x008324fe 0x0000000c Code RO 2389 .ARM.Collect$$libinit$$00000012 c_p.l(libinit2.o)
+ 0x0083250a 0x0083250a 0x00000000 Code RO 2390 .ARM.Collect$$libinit$$00000013 c_p.l(libinit2.o)
+ 0x0083250a 0x0083250a 0x00000000 Code RO 2392 .ARM.Collect$$libinit$$00000015 c_p.l(libinit2.o)
+ 0x0083250a 0x0083250a 0x0000000a Code RO 2393 .ARM.Collect$$libinit$$00000016 c_p.l(libinit2.o)
+ 0x00832514 0x00832514 0x00000000 Code RO 2394 .ARM.Collect$$libinit$$00000017 c_p.l(libinit2.o)
+ 0x00832514 0x00832514 0x00000000 Code RO 2396 .ARM.Collect$$libinit$$00000019 c_p.l(libinit2.o)
+ 0x00832514 0x00832514 0x00000000 Code RO 2398 .ARM.Collect$$libinit$$0000001B c_p.l(libinit2.o)
+ 0x00832514 0x00832514 0x00000000 Code RO 2400 .ARM.Collect$$libinit$$0000001D c_p.l(libinit2.o)
+ 0x00832514 0x00832514 0x00000000 Code RO 2402 .ARM.Collect$$libinit$$0000001F c_p.l(libinit2.o)
+ 0x00832514 0x00832514 0x00000000 Code RO 2404 .ARM.Collect$$libinit$$00000021 c_p.l(libinit2.o)
+ 0x00832514 0x00832514 0x00000000 Code RO 2406 .ARM.Collect$$libinit$$00000023 c_p.l(libinit2.o)
+ 0x00832514 0x00832514 0x00000000 Code RO 2408 .ARM.Collect$$libinit$$00000025 c_p.l(libinit2.o)
+ 0x00832514 0x00832514 0x00000000 Code RO 2412 .ARM.Collect$$libinit$$0000002C c_p.l(libinit2.o)
+ 0x00832514 0x00832514 0x00000000 Code RO 2414 .ARM.Collect$$libinit$$0000002E c_p.l(libinit2.o)
+ 0x00832514 0x00832514 0x00000000 Code RO 2416 .ARM.Collect$$libinit$$00000030 c_p.l(libinit2.o)
+ 0x00832514 0x00832514 0x00000000 Code RO 2418 .ARM.Collect$$libinit$$00000032 c_p.l(libinit2.o)
+ 0x00832514 0x00832514 0x00000002 Code RO 2419 .ARM.Collect$$libinit$$00000033 c_p.l(libinit2.o)
+ 0x00832516 0x00832516 0x00000000 Code RO 2275 .ARM.Collect$$rtentry$$00000000 c_p.l(__rtentry.o)
+ 0x00832516 0x00832516 0x00000000 Code RO 2430 .ARM.Collect$$rtentry$$00000002 c_p.l(__rtentry2.o)
+ 0x00832516 0x00832516 0x00000004 Code RO 2444 .ARM.Collect$$rtentry$$00000005 c_p.l(__rtentry5.o)
+ 0x0083251a 0x0083251a 0x00000000 Code RO 2432 .ARM.Collect$$rtentry$$00000009 c_p.l(__rtentry2.o)
+ 0x0083251a 0x0083251a 0x00000004 Code RO 2433 .ARM.Collect$$rtentry$$0000000A c_p.l(__rtentry2.o)
+ 0x0083251e 0x0083251e 0x00000000 Code RO 2435 .ARM.Collect$$rtentry$$0000000C c_p.l(__rtentry2.o)
+ 0x0083251e 0x0083251e 0x00000008 Code RO 2436 .ARM.Collect$$rtentry$$0000000D c_p.l(__rtentry2.o)
+ 0x00832526 0x00832526 0x00000002 PAD
+ 0x00832528 0x00832528 0x00000004 Code RO 2445 .ARM.Collect$$rtentry$$00002716 c_p.l(__rtentry5.o)
+ 0x0083252c 0x0083252c 0x000003d8 Code RO 15 .app.flash.text system_rtl876x.o
+ 0x00832904 0x00832904 0x00000054 Code RO 3 .text startup_rtl876x.o
+ 0x00832958 0x00832958 0x000001dc Code RO 17 .text system_rtl876x.o
+ 0x00832b34 0x00832b34 0x00000194 Code RO 262 .text rtl876x_gpio.o
+ 0x00832cc8 0x00832cc8 0x000002f8 Code RO 285 .text rtl876x_ir.o
+ 0x00832fc0 0x00832fc0 0x000001a0 Code RO 308 .text rtl876x_keyscan.o
+ 0x00833160 0x00833160 0x0000025c Code RO 331 .text rtl876x_rtc.o
+ 0x008333bc 0x008333bc 0x00000344 Code RO 358 .text rtl876x_codec.o
+ 0x00833700 0x00833700 0x00000130 Code RO 382 .text rtl876x_i2s.o
+ 0x00833830 0x00833830 0x00000368 Code RO 405 .text rtl876x_pinmux.o
+ 0x00833b98 0x00833b98 0x000000c8 Code RO 429 .text rtl876x_nvic.o
+ 0x00833c60 0x00833c60 0x00000310 Code RO 452 .text rtl876x_rcc.o
+ 0x00833f70 0x00833f70 0x0000019c Code RO 472 .text rtl876x_tim.o
+ 0x0083410c 0x0083410c 0x00000334 Code RO 492 .text rtl876x_gdma.o
+ 0x00834440 0x00834440 0x00000254 Code RO 515 .text rtl876x_uart.o
+ 0x00834694 0x00834694 0x0000030c Code RO 538 .text rtl876x_adc.o
+ 0x008349a0 0x008349a0 0x0000024c Code RO 565 .text rtl876x_lpc.o
+ 0x00834bec 0x00834bec 0x00000228 Code RO 589 .text rtl876x_aon_wdg.o
+ 0x00834e14 0x00834e14 0x0000026c Code RO 613 .text dis.o
+ 0x00835080 0x00835080 0x0000016c Code RO 675 .text bas.o
+ 0x008351ec 0x008351ec 0x00000268 Code RO 706 .text hids_rmc.o
+ 0x00835454 0x00835454 0x00000110 Code RO 735 .text vendor_service.o
+ 0x00835564 0x00835564 0x000001ac Code RO 803 .text atvv_service.o
+ 0x00835710 0x00835710 0x00000104 Code RO 833 .text ir_service.o
+ 0x00835814 0x00835814 0x00000d70 Code RO 863 .text dfu_service.o
+ 0x00836584 0x00836584 0x00000480 Code RO 900 .text ota_service.o
+ 0x00836a04 0x00836a04 0x0000012c Code RO 947 .text fms.o
+ 0x00836b30 0x00836b30 0x000003b8 Code RO 983 .text main.o
+ 0x00836ee8 0x00836ee8 0x00000f10 Code RO 1113 .text rcu_application.o
+ 0x00837df8 0x00837df8 0x00000afc Code RO 1171 .text rcu_gap.o
+ 0x008388f4 0x008388f4 0x00000258 Code RO 1200 .text swtimer.o
+ 0x00838b4c 0x00838b4c 0x00000050 Code RO 1236 .text app_task.o
+ 0x00838b9c 0x00838b9c 0x00000060 Code RO 1279 .text reset_watch_dog_timer.o
+ 0x00838bfc 0x00838bfc 0x0000070c Code RO 1308 .text privacy_mgnt.o
+ 0x00839308 0x00839308 0x0000007c Code RO 1333 .text overlay_mgr.o
+ 0x00839384 0x00839384 0x00000094 Code RO 1360 .text loop_queue.o
+ 0x00839418 0x00839418 0x00000434 Code RO 1389 .text rcu_dtm_app.o
+ 0x0083984c 0x0083984c 0x0000015c Code RO 1444 .text rtc_driver.o
+ 0x008399a8 0x008399a8 0x0000071c Code RO 1539 .text dfu_flash.o
+ 0x0083a0c4 0x0083a0c4 0x000000c4 Code RO 1569 .text keyscan_driver.o
+ 0x0083a188 0x0083a188 0x00000bcc Code RO 1611 .text key_handle.o
+ 0x0083ad54 0x0083ad54 0x000002dc Code RO 1658 .text voice_driver.o
+ 0x0083b030 0x0083b030 0x00000b24 Code RO 1695 .text voice.o
+ 0x0083bb54 0x0083bb54 0x0000035c Code RO 1740 .text ir_send_driver.o
+ 0x0083beb0 0x0083beb0 0x0000044c Code RO 1768 .text ir_send_handle.o
+ 0x0083c2fc 0x0083c2fc 0x000001a8 Code RO 1809 .text ir_protocol_nec.o
+ 0x0083c4a4 0x0083c4a4 0x000007c0 Code RO 1832 .text ir_service_handle.o
+ 0x0083cc64 0x0083cc64 0x00000114 Code RO 1867 .text led_driver.o
+ 0x0083cd78 0x0083cd78 0x00000160 Code RO 1898 .text led_pwm_driver.o
+ 0x0083ced8 0x0083ced8 0x00000188 Code RO 1922 .text buzzer_driver.o
+ 0x0083d060 0x0083d060 0x000002a4 Code RO 1951 .text fms_service_handle.o
+ 0x0083d304 0x0083d304 0x000004a4 Code RO 1983 .text battery_driver.o
+ 0x0083d7a8 0x0083d7a8 0x0000076c Code RO 2111 .text app_custom.o
+ 0x0083df14 0x0083df14 0x000000ac Code RO 2148 .text frm_vpk_hal_sflash.o
+ 0x0083dfc0 0x0083dfc0 0x000010cc Code RO 2192 .text gap_utils.lib(gap_lib_system_call.o)
+ 0x0083f08c 0x0083f08c 0x0000030c Code RO 2195 .text adc.lib(adc_lib.o)
+ 0x0083f398 0x0083f398 0x00000030 Code RO 2228 .text c_p.l(llmul.o)
+ 0x0083f3c8 0x0083f3c8 0x00000102 Code RO 2230 .text c_p.l(lludiv.o)
+ 0x0083f4ca 0x0083f4ca 0x00000002 PAD
+ 0x0083f4cc 0x0083f4cc 0x00000024 Code RO 2232 .text c_p.l(vsprintf.o)
+ 0x0083f4f0 0x0083f4f0 0x0000003c Code RO 2235 .text c_p.l(rand.o)
+ 0x0083f52c 0x0083f52c 0x0000015a Code RO 2239 .text c_p.l(aeabi_sdiv.o)
+ 0x0083f686 0x0083f686 0x00000002 PAD
+ 0x0083f688 0x0083f688 0x0000007c Code RO 2245 .text fz_ps.l(d2f.o)
+ 0x0083f704 0x0083f704 0x00000358 Code RO 2247 .text fz_ps.l(daddsub.o)
+ 0x0083fa5c 0x0083fa5c 0x00000448 Code RO 2249 .text fz_ps.l(ddiv.o)
+ 0x0083fea4 0x0083fea4 0x00000048 Code RO 2252 .text fz_ps.l(dfixui.o)
+ 0x0083feec 0x0083feec 0x00000058 Code RO 2254 .text fz_ps.l(dflti.o)
+ 0x0083ff44 0x0083ff44 0x00000248 Code RO 2256 .text fz_ps.l(dmul.o)
+ 0x0084018c 0x0084018c 0x00000054 Code RO 2258 .text fz_ps.l(f2d.o)
+ 0x008401e0 0x008401e0 0x00000160 Code RO 2266 .text fz_ps.l(fdiv.o)
+ 0x00840340 0x00840340 0x00000030 Code RO 2269 .text fz_ps.l(ffixui.o)
+ 0x00840370 0x00840370 0x0000005e Code RO 2271 .text fz_ps.l(fflti.o)
+ 0x008403ce 0x008403ce 0x0000004e Code RO 2286 .text c_p.l(_printf_pad.o)
+ 0x0084041c 0x0084041c 0x00000024 Code RO 2288 .text c_p.l(_printf_truncate.o)
+ 0x00840440 0x00840440 0x00000052 Code RO 2290 .text c_p.l(_printf_str.o)
+ 0x00840492 0x00840492 0x00000002 PAD
+ 0x00840494 0x00840494 0x0000006c Code RO 2292 .text c_p.l(_printf_dec.o)
+ 0x00840500 0x00840500 0x00000026 Code RO 2294 .text c_p.l(_printf_charcount.o)
+ 0x00840526 0x00840526 0x00000002 PAD
+ 0x00840528 0x00840528 0x00000030 Code RO 2296 .text c_p.l(_printf_char_common.o)
+ 0x00840558 0x00840558 0x0000000a Code RO 2298 .text c_p.l(_sputc.o)
+ 0x00840562 0x00840562 0x00000002 PAD
+ 0x00840564 0x00840564 0x000000bc Code RO 2300 .text c_p.l(_printf_wctomb.o)
+ 0x00840620 0x00840620 0x00000070 Code RO 2303 .text c_p.l(_printf_longlong_dec.o)
+ 0x00840690 0x00840690 0x00000070 Code RO 2309 .text c_p.l(_printf_oct_int_ll.o)
+ 0x00840700 0x00840700 0x00000098 Code RO 2329 .text c_p.l(_printf_hex_int_ll_ptr.o)
+ 0x00840798 0x00840798 0x00000188 Code RO 2349 .text c_p.l(__printf_flags_ss_wp.o)
+ 0x00840920 0x00840920 0x0000007a Code RO 2451 .text c_p.l(lludiv10.o)
+ 0x0084099a 0x0084099a 0x000000b0 Code RO 2453 .text c_p.l(_printf_intcommon.o)
+ 0x00840a4a 0x00840a4a 0x00000002 PAD
+ 0x00840a4c 0x00840a4c 0x00000418 Code RO 2455 .text c_p.l(_printf_fp_dec.o)
+ 0x00840e64 0x00840e64 0x000002d8 Code RO 2457 .text c_p.l(_printf_fp_hex.o)
+ 0x0084113c 0x0084113c 0x0000002e Code RO 2462 .text c_p.l(_printf_char.o)
+ 0x0084116a 0x0084116a 0x0000002e Code RO 2464 .text c_p.l(_printf_wchar.o)
+ 0x00841198 0x00841198 0x00000040 Code RO 2467 .text c_p.l(_wcrtomb.o)
+ 0x008411d8 0x008411d8 0x00000028 Code RO 2469 .text c_p.l(rtudiv10.o)
+ 0x00841200 0x00841200 0x00000010 Code RO 2475 .text c_p.l(rt_ctype_table.o)
+ 0x00841210 0x00841210 0x00000008 Code RO 2477 .text c_p.l(rt_locale.o)
+ 0x00841218 0x00841218 0x00000088 Code RO 2482 .text c_p.l(_printf_fp_infnan.o)
+ 0x008412a0 0x008412a0 0x000000d8 Code RO 2484 .text c_p.l(bigflt0.o)
+ 0x00841378 0x00841378 0x00000580 Code RO 2487 .text c_p.l(btod.o)
+ 0x008418f8 0x008418f8 0x00000088 Code RO 2532 .text c_p.l(strcmp.o)
+ 0x00841980 0x00841980 0x00000030 Code RO 2489 i.__ARM_common_ll_muluu c_p.l(btod.o)
+ 0x008419b0 0x008419b0 0x0000001a Code RO 635 i.__ARM_common_switch8 dis.o
+ 0x008419ca 0x008419ca 0x00000002 PAD
+ 0x008419cc 0x008419cc 0x0000002c Code RO 2510 i.__ARM_fpclassify m_ps.l(fpclassify.o)
+ 0x008419f8 0x008419f8 0x0000000e Code RO 2342 i._is_digit c_p.l(__printf_wp.o)
+ 0x00841a06 0x00841a06 0x00000002 PAD
+ 0x00841a08 0x00841a08 0x00000138 Code RO 2224 i.ima_adpcm_encode ima_adpcm_lib.lib(ima_adpcm_enc.o)
+ 0x00841b40 0x00841b40 0x0000002c Code RO 2492 locale$$code c_p.l(lc_numeric_c.o)
+ 0x00841b6c 0x00841b6c 0x0000002c Code RO 2522 locale$$code c_p.l(lc_ctype_c.o)
+ 0x00841b98 0x00841b98 0x0000008c Code RO 2260 x$fpl$fadd fz_ps.l(faddsub.o)
+ 0x00841c24 0x00841c24 0x000000b0 Code RO 2273 x$fpl$fmul fz_ps.l(fmul.o)
+ 0x00841cd4 0x00841cd4 0x000000d0 Code RO 2262 x$fpl$fsub fz_ps.l(faddsub.o)
+ 0x00841da4 0x00841da4 0x00000010 Code RO 2420 x$fpl$printf1 fz_ps.l(printf1.o)
+ 0x00841db4 0x00841db4 0x00000010 Code RO 2422 x$fpl$printf2 fz_ps.l(printf2.o)
+ 0x00841dc4 0x00841dc4 0x00000000 Code RO 2428 x$fpl$usenofp fz_ps.l(usenofp.o)
+ 0x00841dc4 0x00841dc4 0x0000000c Data RO 21 .constdata system_rtl876x.o
+ 0x00841dd0 0x00841dd0 0x00000100 Data RO 22 .constdata system_rtl876x.o
+ 0x00841ed0 0x00841ed0 0x0000009c Data RO 406 .constdata rtl876x_pinmux.o
+ 0x00841f6c 0x00841f6c 0x00000220 Data RO 616 .constdata dis.o
+ 0x0084218c 0x0084218c 0x0000007c Data RO 678 .constdata bas.o
+ 0x00842208 0x00842208 0x00000220 Data RO 709 .constdata hids_rmc.o
+ 0x00842428 0x00842428 0x00000010 Data RO 739 .constdata vendor_service.o
+ 0x00842438 0x00842438 0x000000b4 Data RO 740 .constdata vendor_service.o
+ 0x008424ec 0x008424ec 0x00000010 Data RO 806 .constdata atvv_service.o
+ 0x008424fc 0x008424fc 0x00000108 Data RO 807 .constdata atvv_service.o
+ 0x00842604 0x00842604 0x00000010 Data RO 837 .constdata ir_service.o
+ 0x00842614 0x00842614 0x0000015c Data RO 838 .constdata ir_service.o
+ 0x00842770 0x00842770 0x00000010 Data RO 866 .constdata dfu_service.o
+ 0x00842780 0x00842780 0x0000000c Data RO 867 .constdata dfu_service.o
+ 0x0084278c 0x0084278c 0x00000010 Data RO 904 .constdata ota_service.o
+ 0x0084279c 0x0084279c 0x000002c8 Data RO 905 .constdata ota_service.o
+ 0x00842a64 0x00842a64 0x00000010 Data RO 950 .constdata fms.o
+ 0x00842a74 0x00842a74 0x000000b4 Data RO 951 .constdata fms.o
+ 0x00842b28 0x00842b28 0x0000001d Data RO 1116 .constdata rcu_application.o
+ 0x00842b45 0x00842b45 0x0000000d Data RO 1174 .constdata rcu_gap.o
+ 0x00842b52 0x00842b52 0x0000002f Data RO 1239 .constdata app_task.o
+ 0x00842b81 0x00842b81 0x0000000d Data RO 1311 .constdata privacy_mgnt.o
+ 0x00842b8e 0x00842b8e 0x00000010 Data RO 1361 .constdata loop_queue.o
+ 0x00842b9e 0x00842b9e 0x00000002 PAD
+ 0x00842ba0 0x00842ba0 0x000001ac Data RO 1614 .constdata key_handle.o
+ 0x00842d4c 0x00842d4c 0x00000003 Data RO 1615 .constdata key_handle.o
+ 0x00842d4f 0x00842d4f 0x00000008 Data RO 1616 .constdata key_handle.o
+ 0x00842d57 0x00842d57 0x00000003 Data RO 1617 .constdata key_handle.o
+ 0x00842d5a 0x00842d5a 0x0000002a Data RO 1618 .constdata key_handle.o
+ 0x00842d84 0x00842d84 0x00000008 Data RO 1619 .constdata key_handle.o
+ 0x00842d8c 0x00842d8c 0x0000000c Data RO 1620 .constdata key_handle.o
+ 0x00842d98 0x00842d98 0x00000008 Data RO 1621 .constdata key_handle.o
+ 0x00842da0 0x00842da0 0x0000001f Data RO 1698 .constdata voice.o
+ 0x00842dbf 0x00842dbf 0x00000001 PAD
+ 0x00842dc0 0x00842dc0 0x00000070 Data RO 1810 .constdata ir_protocol_nec.o
+ 0x00842e30 0x00842e30 0x00000028 Data RO 1835 .constdata ir_service_handle.o
+ 0x00842e58 0x00842e58 0x000000d0 Data RO 1870 .constdata led_driver.o
+ 0x00842f28 0x00842f28 0x00000010 Data RO 1900 .constdata led_pwm_driver.o
+ 0x00842f38 0x00842f38 0x00000024 Data RO 2112 .constdata app_custom.o
+ 0x00842f5c 0x00842f5c 0x00000080 Data RO 2250 .constdata fz_ps.l(ddiv.o)
+ 0x00842fdc 0x00842fdc 0x00000040 Data RO 2267 .constdata fz_ps.l(fdiv.o)
+ 0x0084301c 0x0084301c 0x00000008 Data RO 2301 .constdata c_p.l(_printf_wctomb.o)
+ 0x00843024 0x00843024 0x00000028 Data RO 2330 .constdata c_p.l(_printf_hex_int_ll_ptr.o)
+ 0x0084304c 0x0084304c 0x00000011 Data RO 2350 .constdata c_p.l(__printf_flags_ss_wp.o)
+ 0x0084305d 0x0084305d 0x00000026 Data RO 2458 .constdata c_p.l(_printf_fp_hex.o)
+ 0x00843083 0x00843083 0x00000001 PAD
+ 0x00843084 0x00843084 0x00000094 Data RO 2485 .constdata c_p.l(bigflt0.o)
+ 0x00843118 0x00843118 0x00000200 Data RO 23 .conststring system_rtl876x.o
+ 0x00843318 0x00843318 0x00000067 Data RO 868 .conststring dfu_service.o
+ 0x0084337f 0x0084337f 0x00000001 PAD
+ 0x00843380 0x00843380 0x00000019 Data RO 1335 .conststring overlay_mgr.o
+ 0x00843399 0x00843399 0x00000003 PAD
+ 0x0084339c 0x0084339c 0x0000000a Data RO 2114 .conststring app_custom.o
+ 0x008433a6 0x008433a6 0x00000002 PAD
+ 0x008433a8 0x008433a8 0x00000086 Data RO 2149 .conststring frm_vpk_hal_sflash.o
+ 0x0084342e 0x0084342e 0x00000002 PAD
+ 0x00843430 0x00843430 0x00000000 Data RO 2563 Region$$Table anon$$obj.o
+ 0x00843430 0x00843430 0x0000001c Data RO 2491 locale$$data c_p.l(lc_numeric_c.o)
+ 0x0084344c 0x0084344c 0x00000110 Data RO 2521 locale$$data c_p.l(lc_ctype_c.o)
+
+
+
+ Load Region LOAD_APP_TRACE (Base: 0x08800000, Size: 0x00007198, Max: 0x00400000, ABSOLUTE)
+
+ Execution Region App.trace (Exec base: 0x08800000, Load base: 0x08800000, Size: 0x00007198, Max: 0x00400000, ABSOLUTE)
+
+ Exec Addr Load Addr Size Type Attr Idx E Section Name Object
+
+ 0x08800000 0x08800000 0x00000112 Data RO 18 .TRACE system_rtl876x.o
+ 0x08800112 0x08800112 0x00000002 PAD
+ 0x08800114 0x08800114 0x0000002a Data RO 202 .TRACE rtl876x_io_dlps.o
+ 0x0880013e 0x0880013e 0x00000002 PAD
+ 0x08800140 0x08800140 0x000000ae Data RO 614 .TRACE dis.o
+ 0x088001ee 0x088001ee 0x00000002 PAD
+ 0x088001f0 0x088001f0 0x000000de Data RO 676 .TRACE bas.o
+ 0x088002ce 0x088002ce 0x00000002 PAD
+ 0x088002d0 0x088002d0 0x0000010a Data RO 707 .TRACE hids_rmc.o
+ 0x088003da 0x088003da 0x00000002 PAD
+ 0x088003dc 0x088003dc 0x00000095 Data RO 736 .TRACE vendor_service.o
+ 0x08800471 0x08800471 0x00000003 PAD
+ 0x08800474 0x08800474 0x0000012b Data RO 766 .TRACE voice_service.o
+ 0x0880059f 0x0880059f 0x00000001 PAD
+ 0x088005a0 0x088005a0 0x00000136 Data RO 804 .TRACE atvv_service.o
+ 0x088006d6 0x088006d6 0x00000002 PAD
+ 0x088006d8 0x088006d8 0x00000089 Data RO 834 .TRACE ir_service.o
+ 0x08800761 0x08800761 0x00000003 PAD
+ 0x08800764 0x08800764 0x000009ee Data RO 864 .TRACE dfu_service.o
+ 0x08801152 0x08801152 0x00000002 PAD
+ 0x08801154 0x08801154 0x000002f1 Data RO 901 .TRACE ota_service.o
+ 0x08801445 0x08801445 0x00000003 PAD
+ 0x08801448 0x08801448 0x000000ae Data RO 948 .TRACE fms.o
+ 0x088014f6 0x088014f6 0x00000002 PAD
+ 0x088014f8 0x088014f8 0x0000035a Data RO 984 .TRACE main.o
+ 0x08801852 0x08801852 0x00000002 PAD
+ 0x08801854 0x08801854 0x000011a5 Data RO 1114 .TRACE rcu_application.o
+ 0x088029f9 0x088029f9 0x00000003 PAD
+ 0x088029fc 0x088029fc 0x000006dc Data RO 1172 .TRACE rcu_gap.o
+ 0x088030d8 0x088030d8 0x000002e6 Data RO 1201 .TRACE swtimer.o
+ 0x088033be 0x088033be 0x00000002 PAD
+ 0x088033c0 0x088033c0 0x00000038 Data RO 1237 .TRACE app_task.o
+ 0x088033f8 0x088033f8 0x0000003a Data RO 1280 .TRACE reset_watch_dog_timer.o
+ 0x08803432 0x08803432 0x00000002 PAD
+ 0x08803434 0x08803434 0x000005af Data RO 1309 .TRACE privacy_mgnt.o
+ 0x088039e3 0x088039e3 0x00000001 PAD
+ 0x088039e4 0x088039e4 0x000002f5 Data RO 1390 .TRACE rcu_dtm_app.o
+ 0x08803cd9 0x08803cd9 0x00000003 PAD
+ 0x08803cdc 0x08803cdc 0x00000053 Data RO 1416 .TRACE rcu_link_mgr.o
+ 0x08803d2f 0x08803d2f 0x00000001 PAD
+ 0x08803d30 0x08803d30 0x000000df Data RO 1445 .TRACE rtc_driver.o
+ 0x08803e0f 0x08803e0f 0x00000001 PAD
+ 0x08803e10 0x08803e10 0x000003ec Data RO 1540 .TRACE dfu_flash.o
+ 0x088041fc 0x088041fc 0x00000138 Data RO 1570 .TRACE keyscan_driver.o
+ 0x08804334 0x08804334 0x00000a50 Data RO 1612 .TRACE key_handle.o
+ 0x08804d84 0x08804d84 0x0000010e Data RO 1659 .TRACE voice_driver.o
+ 0x08804e92 0x08804e92 0x00000002 PAD
+ 0x08804e94 0x08804e94 0x00000cff Data RO 1696 .TRACE voice.o
+ 0x08805b93 0x08805b93 0x00000001 PAD
+ 0x08805b94 0x08805b94 0x0000033e Data RO 1741 .TRACE ir_send_driver.o
+ 0x08805ed2 0x08805ed2 0x00000002 PAD
+ 0x08805ed4 0x08805ed4 0x00000245 Data RO 1769 .TRACE ir_send_handle.o
+ 0x08806119 0x08806119 0x00000003 PAD
+ 0x0880611c 0x0880611c 0x000007fe Data RO 1833 .TRACE ir_service_handle.o
+ 0x0880691a 0x0880691a 0x00000002 PAD
+ 0x0880691c 0x0880691c 0x00000022 Data RO 1868 .TRACE led_driver.o
+ 0x0880693e 0x0880693e 0x00000002 PAD
+ 0x08806940 0x08806940 0x0000009d Data RO 1923 .TRACE buzzer_driver.o
+ 0x088069dd 0x088069dd 0x00000003 PAD
+ 0x088069e0 0x088069e0 0x000002ff Data RO 1952 .TRACE fms_service_handle.o
+ 0x08806cdf 0x08806cdf 0x00000001 PAD
+ 0x08806ce0 0x08806ce0 0x000004ad Data RO 1984 .TRACE battery_driver.o
+ 0x0880718d 0x0880718d 0x00000003 PAD
+ 0x08807190 0x08807190 0x00000006 Data RO 2170 .TRACE frm_vpk_log.o
+
+
+==============================================================================
+
+Image component sizes
+
+
+ Code (inc. data) RO Data RW Data ZI Data Debug Object Name
+
+ 1900 194 46 4 0 7829 app_custom.o
+ 436 50 103 0 16 4116 app_task.o
+ 428 32 590 0 74 7917 atvv_service.o
+ 364 26 346 0 8 4990 bas.o
+ 1448 200 1197 0 6 7419 battery_driver.o
+ 392 30 157 0 12 5741 buzzer_driver.o
+ 1820 204 1004 1 12 10965 dfu_flash.o
+ 3440 272 2673 168 2220 13071 dfu_service.o
+ 646 60 718 46 132 33213 dis.o
+ 300 24 370 0 8 6491 fms.o
+ 724 86 767 2 8 6277 fms_service_handle.o
+ 172 70 134 0 0 1286 frm_vpk_hal_sflash.o
+ 60 8 6 0 0 812 frm_vpk_log.o
+ 616 34 810 8 12 7381 hids_rmc.o
+ 424 26 112 0 0 3704 ir_protocol_nec.o
+ 1108 94 830 0 8 6824 ir_send_driver.o
+ 1100 28 581 1 1628 16177 ir_send_handle.o
+ 260 16 501 0 4 5217 ir_service.o
+ 1984 128 2086 20 2568 16049 ir_service_handle.o
+ 3296 266 3152 72 552 22132 key_handle.o
+ 920 76 312 14 48 11529 keyscan_driver.o
+ 520 52 242 0 40 5127 led_driver.o
+ 352 12 16 0 2 3605 led_pwm_driver.o
+ 826 6 16 0 0 6404 loop_queue.o
+ 1148 106 858 4 0 39034 main.o
+ 1152 60 1481 0 88 19424 ota_service.o
+ 124 10 25 108 8 4332 overlay_mgr.o
+ 1804 78 1468 2 16 10285 privacy_mgnt.o
+ 4068 360 4546 0 180 20704 rcu_application.o
+ 1076 58 757 1 10 10867 rcu_dtm_app.o
+ 2812 184 1769 14 96 10204 rcu_gap.o
+ 0 0 83 0 0 1880 rcu_link_mgr.o
+ 164 24 58 0 0 5580 reset_watch_dog_timer.o
+ 436 32 223 0 8 11940 rtc_driver.o
+ 780 10 0 0 0 12707 rtl876x_adc.o
+ 552 16 0 0 1 2397 rtl876x_aon_wdg.o
+ 836 20 0 0 0 16196 rtl876x_codec.o
+ 820 24 0 0 0 10940 rtl876x_gdma.o
+ 404 18 0 0 0 7912 rtl876x_gpio.o
+ 304 16 0 0 0 13571 rtl876x_i2s.o
+ 1132 68 42 0 304 33862 rtl876x_io_dlps.o
+ 760 32 0 0 0 22428 rtl876x_ir.o
+ 416 18 0 0 0 7009 rtl876x_keyscan.o
+ 588 26 0 0 1 13754 rtl876x_lpc.o
+ 200 20 0 0 0 11916 rtl876x_nvic.o
+ 872 20 156 0 0 8171 rtl876x_pinmux.o
+ 784 48 0 0 0 3441 rtl876x_rcc.o
+ 604 24 0 0 1 11406 rtl876x_rtc.o
+ 412 20 0 0 0 3668 rtl876x_tim.o
+ 596 30 0 0 0 9845 rtl876x_uart.o
+ 92 72 232 0 0 980 startup_rtl876x.o
+ 840 296 742 0 32 4677 swtimer.o
+ 1936 378 2078 0 20 80553 system_rtl876x.o
+ 272 20 345 0 20 4661 vendor_service.o
+ 2924 212 3358 0 16 16157 voice.o
+ 840 62 270 0 1128 14018 voice_driver.o
+ 0 0 299 0 0 10712 voice_service.o
+
+ ----------------------------------------------------------------------
+ 53288 4356 35632 472 9296 669507 Object Totals
+ 0 0 0 0 0 0 (incl. Generated)
+ 4 0 73 7 9 0 (incl. Padding)
+
+ ----------------------------------------------------------------------
+
+ Code (inc. data) RO Data RW Data ZI Data Debug Library Member Name
+
+ 780 24 0 50 84 8547 adc_lib.o
+ 8 0 0 0 0 68 __main.o
+ 392 6 17 0 0 76 __printf_flags_ss_wp.o
+ 14 0 0 0 0 60 __printf_wp.o
+ 0 0 0 0 0 0 __rtentry.o
+ 12 0 0 0 0 0 __rtentry2.o
+ 8 4 0 0 0 0 __rtentry5.o
+ 10 0 0 0 0 0 _printf_a.o
+ 10 0 0 0 0 0 _printf_c.o
+ 46 0 0 0 0 100 _printf_char.o
+ 48 6 0 0 0 88 _printf_char_common.o
+ 38 0 0 0 0 60 _printf_charcount.o
+ 10 0 0 0 0 0 _printf_d.o
+ 108 18 0 0 0 76 _printf_dec.o
+ 10 0 0 0 0 0 _printf_e.o
+ 10 0 0 0 0 0 _printf_f.o
+ 1048 14 0 0 0 176 _printf_fp_dec.o
+ 728 10 38 0 0 84 _printf_fp_hex.o
+ 136 16 0 0 0 76 _printf_fp_infnan.o
+ 10 0 0 0 0 0 _printf_g.o
+ 152 4 40 0 0 148 _printf_hex_int_ll_ptr.o
+ 10 0 0 0 0 0 _printf_i.o
+ 176 0 0 0 0 84 _printf_intcommon.o
+ 10 0 0 0 0 0 _printf_l.o
+ 10 0 0 0 0 0 _printf_lc.o
+ 10 0 0 0 0 0 _printf_ll.o
+ 10 0 0 0 0 0 _printf_lld.o
+ 10 0 0 0 0 0 _printf_lli.o
+ 10 0 0 0 0 0 _printf_llo.o
+ 10 0 0 0 0 0 _printf_llu.o
+ 10 0 0 0 0 0 _printf_llx.o
+ 112 18 0 0 0 76 _printf_longlong_dec.o
+ 10 0 0 0 0 0 _printf_ls.o
+ 10 0 0 0 0 0 _printf_n.o
+ 10 0 0 0 0 0 _printf_o.o
+ 112 10 0 0 0 112 _printf_oct_int_ll.o
+ 10 0 0 0 0 0 _printf_p.o
+ 78 0 0 0 0 100 _printf_pad.o
+ 2 0 0 0 0 0 _printf_percent.o
+ 4 0 0 0 0 0 _printf_percent_end.o
+ 10 0 0 0 0 0 _printf_s.o
+ 82 0 0 0 0 72 _printf_str.o
+ 36 0 0 0 0 76 _printf_truncate.o
+ 10 0 0 0 0 0 _printf_u.o
+ 46 0 0 0 0 100 _printf_wchar.o
+ 188 6 8 0 0 80 _printf_wctomb.o
+ 10 0 0 0 0 0 _printf_x.o
+ 10 0 0 0 0 60 _sputc.o
+ 64 0 0 0 0 72 _wcrtomb.o
+ 346 0 0 0 0 92 aeabi_sdiv.o
+ 216 6 148 0 0 80 bigflt0.o
+ 1456 30 0 0 0 336 btod.o
+ 44 10 272 0 0 76 lc_ctype_c.o
+ 44 10 28 0 0 76 lc_numeric_c.o
+ 2 0 0 0 0 0 libinit.o
+ 34 0 0 0 0 0 libinit2.o
+ 48 0 0 0 0 72 llmul.o
+ 258 0 0 0 0 88 lludiv.o
+ 122 0 0 0 0 72 lludiv10.o
+ 60 12 0 0 228 88 rand.o
+ 16 4 0 0 0 76 rt_ctype_table.o
+ 8 4 0 0 20 68 rt_locale.o
+ 40 0 0 0 0 60 rtudiv10.o
+ 136 4 0 0 0 72 strcmp.o
+ 36 4 0 0 0 68 vsprintf.o
+ 124 4 0 0 0 72 d2f.o
+ 856 20 0 0 0 208 daddsub.o
+ 1096 26 128 0 0 112 ddiv.o
+ 72 4 0 0 0 68 dfixui.o
+ 88 0 0 0 0 92 dflti.o
+ 584 26 0 0 0 84 dmul.o
+ 84 4 0 0 0 60 f2d.o
+ 348 8 0 0 0 160 faddsub.o
+ 352 10 64 0 0 92 fdiv.o
+ 48 0 0 0 0 60 ffixui.o
+ 94 0 0 0 0 92 fflti.o
+ 176 4 0 0 0 80 fmul.o
+ 16 4 0 0 0 76 printf1.o
+ 16 4 0 0 0 76 printf2.o
+ 0 0 0 0 0 0 usenofp.o
+ 4300 66 0 0 8 4568 gap_lib_system_call.o
+ 312 8 0 420 6 80 ima_adpcm_enc.o
+ 44 4 0 0 0 60 fpclassify.o
+
+ ----------------------------------------------------------------------
+ 16140 412 744 472 348 17755 Library Totals
+ 16 0 1 2 2 0 (incl. Padding)
+
+ ----------------------------------------------------------------------
+
+ Code (inc. data) RO Data RW Data ZI Data Debug Library Name
+
+ 780 24 0 50 84 8547 adc.lib
+ 6734 196 551 0 248 3168 c_p.l
+ 3954 114 192 0 0 1332 fz_ps.l
+ 4300 66 0 0 8 4568 gap_utils.lib
+ 312 8 0 420 6 80 ima_adpcm_lib.lib
+ 44 4 0 0 0 60 m_ps.l
+
+ ----------------------------------------------------------------------
+ 16140 412 744 472 348 17755 Library Totals
+
+ ----------------------------------------------------------------------
+
+==============================================================================
+
+
+ Code (inc. data) RO Data RW Data ZI Data Debug
+
+ 69428 4768 36376 944 9644 679466 Grand Totals
+ 69428 4768 36376 944 9644 679466 ELF Image Totals
+ 69428 4768 36376 944 0 0 ROM Totals
+
+==============================================================================
+
+ Total RO Size (Code + RO Data) 105804 ( 103.32kB)
+ Total RW Size (RW Data + ZI Data) 10588 ( 10.34kB)
+ Total ROM Size (Code + RO Data + RW Data) 106748 ( 104.25kB)
+
+==============================================================================
+
diff --git a/board/evb/google_rcu/mdk/Listings/startup_rtl876x.lst b/board/evb/google_rcu/mdk/Listings/startup_rtl876x.lst
new file mode 100644
index 0000000..9daa96e
--- /dev/null
+++ b/board/evb/google_rcu/mdk/Listings/startup_rtl876x.lst
@@ -0,0 +1,1642 @@
+
+
+
+ARM Macro Assembler Page 1
+
+
+ 1 00000000 #line 1 "..\\..\\..\\..\\src\\mcu\\rtl8
+76x\\arm\\startup_rtl876x.s"
+ 1 00000000
+ 2 00000000 EXPORT __initial_sp
+ 3 00000000 00203800
+ __initial_sp
+ EQU (0x200000 + 14 * 1024)
+ 4 00000000
+ 5 00000000 PRESERVE8
+ 6 00000000 THUMB
+ 7 00000000
+ 8 00000000 ; Vector Table Mapped to Address 0 at Reset
+ 9 00000000
+ 10 00000000 AREA VECTOR, DATA, READONLY
+ 11 00000000 EXPORT __Vectors
+ 12 00000000 EXPORT __Vectors_End
+ 13 00000000 EXPORT __Vectors_Size
+ 14 00000000
+ 15 00000000 00203800
+ __Vectors
+ DCD __initial_sp ; Top of Stack
+ 16 00000004 00000000 DCD Reset_Handler ; Reset Handler
+ 17 00000008 00000000 DCD NMI_Handler ; NMI Handler
+ 18 0000000C 00000000 DCD HardFault_Handler ; Hard Fault
+ Handler
+ 19 00000010 00000000 DCD MemManage_Handler
+ ; MPU Fault Handler
+
+ 20 00000014 00000000 DCD BusFault_Handler
+ ; Bus Fault Handler
+
+ 21 00000018 00000000 DCD UsageFault_Handler ; Usage Faul
+ t Handler
+ 22 0000001C 00000000 DCD 0 ; Reserved
+ 23 00000020 00000000 DCD 0 ; Reserved
+ 24 00000024 00000000 DCD 0 ; Reserved
+ 25 00000028 00000000 DCD 0 ; Reserved
+ 26 0000002C 00000000 DCD SVC_Handler ; SVCall Handler
+ 27 00000030 00000000 DCD 0 ; Reserved
+ 28 00000034 00000000 DCD 0 ; Reserved
+ 29 00000038 00000000 DCD PendSV_Handler ; PendSV Handler
+
+ 30 0000003C 00000000 DCD SysTick_Handler
+ ; SysTick Handler
+ 31 00000040
+ 32 00000040 ; External Interrupts
+ 33 00000040 00000000 DCD System_Handler ;[0] System On
+ interrupt
+ 34 00000044 00000000 DCD WDG_Handler ;[1] Watch dog glo
+ bal insterrupt
+ 35 00000048 00000000 DCD BTMAC_Handler ;[2] See Below T
+ able ( an Extension
+ of interrupt )
+ 36 0000004C 00000000 DCD Timer3_Handler ;[3] Timer3 glo
+ bal interrupt
+ 37 00000050 00000000 DCD Timer2_Handler ;[4] Timer2 glo
+ bal interrupt
+ 38 00000054 00000000 DCD HardFault_Handler ;[5] Platfor
+ m interrupt (platfo
+
+
+
+ARM Macro Assembler Page 2
+
+
+ rm error interrupt)
+
+ 39 00000058 00000000 DCD I2S0_TX_Handler ;[6] I2S0 TX i
+ nterrupt
+ 40 0000005C 00000000 DCD I2S0_RX_Handler ;[7] I2S0 RX i
+ nterrupt
+ 41 00000060 00000000 DCD Timer4_5_Handler ;[8] Timer[4:
+ 7] global interrupt
+
+ 42 00000064 00000000 DCD GPIO4_Handler ;[9] GPIO 4 inte
+ rrupt
+ 43 00000068 00000000 DCD GPIO5_Handler ;[10] GPIO 5 inte
+ rrupt
+ 44 0000006C 00000000 DCD UART1_Handler ;[11] Uart1 inter
+ rupt (default for
+ log)
+ 45 00000070 00000000 DCD UART0_Handler ;[12] Uart0 inter
+ rupt
+ 46 00000074 00000000 DCD RTC_Handler ;[13] Realtime coun
+ ter interrupt
+ 47 00000078 00000000 DCD SPI0_Handler ;[14] SPI0 interru
+ pt
+ 48 0000007C 00000000 DCD SPI1_Handler ;[15] SPI1 interru
+ pt
+ 49 00000080 00000000 DCD I2C0_Handler ;[16] I2C0 interru
+ pt
+ 50 00000084 00000000 DCD I2C1_Handler ;[17] I2C1 interru
+ pt
+ 51 00000088 00000000 DCD ADC_Handler ;[18] ADC global in
+ terrupt
+ 52 0000008C 00000000 DCD Peripheral_Handler ;[19] See Be
+ low Table ( an Exte
+ nsion of interrupt
+ )
+ 53 00000090 00000000 DCD GDMA0_Channel0_Handler ;[20] RT
+ K-DMA0 channel 0 gl
+ obal interrupt
+ 54 00000094 00000000 DCD GDMA0_Channel1_Handler ;[21] RT
+ K-DMA0 channel 1 gl
+ obal interrupt
+ 55 00000098 00000000 DCD GDMA0_Channel2_Handler ;[22] RT
+ K-DMA0 channel 2 gl
+ obal interrupt
+ 56 0000009C 00000000 DCD GDMA0_Channel3_Handler ;[23] RT
+ K-DMA0 channel 3 gl
+ obal interrupt
+ 57 000000A0 00000000 DCD Enhanced_Timer0_Handler ;[24] E
+ nhanced Timer0
+ 58 000000A4 00000000 DCD Enhanced_Timer1_Handler ;[25] E
+ nhanced Timer1
+ 59 000000A8 00000000 DCD GPIO_Group3_Handler ;[26] GPIO(
+ n*4)+3,n={0:7} glob
+ al interrupt
+ 60 000000AC 00000000 DCD GPIO_Group2_Handler ;[27] GPIO(
+ n*4)+2,n={0:7} glob
+ al interrupt
+ 61 000000B0 00000000 DCD IR_Handler ;[28] IR module glo
+ bal interrupt
+ 62 000000B4 00000000 DCD GPIO_Group1_Handler ;[29] GPIO(
+
+
+
+ARM Macro Assembler Page 3
+
+
+ n*4)+1,n={0:7}-{1}
+ global interrupt
+ 63 000000B8 00000000 DCD GPIO_Group0_Handler ;[30] GPIO(
+ n*4)+0,n={0:7}-{1}
+ global interrupt
+ 64 000000BC 00000000 DCD 0 ;[31] Reserved
+ 65 000000C0
+ 66 000000C0 ;Timer[4:5] interrupt
+ 67 000000C0 00000000 DCD Timer4_Handler ;8, 0, 48
+ 68 000000C4 00000000 DCD Timer5_Handler ;8, 1, 49
+ 69 000000C8
+ 70 000000C8 ;Peripheral Interrupts not special interrupt
+ 71 000000C8 ;Interrupt name, Interrupt status bit, Offset in vector
+ 72 000000C8 00000000 DCD SPI_Flash_Handler ;19, 0, 50
+ 73 000000CC 00000000 DCD Qdecode_Handler ;19, 1, 51
+ 74 000000D0 00000000 DCD Keyscan_Handler ;19, 2, 52
+ 75 000000D4 00000000 DCD SPI2W_Handler ;19, 3, 53
+ 76 000000D8 00000000 DCD LPCOMP_Handler ;19, 4, 54
+ 77 000000DC 00000000 DCD PTA_Mailbox_Handler ;19, 5, 55
+ 78 000000E0 00000000 DCD CAP_Touch_Handler ;19, 6, 56
+ 79 000000E4 00000000 DCD TRNG_Handler ;19, 9, 57
+ 80 000000E8 __Vectors_End
+ 81 000000E8
+ 82 000000E8 000000E8
+ __Vectors_Size
+ EQU __Vectors_End - __Vectors
+ 83 000000E8
+ 84 000000E8 AREA RESET, CODE, READONLY
+ 85 00000000
+ 86 00000000 ; Reset Handler
+ 87 00000000 Reset_Handler
+ PROC
+ 88 00000000 EXPORT Reset_Handler [WE
+AK]
+ 89 00000000 IMPORT SystemInit
+ 90 00000000 4800 LDR R0, =SystemInit
+ 91 00000002 4700 BX R0
+ 92 00000004
+ 93 00000004 ENDP ; end of Reset_Hand
+ ler
+ 94 00000004
+ 95 00000004
+ 96 00000004 00000000 AREA |.text|, CODE, READONLY
+ 97 00000000 Default_Handler
+ PROC
+ 98 00000000 EXPORT Default_Handler
+ [WEAK]
+ 99 00000000 EXPORT NMI_Handler
+ [WEAK]
+ 100 00000000 EXPORT HardFault_Handler
+ [WEAK]
+ 101 00000000 EXPORT MemManage_Handler
+ [WEAK]
+ 102 00000000 EXPORT BusFault_Handler
+ [WEAK]
+ 103 00000000 EXPORT UsageFault_Handler
+ [WEAK]
+ 104 00000000 EXPORT SVC_Handler
+ [WEAK]
+
+
+
+ARM Macro Assembler Page 4
+
+
+ 105 00000000 EXPORT PendSV_Handler
+ [WEAK]
+ 106 00000000 EXPORT SysTick_Handler
+ [WEAK]
+ 107 00000000 EXPORT System_Handler
+ [WEAK]
+ 108 00000000 EXPORT WDG_Handler
+ [WEAK]
+ 109 00000000 EXPORT BTMAC_Handler
+ [WEAK]
+ 110 00000000 EXPORT Timer3_Handler
+ [WEAK]
+ 111 00000000 EXPORT Timer2_Handler
+ [WEAK]
+ 112 00000000 EXPORT I2S0_TX_Handler
+ [WEAK]
+ 113 00000000 EXPORT I2S0_RX_Handler
+ [WEAK]
+ 114 00000000 EXPORT Timer4_5_Handler
+ [WEAK]
+ 115 00000000 EXPORT GPIO4_Handler
+ [WEAK]
+ 116 00000000 EXPORT GPIO5_Handler
+ [WEAK]
+ 117 00000000 EXPORT UART1_Handler
+ [WEAK]
+ 118 00000000 EXPORT UART0_Handler
+ [WEAK]
+ 119 00000000 EXPORT RTC_Handler
+ [WEAK]
+ 120 00000000 EXPORT SPI0_Handler
+ [WEAK]
+ 121 00000000 EXPORT SPI1_Handler
+ [WEAK]
+ 122 00000000 EXPORT I2C0_Handler
+ [WEAK]
+ 123 00000000 EXPORT I2C1_Handler
+ [WEAK]
+ 124 00000000 EXPORT ADC_Handler
+ [WEAK]
+ 125 00000000 EXPORT Peripheral_Handler
+ [WEAK]
+ 126 00000000 EXPORT GDMA0_Channel0_Handler
+ [WEAK]
+ 127 00000000 EXPORT GDMA0_Channel1_Handler
+ [WEAK]
+ 128 00000000 EXPORT GDMA0_Channel2_Handler
+ [WEAK]
+ 129 00000000 EXPORT GDMA0_Channel3_Handler
+ [WEAK]
+ 130 00000000 EXPORT Enhanced_Timer0_Handler
+ [WEAK]
+ 131 00000000 EXPORT Enhanced_Timer1_Handler
+ [WEAK]
+ 132 00000000 EXPORT GPIO_Group3_Handler
+ [WEAK]
+ 133 00000000 EXPORT GPIO_Group2_Handler
+ [WEAK]
+ 134 00000000 EXPORT IR_Handler
+
+
+
+ARM Macro Assembler Page 5
+
+
+ [WEAK]
+ 135 00000000 EXPORT GPIO_Group1_Handler
+ [WEAK]
+ 136 00000000 EXPORT GPIO_Group0_Handler
+ [WEAK]
+ 137 00000000
+ 138 00000000 ;Extension Interrupts
+ 139 00000000 EXPORT Timer4_Handler
+ [WEAK]
+ 140 00000000 EXPORT Timer5_Handler
+ [WEAK]
+ 141 00000000 EXPORT SPI_Flash_Handler
+ [WEAK]
+ 142 00000000 EXPORT Qdecode_Handler
+ [WEAK]
+ 143 00000000 EXPORT Keyscan_Handler
+ [WEAK]
+ 144 00000000 EXPORT SPI2W_Handler
+ [WEAK]
+ 145 00000000 EXPORT LPCOMP_Handler
+ [WEAK]
+ 146 00000000 EXPORT PTA_Mailbox_Handler
+ [WEAK]
+ 147 00000000 EXPORT CAP_Touch_Handler
+ [WEAK]
+ 148 00000000 EXPORT TRNG_Handler
+ [WEAK]
+ 149 00000000 EXPORT GPIO0_Handler
+ [WEAK]
+ 150 00000000 EXPORT GPIO1_Handler
+ [WEAK]
+ 151 00000000 EXPORT GPIO2_Handler
+ [WEAK]
+ 152 00000000 EXPORT GPIO3_Handler
+ [WEAK]
+ 153 00000000 EXPORT GPIO6_Handler
+ [WEAK]
+ 154 00000000 EXPORT GPIO7_Handler
+ [WEAK]
+ 155 00000000 EXPORT GPIO8_Handler
+ [WEAK]
+ 156 00000000 EXPORT GPIO9_Handler
+ [WEAK]
+ 157 00000000 EXPORT GPIO10_Handler
+ [WEAK]
+ 158 00000000 EXPORT GPIO11_Handler
+ [WEAK]
+ 159 00000000 EXPORT GPIO12_Handler
+ [WEAK]
+ 160 00000000 EXPORT GPIO13_Handler
+ [WEAK]
+ 161 00000000 EXPORT GPIO14_Handler
+ [WEAK]
+ 162 00000000 EXPORT GPIO15_Handler
+ [WEAK]
+ 163 00000000 EXPORT GPIO16_Handler
+ [WEAK]
+ 164 00000000 EXPORT GPIO17_Handler
+ [WEAK]
+
+
+
+ARM Macro Assembler Page 6
+
+
+ 165 00000000 EXPORT GPIO18_Handler
+ [WEAK]
+ 166 00000000 EXPORT GPIO19_Handler
+ [WEAK]
+ 167 00000000 EXPORT GPIO20_Handler
+ [WEAK]
+ 168 00000000 EXPORT GPIO21_Handler
+ [WEAK]
+ 169 00000000 EXPORT GPIO22_Handler
+ [WEAK]
+ 170 00000000 EXPORT GPIO23_Handler
+ [WEAK]
+ 171 00000000 EXPORT GPIO24_Handler
+ [WEAK]
+ 172 00000000 EXPORT GPIO25_Handler
+ [WEAK]
+ 173 00000000 EXPORT GPIO26_Handler
+ [WEAK]
+ 174 00000000 EXPORT GPIO27_Handler
+ [WEAK]
+ 175 00000000 EXPORT GPIO28_Handler
+ [WEAK]
+ 176 00000000 EXPORT GPIO29_Handler
+ [WEAK]
+ 177 00000000 EXPORT GPIO30_Handler
+ [WEAK]
+ 178 00000000 EXPORT GPIO31_Handler
+ [WEAK]
+ 179 00000000 NMI_Handler
+ 180 00000000 HardFault_Handler
+ 181 00000000 MemManage_Handler
+ 182 00000000 BusFault_Handler
+ 183 00000000 UsageFault_Handler
+ 184 00000000 SVC_Handler
+ 185 00000000 PendSV_Handler
+ 186 00000000 SysTick_Handler
+ 187 00000000 System_Handler
+ 188 00000000 WDG_Handler
+ 189 00000000 BTMAC_Handler
+ 190 00000000 Timer3_Handler
+ 191 00000000 Timer2_Handler
+ 192 00000000 I2S0_TX_Handler
+ 193 00000000 I2S0_RX_Handler
+ 194 00000000 Timer4_5_Handler
+ 195 00000000 GPIO4_Handler
+ 196 00000000 GPIO5_Handler
+ 197 00000000 UART1_Handler
+ 198 00000000 UART0_Handler
+ 199 00000000 RTC_Handler
+ 200 00000000 SPI0_Handler
+ 201 00000000 SPI1_Handler
+ 202 00000000 I2C0_Handler
+ 203 00000000 I2C1_Handler
+ 204 00000000 ADC_Handler
+ 205 00000000 Peripheral_Handler
+ 206 00000000 GDMA0_Channel0_Handler
+ 207 00000000 GDMA0_Channel1_Handler
+ 208 00000000 GDMA0_Channel2_Handler
+ 209 00000000 GDMA0_Channel3_Handler
+
+
+
+ARM Macro Assembler Page 7
+
+
+ 210 00000000 Enhanced_Timer0_Handler
+ 211 00000000 Enhanced_Timer1_Handler
+ 212 00000000 GPIO_Group3_Handler
+ 213 00000000 GPIO_Group2_Handler
+ 214 00000000 IR_Handler
+ 215 00000000 GPIO_Group1_Handler
+ 216 00000000 GPIO_Group0_Handler
+ 217 00000000
+ 218 00000000 ;Extension Interrupts
+ 219 00000000 Timer4_Handler
+ 220 00000000 Timer5_Handler
+ 221 00000000 SPI_Flash_Handler
+ 222 00000000 Qdecode_Handler
+ 223 00000000 Keyscan_Handler
+ 224 00000000 SPI2W_Handler
+ 225 00000000 LPCOMP_Handler
+ 226 00000000 PTA_Mailbox_Handler
+ 227 00000000 CAP_Touch_Handler
+ 228 00000000 TRNG_Handler
+ 229 00000000 GPIO0_Handler
+ 230 00000000 GPIO1_Handler
+ 231 00000000 GPIO2_Handler
+ 232 00000000 GPIO3_Handler
+ 233 00000000 GPIO6_Handler
+ 234 00000000 GPIO7_Handler
+ 235 00000000 GPIO8_Handler
+ 236 00000000 GPIO9_Handler
+ 237 00000000 GPIO10_Handler
+ 238 00000000 GPIO11_Handler
+ 239 00000000 GPIO12_Handler
+ 240 00000000 GPIO13_Handler
+ 241 00000000 GPIO14_Handler
+ 242 00000000 GPIO15_Handler
+ 243 00000000 GPIO16_Handler
+ 244 00000000 GPIO17_Handler
+ 245 00000000 GPIO18_Handler
+ 246 00000000 GPIO19_Handler
+ 247 00000000 GPIO20_Handler
+ 248 00000000 GPIO21_Handler
+ 249 00000000 GPIO22_Handler
+ 250 00000000 GPIO23_Handler
+ 251 00000000 GPIO24_Handler
+ 252 00000000 GPIO25_Handler
+ 253 00000000 GPIO26_Handler
+ 254 00000000 GPIO27_Handler
+ 255 00000000 GPIO28_Handler
+ 256 00000000 GPIO29_Handler
+ 257 00000000 GPIO30_Handler
+ 258 00000000 GPIO31_Handler
+ 259 00000000 IMPORT log_direct
+ 260 00000000 4811 LDR R0, =0x20000000
+ 261 00000002 4912 LDR R1, =DEFAULT_HANDLER_TXT
+ 262 00000004 F3EF 8205 MRS R2, IPSR
+ 263 00000008 4B11 LDR R3, =log_direct
+ 264 0000000A 4798 BLX R3
+ 265 0000000C E7FE B .
+ 266 0000000E
+ 267 0000000E ENDP
+ 268 0000000E
+
+
+
+ARM Macro Assembler Page 8
+
+
+ 269 0000000E
+ 270 0000000E ; User Initial Stack
+ 271 0000000E EXPORT __user_setup_stackheap
+ 272 0000000E __user_setup_stackheap
+ PROC
+ 273 0000000E 4770 BX LR
+ 274 00000010 ENDP
+ 275 00000010
+ 276 00000010 DEFAULT_HANDLER_TXT
+ 277 00000010 45 72 72
+ 6F 72 21
+ 20 50 6C
+ 65 61 73
+ 65 20 69
+ 6D 70 6C
+ 65 6D 65
+ 6E 74 20
+ 79 6F 75
+ 72 20 49
+ 53 52 20
+ 48 61 6E
+ 64 6C 65
+ 72 20 66
+ 6F 72 20
+ 49 52 51
+ 20 25 64
+ 21 0A 00 DCB "Error! Please implement your I
+SR Handler for IRQ %d!\n", 0
+ ; Null terminated s
+ tring
+ 278 00000046 00 00 ALIGN
+ 279 00000048
+ 280 00000048 END
+ 20000000
+ 00000000
+ 00000000
+Command Line: --16 --debug --xref --cpreproc --diag_suppress=9931 --cpu=Cortex-
+M0+ --apcs=interwork --depend=.\objects\startup_rtl876x.d -o.\objects\startup_r
+tl876x.o -I..\rcu -IC:\Users\reparo_liu\AppData\Local\Arm\Packs\ARM\CMSIS\5.4.0
+\Device\ARM\ARMCM0plus\Include --predefine="__UVISION_VERSION SETA 536" --prede
+fine="ARMCM0P_MPU SETA 1" --list=.\listings\startup_rtl876x.lst ..\..\..\..\src
+\mcu\rtl876x\arm\startup_rtl876x.s
+
+
+
+ARM Macro Assembler Page 1 Alphabetic symbol ordering
+Relocatable symbols
+
+VECTOR 00000000
+
+Symbol: VECTOR
+ Definitions
+ At line 10 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ Uses
+ None
+Comment: VECTOR unused
+__Vectors 00000000
+
+Symbol: __Vectors
+ Definitions
+ At line 15 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ Uses
+ At line 11 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 82 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+
+__Vectors_End 000000E8
+
+Symbol: __Vectors_End
+ Definitions
+ At line 80 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ Uses
+ At line 12 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 82 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+
+3 symbols
+
+
+
+ARM Macro Assembler Page 1 Alphabetic symbol ordering
+Relocatable symbols
+
+RESET 00000000
+
+Symbol: RESET
+ Definitions
+ At line 84 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ Uses
+ None
+Comment: RESET unused
+Reset_Handler 00000000
+
+Symbol: Reset_Handler
+ Definitions
+ At line 87 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ Uses
+ At line 16 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 88 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+
+2 symbols
+
+
+
+ARM Macro Assembler Page 1 Alphabetic symbol ordering
+Relocatable symbols
+
+.text 00000000
+
+Symbol: .text
+ Definitions
+ At line 96 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ Uses
+ None
+Comment: .text unused
+ADC_Handler 00000000
+
+Symbol: ADC_Handler
+ Definitions
+ At line 204 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 51 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 124 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+BTMAC_Handler 00000000
+
+Symbol: BTMAC_Handler
+ Definitions
+ At line 189 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 35 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 109 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+BusFault_Handler 00000000
+
+Symbol: BusFault_Handler
+ Definitions
+ At line 182 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 20 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 102 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+CAP_Touch_Handler 00000000
+
+Symbol: CAP_Touch_Handler
+ Definitions
+ At line 227 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 78 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 147 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+DEFAULT_HANDLER_TXT 00000010
+
+
+
+
+ARM Macro Assembler Page 2 Alphabetic symbol ordering
+Relocatable symbols
+
+Symbol: DEFAULT_HANDLER_TXT
+ Definitions
+ At line 276 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 261 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: DEFAULT_HANDLER_TXT used once
+Default_Handler 00000000
+
+Symbol: Default_Handler
+ Definitions
+ At line 97 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ Uses
+ At line 98 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+Comment: Default_Handler used once
+Enhanced_Timer0_Handler 00000000
+
+Symbol: Enhanced_Timer0_Handler
+ Definitions
+ At line 210 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 57 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 130 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+Enhanced_Timer1_Handler 00000000
+
+Symbol: Enhanced_Timer1_Handler
+ Definitions
+ At line 211 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 58 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 131 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+GDMA0_Channel0_Handler 00000000
+
+Symbol: GDMA0_Channel0_Handler
+ Definitions
+ At line 206 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 53 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 126 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+GDMA0_Channel1_Handler 00000000
+
+Symbol: GDMA0_Channel1_Handler
+ Definitions
+ At line 207 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+
+
+
+ARM Macro Assembler Page 3 Alphabetic symbol ordering
+Relocatable symbols
+
+6x.s
+ Uses
+ At line 54 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 127 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+GDMA0_Channel2_Handler 00000000
+
+Symbol: GDMA0_Channel2_Handler
+ Definitions
+ At line 208 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 55 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 128 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+GDMA0_Channel3_Handler 00000000
+
+Symbol: GDMA0_Channel3_Handler
+ Definitions
+ At line 209 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 56 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 129 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+GPIO0_Handler 00000000
+
+Symbol: GPIO0_Handler
+ Definitions
+ At line 229 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 149 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO0_Handler used once
+GPIO10_Handler 00000000
+
+Symbol: GPIO10_Handler
+ Definitions
+ At line 237 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 157 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO10_Handler used once
+GPIO11_Handler 00000000
+
+Symbol: GPIO11_Handler
+ Definitions
+ At line 238 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 158 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+
+
+
+ARM Macro Assembler Page 4 Alphabetic symbol ordering
+Relocatable symbols
+
+6x.s
+Comment: GPIO11_Handler used once
+GPIO12_Handler 00000000
+
+Symbol: GPIO12_Handler
+ Definitions
+ At line 239 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 159 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO12_Handler used once
+GPIO13_Handler 00000000
+
+Symbol: GPIO13_Handler
+ Definitions
+ At line 240 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 160 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO13_Handler used once
+GPIO14_Handler 00000000
+
+Symbol: GPIO14_Handler
+ Definitions
+ At line 241 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 161 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO14_Handler used once
+GPIO15_Handler 00000000
+
+Symbol: GPIO15_Handler
+ Definitions
+ At line 242 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 162 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO15_Handler used once
+GPIO16_Handler 00000000
+
+Symbol: GPIO16_Handler
+ Definitions
+ At line 243 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 163 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO16_Handler used once
+GPIO17_Handler 00000000
+
+Symbol: GPIO17_Handler
+ Definitions
+ At line 244 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+
+
+
+ARM Macro Assembler Page 5 Alphabetic symbol ordering
+Relocatable symbols
+
+ At line 164 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO17_Handler used once
+GPIO18_Handler 00000000
+
+Symbol: GPIO18_Handler
+ Definitions
+ At line 245 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 165 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO18_Handler used once
+GPIO19_Handler 00000000
+
+Symbol: GPIO19_Handler
+ Definitions
+ At line 246 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 166 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO19_Handler used once
+GPIO1_Handler 00000000
+
+Symbol: GPIO1_Handler
+ Definitions
+ At line 230 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 150 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO1_Handler used once
+GPIO20_Handler 00000000
+
+Symbol: GPIO20_Handler
+ Definitions
+ At line 247 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 167 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO20_Handler used once
+GPIO21_Handler 00000000
+
+Symbol: GPIO21_Handler
+ Definitions
+ At line 248 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 168 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO21_Handler used once
+GPIO22_Handler 00000000
+
+Symbol: GPIO22_Handler
+ Definitions
+ At line 249 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+
+
+ARM Macro Assembler Page 6 Alphabetic symbol ordering
+Relocatable symbols
+
+ Uses
+ At line 169 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO22_Handler used once
+GPIO23_Handler 00000000
+
+Symbol: GPIO23_Handler
+ Definitions
+ At line 250 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 170 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO23_Handler used once
+GPIO24_Handler 00000000
+
+Symbol: GPIO24_Handler
+ Definitions
+ At line 251 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 171 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO24_Handler used once
+GPIO25_Handler 00000000
+
+Symbol: GPIO25_Handler
+ Definitions
+ At line 252 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 172 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO25_Handler used once
+GPIO26_Handler 00000000
+
+Symbol: GPIO26_Handler
+ Definitions
+ At line 253 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 173 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO26_Handler used once
+GPIO27_Handler 00000000
+
+Symbol: GPIO27_Handler
+ Definitions
+ At line 254 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 174 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO27_Handler used once
+GPIO28_Handler 00000000
+
+Symbol: GPIO28_Handler
+ Definitions
+ At line 255 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+
+
+
+ARM Macro Assembler Page 7 Alphabetic symbol ordering
+Relocatable symbols
+
+6x.s
+ Uses
+ At line 175 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO28_Handler used once
+GPIO29_Handler 00000000
+
+Symbol: GPIO29_Handler
+ Definitions
+ At line 256 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 176 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO29_Handler used once
+GPIO2_Handler 00000000
+
+Symbol: GPIO2_Handler
+ Definitions
+ At line 231 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 151 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO2_Handler used once
+GPIO30_Handler 00000000
+
+Symbol: GPIO30_Handler
+ Definitions
+ At line 257 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 177 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO30_Handler used once
+GPIO31_Handler 00000000
+
+Symbol: GPIO31_Handler
+ Definitions
+ At line 258 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 178 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO31_Handler used once
+GPIO3_Handler 00000000
+
+Symbol: GPIO3_Handler
+ Definitions
+ At line 232 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 152 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO3_Handler used once
+GPIO4_Handler 00000000
+
+Symbol: GPIO4_Handler
+ Definitions
+
+
+
+ARM Macro Assembler Page 8 Alphabetic symbol ordering
+Relocatable symbols
+
+ At line 195 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 42 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 115 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+GPIO5_Handler 00000000
+
+Symbol: GPIO5_Handler
+ Definitions
+ At line 196 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 43 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 116 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+GPIO6_Handler 00000000
+
+Symbol: GPIO6_Handler
+ Definitions
+ At line 233 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 153 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO6_Handler used once
+GPIO7_Handler 00000000
+
+Symbol: GPIO7_Handler
+ Definitions
+ At line 234 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 154 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO7_Handler used once
+GPIO8_Handler 00000000
+
+Symbol: GPIO8_Handler
+ Definitions
+ At line 235 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 155 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: GPIO8_Handler used once
+GPIO9_Handler 00000000
+
+Symbol: GPIO9_Handler
+ Definitions
+ At line 236 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 156 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+
+
+ARM Macro Assembler Page 9 Alphabetic symbol ordering
+Relocatable symbols
+
+Comment: GPIO9_Handler used once
+GPIO_Group0_Handler 00000000
+
+Symbol: GPIO_Group0_Handler
+ Definitions
+ At line 216 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 63 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 136 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+GPIO_Group1_Handler 00000000
+
+Symbol: GPIO_Group1_Handler
+ Definitions
+ At line 215 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 62 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 135 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+GPIO_Group2_Handler 00000000
+
+Symbol: GPIO_Group2_Handler
+ Definitions
+ At line 213 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 60 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 133 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+GPIO_Group3_Handler 00000000
+
+Symbol: GPIO_Group3_Handler
+ Definitions
+ At line 212 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 59 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 132 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+HardFault_Handler 00000000
+
+Symbol: HardFault_Handler
+ Definitions
+ At line 180 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 18 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 38 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+
+
+
+ARM Macro Assembler Page 10 Alphabetic symbol ordering
+Relocatable symbols
+
+x.s
+ At line 100 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+I2C0_Handler 00000000
+
+Symbol: I2C0_Handler
+ Definitions
+ At line 202 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 49 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 122 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+I2C1_Handler 00000000
+
+Symbol: I2C1_Handler
+ Definitions
+ At line 203 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 50 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 123 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+I2S0_RX_Handler 00000000
+
+Symbol: I2S0_RX_Handler
+ Definitions
+ At line 193 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 40 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 113 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+I2S0_TX_Handler 00000000
+
+Symbol: I2S0_TX_Handler
+ Definitions
+ At line 192 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 39 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 112 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+IR_Handler 00000000
+
+Symbol: IR_Handler
+ Definitions
+ At line 214 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+
+
+
+ARM Macro Assembler Page 11 Alphabetic symbol ordering
+Relocatable symbols
+
+ At line 61 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 134 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+Keyscan_Handler 00000000
+
+Symbol: Keyscan_Handler
+ Definitions
+ At line 223 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 74 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 143 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+LPCOMP_Handler 00000000
+
+Symbol: LPCOMP_Handler
+ Definitions
+ At line 225 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 76 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 145 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+MemManage_Handler 00000000
+
+Symbol: MemManage_Handler
+ Definitions
+ At line 181 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 19 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 101 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+NMI_Handler 00000000
+
+Symbol: NMI_Handler
+ Definitions
+ At line 179 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 17 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 99 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+
+PTA_Mailbox_Handler 00000000
+
+Symbol: PTA_Mailbox_Handler
+ Definitions
+ At line 226 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+
+
+ARM Macro Assembler Page 12 Alphabetic symbol ordering
+Relocatable symbols
+
+ Uses
+ At line 77 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 146 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+PendSV_Handler 00000000
+
+Symbol: PendSV_Handler
+ Definitions
+ At line 185 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 29 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 105 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+Peripheral_Handler 00000000
+
+Symbol: Peripheral_Handler
+ Definitions
+ At line 205 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 52 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 125 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+Qdecode_Handler 00000000
+
+Symbol: Qdecode_Handler
+ Definitions
+ At line 222 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 73 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 142 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+RTC_Handler 00000000
+
+Symbol: RTC_Handler
+ Definitions
+ At line 199 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 46 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 119 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+SPI0_Handler 00000000
+
+Symbol: SPI0_Handler
+ Definitions
+ At line 200 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+
+
+
+ARM Macro Assembler Page 13 Alphabetic symbol ordering
+Relocatable symbols
+
+6x.s
+ Uses
+ At line 47 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 120 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+SPI1_Handler 00000000
+
+Symbol: SPI1_Handler
+ Definitions
+ At line 201 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 48 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 121 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+SPI2W_Handler 00000000
+
+Symbol: SPI2W_Handler
+ Definitions
+ At line 224 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 75 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 144 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+SPI_Flash_Handler 00000000
+
+Symbol: SPI_Flash_Handler
+ Definitions
+ At line 221 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 72 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 141 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+SVC_Handler 00000000
+
+Symbol: SVC_Handler
+ Definitions
+ At line 184 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 26 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 104 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+SysTick_Handler 00000000
+
+Symbol: SysTick_Handler
+ Definitions
+
+
+
+ARM Macro Assembler Page 14 Alphabetic symbol ordering
+Relocatable symbols
+
+ At line 186 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 30 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 106 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+System_Handler 00000000
+
+Symbol: System_Handler
+ Definitions
+ At line 187 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 33 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 107 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+TRNG_Handler 00000000
+
+Symbol: TRNG_Handler
+ Definitions
+ At line 228 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 79 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 148 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+Timer2_Handler 00000000
+
+Symbol: Timer2_Handler
+ Definitions
+ At line 191 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 37 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 111 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+Timer3_Handler 00000000
+
+Symbol: Timer3_Handler
+ Definitions
+ At line 190 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 36 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 110 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+Timer4_5_Handler 00000000
+
+Symbol: Timer4_5_Handler
+
+
+
+ARM Macro Assembler Page 15 Alphabetic symbol ordering
+Relocatable symbols
+
+ Definitions
+ At line 194 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 41 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 114 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+Timer4_Handler 00000000
+
+Symbol: Timer4_Handler
+ Definitions
+ At line 219 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 67 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 139 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+Timer5_Handler 00000000
+
+Symbol: Timer5_Handler
+ Definitions
+ At line 220 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 68 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 140 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+UART0_Handler 00000000
+
+Symbol: UART0_Handler
+ Definitions
+ At line 198 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 45 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 118 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+UART1_Handler 00000000
+
+Symbol: UART1_Handler
+ Definitions
+ At line 197 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 44 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 117 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+UsageFault_Handler 00000000
+
+
+
+
+ARM Macro Assembler Page 16 Alphabetic symbol ordering
+Relocatable symbols
+
+Symbol: UsageFault_Handler
+ Definitions
+ At line 183 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 21 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 103 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+WDG_Handler 00000000
+
+Symbol: WDG_Handler
+ Definitions
+ At line 188 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 34 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ At line 108 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+
+__user_setup_stackheap 0000000E
+
+Symbol: __user_setup_stackheap
+ Definitions
+ At line 272 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 271 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: __user_setup_stackheap used once
+82 symbols
+
+
+
+ARM Macro Assembler Page 1 Alphabetic symbol ordering
+Absolute symbols
+
+__Vectors_Size 000000E8
+
+Symbol: __Vectors_Size
+ Definitions
+ At line 82 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ Uses
+ At line 13 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+Comment: __Vectors_Size used once
+__initial_sp 00203800
+
+Symbol: __initial_sp
+ Definitions
+ At line 3 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876x
+.s
+ Uses
+ At line 2 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876x
+.s
+ At line 15 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+
+2 symbols
+
+
+
+ARM Macro Assembler Page 1 Alphabetic symbol ordering
+External symbols
+
+SystemInit 00000000
+
+Symbol: SystemInit
+ Definitions
+ At line 89 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+ Uses
+ At line 90 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876
+x.s
+Comment: SystemInit used once
+log_direct 00000000
+
+Symbol: log_direct
+ Definitions
+ At line 259 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+ Uses
+ At line 263 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87
+6x.s
+Comment: log_direct used once
+2 symbols
+427 symbols in table
diff --git a/board/evb/google_rcu/mdk/after_build_special.bat b/board/evb/google_rcu/mdk/after_build_special.bat
new file mode 100644
index 0000000..b881556
--- /dev/null
+++ b/board/evb/google_rcu/mdk/after_build_special.bat
@@ -0,0 +1,2 @@
+@echo off
+echo build_before_special bat \ No newline at end of file
diff --git a/board/evb/google_rcu/mdk/app.sct b/board/evb/google_rcu/mdk/app.sct
new file mode 100644
index 0000000..697d275
--- /dev/null
+++ b/board/evb/google_rcu/mdk/app.sct
@@ -0,0 +1,126 @@
+#! armcc -E
+#include "..\mem_config.h"
+
+; *************************************************************
+; *** Scatter-Loading Description File generated by uVision ***
+; *************************************************************
+
+; APP RAM definitions
+#define APP_DATA_ON_ADR APP_GLOBAL_ADDR
+#define APP_DATA_ON_SIZE APP_GLOBAL_SIZE
+
+#define CACHE_DATA_ON_ADR SHARE_CACHE_RAM_ADDR
+#define CACHE_DATA_ON_SIZE SHARE_CACHE_RAM_SIZE
+
+#if (APP_BANK == 0)
+#define APP_FLASH_ADR BANK0_APP_ADDR
+#else
+#define APP_FLASH_ADR BANK1_APP_ADDR
+#endif
+#define APP_FLASH_SIZE BANK0_APP_SIZE
+
+#define APP_TRACE_ADR 0x08800000
+#define APP_TRACE_SIZE (4*1024*1024)
+
+
+LOAD_FLASH APP_FLASH_ADR APP_FLASH_SIZE
+{
+ app.bin +0
+ {
+ * (.app.flash.header)
+ }
+ APP_FLASH_HEADER_EXT +0
+ {
+ * (.app.flash.header_ext)
+ }
+
+#if (FEATURE_ENCRYPTION == 0)
+ FLASH_START_ADDR +0;
+ {
+ startup_rtl876x.o (RESET, +First)
+ }
+#endif
+
+ FLASH_TEXT +0
+ {
+#if FEATURE_RAM_CODE
+ * (InRoot$$Sections)
+#else
+ .ANY (+RO)
+#endif
+ * (.app.flash.text)
+ * (.app.flash.rodata)
+ }
+
+ RAM_VECTOR_TABLE 0x00200000 OVERLAY 0xE8 ; 58 ISRs
+ {
+ * (VECTOR, +First)
+ }
+
+#if (FEATURE_ENCRYPTION == 1)
+ ENCRYPTION_RAM_CODE APP_DATA_ON_ADR OVERLAY
+ {
+ startup_rtl876x.o (RESET, +First)
+ * (.app.encryption.text)
+ * (.enc.dummy.align, +Last)
+ }
+#endif
+
+#if (FEATURE_ENCRYPTION == 1)
+ RAM_DATA_ON +0 OVERLAY (APP_DATA_ON_SIZE) ;real limit is: (APP_DATA_ON_SIZE - ImageLength(ENCRYPTION_RAM_CODE))
+#else
+ RAM_DATA_ON APP_DATA_ON_ADR OVERLAY (APP_DATA_ON_SIZE)
+#endif
+ {
+#if FEATURE_RAM_CODE
+ .ANY (+RO)
+#endif
+ rtl876x_io_dlps.o
+ * (.app.data_ram.text)
+ * (+RW)
+ * (.ram.dataon.data)
+ * (+ZI)
+ * (.ram.dataon.bss)
+ }
+
+; overlay section begin
+ OVERLAY_A ImageLimit(RAM_DATA_ON) OVERLAY
+ {
+ *(.app.overlay_a)
+ }
+
+ OVERLAY_B ImageLimit(RAM_DATA_ON) OVERLAY
+ {
+ *(.app.overlay_b)
+ }
+ OVERLAY_C ImageLimit(RAM_DATA_ON) OVERLAY
+ {
+ *(.app.overlay_c)
+ }
+#if (FEATURE_ENCRYPTION == 0)
+ ScatterAssert((ImageLength(RAM_DATA_ON) + ImageLength(OVERLAY_A)) <= (APP_DATA_ON_SIZE))
+ ScatterAssert((ImageLength(RAM_DATA_ON) + ImageLength(OVERLAY_B)) <= (APP_DATA_ON_SIZE))
+ ScatterAssert((ImageLength(RAM_DATA_ON) + ImageLength(OVERLAY_C)) <= (APP_DATA_ON_SIZE))
+#else
+ ScatterAssert((ImageLength(ENCRYPTION_RAM_CODE) + ImageLength(RAM_DATA_ON) + ImageLength(OVERLAY_A)) <= (APP_DATA_ON_SIZE))
+ ScatterAssert((ImageLength(ENCRYPTION_RAM_CODE) + ImageLength(RAM_DATA_ON) + ImageLength(OVERLAY_B)) <= (APP_DATA_ON_SIZE))
+ ScatterAssert((ImageLength(ENCRYPTION_RAM_CODE) + ImageLength(RAM_DATA_ON) + ImageLength(OVERLAY_C)) <= (APP_DATA_ON_SIZE))
+#endif
+; overlay section end
+
+ CACHE_DATA_ON CACHE_DATA_ON_ADR OVERLAY CACHE_DATA_ON_SIZE
+ {
+#if FEATURE_RAM_CODE
+ .ANY (+RO)
+#endif
+ * (.ram.sharecacheram.text)
+ }
+}
+
+LOAD_APP_TRACE APP_TRACE_ADR APP_TRACE_SIZE
+{
+ App.trace APP_TRACE_ADR APP_TRACE_SIZE
+ {
+ * (.TRACE)
+ }
+}
diff --git a/board/evb/google_rcu/mdk/before_build_special.bat b/board/evb/google_rcu/mdk/before_build_special.bat
new file mode 100644
index 0000000..b881556
--- /dev/null
+++ b/board/evb/google_rcu/mdk/before_build_special.bat
@@ -0,0 +1,2 @@
+@echo off
+echo build_before_special bat \ No newline at end of file
diff --git a/board/evb/google_rcu/mdk/google_rcu.uvguix.reparo_liu b/board/evb/google_rcu/mdk/google_rcu.uvguix.reparo_liu
new file mode 100644
index 0000000..c2f4be5
--- /dev/null
+++ b/board/evb/google_rcu/mdk/google_rcu.uvguix.reparo_liu
@@ -0,0 +1,3664 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<ProjectGui xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_guix.xsd">
+
+ <SchemaVersion>-6.1</SchemaVersion>
+
+ <Header>### uVision Project, (C) Keil Software</Header>
+
+ <PrjGuiSettings>
+ <LastAddFilePath>D:\work_doc\projects\HoneyComb\bee3-google-rcu-sdk-v2.1.0.1\sdk\board\evb\google_rcu\mdk</LastAddFilePath>
+ </PrjGuiSettings>
+
+ <ViewPool/>
+
+ <SECTreeCtrl>
+ <View>
+ <WinId>38003</WinId>
+ <ViewName>Registers</ViewName>
+ <TableColWidths>201 201</TableColWidths>
+ </View>
+ <View>
+ <WinId>346</WinId>
+ <ViewName>Code Coverage</ViewName>
+ <TableColWidths>1090 160</TableColWidths>
+ </View>
+ <View>
+ <WinId>204</WinId>
+ <ViewName>Performance Analyzer</ViewName>
+ <TableColWidths>1250</TableColWidths>
+ </View>
+ </SECTreeCtrl>
+
+ <TreeListPane>
+ <View>
+ <WinId>35141</WinId>
+ <ViewName>Event Statistics</ViewName>
+ <UserString></UserString>
+ <TableColWidths>200 50 700</TableColWidths>
+ </View>
+ <View>
+ <WinId>1506</WinId>
+ <ViewName>Symbols</ViewName>
+ <UserString></UserString>
+ <TableColWidths>53 53 53</TableColWidths>
+ </View>
+ <View>
+ <WinId>1936</WinId>
+ <ViewName>Watch 1</ViewName>
+ <UserString></UserString>
+ <TableColWidths>200 133 133</TableColWidths>
+ </View>
+ <View>
+ <WinId>1937</WinId>
+ <ViewName>Watch 2</ViewName>
+ <UserString></UserString>
+ <TableColWidths>200 133 133</TableColWidths>
+ </View>
+ <View>
+ <WinId>1935</WinId>
+ <ViewName>Call Stack + Locals</ViewName>
+ <UserString></UserString>
+ <TableColWidths>200 133 133</TableColWidths>
+ </View>
+ <View>
+ <WinId>2506</WinId>
+ <ViewName>Trace Data</ViewName>
+ <UserString></UserString>
+ <TableColWidths>75 135 130 95 70 230 200 150</TableColWidths>
+ </View>
+ <View>
+ <WinId>466</WinId>
+ <ViewName>Source Browser</ViewName>
+ <UserString>500</UserString>
+ <TableColWidths>300</TableColWidths>
+ </View>
+ </TreeListPane>
+
+ <CompViewPool/>
+
+ <WindowSettings>
+ <LogicAnalizer>
+ <ShowLACursor>1</ShowLACursor>
+ <ShowSignalInfo>1</ShowSignalInfo>
+ <ShowCycles>0</ShowCycles>
+ <LeftSideBarSize>0</LeftSideBarSize>
+ <TimeBaseIndex>-1</TimeBaseIndex>
+ </LogicAnalizer>
+ </WindowSettings>
+
+ <WinLayoutEx>
+ <sActiveDebugView></sActiveDebugView>
+ <WindowPosition>
+ <length>44</length>
+ <flags>2</flags>
+ <showCmd>3</showCmd>
+ <MinPosition>
+ <xPos>-32000</xPos>
+ <yPos>-32000</yPos>
+ </MinPosition>
+ <MaxPosition>
+ <xPos>-1</xPos>
+ <yPos>-1</yPos>
+ </MaxPosition>
+ <NormalPosition>
+ <Top>141</Top>
+ <Left>1931</Left>
+ <Right>5274</Right>
+ <Bottom>1241</Bottom>
+ </NormalPosition>
+ </WindowPosition>
+ <MDIClientArea>
+ <RegID>0</RegID>
+ <MDITabState>
+ <Len>939</Len>
+ <Data>01000000040000000100000001000000010000000100000000000000020000000000000001000000010000000000000028000000280000000100000006000000000000000100000067443A5C776F726B5F646F635C70726F6A656374735C486F6E6579436F6D625C626565332D676F6F676C652D7263752D73646B2D76322E322E302E315C73646B5C7372635C6170705C676F6F676C655F7263755C766F6963655F6D6F64756C655C766F6963652E630000000007766F6963652E6300000000C5D4F200FFFFFFFF6E443A5C776F726B5F646F635C70726F6A656374735C486F6E6579436F6D625C626565332D676F6F676C652D7263752D73646B2D76322E322E302E315C73646B5C7372635C6170705C676F6F676C655F7263755C766F6963655F6D6F64756C655C766F6963655F6472697665722E68000000000E766F6963655F6472697665722E6800000000FFDC7800FFFFFFFF5F443A5C776F726B5F646F635C70726F6A656374735C486F6E6579436F6D625C626565332D676F6F676C652D7263752D73646B2D76322E322E302E315C73646B5C7372635C6170705C676F6F676C655F7263755C6C6F6F705F71756575652E68000000000C6C6F6F705F71756575652E6800000000BECEA100FFFFFFFF57443A5C776F726B5F646F635C70726F6A656374735C486F6E6579436F6D625C626565332D676F6F676C652D7263752D73646B2D76322E322E302E315C73646B5C696E635C7263755C696D615F616470636D5F656E632E68000000000F696D615F616470636D5F656E632E6800000000F0A0A100FFFFFFFF61443A5C776F726B5F646F635C70726F6A656374735C486F6E6579436F6D625C626565332D676F6F676C652D7263752D73646B2D76322E322E302E315C73646B5C7372635C6D63755C7065726970686572616C5C72746C383736785F756172742E63000000000E72746C383736785F756172742E6300000000BCA8E100FFFFFFFF5C443A5C776F726B5F646F635C70726F6A656374735C486F6E6579436F6D625C626565332D676F6F676C652D7263752D73646B2D76322E322E302E315C73646B5C696E635C7065726970686572616C5C72746C383736785F7764672E68000000000D72746C383736785F7764672E68000000009CC1B600FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD5000100000000000000020000002009000066000000000F00000D030000</Data>
+ </MDITabState>
+ </MDIClientArea>
+ <ViewEx>
+ <ViewType>0</ViewType>
+ <ViewName>Build</ViewName>
+ <Window>
+ <RegID>-1</RegID>
+ <PaneID>-1</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A40000004F00000090050000DD000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>2408000066000000100D0000F4000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1005</RegID>
+ <PaneID>1005</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000006600000099010000DD020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>109</RegID>
+ <PaneID>109</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000006600000099010000DD020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000D80800008D020000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1465</RegID>
+ <PaneID>1465</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000002A0200008D0500009C020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1466</RegID>
+ <PaneID>1466</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000002A0200008D0500009C020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1467</RegID>
+ <PaneID>1467</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000002A0200008D0500009C020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1468</RegID>
+ <PaneID>1468</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000002A0200008D0500009C020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1506</RegID>
+ <PaneID>1506</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>16384</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1913</RegID>
+ <PaneID>1913</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A7000000660000008D050000C4000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1935</RegID>
+ <PaneID>1935</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>32768</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000002A0200008D0500009C020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1936</RegID>
+ <PaneID>1936</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000002A0200008D0500009C020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1937</RegID>
+ <PaneID>1937</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000002A0200008D0500009C020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1939</RegID>
+ <PaneID>1939</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000002A0200008D0500009C020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1940</RegID>
+ <PaneID>1940</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000002A0200008D0500009C020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1941</RegID>
+ <PaneID>1941</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000002A0200008D0500009C020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1942</RegID>
+ <PaneID>1942</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000002A0200008D0500009C020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>195</RegID>
+ <PaneID>195</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000006600000099010000DD020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000D80800008D020000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>196</RegID>
+ <PaneID>196</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000006600000099010000DD020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000D80800008D020000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>197</RegID>
+ <PaneID>197</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>32768</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>03000000110300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>198</RegID>
+ <PaneID>198</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>32768</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>000000001302000090050000B5020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>199</RegID>
+ <PaneID>199</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>03000000110300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>203</RegID>
+ <PaneID>203</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>8192</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A7000000660000008D050000C4000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>204</RegID>
+ <PaneID>204</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A7000000660000008D050000C4000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>221</RegID>
+ <PaneID>221</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>00000000000000000000000000000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>0A0000000A0000006E0000006E000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>2506</RegID>
+ <PaneID>2506</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>2507</RegID>
+ <PaneID>2507</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000002A0200008D0500009C020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>343</RegID>
+ <PaneID>343</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A7000000660000008D050000C4000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>346</RegID>
+ <PaneID>346</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A7000000660000008D050000C4000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35141</RegID>
+ <PaneID>35141</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A7000000660000008D050000C4000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35824</RegID>
+ <PaneID>35824</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A7000000660000008D050000C4000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35885</RegID>
+ <PaneID>35885</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35886</RegID>
+ <PaneID>35886</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35887</RegID>
+ <PaneID>35887</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35888</RegID>
+ <PaneID>35888</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35889</RegID>
+ <PaneID>35889</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35890</RegID>
+ <PaneID>35890</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35891</RegID>
+ <PaneID>35891</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35892</RegID>
+ <PaneID>35892</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35893</RegID>
+ <PaneID>35893</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35894</RegID>
+ <PaneID>35894</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35895</RegID>
+ <PaneID>35895</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35896</RegID>
+ <PaneID>35896</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35897</RegID>
+ <PaneID>35897</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35898</RegID>
+ <PaneID>35898</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35899</RegID>
+ <PaneID>35899</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35900</RegID>
+ <PaneID>35900</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35901</RegID>
+ <PaneID>35901</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35902</RegID>
+ <PaneID>35902</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35903</RegID>
+ <PaneID>35903</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35904</RegID>
+ <PaneID>35904</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35905</RegID>
+ <PaneID>35905</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>38003</RegID>
+ <PaneID>38003</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000006600000099010000DD020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000D80800008D020000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>38007</RegID>
+ <PaneID>38007</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>03000000110300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>436</RegID>
+ <PaneID>436</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>03000000110300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000D80800008D020000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>437</RegID>
+ <PaneID>437</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000002A0200008D0500009C020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>440</RegID>
+ <PaneID>440</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000002A0200008D0500009C020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>463</RegID>
+ <PaneID>463</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>03000000110300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000D80800008D020000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>466</RegID>
+ <PaneID>466</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>03000000110300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000D80800008D020000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>470</RegID>
+ <PaneID>470</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A7000000660000008D050000C4000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC07000053000000840A0000E1000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50000</RegID>
+ <PaneID>50000</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50001</RegID>
+ <PaneID>50001</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50002</RegID>
+ <PaneID>50002</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50003</RegID>
+ <PaneID>50003</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50004</RegID>
+ <PaneID>50004</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50005</RegID>
+ <PaneID>50005</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50006</RegID>
+ <PaneID>50006</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50007</RegID>
+ <PaneID>50007</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50008</RegID>
+ <PaneID>50008</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50009</RegID>
+ <PaneID>50009</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50010</RegID>
+ <PaneID>50010</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50011</RegID>
+ <PaneID>50011</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50012</RegID>
+ <PaneID>50012</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50013</RegID>
+ <PaneID>50013</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50014</RegID>
+ <PaneID>50014</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50015</RegID>
+ <PaneID>50015</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50016</RegID>
+ <PaneID>50016</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50017</RegID>
+ <PaneID>50017</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50018</RegID>
+ <PaneID>50018</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50019</RegID>
+ <PaneID>50019</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>F3040000660000008D0500000A020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>59392</RegID>
+ <PaneID>59392</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>966</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>8192</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>0000000000000000D10300001C000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>0A0000000A0000006E0000006E000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>59393</RegID>
+ <PaneID>0</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>00000000E603000080070000F9030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>0A0000000A0000006E0000006E000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>59399</RegID>
+ <PaneID>59399</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>476</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>8192</RecentFrameAlignment>
+ <RecentRowIndex>1</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>000000001C000000E701000038000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>0A0000000A0000006E0000006E000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>59400</RegID>
+ <PaneID>59400</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>612</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>8192</RecentFrameAlignment>
+ <RecentRowIndex>2</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>00000000380000006F02000054000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>0A0000000A0000006E0000006E000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>824</RegID>
+ <PaneID>824</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000002A0200008D0500009C020000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>BC070000530000005C080000D6000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <DockMan>
+ <Len>3312</Len>
+ <Data>000000000B000000000000000020000000000000FFFFFFFFFFFFFFFFA4000000DD00000090050000E1000000000000000100000004000000010000000000000000000000FFFFFFFF08000000CB00000057010000CC000000F08B00005A01000079070000D601000045890000FFFF02000B004354616262656450616E6500200000000000002408000066000000100D0000F4000000A40000004F00000090050000DD0000000000000040280046080000000B446973617373656D626C7900000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFF0F53797374656D20416E616C797A657200000000D601000001000000FFFFFFFFFFFFFFFF104576656E742053746174697374696373000000004589000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFFEC0400004F000000F004000023020000000000000200000004000000010000000000000000000000FFFFFFFF2B000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C000050C3000051C3000052C3000053C3000054C3000055C3000056C3000057C3000058C3000059C300005AC300005BC300005CC300005DC300005EC300005FC3000060C3000061C3000062C3000063C3000001800040000000000000700C000066000000100D00003A020000F00400004F000000900500002302000000000000404100462B0000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFF000000000050C3000001000000FFFFFFFFFFFFFFFF000000000051C3000001000000FFFFFFFFFFFFFFFF000000000052C3000001000000FFFFFFFFFFFFFFFF000000000053C3000001000000FFFFFFFFFFFFFFFF000000000054C3000001000000FFFFFFFFFFFFFFFF000000000055C3000001000000FFFFFFFFFFFFFFFF000000000056C3000001000000FFFFFFFFFFFFFFFF000000000057C3000001000000FFFFFFFFFFFFFFFF000000000058C3000001000000FFFFFFFFFFFFFFFF000000000059C3000001000000FFFFFFFFFFFFFFFF00000000005AC3000001000000FFFFFFFFFFFFFFFF00000000005BC3000001000000FFFFFFFFFFFFFFFF00000000005CC3000001000000FFFFFFFFFFFFFFFF00000000005DC3000001000000FFFFFFFFFFFFFFFF00000000005EC3000001000000FFFFFFFFFFFFFFFF00000000005FC3000001000000FFFFFFFFFFFFFFFF000000000060C3000001000000FFFFFFFFFFFFFFFF000000000061C3000001000000FFFFFFFFFFFFFFFF000000000062C3000001000000FFFFFFFFFFFFFFFF000000000063C3000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFF9C0100004F000000A0010000F602000001000000020000100400000001000000CFFEFFFF44060000FFFFFFFF05000000ED0300006D000000C3000000C4000000739400000180001000000100000080070000660000001C0900000D030000000000004F0000009C010000F60200000000000040410056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73010000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7301000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657301000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273000000007394000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000000000000FFFFFFFFFFFFFFFF000000000F020000900500001302000000000000010000000400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0F0000008F070000930700009407000095070000960700009007000091070000B5010000B801000038030000B9050000BA050000BB050000BC050000CB09000001800080000000000000800700002A020000100D0000CC020000000000001302000090050000B502000000000000404100460F0000001343616C6C20537461636B202B204C6F63616C73000000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF09554C494E4B706C7573000000003803000001000000FFFFFFFFFFFFFFFF084D656D6F7279203100000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFFC802000013020000CC020000B502000000000000020000000400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000001000000FFFFFFFFFFFFFFFF00000000F602000080070000FA02000001000000010000100400000001000000C9FDFFFF55010000FFFFFFFF06000000C5000000C7000000B4010000D2010000CF01000077940000018000800000010000008007000011030000000F0000FD03000000000000FA02000080070000E60300000000000040820056060000000C4275696C64204F757470757401000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657301000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0E536F757263652042726F7773657200000000D201000001000000FFFFFFFFFFFFFFFF0E416C6C205265666572656E63657300000000CF01000001000000FFFFFFFFFFFFFFFF0742726F77736572000000007794000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000000000000000000</Data>
+ </DockMan>
+ <ToolBar>
+ <RegID>59392</RegID>
+ <Name>File</Name>
+ <Buttons>
+ <Len>2750</Len>
+ <Data>00200000010000002800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000040004000000000000000000000000000000000100000001000000018022E100000000040005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000004000700000000000000000000000000000000010000000100000001802CE10000000004000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000004000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000004000C0000000000000000000000000000000001000000010000000180F4B00000000004000D000000000000000000000000000000000100000001000000018036B10000000004000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF88000000000400460000000000000000000000000000000001000000010000000180FE880000000004004500000000000000000000000000000000010000000100000001800B810000000004001300000000000000000000000000000000010000000100000001800C810000000004001400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F0880000020000000F000000000000000000000000000000000100000001000000FFFF0100120043555646696E64436F6D626F427574746F6EE8030000000000000000000000000000000000000000000000010000000100000096000000020020500000000014656E636F64655F6F75747075745F6275666665729600000000000000080025616E7420746F2067657420726573657420726561736F6E2066726F6D20616F6E203078313608637070636865636B0A55415254782D3E4C53520955415254782D3E4C5314656E636F64655F6F75747075745F627566666572164932435F436C656172494E5450656E64696E674269741C766F6963655F68616E646C655F656E636F64655F7261775F6461746113493243782D3E49435F434C525F52445F5245510000000000000000000000000000000000000000000000000000000000000000018024E10000000000001100000000000000000000000000000000010000000100000001800A810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E2280000002000000150000002153746172742F53746F70202644656275672053657373696F6E094374726C2B46350000000000000000000000000100000001000000000000000000000001000000020021802280000000000000150000002153746172742F53746F70202644656275672053657373696F6E094374726C2B4635000000000000000000000000010000000100000000000000000000000100000000002180E0010000000000007500000021456E65726779204D6561737572656D656E742026776974686F75742044656275670000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000160000000000000000000000000000000001000000010000000180C988000000000400180000000000000000000000000000000001000000010000000180C788000000000000190000000000000000000000000000000001000000010000002180C8880000000000001700000027264B696C6C20416C6C20427265616B706F696E747320696E2043757272656E7420546172676574000000000000000000000000010000000100000000000000000000000100000003002180C8880000000000001700000027264B696C6C20416C6C20427265616B706F696E747320696E2043757272656E7420546172676574000000000000000000000000010000000100000000000000000000000100000000002180E50100000000000078000000264B696C6C20416C6C20427265616B706F696E747320696E204163746976652050726F6A656374000000000000000000000000010000000100000000000000000000000100000000002180E601000000000000790000002F4B696C6C20416C6C20427265616B706F696E747320696E204D756C74692D50726F6A65637420576F726B73706163650000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000021804C010000020001001A0000000F2650726F6A6563742057696E646F77000000000000000000000000010000000100000000000000000000000100000008002180DD880000000000001A0000000750726F6A656374000000000000000000000000010000000100000000000000000000000100000000002180DC8B0000000000003A00000005426F6F6B73000000000000000000000000010000000100000000000000000000000100000000002180E18B0000000000003B0000000946756E6374696F6E73000000000000000000000000010000000100000000000000000000000100000000002180E28B000000000000400000000954656D706C6174657300000000000000000000000001000000010000000000000000000000010000000000218018890000000000003D0000000E536F757263652042726F777365720000000000000000000000000100000001000000000000000000000001000000000021800000000000000400FFFFFFFF00000000000000000001000000000000000100000000000000000000000100000000002180D988000000000000390000000C4275696C64204F7574707574000000000000000000000000010000000100000000000000000000000100000000002180E38B000000000000410000000B46696E64204F75747075740000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001B000000000000000000000000000000000100000001000000000000000446696C65C6030000</Data>
+ </Buttons>
+ <OriginalItems>
+ <Len>1423</Len>
+ <Data>2800FFFF01001100434D4643546F6F6C426172427574746F6E00E1000000000000FFFFFFFF000100000000000000010000000000000001000000018001E1000000000000FFFFFFFF000100000000000000010000000000000001000000018003E1000000000000FFFFFFFF0001000000000000000100000000000000010000000180CD7F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF000000000000000000010000000000000001000000018023E1000000000000FFFFFFFF000100000000000000010000000000000001000000018022E1000000000000FFFFFFFF000100000000000000010000000000000001000000018025E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802BE1000000000000FFFFFFFF00010000000000000001000000000000000100000001802CE1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001807A8A000000000000FFFFFFFF00010000000000000001000000000000000100000001807B8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180D3B0000000000000FFFFFFFF000100000000000000010000000000000001000000018015B1000000000000FFFFFFFF0001000000000000000100000000000000010000000180F4B0000000000000FFFFFFFF000100000000000000010000000000000001000000018036B1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FF88000000000000FFFFFFFF0001000000000000000100000000000000010000000180FE88000000000000FFFFFFFF00010000000000000001000000000000000100000001800B81000000000000FFFFFFFF00010000000000000001000000000000000100000001800C81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180F088000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE7F000000000000FFFFFFFF000100000000000000010000000000000001000000018024E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800A81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802280000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C488000000000000FFFFFFFF0001000000000000000100000000000000010000000180C988000000000000FFFFFFFF0001000000000000000100000000000000010000000180C788000000000000FFFFFFFF0001000000000000000100000000000000010000000180C888000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180DD88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FB7F000000000000FFFFFFFF000100000000000000010000000000000001000000</Data>
+ </OriginalItems>
+ <OrigResetItems>
+ <Len>1423</Len>
+ <Data>2800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000000004000000000000000000000000000000000100000001000000018022E100000000000005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000000000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000000000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000000000C0000000000000000000000000000000001000000010000000180F4B00000000000000D000000000000000000000000000000000100000001000000018036B10000000000000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF880000000000000F0000000000000000000000000000000001000000010000000180FE880000000000001000000000000000000000000000000000010000000100000001800B810000000000001100000000000000000000000000000000010000000100000001800C810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F088000000000000130000000000000000000000000000000001000000010000000180EE7F00000000000014000000000000000000000000000000000100000001000000018024E10000000000001500000000000000000000000000000000010000000100000001800A810000000000001600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000180000000000000000000000000000000001000000010000000180C988000000000000190000000000000000000000000000000001000000010000000180C7880000000000001A0000000000000000000000000000000001000000010000000180C8880000000000001B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180DD880000000000001C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001D000000000000000000000000000000000100000001000000</Data>
+ </OrigResetItems>
+ </ToolBar>
+ <ToolBar>
+ <RegID>59399</RegID>
+ <Name>Build</Name>
+ <Buttons>
+ <Len>966</Len>
+ <Data>00200000010000001000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000000001C0000000000000000000000000000000001000000010000000180D07F0000000002001D000000000000000000000000000000000100000001000000018030800000000000001E000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6EC7040000000000006A0000000C4261746368204275696C2664000000000000000000000000010000000100000000000000000000000100000004000580C7040000000000006A0000000C4261746368204275696C266400000000000000000000000001000000010000000000000000000000010000000000058046070000000000006B0000000D42617463682052656275696C640000000000000000000000000100000001000000000000000000000001000000000005804707000000000000FFFFFFFF0B426174636820436C65616E0100000000000000000000000100000001000000000000000000000001000000000005809E8A0000000000001F0000000F4261746326682053657475702E2E2E000000000000000000000000010000000100000000000000000000000100000000000180D17F0000000004002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA0000000000000000000000000000000000000000000000000100000001000000960000000300205000000000036170709600000000000000010003617070000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000400240000000000000000000000000000000001000000010000000180A8010000000000004E00000000000000000000000000000000010000000100000001807202000000000000530000000000000000000000000000000001000000010000000180BE010000000000005000000000000000000000000000000000010000000100000000000000054275696C64DC010000</Data>
+ </Buttons>
+ <OriginalItems>
+ <Len>583</Len>
+ <Data>1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000FFFFFFFF0001000000000000000100000000000000010000000180D07F000000000000FFFFFFFF00010000000000000001000000000000000100000001803080000000000000FFFFFFFF00010000000000000001000000000000000100000001809E8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D17F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001804C8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001806680000000000000FFFFFFFF0001000000000000000100000000000000010000000180EB88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180B08A000000000000FFFFFFFF0001000000000000000100000000000000010000000180A801000000000000FFFFFFFF00010000000000000001000000000000000100000001807202000000000000FFFFFFFF0001000000000000000100000000000000010000000180BE01000000000000FFFFFFFF000100000000000000010000000000000001000000</Data>
+ </OriginalItems>
+ <OrigResetItems>
+ <Len>583</Len>
+ <Data>1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000000000000000000000000000000000000001000000010000000180D07F00000000000001000000000000000000000000000000000100000001000000018030800000000000000200000000000000000000000000000000010000000100000001809E8A000000000000030000000000000000000000000000000001000000010000000180D17F0000000000000400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000000500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001806680000000000000060000000000000000000000000000000001000000010000000180EB880000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000080000000000000000000000000000000001000000010000000180B08A000000000000090000000000000000000000000000000001000000010000000180A8010000000000000A000000000000000000000000000000000100000001000000018072020000000000000B0000000000000000000000000000000001000000010000000180BE010000000000000C000000000000000000000000000000000100000001000000</Data>
+ </OrigResetItems>
+ </ToolBar>
+ <ToolBar>
+ <RegID>59400</RegID>
+ <Name>Debug</Name>
+ <Buttons>
+ <Len>2373</Len>
+ <Data>00200000000000001900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000002500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000002600000000000000000000000000000000010000000100000001801D800000000000002700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000002800000000000000000000000000000000010000000100000001801B80000000000000290000000000000000000000000000000001000000010000000180E57F0000000000002A00000000000000000000000000000000010000000100000001801C800000000000002B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000002C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B0000000000002D0000000000000000000000000000000001000000010000000180F07F0000000000002E0000000000000000000000000000000001000000010000000180E8880000000000003700000000000000000000000000000000010000000100000001803B010000000000002F0000000000000000000000000000000001000000010000000180BB8A00000000000030000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E0E01000000000000310000000D57617463682057696E646F7773000000000000000000000000010000000100000000000000000000000100000003001380D88B00000000000031000000085761746368202631000000000000000000000000010000000100000000000000000000000100000000001380D98B00000000000031000000085761746368202632000000000000000000000000010000000100000000000000000000000100000000001380CE01000000000000FFFFFFFF0C576174636820416E63686F720100000000000000010000000000000001000000000000000000000001000000000013800F01000000000000320000000E4D656D6F72792057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380D28B00000000000032000000094D656D6F7279202631000000000000000000000000010000000100000000000000000000000100000000001380D38B00000000000032000000094D656D6F7279202632000000000000000000000000010000000100000000000000000000000100000000001380D48B00000000000032000000094D656D6F7279202633000000000000000000000000010000000100000000000000000000000100000000001380D58B00000000000032000000094D656D6F72792026340000000000000000000000000100000001000000000000000000000001000000000013801001000000000000330000000E53657269616C2057696E646F77730000000000000000000000000100000001000000000000000000000001000000040013809307000000000000330000000855415254202326310000000000000000000000000100000001000000000000000000000001000000000013809407000000000000330000000855415254202326320000000000000000000000000100000001000000000000000000000001000000000013809507000000000000330000000855415254202326330000000000000000000000000100000001000000000000000000000001000000000013809607000000000000330000001626446562756720287072696E746629205669657765720000000000000000000000000100000001000000000000000000000001000000000013803C010000000000007200000010416E616C797369732057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380658A000000000000340000000F264C6F67696320416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380DC7F0000000000003E0000001526506572666F726D616E636520416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380E788000000000000380000000E26436F646520436F766572616765000000000000000000000000010000000100000000000000000000000100000000001380CD01000000000000FFFFFFFF0F416E616C7973697320416E63686F7201000000000000000100000000000000010000000000000000000000010000000000138053010000000000003F0000000D54726163652057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013805401000000000000FFFFFFFF115472616365204D656E7520416E63686F720100000000000000010000000000000001000000000000000000000001000000000013802901000000000000350000001553797374656D205669657765722057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013804B01000000000000FFFFFFFF1453797374656D2056696577657220416E63686F720100000000000000010000000000000001000000000000000000000001000000000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000013800189000000000000360000000F26546F6F6C626F782057696E646F7700000000000000000000000001000000010000000000000000000000010000000300138044C5000000000000FFFFFFFF0E5570646174652057696E646F77730100000000000000010000000000000001000000000000000000000001000000000013800000000000000400FFFFFFFF000000000000000000010000000000000001000000000000000000000001000000000013805B01000000000000FFFFFFFF12546F6F6C626F78204D656E75416E63686F72010000000000000001000000000000000100000000000000000000000100000000000000000005446562756764020000</Data>
+ </Buttons>
+ <OriginalItems>
+ <Len>898</Len>
+ <Data>1900FFFF01001100434D4643546F6F6C426172427574746F6ECC88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801780000000000000FFFFFFFF00010000000000000001000000000000000100000001801D80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801A80000000000000FFFFFFFF00010000000000000001000000000000000100000001801B80000000000000FFFFFFFF0001000000000000000100000000000000010000000180E57F000000000000FFFFFFFF00010000000000000001000000000000000100000001801C80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800089000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180E48B000000000000FFFFFFFF0001000000000000000100000000000000010000000180F07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180E888000000000000FFFFFFFF00010000000000000001000000000000000100000001803B01000000000000FFFFFFFF0001000000000000000100000000000000010000000180BB8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D88B000000000000FFFFFFFF0001000000000000000100000000000000010000000180D28B000000000000FFFFFFFF00010000000000000001000000000000000100000001809307000000000000FFFFFFFF0001000000000000000100000000000000010000000180658A000000000000FFFFFFFF0001000000000000000100000000000000010000000180C18A000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE8B000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800189000000000000FFFFFFFF000100000000000000010000000000000001000000</Data>
+ </OriginalItems>
+ <OrigResetItems>
+ <Len>898</Len>
+ <Data>1900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000000000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000000100000000000000000000000000000000010000000100000001801D800000000000000200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000000300000000000000000000000000000000010000000100000001801B80000000000000040000000000000000000000000000000001000000010000000180E57F0000000000000500000000000000000000000000000000010000000100000001801C800000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B000000000000080000000000000000000000000000000001000000010000000180F07F000000000000090000000000000000000000000000000001000000010000000180E8880000000000000A00000000000000000000000000000000010000000100000001803B010000000000000B0000000000000000000000000000000001000000010000000180BB8A0000000000000C0000000000000000000000000000000001000000010000000180D88B0000000000000D0000000000000000000000000000000001000000010000000180D28B0000000000000E000000000000000000000000000000000100000001000000018093070000000000000F0000000000000000000000000000000001000000010000000180658A000000000000100000000000000000000000000000000001000000010000000180C18A000000000000110000000000000000000000000000000001000000010000000180EE8B0000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180018900000000000013000000000000000000000000000000000100000001000000</Data>
+ </OrigResetItems>
+ </ToolBar>
+ <ControlBarsSummary>
+ <Bars>0</Bars>
+ <ScreenCX>1280</ScreenCX>
+ <ScreenCY>720</ScreenCY>
+ </ControlBarsSummary>
+ </ViewEx>
+ <ViewEx>
+ <ViewType>1</ViewType>
+ <ViewName>Debug</ViewName>
+ <Window>
+ <RegID>-1</RegID>
+ <PaneID>-1</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A40000004F00000080070000B3000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>2408000066000000000F0000CA000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1005</RegID>
+ <PaneID>1005</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>03000000660000009D0000005D030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>109</RegID>
+ <PaneID>109</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>03000000660000009D0000005D030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D00000012010000CF010000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1465</RegID>
+ <PaneID>1465</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>C7030000910300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1466</RegID>
+ <PaneID>1466</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>C7030000910300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1467</RegID>
+ <PaneID>1467</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>C7030000910300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1468</RegID>
+ <PaneID>1468</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>C7030000910300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1506</RegID>
+ <PaneID>1506</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>16384</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1913</RegID>
+ <PaneID>1913</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A7000000660000007D0700009A000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1935</RegID>
+ <PaneID>1935</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>32768</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>C7030000910300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1936</RegID>
+ <PaneID>1936</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>C7030000910300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1937</RegID>
+ <PaneID>1937</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>C7030000910300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1939</RegID>
+ <PaneID>1939</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>C7030000910300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1940</RegID>
+ <PaneID>1940</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>C7030000910300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1941</RegID>
+ <PaneID>1941</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>C7030000910300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>1942</RegID>
+ <PaneID>1942</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>C7030000910300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>195</RegID>
+ <PaneID>195</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>03000000660000009D0000005D030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D00000012010000CF010000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>196</RegID>
+ <PaneID>196</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>03000000660000009D0000005D030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D00000012010000CF010000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>197</RegID>
+ <PaneID>197</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>32768</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000005A010000AD0300008E010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>198</RegID>
+ <PaneID>198</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>32768</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>000000007A030000C0030000E6030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>199</RegID>
+ <PaneID>199</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000005A010000AD0300008E010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>203</RegID>
+ <PaneID>203</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>8192</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A40000006300000080070000B3000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>204</RegID>
+ <PaneID>204</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A7000000660000007D0700009A000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>221</RegID>
+ <PaneID>221</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>00000000000000000000000000000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>0A0000000A0000006E0000006E000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>2506</RegID>
+ <PaneID>2506</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>2507</RegID>
+ <PaneID>2507</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>C7030000910300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>343</RegID>
+ <PaneID>343</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A7000000660000007D0700009A000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>346</RegID>
+ <PaneID>346</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A7000000660000007D0700009A000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35141</RegID>
+ <PaneID>35141</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A7000000660000007D0700009A000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35824</RegID>
+ <PaneID>35824</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A7000000660000007D0700009A000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35885</RegID>
+ <PaneID>35885</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35886</RegID>
+ <PaneID>35886</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35887</RegID>
+ <PaneID>35887</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35888</RegID>
+ <PaneID>35888</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35889</RegID>
+ <PaneID>35889</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35890</RegID>
+ <PaneID>35890</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35891</RegID>
+ <PaneID>35891</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35892</RegID>
+ <PaneID>35892</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35893</RegID>
+ <PaneID>35893</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35894</RegID>
+ <PaneID>35894</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35895</RegID>
+ <PaneID>35895</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35896</RegID>
+ <PaneID>35896</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35897</RegID>
+ <PaneID>35897</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35898</RegID>
+ <PaneID>35898</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35899</RegID>
+ <PaneID>35899</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35900</RegID>
+ <PaneID>35900</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35901</RegID>
+ <PaneID>35901</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35902</RegID>
+ <PaneID>35902</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35903</RegID>
+ <PaneID>35903</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35904</RegID>
+ <PaneID>35904</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>35905</RegID>
+ <PaneID>35905</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>38003</RegID>
+ <PaneID>38003</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>03000000660000009D0000005D030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D00000012010000CF010000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>38007</RegID>
+ <PaneID>38007</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000005A010000AD0300008E010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>436</RegID>
+ <PaneID>436</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000005A010000AD0300008E010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D00000012010000CF010000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>437</RegID>
+ <PaneID>437</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>C7030000910300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>440</RegID>
+ <PaneID>440</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>C7030000910300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>463</RegID>
+ <PaneID>463</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000005A010000AD0300008E010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D00000012010000CF010000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>466</RegID>
+ <PaneID>466</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>030000005A010000AD0300008E010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D00000012010000CF010000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>470</RegID>
+ <PaneID>470</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>A7000000660000007D0700009A000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D0000002E020000C5000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50000</RegID>
+ <PaneID>50000</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50001</RegID>
+ <PaneID>50001</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50002</RegID>
+ <PaneID>50002</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50003</RegID>
+ <PaneID>50003</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50004</RegID>
+ <PaneID>50004</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50005</RegID>
+ <PaneID>50005</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50006</RegID>
+ <PaneID>50006</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50007</RegID>
+ <PaneID>50007</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50008</RegID>
+ <PaneID>50008</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50009</RegID>
+ <PaneID>50009</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50010</RegID>
+ <PaneID>50010</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50011</RegID>
+ <PaneID>50011</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50012</RegID>
+ <PaneID>50012</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50013</RegID>
+ <PaneID>50013</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50014</RegID>
+ <PaneID>50014</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50015</RegID>
+ <PaneID>50015</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50016</RegID>
+ <PaneID>50016</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50017</RegID>
+ <PaneID>50017</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50018</RegID>
+ <PaneID>50018</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>50019</RegID>
+ <PaneID>50019</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>1303000066000000AD03000026010000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>59392</RegID>
+ <PaneID>59392</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>953</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>8192</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>0000000000000000C40300001C000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>0A0000000A0000006E0000006E000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>59393</RegID>
+ <PaneID>0</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>00000000E603000080070000F9030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>0A0000000A0000006E0000006E000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>59399</RegID>
+ <PaneID>59399</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>476</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>8192</RecentFrameAlignment>
+ <RecentRowIndex>1</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>000000001C000000E701000038000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>0A0000000A0000006E0000006E000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>59400</RegID>
+ <PaneID>59400</PaneID>
+ <IsVisible>1</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>612</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>8192</RecentFrameAlignment>
+ <RecentRowIndex>2</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>000000001C0000006F02000038000000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>0A0000000A0000006E0000006E000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <Window>
+ <RegID>824</RegID>
+ <PaneID>824</PaneID>
+ <IsVisible>0</IsVisible>
+ <IsFloating>0</IsFloating>
+ <IsTabbed>0</IsTabbed>
+ <IsActivated>0</IsActivated>
+ <MRUWidth>32767</MRUWidth>
+ <PinState>0</PinState>
+ <RecentFrameAlignment>4096</RecentFrameAlignment>
+ <RecentRowIndex>0</RecentRowIndex>
+ <RectRecentDocked>
+ <Len>16</Len>
+ <Data>C7030000910300007D070000CD030000</Data>
+ </RectRecentDocked>
+ <RectRecentFloat>
+ <Len>16</Len>
+ <Data>560000006D000000F6000000F0000000</Data>
+ </RectRecentFloat>
+ </Window>
+ <DockMan>
+ <Len>3311</Len>
+ <Data>000000000B000000000000000020000001000000FFFFFFFFFFFFFFFFA4000000B300000080070000B7000000010000000100001004000000010000000000000000000000FFFFFFFF08000000CB00000057010000CC000000F08B00005A01000079070000D601000045890000FFFF02000B004354616262656450616E6500200000010000002408000066000000000F0000CA000000A40000004F00000080070000B30000000000000040280056080000000B446973617373656D626C7901000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFF0F53797374656D20416E616C797A657200000000D601000001000000FFFFFFFFFFFFFFFF104576656E742053746174697374696373000000004589000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFF0C0300004F000000100300003F010000000000000200000004000000010000000000000000000000FFFFFFFF2B000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C000050C3000051C3000052C3000053C3000054C3000055C3000056C3000057C3000058C3000059C300005AC300005BC300005CC300005DC300005EC300005FC3000060C3000061C3000062C3000063C3000001800040000000000000900A000066000000300B000056010000100300004F000000B00300003F01000000000000404100462B0000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFF000000000050C3000001000000FFFFFFFFFFFFFFFF000000000051C3000001000000FFFFFFFFFFFFFFFF000000000052C3000001000000FFFFFFFFFFFFFFFF000000000053C3000001000000FFFFFFFFFFFFFFFF000000000054C3000001000000FFFFFFFFFFFFFFFF000000000055C3000001000000FFFFFFFFFFFFFFFF000000000056C3000001000000FFFFFFFFFFFFFFFF000000000057C3000001000000FFFFFFFFFFFFFFFF000000000058C3000001000000FFFFFFFFFFFFFFFF000000000059C3000001000000FFFFFFFFFFFFFFFF00000000005AC3000001000000FFFFFFFFFFFFFFFF00000000005BC3000001000000FFFFFFFFFFFFFFFF00000000005CC3000001000000FFFFFFFFFFFFFFFF00000000005DC3000001000000FFFFFFFFFFFFFFFF00000000005EC3000001000000FFFFFFFFFFFFFFFF00000000005FC3000001000000FFFFFFFFFFFFFFFF000000000060C3000001000000FFFFFFFFFFFFFFFF000000000061C3000001000000FFFFFFFFFFFFFFFF000000000062C3000001000000FFFFFFFFFFFFFFFF000000000063C3000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFFA00000004F000000A400000076030000010000000200001004000000010000000000000000000000FFFFFFFF05000000ED0300006D000000C3000000C400000073940000018000100000010000008007000066000000200800008D030000000000004F000000A0000000760300000000000040410056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73000000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7300000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657300000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273010000007394000001000000FFFFFFFFFFFFFFFF04000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000001000000FFFFFFFFFFFFFFFF0000000076030000800700007A03000001000000010000100400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0F0000008F070000930700009407000095070000960700009007000091070000B5010000B801000038030000B9050000BA050000BB050000BC050000CB09000001800080000001000000440B000091030000000F0000FD030000C40300007A03000080070000E603000000000000404100560F0000001343616C6C20537461636B202B204C6F63616C73010000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF09554C494E4B706C7573000000003803000001000000FFFFFFFFFFFFFFFF084D656D6F7279203101000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFF000000000000000001000000000000000100000001000000FFFFFFFFC00300007A030000C4030000E603000001000000020000100400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000000000000FFFFFFFFFFFFFFFF000000003F010000B003000043010000000000000100000004000000010000000000000000000000FFFFFFFF06000000C5000000C7000000B4010000D2010000CF0100007794000001800080000000000000800700005A010000300B0000BE0100000000000043010000B0030000A70100000000000040820046060000000C4275696C64204F757470757400000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0E536F757263652042726F7773657200000000D201000001000000FFFFFFFFFFFFFFFF0E416C6C205265666572656E63657300000000CF01000001000000FFFFFFFFFFFFFFFF0642726F777365000000007794000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000000000000000000</Data>
+ </DockMan>
+ <ToolBar>
+ <RegID>59392</RegID>
+ <Name>File</Name>
+ <Buttons>
+ <Len>2608</Len>
+ <Data>00200000010000002800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000040004000000000000000000000000000000000100000001000000018022E100000000040005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000004000700000000000000000000000000000000010000000100000001802CE10000000004000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000004000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000004000C0000000000000000000000000000000001000000010000000180F4B00000000004000D000000000000000000000000000000000100000001000000018036B10000000004000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF88000000000400460000000000000000000000000000000001000000010000000180FE880000000004004500000000000000000000000000000000010000000100000001800B810000000004001300000000000000000000000000000000010000000100000001800C810000000004001400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F0880000020000000F000000000000000000000000000000000100000001000000FFFF0100120043555646696E64436F6D626F427574746F6EE8030000000000000000000000000000000000000000000000010000000100000096000000020020500000000014524F4D5F57415443485F444F475F454E41424C459600000000000000120014524F4D5F57415443485F444F475F454E41424C4500115357445F50494E4D55585F454E41424C4507444C50535F454E19444C50535F494F52656755736572446C7073456E746572436214426F6F7420436865636B205343454B206661696C23535550504F52545F4241545F504552494F4449435F4445544543545F4645415455524505656E64696606444C50535F4E0A4442475F444952454354094442475F4449524543174741505F434F4E4E5F4445565F53544154455F49444C451D4741505F434F4E4E5F4445565F53544154455F494E4954494154494E470A646566696E6974696F6E1D54494D5F496E69745374727563742E54494D5F534F555243455F44495604656E756D1D444C50535F4552524F525F4348414E4E454C5F4D41505F55504441544507524F4D20574447000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018024E10000000000001100000000000000000000000000000000010000000100000001800A810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E2280000000000000150000002153746172742F53746F70202644656275672053657373696F6E094374726C2B46350000000000000000000000000100000001000000000000000000000001000000020021802280000000000000150000002153746172742F53746F70202644656275672053657373696F6E094374726C2B4635000000000000000000000000010000000100000000000000000000000100000000002180E0010000000000007500000021456E65726779204D6561737572656D656E742026776974686F75742044656275670000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000160000000000000000000000000000000001000000010000000180C988000000000400180000000000000000000000000000000001000000010000000180C788000000000000190000000000000000000000000000000001000000010000000180C8880000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000021804C010000020001001A0000000F2650726F6A6563742057696E646F77000000000000000000000000010000000100000000000000000000000100000008002180DD880000000000001A0000000750726F6A656374000000000000000000000000010000000100000000000000000000000100000000002180DC8B0000000000003A00000005426F6F6B73000000000000000000000000010000000100000000000000000000000100000000002180E18B0000000000003B0000000946756E6374696F6E73000000000000000000000000010000000100000000000000000000000100000000002180E28B000000000000400000000954656D706C6174657300000000000000000000000001000000010000000000000000000000010000000000218018890000000000003D0000000E536F757263652042726F777365720000000000000000000000000100000001000000000000000000000001000000000021800000000000000400FFFFFFFF00000000000000000001000000000000000100000000000000000000000100000000002180D988000000000000390000000C4275696C64204F7574707574000000000000000000000000010000000100000000000000000000000100000000002180E38B000000000000410000000B46696E64204F75747075740000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001B000000000000000000000000000000000100000001000000000000000446696C65B9030000</Data>
+ </Buttons>
+ <OriginalItems>
+ <Len>1423</Len>
+ <Data>2800FFFF01001100434D4643546F6F6C426172427574746F6E00E1000000000000FFFFFFFF000100000000000000010000000000000001000000018001E1000000000000FFFFFFFF000100000000000000010000000000000001000000018003E1000000000000FFFFFFFF0001000000000000000100000000000000010000000180CD7F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF000000000000000000010000000000000001000000018023E1000000000000FFFFFFFF000100000000000000010000000000000001000000018022E1000000000000FFFFFFFF000100000000000000010000000000000001000000018025E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802BE1000000000000FFFFFFFF00010000000000000001000000000000000100000001802CE1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001807A8A000000000000FFFFFFFF00010000000000000001000000000000000100000001807B8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180D3B0000000000000FFFFFFFF000100000000000000010000000000000001000000018015B1000000000000FFFFFFFF0001000000000000000100000000000000010000000180F4B0000000000000FFFFFFFF000100000000000000010000000000000001000000018036B1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FF88000000000000FFFFFFFF0001000000000000000100000000000000010000000180FE88000000000000FFFFFFFF00010000000000000001000000000000000100000001800B81000000000000FFFFFFFF00010000000000000001000000000000000100000001800C81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180F088000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE7F000000000000FFFFFFFF000100000000000000010000000000000001000000018024E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800A81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802280000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C488000000000000FFFFFFFF0001000000000000000100000000000000010000000180C988000000000000FFFFFFFF0001000000000000000100000000000000010000000180C788000000000000FFFFFFFF0001000000000000000100000000000000010000000180C888000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180DD88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FB7F000000000000FFFFFFFF000100000000000000010000000000000001000000</Data>
+ </OriginalItems>
+ <OrigResetItems>
+ <Len>1423</Len>
+ <Data>2800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000000004000000000000000000000000000000000100000001000000018022E100000000000005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000000000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000000000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000000000C0000000000000000000000000000000001000000010000000180F4B00000000000000D000000000000000000000000000000000100000001000000018036B10000000000000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF880000000000000F0000000000000000000000000000000001000000010000000180FE880000000000001000000000000000000000000000000000010000000100000001800B810000000000001100000000000000000000000000000000010000000100000001800C810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F088000000000000130000000000000000000000000000000001000000010000000180EE7F00000000000014000000000000000000000000000000000100000001000000018024E10000000000001500000000000000000000000000000000010000000100000001800A810000000000001600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000180000000000000000000000000000000001000000010000000180C988000000000000190000000000000000000000000000000001000000010000000180C7880000000000001A0000000000000000000000000000000001000000010000000180C8880000000000001B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180DD880000000000001C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001D000000000000000000000000000000000100000001000000</Data>
+ </OrigResetItems>
+ </ToolBar>
+ <ToolBar>
+ <RegID>59399</RegID>
+ <Name>Build</Name>
+ <Buttons>
+ <Len>955</Len>
+ <Data>00200000000000001000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000000001C0000000000000000000000000000000001000000010000000180D07F0000000000001D000000000000000000000000000000000100000001000000018030800000000000001E000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6EC7040000000000006A0000000C4261746368204275696C2664000000000000000000000000010000000100000000000000000000000100000004000580C7040000000000006A0000000C4261746368204275696C266400000000000000000000000001000000010000000000000000000000010000000000058046070000000000006B0000000D42617463682052656275696C640000000000000000000000000100000001000000000000000000000001000000000005804707000000000000FFFFFFFF0B426174636820436C65616E0100000000000000010000000000000001000000000000000000000001000000000005809E8A0000000000001F0000000F4261746326682053657475702E2E2E000000000000000000000000010000000100000000000000000000000100000000000180D17F0000000000002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA00000000000000000000000000000000000000000000000001000000010000009600000003002050FFFFFFFF00960000000000000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000000240000000000000000000000000000000001000000010000000180A8010000000000004E00000000000000000000000000000000010000000100000001807202000000000000530000000000000000000000000000000001000000010000000180BE010000000000005000000000000000000000000000000000010000000100000000000000054275696C64DC010000</Data>
+ </Buttons>
+ <OriginalItems>
+ <Len>583</Len>
+ <Data>1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000FFFFFFFF0001000000000000000100000000000000010000000180D07F000000000000FFFFFFFF00010000000000000001000000000000000100000001803080000000000000FFFFFFFF00010000000000000001000000000000000100000001809E8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D17F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001804C8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001806680000000000000FFFFFFFF0001000000000000000100000000000000010000000180EB88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180B08A000000000000FFFFFFFF0001000000000000000100000000000000010000000180A801000000000000FFFFFFFF00010000000000000001000000000000000100000001807202000000000000FFFFFFFF0001000000000000000100000000000000010000000180BE01000000000000FFFFFFFF000100000000000000010000000000000001000000</Data>
+ </OriginalItems>
+ <OrigResetItems>
+ <Len>583</Len>
+ <Data>1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000000000000000000000000000000000000001000000010000000180D07F00000000000001000000000000000000000000000000000100000001000000018030800000000000000200000000000000000000000000000000010000000100000001809E8A000000000000030000000000000000000000000000000001000000010000000180D17F0000000000000400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000000500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001806680000000000000060000000000000000000000000000000001000000010000000180EB880000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000080000000000000000000000000000000001000000010000000180B08A000000000000090000000000000000000000000000000001000000010000000180A8010000000000000A000000000000000000000000000000000100000001000000018072020000000000000B0000000000000000000000000000000001000000010000000180BE010000000000000C000000000000000000000000000000000100000001000000</Data>
+ </OrigResetItems>
+ </ToolBar>
+ <ToolBar>
+ <RegID>59400</RegID>
+ <Name>Debug</Name>
+ <Buttons>
+ <Len>2362</Len>
+ <Data>00200000010000001900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000002500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000002600000000000000000000000000000000010000000100000001801D800000000004002700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000002800000000000000000000000000000000010000000100000001801B80000000000000290000000000000000000000000000000001000000010000000180E57F0000000000002A00000000000000000000000000000000010000000100000001801C800000000000002B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000002C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B0000020001002D0000000000000000000000000000000001000000010000000180F07F0000020001002E0000000000000000000000000000000001000000010000000180E8880000020000003700000000000000000000000000000000010000000100000001803B010000020001002F0000000000000000000000000000000001000000010000000180BB8A00000200010030000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E0E01000002000000310000000D57617463682057696E646F7773000000000000000000000000010000000100000000000000000000000100000003001380D88B00000000000031000000085761746368202631000000000000000000000000010000000100000000000000000000000100000000001380D98B00000000000031000000085761746368202632000000000000000000000000010000000100000000000000000000000100000000001380CE01000000000000FFFFFFFF0C576174636820416E63686F720100000000000000010000000000000001000000000000000000000001000000000013800F0100000200010032000000094D656D6F7279202631000000000000000000000000010000000100000000000000000000000100000004001380D28B00000000000032000000094D656D6F7279202631000000000000000000000000010000000100000000000000000000000100000000001380D38B00000000000032000000094D656D6F7279202632000000000000000000000000010000000100000000000000000000000100000000001380D48B00000000000032000000094D656D6F7279202633000000000000000000000000010000000100000000000000000000000100000000001380D58B00000000000032000000094D656D6F72792026340000000000000000000000000100000001000000000000000000000001000000000013801001000002000000330000000855415254202326310000000000000000000000000100000001000000000000000000000001000000040013809307000000000000330000000855415254202326310000000000000000000000000100000001000000000000000000000001000000000013809407000000000000330000000855415254202326320000000000000000000000000100000001000000000000000000000001000000000013809507000000000000330000000855415254202326330000000000000000000000000100000001000000000000000000000001000000000013809607000000000000330000001626446562756720287072696E746629205669657765720000000000000000000000000100000001000000000000000000000001000000000013803C010000020000003400000010416E616C797369732057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380658A000000000000340000000F264C6F67696320416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380DC7F0000000000003E0000001526506572666F726D616E636520416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380E788000000000000380000000E26436F646520436F766572616765000000000000000000000000010000000100000000000000000000000100000000001380CD01000000000000FFFFFFFF0F416E616C7973697320416E63686F7201000000000000000100000000000000010000000000000000000000010000000000138053010000000000003F0000000D54726163652057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013805401000000000000FFFFFFFF115472616365204D656E7520416E63686F720100000000000000010000000000000001000000000000000000000001000000000013802901000000000000350000001553797374656D205669657765722057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013804B01000000000000FFFFFFFF1453797374656D2056696577657220416E63686F720100000000000000010000000000000001000000000000000000000001000000000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000013800189000002000000360000000F26546F6F6C626F782057696E646F7700000000000000000000000001000000010000000000000000000000010000000300138044C5000000000000FFFFFFFF0E5570646174652057696E646F77730100000000000000010000000000000001000000000000000000000001000000000013800000000000000400FFFFFFFF000000000000000000010000000000000001000000000000000000000001000000000013805B01000000000000FFFFFFFF12546F6F6C626F78204D656E75416E63686F72010000000000000001000000000000000100000000000000000000000100000000000000000005446562756764020000</Data>
+ </Buttons>
+ <OriginalItems>
+ <Len>898</Len>
+ <Data>1900FFFF01001100434D4643546F6F6C426172427574746F6ECC88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801780000000000000FFFFFFFF00010000000000000001000000000000000100000001801D80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801A80000000000000FFFFFFFF00010000000000000001000000000000000100000001801B80000000000000FFFFFFFF0001000000000000000100000000000000010000000180E57F000000000000FFFFFFFF00010000000000000001000000000000000100000001801C80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800089000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180E48B000000000000FFFFFFFF0001000000000000000100000000000000010000000180F07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180E888000000000000FFFFFFFF00010000000000000001000000000000000100000001803B01000000000000FFFFFFFF0001000000000000000100000000000000010000000180BB8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D88B000000000000FFFFFFFF0001000000000000000100000000000000010000000180D28B000000000000FFFFFFFF00010000000000000001000000000000000100000001809307000000000000FFFFFFFF0001000000000000000100000000000000010000000180658A000000000000FFFFFFFF0001000000000000000100000000000000010000000180C18A000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE8B000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800189000000000000FFFFFFFF000100000000000000010000000000000001000000</Data>
+ </OriginalItems>
+ <OrigResetItems>
+ <Len>898</Len>
+ <Data>1900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000000000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000000100000000000000000000000000000000010000000100000001801D800000000000000200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000000300000000000000000000000000000000010000000100000001801B80000000000000040000000000000000000000000000000001000000010000000180E57F0000000000000500000000000000000000000000000000010000000100000001801C800000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B000000000000080000000000000000000000000000000001000000010000000180F07F000000000000090000000000000000000000000000000001000000010000000180E8880000000000000A00000000000000000000000000000000010000000100000001803B010000000000000B0000000000000000000000000000000001000000010000000180BB8A0000000000000C0000000000000000000000000000000001000000010000000180D88B0000000000000D0000000000000000000000000000000001000000010000000180D28B0000000000000E000000000000000000000000000000000100000001000000018093070000000000000F0000000000000000000000000000000001000000010000000180658A000000000000100000000000000000000000000000000001000000010000000180C18A000000000000110000000000000000000000000000000001000000010000000180EE8B0000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180018900000000000013000000000000000000000000000000000100000001000000</Data>
+ </OrigResetItems>
+ </ToolBar>
+ <ControlBarsSummary>
+ <Bars>0</Bars>
+ <ScreenCX>1280</ScreenCX>
+ <ScreenCY>720</ScreenCY>
+ </ControlBarsSummary>
+ </ViewEx>
+ </WinLayoutEx>
+
+ <MDIGroups>
+ <Orientation>1</Orientation>
+ <ActiveMDIGroup>0</ActiveMDIGroup>
+ <MDIGroup>
+ <Size>100</Size>
+ <ActiveTab>0</ActiveTab>
+ <Doc>
+ <Name>..\..\..\..\src\app\google_rcu\voice_module\voice.c</Name>
+ <ColumnNumber>1</ColumnNumber>
+ <TopLine>80</TopLine>
+ <CurrentLine>92</CurrentLine>
+ <Folding>1</Folding>
+ <ContractedFolders></ContractedFolders>
+ <PaneID>0</PaneID>
+ </Doc>
+ <Doc>
+ <Name>..\..\..\..\src\app\google_rcu\voice_module\voice_driver.h</Name>
+ <ColumnNumber>78</ColumnNumber>
+ <TopLine>43</TopLine>
+ <CurrentLine>54</CurrentLine>
+ <Folding>1</Folding>
+ <ContractedFolders></ContractedFolders>
+ <PaneID>0</PaneID>
+ </Doc>
+ <Doc>
+ <Name>..\..\..\..\src\app\google_rcu\loop_queue.h</Name>
+ <ColumnNumber>15</ColumnNumber>
+ <TopLine>42</TopLine>
+ <CurrentLine>56</CurrentLine>
+ <Folding>1</Folding>
+ <ContractedFolders></ContractedFolders>
+ <PaneID>0</PaneID>
+ </Doc>
+ <Doc>
+ <Name>..\..\..\..\inc\rcu\ima_adpcm_enc.h</Name>
+ <ColumnNumber>0</ColumnNumber>
+ <TopLine>2</TopLine>
+ <CurrentLine>27</CurrentLine>
+ <Folding>1</Folding>
+ <ContractedFolders></ContractedFolders>
+ <PaneID>0</PaneID>
+ </Doc>
+ <Doc>
+ <Name>..\..\..\..\src\mcu\peripheral\rtl876x_uart.c</Name>
+ <ColumnNumber>23</ColumnNumber>
+ <TopLine>55</TopLine>
+ <CurrentLine>68</CurrentLine>
+ <Folding>1</Folding>
+ <ContractedFolders></ContractedFolders>
+ <PaneID>0</PaneID>
+ </Doc>
+ <Doc>
+ <Name>..\..\..\..\inc\peripheral\rtl876x_wdg.h</Name>
+ <ColumnNumber>0</ColumnNumber>
+ <TopLine>21</TopLine>
+ <CurrentLine>46</CurrentLine>
+ <Folding>1</Folding>
+ <ContractedFolders></ContractedFolders>
+ <PaneID>0</PaneID>
+ </Doc>
+ </MDIGroup>
+ </MDIGroups>
+
+</ProjectGui>
diff --git a/board/evb/google_rcu/mdk/google_rcu.uvoptx b/board/evb/google_rcu/mdk/google_rcu.uvoptx
new file mode 100644
index 0000000..049572a
--- /dev/null
+++ b/board/evb/google_rcu/mdk/google_rcu.uvoptx
@@ -0,0 +1,1272 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<ProjectOpt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_optx.xsd">
+
+ <SchemaVersion>1.0</SchemaVersion>
+
+ <Header>### uVision Project, (C) Keil Software</Header>
+
+ <Extensions>
+ <cExt>*.c</cExt>
+ <aExt>*.s*; *.src; *.a*</aExt>
+ <oExt>*.obj; *.o</oExt>
+ <lExt>*.lib</lExt>
+ <tExt>*.txt; *.h; *.inc; *.md</tExt>
+ <pExt>*.plm</pExt>
+ <CppX>*.cpp</CppX>
+ <nMigrate>0</nMigrate>
+ </Extensions>
+
+ <DaveTm>
+ <dwLowDateTime>0</dwLowDateTime>
+ <dwHighDateTime>0</dwHighDateTime>
+ </DaveTm>
+
+ <Target>
+ <TargetName>app</TargetName>
+ <ToolsetNumber>0x4</ToolsetNumber>
+ <ToolsetName>ARM-ADS</ToolsetName>
+ <TargetOption>
+ <CLKADS>12000000</CLKADS>
+ <OPTTT>
+ <gFlags>1</gFlags>
+ <BeepAtEnd>1</BeepAtEnd>
+ <RunSim>0</RunSim>
+ <RunTarget>1</RunTarget>
+ <RunAbUc>0</RunAbUc>
+ </OPTTT>
+ <OPTHX>
+ <HexSelection>1</HexSelection>
+ <FlashByte>65535</FlashByte>
+ <HexRangeLowAddress>0</HexRangeLowAddress>
+ <HexRangeHighAddress>0</HexRangeHighAddress>
+ <HexOffset>0</HexOffset>
+ </OPTHX>
+ <OPTLEX>
+ <PageWidth>79</PageWidth>
+ <PageLength>66</PageLength>
+ <TabStop>8</TabStop>
+ <ListingPath>.\Listings\</ListingPath>
+ </OPTLEX>
+ <ListingPage>
+ <CreateCListing>1</CreateCListing>
+ <CreateAListing>1</CreateAListing>
+ <CreateLListing>1</CreateLListing>
+ <CreateIListing>0</CreateIListing>
+ <AsmCond>1</AsmCond>
+ <AsmSymb>1</AsmSymb>
+ <AsmXref>0</AsmXref>
+ <CCond>1</CCond>
+ <CCode>0</CCode>
+ <CListInc>0</CListInc>
+ <CSymb>0</CSymb>
+ <LinkerCodeListing>0</LinkerCodeListing>
+ </ListingPage>
+ <OPTXL>
+ <LMap>1</LMap>
+ <LComments>1</LComments>
+ <LGenerateSymbols>1</LGenerateSymbols>
+ <LLibSym>1</LLibSym>
+ <LLines>1</LLines>
+ <LLocSym>1</LLocSym>
+ <LPubSym>1</LPubSym>
+ <LXref>0</LXref>
+ <LExpSel>0</LExpSel>
+ </OPTXL>
+ <OPTFL>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <IsCurrentTarget>1</IsCurrentTarget>
+ </OPTFL>
+ <CpuCode>7</CpuCode>
+ <DebugOpt>
+ <uSim>0</uSim>
+ <uTrg>1</uTrg>
+ <sLdApp>1</sLdApp>
+ <sGomain>1</sGomain>
+ <sRbreak>1</sRbreak>
+ <sRwatch>1</sRwatch>
+ <sRmem>1</sRmem>
+ <sRfunc>1</sRfunc>
+ <sRbox>1</sRbox>
+ <tLdApp>1</tLdApp>
+ <tGomain>1</tGomain>
+ <tRbreak>1</tRbreak>
+ <tRwatch>1</tRwatch>
+ <tRmem>1</tRmem>
+ <tRfunc>0</tRfunc>
+ <tRbox>1</tRbox>
+ <tRtrace>1</tRtrace>
+ <sRSysVw>1</sRSysVw>
+ <tRSysVw>1</tRSysVw>
+ <sRunDeb>0</sRunDeb>
+ <sLrtime>0</sLrtime>
+ <bEvRecOn>1</bEvRecOn>
+ <bSchkAxf>0</bSchkAxf>
+ <bTchkAxf>0</bTchkAxf>
+ <nTsel>0</nTsel>
+ <sDll></sDll>
+ <sDllPa></sDllPa>
+ <sDlgDll></sDlgDll>
+ <sDlgPa></sDlgPa>
+ <sIfile></sIfile>
+ <tDll></tDll>
+ <tDllPa></tDllPa>
+ <tDlgDll></tDlgDll>
+ <tDlgPa></tDlgPa>
+ <tIfile>..\rom\startup.ini</tIfile>
+ <pMon>BIN\UL2CM3.DLL</pMon>
+ </DebugOpt>
+ <TargetDriverDllRegistry>
+ <SetRegEntry>
+ <Number>0</Number>
+ <Key>UL2CM3</Key>
+ <Name>UL2CM3(-S0 -C0 -P0 -FC1000 -FD20000000</Name>
+ </SetRegEntry>
+ <SetRegEntry>
+ <Number>0</Number>
+ <Key>JL2CM3</Key>
+ <Name>-U4294967295 -O78 -S5 -ZTIFSpeedSel1000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8001 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD200000 -FC4000 -FN2 -FF0RTL876x_SPI_FLASH -FS0800000 -FL01000000 -FF1RTL876x_LOG_TRACE -FS18000000 -FL11000000</Name>
+ </SetRegEntry>
+ <SetRegEntry>
+ <Number>0</Number>
+ <Key>ARMRTXEVENTFLAGS</Key>
+ <Name>-L70 -Z18 -C0 -M0 -T1</Name>
+ </SetRegEntry>
+ <SetRegEntry>
+ <Number>0</Number>
+ <Key>DLGTARM</Key>
+ <Name>(1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)</Name>
+ </SetRegEntry>
+ <SetRegEntry>
+ <Number>0</Number>
+ <Key>ARMDBGFLAGS</Key>
+ <Name></Name>
+ </SetRegEntry>
+ </TargetDriverDllRegistry>
+ <Breakpoint/>
+ <MemoryWindow1>
+ <Mm>
+ <WinNumber>1</WinNumber>
+ <SubType>2</SubType>
+ <ItemText>CODEC_CH0_CR_REG_BASE</ItemText>
+ <AccSizeX>0</AccSizeX>
+ </Mm>
+ </MemoryWindow1>
+ <Tracepoint>
+ <THDelay>0</THDelay>
+ </Tracepoint>
+ <DebugFlag>
+ <trace>0</trace>
+ <periodic>0</periodic>
+ <aLwin>1</aLwin>
+ <aCover>0</aCover>
+ <aSer1>0</aSer1>
+ <aSer2>0</aSer2>
+ <aPa>0</aPa>
+ <viewmode>1</viewmode>
+ <vrSel>0</vrSel>
+ <aSym>0</aSym>
+ <aTbox>0</aTbox>
+ <AscS1>0</AscS1>
+ <AscS2>0</AscS2>
+ <AscS3>0</AscS3>
+ <aSer3>0</aSer3>
+ <eProf>0</eProf>
+ <aLa>0</aLa>
+ <aPa1>0</aPa1>
+ <AscS4>0</AscS4>
+ <aSer4>0</aSer4>
+ <StkLoc>0</StkLoc>
+ <TrcWin>0</TrcWin>
+ <newCpu>0</newCpu>
+ <uProt>0</uProt>
+ </DebugFlag>
+ <LintExecutable></LintExecutable>
+ <LintConfigFile></LintConfigFile>
+ <bLintAuto>0</bLintAuto>
+ <bAutoGenD>0</bAutoGenD>
+ <LntExFlags>0</LntExFlags>
+ <pMisraName></pMisraName>
+ <pszMrule></pszMrule>
+ <pSingCmds></pSingCmds>
+ <pMultCmds></pMultCmds>
+ <pMisraNamep></pMisraNamep>
+ <pszMrulep></pszMrulep>
+ <pSingCmdsp></pSingCmdsp>
+ <pMultCmdsp></pMultCmdsp>
+ </TargetOption>
+ </Target>
+
+ <Group>
+ <GroupName>include</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>1</FileNumber>
+ <FileType>5</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\inc\platform\rom_uuid.h</PathWithFileName>
+ <FilenameWithoutPath>rom_uuid.h</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>2</FileNumber>
+ <FileType>5</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\inc\platform\app_define.h</PathWithFileName>
+ <FilenameWithoutPath>app_define.h</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>3</FileNumber>
+ <FileType>5</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\google_rcu\board.h</PathWithFileName>
+ <FilenameWithoutPath>board.h</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>4</FileNumber>
+ <FileType>5</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\google_rcu\mem_config.h</PathWithFileName>
+ <FilenameWithoutPath>mem_config.h</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>5</FileNumber>
+ <FileType>5</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\google_rcu\otp_config.h</PathWithFileName>
+ <FilenameWithoutPath>otp_config.h</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>6</FileNumber>
+ <FileType>5</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\.\version.h</PathWithFileName>
+ <FilenameWithoutPath>version.h</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>lib</GroupName>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>2</GroupNumber>
+ <FileNumber>7</FileNumber>
+ <FileType>4</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\bin\mdk\ROM.lib</PathWithFileName>
+ <FilenameWithoutPath>ROM.lib</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>2</GroupNumber>
+ <FileNumber>8</FileNumber>
+ <FileType>4</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\bin\upperstack_img\upperstack_0_0\gap_utils.lib</PathWithFileName>
+ <FilenameWithoutPath>gap_utils.lib</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>2</GroupNumber>
+ <FileNumber>9</FileNumber>
+ <FileType>4</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\bin\mdk\adc.lib</PathWithFileName>
+ <FilenameWithoutPath>adc.lib</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>2</GroupNumber>
+ <FileNumber>10</FileNumber>
+ <FileType>4</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\bin\mdk\ima_adpcm_lib.lib</PathWithFileName>
+ <FilenameWithoutPath>ima_adpcm_lib.lib</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>2</GroupNumber>
+ <FileNumber>11</FileNumber>
+ <FileType>4</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\bin\mdk\auto_k_rf.lib</PathWithFileName>
+ <FilenameWithoutPath>auto_k_rf.lib</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>2</GroupNumber>
+ <FileNumber>12</FileNumber>
+ <FileType>4</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\bin\mdk\auto_k_rf_bonding_lib_DUT.lib</PathWithFileName>
+ <FilenameWithoutPath>auto_k_rf_bonding_lib_DUT.lib</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>2</GroupNumber>
+ <FileNumber>13</FileNumber>
+ <FileType>4</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\bin\mdk\bee3_sdk.lib</PathWithFileName>
+ <FilenameWithoutPath>bee3_sdk.lib</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>cmsis</GroupName>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>3</GroupNumber>
+ <FileNumber>14</FileNumber>
+ <FileType>2</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\rtl876x\arm\startup_rtl876x.s</PathWithFileName>
+ <FilenameWithoutPath>startup_rtl876x.s</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>3</GroupNumber>
+ <FileNumber>15</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\rtl876x\system_rtl876x.c</PathWithFileName>
+ <FilenameWithoutPath>system_rtl876x.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>peripheral</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>16</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_io_dlps.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_io_dlps.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>17</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_gpio.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_gpio.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>18</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_ir.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_ir.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>19</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_keyscan.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_keyscan.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>20</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_rtc.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_rtc.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>21</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_codec.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_codec.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>22</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_i2s.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_i2s.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>23</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_pinmux.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_pinmux.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>24</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_nvic.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_nvic.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>25</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_rcc.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_rcc.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>26</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_tim.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_tim.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>27</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_gdma.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_gdma.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>28</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_uart.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_uart.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>29</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_adc.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_adc.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>30</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_lpc.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_lpc.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>4</GroupNumber>
+ <FileNumber>31</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\peripheral\rtl876x_aon_wdg.c</PathWithFileName>
+ <FilenameWithoutPath>rtl876x_aon_wdg.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>profile</GroupName>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>5</GroupNumber>
+ <FileNumber>32</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\ble\profile\server\dis.c</PathWithFileName>
+ <FilenameWithoutPath>dis.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>5</GroupNumber>
+ <FileNumber>33</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\ble\profile\server\bas.c</PathWithFileName>
+ <FilenameWithoutPath>bas.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>5</GroupNumber>
+ <FileNumber>34</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\profile_module\hids_rmc.c</PathWithFileName>
+ <FilenameWithoutPath>hids_rmc.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>5</GroupNumber>
+ <FileNumber>35</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\ble\profile\server\vendor_service.c</PathWithFileName>
+ <FilenameWithoutPath>vendor_service.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>5</GroupNumber>
+ <FileNumber>36</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\ble\profile\server\voice_service.c</PathWithFileName>
+ <FilenameWithoutPath>voice_service.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>5</GroupNumber>
+ <FileNumber>37</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\ble\profile\server\atvv_service.c</PathWithFileName>
+ <FilenameWithoutPath>atvv_service.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>5</GroupNumber>
+ <FileNumber>38</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\profile_module\ir_service.c</PathWithFileName>
+ <FilenameWithoutPath>ir_service.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>5</GroupNumber>
+ <FileNumber>39</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\profile_module\dfu_service.c</PathWithFileName>
+ <FilenameWithoutPath>dfu_service.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>5</GroupNumber>
+ <FileNumber>40</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\profile_module\ota_service.c</PathWithFileName>
+ <FilenameWithoutPath>ota_service.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>5</GroupNumber>
+ <FileNumber>41</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\profile_module\fms.c</PathWithFileName>
+ <FilenameWithoutPath>fms.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>app</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>6</GroupNumber>
+ <FileNumber>42</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\main.c</PathWithFileName>
+ <FilenameWithoutPath>main.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>6</GroupNumber>
+ <FileNumber>43</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\rcu_application.c</PathWithFileName>
+ <FilenameWithoutPath>rcu_application.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>6</GroupNumber>
+ <FileNumber>44</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\rcu_gap.c</PathWithFileName>
+ <FilenameWithoutPath>rcu_gap.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>6</GroupNumber>
+ <FileNumber>45</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\swtimer.c</PathWithFileName>
+ <FilenameWithoutPath>swtimer.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>6</GroupNumber>
+ <FileNumber>46</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\app_task.c</PathWithFileName>
+ <FilenameWithoutPath>app_task.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>6</GroupNumber>
+ <FileNumber>47</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\reset_watch_dog_timer.c</PathWithFileName>
+ <FilenameWithoutPath>reset_watch_dog_timer.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>6</GroupNumber>
+ <FileNumber>48</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\ble\privacy\privacy_mgnt.c</PathWithFileName>
+ <FilenameWithoutPath>privacy_mgnt.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>6</GroupNumber>
+ <FileNumber>49</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\mcu\rtl876x\overlay_mgr.c</PathWithFileName>
+ <FilenameWithoutPath>overlay_mgr.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>6</GroupNumber>
+ <FileNumber>50</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\loop_queue.c</PathWithFileName>
+ <FilenameWithoutPath>loop_queue.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>6</GroupNumber>
+ <FileNumber>51</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\dtm_module\rcu_dtm_app.c</PathWithFileName>
+ <FilenameWithoutPath>rcu_dtm_app.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>6</GroupNumber>
+ <FileNumber>52</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\address_module\rcu_link_mgr.c</PathWithFileName>
+ <FilenameWithoutPath>rcu_link_mgr.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>rtc</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>7</GroupNumber>
+ <FileNumber>53</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\rtc_module\rtc_driver.c</PathWithFileName>
+ <FilenameWithoutPath>rtc_driver.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>dfu</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>8</GroupNumber>
+ <FileNumber>54</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\dfu\dfu_main.c</PathWithFileName>
+ <FilenameWithoutPath>dfu_main.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>8</GroupNumber>
+ <FileNumber>55</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\dfu\dfu_task.c</PathWithFileName>
+ <FilenameWithoutPath>dfu_task.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>8</GroupNumber>
+ <FileNumber>56</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\dfu\dfu_application.c</PathWithFileName>
+ <FilenameWithoutPath>dfu_application.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>8</GroupNumber>
+ <FileNumber>57</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\platform\dfu_flash.c</PathWithFileName>
+ <FilenameWithoutPath>dfu_flash.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>key</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>9</GroupNumber>
+ <FileNumber>58</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\key_module\keyscan_driver.c</PathWithFileName>
+ <FilenameWithoutPath>keyscan_driver.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>9</GroupNumber>
+ <FileNumber>59</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\key_module\key_handle.c</PathWithFileName>
+ <FilenameWithoutPath>key_handle.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>voice</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>10</GroupNumber>
+ <FileNumber>60</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\voice_module\voice_driver.c</PathWithFileName>
+ <FilenameWithoutPath>voice_driver.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>10</GroupNumber>
+ <FileNumber>61</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\voice_module\voice.c</PathWithFileName>
+ <FilenameWithoutPath>voice.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>ir</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>11</GroupNumber>
+ <FileNumber>62</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\ir_module\ir_send_driver.c</PathWithFileName>
+ <FilenameWithoutPath>ir_send_driver.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>11</GroupNumber>
+ <FileNumber>63</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\ir_module\ir_send_handle.c</PathWithFileName>
+ <FilenameWithoutPath>ir_send_handle.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>11</GroupNumber>
+ <FileNumber>64</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\ir_module\ir_protocol_nec.c</PathWithFileName>
+ <FilenameWithoutPath>ir_protocol_nec.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>11</GroupNumber>
+ <FileNumber>65</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\ir_module\ir_service_handle.c</PathWithFileName>
+ <FilenameWithoutPath>ir_service_handle.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>led</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>12</GroupNumber>
+ <FileNumber>66</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\led_module\led_driver.c</PathWithFileName>
+ <FilenameWithoutPath>led_driver.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>12</GroupNumber>
+ <FileNumber>67</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\led_module\led_pwm_driver.c</PathWithFileName>
+ <FilenameWithoutPath>led_pwm_driver.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>buzzer</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>13</GroupNumber>
+ <FileNumber>68</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\buzzer_module\buzzer_driver.c</PathWithFileName>
+ <FilenameWithoutPath>buzzer_driver.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>13</GroupNumber>
+ <FileNumber>69</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\buzzer_module\fms_service_handle.c</PathWithFileName>
+ <FilenameWithoutPath>fms_service_handle.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>battery</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>14</GroupNumber>
+ <FileNumber>70</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\bat_module\battery_driver.c</PathWithFileName>
+ <FilenameWithoutPath>battery_driver.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>test</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>15</GroupNumber>
+ <FileNumber>71</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\test_module\data_uart_test.c</PathWithFileName>
+ <FilenameWithoutPath>data_uart_test.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>15</GroupNumber>
+ <FileNumber>72</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\test_module\mp_test.c</PathWithFileName>
+ <FilenameWithoutPath>mp_test.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>15</GroupNumber>
+ <FileNumber>73</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\test_module\single_tone.c</PathWithFileName>
+ <FilenameWithoutPath>single_tone.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>15</GroupNumber>
+ <FileNumber>74</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\test_module\uart_transport.c</PathWithFileName>
+ <FilenameWithoutPath>uart_transport.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>frm_vpk</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>16</GroupNumber>
+ <FileNumber>75</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\frm_vpk\src\app_flash_write.c</PathWithFileName>
+ <FilenameWithoutPath>app_flash_write.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>16</GroupNumber>
+ <FileNumber>76</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\frm_vpk\src\app_custom.c</PathWithFileName>
+ <FilenameWithoutPath>app_custom.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>frm_vpk_api</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>17</GroupNumber>
+ <FileNumber>77</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\frm_vpk\frm_vpk_api\frm_vpk_hal_sflash.c</PathWithFileName>
+ <FilenameWithoutPath>frm_vpk_hal_sflash.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>17</GroupNumber>
+ <FileNumber>78</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\src\app\google_rcu\frm_vpk\frm_vpk_api\frm_vpk_log.c</PathWithFileName>
+ <FilenameWithoutPath>frm_vpk_log.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+</ProjectOpt>
diff --git a/board/evb/google_rcu/mdk/google_rcu.uvprojx b/board/evb/google_rcu/mdk/google_rcu.uvprojx
new file mode 100644
index 0000000..e6b7d37
--- /dev/null
+++ b/board/evb/google_rcu/mdk/google_rcu.uvprojx
@@ -0,0 +1,925 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
+
+ <SchemaVersion>2.1</SchemaVersion>
+
+ <Header>### uVision Project, (C) Keil Software</Header>
+
+ <Targets>
+ <Target>
+ <TargetName>app</TargetName>
+ <ToolsetNumber>0x4</ToolsetNumber>
+ <ToolsetName>ARM-ADS</ToolsetName>
+ <pCCUsed>5060960::V5.06 update 7 (build 960)::.\ARMCC</pCCUsed>
+ <uAC6>0</uAC6>
+ <TargetOption>
+ <TargetCommonOption>
+ <Device>ARMCM0P_MPU</Device>
+ <Vendor>ARM</Vendor>
+ <PackID>ARM.CMSIS.5.4.0</PackID>
+ <PackURL>http://www.keil.com/pack/</PackURL>
+ <Cpu>IRAM(0x20000000,0x00020000) IROM(0x00000000,0x00040000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ESEL ELITTLE</Cpu>
+ <FlashUtilSpec></FlashUtilSpec>
+ <StartupFile></StartupFile>
+ <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000)</FlashDriverDll>
+ <DeviceId>0</DeviceId>
+ <RegisterFile>$$Device:ARMCM0P_MPU$Device\ARM\ARMCM0plus\Include\ARMCM0plus_MPU.h</RegisterFile>
+ <MemoryEnv></MemoryEnv>
+ <Cmp></Cmp>
+ <Asm></Asm>
+ <Linker></Linker>
+ <OHString></OHString>
+ <InfinionOptionDll></InfinionOptionDll>
+ <SLE66CMisc></SLE66CMisc>
+ <SLE66AMisc></SLE66AMisc>
+ <SLE66LinkerMisc></SLE66LinkerMisc>
+ <SFDFile></SFDFile>
+ <bCustSvd>0</bCustSvd>
+ <UseEnv>0</UseEnv>
+ <BinPath></BinPath>
+ <IncludePath></IncludePath>
+ <LibPath></LibPath>
+ <RegisterFilePath></RegisterFilePath>
+ <DBRegisterFilePath></DBRegisterFilePath>
+ <TargetStatus>
+ <Error>0</Error>
+ <ExitCodeStop>0</ExitCodeStop>
+ <ButtonStop>0</ButtonStop>
+ <NotGenerated>0</NotGenerated>
+ <InvalidFlash>1</InvalidFlash>
+ </TargetStatus>
+ <OutputDirectory>.\Objects\</OutputDirectory>
+ <OutputName>app</OutputName>
+ <CreateExecutable>1</CreateExecutable>
+ <CreateLib>0</CreateLib>
+ <CreateHexFile>1</CreateHexFile>
+ <DebugInformation>1</DebugInformation>
+ <BrowseInformation>1</BrowseInformation>
+ <ListingPath>.\Listings\</ListingPath>
+ <HexFormatSelection>1</HexFormatSelection>
+ <Merge32K>0</Merge32K>
+ <CreateBatchFile>0</CreateBatchFile>
+ <BeforeCompile>
+ <RunUserProg1>0</RunUserProg1>
+ <RunUserProg2>0</RunUserProg2>
+ <UserProg1Name></UserProg1Name>
+ <UserProg2Name></UserProg2Name>
+ <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+ <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+ <nStopU1X>0</nStopU1X>
+ <nStopU2X>0</nStopU2X>
+ </BeforeCompile>
+ <BeforeMake>
+ <RunUserProg1>1</RunUserProg1>
+ <RunUserProg2>1</RunUserProg2>
+ <UserProg1Name>..\..\..\..\tool\before_build_common.bat</UserProg1Name>
+ <UserProg2Name>before_build_special.bat</UserProg2Name>
+ <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+ <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+ <nStopB1X>0</nStopB1X>
+ <nStopB2X>0</nStopB2X>
+ </BeforeMake>
+ <AfterMake>
+ <RunUserProg1>1</RunUserProg1>
+ <RunUserProg2>1</RunUserProg2>
+ <UserProg1Name>..\..\..\..\tool\after_build_common.bat $J #L @L</UserProg1Name>
+ <UserProg2Name>after_build_special.bat</UserProg2Name>
+ <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+ <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+ <nStopA1X>0</nStopA1X>
+ <nStopA2X>0</nStopA2X>
+ </AfterMake>
+ <SelectedForBatchBuild>0</SelectedForBatchBuild>
+ <SVCSIdString></SVCSIdString>
+ </TargetCommonOption>
+ <CommonProperty>
+ <UseCPPCompiler>0</UseCPPCompiler>
+ <RVCTCodeConst>0</RVCTCodeConst>
+ <RVCTZI>0</RVCTZI>
+ <RVCTOtherData>0</RVCTOtherData>
+ <ModuleSelection>0</ModuleSelection>
+ <IncludeInBuild>1</IncludeInBuild>
+ <AlwaysBuild>0</AlwaysBuild>
+ <GenerateAssemblyFile>0</GenerateAssemblyFile>
+ <AssembleAssemblyFile>0</AssembleAssemblyFile>
+ <PublicsOnly>0</PublicsOnly>
+ <StopOnExitCode>3</StopOnExitCode>
+ <CustomArgument></CustomArgument>
+ <IncludeLibraryModules></IncludeLibraryModules>
+ <ComprImg>1</ComprImg>
+ </CommonProperty>
+ <DllOption>
+ <SimDllName>SARMCM3.DLL</SimDllName>
+ <SimDllArguments> -MPU </SimDllArguments>
+ <SimDlgDll>DARMCM1.DLL</SimDlgDll>
+ <SimDlgDllArguments>-pCM0+</SimDlgDllArguments>
+ <TargetDllName>SARMCM3.DLL</TargetDllName>
+ <TargetDllArguments>-MPU </TargetDllArguments>
+ <TargetDlgDll>TARMCM1.DLL</TargetDlgDll>
+ <TargetDlgDllArguments>-pCM0+</TargetDlgDllArguments>
+ </DllOption>
+ <DebugOption>
+ <OPTHX>
+ <HexSelection>1</HexSelection>
+ <HexRangeLowAddress>0</HexRangeLowAddress>
+ <HexRangeHighAddress>0</HexRangeHighAddress>
+ <HexOffset>0</HexOffset>
+ <Oh166RecLen>16</Oh166RecLen>
+ </OPTHX>
+ </DebugOption>
+ <Utilities>
+ <Flash1>
+ <UseTargetDll>1</UseTargetDll>
+ <UseExternalTool>0</UseExternalTool>
+ <RunIndependent>0</RunIndependent>
+ <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
+ <Capability>1</Capability>
+ <DriverSelection>4096</DriverSelection>
+ </Flash1>
+ <bUseTDR>1</bUseTDR>
+ <Flash2>BIN\UL2CM3.DLL</Flash2>
+ <Flash3></Flash3>
+ <Flash4></Flash4>
+ <pFcarmOut></pFcarmOut>
+ <pFcarmGrp></pFcarmGrp>
+ <pFcArmRoot></pFcArmRoot>
+ <FcArmLst>0</FcArmLst>
+ </Utilities>
+ <TargetArmAds>
+ <ArmAdsMisc>
+ <GenerateListings>0</GenerateListings>
+ <asHll>1</asHll>
+ <asAsm>1</asAsm>
+ <asMacX>1</asMacX>
+ <asSyms>1</asSyms>
+ <asFals>1</asFals>
+ <asDbgD>1</asDbgD>
+ <asForm>1</asForm>
+ <ldLst>0</ldLst>
+ <ldmm>1</ldmm>
+ <ldXref>1</ldXref>
+ <BigEnd>0</BigEnd>
+ <AdsALst>1</AdsALst>
+ <AdsACrf>1</AdsACrf>
+ <AdsANop>0</AdsANop>
+ <AdsANot>0</AdsANot>
+ <AdsLLst>1</AdsLLst>
+ <AdsLmap>1</AdsLmap>
+ <AdsLcgr>1</AdsLcgr>
+ <AdsLsym>1</AdsLsym>
+ <AdsLszi>1</AdsLszi>
+ <AdsLtoi>1</AdsLtoi>
+ <AdsLsun>1</AdsLsun>
+ <AdsLven>1</AdsLven>
+ <AdsLsxf>1</AdsLsxf>
+ <RvctClst>0</RvctClst>
+ <GenPPlst>0</GenPPlst>
+ <AdsCpuType>"Cortex-M0+"</AdsCpuType>
+ <RvctDeviceName></RvctDeviceName>
+ <mOS>0</mOS>
+ <uocRom>0</uocRom>
+ <uocRam>0</uocRam>
+ <hadIROM>1</hadIROM>
+ <hadIRAM>1</hadIRAM>
+ <hadXRAM>0</hadXRAM>
+ <uocXRam>0</uocXRam>
+ <RvdsVP>0</RvdsVP>
+ <RvdsMve>0</RvdsMve>
+ <RvdsCdeCp>0</RvdsCdeCp>
+ <hadIRAM2>0</hadIRAM2>
+ <hadIROM2>0</hadIROM2>
+ <StupSel>8</StupSel>
+ <useUlib>0</useUlib>
+ <EndSel>1</EndSel>
+ <uLtcg>0</uLtcg>
+ <nSecure>0</nSecure>
+ <RoSelD>3</RoSelD>
+ <RwSelD>3</RwSelD>
+ <CodeSel>0</CodeSel>
+ <OptFeed>0</OptFeed>
+ <NoZi1>0</NoZi1>
+ <NoZi2>0</NoZi2>
+ <NoZi3>0</NoZi3>
+ <NoZi4>0</NoZi4>
+ <NoZi5>0</NoZi5>
+ <Ro1Chk>0</Ro1Chk>
+ <Ro2Chk>0</Ro2Chk>
+ <Ro3Chk>0</Ro3Chk>
+ <Ir1Chk>1</Ir1Chk>
+ <Ir2Chk>0</Ir2Chk>
+ <Ra1Chk>0</Ra1Chk>
+ <Ra2Chk>0</Ra2Chk>
+ <Ra3Chk>0</Ra3Chk>
+ <Im1Chk>1</Im1Chk>
+ <Im2Chk>0</Im2Chk>
+ <OnChipMemories>
+ <Ocm1>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </Ocm1>
+ <Ocm2>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </Ocm2>
+ <Ocm3>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </Ocm3>
+ <Ocm4>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </Ocm4>
+ <Ocm5>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </Ocm5>
+ <Ocm6>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </Ocm6>
+ <IRAM>
+ <Type>0</Type>
+ <StartAddress>0x20000000</StartAddress>
+ <Size>0x20000</Size>
+ </IRAM>
+ <IROM>
+ <Type>1</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x40000</Size>
+ </IROM>
+ <XRAM>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </XRAM>
+ <OCR_RVCT1>
+ <Type>1</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT1>
+ <OCR_RVCT2>
+ <Type>1</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT2>
+ <OCR_RVCT3>
+ <Type>1</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT3>
+ <OCR_RVCT4>
+ <Type>1</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x40000</Size>
+ </OCR_RVCT4>
+ <OCR_RVCT5>
+ <Type>1</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT5>
+ <OCR_RVCT6>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT6>
+ <OCR_RVCT7>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT7>
+ <OCR_RVCT8>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT8>
+ <OCR_RVCT9>
+ <Type>0</Type>
+ <StartAddress>0x20000000</StartAddress>
+ <Size>0x20000</Size>
+ </OCR_RVCT9>
+ <OCR_RVCT10>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT10>
+ </OnChipMemories>
+ <RvctStartVector></RvctStartVector>
+ </ArmAdsMisc>
+ <Cads>
+ <interw>1</interw>
+ <Optim>3</Optim>
+ <oTime>0</oTime>
+ <SplitLS>0</SplitLS>
+ <OneElfS>0</OneElfS>
+ <Strict>0</Strict>
+ <EnumInt>0</EnumInt>
+ <PlainCh>0</PlainCh>
+ <Ropi>0</Ropi>
+ <Rwpi>0</Rwpi>
+ <wLevel>2</wLevel>
+ <uThumb>0</uThumb>
+ <uSurpInc>0</uSurpInc>
+ <uC99>1</uC99>
+ <uGnu>0</uGnu>
+ <useXO>0</useXO>
+ <v6Lang>1</v6Lang>
+ <v6LangP>1</v6LangP>
+ <vShortEn>1</vShortEn>
+ <vShortWch>1</vShortWch>
+ <v6Lto>0</v6Lto>
+ <v6WtE>0</v6WtE>
+ <v6Rtti>0</v6Rtti>
+ <VariousControls>
+ <MiscControls>--gnu --preinclude app_define.h --bss_threshold=0</MiscControls>
+ <Define>SUPPORT_ALONE_UPPERSTACK_IMG</Define>
+ <Undefine></Undefine>
+ <IncludePath>..\..\..\..\bin\upperstack_img\upperstack_0_0;..\..\google_rcu;..\..\..\..\src\app\google_rcu;..\..\..\..\src\app\google_rcu\bat_module;..\..\..\..\src\app\google_rcu\ir_module;..\..\..\..\src\app\google_rcu\key_module;..\..\..\..\src\app\google_rcu\led_module;..\..\..\..\src\app\google_rcu\voice_module;..\..\..\..\src\app\google_rcu\test_module;..\..\..\..\src\app\google_rcu\rtc_module;..\..\..\..\src\app\google_rcu\opus;..\..\..\..\src\app\google_rcu\profile_module;..\..\..\..\src\ble;..\..\..\..\src\ble\privacy;..\..\..\..\src\dfu;..\..\..\..\inc\app;..\..\..\..\inc\bluetooth\gap;..\..\..\..\inc\bluetooth\gap\gap_lib;..\..\..\..\inc\bluetooth\profile;..\..\..\..\inc\bluetooth\profile\server;..\..\..\..\inc\platform;..\..\..\..\inc\peripheral;..\..\..\..\inc\os;..\..\..\..\inc\rcu;..\..\..\..\inc\rcu\opus_inc;..\..\..\..\..\bluetooth\crypto;..\..\..\..\..\patch\inc;..\..\..\..\src\app\google_rcu\frm_vpk\src;..\..\..\..\src\app\google_rcu\frm_vpk\frm_vpk_api;..\..\..\..\src\app\google_rcu\frm_vpk;..\..\..\..\src\app\google_rcu\buzzer_module;..\..\..\..\src\app\google_rcu\dtm_module;..\..\..\..\src\app\google_rcu\address_module</IncludePath>
+ </VariousControls>
+ </Cads>
+ <Aads>
+ <interw>1</interw>
+ <Ropi>0</Ropi>
+ <Rwpi>0</Rwpi>
+ <thumb>1</thumb>
+ <SplitLS>0</SplitLS>
+ <SwStkChk>0</SwStkChk>
+ <NoWarn>0</NoWarn>
+ <uSurpInc>0</uSurpInc>
+ <useXO>0</useXO>
+ <ClangAsOpt>4</ClangAsOpt>
+ <VariousControls>
+ <MiscControls>--cpreproc</MiscControls>
+ <Define></Define>
+ <Undefine></Undefine>
+ <IncludePath></IncludePath>
+ </VariousControls>
+ </Aads>
+ <LDads>
+ <umfTarg>0</umfTarg>
+ <Ropi>0</Ropi>
+ <Rwpi>0</Rwpi>
+ <noStLib>0</noStLib>
+ <RepFail>1</RepFail>
+ <useFile>0</useFile>
+ <TextAddressRange>0x00000000</TextAddressRange>
+ <DataAddressRange>0x20000000</DataAddressRange>
+ <pXoBase></pXoBase>
+ <ScatterFile>.\app.sct</ScatterFile>
+ <IncludeLibs></IncludeLibs>
+ <IncludeLibsPath></IncludeLibsPath>
+ <Misc>--diag_suppress=L6314,L6312 --datacompressor off</Misc>
+ <LinkerInputFile></LinkerInputFile>
+ <DisabledWarnings></DisabledWarnings>
+ </LDads>
+ </TargetArmAds>
+ </TargetOption>
+ <Groups>
+ <Group>
+ <GroupName>include</GroupName>
+ <Files>
+ <File>
+ <FileName>rom_uuid.h</FileName>
+ <FileType>5</FileType>
+ <FilePath>..\..\..\..\inc\platform\rom_uuid.h</FilePath>
+ </File>
+ <File>
+ <FileName>app_define.h</FileName>
+ <FileType>5</FileType>
+ <FilePath>..\..\..\..\inc\platform\app_define.h</FilePath>
+ </File>
+ <File>
+ <FileName>board.h</FileName>
+ <FileType>5</FileType>
+ <FilePath>..\..\google_rcu\board.h</FilePath>
+ </File>
+ <File>
+ <FileName>mem_config.h</FileName>
+ <FileType>5</FileType>
+ <FilePath>..\..\google_rcu\mem_config.h</FilePath>
+ </File>
+ <File>
+ <FileName>otp_config.h</FileName>
+ <FileType>5</FileType>
+ <FilePath>..\..\google_rcu\otp_config.h</FilePath>
+ </File>
+ <File>
+ <FileName>version.h</FileName>
+ <FileType>5</FileType>
+ <FilePath>..\.\version.h</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>lib</GroupName>
+ <Files>
+ <File>
+ <FileName>ROM.lib</FileName>
+ <FileType>4</FileType>
+ <FilePath>..\..\..\..\bin\mdk\ROM.lib</FilePath>
+ </File>
+ <File>
+ <FileName>gap_utils.lib</FileName>
+ <FileType>4</FileType>
+ <FilePath>..\..\..\..\bin\upperstack_img\upperstack_0_0\gap_utils.lib</FilePath>
+ </File>
+ <File>
+ <FileName>adc.lib</FileName>
+ <FileType>4</FileType>
+ <FilePath>..\..\..\..\bin\mdk\adc.lib</FilePath>
+ </File>
+ <File>
+ <FileName>ima_adpcm_lib.lib</FileName>
+ <FileType>4</FileType>
+ <FilePath>..\..\..\..\bin\mdk\ima_adpcm_lib.lib</FilePath>
+ </File>
+ <File>
+ <FileName>auto_k_rf.lib</FileName>
+ <FileType>4</FileType>
+ <FilePath>..\..\..\..\bin\mdk\auto_k_rf.lib</FilePath>
+ </File>
+ <File>
+ <FileName>auto_k_rf_bonding_lib_DUT.lib</FileName>
+ <FileType>4</FileType>
+ <FilePath>..\..\..\..\bin\mdk\auto_k_rf_bonding_lib_DUT.lib</FilePath>
+ </File>
+ <File>
+ <FileName>bee3_sdk.lib</FileName>
+ <FileType>4</FileType>
+ <FilePath>..\..\..\..\bin\mdk\bee3_sdk.lib</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>cmsis</GroupName>
+ <Files>
+ <File>
+ <FileName>startup_rtl876x.s</FileName>
+ <FileType>2</FileType>
+ <FilePath>..\..\..\..\src\mcu\rtl876x\arm\startup_rtl876x.s</FilePath>
+ <FileOption>
+ <CommonProperty>
+ <UseCPPCompiler>2</UseCPPCompiler>
+ <RVCTCodeConst>0</RVCTCodeConst>
+ <RVCTZI>0</RVCTZI>
+ <RVCTOtherData>0</RVCTOtherData>
+ <ModuleSelection>0</ModuleSelection>
+ <IncludeInBuild>2</IncludeInBuild>
+ <AlwaysBuild>1</AlwaysBuild>
+ <GenerateAssemblyFile>2</GenerateAssemblyFile>
+ <AssembleAssemblyFile>2</AssembleAssemblyFile>
+ <PublicsOnly>2</PublicsOnly>
+ <StopOnExitCode>11</StopOnExitCode>
+ <CustomArgument></CustomArgument>
+ <IncludeLibraryModules></IncludeLibraryModules>
+ <ComprImg>1</ComprImg>
+ </CommonProperty>
+ <FileArmAds>
+ <Aads>
+ <interw>2</interw>
+ <Ropi>2</Ropi>
+ <Rwpi>2</Rwpi>
+ <thumb>2</thumb>
+ <SplitLS>2</SplitLS>
+ <SwStkChk>2</SwStkChk>
+ <NoWarn>2</NoWarn>
+ <uSurpInc>2</uSurpInc>
+ <useXO>2</useXO>
+ <ClangAsOpt>0</ClangAsOpt>
+ <VariousControls>
+ <MiscControls></MiscControls>
+ <Define></Define>
+ <Undefine></Undefine>
+ <IncludePath>..\rcu</IncludePath>
+ </VariousControls>
+ </Aads>
+ </FileArmAds>
+ </FileOption>
+ </File>
+ <File>
+ <FileName>system_rtl876x.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\rtl876x\system_rtl876x.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>peripheral</GroupName>
+ <Files>
+ <File>
+ <FileName>rtl876x_io_dlps.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_io_dlps.c</FilePath>
+ </File>
+ <File>
+ <FileName>rtl876x_gpio.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_gpio.c</FilePath>
+ </File>
+ <File>
+ <FileName>rtl876x_ir.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_ir.c</FilePath>
+ </File>
+ <File>
+ <FileName>rtl876x_keyscan.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_keyscan.c</FilePath>
+ </File>
+ <File>
+ <FileName>rtl876x_rtc.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_rtc.c</FilePath>
+ </File>
+ <File>
+ <FileName>rtl876x_codec.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_codec.c</FilePath>
+ </File>
+ <File>
+ <FileName>rtl876x_i2s.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_i2s.c</FilePath>
+ </File>
+ <File>
+ <FileName>rtl876x_pinmux.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_pinmux.c</FilePath>
+ </File>
+ <File>
+ <FileName>rtl876x_nvic.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_nvic.c</FilePath>
+ </File>
+ <File>
+ <FileName>rtl876x_rcc.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_rcc.c</FilePath>
+ </File>
+ <File>
+ <FileName>rtl876x_tim.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_tim.c</FilePath>
+ </File>
+ <File>
+ <FileName>rtl876x_gdma.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_gdma.c</FilePath>
+ </File>
+ <File>
+ <FileName>rtl876x_uart.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_uart.c</FilePath>
+ </File>
+ <File>
+ <FileName>rtl876x_adc.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_adc.c</FilePath>
+ </File>
+ <File>
+ <FileName>rtl876x_lpc.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_lpc.c</FilePath>
+ </File>
+ <File>
+ <FileName>rtl876x_aon_wdg.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\peripheral\rtl876x_aon_wdg.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>profile</GroupName>
+ <Files>
+ <File>
+ <FileName>dis.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\ble\profile\server\dis.c</FilePath>
+ </File>
+ <File>
+ <FileName>bas.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\ble\profile\server\bas.c</FilePath>
+ </File>
+ <File>
+ <FileName>hids_rmc.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\profile_module\hids_rmc.c</FilePath>
+ </File>
+ <File>
+ <FileName>vendor_service.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\ble\profile\server\vendor_service.c</FilePath>
+ </File>
+ <File>
+ <FileName>voice_service.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\ble\profile\server\voice_service.c</FilePath>
+ </File>
+ <File>
+ <FileName>atvv_service.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\ble\profile\server\atvv_service.c</FilePath>
+ </File>
+ <File>
+ <FileName>ir_service.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\profile_module\ir_service.c</FilePath>
+ </File>
+ <File>
+ <FileName>dfu_service.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\profile_module\dfu_service.c</FilePath>
+ </File>
+ <File>
+ <FileName>ota_service.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\profile_module\ota_service.c</FilePath>
+ </File>
+ <File>
+ <FileName>fms.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\profile_module\fms.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>app</GroupName>
+ <Files>
+ <File>
+ <FileName>main.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\main.c</FilePath>
+ </File>
+ <File>
+ <FileName>rcu_application.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\rcu_application.c</FilePath>
+ </File>
+ <File>
+ <FileName>rcu_gap.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\rcu_gap.c</FilePath>
+ </File>
+ <File>
+ <FileName>swtimer.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\swtimer.c</FilePath>
+ </File>
+ <File>
+ <FileName>app_task.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\app_task.c</FilePath>
+ </File>
+ <File>
+ <FileName>reset_watch_dog_timer.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\reset_watch_dog_timer.c</FilePath>
+ </File>
+ <File>
+ <FileName>privacy_mgnt.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\ble\privacy\privacy_mgnt.c</FilePath>
+ </File>
+ <File>
+ <FileName>overlay_mgr.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\mcu\rtl876x\overlay_mgr.c</FilePath>
+ </File>
+ <File>
+ <FileName>loop_queue.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\loop_queue.c</FilePath>
+ </File>
+ <File>
+ <FileName>rcu_dtm_app.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\dtm_module\rcu_dtm_app.c</FilePath>
+ </File>
+ <File>
+ <FileName>rcu_link_mgr.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\address_module\rcu_link_mgr.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>rtc</GroupName>
+ <Files>
+ <File>
+ <FileName>rtc_driver.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\rtc_module\rtc_driver.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>dfu</GroupName>
+ <Files>
+ <File>
+ <FileName>dfu_main.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\dfu\dfu_main.c</FilePath>
+ </File>
+ <File>
+ <FileName>dfu_task.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\dfu\dfu_task.c</FilePath>
+ </File>
+ <File>
+ <FileName>dfu_application.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\dfu\dfu_application.c</FilePath>
+ </File>
+ <File>
+ <FileName>dfu_flash.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\platform\dfu_flash.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>key</GroupName>
+ <Files>
+ <File>
+ <FileName>keyscan_driver.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\key_module\keyscan_driver.c</FilePath>
+ </File>
+ <File>
+ <FileName>key_handle.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\key_module\key_handle.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>voice</GroupName>
+ <Files>
+ <File>
+ <FileName>voice_driver.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\voice_module\voice_driver.c</FilePath>
+ </File>
+ <File>
+ <FileName>voice.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\voice_module\voice.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>ir</GroupName>
+ <Files>
+ <File>
+ <FileName>ir_send_driver.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\ir_module\ir_send_driver.c</FilePath>
+ </File>
+ <File>
+ <FileName>ir_send_handle.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\ir_module\ir_send_handle.c</FilePath>
+ </File>
+ <File>
+ <FileName>ir_protocol_nec.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\ir_module\ir_protocol_nec.c</FilePath>
+ </File>
+ <File>
+ <FileName>ir_service_handle.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\ir_module\ir_service_handle.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>led</GroupName>
+ <Files>
+ <File>
+ <FileName>led_driver.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\led_module\led_driver.c</FilePath>
+ </File>
+ <File>
+ <FileName>led_pwm_driver.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\led_module\led_pwm_driver.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>buzzer</GroupName>
+ <Files>
+ <File>
+ <FileName>buzzer_driver.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\buzzer_module\buzzer_driver.c</FilePath>
+ </File>
+ <File>
+ <FileName>fms_service_handle.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\buzzer_module\fms_service_handle.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>battery</GroupName>
+ <Files>
+ <File>
+ <FileName>battery_driver.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\bat_module\battery_driver.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>test</GroupName>
+ <Files>
+ <File>
+ <FileName>data_uart_test.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\test_module\data_uart_test.c</FilePath>
+ </File>
+ <File>
+ <FileName>mp_test.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\test_module\mp_test.c</FilePath>
+ </File>
+ <File>
+ <FileName>single_tone.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\test_module\single_tone.c</FilePath>
+ </File>
+ <File>
+ <FileName>uart_transport.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\test_module\uart_transport.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>frm_vpk</GroupName>
+ <Files>
+ <File>
+ <FileName>app_flash_write.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\frm_vpk\src\app_flash_write.c</FilePath>
+ </File>
+ <File>
+ <FileName>app_custom.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\frm_vpk\src\app_custom.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>frm_vpk_api</GroupName>
+ <Files>
+ <File>
+ <FileName>frm_vpk_hal_sflash.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\frm_vpk\frm_vpk_api\frm_vpk_hal_sflash.c</FilePath>
+ </File>
+ <File>
+ <FileName>frm_vpk_log.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\src\app\google_rcu\frm_vpk\frm_vpk_api\frm_vpk_log.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ </Groups>
+ </Target>
+ </Targets>
+
+ <RTE>
+ <packages>
+ <filter>
+ <targetInfos/>
+ </filter>
+ <package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="5.4.0">
+ <targetInfos>
+ <targetInfo name="app" versionMatchMode="fixed"/>
+ </targetInfos>
+ </package>
+ </packages>
+ <apis/>
+ <components/>
+ <files/>
+ </RTE>
+
+ <LayerInfo>
+ <Layers>
+ <Layer>
+ <LayName>google_rcu</LayName>
+ <LayPrjMark>1</LayPrjMark>
+ </Layer>
+ </Layers>
+ </LayerInfo>
+
+</Project>
diff --git a/board/evb/google_rcu/mem_config.h b/board/evb/google_rcu/mem_config.h
new file mode 100644
index 0000000..be33a6a
--- /dev/null
+++ b/board/evb/google_rcu/mem_config.h
@@ -0,0 +1,81 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file mem_config.h
+ * @brief Memory Configuration
+ * @date 2017.6.6
+ * @version v1.0
+ * *************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ * *************************************************************************************
+ */
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef MEM_CONFIG_H
+#define MEM_CONFIG_H
+
+#include "flash_map.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*============================================================================*
+ * Code configuration
+ *============================================================================*/
+/** @brief set app bank to support OTA: 1 is ota bank1, 0 is ota bank0 */
+#define APP_BANK 0
+
+/** @brief ram code configuration: 1 is ram code, 0 is flash code */
+#define FEATURE_RAM_CODE 0
+
+/** @brief encrypt app or not */
+#define FEATURE_ENCRYPTION 0
+
+
+/*============================================================================*
+ * data ram layout configuration
+ *============================================================================*/
+/* Data RAM layout: 88K
+example:
+ 1) reserved for rom: 14K (fixed)
+ 2) Patch: 15K (fixed)
+ 3) upperstack: 2K (adjustable, depend on used upperstack version)
+ 4) app global + ram code: 24K (adjustable, config APP_GLOBAL_SIZE)
+ 5) Heap ON: 33K (adjustable, config HEAP_DATA_ON_SIZE)
+*/
+
+/** @brief data ram size for upperstack global variables and code */
+#define UPPERSTACK_GLOBAL_SIZE (2 * 1024)
+
+/** @brief data ram size for app global variables and code, could be changed */
+#define APP_GLOBAL_SIZE (20 * 1024)
+
+/** @brief data ram size for heap, could be changed, but (UPPERSTACK_GLOBAL_SIZE + APP_GLOBAL_SIZE + HEAP_DATA_ON_SIZE) must be 59k */
+#define HEAP_DATA_ON_SIZE (59 * 1024 - APP_GLOBAL_SIZE - UPPERSTACK_GLOBAL_SIZE)
+
+/** @brief shared cache ram size (adjustable, config SHARE_CACHE_RAM_SIZE: 0/4KB/8KB) */
+#define SHARE_CACHE_RAM_SIZE (0 * 1024)
+/*****************************************************/
+
+
+/***************The following macros can't be modified***************/
+#define DATA_RAM_START_ADDR 0x00200000
+#define DATA_RAM_TOTAL_SIZE (88 * 1024)
+#define DATA_RAM_RESERVED_SIZE (29 * 1024)
+
+#define APP_GLOBAL_ADDR (DATA_RAM_START_ADDR + DATA_RAM_RESERVED_SIZE + UPPERSTACK_GLOBAL_SIZE)
+#define SHARE_CACHE_RAM_ADDR (DATA_RAM_START_ADDR + DATA_RAM_TOTAL_SIZE)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/** @} */ /* End of group MEM_CONFIG */
+#endif
diff --git a/board/evb/google_rcu/mp.ini b/board/evb/google_rcu/mp.ini
new file mode 100644
index 0000000..8c9626a
--- /dev/null
+++ b/board/evb/google_rcu/mp.ini
@@ -0,0 +1,51 @@
+; This is a config file used by prepend_header tool to generate MP header for a given image.
+;
+; The following four sections are mandatory: BinID, Version, PartNumber and DataLength. Among
+; which the DataLength key is not really needed to write in this file, as it would be calculated
+; by the prepend_header tool and automatically filled in the MP header.
+;
+; Note that MP header is a 512 bytes fixed data area, pay attention to the long strings you have
+; written and ensure they are not out of bound of the header.
+
+
+[MandatoryInfo]
+
+; To recognize what is this .bin and where is came from. Defined IDs are: ID_APP, ID_PATCH,
+; ID_CONFIG, ID_SECURE_BOOTLOADER, ID_OTA_HEADER, ID_APP_DATA1, ID_APP_DATA2
+BinID=ID_APP
+
+; This bin version (suggested sync with tool version). Range: 0.0.0.0 ~ 255.255.255.255
+Version=1.0.0.0
+
+; This bin is for what IC part number, ASCII type, 32 bytes maximum.
+PartNumber=RTL8762E
+
+
+[OptionalInfo]
+
+; Optional. Depended on what other .bins, for .bin merging check. Fill the required version number
+; in specific field if specific image is needed. Item would be ignored if the format of the value
+; is wrong or the value is not exist.
+DependOnConfig =
+DependOnPatch =
+DependOnApp =
+DependOnAppData =
+DependOnAppDataTone =
+DependOnAppDataVp =
+DependOnAppDspParam =
+DependOnDspSys =
+DependOnDspPatch =
+DependOnDspScenario1 =
+DependOnDspScenario2 =
+
+; Optional ASCII type comment string, 255 bytes maximum.
+Comment=
+
+; Optional ASCII type author information string, 255 bytes maximum.
+Author=
+
+; Optional ASCII type date and time string, 255 bytes maximum.
+Date=
+
+; Optional bin header format revision.
+Revision=0x01
diff --git a/board/evb/google_rcu/otp_config.h b/board/evb/google_rcu/otp_config.h
new file mode 100644
index 0000000..92de85a
--- /dev/null
+++ b/board/evb/google_rcu/otp_config.h
@@ -0,0 +1,135 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file otp_config.h
+ * @brief Update Configuration in APP
+ * @date 2020.03.10
+ * @version v1.1
+ * *************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2020 Realtek Semiconductor Corporation</center></h2>
+ * *************************************************************************************
+ */
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef OTP_CONFIG_H
+#define OTP_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "rtl876x_wdg.h"
+/*============================================================================*
+ * debug configuration
+ *============================================================================*/
+/** @brief just for OTA Demo test */
+#define OTA_TEST 0
+/** @brief just for OTA Demo test */
+#define OTA_TEST_BANK_SWITCH 0
+#if (OTA_TEST_BANK_SWITCH == 0)
+#define OTA_TEST_IMAGE_VERSION 0
+#endif
+
+/** @brief just for debug */
+#define SYSTEM_TRACE_ENABLE 0
+
+
+/*============================================================================*
+ * flash configuration
+ *============================================================================*/
+/** @brief support for puran flash*/
+#define FTL_APP_CALLBACK_ENABLE 0
+/** @brief modify ftl logic space size to adjust the RAM footprint of the ftl Mapping Table
+ * PAGE_ELEMENT_DATA_NUM = ((FMC_PAGE_SIZE / 8) - 1).
+ * MAX_LOGICAL_ADDR_SIZE = (((PAGE_ELEMENT_DATA_NUM * (g_page_num - 1)) - 1) << 2)
+ * if sector size is 4KB, PAGE_ELEMENT_DATA_NUM equal 511.
+ * g_page_num = ftl physical size / FMC_PAGE_SIZE. so if ftl size is 16KB, g_page_num is 4.
+ * example: default ftl size in flash layout is 16KB, MAX_LOGICAL_ADDR_SIZE = 0x17F0 = 6128
+ * FTL_REAL_LOGIC_ADDR_SIZE must be less or equal MAX_LOGICAL_ADDR_SIZE, otherwise will init ftl fail.
+*/
+#define FTL_REAL_LOGIC_ADDR_SIZE (4 * 1024)
+/** @brief enable BP, set lock level depend on flash layout and selected flash id */
+#define FLASH_BLOCK_PROTECT_ENABLE 0
+/** @brief modify delay time for wakeup flash from power down mode to standby mode*/
+#define AFTER_TOGGLE_CS_DELAY 6
+
+
+/*============================================================================*
+ * platform configuration
+ *============================================================================*/
+/** @brief default enable swd pinmux */
+#define SWD_PINMUX_ENABLE 0
+/** @brief enable aon wdg which continue work in dlps state */
+#define AON_WDG_ENABLE 1
+/** @brief set aon wdg timeout period in seconds, max value is 65s */
+#define AON_WDG_TIME_OUT_PERIOD_SECOND 31
+/** @brief default disable watch dog in rom */
+#define ROM_WATCH_DOG_ENABLE 1
+/** @brief set wdg mode, default reset all */
+#define ROM_WATCH_DOG_MODE RESET_ALL
+/** @brief Watch Dog Timer Config, default 4s timeout
+ * div_factor: 16Bit: 32.768k/(1+divfactor).
+ * cnt_limit: 2^(cnt_limit+1) - 1 ; max 11~15 = 0xFFF.
+ * wdg_mode:
+ * 1: RESET_ALL_EXCEPT_AON
+ * 3: RESET_ALL
+**/
+#define ROM_WATCH_DOG_CFG_DIV_FACTOR 31
+#define ROM_WATCH_DOG_CFG_CNT_LIMIT 15
+
+/*before wdg system reset, write reset reason to specific flash addr if enable*/
+#define WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE 0
+#if (WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE > 0)
+/*write reset reason to specific flash address*/
+#define REBOOT_REASON_RECORD_ADDRESS 0x8cb000
+/*max number of reboot record (2^n), one reset reason need 4 bytes, occupy flash size equal 2^(n+2)*/
+#define REBOOT_REASON_RECORD_LIMIT_POWERT2 10 //reserve 4K
+#endif
+
+
+/*============================================================================*
+ * upperstack configuration
+ *============================================================================*/
+//#define BT_STACK_CONFIG_ENABLE
+
+//#ifdef BT_STACK_CONFIG_ENABLE
+//void bt_stack_config_init(void);
+//#endif
+
+/*============================================================================*
+* OTA configuration
+*============================================================================*/
+/*If support unsafe single bank ota user data, must define the following macros */
+#define SUPPORT_SINGLE_BANK_OTA_USER_DATA
+#ifdef SUPPORT_SINGLE_BANK_OTA_USER_DATA
+#define USER_DATA_START_ADDR 0x00840000 //back 8M(0x1000000) or 0x00840000
+#define USER_DATA_MAX_SIZE (1025 * 1024) //1M+1K
+#endif
+
+/*normal ota timeout settings*/
+#define OTA_TIMEOUT_TOTAL 240
+#define OTA_TIMEOUT_WAIT4_CONN 60
+#define OTA_TIMEOUT_WAIT4_IMAGE_TRANS 200
+#define OTA_TIMEOUT_CTITTV 0xFF
+
+
+/*============================================================================*
+ * app configuration
+ *============================================================================*/
+//add more here
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/** @} */ /* End of group OTP_CONFIG */
+#endif
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/board/evb/google_rcu/platform_autoconf.h b/board/evb/google_rcu/platform_autoconf.h
new file mode 100644
index 0000000..5275d49
--- /dev/null
+++ b/board/evb/google_rcu/platform_autoconf.h
@@ -0,0 +1,46 @@
+/**
+************************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+************************************************************************************************************
+* @file platform_autoconf.h
+* @brief Platform configuration
+* @author
+* @date 2020-02-24
+* @version v1.0
+*************************************************************************************************************
+*/
+#ifndef _PLATFORM_AUTOCONF_H_
+#define _PLATFORM_AUTOCONF_H_
+
+#include "board.h"
+
+/** @defgroup BUILD_CONFIGURATION Build Configuration
+ * @brief Platform build configuration
+ * @{
+ */
+#if IS_RELEASE_VERSION
+#define RELEASE_VERSION
+#endif
+
+#ifdef RELEASE_VERSION
+#define CHECK_STACK_OVERFLOW_ENABLE 0
+#define CHECK_LOG_BUFFER_BEFORE_DLPS_ENABLE 0
+#define PLATFORM_ASSERT_ENABLE 0
+#define CONFIG_LOG_FUNCTION_ENABLE 0
+#define RUN_APP_IN_HCIMODE_ENABLE 0
+#define DEBUG_WATCHPOINT_ENABLE 0
+#else
+#define CHECK_STACK_OVERFLOW_ENABLE 1
+#define CHECK_LOG_BUFFER_BEFORE_DLPS_ENABLE 1
+#define PLATFORM_ASSERT_ENABLE 1
+#define CONFIG_LOG_FUNCTION_ENABLE 1
+#define RUN_APP_IN_HCIMODE_ENABLE 0
+#define DEBUG_WATCHPOINT_ENABLE 0
+#endif
+
+
+/** End of BUILD_CONFIGURATION
+ * @}
+ */
+
+#endif /* End of _PLATFORM_AUTOCONF_H_ */
diff --git a/board/evb/google_rcu/version.h b/board/evb/google_rcu/version.h
new file mode 100644
index 0000000..21cb341
--- /dev/null
+++ b/board/evb/google_rcu/version.h
@@ -0,0 +1,21 @@
+#define VERSION_MAJOR 2
+#define VERSION_MINOR 2
+#define VERSION_REVISION 0
+#define VERSION_BUILDNUM 1
+#define VERSION_GCID 0xa27967be
+#define VERSION_GCID2 0x50850203
+#define CUSTOMER_NAME sdk
+#define CN_1 's'
+#define CN_2 'd'
+#define CN_3 'k'
+#define CN_4 '#'
+#define CN_5 '#'
+#define CN_6 '#'
+#define CN_7 '#'
+#define CN_8 '#'
+#define BUILDING_TIME "Wed Mar 17 09:56:33 2021"
+#define NAME2STR(a) #a
+#define CUSTOMER_NAME_S #NAME2STR(CUSTOMER_NAME)
+#define NUM4STR(a,b,c,d) #a "." #b "." #c "." #d
+#define VERSIONBUILDSTR(a,b,c,d) NUM4STR(a,b,c,d)
+#define VERSION_BUILD_STR VERSIONBUILDSTR(VERSION_MAJOR,VERSION_MINOR,VERSION_REVISION,VERSION_BUILDNUM)
diff --git a/inc/app/app_msg.h b/inc/app/app_msg.h
new file mode 100644
index 0000000..a1405fa
--- /dev/null
+++ b/inc/app/app_msg.h
@@ -0,0 +1,226 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+ * @file app_msg.h
+ * @brief Message definition for user application task.
+ * @note If new message types/sub types are to be added, add to the end of enumeration.
+ * The orders are NOT to changed.
+ * @author Lory
+ * @date 2017.2.9
+ * @version v1.0
+*********************************************************************************************************
+*/
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+
+#ifndef _APP_MSG_H_
+#define _APP_MSG_H_
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @defgroup APP_MSG APP Message
+ * @brief message definition for user application task
+ * @{
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup APP_MSG_Exported_Types APP Message Exported Types
+ * @{
+ */
+
+/** @brief Event type definitions.*/
+typedef enum
+{
+ EVENT_GAP_MSG = 0x01, /**< message from gap layer for stack */
+ EVENT_IO_TO_APP = 0x02, /**< message from IO to user application */
+} T_EVENT_TYPE;
+
+/** @brief IO type definitions for IO message, may extend as requested */
+typedef enum
+{
+ IO_MSG_TYPE_BT_STATUS, /**< BT status change with subtype @ref GAP_MSG_TYPE */
+ IO_MSG_TYPE_KEYSCAN, /**< Key scan message with subtype @ref T_IO_MSG_KEYSCAN */
+ IO_MSG_TYPE_QDECODE, /**< subtype to be defined */
+ IO_MSG_TYPE_UART, /**< Uart message with subtype @ref T_IO_MSG_UART */
+ IO_MSG_TYPE_KEYPAD, /**< subtype to be defined */
+ IO_MSG_TYPE_IR, /**< subtype to be defined */
+ IO_MSG_TYPE_GDMA, /**< subtype to be defined */
+ IO_MSG_TYPE_ADC, /**< subtype to be defined */
+ IO_MSG_TYPE_D3DG, /**< subtype to be defined */
+ IO_MSG_TYPE_SPI, /**< subtype to be defined */
+ IO_MSG_TYPE_MOUSE_BUTTON, /**< subtype to be defined */
+ IO_MSG_TYPE_GPIO, /**< Gpio message with subtype @ref T_IO_MSG_GPIO*/
+ IO_MSG_TYPE_MOUSE_SENSOR, /**< subtype to be defined */
+ IO_MSG_TYPE_TIMER, /**< App timer message with subtype @ref T_IO_MSG_TIMER */
+ IO_MSG_TYPE_WRISTBNAD, /**< wristband message with subtype @ref T_IO_MSG_WRISTBAND */
+ IO_MSG_TYPE_MESH_STATUS, /**< subtype to be defined */
+ IO_MSG_TYPE_KEYBOARD_BUTTON, /**< subtype to be defined */
+ IO_MSG_TYPE_ANCS, /**< ANCS message*/
+ IO_MSG_TYPE_IR_LEARN_DATA, /**< ir learn data message*/
+ IO_MSG_TYPE_IR_LEARN_STOP, /**< ir learn stop message*/
+ IO_MSG_TYPE_IR_START_SEND_REPEAT_CODE, /**< ir send repeat code message*/
+ IO_MSG_TYPE_IR_SEND_COMPLETE, /**< ir send complete message*/
+ IO_MSG_TYPE_BAT_LPC, /**< lpc send low power message*/
+ IO_MSG_TYPE_BAT_DETECT, /**< BAT adc detect battery value*/
+ IO_MSG_TYPE_AUDIO, /**< Audio message with subtype @ref T_IO_MSG_TYPE_AUDIO*/
+ IO_MSG_TYPE_RESET_WDG_TIMER, /**< reset watch dog timer*/
+ IO_MSG_TYPE_RESET_AON_WDG_TIMER, /**< reset aon watch dog timer*/
+ IO_MSG_TYPE_BBPRO_HCI, /**< bbpro hci message*/
+ IO_MSG_TYPE_RTC, /**< subtype to be defined */
+ IO_MSG_TYPE_I2C, /**< subtype to be defined */
+ IO_MSG_TYPE_WIFI_UART, /**< wifi uart message */
+ IO_MSG_TYPE_PD_TIMER,
+ IO_MSG_TYPE_AMA_BT_MSG,
+ IO_MSG_TYPE_DFU_VALID_FW,
+ IO_MSG_TYPE_VOICE, /**< voice message */
+ IO_MSG_TYPE_IR_FLASH,
+ IO_MSG_TYPE_LE_AUDIO,
+ IO_MSG_TYPE_DONGLE_STOP_SYNC,
+ IO_MSG_TYPE_LATENCY,
+ IO_MSG_TYPE_MOUSE_MODE_MONITOR,
+} T_IO_MSG_TYPE;
+
+/** @brief IO subtype definitions for @ref IO_MSG_TYPE_ADC type */
+typedef enum
+{
+ IO_MSG_ADC_FIFO_READ_ERR,
+ IO_MSG_ADC_FIFO_OVERFLOW,
+} T_IO_MSG_TYPE_ADC;
+
+/** @brief IO subtype definitions for @ref IO_MSG_TYPE_AUDIO type */
+typedef enum
+{
+ IO_MSG_AUDIO_INPUT_BUFF_READY,
+ IO_MSG_AUDIO_PROCESS_DONE,
+ IO_MSG_AUDIO_TIMEOUT,
+ IO_MSG_AUDIO_HD_ATTACHED,
+ IO_MSG_AUDIO_HD_DETACHED,
+} T_IO_MSG_TYPE_AUDIO;
+
+/** @brief IO subtype definitions for @ref IO_MSG_TYPE_KEYSCAN type */
+typedef enum
+{
+ IO_MSG_KEYSCAN_RX_PKT = 1, /**< Keyscan RX data event */
+ IO_MSG_KEYSCAN_MAX = 2, /**< */
+ IO_MSG_KEYSCAN_ALLKEYRELEASE = 3, /**< All keys are released event */
+ IO_MSG_KEYSCAN_STUCK = 4, /**< key stuck message */
+ IO_MSG_KEYSCAN_LONG_PRESS = 5,
+ IO_MSG_KEYSCAN_REPEAT_SEND = 6,
+} T_IO_MSG_KEYSCAN;
+
+/** @brief IO subtype definitions for @ref IO_MSG_TYPE_UART type */
+typedef enum
+{
+ IO_MSG_UART_RX = 1,
+ IO_MSG_UART_RX_TIMEOUT = 2,
+ IO_MSG_UART_RX_OVERFLOW = 3,
+ IO_MSG_UART_RX_TIMEOUT_OVERFLOW = 4,
+ IO_MSG_UART_RX_EMPTY = 5,
+} T_IO_MSG_UART;
+
+/** @brief IO subtype definitions for @ref IO_MSG_TYPE_GPIO type */
+typedef enum
+{
+ IO_MSG_GPIO_KEY, /**< KEY GPIO event */
+ IO_MSG_GPIO_LINE_IN, /**< LINE IN event */
+ IO_MSG_GPIO_NFC, /**< NFC event */
+ IO_MSG_GPIO_UART_WAKE_UP, /**< UART WAKE UP event */
+ IO_MSG_GPIO_CHARGER, /**< CHARGER event */
+} T_IO_MSG_GPIO;
+
+/** @brief IO subtype definitions for @ref IO_MSG_TYPE_TIMER type */
+typedef enum
+{
+ IO_MSG_TIMER_ALARM,
+ IO_MSG_TIMER_RWS
+} T_IO_MSG_TIMER;
+
+/** @brief IO subtype definitions for @ref IO_MSG_TYPE_WRISTBNAD type */
+typedef enum
+{
+ IO_MSG_BWPS_TX_VALUE,
+ IO_MSG_RTC_TIMEROUT_WALL_CLOCK,
+ IO_MSG_SENSOR_WAKE_UP,
+ IO_MSG_LED_TWINKLE,
+ IO_MSG_MOTOR_VIBRATE,
+ IO_MSG_CHARGER_STATE,
+ IO_MSG_RTC_LOW_BATTERY_RESTORE,
+ IO_MSG_RTC_ALARM,
+ IO_MSG_POWER_OFF,
+ IO_MSG_POWER_ON,
+ IO_MSG_HRS_EVENT,
+ IO_MSG_SENSOR_MOTION_INTERRUPT,
+ IO_MSG_UART_CMD_DEBUG,
+ IO_MSG_HRS_TIMEOUT_HANDLE,
+ IO_MSG_UPDATE_CONPARA,
+ IO_MSG_REPORT_BUTTON,
+ IO_MSG_UART_GPS,
+ IO_MSG_UART_DEBUG_RX,
+ IO_MSG_WAS_RX_VALUE,
+ IO_MSG_WAS_ENABLE_CCCD,
+ IO_MSG_VOICE_DMA_RX,
+ IO_MSG_TOUCH_GES,
+ IO_MSG_TOUCH_INT,
+ IO_MSG_TOUCH_TIMEOUT,
+ IO_MSG_TOUCH_HANDLE,
+ IO_MSG_MENU_TIMER,
+ IO_MSG_LCD_SYNC,
+ IO_MSG_MAGIC_OPEN_ADV,
+ IO_MSG_MAGIC_PAIR_ADV,
+ IO_MSG_MAGIC_STOP_ADV,
+ IO_MSG_BREEZE_AIS_CB,
+ IO_MSG_ANCS_DISCOVERY,
+ IO_MSG_TYPE_AMS
+} T_IO_MSG_WRISTBAND;
+
+/** @brief IO subtype definitions for @ref IO_MSG_TYPE_BBPRO_HCI type */
+typedef enum
+{
+ IO_MSG_BBPRO_HCI_RX_PKT = 1, /**< BBPRO HCI RX data event */
+ IO_MSG_BBPRO_HCI_RETRANS = 2, /**< BBPRO HCI retransmission event*/
+ IO_MSG_BBPRO_HCI_RETRANS_FAIL = 3, /**< BBPRO HCI retransmission failed event*/
+ IO_MSG_BBPRO_HCI_TIMEOUT = 4, /**< BBPRO HCI timeout event */
+} T_IO_MSG_BBPRO_HCI;
+
+/** @brief IO subtype definitions for @ref IO_MSG_TYPE_UART type */
+typedef enum
+{
+ IO_MSG_WIFI_UART_RX_PKT = 1, /**< WIFI UART RX data event */
+ IO_MSG_WIFI_UART_RETRANS = 2, /**< WIFI UART retransmission event*/
+ IO_MSG_WIFI_UART_RETRANS_FAIL = 3, /**< WIFI UART retransmission failed event*/
+} T_IO_MSG_WIFI_UART;
+
+
+/** @brief IO message definition for communications between tasks*/
+typedef struct
+{
+ uint16_t type;
+ uint16_t subtype;
+ union
+ {
+ uint32_t param;
+ void *buf;
+ } u;
+} T_IO_MSG;
+
+/** @} */ /* End of group APP_MSG_Exported_Types */
+
+/** @} */ /* End of group APP_MSG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _APP_MSG_H_ */
diff --git a/inc/app/dfu_api.h b/inc/app/dfu_api.h
new file mode 100644
index 0000000..c828cbf
--- /dev/null
+++ b/inc/app/dfu_api.h
@@ -0,0 +1,179 @@
+/**
+************************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+************************************************************************************************************
+* @file dfu_api.h
+* @brief APIs to implement device firmware update.
+* @details OTA is used to update device firmware via bluetooth.
+* @author ranhui
+* @date 2015-10-29
+* @version v1.0
+*************************************************************************************************************
+*/
+
+#ifndef _DFU_API_H_
+#define _DFU_API_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#include "string.h"
+#include "patch_header_check.h"
+#include "sha256.h"
+
+#define MAJOR_IMG_VER(p) (p & 0xf)
+#define MINOR_IMG_VER(p) ((p & 0xff0) >> 4)
+#define REVISION_IMG_VER(p) ((p & 0x07fff000) >> 12)
+#define RESERVE_IMG_VER(p) ((p & 0xf8000000) >> 27)
+
+/*convert T_IMAGE_VERSION to little endian uint32_t value, so that compare version value directly */
+#define IMAGE_VERSION_TO_LE_UINT32(ver) (((ver & 0xf) << 28 )\
+ + (((ver & 0xff0) >> 4) << 20)\
+ + (((ver & 0x07fff000) >> 12) << 5)\
+ + ((ver & 0xf8000000) >> 27))
+
+
+/* dfu service uuid */
+#define GATT_UUID128_DFU_SERVICE 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0x87, 0x62, 0x00, 0x00
+#define GATT_UUID128_DFU_DATA 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0x87, 0x63, 0x00, 0x00
+#define GATT_UUID128_DFU_CONTROL_POINT 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0x87, 0x64, 0x00, 0x00
+
+/*length of each control point procedure*/
+#define DFU_LENGTH_START_DFU (1+12+4)/*4 bytes is padding for encrypt*/
+#define DFU_LENGTH_RECEIVE_FW_IMAGE_INFO (1+2+4) //img_id + cur_offset
+#define DFU_LENGTH_VALID_FW (1+2) //img_id
+#define DFU_LENGTH_ACTIVE_IMAGE_RESET (1)
+#define DFU_LENGTH_ACTIVE_IMAGE_RESET_TO_OTA_MODE (1+1) //uint8_t reset_mode, 1: reset to ota mode
+#define DFU_LENGTH_SYSTEM_RESET (1)
+#define DFU_LENGTH_REPORT_TARGET_INFO (1+2) //img_id
+#define DFU_LENGTH_CONN_PARA_TO_UPDATE_REQ (1+2+2+2+2) //conn_interval_min,conn_interval_max,conn_latency,superv_tout
+#define DFU_LENGTH_BUFFER_CHECK_EN (1)
+#define DFU_LENGTH_REPORT_BUFFER_CRC (1+2+2) //buf_size, buf_crc
+#define DFU_LENGTH_MAX DFU_LENGTH_START_DFU
+
+/*length of notification*/
+#define DFU_NOTIFY_LENGTH_ARV 3 //others opcode notification length
+#define DFU_NOTIFY_LENGTH_START_DFU (DFU_NOTIFY_LENGTH_ARV)
+#define DFU_NOTIFY_LENGTH_VALID_FW (DFU_NOTIFY_LENGTH_ARV)
+#define DFU_NOTIFY_LENGTH_CONN_PARA_UPDATE_REQ (DFU_NOTIFY_LENGTH_ARV)
+#define DFU_NOTIFY_LENGTH_REPORT_TARGET_INFO (DFU_NOTIFY_LENGTH_ARV+4+4) //img_ver, cur_offset
+#define DFU_NOTIFY_LENGTH_BUFFER_CHECK_EN (DFU_NOTIFY_LENGTH_ARV+2+2) //buf_size, mtu_size
+#define DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC (DFU_NOTIFY_LENGTH_ARV+4) //cur_offset
+#define DFU_NOTIFY_LENGTH_RECEIVE_IC_TYPE (DFU_NOTIFY_LENGTH_ARV+1) //ic_type
+/*max length*/
+#define DFU_NOTIFY_LENGTH_MAX DFU_NOTIFY_LENGTH_REPORT_TARGET_INFO
+
+
+/** @defgroup DFU_Client_Exported_Types Exported Types
+ * @{
+ */
+
+typedef union
+{
+ uint8_t value;
+ struct
+ {
+ uint8_t buf_check_en: 1; // 1:support, 0:don't support
+ uint8_t aesflg: 1; // 1:aes encrypt when ota, 0:not encrypt
+ uint8_t aesmode: 1; // 1:all data is encrypted, 0:only encrypt 16byte
+ uint8_t copy_img: 1; //1:support ,0:don't support
+ uint8_t multi_img: 1; //1:support(update multi img at a time) ,0:don't support(one img at a time)
+ uint8_t rsvd: 3;
+ } mode_flag;
+} T_OTA_MODE;
+
+
+/*each control point procedure,can't modify exist value*/
+typedef enum
+{
+ DFU_OPCODE_MIN = 0x00, /*control point opcode min*/
+ DFU_OPCODE_START_DFU = 0x01,
+ DFU_OPCODE_RECEIVE_FW_IMAGE_INFO = 0x02,
+ DFU_OPCODE_VALID_FW = 0x03,
+ DFU_OPCODE_ACTIVE_IMAGE_RESET = 0x04,
+ DFU_OPCODE_SYSTEM_RESET = 0x05,
+ DFU_OPCODE_REPORT_TARGET_INFO = 0x06,
+ DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ = 0x07,
+ DFU_OPCODE_PKT_RX_NOTIFICATION_VOICE = 0x08,
+ DFU_OPCODE_BUFFER_CHECK_EN = 0x09,
+ DFU_OPCODE_REPORT_BUFFER_CRC = 0x0a,
+ DFU_OPCODE_RECEIVE_IC_TYPE = 0x0b,
+ DFU_OPCODE_COPY_IMG = 0x0c,
+ DFU_OPCODE_MAX = 0x0d, /*control point opcode max*/
+ DFU_OPCODE_NOTIFICATION = 0x10, /*notification opcode,fixed*/
+} T_DFU_CP_OPCODE;
+
+/*dfu error code*/
+typedef enum
+{
+ DFU_ARV_SUCCESS = 0x01,
+ DFU_ARV_FAIL_INVALID_PARAMETER = 0x02,
+ DFU_ARV_FAIL_OPERATION = 0x03,
+ DFU_ARV_FAIL_DATA_SIZE_EXCEEDS_LIMIT = 0x04,
+ DFU_ARV_FAIL_CRC_ERROR = 0x05,
+ DFU_ARV_FAIL_LENGTH_ERROR = 0x06,
+ DFU_ARV_FAIL_PROG_ERROR = 0x07,
+ DFU_ARV_FAIL_ERASE_ERROR = 0x08,
+ DFU_ARV_FAIL_SYS_VERSION_ERROR = 0x09,
+} T_DFU_ARV_ERROR_CODE;
+
+
+/** @defgroup DFU_API DFU API Sets
+ * @brief API sets for device firmware update implementation
+ * @{
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup DFU_API_Exported_Functions DFU API Sets Exported Functions
+ * @{
+ */
+bool dfu_reset(uint16_t image_id);
+
+/**
+ * @brief set specified image valid bit..
+ * @param p_header specified image.
+ * @return true if ready bit sets to 0, false otherwise
+*/
+extern void dfu_set_ready(T_IMG_CTRL_HEADER_FORMAT *p_header);
+
+extern void dfu_set_obsolete(T_IMG_CTRL_HEADER_FORMAT *p_header);
+
+/**
+ * @brief dump image header for debug.
+*/
+extern void dfu_dump_header(T_IMG_HEADER_FORMAT *p_header);
+
+extern uint16_t dfu_process_crc(uint16_t fcs, uint8_t *buf, uint32_t buf_max_size, uint8_t *pdata,
+ size_t data_len);
+
+extern void dfu_process_sha256(SHA256_CTX *ctx, uint8_t *buf, uint32_t buf_max_size, uint8_t *pdata,
+ size_t data_len);
+
+
+static inline uint32_t get_image_version_le_value_from_start_addr(uint32_t start_addr)
+{
+ uint32_t img_ver = 0;
+ T_IMG_HEADER_FORMAT *p_header = (T_IMG_HEADER_FORMAT *)start_addr;
+ if (p_header)
+ {
+ img_ver = (p_header->git_ver.ver_info.sub_version._version_major << 28)
+ + (p_header->git_ver.ver_info.sub_version._version_minor << 20)
+ + (p_header->git_ver.ver_info.sub_version._version_revision << 5)
+ + p_header->git_ver.ver_info.sub_version._version_reserve;
+ }
+ return img_ver;
+}
+
+
+/** @} */ /* End of group DFU_API_Exported_Functions */
+/** @} */ /* End of group DFU_API */
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif
+
diff --git a/inc/app/readme b/inc/app/readme
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/inc/app/readme
diff --git a/inc/bluetooth/gap/bt_types.h b/inc/bluetooth/gap/bt_types.h
new file mode 100644
index 0000000..1c8ed7b
--- /dev/null
+++ b/inc/bluetooth/gap/bt_types.h
@@ -0,0 +1,752 @@
+/**
+ * Copyright (c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+ */
+
+#ifndef _BT_TYPES_H_
+#define _BT_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "upperstack_config.h"
+
+/**
+ * \defgroup BTTYPES BT Types
+ *
+ * \brief Defines BT related macros for the upper layers.
+ *
+ */
+
+
+/**
+ * bt_types.h
+ *
+ * \name BT_LE_LOCAL_SUPPORTED_FEATURES
+ * \brief BT LE Local Supported Features definitions.
+ * \anchor BT_LE_LOCAL_SUPPORTED_FEATURES
+ */
+/**
+ * \ingroup BTTYPES
+ */
+#define LE_SUPPORT_FEATURES_MASK_ARRAY_INDEX0 0
+
+#define LE_SUPPORT_FEATURES_ENCRYPTION_MASK_BIT ((uint8_t)0x01)
+#define LE_SUPPORT_FEATURES_CONNPARA_REQ_PROC_MASK_BIT ((uint8_t)0x02)
+#define LE_SUPPORT_FEATURES_EXTENDED_REJECTION_IND_MASK_BIT ((uint8_t)0x04)
+#define LE_SUPPORT_FEATURES_SLAVE_INITIATED_FEATURE_EXCHANGE_MASK_BIT ((uint8_t)0x08)
+#define LE_SUPPORT_FEATURES_LE_PING_MASK_BIT ((uint8_t)0x10)
+#define LE_SUPPORT_FEATURES_LE_DATA_LENGTH_EXTENSION_MASK_BIT ((uint8_t)0x20)
+#define LE_SUPPORT_FEATURES_LL_PRIVACY_MASK_BIT ((uint8_t)0x40)
+#define LE_SUPPORT_FEATURES_EXTENDED_SCANNER_FILTER_POLICY_MASK_BIT ((uint8_t)0x80)
+
+#define LE_SUPPORT_FEATURES_MASK_ARRAY_INDEX1 1
+
+#define LE_SUPPORT_FEATURES_LE_2M_MASK_BIT ((uint8_t)0x01)
+#define LE_SUPPORT_FEATURES_STABLE_MODULATION_INDEX_TX_MASK_BIT ((uint8_t)0x02)
+#define LE_SUPPORT_FEATURES_STABLE_MODULATION_INDEX_RX_MASK_BIT ((uint8_t)0x04)
+#define LE_SUPPORT_FEATURES_LE_CODED_PHY_MASK_BIT ((uint8_t)0x08)
+#define LE_SUPPORT_FEATURES_LE_EXTENDED_ADV_BIT ((uint8_t)0x10)
+#define LE_SUPPORT_FEATURES_LE_PERIODIC_ADV_MASK_BIT ((uint8_t)0x20)
+#define LE_SUPPORT_FEATURES_CSA2_BIT ((uint8_t)0x40)
+#define LE_SUPPORT_FEATURES_LE_POWER_CLASS1_MASK_BIT ((uint8_t)0x80)
+
+#define LE_SUPPORT_FEATURES_MASK_ARRAY_INDEX2 2
+
+#define LE_SUPPORT_FEATURES_MIN_NUM_USED_CHANNEL_MASK_BIT ((uint8_t)0x01)
+#define LE_SUPPORT_FEATURES_CONNECTION_CTE_REQUEST_MASK_BIT ((uint8_t)0x02)
+#define LE_SUPPORT_FEATURES_CONNECTION_CTE_RESPONSE_MASK_BIT ((uint8_t)0x04)
+#define LE_SUPPORT_FEATURES_CONNECTIONLESS_CTE_TRANSMITTER_MASK_BIT ((uint8_t)0x08)
+#define LE_SUPPORT_FEATURES_CONNECTIONLESS_CTE_RECEIVER_MASK_BIT ((uint8_t)0x10)
+#define LE_SUPPORT_FEATURES_AOD_MASK_BIT ((uint8_t)0x20)
+#define LE_SUPPORT_FEATURES_AOA_MASK_BIT ((uint8_t)0x40)
+#define LE_SUPPORT_FEATURES_RECEIVING_CTE_MASK_BIT ((uint8_t)0x80)
+
+#define LE_SUPPORT_FEATURES_MASK_ARRAY_INDEX3 3
+
+#define LE_SUPPORT_FEATURES_PAST_SENDER_MASK_BIT ((uint8_t)0x01)
+#define LE_SUPPORT_FEATURES_PAST_RECIPIENT_MASK_BIT ((uint8_t)0x02)
+#define LE_SUPPORT_FEATURES_SLEEP_CLOCK_ACCURACY_UPDATES_MASK_BIT ((uint8_t)0x04)
+#define LE_SUPPORT_FEATURES_REMOTE_PUBLIC_KEY_VALIDATION_MASK_BIT ((uint8_t)0x08)
+#define LE_SUPPORT_FEATURES_CIS_MASTER_MASK_BIT ((uint8_t)0x10)
+#define LE_SUPPORT_FEATURES_CIS_SLAVE_MASK_BIT ((uint8_t)0x20)
+#define LE_SUPPORT_FEATURES_ISOCHRONOUS_BROADCASTER_MASK_BIT ((uint8_t)0x40)
+#define LE_SUPPORT_FEATURES_SYNCHRONIZED_RECEIVER_MASK_BIT ((uint8_t)0x80)
+
+#define LE_SUPPORT_FEATURES_MASK_ARRAY_INDEX4 4
+
+#define LE_SUPPORT_FEATURES_ISOCH_HOST_SUPPORT_MASK_BIT ((uint8_t)0x01)
+#define LE_SUPPORT_FEATURES_LE_POWER_CONTROL_REQUEST_MASK_BIT ((uint8_t)0x02)
+#define LE_SUPPORT_FEATURES_LE_POWER_CHANGE_INDICATION_MASK_BIT ((uint8_t)0x04)
+#define LE_SUPPORT_FEATURES_LE_PATH_LOSS_MONITORING_MASK_BIT ((uint8_t)0x08)
+
+/**
+ * bt_types.h
+ *
+ * \name BT_LE_SET_HOST_FEATURE
+ * \brief BT LE Set Host Feature definitions.
+ * \anchor BT_LE_SET_HOST_FEATURE
+ */
+/**
+ * \ingroup BTTYPES
+ */
+#define LE_SET_HOST_FEATURE_BIT_VALUE_DISABLE ((uint8_t)0x00)
+#define LE_SET_HOST_FEATURE_BIT_VALUE_ENABLE ((uint8_t)0x01)
+#define LE_SET_HOST_FEATURE_BIT_VALUE_RFU ((uint8_t)0xFF)
+
+#define LE_SET_HOST_FEATURE_BIT_NUMBER_ISOCH_HOST_SUPPORT ((uint8_t)0x20)
+#define LE_SET_HOST_FEATURE_BIT_NUMBER_RFU ((uint8_t)0xFF)
+
+/**
+ * bt_types.h
+ *
+ * \name BT_STACK_MODULE_ERROR
+ * \brief BT stack module error code mask.
+ * \anchor BT_STACK_MODULE_ERROR
+ */
+/**
+ * \ingroup BTTYPES
+ */
+#define GAP_ERR 0x0000
+#define HCI_ERR 0x0100
+#define L2C_ERR 0x0200
+#define SDP_ERR 0x0300
+#define ATT_ERR 0x0400
+#define SM_ERR 0x0500
+
+#define GATT_ERR 0x0C00
+#define APP_ERR 0x0D00
+
+/**
+ * bt_types.h
+ *
+ * \name BT_HCI_ERROR
+ * \brief BT hci error code definitions.
+ * \anchor BT_HCI_ERROR
+ */
+/**
+ * \ingroup BTTYPES
+ */
+#define HCI_SUCCESS 0x00
+#define HCI_ERR_UNKNOWN_CMD 0x01
+#define HCI_ERR_UNKNOWN_CONN_ID 0x02
+#define HCI_ERR_HARDWARE_FAIL 0x03
+#define HCI_ERR_PAGE_TIMEOUT 0x04
+#define HCI_ERR_AUTHEN_FAIL 0x05
+#define HCI_ERR_KEY_MISSING 0x06
+#define HCI_ERR_MEMORY_FULL 0x07
+#define HCI_ERR_CONN_TIMEOUT 0x08
+#define HCI_ERR_MAX_NUM_CONN 0x09
+#define HCI_ERR_MAX_NUM_SCO_CONN 0x0A /* 10 */
+#define HCI_ERR_ACL_CONN_EXIST 0x0B /* 11 */
+#define HCI_ERR_CMD_DISALLOWED 0x0C /* 12 */
+#define HCI_ERR_REJECT_LIMITED_RESOURCE 0x0D /* 13 */
+#define HCI_ERR_REJECT_SECURITY_REASON 0x0E /* 14 */
+#define HCI_ERR_REJECT_UNACCEPTABLE_ADDR 0x0F /* 15 */
+#define HCI_ERR_HOST_TIMEOUT 0x10 /* 16 */
+#define HCI_ERR_UNSUPPORTED_PARAM 0x11 /* 17 */
+#define HCI_ERR_INVALID_PARAM 0x12 /* 18 */
+#define HCI_ERR_REMOTE_USER_TERMINATE 0x13 /* 19 */
+#define HCI_ERR_REMOTE_LOW_RESOURCE 0x14 /* 20 */
+#define HCI_ERR_REMOTE_POWER_OFF 0x15 /* 21 */
+#define HCI_ERR_LOCAL_HOST_TERMINATE 0x16 /* 22 */
+#define HCI_ERR_REPEATED_ATTEMPTS 0x17 /* 23 */
+#define HCI_ERR_PARING_NOT_ALLOWED 0x18 /* 24 */
+#define HCI_ERR_UNKNOWN_LMP_PDU 0x19 /* 25 */
+#define HCI_ERR_UNSUPPORTED_REMOTE_FEAT 0x1A /* 26 */
+#define HCI_ERR_SCO_OFFSET_REJECTED 0x1B /* 27 */
+#define HCI_ERR_SCO_INTERVAL_REJECTED 0x1C /* 28 */
+#define HCI_ERR_SCO_AIR_MODE_REJECTED 0x1D /* 29 */
+#define HCI_ERR_INVALID_LMP_PARAM 0x1E /* 30 */
+#define HCI_ERR_UNSPECIFIED_ERROR 0x1F /* 31 */
+#define HCI_ERR_UNSUPPORTED_LMP_PARAM 0x20 /* 32 */
+#define HCI_ERR_ROLE_CHANGE_NOT_ALLOWED 0x21 /* 33 */
+#define HCI_ERR_LMP_RESPONSE_TIMEOUT 0x22 /* 34 */
+#define HCI_ERR_LMP_ERROR_TRANS_COLLISION 0x23 /* 35 */
+#define HCI_ERR_LMP_PDU_NOT_ALLOWED 0x24 /* 36 */
+#define HCI_ERR_ENCRYPT_MODE_NOT_ACCEPTABLE 0x25 /* 37 */
+#define HCI_ERR_UNIT_KEY_USED 0x26 /* 38 */
+#define HCI_ERR_QOS_NOT_SUPPORTED 0x27 /* 39 */
+#define HCI_ERR_INSTANT_PASSED 0x28 /* 40 */
+#define HCI_ERR_PAIR_UNIT_KEY_NOT_SUPPORT 0x29 /* 41 */
+#define HCI_ERR_DIFF_TRANS_COLLISION 0x2A /* 42 */
+#define HCI_ERR_QOS_UNACCEPTABLE_PARAM 0x2C /* 44 */
+#define HCI_ERR_QOS_REJECT 0x2D /* 45 */
+#define HCI_ERR_CHANN_ASSESS_NOT_SUPPORT 0x2E /* 46 */
+#define HCI_ERR_INSUFFICIENT_SECURITY 0x2F /* 47 */
+#define HCI_ERR_PARAM_OUT_OF_RANGE 0x30 /* 48 */
+#define HCI_ERR_ROLE_SWITCH_PENDING 0x32 /* 50 */
+#define HCI_ERR_RESERVED_SLOT_VIOLATION 0x34 /* 52 */
+#define HCI_ERR_ROLE_SWITCH_FAILED 0x35 /* 53 */
+#define HCI_ERR_EXT_INQUIRY_RSP_TOO_LARGE 0x36 /* 54 */
+#define HCI_ERR_SSP_NOT_SUPPORTED_BY_HOST 0x37 /* 55 */
+#define HCI_ERR_HOST_BUSY_PAIRING 0x38 /* 56 */
+#define HCI_ERR_REJECT_NO_SUITABLE_CHANN 0x39 /* 57 */
+#define HCI_ERR_CONTROLLER_BUSY 0x3A /* 58 */
+#define HCI_ERR_UNACCEPTABLE_CONN_INTERVAL 0x3B /* 59 */
+#define HCI_ERR_DIRECTED_ADV_TIMEOUT 0x3C /* 60 */
+#define HCI_ERR_MIC_FAILURE 0x3D /* 61 */
+#define HCI_ERR_FAIL_TO_ESTABLISH_CONN 0x3E /* 62 */
+#define HCI_ERR_MAC_CONN_FAIL 0x3F /* 63 */
+#define HCI_ERR_COARSE_CLOCK_ADJUST_REJECTED 0x40
+#define HCI_ERR_TYPE0_SUBMAP_NOT_DEFINED 0x41
+#define HCI_ERR_UNKNOWN_ADVERTISING_IDENTIFIER 0x42
+#define HCI_ERR_LIMIT_REACHED 0x43
+#define HCI_ERR_OPERATION_CANCELLED_BY_HOST 0x44
+#define HCI_ERR_OPERATION_PACKET_TOO_LONG 0x45
+
+/* hci local error code */
+#define HCI_ERR_INVALID_ADDR 0x64 /* 100 */
+#define HCI_ERR_TIMEOUT 0x65 /* 101 */
+#define HCI_ERR_OUT_OF_SYNC 0x66 /* 102 */
+#define HCI_ERR_NO_DESCRIPTOR 0x67 /* 103 */
+#define HCI_ERR_NO_MEMORY 0x68 /* 104 */
+#define HCI_ERR_INVALID_STATE 0x69 /* 105 */
+#define HCI_ERR_LOCAL_KEY_MISSING 0x6A /* 106 */
+
+/**
+ * bt_types.h
+ *
+ * \name BT_L2CAP_ERROR
+ * \brief BT l2cap error code definitions.
+ * \anchor BT_L2CAP_ERROR
+ */
+/**
+ * \ingroup BTTYPES
+ */
+#define L2C_SUCCESS 0x00
+
+#define L2C_CONN_ACCEPT 0x0000
+#define L2C_CONN_RSP_PENDING 0x0001
+#define L2C_CONN_RSP_INVALID_PSM 0x0002
+#define L2C_CONN_RSP_SECURITY_BLOCK 0x0003
+#define L2C_CONN_RSP_NO_RESOURCE 0x0004
+#define L2C_CONN_RSP_INVALID_PARAM 0x0005
+#define L2C_CONN_RSP_INVALID_SOURCE_CID 0x0006
+#define L2C_CONN_RSP_SOURCE_CID_ALLOCATED 0x0007
+
+/* request cmd reject reasons */
+#define L2C_CMD_REJ_NOT_UNDERSTOOD 0x0000
+#define L2C_CMD_REJ_SIGNAL_MTU_EXCEEDED 0x0001
+#define L2C_CMD_REJ_INVALID_CID_IN_REQ 0x0002
+
+/* config response result codes */
+#define L2C_CFG_RSP_SUCCESS 0x0000
+#define L2C_CFG_RSP_UNACCEPTABLE_PARAMS 0x0001
+#define L2C_CFG_RSP_REJECTED 0x0002
+#define L2C_CFG_RSP_UNKNOWN_OPTIONS 0x0003
+#define L2C_CFG_RSP_PENDING 0x0004
+#define L2C_CFG_RSP_FLOW_SPEC_REJECTED 0x0005
+
+#define L2C_LE_CREDIT_CONN_SUCCESS 0x0000
+#define L2C_LE_CREDIT_RSP_PSM_NOT_SUPPORTED 0x0002
+#define L2C_LE_CREDIT_RSP_NO_RESOURCES 0x0004
+#define L2C_LE_CREDIT_RSP_INSUFFICIENT_AUTHEN 0x0005
+#define L2C_LE_CREDIT_RSP_INSUFFICIENT_AUTHOR 0x0006
+#define L2C_LE_CREDIT_RSP_INSUFFICIENT_ENCRYP_KEY_SIZE 0x0007
+#define L2C_LE_CREDIT_RSP_INSUFFICIENT_ENCRYP 0x0008
+#define L2C_LE_CREDIT_RSP_INVALID_SOURCE_CID 0x0009
+#define L2C_LE_CREDIT_RSP_SOURCE_CID_ALREADY_ALLOC 0x000A
+
+/* status for connection updata response */
+#define L2C_LE_CONN_UPDATE_ACCEPT 0x0000
+#define L2C_LE_CONN_UPDATE_RSP_REJECT 0x0001
+#define L2C_LE_CONN_UPDATE_RSP_TOUT 0x0002
+
+/* l2cap error code */
+#define L2C_ERR_REJ_BASE 0x0010
+#define L2C_ERR_CFG_BASE 0x0020
+#define L2C_ERR_LE_CREDIT_BASE 0x0030
+#define L2C_ERR_LE_CONN_UPDATE_BASE 0x0040
+#define L2C_ERR_VND_BASE 0x00F0
+
+#define L2C_ERR_PENDING L2C_CONN_RSP_PENDING
+#define L2C_ERR_INVALID_PSM L2C_CONN_RSP_INVALID_PSM
+#define L2C_ERR_SECURITY_BLOCK L2C_CONN_RSP_SECURITY_BLOCK
+#define L2C_ERR_NO_RESOURCE L2C_CONN_RSP_NO_RESOURCE
+#define L2C_ERR_INVALID_PARAM L2C_CONN_RSP_INVALID_PARAM
+#define L2C_ERR_INVALID_SOURCE_CID L2C_CONN_RSP_INVALID_SOURCE_CID
+#define L2C_ERR_SOURCE_CID_ALLOCATED L2C_CONN_RSP_SOURCE_CID_ALLOCATED
+
+#define L2C_ERR_CMD_NOT_UNDERSTOOD (L2C_ERR_REJ_BASE + L2C_CMD_REJ_NOT_UNDERSTOOD)
+#define L2C_ERR_SIGNAL_MTU_EXCEEDED (L2C_ERR_REJ_BASE + L2C_CMD_REJ_SIGNAL_MTU_EXCEEDED)
+#define L2C_ERR_INVALID_CID_IN_REQ (L2C_ERR_REJ_BASE + L2C_CMD_REJ_INVALID_CID_IN_REQ)
+
+#define L2C_ERR_CFG_UNACCEPTABLE_PARAM (L2C_ERR_CFG_BASE + L2C_CFG_RSP_UNACCEPTABLE_PARAMS)
+#define L2C_ERR_CFG_REJECTED (L2C_ERR_CFG_BASE + L2C_CFG_RSP_REJECTED)
+#define L2C_ERR_CFG_UNKNOWN_OPTIONS (L2C_ERR_CFG_BASE + L2C_CFG_RSP_UNKNOWN_OPTIONS)
+#define L2C_ERR_CFG_PENDING (L2C_ERR_CFG_BASE + L2C_CFG_RSP_PENDING)
+#define L2C_ERR_CFG_FLOW_SPEC_REJECTED (L2C_ERR_CFG_BASE + L2C_CFG_RSP_FLOW_SPEC_REJECTED)
+
+#define L2C_ERR_LE_CREDIT_PSM_NOT_SUPPORTED (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_PSM_NOT_SUPPORTED)
+#define L2C_ERR_LE_CREDIT_NO_RESOURCES (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_NO_RESOURCES)
+#define L2C_ERR_LE_CREDIT_INSUFFICIENT_AUTHEN (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_INSUFFICIENT_AUTHEN)
+#define L2C_ERR_LE_CREDIT_INSUFFICIENT_AUTHOR (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_INSUFFICIENT_AUTHOR)
+#define L2C_ERR_LE_CREDIT_INSUFFICIENT_ENCRYP_KEY_SIZE (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_INSUFFICIENT_ENCRYP_KEY_SIZE)
+#define L2C_ERR_LE_CREDIT_INSUFFICIENT_ENCRYP (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_INSUFFICIENT_ENCRYP)
+#define L2C_ERR_LE_CREDIT_INVALID_SOURCE_CID (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_INVALID_SOURCE_CID)
+#define L2C_ERR_LE_CREDIT_SOURCE_CID_ALREADY_ALLOC (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_SOURCE_CID_ALREADY_ALLOC)
+
+#define L2C_ERR_LE_CONN_PARAM_UPDATE_REJECT (L2C_ERR_LE_CONN_UPDATE_BASE + L2C_LE_CONN_UPDATE_RSP_REJECT)
+#define L2C_ERR_LE_CONN_PARAM_UPDATE_TOUT (L2C_ERR_LE_CONN_UPDATE_BASE + L2C_LE_CONN_UPDATE_RSP_TOUT)
+
+#define L2C_ERR_VND_CREDITS_EXCEED (L2C_ERR_VND_BASE + 0x00)
+#define L2C_ERR_VND_INVALID_PDU (L2C_ERR_VND_BASE + 0x01)
+#define L2C_ERR_VND_CREDITS_LACK (L2C_ERR_VND_BASE + 0x02)
+#define L2C_ERR_VND_NO_MEMORY (L2C_ERR_VND_BASE + 0x03)
+#define L2C_ERR_VND_INVALID_STATE (L2C_ERR_VND_BASE + 0x04)
+#define L2C_ERR_VND_INVALID_RX_SEQ (L2C_ERR_VND_BASE + 0x05)
+#define L2C_ERR_VND_TIMEOUT (L2C_ERR_VND_BASE + 0x06)
+#define L2C_ERR_VND_INVALID_MODE (L2C_ERR_VND_BASE + 0x07)
+#define L2C_ERR_VND_REMOTE_DISCONNECT (L2C_ERR_VND_BASE + 0x08)
+
+/**
+ * bt_types.h
+ *
+ * \name BT_ATT_ERROR
+ * \brief BT att error code definitions.
+ * \anchor BT_ATT_ERROR
+ */
+/**
+ * \ingroup BTTYPES
+ */
+#define ATT_SUCCESS 0 /**< internal value .. */
+#define ATT_ERR_INVALID_HANDLE 0x01 /**< Attribute handle value given was not valid on this attribute server */
+#define ATT_ERR_READ_NOT_PERMITTED 0x02 /**< Attribute cannot be read */
+#define ATT_ERR_WRITE_NOT_PERMITTED 0x03 /**< Attribute cannot be written */
+#define ATT_ERR_INVALID_PDU 0x04 /**< The attribute PDU was invalid */
+#define ATT_ERR_INSUFFICIENT_AUTHEN 0x05 /**< The attribute requires authentication before it can be read or written */
+#define ATT_ERR_UNSUPPORTED_REQ 0x06 /**< Attribute server doesn't support the request received from the attribute client */
+#define ATT_ERR_INVALID_OFFSET 0x07 /**< Offset specified was past the end of the attribute */
+#define ATT_ERR_INSUFFICIENT_AUTHOR 0x08 /**< The attribute requires an authorization before it can be read or written */
+#define ATT_ERR_PREP_QUEUE_FULL 0x09 /**< Too many prepare writes have been queued */
+#define ATT_ERR_ATTR_NOT_FOUND 0x0A /**< No attribute found within the given attribute handle range */
+#define ATT_ERR_ATTR_NOT_LONG 0x0B /**< Attribute cannot be read or written using the Read Blob Request or Prepare Write Request */
+#define ATT_ERR_INSUFFICIENT_KEY_SIZE 0x0C /**< The Encryption Key Size used for encrypting this link is insufficient */
+#define ATT_ERR_INVALID_VALUE_SIZE 0x0D /**< The attribute value length is invalid for the operation */
+#define ATT_ERR_UNLIKELY 0x0E /**< The attribute request that was requested has encountered an error that was very unlikely, and therefore could not be completed as requested */
+#define ATT_ERR_INSUFFICIENT_ENCRYPT 0x0F /**< The attribute requires encryption before it can be read or written */
+#define ATT_ERR_UNSUPPORTED_GROUP_TYPE 0x10 /**< The attribute type is not a supported grouping attribute as defined by a higher layer specification */
+#define ATT_ERR_INSUFFICIENT_RESOURCES 0x11 /**< Insufficient Resources to complete the request */
+#define ATT_ERR_DATABASE_OUT_OF_SYNC 0x12 /**< The server requests the client to rediscover the database. */
+#define ATT_ERR_VALUE_NOT_ALLOWED 0x13 /**< The attribute parameter value was not allowed. */
+
+/* profile dependent application error codes >= 0x80: */
+#define ATT_ERR_INVALID_VALUE 0x80 /**< The attribute value is invalid for the operation */
+
+/* manufacturer specific error codes that are "missing" in GATT spec. >= 0xC0: */
+#define ATT_ERR_INVALID_CCC_BITS 0xC0 /**< Invalid client char. config. bits */
+#define ATT_ERR_INVALID_SIGNED_COUNT 0xC1 /**< Invalid sign count */
+#define ATT_ERR_INVALID_SIGNED_MAC_FAILED 0xC2 /**< Invalid sign mac value */
+#define ATT_ERR_MIN_APPLIC_CODE 0xC3
+
+/* error codes common to various profiles (see "CSS v2.pdf"), >= 0xE0 */
+#define ATT_ERR_WRITE_REQUEST_REJECTED 0xFC /**< Write Request Rejected */
+#define ATT_ERR_CCCD_IMPROPERLY_CONFIGURED 0xFD /**< CCCD improperly configured */
+#define ATT_ERR_PROC_ALREADY_IN_PROGRESS 0xFE /**< Procedure Already in Progress */
+#define ATT_ERR_OUT_OF_RANGE 0xFF /**< An attribute value is out of range as defined by a profile or service specification. */
+
+/**
+ * bt_types.h
+ *
+ * \name BT_GATT_ERROR
+ * \brief BT gatt error code definitions.
+ * \anchor BT_GATT_ERROR
+ */
+/**
+ * \ingroup BTTYPES
+ */
+#define GATT_SUCCESS 0x00
+#define GATT_ERR_OUT_OF_RESOURCE 0x01
+#define GATT_ERR_UNSUPPORTED 0x02
+#define GATT_ERR_INVALID_ROLE 0x03
+#define GATT_ERR_INVALID_STATE 0x04
+#define GATT_ERR_INVALID_CODING 0x05
+#define GATT_ERR_INVALID_HANDLE 0x06
+#define GATT_ERR_INVALID_PARAM 0x07
+#define GATT_ERR_INTERNAL 0x08
+#define GATT_ERR_NOT_ALLOWED 0x09
+#define GATT_ERR_NOTIF_IND_NOT_CFG 0x0A
+#define GATT_ERR_NOTIF_IND_CFG 0x0B
+#define GATT_ERR_NOTIF_IND_CONF_PD 0x0C
+#define GATT_ERR_TIMEOUT 0x0D
+#define GATT_ERR_LINK_DEACTIVATED 0x0E
+#define GATT_ERR_NOT_AUTHENTICATED 0x0F
+#define GATT_ERR_NOT_ENCRYPTED 0x10
+#define GATT_ERR_PROC_FAIL 0x11
+
+/* sm error code */
+#define SM_SUCCESS 0x00
+/* SMP_OP_PAIRING_FAILED causes */
+#define SMP_ERR_SUCCESS 0x00
+#define SMP_ERR_PASSKEY_ENTRY_FAIL 0x01
+#define SMP_ERR_OOB_NOT_AVAILABLE 0x02
+#define SMP_ERR_AUTHEN_REQUIREMENTS 0x03
+#define SMP_ERR_CFM_VALUE_FAILED 0x04
+#define SMP_ERR_PAIRING_NOT_SUPPORTED 0x05
+#define SMP_ERR_ENCRYPTION_KEY_SIZE 0x06
+#define SMP_ERR_CMD_NOT_SUPPORTED 0x07
+#define SMP_ERR_UNSPECIFIED_REASON 0x08
+#define SMP_ERR_REPEATED_ATTEMPTS 0x09
+#define SMP_ERR_INVALID_PARAM 0x0A
+#define SMP_ERR_DHKEY_CHECK_FAILED 0x0B
+#define SMP_ERR_NUMERIC_COMPARISON_FAIL 0x0C
+#define SMP_ERR_BREDR_PAIRING_IN_PROGRESS 0x0D
+#define SMP_ERR_CRS_TRANS_KEY_GEN_NOT_ALLOW 0x0E
+
+#define SM_ERR_NO_ENTRY 0xE1
+#define SM_ERR_DB_FULL 0xE2
+#define SM_ERR_INVALID_PARAM 0xE3
+#define SM_ERR_INSUFFICIENT_LINK_KEY 0xE4
+#define SM_ERR_LE_ADDR_NOT_RESOLVED 0xE5
+#define SM_ERR_INVALID_STATE 0xE6
+#define SM_ERR_NO_RESOURCE 0xE7
+#define SM_ERR_LINK_KEY_MISSING 0xE8
+#define SM_ERR_DISCONNECT 0xE9
+#define SM_ERR_PARING_NOT_ALLOWED 0xEA
+#define SM_ERR_KEY_SAVE_FAILED 0xEB
+#define SM_ERR_TIMEOUT 0xEC
+#define SM_ERR_UNKNOWN 0xED
+#define SM_ERR_NO_PAIRABLE_MODE 0xEF
+
+/**
+ * bt_types.h
+ *
+ * \name BT_BTIF_ERROR
+ * \brief BT btif error code definitions.
+ * \anchor BT_BTIF_ERROR
+ */
+/**
+ * \ingroup BTTYPES
+ */
+#define BTIF_ERR 0x0000
+#define BTIF_SUCCESS 0x00
+#define BTIF_ACCEPT 0x01
+#define BTIF_ERR_REJECT 0x02
+#define BTIF_ERR_NO_RESOURCE 0x03
+#define BTIF_ERR_INVALID_PARAM 0x04
+#define BTIF_ERR_INVALID_STATE 0x05
+#define BTIF_ERR_CONN_DISCONNECT 0x06
+#define BTIF_ERR_CONN_LOST 0x07
+#define BTIF_ERR_AUTHEN_FAIL 0x08
+#define BTIF_ERR_INIT_TOUT 0x09
+#define BTIF_ERR_INIT_OUT_OF_SYNC 0x0A
+#define BTIF_ERR_INIT_HARDWARE_ERROR 0x0B
+#define BTIF_ERR_LOWER_LAYER_ERROR 0x0C
+#define BTIF_ERR_ADDR_NOT_RESOLVED 0x0D
+#define BTIF_ERR_TOUT 0x0E
+
+#define BTIF_ERR_UNSPECIFIED 0xFD
+#define BTIF_ERR_NOT_SUPPORTED 0xFE
+
+/**
+ * bt_types.h
+ *
+ * \name BT_GAP_ERROR
+ * \brief BT GAP error code definitions.
+ * \anchor BT_GAP_ERROR
+ */
+/**
+ * \ingroup BTTYPES
+ */
+#define GAP_SUCCESS 0x00
+#define GAP_ACCEPT 0x01
+#define GAP_ERR_REJECT 0x02
+#define GAP_ERR_NO_RESOURCE 0x03
+#define GAP_ERR_INVALID_PARAM 0x04
+#define GAP_ERR_INVALID_STATE 0x05
+#define GAP_ERR_CONN_DISCONNECT 0x06
+#define GAP_ERR_CONN_LOST 0x07
+#define GAP_ERR_AUTHEN_FAIL 0x08
+#define GAP_ERR_INIT_TOUT 0x09
+#define GAP_ERR_INIT_OUT_OF_SYNC 0x0A
+#define GAP_ERR_INIT_HARDWARE_ERROR 0x0B
+#define GAP_ERR_LOWER_LAYER_ERROR 0x0C
+#define GAP_ERR_ADDR_NOT_RESOLVED 0x0D
+#define GAP_ERR_TOUT 0x0E
+
+#define GAP_ERR_REQ_FAILED 0xFB
+#define GAP_ERR_SW_RESET 0xFC
+#define GAP_ERR_UNSPECIFIED 0xFD
+#define GAP_ERR_NOT_SUPPORTED 0xFE
+
+/**
+ * bt_types.h
+ *
+ * \name BT_APP_ERROR
+ * \brief BT APP error code definitions.
+ * \anchor BT_APP_ERROR
+ */
+/**
+ * \ingroup BTTYPES
+ */
+#define APP_SUCCESS 0x00
+#define APP_ERR_PENDING 0x01
+#define APP_ERR_ACCEPT 0x03
+#define APP_ERR_REJECT 0x04
+#define APP_ERR_NOT_RELEASE 0x05
+
+/**
+ * bt_types.h
+ *
+ * \name BT_BYTE_ORDER
+ * \brief BT buffer/array byte-order utility macros.
+ * \anchor BT_BYTE_ORDER
+ */
+/**
+ * \ingroup BTTYPES
+ */
+/** Calculate integer bit count of b'1 */
+#define INT_BIT_COUNT(integer, count) { \
+ count = 0; \
+ while (integer) \
+ { \
+ count++; \
+ integer &= integer - 1; \
+ } \
+ }
+
+/** Stream skip len */
+#define STREAM_SKIP_LEN(s, len) { \
+ s += len; \
+ }
+
+/** Stream to array */
+#define STREAM_TO_ARRAY(a, s, len) { \
+ uint32_t ii; \
+ for (ii = 0; ii < len; ii++) \
+ { \
+ *((uint8_t *)(a) + ii) = *s++; \
+ } \
+ }
+
+/** Array to stream */
+#define ARRAY_TO_STREAM(s, a, len) { \
+ uint32_t ii; \
+ for (ii = 0; ii < len; ii++) \
+ { \
+ *s++ = *((uint8_t *)(a) + ii); \
+ } \
+ }
+
+/** Little Endian stream to uint8 */
+#define LE_STREAM_TO_UINT8(u8, s) { \
+ u8 = (uint8_t)(*s); \
+ s += 1; \
+ }
+
+/** Little Endian stream to uint16 */
+#define LE_STREAM_TO_UINT16(u16, s) { \
+ u16 = ((uint16_t)(*(s + 0)) << 0) + \
+ ((uint16_t)(*(s + 1)) << 8); \
+ s += 2; \
+ }
+
+/** Little Endian stream to uint24 */
+#define LE_STREAM_TO_UINT24(u24, s) { \
+ u24 = ((uint32_t)(*(s + 0)) << 0) + \
+ ((uint32_t)(*(s + 1)) << 8) + \
+ ((uint32_t)(*(s + 2)) << 16); \
+ s += 3; \
+ }
+
+/** Little Endian stream to uint32 */
+#define LE_STREAM_TO_UINT32(u32, s) { \
+ u32 = ((uint32_t)(*(s + 0)) << 0) + \
+ ((uint32_t)(*(s + 1)) << 8) + \
+ ((uint32_t)(*(s + 2)) << 16) + \
+ ((uint32_t)(*(s + 3)) << 24); \
+ s += 4; \
+ }
+
+/** Little Endian uint8 to stream */
+#define LE_UINT8_TO_STREAM(s, u8) { \
+ *s++ = (uint8_t)(u8); \
+ }
+
+/** Little Endian uint16 to stream */
+#define LE_UINT16_TO_STREAM(s, u16) { \
+ *s++ = (uint8_t)((u16) >> 0); \
+ *s++ = (uint8_t)((u16) >> 8); \
+ }
+
+/** Little Endian uint24 to stream */
+#define LE_UINT24_TO_STREAM(s, u24) { \
+ *s++ = (uint8_t)((u24) >> 0); \
+ *s++ = (uint8_t)((u24) >> 8); \
+ *s++ = (uint8_t)((u24) >> 16); \
+ }
+
+/** Little Endian uint32 to stream */
+#define LE_UINT32_TO_STREAM(s, u32) { \
+ *s++ = (uint8_t)((u32) >> 0); \
+ *s++ = (uint8_t)((u32) >> 8); \
+ *s++ = (uint8_t)((u32) >> 16); \
+ *s++ = (uint8_t)((u32) >> 24); \
+ }
+
+/** Little Endian array to uint8 */
+#define LE_ARRAY_TO_UINT8(u8, a) { \
+ u8 = (uint8_t)(*(a + 0)); \
+ }
+
+/** Little Endian array to uint16 */
+#define LE_ARRAY_TO_UINT16(u16, a) { \
+ u16 = ((uint16_t)(*(a + 0)) << 0) + \
+ ((uint16_t)(*(a + 1)) << 8); \
+ }
+
+/** Little Endian array to uint24 */
+#define LE_ARRAY_TO_UINT24(u24, a) { \
+ u24 = ((uint32_t)(*(a + 0)) << 0) + \
+ ((uint32_t)(*(a + 1)) << 8) + \
+ ((uint32_t)(*(a + 2)) << 16); \
+ }
+
+/** Little Endian array to uint32 */
+#define LE_ARRAY_TO_UINT32(u32, a) { \
+ u32 = ((uint32_t)(*(a + 0)) << 0) + \
+ ((uint32_t)(*(a + 1)) << 8) + \
+ ((uint32_t)(*(a + 2)) << 16) + \
+ ((uint32_t)(*(a + 3)) << 24); \
+ }
+
+/** Little Endian uint8 to array */
+#define LE_UINT8_TO_ARRAY(a, u8) { \
+ *((uint8_t *)(a) + 0) = (uint8_t)(u8); \
+ }
+
+/** Little Endian uint16 to array */
+#define LE_UINT16_TO_ARRAY(a, u16) { \
+ *((uint8_t *)(a) + 0) = (uint8_t)((u16) >> 0); \
+ *((uint8_t *)(a) + 1) = (uint8_t)((u16) >> 8); \
+ }
+
+/** Little Endian uint24 to array */
+#define LE_UINT24_TO_ARRAY(a, u24) { \
+ *((uint8_t *)(a) + 0) = (uint8_t)((u24) >> 0); \
+ *((uint8_t *)(a) + 1) = (uint8_t)((u24) >> 8); \
+ *((uint8_t *)(a) + 2) = (uint8_t)((u24) >> 16); \
+ }
+
+/** Little Endian uint32 to array */
+#define LE_UINT32_TO_ARRAY(a, u32) { \
+ *((uint8_t *)(a) + 0) = (uint8_t)((u32) >> 0); \
+ *((uint8_t *)(a) + 1) = (uint8_t)((u32) >> 8); \
+ *((uint8_t *)(a) + 2) = (uint8_t)((u32) >> 16); \
+ *((uint8_t *)(a) + 3) = (uint8_t)((u32) >> 24); \
+ }
+
+/** Big Endian stream to uint8 */
+#define BE_STREAM_TO_UINT8(u8, s) { \
+ u8 = (uint8_t)(*(s + 0)); \
+ s += 1; \
+ }
+
+/** Big Endian stream to uint16 */
+#define BE_STREAM_TO_UINT16(u16, s) { \
+ u16 = ((uint16_t)(*(s + 0)) << 8) + \
+ ((uint16_t)(*(s + 1)) << 0); \
+ s += 2; \
+ }
+
+/** Big Endian stream to uint24 */
+#define BE_STREAM_TO_UINT24(u24, s) { \
+ u24 = ((uint32_t)(*(s + 0)) << 16) + \
+ ((uint32_t)(*(s + 1)) << 8) + \
+ ((uint32_t)(*(s + 2)) << 0); \
+ s += 3; \
+ }
+
+/** Big Endian stream to uint32 */
+#define BE_STREAM_TO_UINT32(u32, s) { \
+ u32 = ((uint32_t)(*(s + 0)) << 24) + \
+ ((uint32_t)(*(s + 1)) << 16) + \
+ ((uint32_t)(*(s + 2)) << 8) + \
+ ((uint32_t)(*(s + 3)) << 0); \
+ s += 4; \
+ }
+
+/** Big Endian uint8 to stream */
+#define BE_UINT8_TO_STREAM(s, u8) { \
+ *s++ = (uint8_t)(u8); \
+ }
+
+/** Big Endian uint16 to stream */
+#define BE_UINT16_TO_STREAM(s, u16) { \
+ *s++ = (uint8_t)((u16) >> 8); \
+ *s++ = (uint8_t)((u16) >> 0); \
+ }
+
+/** Big Endian uint24 to stream */
+#define BE_UINT24_TO_STREAM(s, u24) { \
+ *s++ = (uint8_t)((u24) >> 16); \
+ *s++ = (uint8_t)((u24) >> 8); \
+ *s++ = (uint8_t)((u24) >> 0); \
+ }
+
+/** Big Endian uint32 to stream */
+#define BE_UINT32_TO_STREAM(s, u32) { \
+ *s++ = (uint8_t)((u32) >> 24); \
+ *s++ = (uint8_t)((u32) >> 16); \
+ *s++ = (uint8_t)((u32) >> 8); \
+ *s++ = (uint8_t)((u32) >> 0); \
+ }
+
+/** Big Endian array to uint8 */
+#define BE_ARRAY_TO_UINT8(u8, a) { \
+ u8 = (uint8_t)(*(a + 0)); \
+ }
+
+/** Big Endian array to uint16 */
+#define BE_ARRAY_TO_UINT16(u16, a) { \
+ u16 = ((uint16_t)(*(a + 0)) << 8) + \
+ ((uint16_t)(*(a + 1)) << 0); \
+ }
+
+/** Big Endian array to uint24 */
+#define BE_ARRAY_TO_UINT24(u24, a) { \
+ u24 = ((uint32_t)(*(a + 0)) << 16) + \
+ ((uint32_t)(*(a + 1)) << 8) + \
+ ((uint32_t)(*(a + 2)) << 0); \
+ }
+
+/** Big Endian array to uint32 */
+#define BE_ARRAY_TO_UINT32(u32, a) { \
+ u32 = ((uint32_t)(*(a + 0)) << 24) + \
+ ((uint32_t)(*(a + 1)) << 16) + \
+ ((uint32_t)(*(a + 2)) << 8) + \
+ ((uint32_t)(*(a + 3)) << 0); \
+ }
+
+/** Big Endian uint8 to array */
+#define BE_UINT8_TO_ARRAY(a, u8) { \
+ *((uint8_t *)(a) + 0) = (uint8_t)(u8); \
+ }
+
+/** Big Endian uint16 to array */
+#define BE_UINT16_TO_ARRAY(a, u16) { \
+ *((uint8_t *)(a) + 0) = (uint8_t)((u16) >> 8); \
+ *((uint8_t *)(a) + 1) = (uint8_t)((u16) >> 0); \
+ }
+
+/** Big Endian uint24 to array */
+#define BE_UINT24_TO_ARRAY(a, u24) { \
+ *((uint8_t *)(a) + 0) = (uint8_t)((u24) >> 16); \
+ *((uint8_t *)(a) + 1) = (uint8_t)((u24) >> 8); \
+ *((uint8_t *)(a) + 2) = (uint8_t)((u24) >> 0); \
+ }
+
+/** Big Endian uint32 to array */
+#define BE_UINT32_TO_ARRAY(a, u32) { \
+ *((uint8_t *)(a) + 0) = (uint8_t)((u32) >> 24); \
+ *((uint8_t *)(a) + 1) = (uint8_t)((u32) >> 16); \
+ *((uint8_t *)(a) + 2) = (uint8_t)((u32) >> 8); \
+ *((uint8_t *)(a) + 3) = (uint8_t)((u32) >> 0); \
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BT_TYPES_H_ */
diff --git a/inc/bluetooth/gap/gap.h b/inc/bluetooth/gap/gap.h
new file mode 100644
index 0000000..8882858
--- /dev/null
+++ b/inc/bluetooth/gap/gap.h
@@ -0,0 +1,644 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gap.h
+ * @brief This file contains all the constants and functions prototypes for GAP.
+ * @details This file is used both bredr and le.
+ * @author jane
+ * @date 2017-02-18
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_H
+#define GAP_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdint.h>
+#include <stdbool.h>
+#include "upperstack_config.h"
+#include <bt_types.h>
+
+/** @addtogroup GAP_COMMON GAP Common
+ * @brief GAP common module
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GAP_Common_Exported_Macros GAP Common Exported Macros
+ * @{
+ */
+
+/** @defgroup GAP_Common_Macros GAP Common Macros
+ * @{
+ */
+#define GAP_BD_ADDR_LEN 6 //!< Default Bluetooth Device Address Length.
+#define GAP_KEY_LEN 16 //!< Default Long Term Key(LTK) length.
+#define GAP_DEVICE_NAME_LEN (39+1)//!< Max length of device name, if device name length exceeds it, it will be truncated.
+#define GAP_PASSCODE_MAX 999999//!< Maximum Pairing Passcode/Passkey value. Range of a passkey can be 0 - 999,999.
+#define GAP_OOB_LEN 16 //!< Length of out of band data.
+/**
+ * @}
+ */
+
+/** @defgroup BOND_PAIRING_MODE_DEFINES Pairing Modes
+ * @{
+ */
+#define GAP_PAIRING_MODE_NO_PAIRING 0x00 //!< Pairing is not allowed.
+#define GAP_PAIRING_MODE_PAIRABLE 0x01 //!< Pairable, Wait for a pairing request from master or security request from slave.
+/**
+ * @}
+ */
+
+/** @defgroup BOND_MITM_DEFINES Mitm And Bonding Flags
+ * @{
+ */
+#define GAP_AUTHEN_BIT_NONE 0 //!< No authentication required.
+#define GAP_AUTHEN_BIT_BONDING_FLAG 0x0001 //!< Bonding is required
+#define GAP_AUTHEN_BIT_MITM_FLAG 0x0004 //!< Mitm is preferred
+#if F_BT_LE_4_2_SC_SUPPORT
+#define GAP_AUTHEN_BIT_SC_FLAG 0x0008 //!< Secure connection is preferred
+#define GAP_AUTHEN_BIT_SC_ONLY_FLAG 0x0200 //!< Secure connection only mode for BLE is required
+#endif
+#if F_BT_KEY_PRESS_SUPPORT
+#define GAP_AUTHEN_BIT_KEYPRESS_FLAG 0x0010 //!< Keypress notification is preferred
+#endif
+#define GAP_AUTHEN_BIT_FORCE_BONDING_FLAG 0x0100 //!< Force bonding is required
+
+/**
+ * @}
+ */
+
+/** @defgroup GAP_COMMON_MSG_TYPE GAP Msg Type
+ * @{
+ */
+#define GAP_MSG_WRITE_AIRPLAN_MODE 0x00 //!<gap_write_airplan_mode
+#define GAP_MSG_READ_AIRPLAN_MODE 0x01 //!<gap_read_airplan_mode
+#define GAP_MSG_VENDOR_CMD_RSP 0x03 //!<gap_vendor_cmd_req
+#define GAP_MSG_VENDOR_EVT_INFO 0x04 //!<gap_vendor_cmd_req
+/**
+ * @}
+ */
+
+/** End of GAP_Common_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_Common_Exported_Types GAP Common Exported Types
+ * @{
+ */
+
+/** @brief I/O Capabilities */
+typedef enum
+{
+ GAP_IO_CAP_DISPLAY_ONLY, //!< Only a Display present, no Keyboard or Yes/No Keys.
+ GAP_IO_CAP_DISPLAY_YES_NO, //!< Display and Yes/No Keys present.
+ GAP_IO_CAP_KEYBOARD_ONLY, //!< Only a Keyboard present, no Display.
+ GAP_IO_CAP_NO_INPUT_NO_OUTPUT, //!< No input/output capabilities.
+ GAP_IO_CAP_KEYBOARD_DISPLAY, //!< Keyboard and Display present.
+} T_GAP_IO_CAP;
+
+/** @brief Key types */
+typedef enum
+{
+ GAP_KEY_LE_LOCAL_LTK = 0x11, /**< BLE Long Term Key Blob. */
+ GAP_KEY_LE_REMOTE_LTK = 0x12, /**< BLE Long Term Key Blob. */
+ GAP_KEY_LE_LOCAL_IRK = 0x13, /**< BLE Identity Resolving Key. */
+ GAP_KEY_LE_REMOTE_IRK = 0x14, /**< BLE Identity Resolving Key. */
+ GAP_KEY_LE_LOCAL_CSRK = 0x15, /**< BLE Local CSR Key. */
+ GAP_KEY_LE_REMOTE_CSRK = 0x16, /**< BLE Remote CSR Key. */
+ GAP_KEY_DELETE = 0xFF /**< Link key is no longer valid and should be deleted. */
+} T_GAP_KEY_TYPE;
+
+/** @brief Keypress notification type.*/
+typedef enum
+{
+ GAP_PASSKEY_ENTRY_STARTED, /**< The passkey key entry protocol procedure is started. */
+ GAP_PASSKEY_DIGIT_ENTERED, /**< A digit is entered by the remote user. */
+ GAP_PASSKEY_DIGIT_ERASED, /**< A digit is erased by the remote user. */
+ GAP_PASSKEY_CLEARED, /**< The display is cleared by the remote user. */
+ GAP_PASSKEY_ENTRY_CMPL, /**< The passkey key entry protocol procedure is completed. */
+} T_GAP_KEYPRESS_NOTIF_TYPE;
+
+/** @brief GAP Remote Address Type */
+typedef enum
+{
+ GAP_REMOTE_ADDR_LE_PUBLIC = 0x00, /**< LE Public device address type. */
+ GAP_REMOTE_ADDR_LE_RANDOM = 0x01, /**< LE Random device address type. */
+#if F_BT_LE_PRIVACY_SUPPORT
+ GAP_REMOTE_ADDR_LE_PUBLIC_IDENTITY = 0x02, /**< LE Public identity address type. */
+ GAP_REMOTE_ADDR_LE_RANDOM_IDENTITY = 0x03, /**< LE Random identity address type. */
+#endif
+ GAP_REMOTE_ADDR_LE_ANONYMOUS = 0xff, /**< LE anonymous device address type. */
+} T_GAP_REMOTE_ADDR_TYPE;
+
+/** @brief GAP Cause List */
+typedef enum
+{
+ GAP_CAUSE_SUCCESS = 0x00,//!< Operation success.
+ GAP_CAUSE_ALREADY_IN_REQ = 0x01,//!< Operation already in progress.
+ GAP_CAUSE_INVALID_STATE = 0x02,//!< Invalid state.
+ GAP_CAUSE_INVALID_PARAM = 0x03,//!< Invalid parameter.
+ GAP_CAUSE_NON_CONN = 0x04,//!< No connection establishment.
+ GAP_CAUSE_NOT_FIND_IRK = 0x05,//!< IRK not found.
+ GAP_CAUSE_ERROR_CREDITS = 0x06,//!< Credits error.
+ GAP_CAUSE_SEND_REQ_FAILED = 0x07,//!< Send Request failed.
+ GAP_CAUSE_NO_RESOURCE = 0x08,//!< No resource.
+ GAP_CAUSE_INVALID_PDU_SIZE = 0x09,//!< Invalid PDU size.
+ GAP_CAUSE_NOT_FIND = 0x0a,//!< Not Found.
+ GAP_CAUSE_CONN_LIMIT = 0x0b,//!< Connection reachs limited count.
+ GAP_CAUSE_NO_BOND = 0x0c,//!< No Bond.
+ GAP_CAUSE_ERROR_UNKNOWN = 0xFF,//!< Unknown error.
+} T_GAP_CAUSE;
+
+/** @brief GAP Confirmation Cause List */
+typedef enum
+{
+ GAP_CFM_CAUSE_ACCEPT = (GAP_ERR | GAP_ACCEPT), /**< Accept for indication, only used when confirmation. */
+ GAP_CFM_CAUSE_REJECT = (GAP_ERR | GAP_ERR_REJECT),/**< Reject for indication, only used when confirmation. */
+} T_GAP_CFM_CAUSE;
+
+/** @brief APP Return Result List */
+typedef enum
+{
+ APP_RESULT_SUCCESS = (APP_SUCCESS),
+ APP_RESULT_PENDING = (APP_ERR | APP_ERR_PENDING),
+ APP_RESULT_ACCEPT = (APP_ERR | APP_ERR_ACCEPT),
+ APP_RESULT_REJECT = (APP_ERR | APP_ERR_REJECT),
+ APP_RESULT_NOT_RELEASE = (APP_ERR | APP_ERR_NOT_RELEASE),
+
+ APP_RESULT_PREP_QUEUE_FULL = (ATT_ERR | ATT_ERR_PREP_QUEUE_FULL),
+ APP_RESULT_INVALID_OFFSET = (ATT_ERR | ATT_ERR_INVALID_OFFSET),
+ APP_RESULT_INVALID_VALUE_SIZE = (ATT_ERR | ATT_ERR_INVALID_VALUE_SIZE),
+ APP_RESULT_INVALID_PDU = (ATT_ERR | ATT_ERR_INVALID_PDU),
+ APP_RESULT_ATTR_NOT_FOUND = (ATT_ERR | ATT_ERR_ATTR_NOT_FOUND),
+ APP_RESULT_ATTR_NOT_LONG = (ATT_ERR | ATT_ERR_ATTR_NOT_LONG),
+ APP_RESULT_INSUFFICIENT_RESOURCES = (ATT_ERR | ATT_ERR_INSUFFICIENT_RESOURCES),
+ APP_RESULT_VALUE_NOT_ALLOWED = (ATT_ERR | ATT_ERR_VALUE_NOT_ALLOWED),
+ APP_RESULT_APP_ERR = (ATT_ERR | ATT_ERR_MIN_APPLIC_CODE),
+ APP_RESULT_CCCD_IMPROPERLY_CONFIGURED = (ATT_ERR | ATT_ERR_CCCD_IMPROPERLY_CONFIGURED),
+ APP_RESULT_PROC_ALREADY_IN_PROGRESS = (ATT_ERR | ATT_ERR_PROC_ALREADY_IN_PROGRESS),
+} T_APP_RESULT;
+
+/** @brief GAP Parameter List */
+typedef enum
+{
+ GAP_PARAM_BD_ADDR = 0x200,//!< Locol Device's Address. Read Only. Size is uint8[GAP_BD_ADDR_LEN]. This item is read from the controller.
+ GAP_PARAM_BOND_PAIRING_MODE = 0x202,//!< Pairing Mode. Read/Write. Size is uint8_t. Default is GAP_PAIRING_MODE_PAIRABLE (@ref BOND_PAIRING_MODE_DEFINES).
+ GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS = 0x203,//!< Man-In-The-Middle (MITM) basically turns on Passkey protection in the pairing algorithm. Read/Write. Size is uint8_t. Default is GAP_AUTHEN_NO_MITM_YES_BOND (@ref BOND_MITM_DEFINES).
+ GAP_PARAM_BOND_IO_CAPABILITIES = 0x204,//!< I/O capabilities. Read/Write. Size is uint8_t. Default is GAP_IO_CAP_NO_INPUT_NO_OUTPUT (@ref T_GAP_IO_CAP).
+#if F_BT_OOB_SUPPORT
+ GAP_PARAM_BOND_OOB_ENABLED = 0x205,//!< OOB data available for pairing algorithm. Read/Write. Size is uint8_t. Default is 0(disabled).
+#endif
+} T_GAP_PARAM_TYPE;
+
+#if F_BT_LE_5_0_PA_SYNC_SUPPORT
+//fixme
+/** @brief GAP Remote Address Type */
+typedef enum
+{
+ PA_SYNC_ADV_ADDR_PUBLIC = 0x00, /**< Public Device Address or Public Identity Address. */
+ PA_SYNC_ADV_ADDR_RANDOM = 0x01, /**< Random Device Address or Random (static) Identity Address. */
+#if F_BT_LE_PRIVACY_SUPPORT
+ PA_SYNC_ADV_ADDR_RPA_PUBLIC_IDENTITY = 0x02, /**< Public Identity Address (corresponds to Resolved Private Address), only for event. */
+ PA_SYNC_ADV_ADDR_RPA_RANDOM_IDENTITY = 0x03, /**< Random (static) Identity Address (corresponds to Resolved Private Address), only for event. */
+#endif
+} T_GAP_PA_SYNC_ADV_ADDR_TYPE;
+#endif
+
+/** @brief Response for write airplane mode */
+typedef struct
+{
+ uint16_t cause; //!< Write response result.
+} T_GAP_WRITE_AIRPLAN_MODE_RSP;
+
+/** @brief Response for read airplane mode */
+typedef struct
+{
+ uint16_t cause; //!< Read response result.
+ uint8_t mode; //!< Current airplane mode.
+} T_GAP_READ_AIRPLAN_MODE_RSP;
+
+typedef struct
+{
+ uint16_t command; /**< Vendor command. Should be the same as that in request. */
+ uint16_t cause; /**< Result of executing command. */
+ bool is_cmpl_evt; /**< Whether the response is generated from command complete event. */
+ uint8_t param_len; /**< Response parameter length. */
+ uint8_t param[1]; /**< Response parameter buffer. */
+} T_GAP_VENDOR_CMD_RSP;
+
+typedef struct
+{
+ uint8_t param_len; /**< Information parameter length. */
+ uint8_t param[1]; /**< Information parameter buffer. */
+} T_GAP_VENDOR_EVT_INFO;
+
+/** @brief Response for airplane mode */
+typedef union
+{
+ T_GAP_WRITE_AIRPLAN_MODE_RSP *p_gap_write_airplan_mode_rsp; //!< Write airplane mode response.
+ T_GAP_READ_AIRPLAN_MODE_RSP *p_gap_read_airplan_mode_rsp;//!< Read airplane mode response.
+ T_GAP_VENDOR_CMD_RSP *p_gap_vendor_cmd_rsp;
+ T_GAP_VENDOR_EVT_INFO *p_gap_vendor_evt_info;
+} T_GAP_CB_DATA;
+
+/** End of GAP_Common_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @defgroup GAP_COMMON_EXPORT_Functions GAP Common Exported Functions
+ *
+ * @{
+ */
+
+/**
+ * @brief Callback for gap to notify app
+ * @param[in] cb_type callback msy type @ref GAP_COMMON_MSG_TYPE.
+ * @param[in] p_cb_data point to callback data @ref T_GAP_CB_DATA.
+ * @retval void
+ */
+typedef void(*P_FUN_GAP_APP_CB)(uint8_t cb_type, void *p_cb_data);
+
+/**
+ * @brief Make upper stack ready to use by sending the register request.
+ * @param[in] evt_queue Event queue handle which is created by APP.
+ * @param[in] io_queue IO message queue handle which is created by APP.
+ * @param[in] msg_queue_elem_num Number of GAP message queue which will be created by GAP module.
+ * @return result
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_main_task(void *p_param)
+ {
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+ }
+ * \endcode
+ */
+bool gap_start_bt_stack(void *evt_queue, void *io_queue, uint16_t msg_queue_elem_num);
+
+/**
+ * @brief Initialize gap lib to use some extended functions.
+ * @return void
+ * <b>Example usage</b>
+ * \code{.c}
+ int main(void)
+ {
+ ...
+ gap_lib_init();
+ ...
+ }
+ * \endcode
+ */
+void gap_lib_init(void);
+
+/**
+ * @brief Register callback to gap, when messages in @ref GAP_COMMON_MSG_TYPE happens, it will callback to app.
+ * @param[in] app_callback Callback function provided by the APP to handle gap common messages sent from the GAP.
+ * @arg NULL -> Not send gap common messages to APP.
+ * @arg Other -> Use application defined callback function.
+ * @return void
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_gap_init()
+ {
+ ...
+ le_register_app_cb(app_gap_callback);
+ gap_register_app_cb(app_gap_common_callback);
+ }
+ \endcode
+ */
+void gap_register_app_cb(P_FUN_GAP_APP_CB app_callback);
+
+/**
+ * @brief Set a GAP parameter.
+ *
+ * NOTE: You can call this function with a GAP Common Parameter type and it will set the
+ * GAP Parameter. GAP Peripheral Parameters are defined in @ref T_GAP_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param GAP parameter ID: @ref T_GAP_PARAM_TYPE.
+ * @param[in] len Length of data to write.
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type param is uint16, p_value will be cast to
+ * pointer of uint16_t).
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_gap_init(void)
+ {
+ ...
+ //GAP Bond Manager parameters
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG | GAP_AUTHEN_BIT_MITM_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+
+ // Setup the GAP Bond Manager
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gap_set_param(T_GAP_PARAM_TYPE param, uint8_t len, void *p_value);
+
+/**
+ * @brief Get a GAP Common parameter.
+ *
+ * NOTE: You can call this function with a GAP Common Parameter type and it will get a
+ * GAP Common Parameter. GAP Common Parameters are defined in @ref T_GAP_PARAM_TYPE.
+ *
+ * @param[in] param GAP parameter type: @ref T_GAP_PARAM_TYPE
+ * @param[in,out] p_value Pointer to location to get the value. This is dependent on
+ * the parameter ID and WILL be cast to the appropriate
+ * data type (For example: if data type param is uint16, p_value will be cast to
+ * pointer of uint16_t).
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t bt_addr[6];
+ gap_get_param(GAP_PARAM_BD_ADDR, bt_addr);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gap_get_param(T_GAP_PARAM_TYPE param, void *p_value);
+
+/**
+ * @brief Make the device in pairable mode.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ */
+T_GAP_CAUSE gap_set_pairable_mode(void);
+
+/**
+ * @brief Write command to control device to enter airplane mode, the result will be notified by callback
+ regisgtered by @ref gap_register_app_cb.
+ * @param[in] mode the mode of the device
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_wairplane(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ T_GAP_CAUSE cause;
+ uint8_t mode = p_parse_value->dw_param[0];
+ cause = gap_write_airplan_mode(mode);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+
+ void app_gap_common_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_GAP_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_GAP_CB_DATA));
+ APP_PRINT_INFO1("app_gap_common_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ case GAP_MSG_WRITE_AIRPLAN_MODE:
+ APP_PRINT_INFO1("GAP_MSG_WRITE_AIRPLAN_MODE: cause 0x%x",
+ cb_data.p_gap_write_airplan_mode_rsp->cause);
+ break;
+ case GAP_MSG_READ_AIRPLAN_MODE:
+ APP_PRINT_INFO2("GAP_MSG_READ_AIRPLAN_MODE: cause 0x%x, mode %d",
+ cb_data.p_gap_read_airplan_mode_rsp->cause,
+ cb_data.p_gap_read_airplan_mode_rsp->mode);
+ break;
+ default:
+ break;
+ }
+ return;
+ }
+ * \endcode
+ */
+
+T_GAP_CAUSE gap_write_airplan_mode(uint8_t mode);
+
+/**
+ * @brief Read the airplane mode of the device, the result will be notified by callback regisgtered
+ by @ref gap_register_app_cb.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_rairplane(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ T_GAP_CAUSE cause;
+ cause = gap_read_airplan_mode();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+
+ void app_gap_common_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_GAP_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_GAP_CB_DATA));
+ APP_PRINT_INFO1("app_gap_common_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ case GAP_MSG_WRITE_AIRPLAN_MODE:
+ APP_PRINT_INFO1("GAP_MSG_WRITE_AIRPLAN_MODE: cause 0x%x",
+ cb_data.p_gap_write_airplan_mode_rsp->cause);
+ break;
+ case GAP_MSG_READ_AIRPLAN_MODE:
+ APP_PRINT_INFO2("GAP_MSG_READ_AIRPLAN_MODE: cause 0x%x, mode %d",
+ cb_data.p_gap_read_airplan_mode_rsp->cause,
+ cb_data.p_gap_read_airplan_mode_rsp->mode);
+ break;
+ default:
+ break;
+ }
+ return;
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gap_read_airplan_mode(void);
+
+/**
+ * @brief Handle GAP message received from BT stack or timeout event for GAP timer.
+ * @param[in] event Event type which is received from APP event queue.
+ * @return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_main_task(void *p_param)
+ {
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+ }
+ * \endcode
+ */
+void gap_handle_msg(uint8_t event);
+
+/**
+ * @brief Release the buffer of GAP supplied.
+ * @param[in] p_buf Point the buffer that needs to release.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ uint8_t *p_data_buf;
+ uint16_t data_offset;
+ T_APP_RESULT simp_ble_service_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index, T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value,
+ P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+ {
+ ......
+ server_get_write_cmd_data_buffer(conn_id, &p_data_buf, &data_offset);
+ return APP_RESULT_NOT_RELEASE;
+ }
+ void release(void)
+ {
+ if(p_data_buf != NULL)
+ {
+ gap_buffer_free(p_data_buf);
+ p_data_buf = NULL;
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gap_buffer_free(void *p_buf);
+
+/**
+ * @brief Send vendor command.
+ * @param[in] op Opcode of command.
+ * @param[in] len Length of parameters.
+ * @param[in] p_param Pointer to parameters to write.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Send request successfully.
+ * @retval Others Failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ //send vendor command
+ void test(void)
+ {
+ T_GAP_CAUSE cause = GAP_CAUSE_SUCCESS;
+ uint16_t opcode;
+ uint8_t param[2];
+ param[0] = 0;
+ param[1] = 0;
+ cause = gap_vendor_cmd_req(opcode, 2, param);
+ }
+
+ //register callback, and handle response
+ void app_le_gap_init(void)
+ {
+ ......
+ gap_register_app_cb(app_gap_common_callback);
+ }
+
+ void app_gap_common_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_GAP_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_GAP_CB_DATA));
+ APP_PRINT_INFO1("app_gap_common_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ case GAP_MSG_VENDOR_CMD_RSP:
+ APP_PRINT_INFO3("GAP_MSG_VENDOR_CMD_RSP: command 0x%x, cause 0x%x, param_len %d",
+ cb_data.p_gap_vendor_cmd_rsp->command,
+ cb_data.p_gap_vendor_cmd_rsp->cause,
+ cb_data.p_gap_vendor_cmd_rsp->param_len);
+ break;
+ ......
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gap_vendor_cmd_req(uint16_t op, uint8_t len, uint8_t *p_param);
+/** @} */ /* End of group GAP_COMMON_EXPORT_Functions */
+
+/** @} */ /* End of group GAP_COMMON */
+
+/*-------------------------------------------------------------------
+-------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_H */
diff --git a/inc/bluetooth/gap/gap_adv.h b/inc/bluetooth/gap/gap_adv.h
new file mode 100644
index 0000000..11c6018
--- /dev/null
+++ b/inc/bluetooth/gap/gap_adv.h
@@ -0,0 +1,482 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_adv.h
+* @brief Head file for Gap adv
+* @details This file defines advertising related API
+* @author ranhui
+* @date 2016-02-18
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_ADV_H
+#define GAP_ADV_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#if F_BT_LE_GAP_PERIPHERAL_SUPPORT
+#include "gap_le.h"
+
+
+/** @addtogroup GAP_BROADCASTER_Role GAP Broadcaster Role
+ * @brief GAP Broadcaster Role
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @addtogroup GAP_Broadcaster_Exported_Macros GAP Broadcaster Exported Macros
+ * @brief
+ * @{
+ */
+#define GAP_MAX_ADV_LEN 31 //!< BLE Maximum Advertising or Scan Response Packet Length
+
+/** End of GAP_Broadcaster_Exported_Macros
+* @}
+*/
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_Broadcaster_Exported_Types GAP Broadcaster Exported Types
+ * @brief
+ * @{
+ */
+
+/** @brief LE advertising parameter types */
+typedef enum
+{
+ GAP_PARAM_ADV_LOCAL_ADDR_TYPE = 0x260,//!< Advertisement used local bluetooth device address type. Read/Write Size is uint8.
+ GAP_PARAM_ADV_DATA = 0x261,//!< Advertisement Data. Read/Write. Max size is uint8[GAP_MAX_ADV_LEN]. Default is "02:01:05", which means that it is a Limited Discoverable Advertisement.
+ GAP_PARAM_SCAN_RSP_DATA = 0x262,//!< Scan Response Data. Read/Write. Max size is uint8[GAP_MAX_ADV_LEN]. Defaults to all 0.
+ GAP_PARAM_ADV_EVENT_TYPE = 0x263,//!< Advertisement Type. Read/Write. Size is uint8. Default is GAP_ADTYPE_ADV_IND (@ref T_GAP_ADTYPE).
+ GAP_PARAM_ADV_DIRECT_ADDR_TYPE = 0x264,//!< Direct Advertisement Address Type. Read/Write. Size is uint8.
+ GAP_PARAM_ADV_DIRECT_ADDR = 0x265,//!< Direct Advertisement Address. Read/Write. Size is uint8[GAP_BD_ADDR_LEN]. Default is NULL.
+ GAP_PARAM_ADV_CHANNEL_MAP = 0x266,//!< Which channels to advertise on. Read/Write Size is uint8. Default is GAP_ADVCHAN_ALL (@ref ADV_CHANNEL_MAP)
+ GAP_PARAM_ADV_FILTER_POLICY = 0x267,//!< Filter Policy. Ignored when directed advertising is used. Read/Write. Size is uint8. Default is GAP_ADV_FILTER_ANY (@ref T_GAP_ADV_FILTER_POLICY).
+ GAP_PARAM_ADV_INTERVAL_MIN = 0x268,//!< Minimum advertising interval for undirected and low duty cycle directed advertising. Value range: 0x0020 - 0x4000 (20ms - 10240ms 0.625ms/step),Read/Write Size is uint16_t.
+ GAP_PARAM_ADV_INTERVAL_MAX = 0x269,//!< Maximum advertising interval for undirected and low duty cycle directed advertising. Value range: 0x0020 - 0x4000 (20ms - 10240ms 0.625ms/step)),Read/Write Size is uint16_t.
+} T_LE_ADV_PARAM_TYPE;
+
+/** End of GAP_Broadcaster_Exported_Types
+* @}
+*/
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup GAP_Broadcaster_Exported_Functions GAP Broadcaster Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Set a GAP advertising parameter.
+ *
+ * NOTE: You can call this function with a advertising parameter type and it will set the
+ * advertising parameter. Advertising parameters are defined in @ref T_LE_ADV_PARAM_TYPE.
+ * If the "len" field sets to the size of "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param LE advertising parameter type: @ref T_LE_ADV_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and will be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_INVALID_PARAM Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_gap_init(void)
+ {
+ //advertising parameters
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MIN;
+
+ //Set advertising parameters
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), scan_rsp_data);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_adv_set_param(T_LE_ADV_PARAM_TYPE param, uint8_t len, void *p_value);
+
+/**
+ * @brief Get a GAP advertising parameter.
+ *
+ * NOTE: You can call this function with a advertising parameter type and it will get a
+ * advertising parameter. Advertising parameters are defined in @ref T_LE_ADV_PARAM_TYPE.
+ * Also, the "p_value" field must point to a data with type "uint16_t".
+ *
+ * @param[in] param Advertising parameter type: @ref T_LE_ADV_PARAM_TYPE
+ * @param[in,out] p_value Pointer to the location to get the parameter value. This is dependent on
+ * the parameter type and will be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_INVALID_PARAM Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t local_bd_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+ le_adv_get_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, &local_bd_type);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_adv_get_param(T_LE_ADV_PARAM_TYPE param, void *p_value);
+
+/**
+ * @brief Start advertising with params set by @ref le_adv_set_param.
+ *
+ * NOTE: This function can be called after @ref gap_start_bt_stack is invoked.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Start request success.
+ * @retval other Start request failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MIN;
+
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ le_adv_start();
+ }
+
+ void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+ {
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+
+ le_adv_start();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+ }
+
+ //When the link was establishment, app_gap_callback will be called with callback type GAP_MSG_LE_CREATE_CONN_IND
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_CREATE_CONN_IND:
+ APP_PRINT_INFO0("GAP_MSG_LE_CREATE_CONN_IND");
+ result = APP_RESULT_ACCEPT;
+ break;
+ ...
+ }
+ }
+
+ * \endcode
+ */
+T_GAP_CAUSE le_adv_start(void);
+
+/**
+ * @brief Stop advertising. When the device is in advertising state, App can call this API to stop advertising.
+ *
+ * NOTE: This function can be called after @ref gap_start_bt_stack is invoked.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ le_adv_stop();
+ }
+
+ void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+ {
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+
+ le_adv_start();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_adv_stop(void);
+
+/**
+ * @brief Update advertising parameters.
+ * Application can update one or more advertising parameters, @ref le_adv_set_param should be called first to specify
+ * which parameter shall be update. If gap adv state is not @ref GAP_ADV_STATE_IDLE, application can only update
+ * advertising data and scan response data.
+ *
+ * NOTE: This function can be called after @ref gap_start_bt_stack is invoked.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ ...
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), adv_data);
+ le_adv_update_param();
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_ADV_UPDATE_PARAM:
+ APP_PRINT_INFO1("GAP_MSG_LE_ADV_UPDATE_PARAM: cause 0x%x",
+ cb_data.p_le_adv_update_param_rsp->cause);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+
+T_GAP_CAUSE le_adv_update_param(void);
+
+#if F_BT_LE_READ_ADV_TX_POWRE_SUPPORT
+/**
+ * @brief Read advertising transmit power.
+ *
+ * NOTE: This function can be called after @ref gap_start_bt_stack is invoked.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ le_adv_read_tx_power();
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_ADV_READ_TX_POWER:
+ APP_PRINT_INFO2("GAP_MSG_LE_ADV_READ_TX_POWER: cause 0x%x, tx_power_level 0x%x",
+ cb_data.p_le_adv_read_tx_power_rsp->cause,
+ cb_data.p_le_adv_read_tx_power_rsp->tx_power_level);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_adv_read_tx_power(void);
+#endif
+/**
+ * @brief Set the advertising tx power for the device, or reset advertising tx power to default value.
+ *
+ * NOTE: This function can be called after @ref gap_start_bt_stack is invoked.
+ *
+ * @param[in] type adv tx power type.
+ * @param[in] tx_gain index for power level. NOTE: The following tx gain table may be changed in future version.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ T_GAP_CAUSE cause;
+ uint8_t type = GAP_ADV_TX_POW_SET_1M;
+ uint8_t tx_gain = 0x80;
+ cause = le_adv_set_tx_power((T_GAP_ADV_TX_POW_TYPE)type, tx_gain);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: msgType = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_ADV_SET_TX_POWER:
+ APP_PRINT_INFO1("GAP_MSG_LE_ADV_SET_TX_POWER: cause 0x%x",
+ p_data->p_le_adv_set_tx_power_rsp->cause);
+ break;
+ ...
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_adv_set_tx_power(T_GAP_ADV_TX_POW_TYPE type, uint8_t tx_gain);
+
+/**
+ * @brief Trigger One Shot Advertising.
+ * NOTE: Trigger advertising after guard_slot * 625 + guard_usec + wait_usec(us).
+ * This function can be called after @ref gap_start_bt_stack is invoked.
+ * This function cannot be used if advertising type is connectable high duty cycle directed advertising.
+ *
+ * @param[in] guard_slot The delay time to trigger advertising in units of 625us, range: 0~224
+ * @param[in] guard_usec The delay time to trigger advertising in units of us, range: 0~65535
+ * @param[in] wait_usec The delay time to trigger advertising in units of us, range: 0~65535
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS: Operation success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_oneshot(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t guard_slot = p_parse_value->dw_param[0];
+ uint16_t guard_usec = p_parse_value->dw_param[1];
+ uint16_t wait_usec = p_parse_value->dw_param[2];
+ T_GAP_CAUSE cause;
+
+ cause = le_vendor_one_shot_adv(guard_slot, guard_usec, wait_usec);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_VENDOR_ONE_SHOT_ADV:
+ APP_PRINT_INFO1("GAP_MSG_LE_VENDOR_ONE_SHOT_ADV: cause 0x%x",
+ p_data->le_cause.cause);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_vendor_one_shot_adv(uint8_t guard_slot, uint16_t guard_usec, uint16_t wait_usec);
+
+/** @} */ /* End of group GAP_Broadcaster_Exported_Functions */
+/** @} */ /* End of group GAP_Broadcaster_Role */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_ADV_H */
diff --git a/inc/bluetooth/gap/gap_aox.h b/inc/bluetooth/gap/gap_aox.h
new file mode 100644
index 0000000..4f5227d
--- /dev/null
+++ b/inc/bluetooth/gap/gap_aox.h
@@ -0,0 +1,375 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_aox.h
+* @brief Head file for GAP AoA/AoD
+* @details
+* @author
+* @date 2020-06-18
+* @version v0.8
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_AOX_H
+#define GAP_AOX_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#include "gap_le.h"
+#include "gap_le_types.h"
+
+#if F_BT_LE_5_1_AOA_AOD_SUPPORT
+
+/** @addtogroup GAP GAP Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE GAP LE Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE_AOX GAP LE AoA/AoD Module
+ * @{
+ */
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GAP_LE_AOX_Exported_Macros GAP LE AoX Exported Macros
+ * @{
+ */
+
+/** @defgroup GAP_LE_AOX_MSG_Types GAP LE AoX Msg Types
+ * @{
+ */
+#define GAP_MSG_LE_AOX_READ_ANTENNA_INFORMATION 0x01 /**<Response msg type for le_aox_read_antenna_information. */
+
+#define GAP_MSG_LE_AOX_SET_CONN_CTE_RECEIVE_PARAMS 0x21 /**<Response msg type for le_aox_set_conn_cte_receive_params. */
+#define GAP_MSG_LE_AOX_SET_CONN_CTE_TRANSMIT_PARAMS 0x22 /**<Response msg type for le_aox_set_conn_cte_transmit_params. */
+#define GAP_MSG_LE_AOX_CONN_CTE_RESPONSE_ENABLE 0x23 /**<Response msg type for le_aox_conn_cte_response_enable. */
+#define GAP_MSG_LE_AOX_CONN_CTE_REQUEST_ENABLE 0x24 /**<Response msg type for le_aox_conn_cte_request_enable. */
+#define GAP_MSG_LE_AOX_CONN_IQ_REPORT_INFO 0x25 /**<Notification msg type for connection IQ report. */
+#define GAP_MSG_LE_AOX_CTE_REQUEST_FAILED_INFO 0x26 /**<Notification msg type for failure of CTE request. */
+
+#define GAP_MSG_LE_AOX_CONNLESS_TRANSMITTER_SET_CTE_TRANSMIT_PARAMS 0x40 /**<Response msg type for le_aox_connless_transmitter_set_cte_transmit_params. */
+#define GAP_MSG_LE_AOX_CONNLESS_TRANSMITTER_STATE_CHANGE_INFO 0x41 /**<Notification msg type for connectionless CTE transmitter state change. */
+
+#define GAP_MSG_LE_AOX_CONNLESS_RECEIVER_SET_IQ_SAMPLING_ENABLE 0x50 /**<Response msg type for le_aox_connless_receiver_set_iq_sampling_enable. */
+#define GAP_MSG_LE_AOX_CONNLESS_RECEIVER_CONNLESS_IQ_REPORT_INFO 0x51 /**<Notification msg type for connectionless IQ report info. */
+
+/** @defgroup GAP_AOX_SUPPORTED_SWITCH_SAMPLE_BITS LE AoX Supported Switching Sampling Rates Bits
+* @{
+ */
+#define GAP_AOX_SUPPORTED_SWITCH_AOD_TRANS_BIT 0x01 /**< 1 us switching supported for AoD transmission. */
+#define GAP_AOX_SUPPORTED_SAMPLE_AOD_RECEP_BIT 0x02 /**< 1 us sampling supported for AoD reception. */
+#define GAP_AOX_SUPPORTED_SWITCH_SAMPLE_AOA_RECEP_BIT 0x04 /**< 1 us switching and sampling supported for AoA reception. */
+/**
+ * @}
+ */
+
+/** End of GAP_LE_AOX_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_AOX_Exported_Types GAP LE AoA/AoD Exported Types
+ * @brief
+ * @{
+ */
+typedef enum
+{
+ GAP_AOX_PACKET_CRC_CORRECT = 0x00, /**< CRC was correct. */
+ GAP_AOX_PACKET_CRC_INCORRECT_DETERMINE = 0x01, /**< CRC was incorrect, and the Length and CTETime fields
+ of the packet used to determine sampling points. */
+ GAP_AOX_PACKET_CRC_INCORRECT_DETERMINE_OTHERWAY = 0x02, /**< CRC was incorrect but the Controller has determined
+ the position and length of the Constant Tone Extension
+ in some other way. */
+ GAP_AOX_PACKET_INSUFFI_RESOURCES = 0xFF, /**< Insufficient resources to sample
+ (Data_Channel_Index, CTE_Type, and Slot_Durations invalid). */
+} T_GAP_AOX_PACKET_STATUS_TYPE;
+
+typedef struct
+{
+ uint16_t cause;
+ uint8_t supported_switching_sampling_rates; /**< A bit field that indicates the type of switching sampling rates
+ supported by the Controller. @ref GAP_AOX_SUPPORTED_SWITCH_SAMPLE_BITS.*/
+ uint8_t num_antennae;
+ uint8_t max_switching_pattern_length;
+ uint8_t max_cte_length;
+} T_LE_AOX_READ_ANTENNA_INFORMATION_RSP;
+
+#if F_BT_LE_5_1_AOX_CONN_SUPPORT
+typedef struct
+{
+ uint16_t cause;
+ uint8_t conn_id;
+} T_LE_AOX_SET_CONN_CTE_RECEIVE_PARAMS_RSP;
+
+typedef struct
+{
+ uint16_t cause;
+ uint8_t conn_id;
+} T_LE_AOX_SET_CONN_CTE_TRANSMIT_PARAMS_RSP;
+
+typedef struct
+{
+ uint16_t cause;
+ uint8_t conn_id;
+} T_LE_AOX_CONN_CTE_REQUEST_ENABLE_RSP;
+
+typedef struct
+{
+ uint16_t cause;
+ uint8_t conn_id;
+} T_LE_AOX_CONN_CTE_RESPONSE_ENABLE_RSP;
+
+typedef struct
+{
+ uint8_t conn_id;
+ uint8_t rx_phy;/**< 0x01: The receiver PHY for the connection is LE 1M.
+ 0x02: The receiver PHY for the connection is LE 2M. */
+ uint8_t data_chan_index;/**< The index of the data channel on which the
+ Data Physical Channel PDU was received.
+ Range: 0x00 to 0x24. */
+ int16_t rssi;/**< RSSI of the packet.
+ Range: -1270 to +200, Units: 0.1 dBm. */
+ uint8_t rssi_antenna_id;
+ T_GAP_CTE_TYPE cte_type;
+ T_GAP_SLOT_DUATIONS_TYPE slot_durations;
+ T_GAP_AOX_PACKET_STATUS_TYPE packet_status;
+ uint16_t connection_event_counter;
+ uint8_t sample_count; /**< 0x00: No samples provided
+ (only permitted if Packet_Status is 0xFF);
+ 0x09 - 0x52:Total number of sample pairs
+ (there shall be the same number of I samples and Q samples). */
+ int8_t *p_iq_sample; /**< I_Sample[0],Q_Sample[0], ... ,
+ I_Sample[i],Q_Sample[i]
+ Value 0x80 indicates No valid sample available. */
+} T_LE_AOX_CONN_IQ_REPORT_INFO;
+
+typedef struct
+{
+ uint16_t cause;
+ uint8_t conn_id;
+} T_LE_AOX_CTE_REQUEST_FAILED_INFO;
+#endif
+
+#if F_BT_LE_5_1_AOX_CONNLESS_SUPPORT
+#if F_BT_LE_5_1_AOX_CONNLESS_TRANSMITTER_SUPPORT
+typedef struct
+{
+ uint16_t cause;
+ uint8_t adv_handle;
+} T_LE_AOX_CONNLESS_TRANSMITTER_SET_CTE_TRANSMIT_PARAMS_RSP;
+
+typedef struct
+{
+ uint16_t cause;
+ uint8_t adv_handle;
+ uint8_t state;
+} T_LE_AOX_CONNLESS_TRANSMITTER_STATE_CHANGE_INFO;
+#endif
+#if F_BT_LE_5_1_AOX_CONNLESS_RECEIVER_SUPPORT
+typedef struct
+{
+ uint8_t sync_id;
+ uint16_t sync_handle;
+ uint16_t cause;
+ uint8_t sampling_enable;
+} T_LE_AOX_CONNLESS_RECEIVER_SET_IQ_SAMPLING_ENABLE_RSP;
+
+typedef struct
+{
+ uint8_t sync_id;
+ uint16_t sync_handle;
+ uint8_t
+ channel_index;/**< The index of the channel on which the packet was received.
+ Range: 0x00 to 0x27.
+ Note: 0x25 to 0x27 can be used only for packets generated during test modes.*/
+ int16_t rssi;/**< RSSI of the packet.
+ Range: -1270 to +200, Units: 0.1 dBm. */
+ uint8_t rssi_antenna_id;
+ T_GAP_CTE_TYPE cte_type;
+ T_GAP_SLOT_DUATIONS_TYPE slot_durations;
+ T_GAP_AOX_PACKET_STATUS_TYPE packet_status;
+ uint16_t periodic_event_counter;
+ uint8_t sample_count; /**< 0x00: No samples provided
+ (only permitted if Packet_Status is 0xFF);
+ 0x09 - 0x52:Total number of sample pairs
+ (there shall be the same number of I samples and Q samples). */
+ int8_t *p_iq_sample; /**< I_Sample[0],Q_Sample[0], ... ,
+ I_Sample[i],Q_Sample[i]
+ Value 0x80 indicates No valid sample available. */
+} T_LE_AOX_CONNLESS_RECEIVER_CONNECTIONLESS_IQ_REPORT_INFO;
+#endif
+#endif
+
+/** @brief GAP AoX Callback Data*/
+typedef union
+{
+ T_LE_AOX_READ_ANTENNA_INFORMATION_RSP *p_le_aox_read_antenna_information_rsp;
+#if F_BT_LE_5_1_AOX_CONN_SUPPORT
+ T_LE_AOX_SET_CONN_CTE_RECEIVE_PARAMS_RSP *p_le_aox_set_conn_cte_receive_params_rsp;
+ T_LE_AOX_SET_CONN_CTE_TRANSMIT_PARAMS_RSP *p_le_aox_set_conn_cte_transmit_params_rsp;
+ T_LE_AOX_CONN_CTE_REQUEST_ENABLE_RSP *p_le_aox_conn_cte_request_enable_rsp;
+ T_LE_AOX_CONN_CTE_RESPONSE_ENABLE_RSP *p_le_aox_conn_cte_response_enable_rsp;
+ T_LE_AOX_CONN_IQ_REPORT_INFO *p_le_aox_conn_iq_report_info;
+ T_LE_AOX_CTE_REQUEST_FAILED_INFO *p_le_aox_cte_request_failed_info;
+#endif
+#if F_BT_LE_5_1_AOX_CONNLESS_SUPPORT
+#if F_BT_LE_5_1_AOX_CONNLESS_TRANSMITTER_SUPPORT
+ T_LE_AOX_CONNLESS_TRANSMITTER_SET_CTE_TRANSMIT_PARAMS_RSP
+ *p_le_aox_connless_transmitter_set_cte_transmit_params_rsp;
+ T_LE_AOX_CONNLESS_TRANSMITTER_STATE_CHANGE_INFO
+ *p_le_aox_connless_transmitter_state_change_info;
+#endif
+#if F_BT_LE_5_1_AOX_CONNLESS_RECEIVER_SUPPORT
+ T_LE_AOX_CONNLESS_RECEIVER_SET_IQ_SAMPLING_ENABLE_RSP
+ *p_le_aox_connless_receiver_set_iq_sampling_enable_rsp;
+ T_LE_AOX_CONNLESS_RECEIVER_CONNECTIONLESS_IQ_REPORT_INFO
+ *p_le_aox_connless_receiver_connectionless_iq_report_info;
+#endif
+#endif
+} T_LE_AOX_CB_DATA;
+
+/** End of GAP_LE_AOX_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/** @defgroup GAP_LE_AOA_AOD_Exported_Functions GAP LE AoA/AoD Exported Functions
+ * @brief
+ * @{
+ */
+/**
+ * @brief Callback for gap aox to notify app
+ * @param[in] cb_type callback msy type @ref GAP_AOX_MSG_TYPE.
+ * @param[in] p_cb_data point to callback data @ref T_LE_AOX_CB_DATA.
+ * @retval void
+ */
+typedef T_APP_RESULT(*P_FUN_LE_AOX_CB)(uint8_t cb_type, void *p_cb_data);
+
+/**
+ * @brief Register callback to gap, when messages in @ref GAP_LE_AOX_MSG_Types happens, it will callback to app.
+ * @param[in] aox_callback Callback function provided by the APP to handle gap aox command messages sent from the GAP.
+ * @arg NULL -> Not send gap aox command messages to APP.
+ * @arg Other -> Use application defined callback function.
+ * @return void
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_gap_init(void)
+ {
+ ......
+ le_register_aox_cb(app_gap_aox_callback);
+ }
+ T_APP_RESULT app_gap_aox_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_AOX_CB_DATA *p_data = (T_LE_AOX_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_AOX_READ_ANTENNA_INFORMATION:
+ APP_PRINT_INFO5("GAP_MSG_LE_AOX_READ_ANTENNA_INFORMATION: cause 0x%x, supported_switching_sampling_rates 0x%x, num_antennae %d, max_switching_pattern_length %d, max_cte_length %d",
+ p_data->p_le_aox_read_antenna_information_rsp->cause,
+ p_data->p_le_aox_read_antenna_information_rsp->supported_switching_sampling_rates,
+ p_data->p_le_aox_read_antenna_information_rsp->num_antennae,
+ p_data->p_le_aox_read_antenna_information_rsp->max_switching_pattern_length,
+ p_data->p_le_aox_read_antenna_information_rsp->max_cte_length
+ );
+ break;
+ ......
+ }
+ ......
+ }
+ \endcode
+ */
+void le_register_aox_cb(P_FUN_LE_AOX_CB aox_callback);
+
+/**
+ * @brief Read antenna information.
+ * Read the supported_switching_sampling_rates, num_antennae, max_switching_pattern_length, max_cte_length
+ * of a transmitted Constant Tone Extension supported by the Controller.
+ * Antenna information will be returned by @ref app_gap_aox_callback with cb_type @ref GAP_MSG_LE_AOX_READ_ANTENNA_INFORMATION.
+ *
+ * Application can only call this API after stack is ready.
+ * Explanation: If stack is ready, Application will be notified by message @ref GAP_MSG_LE_DEV_STATE_CHANGE
+ * with new_state about gap_init_state which is configured as @ref GAP_INIT_STATE_STACK_READY.
+ *
+ * @return Result of sending request.
+ * @retval GAP_CAUSE_SUCCESS: Send request success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED: Send request sent fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ le_aox_read_antenna_information();
+ }
+
+ T_APP_RESULT app_gap_aox_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_AOX_CB_DATA *p_data = (T_LE_AOX_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ ......
+ case GAP_MSG_LE_AOX_READ_ANTENNA_INFORMATION:
+ APP_PRINT_INFO5("GAP_MSG_LE_AOX_READ_ANTENNA_INFORMATION: cause 0x%x, supported_switching_sampling_rates 0x%x, num_antennae %d, max_switching_pattern_length %d, max_cte_length %d",
+ p_data->p_le_aox_read_antenna_information_rsp->cause,
+ p_data->p_le_aox_read_antenna_information_rsp->supported_switching_sampling_rates,
+ p_data->p_le_aox_read_antenna_information_rsp->num_antennae,
+ p_data->p_le_aox_read_antenna_information_rsp->max_switching_pattern_length,
+ p_data->p_le_aox_read_antenna_information_rsp->max_cte_length
+ );
+ break;
+ ......
+ }
+ ......
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_aox_read_antenna_information(void);
+
+/** End of GAP_LE_AOA_AOD_Exported_Functions
+ * @}
+ */
+
+/** End of GAP_LE_AOA_AOD
+ * @}
+ */
+
+/** End of GAP_LE
+ * @}
+ */
+
+/** End of GAP
+ * @}
+ */
+
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_AOX_H */
diff --git a/inc/bluetooth/gap/gap_aox_conn.h b/inc/bluetooth/gap/gap_aox_conn.h
new file mode 100644
index 0000000..5016411
--- /dev/null
+++ b/inc/bluetooth/gap/gap_aox_conn.h
@@ -0,0 +1,374 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_aox_conn.h
+* @brief Head file for GAP AoA/AoD connection
+* @details
+* @author
+* @date 2020-06-18
+* @version v0.8
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_AOX_CONN_H
+#define GAP_AOX_CONN_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#include "gap_le.h"
+#include "gap_le_types.h"
+
+#if F_BT_LE_5_1_AOX_CONN_SUPPORT
+
+/** @addtogroup GAP GAP Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE GAP LE Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE_AOX_CONN GAP LE AoA/AoD Module
+ * @{
+ */
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GAP_LE_AOX_CONN_Exported_Macros GAP LE AoX Exported Macros
+ * @{
+ */
+
+/** @defgroup GAP_AOX_CONN_CTE_TYPES_BITS LE AoX Connection CTE Types Bits
+* @{
+ */
+#define GAP_AOX_CONN_CTE_TYPES_AOA_BIT 0x01 /**< Allow AoA Constant Tone Extension Response. */
+#define GAP_AOX_CONN_CTE_TYPES_AOD_1US_BIT 0x02 /**< Allow AoD Constant Tone Extension Response with 1 us slots. */
+#define GAP_AOX_CONN_CTE_TYPES_AOD_2US_BIT 0x04 /**< Allow AoD Constant Tone Extension Response with 2 us slots. */
+/**
+ * @}
+ */
+
+/** End of GAP_LE_AOX_CONN_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_AOX_CONN_Exported_Types GAP LE AoA/AoD Exported Types
+ * @brief
+ * @{
+ */
+typedef enum
+{
+ GAP_AOX_SAMPLING_DISABLE = 0x00, /**< Connection IQ sampling is disabled (default). */
+ GAP_AOX_SAMPLING_ENABLE = 0x01, /**< Connection IQ sampling is enabled. */
+} T_GAP_AOX_SAMPLING_ENABLE_TYPE;
+
+typedef enum
+{
+ GAP_AOX_CTE_REQUEST_DISABLE = 0x00, /**< Disable Constant Tone Extension Request for the connection (default). */
+ GAP_AOX_CTE_REQUEST_ENABLE = 0x01, /**< Enable Constant Tone Extension Request for the connection. */
+} T_GAP_AOX_CTE_REQUEST_ENABLE_TYPE;
+
+typedef enum
+{
+ GAP_AOX_CTE_RESPONSE_DISABLE = 0x00, /**< Disable Constant Tone Extension Response for the connection (default). */
+ GAP_AOX_CTE_RESPONSE_ENABLE = 0x01, /**< Enable Constant Tone Extension Response for the connection. */
+} T_GAP_AOX_CTE_RESPONSE_ENABLE_TYPE;
+
+/** End of GAP_LE_AOX_CONN_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/** @defgroup GAP_LE_AOA_AOD_CONN_Exported_Functions GAP LE AoA/AoD Exported Functions
+ * @brief
+ * @{
+ */
+/**
+ * @brief Set Connection CTE Receive Parameters.
+ * Result will be returned by @ref app_gap_aox_callback with cb_type @ref GAP_MSG_LE_AOX_SET_CONN_CTE_RECEIVE_PARAMS.
+ *
+ * @param[in] conn_id Connection ID.
+ * @param[in] sampling_enable Enable/disable Connection IQ sampling: @ref T_GAP_AOX_SAMPLING_ENABLE_TYPE.
+ * @param[in] slot_durations Switching and sampling slots: @ref T_GAP_SLOT_DUATIONS_TYPE.
+ * @param[in] switching_pattern_length The number of Antenna IDs in the pattern.
+ Range: 0x02 to max_switching_pattern_length supported by controller
+ max_switching_pattern_length shall be less than or equal to 0x4B.
+ * @param[in] p_antenna_ids Antenna ID in the pattern.
+ * @return Result of sending request.
+ * @retval GAP_CAUSE_SUCCESS: Send request success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED: Send request sent fail.
+ * @retval GAP_CAUSE_NON_CONN: Failed. No connection.
+ * @retval GAP_CAUSE_INVALID_PARAM: Failed. Invalid parameter.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t conn_id = 0;
+ T_GAP_AOX_SAMPLING_ENABLE_TYPE sampling_enable = GAP_AOX_SAMPLING_ENABLE;
+ T_GAP_SLOT_DUATIONS_TYPE slot_durations = GAP_SLOT_DURATIONS_SWITCH_SAMPLE_2US;
+ uint8_t switching_pattern_length = 2;
+ uint8_t p_antenna_ids[2] = {0, 1};
+
+ le_aox_set_conn_cte_receive_params(conn_id, sampling_enable, slot_durations,
+ switching_pattern_length, p_antenna_ids);
+ }
+
+ T_APP_RESULT app_gap_aox_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_AOX_CB_DATA *p_data = (T_LE_AOX_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ ......
+ case GAP_MSG_LE_AOX_SET_CONN_CTE_RECEIVE_PARAMS:
+ APP_PRINT_INFO2("GAP_MSG_LE_AOX_SET_CONN_CTE_RECEIVE_PARAMS: cause 0x%x, conn_id %d",
+ p_data->p_le_aox_set_conn_cte_receive_params_rsp->cause,
+ p_data->p_le_aox_set_conn_cte_receive_params_rsp->conn_id);
+ break;
+ ......
+ }
+ ......
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_aox_set_conn_cte_receive_params(uint8_t conn_id,
+ T_GAP_AOX_SAMPLING_ENABLE_TYPE sampling_enable,
+ T_GAP_SLOT_DUATIONS_TYPE slot_durations,
+ uint8_t switching_pattern_length,
+ uint8_t *p_antenna_ids);
+
+/**
+ * @brief Set Connection CTE Transmit Parameters.
+ * Result will be returned by @ref app_gap_aox_callback with cb_type @ref GAP_MSG_LE_AOX_SET_CONN_CTE_TRANSMIT_PARAMS.
+ *
+ * @param[in] conn_id Connection ID
+ * @param[in] cte_types A bit field that indicates the type of Constant Tone Extension that the Controller support
+ @ref GAP_AOX_CONN_CTE_TYPES_BITS.
+ * @param[in] switching_pattern_length The number of Antenna IDs in the pattern, and shall be ignored when cte_types does not
+ have a bit set for an AoD Constant Tone Extension.
+ Range: 0x02 to max_switching_pattern_length supported by controller
+ max_switching_pattern_length shall be less than or equal to 0x4B.
+ * @param[in] p_antenna_ids Antenna ID in the pattern, and shall be ignored when cte_types does not
+ have a bit set for an AoD Constant Tone Extension.
+ * @return Result of sending request.
+ * @retval GAP_CAUSE_SUCCESS: Send request success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED: Send request sent fail.
+ * @retval GAP_CAUSE_NON_CONN: Failed. No connection.
+ * @retval GAP_CAUSE_INVALID_PARAM: Failed. Invalid parameter.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t conn_id = 0;
+ uint8_t cte_types = GAP_AOX_CONN_CTE_TYPES_AOA_BIT | GAP_AOX_CONN_CTE_TYPES_AOD_2US_BIT;
+ uint8_t switching_pattern_length = 2;
+ uint8_t p_antenna_ids[2] = {0, 1};
+
+ le_aox_set_conn_cte_transmit_params(conn_id, cte_types, switching_pattern_length, p_antenna_ids);
+ }
+
+ T_APP_RESULT app_gap_aox_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_AOX_CB_DATA *p_data = (T_LE_AOX_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ ......
+ case GAP_MSG_LE_AOX_SET_CONN_CTE_TRANSMIT_PARAMS:
+ APP_PRINT_INFO2("GAP_MSG_LE_AOX_SET_CONN_CTE_TRANSMIT_PARAMS: cause 0x%x, conn_id %d",
+ p_data->p_le_aox_set_conn_cte_transmit_params_rsp->cause,
+ p_data->p_le_aox_set_conn_cte_transmit_params_rsp->conn_id);
+ break;
+ ......
+ }
+ ......
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_aox_set_conn_cte_transmit_params(uint8_t conn_id, uint8_t cte_types,
+ uint8_t switching_pattern_length,
+ uint8_t *p_antenna_ids);
+
+/**
+ * @brief Request the Controller to start or stop initiating the Constant Tone Extension Request procedure.
+ * Result will be returned by @ref app_gap_aox_callback with cb_type @ref GAP_MSG_LE_AOX_CONN_CTE_REQUEST_ENABLE.
+ *
+ * IQ samples will be returned by @ref app_gap_aox_callback with cb_type @ref GAP_MSG_LE_AOX_CONN_IQ_REPORT_INFO
+ * on Constant Tone Extensions received.
+ * Otherwise, request failed info will be returned by @ref app_gap_aox_callback with cb_type
+ * @ref GAP_MSG_LE_AOX_CTE_REQUEST_FAILED_INFO.
+ *
+ * @param[in] conn_id Connection ID
+ * @param[in] enable Enable/disable Constant Tone Extension Request: @ref T_GAP_AOX_CTE_REQUEST_ENABLE_TYPE.
+ If Enable is set to GAP_AOX_CTE_REQUEST_DISABLE, the remaining parameters shall be ignored.
+ * @param[in] cte_request_interval Defines whether the Constant Tone Extension Request procedure is initiated
+ only once or periodically.
+ 0x0000: Initiate the Constant Tone Extension Request procedure once, at the
+ earliest practical opportunity
+ 0x0001 to 0xFFFF: Requested interval for initiating the Constant Tone Extension
+ Request procedure in number of connection events.
+ * @param[in] requested_cte_length The minimum length of the Constant Tone Extension that the Controller shall
+ request from the remote device.
+ Range: 0x02 to 0x14.
+ Units: 8 us.
+ * @param[in] requested_cte_type The type of Constant Tone Extension that the Controller shall request from the remote device:
+ * @ref T_GAP_CTE_TYPE.
+ * @return Result of sending request.
+ * @retval GAP_CAUSE_SUCCESS: Send request success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED: Send request sent fail.
+ * @retval GAP_CAUSE_NON_CONN: Failed. No connection.
+ * @retval GAP_CAUSE_INVALID_PARAM: Failed. Invalid parameter.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t conn_id = 0;
+ T_GAP_AOX_CTE_REQUEST_ENABLE_TYPE enable = GAP_AOX_CTE_REQUEST_ENABLE;
+ uint16_t cte_request_interval = 0;
+ uint8_t requested_cte_length = 2;
+ T_GAP_CTE_TYPE requested_cte_type = GAP_CTE_TYPE_AOA;
+
+ le_aox_conn_cte_request_enable(conn_id, enable, cte_request_interval,
+ requested_cte_length, requested_cte_type);
+ }
+
+ T_APP_RESULT app_gap_aox_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_AOX_CB_DATA *p_data = (T_LE_AOX_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ ......
+ case GAP_MSG_LE_AOX_CONN_CTE_REQUEST_ENABLE:
+ APP_PRINT_INFO2("GAP_MSG_LE_AOX_CONN_CTE_REQUEST_ENABLE: cause 0x%x, conn_id %d",
+ p_data->p_le_aox_conn_cte_request_enable_rsp->cause,
+ p_data->p_le_aox_conn_cte_request_enable_rsp->conn_id);
+ break;
+ case GAP_MSG_LE_AOX_CONN_IQ_REPORT_INFO:
+ APP_PRINT_INFO8("GAP_MSG_LE_AOX_CONN_IQ_REPORT_INFO: conn_id %d, rx_phy %d, data_chan_index %d, rssi %d, rssi_antenna_id %d, cte_type %d, slot_durations %d, packet_status %d",
+ p_data->p_le_aox_conn_iq_report_info->conn_id,
+ p_data->p_le_aox_conn_iq_report_info->rx_phy,
+ p_data->p_le_aox_conn_iq_report_info->data_chan_index,
+ p_data->p_le_aox_conn_iq_report_info->rssi,
+ p_data->p_le_aox_conn_iq_report_info->rssi_antenna_id,
+ p_data->p_le_aox_conn_iq_report_info->cte_type,
+ p_data->p_le_aox_conn_iq_report_info->slot_durations,
+ p_data->p_le_aox_conn_iq_report_info->packet_status);
+ APP_PRINT_INFO2("GAP_MSG_LE_AOX_CONN_IQ_REPORT_INFO: connection_event_counter %d, sample_count %d",
+ p_data->p_le_aox_conn_iq_report_info->connection_event_counter,
+ p_data->p_le_aox_conn_iq_report_info->sample_count);
+ if (p_data->p_le_aox_conn_iq_report_info->sample_count)
+ {
+ APP_PRINT_INFO1("GAP_MSG_LE_AOX_CONN_IQ_REPORT_INFO: iq_sample %b",
+ TRACE_BINARY(p_data->p_le_aox_conn_iq_report_info->sample_count * 2,
+ p_data->p_le_aox_conn_iq_report_info->p_iq_sample));
+ }
+ break;
+ case GAP_MSG_LE_AOX_CTE_REQUEST_FAILED_INFO:
+ APP_PRINT_INFO2("GAP_MSG_LE_AOX_CTE_REQUEST_FAILED_INFO: cause 0x%x, conn_id %d",
+ p_data->p_le_aox_cte_request_failed_info->cause,
+ p_data->p_le_aox_cte_request_failed_info->conn_id);
+ break;
+ ......
+ }
+ ......
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_aox_conn_cte_request_enable(uint8_t conn_id,
+ T_GAP_AOX_CTE_REQUEST_ENABLE_TYPE enable,
+ uint16_t cte_request_interval, uint8_t requested_cte_length,
+ T_GAP_CTE_TYPE requested_cte_type);
+
+/**
+ * @brief Request the Controller to respond to Constant Tone Extension Request.
+ * Result will be returned by @ref app_gap_aox_callback with cb_type @ref GAP_MSG_LE_AOX_CONN_CTE_RESPONSE_ENABLE.
+ *
+ * @param[in] conn_id Connection ID.
+ * @param[in] enable Enable/disable Constant Tone Extension Response: @ref T_GAP_AOX_CTE_RESPONSE_ENABLE_TYPE.
+ * @return Result of sending request.
+ * @retval GAP_CAUSE_SUCCESS: Send request success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED: Send request sent fail.
+ * @retval GAP_CAUSE_NON_CONN: Failed. No connection.
+ * @retval GAP_CAUSE_INVALID_PARAM: Failed. Invalid parameter.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t conn_id = 0;
+ T_GAP_AOX_CTE_RESPONSE_ENABLE_TYPE enable = GAP_AOX_CTE_RESPONSE_ENABLE;
+
+ le_aox_conn_cte_response_enable(conn_id, enable);
+ }
+
+ T_APP_RESULT app_gap_aox_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_AOX_CB_DATA *p_data = (T_LE_AOX_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ ......
+ case GAP_MSG_LE_AOX_CONN_CTE_RESPONSE_ENABLE:
+ APP_PRINT_INFO2("GAP_MSG_LE_AOX_CONN_CTE_RESPONSE_ENABLE: cause 0x%x, conn_id %d",
+ p_data->p_le_aox_conn_cte_response_enable_rsp->cause,
+ p_data->p_le_aox_conn_cte_response_enable_rsp->conn_id);
+ break;
+ ......
+ }
+ ......
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_aox_conn_cte_response_enable(uint8_t conn_id,
+ T_GAP_AOX_CTE_RESPONSE_ENABLE_TYPE enable);
+
+/** End of GAP_LE_AOA_AOD_CONN_Exported_Functions
+ * @}
+ */
+
+/** End of GAP_LE_AOA_AOD
+ * @}
+ */
+
+/** End of GAP_LE
+ * @}
+ */
+
+/** End of GAP
+ * @}
+ */
+
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_AOX_CONN_H */
diff --git a/inc/bluetooth/gap/gap_aox_connless_receiver.h b/inc/bluetooth/gap/gap_aox_connless_receiver.h
new file mode 100644
index 0000000..752fbac
--- /dev/null
+++ b/inc/bluetooth/gap/gap_aox_connless_receiver.h
@@ -0,0 +1,108 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_aox_connless_receiver.h
+* @brief Head file for GAP AoA/AoD
+* @details
+* @author
+* @date 2020-06-18
+* @version v0.8
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_AOX_CONNLESS_RECEIVER_H
+#define GAP_AOX_CONNLESS_RECEIVER_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#include "gap_le.h"
+#include "gap_le_types.h"
+
+#if F_BT_LE_5_1_AOX_CONNLESS_RECEIVER_SUPPORT
+
+/** @addtogroup GAP GAP Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE GAP LE Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE_AOX GAP LE AoA/AoD Module
+ * @{
+ */
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GAP_LE_AOX_Exported_Macros GAP LE AoX Exported Macros
+ * @{
+ */
+/** @defgroup AOX_CONNLESS_RECEIVER_SAMPLING_ENABLE Periodic Advertising Enable flag
+ * @brief Use the macro definitions to describe the enable parameters.
+ * @{
+ */
+#define AOX_CONNLESS_RECEIVER_SAMPLING_ENABLE_IQ_SAMPLING_DISABLED 0x00 /**< Connectionless IQ sampling is disabled (default). */
+#define AOX_CONNLESS_RECEIVER_SAMPLING_ENABLE_IQ_SAMPLING_ENABLED 0x01 /**< Connectionless IQ sampling is enabled. */
+/** End of AOX_CONNLESS_RECEIVER_SAMPLING_ENABLE
+ * @}
+ */
+
+/** End of GAP_LE_AOX_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/** @defgroup GAP_LE_AOA_AOD_Exported_Functions GAP LE AoA/AoD Exported Functions
+ * @brief
+ * @{
+ */
+/*
+ sampling_enable: @ref AOX_CONNLESS_RECEIVER_SAMPLING_ENABLE
+*/
+T_GAP_CAUSE le_aox_connless_receiver_set_iq_sampling_enable(uint8_t sync_id,
+ uint8_t sampling_enable, T_GAP_SLOT_DUATIONS_TYPE slot_durations, uint8_t max_sampled_ctes,
+ uint8_t switching_pattern_length, uint8_t *p_antenna_ids);
+
+/** End of GAP_LE_AOA_AOD_Exported_Functions
+ * @}
+ */
+
+/** End of GAP_LE_AOA_AOD
+ * @}
+ */
+
+/** End of GAP_LE
+ * @}
+ */
+
+/** End of GAP
+ * @}
+ */
+
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_AOX_CONNLESS_RECEIVER_H */
diff --git a/inc/bluetooth/gap/gap_aox_connless_transmitter.h b/inc/bluetooth/gap/gap_aox_connless_transmitter.h
new file mode 100644
index 0000000..a7cab6a
--- /dev/null
+++ b/inc/bluetooth/gap/gap_aox_connless_transmitter.h
@@ -0,0 +1,143 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_aox_connless_transmitter.h
+* @brief Head file for GAP AoA/AoD connless transmitter
+* @details
+* @author
+* @date 2020-10-18
+* @version v0.4
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_AOX_CONNLESS_TRANSMITTER_H
+#define GAP_AOX_CONNLESS_TRANSMITTER_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#include "gap_le.h"
+#include "gap_le_types.h"
+
+#if F_BT_LE_5_1_AOX_CONNLESS_TRANSMITTER_SUPPORT
+
+/** @addtogroup GAP GAP Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE GAP LE Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE_AOX_CONNLESS_TRANSMITTER GAP LE AoA/AoD Module
+ * @{
+ */
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GAP_LE_AOX_CONNLESS_TRANSMITTER_Exported_Macros GAP LE AoX Exported Macros
+ * @{
+ */
+
+/** @defgroup AOX_CONNLESS_TRANSMITTER_CTE_ENABLE Periodic Advertising Enable flag
+ * @brief Use the macro definitions to describe the enable parameters.
+ * @{
+ */
+#define AOX_CONNLESS_TRANSMITTER_CTE_ENABLE_ADV_WITH_CTE_DISABLED 0x00 /**< Advertising with Constant Tone Extension is disabled (default). */
+#define AOX_CONNLESS_TRANSMITTER_CTE_ENABLE_ADV_WITH_CTE_ENABLED 0x01 /**< Advertising with Constant Tone Extension is enabled. */
+/** End of AOX_CONNLESS_TRANSMITTER_CTE_ENABLE
+ * @}
+ */
+
+/** End of GAP_LE_AOX_CONNLESS_TRANSMITTER_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_AOX_CONNLESS_TRANSMITTER_Exported_Types GAP LE AoA/AoD Exported Types
+ * @brief
+ * @{
+ */
+typedef enum
+{
+ GAP_AOX_CONNLESS_TRANSMITTER_CTE_TYPES_AOA = 0x00, /**< AoA Constant Tone Extension. */
+ GAP_AOX_CONNLESS_TRANSMITTER_CTE_TYPES_AOD_1US = 0x01, /**< AoD Constant Tone Extension with 1 μs slots. */
+ GAP_AOX_CONNLESS_TRANSMITTER_CTE_TYPES_AOD_2US = 0x02, /**< AoD Constant Tone Extension with 2 μs slots. */
+} T_GAP_AOX_CONNLESS_TRANSMITTER_CTE_TYPES;
+
+typedef enum
+{
+ AOX_CONNLESS_TRANSMITTER_STATE_IDLE = 0x00,
+ AOX_CONNLESS_TRANSMITTER_STATE_ENABLING_EXT_ADV_STATE_PA_ADV_STATE_IDLE = 0x01,
+ AOX_CONNLESS_TRANSMITTER_STATE_WAIT_EXT_ADV_STATE_PA_ADV_STATE_ADVERTISING = 0x02,
+ AOX_CONNLESS_TRANSMITTER_STATE_ENABLING_PA_ADV_STATE_IDLE = 0x03,
+ AOX_CONNLESS_TRANSMITTER_STATE_WAIT_PA_ADV_STATE_ADVERTISING = 0x04,
+ AOX_CONNLESS_TRANSMITTER_STATE_ENABLING_EXT_ADV_STATE_IDLE = 0x05,
+ AOX_CONNLESS_TRANSMITTER_STATE_WAIT_EXT_ADV_STATE_ADVERTISING = 0x06,
+ AOX_CONNLESS_TRANSMITTER_STATE_ENABLING = 0x07,
+ AOX_CONNLESS_TRANSMITTER_STATE_TRANSMITTING = 0x08, /**< Transmitting Constant Tone Extensions. */
+ AOX_CONNLESS_TRANSMITTER_STATE_DISABLING = 0x09,
+} T_GAP_AOX_CONNLESS_TRANSMITTER_STATE;
+
+/** End of GAP_LE_AOX_CONNLESS_TRANSMITTER_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/** @defgroup GAP_LE_AOA_AOD_Exported_Functions GAP LE AoA/AoD Exported Functions
+ * @brief
+ * @{
+ */
+
+T_GAP_CAUSE le_aox_connless_transmitter_init(uint8_t adv_set_num);
+
+T_GAP_CAUSE le_aox_connless_transmitter_set_cte_transmit_params(uint8_t adv_handle,
+ uint8_t cte_length, T_GAP_AOX_CONNLESS_TRANSMITTER_CTE_TYPES cte_type, uint8_t cte_count,
+ uint8_t switching_pattern_length, uint8_t *p_antenna_ids);
+
+/*
+ cte_enable: @ref AOX_CONNLESS_TRANSMITTER_CTE_ENABLE
+*/
+T_GAP_CAUSE le_aox_connless_transmitter_set_cte_transmit_enable(uint8_t adv_handle,
+ uint8_t cte_enable);
+
+/** End of GAP_LE_AOA_AOD_Exported_Functions
+ * @}
+ */
+
+/** End of GAP_LE_AOA_AOD
+ * @}
+ */
+
+/** End of GAP_LE
+ * @}
+ */
+
+/** End of GAP
+ * @}
+ */
+
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_AOX_CONNLESS_TRANSMITTER_H */
diff --git a/inc/bluetooth/gap/gap_bond_le.h b/inc/bluetooth/gap/gap_bond_le.h
new file mode 100644
index 0000000..504ed59
--- /dev/null
+++ b/inc/bluetooth/gap/gap_bond_le.h
@@ -0,0 +1,852 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gap_bond_le.h
+ * @brief This file contains all the functions prototypes for the GAP bond and pairing
+ * related functions.
+ * @details
+ * @author ranhui
+ * @date 2016-02-18
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_BOND_LE_H
+#define GAP_BOND_LE_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#include "gap_le.h"
+
+/** @defgroup GAP_LE_Bond_Manager GAP LE Bond Manager
+ * @brief GAP LE Bond Manager
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_BOND_MANAGER_Exported_Types GAP LE Bond Manager Exported Types
+ * @{
+ */
+
+/** @brief LE bond parameter types */
+typedef enum
+{
+#if F_BT_LE_SMP_OOB_SUPPORT
+ GAP_PARAM_BOND_OOB_DATA = 0x210,//!< OOB Data. Read/Write. size uint8_t[16]. Default is all 0's.
+#endif
+ GAP_PARAM_BOND_FIXED_PASSKEY = 0x211,//!< The fix passcode for MITM protection. Read/Write. size is uint32_t. Range is 0 - 999,999. Default is 0.
+ GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE = 0x212,//!< The fix passcode available for pairing. Read/Write. size is uint8_t. Default is 0(disabled).
+ GAP_PARAM_BOND_SEC_REQ_ENABLE = 0x213,//!< Send smp security request when connected. Read/Write. size is uint8_t. Default is 0(disabled).
+ GAP_PARAM_BOND_SEC_REQ_REQUIREMENT = 0x214,//!< Security request requirements. Read/Write. size is uint8_t. Default is GAP_AUTHEN_BIT_BONDING_FLAG (@ref BOND_MITM_DEFINES)
+ GAP_PARAM_BOND_MIN_KEY_SIZE = 0x215,//!< Minium LTK size required. Read/Write. size is uint8_t.
+#if F_BT_LE_LOCAL_IRK_SETTING_SUPPORT
+ GAP_PARAM_BOND_GEN_LOCAL_IRK_AUTO = 0x216,//!< Auto generate local IRK. Write only. size is uint8_t. Default is 0(disabled).
+ GAP_PARAM_BOND_SET_LOCAL_IRK = 0x217,//!< Set local IRK. Write only. size is uint8_t. Default is all zero.
+#endif
+ GAP_PARAM_BOND_KEY_MANAGER = 0x218,//!< Key manager. Write only. size is uint8_t. Default is 0(disabled).
+ GAP_PARAM_BOND_SIGN_KEY_FLAG = 0x219,//!< Sign key flag configure. Write only. size is uint8_t. Default is 0(disabled).
+ GAP_PARAM_BOND_CCCD_STORAGE = 0x21A,//!< Whether to store cccd information. Write only. size is uint8_t. Default is true.
+} T_LE_BOND_PARAM_TYPE;
+
+#if F_BT_LE_4_2_SC_OOB_SUPPORT
+/** @brief LE local out of bond data */
+typedef struct
+{
+ uint8_t present;
+ uint8_t rand[16];
+ uint8_t confirm[16];
+ uint8_t bd_addr_to[6];
+ uint8_t local_sk[32];
+ uint8_t local_pk[64];
+} T_GAP_LE_LOCAL_OOB_DATA;
+
+/** @brief LE peer out of bond data */
+typedef struct
+{
+ uint8_t present;
+ uint8_t rand[16];
+ uint8_t confirm[16];
+ uint8_t bd_addr_from[6];
+} T_GAP_LE_PEER_OOB_DATA;
+#endif
+
+/** End of GAP_LE_BOND_MANAGER_Exported_Types
+* @}
+*/
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup GAP_LE_BONDMGR_Exported_Functions GAP LE Bond Manager Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Set a GAP Bond Manager Parameter.
+ *
+ * NOTE: You can call this function with a bond parameter type and it will set the
+ * bond parameter. Bond parameters are defined in @ref T_LE_BOND_PARAM_TYPE.
+ * if the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param Bond parameter type: @ref T_LE_BOND_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and will be cast to the appropriate
+ * data type (For example: if data type param is uint16, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Set result
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure. No connection.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_gap_init(void)
+ {
+ ...
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+ uint8_t auth_sec_req_enable = false;
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_NONE;
+
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+ ....
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_bond_set_param(T_LE_BOND_PARAM_TYPE param, uint8_t len, void *p_value);
+
+/**
+ * @brief Get a GAP Bond Manager Parameter.
+ *
+ * NOTE: You can call this function with a bond parameter type and it will get a
+ * bond parameter. Bond parameters are defined in @ref T_LE_BOND_PARAM_TYPE. Also, the
+ * "p_value" field must point to a "uint16".
+ *
+ * @param[in] param Profile parameter ID: @ref T_LE_BOND_PARAM_TYPE
+ * @param[in,out] p_value pointer to location to get the value. This is dependent on
+ * the parameter type and will be cast to the appropriate
+ * data type (For example: if data type param is uint16, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Get result
+ * @retval GAP_CAUSE_SUCCESS Get parameter success.
+ * @retval other Get parameter failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t seq_req;
+ le_bond_get_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, &seq_req);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_bond_get_param(T_LE_BOND_PARAM_TYPE param, void *p_value);
+
+/**
+ * @brief Start authentication the link.
+ *
+ * NOTE: If the link has not been bonded, it will trigger pairing procedure, otherwise
+ * it will trigger the link encryption procedure.
+ * @param[in] conn_id Connection ID.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_NON_CONN Operation failure. No connection.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t conn_id = 0;
+ le_bond_pair(conn_id);
+ }
+
+ void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+ {
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_bond_pair(uint8_t conn_id);
+
+/**
+ * @brief Get the display key information
+ *
+ * @param[in] conn_id Connection ID.
+ * @param[in,out] p_key Passkey valueto be displayed as a 6 digit decimal number.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_NON_CONN Operation failure. No connection.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_handle_gap_msg(T_IO_MSG *p_io_msg)
+ {
+ T_LE_GAP_MSG bt_msg;
+ uint8_t conn_id;
+
+ memcpy(&bt_msg, &p_io_msg->u.param, sizeof(p_io_msg->u.param));
+
+ switch (p_io_msg->subtype)
+ {
+ ...
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+ ...
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_bond_get_display_key(uint8_t conn_id, uint32_t *p_key);
+
+/**
+ * @brief Send passkey to gap bond manager when pairing with passkey entry,
+ * and local should input passkey.
+ *
+ * @param[in] conn_id Connection ID.
+ * @param[in] passcode Result of Keyboard input.
+ * @param[in] cause User confirm result.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_NON_CONN Operation failure. No connection.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_handle_gap_msg(T_IO_MSG *p_io_msg)
+ {
+ T_LE_GAP_MSG bt_msg;
+ uint8_t conn_id;
+
+ memcpy(&bt_msg, &p_io_msg->u.param, sizeof(p_io_msg->u.param));
+
+ switch (p_io_msg->subtype)
+ {
+ ...
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ conn_id = bt_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_PASSKEY_INPUT");
+ uint32_t passKey = 888888;
+ le_bond_passkey_input_confirm(conn_id, passKey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+ ...
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_bond_passkey_input_confirm(uint8_t conn_id, uint32_t passcode,
+ T_GAP_CFM_CAUSE cause);
+
+#if F_BT_LE_SMP_OOB_SUPPORT
+/**
+ * @brief Send oob data to gap bond manager when pairing with out of bond,
+ * and local should input oob data.
+ * @param[in] conn_id connection ID.
+ * @param[in] cause User confirm result.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_NON_CONN Operation failure. No connection.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_handle_gap_msg(T_IO_MSG *p_io_msg)
+ {
+ T_LE_GAP_MSG bt_msg;
+ uint8_t conn_id;
+
+ memcpy(&bt_msg, &p_io_msg->u.param, sizeof(p_io_msg->u.param));
+
+ switch (p_io_msg->subtype)
+ {
+ ...
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ conn_id = bt_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ uint8_t ooBData[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, ooBData);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+ ...
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_bond_oob_input_confirm(uint8_t conn_id, T_GAP_CFM_CAUSE cause);
+#endif
+/**
+ * @brief Send user confirmation request to confirm result to upper stack when
+ pairing with just work.
+ * @param[in] conn_id Connection ID.
+ * @param[in] cause User confirm result.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_NON_CONN Operation failure. No connection.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_handle_gap_msg(T_IO_MSG *p_io_msg)
+ {
+ T_LE_GAP_MSG bt_msg;
+ uint8_t conn_id;
+
+ memcpy(&bt_msg, &p_io_msg->u.param, sizeof(p_io_msg->u.param));
+
+ switch (p_io_msg->subtype)
+ {
+ ...
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+ ...
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_bond_just_work_confirm(uint8_t conn_id, T_GAP_CFM_CAUSE cause);
+
+
+/**
+ * @brief Send user confirmation request to confirm result to upper stack when
+ pairing with passkey entry, and local shall display a passkey.
+ * @param[in] conn_id Connection ID.
+ * @param[in] cause User confirm result.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_NON_CONN Operation failure. No connection.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_handle_gap_msg(T_IO_MSG *p_io_msg)
+ {
+ T_LE_GAP_MSG bt_msg;
+ uint8_t conn_id;
+
+ memcpy(&bt_msg, &p_io_msg->u.param, sizeof(p_io_msg->u.param));
+
+ switch (p_io_msg->subtype)
+ {
+ ...
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+ ...
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_bond_passkey_display_confirm(uint8_t conn_id, T_GAP_CFM_CAUSE cause);
+
+#if F_BT_LE_4_2_SC_SUPPORT
+/**
+ * @brief Send user confirmation request to confirm result to upper stack
+ * @param[in] conn_id Connection ID.
+ * @param[in] cause User confirm result.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_NON_CONN Operation failure. No connection.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_handle_gap_msg(T_IO_MSG *p_io_msg)
+ {
+ T_LE_GAP_MSG bt_msg;
+ uint8_t conn_id;
+
+ memcpy(&bt_msg, &p_io_msg->u.param, sizeof(p_io_msg->u.param));
+
+ switch (p_io_msg->subtype)
+ {
+ ...
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+ ...
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_bond_user_confirm(uint8_t conn_id, T_GAP_CFM_CAUSE cause);
+#endif
+
+#if F_BT_LE_4_2_KEY_PRESS_SUPPORT
+/**
+ * @brief Send keypress notification to upper stack
+ * @param[in] conn_id Connection ID.
+ * @param[in] type Keypress notify type @ref T_GAP_KEYPRESS_NOTIF_TYPE.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_NON_CONN Operation failure. No connection.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_KEYPRESS_NOTIFY:
+ APP_PRINT_INFO2("GAP_MSG_LE_KEYPRESS_NOTIFY:conn %d, cause 0x%x",
+ cb_data.p_le_keypress_notify_rsp->conn_id, cb_data.p_le_keypress_notify_rsp->cause);
+ break;
+
+ case GAP_MSG_LE_KEYPRESS_NOTIFY_INFO:
+ APP_PRINT_INFO2("GAP_MSG_LE_KEYPRESS_NOTIFY_INFO:conn %d, type 0x%x",
+ cb_data.p_le_keypress_notify_info->conn_id, cb_data.p_le_keypress_notify_info->event_type);
+ break;
+ ...
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_bond_keypress_notify(uint8_t conn_id, T_GAP_KEYPRESS_NOTIF_TYPE type);
+#endif
+/**
+ * @brief Set local key distribution field
+ * @param[in] init_dist Initiator key distribution.
+ * @param[in] rsp_dist Responder key distribution.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure. No connection.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_setkeydis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t init_dist = p_parse_value->dw_param[0];
+ uint8_t rsp_dist = p_parse_value->dw_param[1];
+ le_bond_cfg_local_key_distribute(init_dist, rsp_dist);
+ return (RESULT_SUCCESS);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_bond_cfg_local_key_distribute(uint8_t init_dist, uint8_t rsp_dist);
+
+#if F_BT_LE_4_2_SC_OOB_SUPPORT
+/**
+ * @brief Initialize local out of bond data
+ * @param[in] p_ecc_rand_in Poniter to ecc rand.
+ * @param[in] local_rand Poniter to local rand.
+ * @param[in] p_local_oob_data Poniter to local oob data.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure. No connection.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_scoob(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ int idx = p_parse_value->dw_param[0];
+ bool ret;
+ T_GAP_LE_PEER_OOB_DATA peer_oob_data;
+
+ if (idx == 1)
+ {
+ uint64_t ecc_rand_in[4] = {0x1111111111111111, 0x1111111111111111, 0x1111111111111111, 0x1111111111111111};
+ uint8_t local_rand[16] = {0x11, 0x11};
+ T_GAP_LE_LOCAL_OOB_DATA local_oob_data;
+ ret = le_bond_sc_local_oob_init(ecc_rand_in, local_rand, &local_oob_data);
+
+ uint8_t bd_from[6] = {0x00, 0x80, 0x25, 0x49, 0x78, 0x43};
+ uint8_t peer_rand[16] = {0x22, 0x22};
+ uint8_t confirm[16] = {0x56, 0x3E, 0x60, 0x47, 0xA4, 0xF3, 0x13, 0x6D, 0x45, 0x52, 0x72, 0x36, 0x0B, 0x4B, 0x37, 0xA3};
+ memcpy(peer_oob_data.bd_addr_from, bd_from, 6);
+ memcpy(peer_oob_data.rand, peer_rand, 16);
+ memcpy(peer_oob_data.confirm, confirm, 16);
+ }
+ else
+ {
+ uint64_t ecc_rand_in[4] = {0x2222222222222222, 0x2222222222222222, 0x2222222222222222, 0x2222222222222222};
+ uint8_t local_rand[16] = {0x22, 0x22};
+ T_GAP_LE_LOCAL_OOB_DATA local_oob_data;
+ ret = le_bond_sc_local_oob_init(ecc_rand_in, local_rand, &local_oob_data);
+
+ uint8_t bd_from[6] = {0x00, 0x80, 0x25, 0x48, 0x19, 0x3d};
+ uint8_t peer_rand[16] = {0x11, 0x11};
+ uint8_t confirm[16] = {0xC3, 0x66, 0x45, 0x51, 0x1B, 0xC7, 0x58, 0x22, 0xB5, 0xE1, 0xF3, 0x40, 0x48, 0xB1, 0x52, 0xEF};
+ memcpy(peer_oob_data.bd_addr_from, bd_from, 6);
+ memcpy(peer_oob_data.rand, peer_rand, 16);
+ memcpy(peer_oob_data.confirm, confirm, 16);
+ }
+ if (ret)
+ {
+ ret = le_bond_sc_peer_oob_init(&peer_oob_data);
+ }
+ if (ret)
+ {
+ return RESULT_SUCCESS;
+ }
+ else
+ {
+ return RESULT_ERR;
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_bond_sc_local_oob_init(uint64_t *p_ecc_rand_in, uint8_t *local_rand,
+ T_GAP_LE_LOCAL_OOB_DATA *p_local_oob_data);
+
+/**
+ * @brief Initialize peer out of bond data
+ * @param[in] p_peer_oob_data Poniter to peer out of bond data.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure. No connection.
+ */
+T_GAP_CAUSE le_bond_sc_peer_oob_init(T_GAP_LE_PEER_OOB_DATA *p_peer_oob_data);
+#endif
+/**
+ * @brief Erase all link keys of bonded devices
+ * @return void
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ ...
+#if APP_PRIVACY_EN
+ case GAP_MSG_LE_BOND_MODIFY_INFO:
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x",
+ p_data->p_le_bond_modify_info->type);
+ privacy_handle_bond_modify_msg(p_data->p_le_bond_modify_info->type,
+ p_data->p_le_bond_modify_info->p_entry, true);
+ break;
+#endif
+ ...
+ }
+ }
+
+ void privacy_handle_bond_modify_msg(T_LE_BOND_MODIFY_TYPE type, T_LE_KEY_ENTRY *p_entry,
+ bool handle_add)
+ {
+ APP_PRINT_INFO1("[PRIVACY] privacy_handle_bond_modify_msg: type 0x%x", type);
+
+ if (type == LE_BOND_CLEAR)
+ {
+ privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_CLEAR, GAP_IDENT_ADDR_PUBLIC, NULL, false);
+ }
+ else if (type == LE_BOND_DELETE)
+ {
+ if (p_entry->flags & LE_KEY_STORE_REMOTE_IRK_BIT)
+ {
+ privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE,
+ (T_GAP_IDENT_ADDR_TYPE)p_entry->resolved_remote_bd.remote_bd_type,
+ p_entry->resolved_remote_bd.addr, false);
+ }
+ else
+ {
+ privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE,
+ (T_GAP_IDENT_ADDR_TYPE)p_entry->remote_bd.remote_bd_type,
+ p_entry->remote_bd.addr, false);
+ }
+ }
+ else if (type == LE_BOND_ADD)
+ {
+ if (handle_add)
+ {
+ privacy_add_device(p_entry);
+ }
+ }
+ privacy_handle_resolv_list();
+ }
+ * \endcode
+ */
+void le_bond_clear_all_keys(void);
+
+/**
+ * @brief Delete bond information by index
+ * @param[in] idx Index of key entry.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS: Operation success.
+ * @retval GAP_CAUSE_NOT_FIND: Operation failure. Not found.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ ...
+#if APP_PRIVACY_EN
+ case GAP_MSG_LE_BOND_MODIFY_INFO:
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x",
+ p_data->p_le_bond_modify_info->type);
+ privacy_handle_bond_modify_msg(p_data->p_le_bond_modify_info->type,
+ p_data->p_le_bond_modify_info->p_entry, true);
+ break;
+#endif
+ ...
+ }
+ }
+
+ void privacy_handle_bond_modify_msg(T_LE_BOND_MODIFY_TYPE type, T_LE_KEY_ENTRY *p_entry,
+ bool handle_add)
+ {
+ APP_PRINT_INFO1("[PRIVACY] privacy_handle_bond_modify_msg: type 0x%x", type);
+
+ if (type == LE_BOND_CLEAR)
+ {
+ privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_CLEAR, GAP_IDENT_ADDR_PUBLIC, NULL, false);
+ }
+ else if (type == LE_BOND_DELETE)
+ {
+ if (p_entry->flags & LE_KEY_STORE_REMOTE_IRK_BIT)
+ {
+ privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE,
+ (T_GAP_IDENT_ADDR_TYPE)p_entry->resolved_remote_bd.remote_bd_type,
+ p_entry->resolved_remote_bd.addr, false);
+ }
+ else
+ {
+ privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE,
+ (T_GAP_IDENT_ADDR_TYPE)p_entry->remote_bd.remote_bd_type,
+ p_entry->remote_bd.addr, false);
+ }
+ }
+ else if (type == LE_BOND_ADD)
+ {
+ if (handle_add)
+ {
+ privacy_add_device(p_entry);
+ }
+ }
+ privacy_handle_resolv_list();
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_bond_delete_by_idx(uint8_t idx);
+
+/**
+ * @brief Delete bond information by bluetooth device address and address type
+ * @param[in] bd_addr Bonded bluetooth device address.
+ * @param[in] bd_type Bonded bluetooth device address type.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS: Operation success.
+ * @retval GAP_CAUSE_NOT_FIND: Operation failure. Not found.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ ...
+#if APP_PRIVACY_EN
+ case GAP_MSG_LE_BOND_MODIFY_INFO:
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x",
+ p_data->p_le_bond_modify_info->type);
+ privacy_handle_bond_modify_msg(p_data->p_le_bond_modify_info->type,
+ p_data->p_le_bond_modify_info->p_entry, true);
+ break;
+#endif
+ ...
+ }
+ }
+
+ void privacy_handle_bond_modify_msg(T_LE_BOND_MODIFY_TYPE type, T_LE_KEY_ENTRY *p_entry,
+ bool handle_add)
+ {
+ APP_PRINT_INFO1("[PRIVACY] privacy_handle_bond_modify_msg: type 0x%x", type);
+
+ if (type == LE_BOND_CLEAR)
+ {
+ privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_CLEAR, GAP_IDENT_ADDR_PUBLIC, NULL, false);
+ }
+ else if (type == LE_BOND_DELETE)
+ {
+ if (p_entry->flags & LE_KEY_STORE_REMOTE_IRK_BIT)
+ {
+ privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE,
+ (T_GAP_IDENT_ADDR_TYPE)p_entry->resolved_remote_bd.remote_bd_type,
+ p_entry->resolved_remote_bd.addr, false);
+ }
+ else
+ {
+ privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE,
+ (T_GAP_IDENT_ADDR_TYPE)p_entry->remote_bd.remote_bd_type,
+ p_entry->remote_bd.addr, false);
+ }
+ }
+ else if (type == LE_BOND_ADD)
+ {
+ if (handle_add)
+ {
+ privacy_add_device(p_entry);
+ }
+ }
+ privacy_handle_resolv_list();
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_bond_delete_by_bd(uint8_t *bd_addr, T_GAP_REMOTE_ADDR_TYPE bd_type);
+
+/**
+ * @brief Get the security level.
+ * @param[in] conn_id Connection ID.
+ * @param[out] p_type Pointer to location to get the security level.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_INVALID_PARAM Operation failure. No connection.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_seclevel(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ T_GAP_CAUSE cause;
+ T_GAP_SEC_LEVEL sec_level;
+ uint8_t conn_id = p_parse_value->dw_param[0];
+
+ cause = le_bond_get_sec_level(conn_id, &sec_level);
+ if(sec_level == GAP_SEC_LEVEL_NO)
+ {
+ data_uart_print("GAP_SEC_LEVEL_NO\r\n");
+ }
+ else if(sec_level == GAP_SEC_LEVEL_UNAUTHEN)
+ {
+ data_uart_print("GAP_SEC_LEVEL_UNAUTHEN\r\n");
+ }
+ else if(sec_level == GAP_SEC_LEVEL_AUTHEN)
+ {
+ data_uart_print("GAP_SEC_LEVEL_AUTHEN\r\n");
+ }
+ else if(sec_level == GAP_SEC_LEVEL_SC_UNAUTHEN)
+ {
+ data_uart_print("GAP_SEC_LEVEL_SC_UNAUTHEN\r\n");
+ }
+ else if(sec_level == GAP_SEC_LEVEL_SC_AUTHEN)
+ {
+ data_uart_print("GAP_SEC_LEVEL_SC_AUTHEN\r\n");
+ }
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_bond_get_sec_level(uint8_t conn_id, T_GAP_SEC_LEVEL *p_type);
+
+#if F_BT_LE_APP_KEY_MANAGER
+T_GAP_CAUSE le_bond_authen_result_confirm(uint8_t *bd_addr, T_GAP_REMOTE_ADDR_TYPE remote_addr_type,
+ T_GAP_KEY_TYPE key_type, T_GAP_CFM_CAUSE cause);
+
+T_GAP_CAUSE le_bond_authen_key_req_confirm(uint8_t *bd_addr,
+ T_GAP_REMOTE_ADDR_TYPE remote_addr_type,
+ uint8_t key_len, uint8_t *p_key, T_GAP_KEY_TYPE key_type,
+ T_GAP_CFM_CAUSE cause);
+T_GAP_CAUSE le_bond_gatt_server_store_confirm(T_GATT_STORE_OPCODE op, uint8_t *bd_addr,
+ T_GAP_REMOTE_ADDR_TYPE remote_addr_type,
+ uint8_t data_len, uint8_t *data, T_GAP_CFM_CAUSE cause);
+#endif
+
+#if F_BT_LE_GATT_CCCD_DATA_PENDING
+bool le_bond_set_cccd_data_pending(T_LE_KEY_ENTRY *p_entry, uint16_t handle, bool data_pending);
+#endif
+
+/** End of GAP_LE_BONDMGR_Exported_Functions
+ * @}
+ */
+
+/** End of GAP_LE_Bond_Manager
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_BOND_LE_H */
diff --git a/inc/bluetooth/gap/gap_callback_le.h b/inc/bluetooth/gap/gap_callback_le.h
new file mode 100644
index 0000000..00691f3
--- /dev/null
+++ b/inc/bluetooth/gap/gap_callback_le.h
@@ -0,0 +1,901 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gap_callback_le.h
+ * @brief This file contains function prototype for all GAP roles.
+ * @details
+ * @author ranhui
+ * @date 2016-02-18
+ * @version v0.1
+ * *************************************************************************************
+ */
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_CALLBACK_LE_H
+#define GAP_CALLBACK_LE_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#include "gap_storage_le.h"
+#include "gap_le_types.h"
+
+/** @defgroup GAP_CB_MSG_MODULE GAP Callback Message
+ * @brief GAP Callback Message
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup Gap_CB_Msg_Exported_Macros GAP Callback Msg Exported Macros
+ * @{
+ */
+
+/** @defgroup GAP_LE_MSG_Types GAP LE Msg Types
+ * @{
+ */
+
+//gap_le.h
+#define GAP_MSG_LE_MODIFY_WHITE_LIST 0x01 //!<Response msg type for le_modify_white_list
+#define GAP_MSG_LE_SET_RAND_ADDR 0x02 //!<Response msg type for le_set_rand_addr
+#define GAP_MSG_LE_SET_HOST_CHANN_CLASSIF 0x03 //!<Response msg type for le_set_host_chann_classif
+#if F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT
+#define GAP_MSG_LE_WRITE_DEFAULT_DATA_LEN 0x04 //!<Response msg type for le_write_default_data_len
+#endif
+
+//gap_conn_le.h
+#define GAP_MSG_LE_READ_RSSI 0x10 //!<Response msg type for le_read_rssi
+#if F_BT_LE_READ_CHANN_MAP
+#define GAP_MSG_LE_READ_CHANN_MAP 0x11 //!<Response msg type for le_read_chann_map
+#endif
+#define GAP_MSG_LE_DISABLE_SLAVE_LATENCY 0x12 //!<Response msg type for le_disable_slave_latency
+#if F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT
+#define GAP_MSG_LE_SET_DATA_LEN 0x13 //!<Response msg type for le_set_data_len
+#define GAP_MSG_LE_DATA_LEN_CHANGE_INFO 0x14 //!<Notification msg type for data length changed
+#endif
+#if F_BT_LE_GAP_CENTRAL_SUPPORT
+#define GAP_MSG_LE_CONN_UPDATE_IND 0x15 //!<Indication for le connection parameter update
+#endif
+#define GAP_MSG_LE_CREATE_CONN_IND 0x16 //!<Indication for create le connection
+#if F_BT_LE_5_0_SET_PHYS_SUPPORT
+#define GAP_MSG_LE_PHY_UPDATE_INFO 0x17 //!<Indication for le phyical update information
+#endif
+#define GAP_MSG_LE_UPDATE_PASSED_CHANN_MAP 0x18 //!<Response msg type for le_update_passed_chann_map
+#if F_BT_LE_READ_REMOTE_FEATS
+#define GAP_MSG_LE_REMOTE_FEATS_INFO 0x19 //!<Information for remote device supported features
+#endif
+#define GAP_MSG_LE_SET_CONN_TX_PWR 0x1A //!<Response msg type for le_set_conn_tx_power
+#if F_BT_LE_READ_REMOTE_VERSION_INFO_SUPPORT
+#define GAP_MSG_LE_READ_REMOTE_VERSION 0x1B //!<Response msg type for le_read_remote_version
+#endif
+
+//gap_bond_le.h
+#define GAP_MSG_LE_BOND_MODIFY_INFO 0x20 //!<Notification msg type for bond modify
+#if F_BT_LE_4_2_KEY_PRESS_SUPPORT
+#define GAP_MSG_LE_KEYPRESS_NOTIFY 0x21 //!<Response msg type for le_bond_keypress_notify
+#define GAP_MSG_LE_KEYPRESS_NOTIFY_INFO 0x22 //!<Notification msg type for le_bond_keypress_notify
+#endif
+#if F_BT_LE_ATT_SIGNED_WRITE_SUPPORT
+#define GAP_MSG_LE_GATT_SIGNED_STATUS_INFO 0x23 //!<Notification msg type for le signed status information
+#endif
+#if F_BT_LE_BOND_KEY_REQ_SUPPORT
+/* The type of callback will only be used when gap_param_key_manager equals 2 and no matching key entry is found*/
+#define GAP_MSG_LE_BOND_KEY_REQ 0x24 //!<Notification msg type for le bond key request information
+#endif
+
+//gap_scan.h
+#if F_BT_LE_GAP_SCAN_SUPPORT
+#define GAP_MSG_LE_SCAN_INFO 0x30 //!<Notification msg type for le scan
+#if F_BT_LE_PRIVACY_SUPPORT
+#define GAP_MSG_LE_DIRECT_ADV_INFO 0x31 //!<Notification msg type for le direct adv info
+#endif
+#endif
+
+//gap_adv.h
+#if F_BT_LE_GAP_PERIPHERAL_SUPPORT
+#define GAP_MSG_LE_ADV_UPDATE_PARAM 0x40 //!<Response msg type for le_adv_update_param
+#if F_BT_LE_READ_ADV_TX_POWRE_SUPPORT
+#define GAP_MSG_LE_ADV_READ_TX_POWER 0x41 //!<Response msg type for le_adv_read_tx_power
+#endif
+#define GAP_MSG_LE_ADV_SET_TX_POWER 0x42 //!<Response msg type for le_adv_set_tx_power
+#endif
+//gap_dtm.h
+#if F_BT_LE_4_0_DTM_SUPPORT
+#define GAP_MSG_LE_DTM_RECEIVER_TEST 0x70 //!<Response msg type for le_dtm_receiver_test
+#define GAP_MSG_LE_DTM_TRANSMITTER_TEST 0x71 //!<Response msg type for le_dtm_transmitter_test
+#define GAP_MSG_LE_DTM_TEST_END 0x72 //!<Response msg type for le_dtm_test_end
+#if F_BT_LE_5_0_DTM_SUPPORT
+#define GAP_MSG_LE_DTM_ENHANCED_RECEIVER_TEST 0x73 //!<Response msg type for le_dtm_enhanced_receiver_test
+#define GAP_MSG_LE_DTM_ENHANCED_TRANSMITTER_TEST 0x74 //!<Response msg type for le_dtm_enhanced_transmitter_test
+#endif
+#if F_BT_LE_5_1_DTM_SUPPORT
+#define GAP_MSG_LE_DTM_RECEIVER_TEST_V3 0x75 //!<Response msg type for le_dtm_receiver_test_v3
+#define GAP_MSG_LE_DTM_TRANSMITTER_TEST_V3 0x76 //!<Response msg type for le_dtm_transmitter_test_v3
+#endif
+#if F_BT_LE_5_2_DTM_SUPPORT
+#define GAP_MSG_LE_DTM_TRANSMITTER_TEST_V4 0x77 //!<Response msg type for le_dtm_transmitter_test_v4
+#endif
+#endif
+
+//gap_vendor.h
+#define GAP_MSG_LE_VENDOR_SET_MIN_REM_SCA 0xA2 //!<Response msg type for le_set_min_rem_sca
+#define GAP_MSG_LE_VENDOR_ONE_SHOT_ADV 0xA3 //!<Response msg type for le_vendor_one_shot_adv
+
+#if F_BT_LE_5_0_AE_SCAN_SUPPORT
+//gap_ext_scan.h
+#define GAP_MSG_LE_EXT_ADV_REPORT_INFO 0x50 //!<Notification msg type for le extended adv report
+#if F_BT_LE_GAP_MSG_INFO_WAY
+/* The type of callback will only be used after APP calls le_ext_scan_gap_msg_info_way(false). */
+#define GAP_MSG_LE_EXT_SCAN_STATE_CHANGE_INFO 0x51 //!<Notification msg type for extended scanning state
+#endif
+#endif
+#if F_BT_LE_5_0_PA_SYNC_SUPPORT
+//gap_pa_sync.h
+#define GAP_MSG_LE_PA_SYNC_MODIFY_PERIODIC_ADV_LIST 0x54 //!<Response msg type for le_pa_sync_modify_periodic_adv_list
+#define GAP_MSG_LE_PERIODIC_ADV_REPORT_INFO 0x55 //!<Notification msg type for LE periodic advertising report
+#define GAP_MSG_LE_PA_SYNC_DEV_STATE_CHANGE_INFO 0x56 //!<Notification msg type for synchronization device state of periodic advertising trains
+#define GAP_MSG_LE_PA_SYNC_STATE_CHANGE_INFO 0x57 //!<Notification msg type for synchronization state of periodic advertising trains
+#endif
+#if ((F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_SUPPORT) || F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT)
+//gap_pa_sync.h
+#define GAP_MSG_LE_PA_SYNC_SET_PERIODIC_ADV_RECEIVE_ENABLE 0x58 //!<Response msg type for le_pa_sync_set_periodic_adv_receive_enable
+#endif
+#if F_BT_LE_5_1_PAST_SENDER_SYNC_SUPPORT
+//gap_past_sender.h
+#define GAP_MSG_LE_PAST_SENDER_PERIODIC_ADV_SYNC_TRANSFER 0x59 //!<Response msg type for le_past_sender_periodic_adv_sync_transfer
+#endif
+#if F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT
+//gap_past_recipient.h
+#define GAP_MSG_LE_PAST_RECIPIENT_SET_DEFAULT_PERIODIC_ADV_SYNC_TRANSFER_PARAMS 0x5A //!<Response msg type for le_past_recipient_set_default_periodic_adv_sync_transfer_params
+#define GAP_MSG_LE_PAST_RECIPIENT_SET_PERIODIC_ADV_SYNC_TRANSFER_PARAMS 0x5B //!<Response msg type for le_past_recipient_set_periodic_adv_sync_transfer_params
+#define GAP_MSG_LE_PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_RECEIVED_INFO 0x5C //!<Notification msg type for le_past_recipient_set_default_periodic_adv_sync_transfer_params or le_past_recipient_set_periodic_adv_sync_transfer_params
+#endif
+#if F_BT_LE_5_2_SUPPORT
+//gap_pa_sync.h
+#define GAP_MSG_LE_BIGINFO_ADV_REPORT_INFO 0x5D //!<Notification msg type for LE BIGInfo advertising report
+#endif
+
+#if F_BT_LE_5_0_AE_ADV_SUPPORT
+//gap_ext_adv.h
+#define GAP_MSG_LE_EXT_ADV_START_SETTING 0x60 //!<Response msg type for le_ext_adv_start_setting
+#define GAP_MSG_LE_EXT_ADV_REMOVE_SET 0x61 //!<Response msg type for le_ext_adv_remove_set
+#define GAP_MSG_LE_EXT_ADV_CLEAR_SET 0x62 //!<Response msg type for le_ext_adv_clear_set
+#define GAP_MSG_LE_EXT_ADV_ENABLE 0x63 //!<Response msg type for le_ext_adv_enable
+#define GAP_MSG_LE_EXT_ADV_DISABLE 0x64 //!<Response msg type for le_ext_adv_disable
+#define GAP_MSG_LE_SCAN_REQ_RECEIVED_INFO 0x65 //!<Notification msg type for le scan received info
+#if F_BT_LE_GAP_MSG_INFO_WAY
+/* The type of callback will only be used after APP calls le_ext_adv_gap_msg_info_way(false). */
+#define GAP_MSG_LE_EXT_ADV_STATE_CHANGE_INFO 0x66 //!<Notification msg type for extended advertising state
+#endif
+#endif
+#if F_BT_LE_5_0_PA_ADV_SUPPORT
+//gap_pa_adv.h
+#define GAP_MSG_LE_PA_ADV_START_SETTING 0x6A //!<Response msg type for le_pa_adv_start_setting
+#define GAP_MSG_LE_PA_ADV_SET_PERIODIC_ADV_ENABLE 0x6B //!<Response msg type for le_pa_adv_set_periodic_adv_enable
+#define GAP_MSG_LE_PA_ADV_STATE_CHANGE_INFO 0x6C //!<Notification msg type for advertising state of periodic advertising trains
+#endif
+#if F_BT_LE_5_1_PAST_SENDER_ADV_SUPPORT
+//gap_past_sender.h
+#define GAP_MSG_LE_PAST_SENDER_PERIODIC_ADV_SET_INFO_TRANSFER 0x6E //!<Response msg type for le_past_sender_periodic_adv_set_info_transfer
+#endif
+
+
+#define GAP_MSG_LE_GAP_STATE_MSG 0xB0
+
+#if F_BT_LE_APP_KEY_MANAGER
+#define GAP_MSG_LE_AUTHEN_RESULT_IND 0x80
+#define GAP_MSG_LE_AUTHEN_KEY_REQ_IND 0x81
+#define GAP_MSG_LE_GATT_SERVER_STORE_IND 0x82
+#endif
+
+#if F_BT_LE_FIX_CHANN_SUPPORT
+//gap_fix_chann_conn.h
+#define GAP_MSG_LE_FIXED_CHANN_DATA_SEND 0xC0 //!<Response msg type for le_fixed_chann_data_send
+#define GAP_MSG_LE_FIXED_CHANN_DATA_IND 0xC1 //!<Indication for le fixed channel data received
+#define GAP_MSG_LE_FIXED_CHANN_REG 0xC2 //!<Response msg type for le_fixed_chann_reg
+#endif
+
+/** End of GAP_LE_MSG_Types
+ * @}
+ */
+
+/** End of Gap_CB_Msg_Exported_Macros
+* @}
+*/
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup Gap_CB_Msg_Exported_Types GAP Callback Msg Exported Types
+ * @{
+ */
+typedef struct
+{
+ uint16_t cause;
+} T_LE_CAUSE;
+
+/** @brief Response of le modify white list request.*/
+typedef struct
+{
+ T_GAP_WHITE_LIST_OP operation;
+ uint16_t cause;
+} T_LE_MODIFY_WHITE_LIST_RSP;
+
+/** @brief Response of le set random address request. */
+typedef struct
+{
+ uint16_t cause;
+} T_LE_SET_RAND_ADDR_RSP;
+
+/** @brief Response of le set channel classification request. */
+typedef struct
+{
+ uint16_t cause;
+} T_LE_SET_HOST_CHANN_CLASSIF_RSP;
+
+/** @brief Response for read rssi.*/
+typedef struct
+{
+ uint8_t conn_id;
+ int8_t rssi;
+ uint16_t cause;
+} T_LE_READ_RSSI_RSP;
+
+#if F_BT_LE_READ_CHANN_MAP
+/** @brief Response for read channel map.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cause;
+ uint8_t channel_map[5];
+} T_LE_READ_CHANN_MAP_RSP;
+#endif
+/** @brief Response for disable slave latency.*/
+typedef struct
+{
+ uint16_t cause;
+} T_LE_DISABLE_SLAVE_LATENCY_RSP;
+
+#if F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT
+/** @brief Response for set data length, which is used for BT4.2 data length extension.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cause;
+} T_LE_SET_DATA_LEN_RSP;
+
+/** @brief Notification for data length change info, which is used for BT4.2 data length extension.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t max_tx_octets;
+ uint16_t max_tx_time;
+ uint16_t max_rx_octets;
+ uint16_t max_rx_time;
+} T_LE_DATA_LEN_CHANGE_INFO;
+#endif
+
+#if F_BT_LE_GAP_CENTRAL_SUPPORT
+/** @brief Indication for connection paramete update.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t conn_interval_min;
+ uint16_t conn_interval_max;
+ uint16_t conn_latency;
+ uint16_t supervision_timeout;
+} T_LE_CONN_UPDATE_IND;
+#endif
+
+/** @brief Indication of le connectiona. */
+typedef struct
+{
+ uint8_t bd_addr[6];/**< Bluetooth address of remote device */
+ T_GAP_REMOTE_ADDR_TYPE remote_addr_type; /**< Address type of remote device */
+} T_LE_CREATE_CONN_IND;
+
+#if F_BT_LE_5_0_SET_PHYS_SUPPORT
+/** @brief Notification information when phy changed.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cause;
+ T_GAP_PHYS_TYPE tx_phy;
+ T_GAP_PHYS_TYPE rx_phy;
+} T_LE_PHY_UPDATE_INFO;
+#endif
+
+/** @brief Response for update passed channel map.*/
+typedef struct
+{
+ uint16_t cause;
+} T_LE_UPDATE_PASSED_CHANN_MAP_RSP;
+
+#if F_BT_LE_READ_REMOTE_FEATS
+/** @brief Information for remote device features.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cause;
+ uint8_t remote_feats[8];
+} T_LE_REMOTE_FEATS_INFO;
+#endif
+
+#if F_BT_LE_READ_REMOTE_VERSION_INFO_SUPPORT
+/** @brief Response for reading remote version information.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cause;
+ uint8_t version;
+ uint16_t manufacturer_name;
+ uint16_t subversion;
+} T_LE_READ_REMOTE_VERSION_RSP;
+#endif
+
+//gap_bond_le.h
+/** @brief Bond information modify type*/
+typedef enum
+{
+ LE_BOND_DELETE,
+ LE_BOND_ADD,
+ LE_BOND_CLEAR,
+ LE_BOND_FULL,
+ LE_BOND_KEY_MISSING,
+} T_LE_BOND_MODIFY_TYPE;
+
+/** @brief Structure for modify bonding information.*/
+typedef struct
+{
+ T_LE_BOND_MODIFY_TYPE type;
+ T_LE_KEY_ENTRY *p_entry;
+} T_LE_BOND_MODIFY_INFO;
+
+#if F_BT_LE_4_2_KEY_PRESS_SUPPORT
+/** @brief Structure for notify keypress result.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cause;
+} T_LE_KEYPRESS_NOTIFY_RSP;
+
+/** @brief Structure for notify keypress information.*/
+typedef struct
+{
+ uint8_t conn_id;
+ T_GAP_KEYPRESS_NOTIF_TYPE event_type;
+} T_LE_KEYPRESS_NOTIFY_INFO;
+#endif
+
+#if F_BT_LE_ATT_SIGNED_WRITE_SUPPORT
+/** @brief Structure for LE signed information.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cause;
+ bool update_local;
+ uint32_t local_sign_count;
+ uint32_t remote_sign_count;
+} T_LE_GATT_SIGNED_STATUS_INFO;
+#endif
+
+#if F_BT_LE_BOND_KEY_REQ_SUPPORT
+typedef struct
+{
+ uint8_t bd_addr[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_addr_type;
+ T_GAP_KEY_TYPE key_type; /**< Key type. */
+ uint8_t key_len; /**< Provided by APP. */
+ uint8_t link_key[28]; /**< Provided by APP. */
+} T_LE_BOND_KEY_REQ;
+#endif
+
+#if F_BT_LE_4_0_DTM_SUPPORT
+/** @brief Response of le receiver test request. */
+typedef struct
+{
+ uint16_t cause;
+ uint16_t num_pkts;
+} T_LE_DTM_TEST_END_RSP;
+#endif
+
+//gap_scan.h
+#if F_BT_LE_GAP_SCAN_SUPPORT
+/** @brief Information of le scan information. */
+typedef struct
+{
+ uint8_t bd_addr[6];/**< Bluetooth address of remote device. */
+ T_GAP_REMOTE_ADDR_TYPE remote_addr_type;/**< Address type of remote device. */
+ T_GAP_ADV_EVT_TYPE adv_type;/**< Advertising event type. */
+ int8_t rssi; /**< RSSI. */
+ uint8_t data_len;
+ uint8_t data[31];
+} T_LE_SCAN_INFO;
+
+#if F_BT_LE_PRIVACY_SUPPORT
+/** @brief Information of le direct advertising. */
+typedef struct
+{
+ uint8_t bd_addr[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_addr_type;
+ uint8_t direct_bd_addr[6];
+ T_GAP_DIRECT_ADDR_TYPE direct_addr_type;
+ T_GAP_ADV_EVT_TYPE direct_adv_type;
+ int8_t rssi;
+} T_LE_DIRECT_ADV_INFO;
+#endif
+#endif
+
+//gap_adv.h
+#if F_BT_LE_GAP_PERIPHERAL_SUPPORT
+/** @brief LE advertising parameter update result.*/
+typedef struct
+{
+ uint16_t cause;
+} T_LE_ADV_UPDATE_PARAM_RSP;
+
+#if F_BT_LE_READ_ADV_TX_POWRE_SUPPORT
+/** @brief Response of le read advertising transmitter power request. */
+typedef struct
+{
+ uint16_t cause;
+ uint8_t tx_power_level;
+} T_LE_ADV_READ_TX_POWER_RSP;
+#endif
+#endif
+
+/** @brief LE vendor advertising data type.*/
+typedef enum
+{
+ GAP_ADV_VENDOR_ADV_38_DATA,
+ GAP_ADV_VENDOR_ADV_39_DATA,
+ GAP_ADV_VENDOR_SCANRSP_38_DATA,
+ GAP_ADV_VENDOR_SCANRSP_39_DATA,
+} T_GAP_ADV_VENDOR_DATA_TYPE;
+
+typedef struct
+{
+ T_GAP_ADV_VENDOR_DATA_TYPE type;
+ uint16_t cause;
+} T_LE_VENDOR_ADV_3_DATA_SET_RSP;
+
+#if F_BT_LE_5_0_AE_SCAN_SUPPORT
+/** @brief Information of le extended advertising report. */
+typedef struct
+{
+ uint16_t event_type;
+ T_GAP_EXT_ADV_EVT_DATA_STATUS data_status;
+ T_GAP_REMOTE_ADDR_TYPE addr_type;
+ uint8_t bd_addr[6];
+ T_GAP_PHYS_PRIM_ADV_TYPE primary_phy;
+ uint8_t secondary_phy;
+ uint8_t adv_sid;
+ int8_t tx_power;
+ int8_t rssi;
+ uint16_t peri_adv_interval;
+ T_GAP_DIRECT_ADDR_TYPE direct_addr_type;
+ uint8_t direct_addr[6];
+ uint8_t data_len;
+ uint8_t *p_data; //max 229 bytes
+} T_LE_EXT_ADV_REPORT_INFO;
+
+#if F_BT_LE_GAP_MSG_INFO_WAY
+/* The struct will only be used after APP calls le_ext_scan_gap_msg_info_way(false). */
+typedef struct
+{
+ uint16_t cause;
+ uint8_t state;
+} T_LE_EXT_SCAN_STATE_CHANGE_INFO;
+#endif
+#endif
+
+#if F_BT_LE_5_0_AE_ADV_SUPPORT
+//gap_ext_adv.h
+typedef struct
+{
+ uint16_t cause;
+ uint8_t adv_handle;
+ uint8_t flag;
+} T_LE_EXT_ADV_START_SETTING_RSP;
+
+typedef struct
+{
+ uint16_t cause;
+ uint8_t adv_handle;
+} T_LE_EXT_ADV_REMOVE_SET_RSP;
+
+typedef struct
+{
+ uint16_t cause;
+} T_LE_EXT_ADV_CLEAR_SET_RSP;
+
+/** @brief Information of le scan request received. */
+typedef struct
+{
+ uint8_t adv_handle;
+ uint8_t scanner_addr_type;
+ uint8_t scanner_addr[6];
+} T_LE_SCAN_REQ_RECEIVED_INFO;
+
+#if F_BT_LE_GAP_MSG_INFO_WAY
+/* The struct will only be used after APP calls le_ext_adv_gap_msg_info_way(false). */
+typedef struct
+{
+ uint16_t cause;
+ uint8_t adv_handle;
+ uint8_t state;
+} T_LE_EXT_ADV_STATE_CHANGE_INFO;
+#endif
+#endif
+
+#if F_BT_LE_5_0_PA_ADV_SUPPORT
+typedef struct
+{
+ uint16_t cause;
+ uint8_t adv_handle;
+ uint8_t flag;
+} T_LE_PA_ADV_START_SETTING_RSP;
+
+typedef struct
+{
+ uint16_t cause;
+ uint8_t adv_handle;
+ uint8_t enable;
+} T_LE_PA_ADV_SET_PERIODIC_ADV_ENABLE_RSP;
+
+typedef struct
+{
+ uint16_t cause;
+ uint8_t adv_handle;
+ uint8_t state;
+} T_LE_PA_ADV_STATE_CHANGE_INFO;
+#endif
+
+#if F_BT_LE_5_0_PA_SYNC_SUPPORT
+/** @brief Response of le modify periodic advertiser list request.*/
+typedef struct
+{
+ T_GAP_PA_SYNC_PERIODIC_ADV_LIST_OP operation;
+ uint16_t cause;
+} T_LE_PA_SYNC_MODIFY_PERIODIC_ADV_LIST_RSP;
+
+/** @brief Information of le periodic advertising report. */
+typedef struct
+{
+ uint8_t sync_id;
+ uint16_t sync_handle;
+ int8_t tx_power;
+ int8_t rssi;
+ T_GAP_PERIODIC_ADV_REPORT_CTE_TYPE cte_type;
+ T_GAP_PERIODIC_ADV_REPORT_DATA_STATUS data_status;
+ uint8_t data_len;
+ uint8_t *p_data; /* 0 to 247 bytes */
+} T_LE_PERIODIC_ADV_REPORT_INFO;
+
+typedef struct
+{
+ uint8_t gap_terminate_sync_state: 1; //!< @ref GAP_PA_TERMINATE_SYNC_DEV_STATE
+ uint8_t gap_create_sync_state: 1; //!< @ref GAP_PA_SYNC_SCAN_DEV_STATE
+ uint8_t gap_periodic_adv_receive_enable_state: 1; //!< @ref GAP_PA_RECEIVE_ENABLE_DEV_STATE
+ uint8_t gap_pa_sync_rfu_state: 5; //!< @ref reserved for future
+} T_GAP_PA_SYNC_DEV_STATE;
+
+typedef struct
+{
+ T_GAP_PA_SYNC_DEV_STATE state;
+ uint16_t cause;
+} T_LE_PA_SYNC_DEV_STATE_CHANGE_INFO;
+
+typedef struct
+{
+ uint8_t sync_id;
+ uint16_t sync_handle;
+ uint8_t state;
+ bool sync_transfer_received_flag; /* sync_transfer_received_flag will be only used when state is GAP_PA_SYNC_STATE_SYNCHRONIZED.
+ true: Periodic advertising synchroinzation is received through le_past_recipient_set_default_periodic_adv_sync_transfer_params
+ or le_past_recipient_set_periodic_adv_sync_transfer_params.
+ false: Periodic advertising packet is received through le_pa_sync_create_sync.*/
+ uint16_t cause;
+} T_LE_PA_SYNC_STATE_CHANGE_INFO;
+#endif
+
+#if ((F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_SUPPORT) || F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT)
+typedef struct
+{
+ uint8_t sync_id;
+ uint16_t sync_handle;
+ uint16_t cause;
+ uint8_t enable;
+} T_LE_PA_SET_PERIODIC_ADV_RECEIVE_ENABLE_RSP;
+#endif
+
+#if F_BT_LE_5_1_PAST_SUPPORT
+#if F_BT_LE_5_1_PAST_SENDER_SUPPORT
+#if F_BT_LE_5_1_PAST_SENDER_ADV_SUPPORT
+typedef struct
+{
+ uint16_t cause;
+ uint8_t conn_id;
+ uint8_t adv_handle;
+} T_LE_PAST_SENDER_PERIODIC_ADV_SET_INFO_TRANSFER_RSP;
+#endif
+#if F_BT_LE_5_1_PAST_SENDER_SYNC_SUPPORT
+typedef struct
+{
+ uint16_t cause;
+ uint8_t conn_id;
+ uint8_t sync_id;
+ uint16_t sync_handle;
+} T_LE_PAST_SENDER_PERIODIC_ADV_SYNC_TRANSFER_RSP;
+#endif
+#endif
+#if F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT
+typedef struct
+{
+ uint16_t cause;
+} T_LE_PAST_RECIPIENT_SET_DEFAULT_PERIODIC_ADV_SYNC_TRANSFER_PARAMS_RSP;
+
+typedef struct
+{
+ uint16_t cause;
+ uint8_t conn_id;
+} T_LE_PAST_RECIPIENT_SET_PERIODIC_ADV_SYNC_TRANSFER_PARAMS_RSP;
+
+typedef struct
+{
+ uint16_t cause;
+ uint8_t conn_id;
+ uint8_t sync_id;
+ uint16_t sync_handle;
+ uint16_t service_data;
+ uint8_t adv_sid;
+ T_GAP_PA_SYNC_ADV_ADDR_TYPE adv_addr_type;
+ uint8_t adv_addr[GAP_BD_ADDR_LEN];
+ T_GAP_PHYS_TYPE adv_phy;
+ uint16_t periodic_adv_interval;
+ uint8_t adv_clock_accuracy;
+} T_LE_PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_RECEIVED_INFO;
+#endif
+#endif
+
+
+#if F_BT_LE_5_2_SUPPORT
+typedef struct
+{
+ uint8_t sync_id;
+ uint16_t sync_handle;
+ uint8_t num_bis;
+ uint8_t nse;
+ uint16_t iso_interval;
+ uint8_t bn;
+ uint8_t pto;
+ uint8_t irc;
+ uint16_t max_pdu;
+ uint32_t sdu_interval;
+ uint16_t max_sdu;
+ T_GAP_PHYS_TYPE phy;
+ uint8_t framing;
+ uint8_t encryption;
+} T_LE_BIGINFO_ADV_REPORT_INFO;
+#endif
+
+#if F_BT_LE_APP_KEY_MANAGER
+typedef struct
+{
+ uint8_t bd_addr[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_addr_type;
+ uint8_t key_len;
+ T_GAP_KEY_TYPE key_type; /**< Key type. */
+ uint8_t link_key[28];
+ uint16_t cause;
+} T_LE_AUTHEN_RESULT_IND;
+
+typedef struct
+{
+ uint8_t bd_addr[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_addr_type;
+ T_GAP_KEY_TYPE key_type; /**< Requested Key type. */
+} T_LE_AUTHEN_KEY_REQ_IND;
+
+typedef struct
+{
+ T_GATT_STORE_OPCODE op;
+ T_GAP_REMOTE_ADDR_TYPE remote_addr_type;
+ uint8_t bd_addr[6];
+ uint8_t data_len;
+ uint8_t *p_data;
+} T_LE_GATT_SERVER_STORE_IND;
+#endif
+
+#if F_BT_LE_FIX_CHANN_SUPPORT
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cid;
+ uint16_t cause;
+} T_LE_FIXED_CHANN_DATA_SEND_RSP;
+
+typedef struct
+{
+ uint8_t conn_id; /**< local link ID. */
+ uint16_t cid; /**< channel ID */
+ uint16_t value_len; /**< value length */
+ uint8_t *p_data; /**< value. */
+} T_LE_FIXED_CHANN_DATA_IND;
+
+typedef struct
+{
+ uint16_t cid;
+ uint16_t cause;
+} T_LE_FIXED_CHANN_REG_RSP;
+#endif
+
+/** @brief GAP LE Callback Data*/
+typedef union
+{
+ T_LE_CAUSE le_cause;
+
+//gap_le.h
+ T_LE_MODIFY_WHITE_LIST_RSP *p_le_modify_white_list_rsp;
+ T_LE_SET_RAND_ADDR_RSP *p_le_set_rand_addr_rsp;
+ T_LE_SET_HOST_CHANN_CLASSIF_RSP *p_le_set_host_chann_classif_rsp;
+
+//gap_conn_le.h
+ T_LE_READ_RSSI_RSP *p_le_read_rssi_rsp;
+#if F_BT_LE_READ_CHANN_MAP
+ T_LE_READ_CHANN_MAP_RSP *p_le_read_chann_map_rsp;
+#endif
+ T_LE_DISABLE_SLAVE_LATENCY_RSP *p_le_disable_slave_latency_rsp;
+#if F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT
+ T_LE_SET_DATA_LEN_RSP *p_le_set_data_len_rsp;
+ T_LE_DATA_LEN_CHANGE_INFO *p_le_data_len_change_info;
+#endif
+#if F_BT_LE_GAP_CENTRAL_SUPPORT
+ T_LE_CONN_UPDATE_IND *p_le_conn_update_ind;
+#endif
+ T_LE_CREATE_CONN_IND *p_le_create_conn_ind;
+#if F_BT_LE_5_0_SET_PHYS_SUPPORT
+ T_LE_PHY_UPDATE_INFO *p_le_phy_update_info;
+#endif
+ T_LE_UPDATE_PASSED_CHANN_MAP_RSP *p_le_update_passed_chann_map_rsp;
+#if F_BT_LE_READ_REMOTE_FEATS
+ T_LE_REMOTE_FEATS_INFO *p_le_remote_feats_info;
+#endif
+#if F_BT_LE_READ_REMOTE_VERSION_INFO_SUPPORT
+ T_LE_READ_REMOTE_VERSION_RSP *p_le_read_remote_version_rsp;
+#endif
+//gap_bond_le.h
+ T_LE_BOND_MODIFY_INFO *p_le_bond_modify_info;
+#if F_BT_LE_4_2_KEY_PRESS_SUPPORT
+ T_LE_KEYPRESS_NOTIFY_RSP *p_le_keypress_notify_rsp;
+ T_LE_KEYPRESS_NOTIFY_INFO *p_le_keypress_notify_info;
+#endif
+#if F_BT_LE_ATT_SIGNED_WRITE_SUPPORT
+ T_LE_GATT_SIGNED_STATUS_INFO *p_le_gatt_signed_status_info;
+#endif
+#if F_BT_LE_BOND_KEY_REQ_SUPPORT
+ T_LE_BOND_KEY_REQ *p_le_bond_key_req;
+#endif
+
+//gap_scan.h
+#if F_BT_LE_GAP_SCAN_SUPPORT
+ T_LE_SCAN_INFO *p_le_scan_info;
+#if F_BT_LE_PRIVACY_SUPPORT
+ T_LE_DIRECT_ADV_INFO *p_le_direct_adv_info;
+#endif
+#endif
+//gap_adv.h
+#if F_BT_LE_GAP_PERIPHERAL_SUPPORT
+ T_LE_ADV_UPDATE_PARAM_RSP *p_le_adv_update_param_rsp;
+#if F_BT_LE_READ_ADV_TX_POWRE_SUPPORT
+ T_LE_ADV_READ_TX_POWER_RSP *p_le_adv_read_tx_power_rsp;
+#endif
+#endif
+//gap_dtm.h
+#if F_BT_LE_4_0_DTM_SUPPORT
+ T_LE_DTM_TEST_END_RSP *p_le_dtm_test_end_rsp;
+#endif
+//gap_vendor.h
+ T_LE_VENDOR_ADV_3_DATA_SET_RSP *p_le_vendor_adv_3_data_set_rsp;
+
+//gap_ext_scan.h
+#if F_BT_LE_5_0_AE_SCAN_SUPPORT
+ T_LE_EXT_ADV_REPORT_INFO *p_le_ext_adv_report_info;
+#if F_BT_LE_GAP_MSG_INFO_WAY
+ /* The callback data will only be used after APP calls le_ext_scan_gap_msg_info_way(false). */
+ T_LE_EXT_SCAN_STATE_CHANGE_INFO *p_le_ext_scan_state_change_info;
+#endif
+#endif
+//gap_ext_adv.h
+#if F_BT_LE_5_0_AE_ADV_SUPPORT
+ T_LE_EXT_ADV_START_SETTING_RSP *p_le_ext_adv_start_setting_rsp;
+ T_LE_EXT_ADV_REMOVE_SET_RSP *p_le_ext_adv_remove_set_rsp;
+ T_LE_EXT_ADV_CLEAR_SET_RSP *p_le_ext_adv_clear_set_rsp;
+ T_LE_SCAN_REQ_RECEIVED_INFO *p_le_scan_req_received_info;
+#if F_BT_LE_GAP_MSG_INFO_WAY
+ /* The callback data will only be used after APP calls le_ext_adv_gap_msg_info_way(false). */
+ T_LE_EXT_ADV_STATE_CHANGE_INFO *p_le_ext_adv_state_change_info;
+#endif
+#endif
+
+#if F_BT_LE_5_0_PA_ADV_SUPPORT
+ T_LE_PA_ADV_START_SETTING_RSP *p_le_pa_adv_start_setting_rsp;
+ T_LE_PA_ADV_SET_PERIODIC_ADV_ENABLE_RSP *p_le_pa_adv_set_periodic_adv_enable_rsp;
+ T_LE_PA_ADV_STATE_CHANGE_INFO *p_le_pa_adv_state_change_info;
+#endif
+#if F_BT_LE_5_0_PA_SYNC_SUPPORT
+ T_LE_PA_SYNC_MODIFY_PERIODIC_ADV_LIST_RSP *p_le_pa_sync_modify_periodic_adv_list_rsp;
+ T_LE_PERIODIC_ADV_REPORT_INFO *p_le_periodic_adv_report_info;
+ T_LE_PA_SYNC_DEV_STATE_CHANGE_INFO *p_le_pa_sync_dev_state_change_info;
+ T_LE_PA_SYNC_STATE_CHANGE_INFO *p_le_pa_sync_state_change_info;
+#endif
+#if ((F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_SUPPORT) || F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT)
+ T_LE_PA_SET_PERIODIC_ADV_RECEIVE_ENABLE_RSP *p_le_pa_set_periodic_adv_receive_enable_rsp;
+#endif
+
+#if F_BT_LE_5_1_PAST_SUPPORT
+#if F_BT_LE_5_1_PAST_SENDER_SUPPORT
+#if F_BT_LE_5_1_PAST_SENDER_ADV_SUPPORT
+ T_LE_PAST_SENDER_PERIODIC_ADV_SET_INFO_TRANSFER_RSP
+ *p_le_past_sender_periodic_adv_set_info_transfer_rsp;
+#endif
+#if F_BT_LE_5_1_PAST_SENDER_SYNC_SUPPORT
+ T_LE_PAST_SENDER_PERIODIC_ADV_SYNC_TRANSFER_RSP
+ *p_le_past_sender_periodic_adv_sync_transfer_rsp;
+#endif
+#endif
+#if F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT
+ T_LE_PAST_RECIPIENT_SET_DEFAULT_PERIODIC_ADV_SYNC_TRANSFER_PARAMS_RSP
+ *p_le_past_recipient_set_default_periodic_adv_sync_transfer_params_rsp;
+ T_LE_PAST_RECIPIENT_SET_PERIODIC_ADV_SYNC_TRANSFER_PARAMS_RSP
+ *p_le_past_recipient_set_periodic_adv_sync_transfer_params_rsp;
+ T_LE_PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_RECEIVED_INFO
+ *p_le_past_recipient_periodic_adv_sync_transfer_received_info;
+#endif
+#endif
+
+#if F_BT_LE_5_2_SUPPORT
+ T_LE_BIGINFO_ADV_REPORT_INFO *p_le_biginfo_adv_report_info;
+#endif
+
+ void *p_gap_state_msg;
+
+ void *p_le_cb_data;
+
+#if F_BT_LE_APP_KEY_MANAGER
+ T_LE_AUTHEN_KEY_REQ_IND *p_le_authen_key_req_ind;
+ T_LE_AUTHEN_RESULT_IND *p_le_authen_result_ind;
+ T_LE_GATT_SERVER_STORE_IND *p_le_gatt_server_store_ind;
+#endif
+//gap_fixed_chann_conn.h
+#if F_BT_LE_FIX_CHANN_SUPPORT
+ T_LE_FIXED_CHANN_DATA_SEND_RSP *p_le_fixed_chann_data_send_rsp;
+ T_LE_FIXED_CHANN_DATA_IND *p_le_fixed_chann_data_ind;
+ T_LE_FIXED_CHANN_REG_RSP *p_le_fixed_chann_reg_rsp;
+#endif
+} T_LE_CB_DATA;
+
+/** End of Gap_CB_Msg_Exported_Types
+* @}
+*/
+
+/** End of GAP_CB_MSG_MODULE
+* @}
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_MSG_H */
diff --git a/inc/bluetooth/gap/gap_conn_le.h b/inc/bluetooth/gap/gap_conn_le.h
new file mode 100644
index 0000000..edcba14
--- /dev/null
+++ b/inc/bluetooth/gap/gap_conn_le.h
@@ -0,0 +1,1000 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gap_conn_le.h
+ * @brief This file contains all the constants and functions prototypes for GAP protocol.
+ * @details
+ * @author jane
+ * @date 2016-02-18
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_CONN_LE_H
+#define GAP_CONN_LE_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#include "gap.h"
+#include "gap_le.h"
+#include "gap_msg.h"
+
+/** @defgroup GAP_LE_CONNECTION_MODULE GAP LE Connection Module
+ * @brief GAP LE connection module
+ * @{
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_CONNECTION_Exported_Types GAP Connection Exported Types
+ * @{
+ */
+#if F_BT_LE_GAP_CENTRAL_SUPPORT
+/** @brief GAP connection phy types*/
+typedef enum
+{
+ GAP_CONN_PARAM_1M = 0,
+#if F_BT_LE_5_0_AE_ADV_SUPPORT
+ GAP_CONN_PARAM_2M = 1,
+ GAP_CONN_PARAM_CODED = 2,
+#endif
+} T_GAP_CONN_PARAM_TYPE;
+#endif
+
+/** @brief GAP link roles */
+typedef enum
+{
+ GAP_LINK_ROLE_UNDEFINED, //!< Unknown.
+ GAP_LINK_ROLE_MASTER, //!< Role is master.
+ GAP_LINK_ROLE_SLAVE //!< Role is slave.
+} T_GAP_ROLE;
+
+/** @brief LE connection parameter types */
+typedef enum
+{
+ GAP_PARAM_CONN_BD_ADDR = 0x270,//!< Address of connected device. Read only. Size is uint8[B_MAX_ADV_LEN]. Set to all zeros when not connected.
+ GAP_PARAM_CONN_BD_ADDR_TYPE = 0x271,//!< Address type of connected device. Read only. Size is uint8. Set to zero when not connected.
+ GAP_PARAM_CONN_INTERVAL = 0x272,//!< Current connection interval. Read only. Size is uint16. Range is 7.5ms to 4 seconds (0x0006 to 0x0C80). Default is 0 (no connection).
+ GAP_PARAM_CONN_LATENCY = 0x273,//!< Current slave latency. Read only. Size is uint16. Range is 0 to 499. Default is 0 (no slave latency or no connection).
+ GAP_PARAM_CONN_TIMEOUT = 0x274,//!< Current timeout value. Read only. size is uint16. Range is 100ms to 32 seconds. Default is 0 (no connection).
+ GAP_PARAM_CONN_MTU_SIZE = 0x275,//!< MTU size. Read only. size is uint16.
+ GAP_PARAM_CONN_LOCAL_BD_TYPE = 0x276,//!< Local bluetooth address type. Read only. size is 1 byte.
+#if F_BT_LE_5_0_SET_PHYS_SUPPORT
+ GAP_PARAM_CONN_RX_PHY_TYPE = 0x277,//!< Rx phy type. Read only. size is 1 byte.
+ GAP_PARAM_CONN_TX_PHY_TYPE = 0x278,//!< Tx phy type. Read only. size is 1 byte.
+#endif
+#if F_BT_LE_READ_REMOTE_FEATS
+ GAP_PARAM_CONN_REMOTE_FEATURES = 0x279,//!< Remote supported features. Read only.
+#endif
+ GAP_PARAM_CONN_CHANN_ALGORITHM = 0x27a,//!< LE Channel Selection Algorithm used. Read only.
+ GAP_PARAM_CONN_HANDLE = 0x27b,//!< LE link connection handle. Read only.
+} T_LE_CONN_PARAM_TYPE;
+
+/** @brief Connected device information.*/
+typedef struct
+{
+ T_GAP_CONN_STATE conn_state; //!< Connection state
+ T_GAP_ROLE role; //!< Device role
+ uint8_t remote_bd[GAP_BD_ADDR_LEN]; //!< Remote address
+ uint8_t remote_bd_type; //!< Remote address type
+} T_GAP_CONN_INFO;
+
+#if F_BT_LE_GAP_CENTRAL_SUPPORT
+/** @brief Definition of LE connection request parameter.*/
+typedef struct
+{
+ uint16_t scan_interval;/**< Time interval from when the Controller started its last scan
+ until it begins the subsequent scan on the primary advertising channel.
+
+ By default @ref GAP_PARAM_USE_EXTENDED_ADV is false,
+ Range: 0x0004 to 0x4000
+ Time = N * 0.625 ms
+ Time Range: 2.5 ms to 10.24 s
+
+ If @ref GAP_PARAM_USE_EXTENDED_ADV is set as true,
+ Range: 0x0004 to 0xFFFF
+ Time = N * 0.625 ms
+ Time Range: 2.5 ms to 40.959375 s */
+ uint16_t scan_window;/**< Duration of the scan on the primary advertising channel.
+ By default @ref GAP_PARAM_USE_EXTENDED_ADV is false,
+ Range: 0x0004 to 0x4000
+ Time = N * 0.625 ms
+ Time Range: 2.5 ms to 10.24 s
+
+ If @ref GAP_PARAM_USE_EXTENDED_ADV is set as true,
+ Range: 0x0004 to 0xFFFF
+ Time = N * 0.625 ms
+ Time Range: 2.5 ms to 40.959375 s */
+ uint16_t conn_interval_min;/**< Minimum value for the connection interval. This shall be less
+ than or equal to Conn_Interval_Max[i].
+ Range: 0x0006 to 0x0C80
+ Time = N * 1.25 ms
+ Time Range: 7.5 ms to 4 s */
+ uint16_t conn_interval_max;/**< Maximum value for the connection interval. This shall be greater
+ than or equal to Conn_Interval_Max[i].
+ Range: 0x0006 to 0x0C80
+ Time = N * 1.25 ms
+ Time Range: 7.5 ms to 4 s */
+ uint16_t conn_latency;/**< Slave latency for the connection in number of connection events.
+ Range: 0x0000 to 0x01F3
+ This shall be less than or equal to (((supv_tout * 10 ms) / (conn_interval_max * 1.25 ms * 2)) - 1) */
+ uint16_t supv_tout;/**< Supervision timeout for the LE Link.
+ Range: 0x000A to 0x0C80
+ Time = N * 10 ms
+ Time Range: 100 ms to 32 s */
+ uint16_t ce_len_min;/**< Informative parameter recommending the minimum length of connection
+ event needed for this LE connection.
+ Range: 0x0000 - 0xFFFF
+ Time = N * 0.625 ms */
+ uint16_t ce_len_max;/**< Informative parameter recommending the maximum length of connection
+ event needed for this LE connection.
+ Range: 0x0000 - 0xFFFF
+ Time = N * 0.625 ms */
+} T_GAP_LE_CONN_REQ_PARAM;
+#endif
+
+/** End of GAP_LE_CONNECTION_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @defgroup GAP_CONNECTION_COMMON_EXPORT_Functions GAP Connection Exported Functions
+ *
+ * @{
+ */
+
+/**
+ * @brief Get a GAP connection parameter.
+ *
+ * NOTE: You can call this function with a GAP connection parameter type and it will get a
+ * GAP connection parameter. GAP connection parameters are defined in @ref T_LE_CONN_PARAM_TYPE. Also, the
+ * "p_value" field must point to a data with type "uint16_t".
+ *
+ * @param[in] param Connection parameter type: @ref T_LE_CONN_PARAM_TYPE
+ * @param[in,out] p_value Pointer to location to get the value. This is dependent on
+ * the parameter type and will be cast to the appropriate
+ * data type (For example: if data type param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ * @param[in] conn_id Connection id.
+ *
+ * @return Get result
+ * @retval GAP_CAUSE_SUCCESS Get parameter success.
+ * @retval other Get parameter failed.
+ */
+T_GAP_CAUSE le_get_conn_param(T_LE_CONN_PARAM_TYPE param, void *p_value, uint8_t conn_id);
+
+/**
+ * @brief Get connection information.
+ * @param[in] conn_id Connection ID
+ * @param[in,out] p_conn_info Connection information @ref T_GAP_CONN_INFO
+ * @return Get result
+ * @retval true Success
+ * @retval false Get failed
+ */
+bool le_get_conn_info(uint8_t conn_id, T_GAP_CONN_INFO *p_conn_info);
+
+/**
+ * @brief Get connection address information.
+ * @param[in] conn_id Connection ID
+ * @param[in,out] bd_addr Remote bluetooth device address
+ * @param[in,out] bd_type Remote bluetooth device address type
+ * @return Get result
+ * @retval true Success
+ * @retval false Get failed
+ */
+bool le_get_conn_addr(uint8_t conn_id, uint8_t *bd_addr, uint8_t *bd_type);
+
+/**
+ * @brief Get connection ID.
+ * @param[in] bd_addr Remote bluetooth device address
+ * @param[in] bd_type Remote bluetooth device address type
+ * @param[in, out] p_conn_id Connection ID
+ * @return Get result
+ * @retval true Success
+ * @retval false Get failed
+ */
+bool le_get_conn_id(uint8_t *bd_addr, uint8_t bd_type, uint8_t *p_conn_id);
+
+/**
+ * @brief Get connection ID from connection handle.
+ * @param[in] conn_handle Connection handle
+ * @param[in, out] p_conn_id Connection ID
+ * @return Get result
+ * @retval true Success
+ * @retval false Get failed
+ */
+bool le_get_conn_id_by_handle(uint16_t conn_handle, uint8_t *p_conn_id);
+
+/**
+ * @brief Get connection local address by connection ID.
+ * @param[in] conn_handle Connection handle
+ * @param[in, out] bd_addr Local bluetooth device address
+ * @param[in, out] bd_type Local bluetooth device address type
+ * @return Get result
+ * @retval true Success
+ * @retval false Get failed
+ */
+bool le_get_conn_local_addr_by_conn_id(uint8_t conn_id, uint8_t *bd_addr, uint8_t *bd_type);
+
+/**
+* @brief Get the active link number.
+*
+* @return Active link number
+* @retval 0 No connection created
+* @retval other Connected links number
+*/
+uint8_t le_get_active_link_num(void);
+
+/**
+* @brief Get the idle link number.
+*
+* @return Idle link number.
+* @retval 0 Can't create new connection
+* @retval other Can create new connection
+*/
+uint8_t le_get_idle_link_num(void);
+
+/**
+ * @brief Terminates the existing connection. When link is disconnected, @ref app_handle_conn_state_evt will be
+ * called with new_state as @ref GAP_CONN_STATE_DISCONNECTED.
+ * The disconnection reason is HCI_ERR_REMOTE_USER_TERMINATE.
+ *
+ * @param[in] conn_id connection ID to be disconnected.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Send request success
+ * @retval GAP_CAUSE_NON_CONN Failed. No connection
+ * @retval GAP_CAUSE_INVALID_PARAM Failed. Invalid parameter
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t conn_id = 0;
+ le_disconnect(conn_id);
+ }
+
+ void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+ {
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_disconnect(uint8_t conn_id);
+
+/**
+ * @brief Terminates the existing connection with reason. When link is disconnected, app_handle_conn_state_evt will be
+ * called with new_state as @ref GAP_CONN_STATE_DISCONNECTED.
+ *
+ * @param[in] conn_id connection ID to be disconnected.
+ * @param[in] reason disconnection reason.
+ * @arg HCI_ERR_REMOTE_USER_TERMINATE: 0x13
+ * @arg HCI_ERR_REMOTE_LOW_RESOURCE: 0x14
+ * @arg HCI_ERR_REMOTE_POWER_OFF: 0x15
+ * @arg HCI_ERR_UNSUPPORTED_REMOTE_FEAT: 0x1A
+ * @arg HCI_ERR_UNACCEPTABLE_CONN_INTERVAL: 0x3B
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Send request success
+ * @retval GAP_CAUSE_NON_CONN Failed. No connection
+ * @retval GAP_CAUSE_INVALID_PARAM Failed. Invalid parameter
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t conn_id = 0x01;
+ le_disconnect_with_reason(conn_id, HCI_ERR_REMOTE_USER_TERMINATE);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_disconnect_with_reason(uint8_t conn_id, uint8_t reason);
+
+#if F_BT_LE_READ_REMOTE_VERSION_INFO_SUPPORT
+/**
+ * @brief Obtain the values for the version information for the remote device identified by the conn_id parameter.
+ * Remote version information will be returned by @ref app_gap_callback with cb_type @ref GAP_MSG_LE_READ_REMOTE_VERSION.
+ *
+ * @param[in] conn_id Connection ID
+ * @return Read request result.
+ * @retval GAP_CAUSE_SUCCESS: Send request success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED: Send request sent fail.
+ * @retval GAP_CAUSE_NON_CONN: Failed. No connection
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t conn_id = 0;
+ le_read_remote_version(conn_id);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type is %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_READ_REMOTE_VERSION:
+ APP_PRINT_INFO5("GAP_MSG_LE_READ_REMOTE_VERSION: conn_id %d, cause 0x%x, version 0x%x, manufacturer_name 0x%x, subversion 0x%x",
+ p_data->p_le_read_remote_version_rsp->conn_id,
+ p_data->p_le_read_remote_version_rsp->cause,
+ p_data->p_le_read_remote_version_rsp->version,
+ p_data->p_le_read_remote_version_rsp->manufacturer_name,
+ p_data->p_le_read_remote_version_rsp->subversion);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_read_remote_version(uint8_t conn_id);
+#endif
+
+/**
+ * @brief Read rssi value of the connection. RSSI value will be returned by
+ * @ref app_gap_callback with cb_type @ref GAP_MSG_LE_READ_RSSI.
+ *
+ * @param[in] conn_id Connection ID
+ * @return Read request result.
+ * @retval GAP_CAUSE_SUCCESS: Read request sent success.<BR>
+ * @retval GAP_CAUSE_NON_CONN: Read request sent fail.<BR>
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t conn_id = 0;
+ le_read_rssi(conn_id);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_READ_RSSI:
+ APP_PRINT_INFO3("GAP_MSG_LE_READ_RSSI: conn_id %d, cause 0x%x, rssi %d",
+ cb_data.p_le_read_rssi_rsp->conn_id,
+ cb_data.p_le_read_rssi_rsp->cause,
+ cb_data.p_le_read_rssi_rsp->rssi);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_read_rssi(uint8_t conn_id);
+
+#if F_BT_LE_READ_CHANN_MAP
+/**
+ * @brief Read the used channel map of the connection. Channel map value will be returned by
+ * @ref app_gap_callback with cb_type @ref GAP_MSG_LE_READ_CHANN_MAP.
+ *
+ * @param[in] conn_id Connection ID
+ * @return Read request result.
+ * @retval GAP_CAUSE_SUCCESS: Read request sent success.<BR>
+ * @retval GAP_CAUSE_NON_CONN: Read request sent fail.<BR>
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t conn_id = 0;
+ le_read_chann_map(conn_id);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_READ_CHANN_MAP:
+ APP_PRINT_INFO7("GAP_MSG_LE_READ_CHANN_MAP: conn_id %d, cause 0x%x, map[0x%x:0x%x:0x%x:0x%x:0x%x]",
+ cb_data.p_le_read_chann_map_rsp->conn_id,
+ cb_data.p_le_read_chann_map_rsp->cause,
+ cb_data.p_le_read_chann_map_rsp->channel_map[0],
+ cb_data.p_le_read_chann_map_rsp->channel_map[1],
+ cb_data.p_le_read_chann_map_rsp->channel_map[2],
+ cb_data.p_le_read_chann_map_rsp->channel_map[3],
+ cb_data.p_le_read_chann_map_rsp->channel_map[4]);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_read_chann_map(uint8_t conn_id);
+#endif
+
+#if F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT
+/**
+ * @brief Set the data length used in LL for data length extension. LE set data length response will be returned by
+ * @ref app_gap_callback with cb_type @ref GAP_MSG_LE_SET_DATA_LEN. And if data length was changed,
+ * @ref app_gap_callback with cb_type @ref GAP_MSG_LE_DATA_LEN_CHANGE_INFO will be called.
+ *
+ * @param[in] conn_id Connection ID
+ * @param[in] tx_octets Preferred maximum number of payload octets that the local Controller
+ * should include in a single Link Layer packet on this connection.
+ Range 0x001B-0x00FB (all other values reserved for future use)
+ * @param[in] tx_time Preferred maximum number of microseconds that the local Controller
+ should use to transmit a single Link Layer packet on this connection.
+ Range 0x0148-0x4290 (all other values reserved for future use)
+ * @return result.
+ * @retval GAP_CAUSE_SUCCESS: Set request sent success.<BR>
+ * @retval GAP_CAUSE_NON_CONN: Set request sent fail.<BR>
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t conn_id = 0;
+ uint16_t tx_octets = 251;
+ uint16_t tx_time = 2120;
+ le_set_data_len(conn_id, tx_octets, tx_time);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_SET_DATA_LEN:
+ APP_PRINT_INFO2("GAP_MSG_LE_SET_DATA_LEN: conn_id %d, cause 0x%x",
+ cb_data.p_le_set_data_len_rsp->conn_id,
+ cb_data.p_le_set_data_len_rsp->cause);
+ break;
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO5("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, max_tx_octets 0x%x, max_tx_time 0x%x,
+ max_rx_octets 0x%x, max_rx_time 0x%x",
+ cb_data.p_le_data_len_change_info->conn_id,
+ cb_data.p_le_data_len_change_info->max_tx_octets,
+ cb_data.p_le_data_len_change_info->max_tx_time,
+ cb_data.p_le_data_len_change_info->max_rx_octets,
+ cb_data.p_le_data_len_change_info->max_rx_time);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_set_data_len(uint8_t conn_id, uint16_t tx_octets, uint16_t tx_time);
+#endif
+
+#if F_BT_LE_5_0_SET_PHYS_SUPPORT
+/**
+ * @brief Set the PHY preferences for the connection identified by the Connection_Handle.
+ * The Controller might not be able to make the change (e.g. because the peer does
+ * not support the requested PHY) or may decide that the current PHY is preferable.
+ * If the phy used was changed, @ref app_gap_callback with cb_type @ref GAP_MSG_LE_PHY_UPDATE_INFO will be called.
+ *
+ * @param[in] conn_id Connection ID
+ * @param[in] all_phys A bit field that allows the Host to specify, for each direction,
+ * whether it has no preference among the PHYs that the Controller
+ * supports in a given direction or whether it has specified particular PHYs that it
+ * prefers in the TX_PHYS or RX_PHYS parameter.
+ * @param[in] tx_phys A bit field that indicates the transmitter PHYs that
+ * the Host prefers the Controller to use. If the ALL_PHYS parameter specifies
+ * that the Host has no preference, the TX_PHYS parameter is ignored;
+ * otherwise at least one bit shall be set to 1.
+ * @param[in] rx_phys A bit field that indicates the receiver PHYs that the
+ * Host prefers the Controller to use. If the ALL_PHYS parameter specifies that
+ * the Host has no preference, the RX_PHYS parameter is ignored; otherwise at
+ * least one bit shall be set to 1.
+ * @param[in] phy_options A bit field that allows the Host to specify options
+ * for PHYs. The default value for a new connection shall be all zero bits. The
+ * Controller may override any preferred coding for transmitting on the LE Coded
+ * PHY.
+ * @return result.
+ * @retval GAP_CAUSE_SUCCESS: Set request sent success.<BR>
+ * @retval GAP_CAUSE_NON_CONN: Set request sent fail.<BR>
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t conn_id = 0;
+ uint8_t all_phys = GAP_PHYS_NO_PREFER_TX_BIT;
+ uint8_t tx_phys = GAP_PHYS_PREFER_CODED_BIT;
+ uint8_t rx_phys = GAP_PHYS_PREFER_CODED_BIT;
+ uint16_t phy_options = GAP_PHYS_OPTIONS_CODED_PREFER_S8;
+ le_set_phy(conn_id, all_phys, tx_phys, rx_phys, phy_options);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_PHY_UPDATE_INFO:
+ APP_PRINT_INFO4("GAP_MSG_LE_PHY_UPDATE_INFO:conn %d, cause 0x%x, rx_phy %d, tx_phy %d",
+ cb_data.p_le_phy_update_info->conn_id,
+ cb_data.p_le_phy_update_info->cause,
+ cb_data.p_le_phy_update_info->rx_phy,
+ cb_data.p_le_phy_update_info->tx_phy);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_set_phy(uint8_t conn_id, uint8_t all_phys, uint8_t tx_phys, uint8_t rx_phys,
+ T_GAP_PHYS_OPTIONS phy_options);
+#endif
+
+/**
+ * @brief Disable the slave latency used in slave role. LE disable slave latency response will be returned by
+ * @ref app_gap_callback with cb_type @ref GAP_MSG_LE_DISABLE_SLAVE_LATENCY.
+ *
+ * NOTE: When slave latency is not 0, and user disable slave latency, the slave will listen to pkts in
+ * every connection interval.
+ *
+ * @param[in] conn_id Connection ID
+ * @param[in] disable Disable/enable slave latency
+ * \arg \c true disable slave latency
+ * \arg \c false enable slave latency
+ * @return result.
+ * @retval GAP_CAUSE_SUCCESS: Set request sent success.<BR>
+ * @retval GAP_CAUSE_NON_CONN: Set request sent fail.<BR>
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t conn_id = 0;
+ bool disable = true;
+ le_disable_slave_latency(conn_id);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_DISABLE_SLAVE_LATENCY:
+ APP_PRINT_INFO1("GAP_MSG_LE_DISABLE_SLAVE_LATENCY: cause 0x%x",
+ cb_data.p_le_disable_slave_latency_rsp->cause);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_disable_slave_latency(uint8_t conn_id, bool disable);
+
+/**
+ * @brief Update instant passed channel map. LE update passed channel map response will be returned by
+ * @ref app_gap_callback with cb_type @ref GAP_MSG_LE_UPDATE_PASSED_CHANN_MAP.
+ *
+ * When this feature is enabled, if we receive a instant passed channel map req, we will not disconnect
+ * the link.
+ *
+ * @param[in] enable Enable/disable instant update passed channel map feature.
+ * \arg \c true enable instant update passed channel map feature
+ * \arg \c false disable instant update passed channel map feature
+ * @return result.
+ * @retval GAP_CAUSE_SUCCESS Send request success
+ * @retval GAP_CAUSE_NON_CONN Failed. No connection
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ bool enable = true;
+ le_update_passed_chann_map(enable);
+ }
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_UPDATE_PASSED_CHANN_MAP:
+ APP_PRINT_INFO1("GAP_MSG_LE_UPDATE_PASSED_CHANN_MAP:cause 0x%x",
+ cb_data.p_le_update_passed_chann_map_rsp->cause);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_update_passed_chann_map(bool enable);
+
+#if F_BT_LE_GAP_CENTRAL_SUPPORT
+/**
+ * @brief Set connection parameter.
+ *
+ * App can call this api to modify connection interval, latency and supervision timeout value.
+ *
+ * @param[in] type Connection ID for this link.
+ * @param[in] p_conn_param Connection parameters @ref T_GAP_LE_CONN_REQ_PARAM.
+ * @return result.
+ * @retval GAP_CAUSE_SUCCESS Send request success
+ * @retval GAP_CAUSE_NON_CONN Failed. No connection
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ T_GAP_LE_CONN_REQ_PARAM conn_req_param;
+ T_GAP_REMOTE_ADDR_TYPE bd_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t bd_addr[BD_ADDR_SIZE] = {0x00, 0xe0, x04c, 0x23, 0x99, 0x87};
+ conn_req_param.scan_interval = 0x10;
+ conn_req_param.scan_window = 0x10;
+ conn_req_param.conn_interval_min = 80;
+ conn_req_param.conn_interval_max = 80;
+ conn_req_param.conn_latency = 0;
+ conn_req_param.supv_tout = 1000;
+ conn_req_param.ce_len_min = 2 * (conn_req_param.conn_interval_min - 1);
+ conn_req_param.ce_len_max = 2 * (conn_req_param.conn_interval_max - 1);
+ le_set_conn_param(GAP_CONN_PARAM_1M, &conn_req_param);
+
+ le_connect(0, bd_addr,
+ bd_type,
+ GAP_LOCAL_ADDR_LE_PUBLIC,
+ 1000);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_set_conn_param(T_GAP_CONN_PARAM_TYPE type,
+ T_GAP_LE_CONN_REQ_PARAM *p_conn_param);
+
+/**
+ * @brief Create a connection to a connectable advertiser. @ref le_set_conn_param shall be called first to set connection parameters.
+ *
+ * @param[in] init_phys The PHY(s) on which the advertising packets should be received on the primary advertising channel and the PHYs
+ * for which connection parameters have been specified.
+ * @param[in] remote_bd The Peer's Public Device Address, Random (static) Device Address, Non-Resolvable Private Address, or
+ Resolvable Private Address depending on the Peer_Address_Type parameter.
+ * @param[in] remote_bd_type The type of address used in the connectable advertisement sent by the peer.
+ * @param[in] local_bd_type The type of address being used in the connection request packets.
+ * @param[in] scan_timeout Scan timeout value.
+ * @return result.
+ * @retval GAP_CAUSE_SUCCESS Send request success
+ * @retval GAP_CAUSE_NON_CONN Failed. No connection
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ T_GAP_LE_CONN_REQ_PARAM conn_req_param;
+ T_GAP_REMOTE_ADDR_TYPE bd_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t bd_addr[BD_ADDR_SIZE] = {0x00, 0xe0, x04c, 0x23, 0x99, 0x87};
+ conn_req_param.scan_interval = 0x10;
+ conn_req_param.scan_window = 0x10;
+ conn_req_param.conn_interval_min = 80;
+ conn_req_param.conn_interval_max = 80;
+ conn_req_param.conn_latency = 0;
+ conn_req_param.supv_tout = 1000;
+ conn_req_param.ce_len_min = 2 * (conn_req_param.conn_interval_min - 1);
+ conn_req_param.ce_len_max = 2 * (conn_req_param.conn_interval_max - 1);
+ le_set_conn_param(GAP_CONN_PARAM_1M, &conn_req_param);
+
+ le_connect(0, bd_addr,
+ bd_type,
+ GAP_LOCAL_ADDR_LE_PUBLIC,
+ 1000);
+ }
+
+ void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+ {
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+ }
+
+ //When link is connected, stack will read remote used feaures, and the result will be notified by msg GAP_MSG_LE_REMOTE_FEATS_INFO
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_REMOTE_FEATS_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_REMOTE_FEATS_INFO: conn id %d, cause 0x%x, remote_feats %b",
+ cb_data.p_le_remote_feats_info->conn_id,
+ cb_data.p_le_remote_feats_info->cause,
+ TRACE_BINARY(8, cb_data.p_le_remote_feats_info->remote_feats));
+ break;
+ }
+ ...
+ }
+ *
+ * \endcode
+ */
+T_GAP_CAUSE le_connect(uint8_t init_phys, uint8_t *remote_bd,
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type,
+ T_GAP_LOCAL_ADDR_TYPE local_bd_type, uint16_t scan_timeout);
+#endif
+/**
+ * @brief Send connection parameter update request msg to bt stack. Connection parameter update result will be returned
+ * by @ref app_handle_conn_param_update_evt.
+ *
+ * App can call this api to modify connection interval, latency and supervision timeout value.
+ *
+ * @param[in] conn_id Connection ID for this link.
+ * @param[in] conn_interval_min Value range: 0x0006 - 0x0C80 (7.5ms - 4000ms, 1.25ms/step).
+ * @param[in] conn_interval_max Value range: 0x0006 - 0x0C80 (7.5ms - 4000ms, 1.25ms/step).
+ * @param[in] conn_latency Value range: 0x0000 - 0x01F3
+ This shall be less than or equal to (((supervision_timeout * 10ms) / (conn_interval_max * 1.25ms * 2)) - 1).
+ * @param[in] supervision_timeout Value range: 0x000A - 0x0C80 (100ms - 32000ms, 10ms/step).
+ * @param[in] ce_length_min Value range: 0x0006 - 0x0C80 (7.5ms - 4000ms, 1.25ms/step).
+ * @param[in] ce_length_max Value range: 0x0006 - 0x0C80 (7.5ms - 4000ms, 1.25ms/step).
+ * @return result.
+ * @retval GAP_CAUSE_SUCCESS Send request success.
+ * @retval GAP_CAUSE_NON_CONN Failed. No connection.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t conn_id = 0;
+ T_GAP_CAUSE cause;
+ uint16_t conn_interval_min = 0x10;
+ uint16_t conn_interval_max = 0x10;
+ uint16_t conn_latency = 50;
+ uint16_t supervision_timeout = 1000;
+ uint16_t ce_length_min = 2 * (conn_interval_min - 1);
+ uint16_t ce_length_max = 2 * (conn_interval_max - 1);
+
+
+ cause = le_update_conn_param(conn_id,
+ conn_interval_min,
+ conn_interval_max,
+ conn_latency,
+ supervision_timeout,
+ ce_length_min,
+ ce_length_max
+ );
+
+ }
+
+ void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+ {
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+
+ //If app receive connection parameter update request from remote device, app will receive GAP_MSG_LE_CONN_UPDATE_IND
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_CONN_UPDATE_IND:
+ APP_PRINT_INFO4("GAP_MSG_LE_CONN_UPDATE_IND: conn_interval_max 0x%x, conn_interval_min 0x%x, conn_latency 0x%x
+ , supervision_timeout 0x%x",
+ cb_data.p_le_conn_update_ind->conn_interval_max,
+ cb_data.p_le_conn_update_ind->conn_interval_min,
+ cb_data.p_le_conn_update_ind->conn_latency,
+ cb_data.p_le_conn_update_ind->supervision_timeout);
+ if (cb_data.p_le_conn_update_ind->conn_latency > 60)
+ {
+ result = APP_RESULT_REJECT;
+ }
+ else
+ {
+ result = APP_RESULT_ACCEPT;
+ }
+ break;
+ ...
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_update_conn_param(uint8_t conn_id,
+ uint16_t conn_interval_min,
+ uint16_t conn_interval_max,
+ uint16_t conn_latency,
+ uint16_t supervision_timeout,
+ uint16_t ce_length_min,
+ uint16_t ce_length_max);
+
+/**
+ * @brief Set the link tx power for the device.
+ *
+ * Set LE link tx power. Or reset link tx power to default value.
+ * Tx power is set to default every time a link is connect. Use this command
+ * after the link is connected.
+ *
+ * @param[in] conn_id Connection ID for this link.
+ * @param[in] reset Whether to reset to default value.
+ * @param[in] tx_power index for power level. NOTE: The following tx power table may be changed in future version.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ T_GAP_CAUSE cause;
+ uint8_t conn_id = 0;
+ bool reset = false;
+ uint8_t tx_pwr = 0x80;
+
+ cause = le_set_conn_tx_power(conn_id, reset, tx_pwr);
+
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: msgType = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_SET_CONN_TX_PWR:
+ APP_PRINT_INFO1("GAP_MSG_LE_SET_CONN_TX_PWR: cause 0x%x",
+ p_data->le_cause.cause);
+ break;
+ ...
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_set_conn_tx_power(uint8_t conn_id, bool reset, uint8_t tx_power);
+/** @} */ /* End of group GAP_CONNECTION_COMMON_EXPORT_Functions */
+/** @} */ /* End of group GAP_LE_CONNECTION_MODULE */
+
+
+/*-------------------------------------------------------------------
+-------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_CONN_LE_H */
+
+
diff --git a/inc/bluetooth/gap/gap_credit_based_conn.h b/inc/bluetooth/gap/gap_credit_based_conn.h
new file mode 100644
index 0000000..ce1828d
--- /dev/null
+++ b/inc/bluetooth/gap/gap_credit_based_conn.h
@@ -0,0 +1,155 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file gap_credit_based_conn.h
+* @brief header file of LE Credit-Based Connection message handle.
+* @details none.
+* @author Tifnan
+* @date 2016-03-16
+* @version v0.1
+*********************************************************************************************************
+*/
+
+#ifndef _LE_CREDIT_BASED_CONN_H_
+#define _LE_CREDIT_BASED_CONN_H_
+
+#include "upperstack_config.h"
+#include "gap_le.h"
+#include "gap.h"
+
+#if F_BT_LE_4_1_COC_SUPPORT
+
+/** @addtogroup GAP GAP Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE GAP LE Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE_CREDIT_BASED_CONN GAP LE Credit Based Connection Module
+ * @{
+ */
+typedef enum
+{
+ GAP_CHANN_STATE_DISCONNECTED, //!< Disconnected.
+ GAP_CHANN_STATE_CONNECTING, //!< Connecting.
+ GAP_CHANN_STATE_CONNECTED, //!< Connected.
+ GAP_CHANN_STATE_DISCONNECTING //!< Disconnecting.
+} T_GAP_CHANN_STATE;
+
+typedef enum
+{
+ COC_PARAM_CREDITS_THRESHOLD = 0x400,
+ COC_PARAM_LOCAL_MTU = 0x401,
+} T_LE_COC_PARAM_TYPE;
+
+typedef enum
+{
+ COC_CHANN_PARAM_CUR_CREDITS = 0x410,
+ COC_CHANN_PARAM_MAX_CREDITS = 0x411,
+ COC_CHANN_PARAM_MTU = 0x412,
+} T_LE_COC_CHANN_PARAM_TYPE;
+
+/** @brief Definition of LE security requirement*/
+typedef enum
+{
+ LE_COC_SECURITY_NONE, /**< Security None */
+ LE_COC_SECURITY_UNAUTHEN_ENCRYPT, /**< Security unauthenticated encryption */
+ LE_COC_SECURITY_AUTHEN_ENCRYPT, /**< Security authenticated encryption */
+ LE_COC_SECURITY_UNAUTHEN_DATA_SIGN,/**< Security unauthenticated data signed */
+ LE_COC_SECURITY_AUTHEN_DATA_SIGN, /**< Security authenticated data signed */
+ LE_COC_SECURITY_AUTHOR /**< Security authorized */
+} T_LE_COC_SECURITY_MODE;
+
+typedef struct
+{
+ uint8_t conn_id; /**< local link ID. */
+ uint16_t cid; /**< channel ID */
+ uint16_t value_len; /**< value length */
+ uint8_t *p_data;
+} T_LE_COC_RECEIVE_DATA;
+
+typedef struct
+{
+ uint8_t conn_id; /**< local link ID. */
+ uint16_t cid; /**< channel ID */
+ uint16_t cause; /**< value length */
+ uint8_t credit;
+} T_LE_COC_SEND_DATA;
+
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cid;
+ T_GAP_CHANN_STATE conn_state;
+ uint16_t cause;
+} T_LE_COC_CHANN_STATE;
+
+/** @brief Response of le credit based security register request.*/
+typedef struct
+{
+ uint16_t cause;
+} T_LE_COC_CREDIT_BASED_SECURITY_REG_RSP;
+
+/** @brief Response of le credit based psm register request.*/
+typedef struct
+{
+ uint16_t le_psm;
+ uint16_t cause;
+} T_LE_COC_CREDIT_BASED_PSM_REG_RSP;
+
+#define GAP_COC_MSG_LE_CHANN_STATE 0x01
+#define GAP_COC_MSG_LE_REG_PSM 0x02
+#define GAP_COC_MSG_LE_SET_PSM_SECURITY 0x03
+#define GAP_COC_MSG_LE_SEND_DATA 0x04
+#define GAP_COC_MSG_LE_RECEIVE_DATA 0x05
+
+typedef union
+{
+ T_LE_COC_CHANN_STATE *p_le_chann_state;
+ T_LE_COC_RECEIVE_DATA *p_le_receive_data;
+ T_LE_COC_SEND_DATA *p_le_send_data;
+ T_LE_COC_CREDIT_BASED_SECURITY_REG_RSP *p_le_set_psm_security_rsp;
+ T_LE_COC_CREDIT_BASED_PSM_REG_RSP *p_le_reg_psm_rsp;
+} T_LE_COC_DATA;
+
+typedef T_APP_RESULT(*P_FUN_LE_COC_APP_CB)(uint8_t coc_type, void *p_coc_data);
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup GAP_LE_CREDIT_BASED_CONN_Exported_Functions GAP LE Credit Based Connection Exported Functions
+ * @brief
+ * @{
+ */
+bool le_coc_init(uint8_t chann_num);
+void le_coc_register_app_cb(P_FUN_LE_COC_APP_CB app_callback);
+T_GAP_CAUSE le_coc_set_param(T_LE_COC_PARAM_TYPE param, uint8_t len, void *p_value);
+T_GAP_CAUSE le_coc_get_chann_param(T_LE_COC_CHANN_PARAM_TYPE param, void *p_value, uint16_t cid);
+T_GAP_CAUSE le_coc_create(uint8_t conn_id, uint16_t le_psm);
+T_GAP_CAUSE le_coc_disc(uint16_t cid);
+T_GAP_CAUSE le_coc_send_data(uint16_t cid, uint8_t *p_data, uint16_t data_len);
+T_GAP_CAUSE le_coc_reg_psm(uint16_t le_psm, uint8_t action);
+T_GAP_CAUSE le_coc_set_psm_security(uint16_t le_psm, bool active, T_LE_COC_SECURITY_MODE mode,
+ uint8_t key_size);
+/** End of GAP_LE_CREDIT_BASED_CONN_Exported_Functions
+ * @}
+ */
+
+/** End of GAP_LE_CREDIT_BASED_CONN
+ * @}
+ */
+
+/** End of GAP_LE
+ * @}
+ */
+
+/** End of GAP
+ * @}
+ */
+#endif
+
+
+
+#endif /* _LE_CREDIT_BASED_CONN_H_ */
diff --git a/inc/bluetooth/gap/gap_dtm.h b/inc/bluetooth/gap/gap_dtm.h
new file mode 100644
index 0000000..e1b489e
--- /dev/null
+++ b/inc/bluetooth/gap/gap_dtm.h
@@ -0,0 +1,560 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gap_dtm.h
+ * @brief
+ * @details
+ * @author jeff_zheng
+ * @date 2017-08-02
+ * @version v1.0
+ ******************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ ******************************************************************************
+ */
+/* Define to prevent recursive inclusion **/
+#ifndef GAP_DTM_H
+#define GAP_DTM_H
+
+#include "upperstack_config.h"
+#include "gap_le.h"
+#include <gap_le_types.h>
+
+#if F_BT_LE_4_0_DTM_SUPPORT
+/** @addtogroup GAP_LE_DTM GAP LE Direct Test Mode Module
+ * @brief GAP LE Direct Test Mode Module
+ * @{
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_DTM_Exported_Types GAP LE DTM Exported Types
+ * @brief
+ * @{
+ */
+typedef enum
+{
+ GAP_DTM_MODULATION_INDEX_STANDARD = 0x00, /**< Assume transmitter will have a standard modulation index. */
+ GAP_DTM_MODULATION_INDEX_STABLE = 0x01, /**< Assume transmitter will have a stable modulation index. */
+} T_GAP_DTM_MODULATION_INDEX_TYPE;
+
+typedef enum
+{
+ GAP_DTM_PACKET_PAYLOAD_PRBS9 = 0x00, /**< PRBS9 sequence '11111111100000111101' (in transmission order). */
+ GAP_DTM_PACKET_PAYLOAD_1100 = 0x01, /**< Repeated '11110000' (in transmission order) sequence. */
+ GAP_DTM_PACKET_PAYLOAD_10 = 0x02, /**< Repeated '10101010' (in transmission order) sequence. */
+ GAP_DTM_PACKET_PAYLOAD_PRBS15 = 0x03, /**< PRBS15 sequence. */
+ GAP_DTM_PACKET_PAYLOAD_ALL1 = 0x04, /**< Repeated '11111111' (in transmission order) sequence. . */
+ GAP_DTM_PACKET_PAYLOAD_ALL0 = 0x05, /**< Repeated '00000000' (in transmission order) sequence. . */
+ GAP_DTM_PACKET_PAYLOAD_0011 = 0x06, /**< Repeated '00001111' (in transmission order) sequence. . */
+ GAP_DTM_PACKET_PAYLOAD_01 = 0x07 /**< Repeated '01010101' (in transmission order) sequence. . */
+} T_GAP_DTM_PACKET_PAYLOAD_TYPE;
+
+typedef enum
+{
+ GAP_DTM_PHYS_1M = 0x01, /**< LE PHY 1M used. */
+ GAP_DTM_PHYS_2M = 0x02, /**< LE PHY 2M used. */
+ GAP_DTM_PHYS_CODED_S8 = 0x03, /**< LE Coded PHY with S=8 data coding. */
+ GAP_DTM_PHYS_CODED_S2 = 0x04, /**< LE Coded PHY with S=2 data coding. */
+} T_GAP_DTM_PHYS_TYPE;
+
+/** End of GAP_LE_DTM_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/** @defgroup GAP_LE_DTM_Exported_Functions GAP LE Direct Test Mode Exported Functions
+ * @brief GAP LE Direct Test Mode Exported Functions
+ * @{
+ */
+
+/**
+* @brief Start a test where the DUT receives test reference packets at a fixed interval.
+ The tester generates the test reference packets.
+*
+* @param[in] rx_chann - channel to receive packets.
+*
+* @retval GAP_CAUSE_SUCCESS: Operation success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ rx_chann = (command & 0x3f00) >> 8;
+ le_dtm_receiver_test_req(rx_chann);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_DTM_RECEIVER_TEST:
+ status = p_data->p_le_receive_test_rsp->cause;
+ if (status == 0)
+ {
+ APP_PRINT_INFO2("dtm_event_trace: ev = 0x%x, st = 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("dtm_evt_trace: EV = 0x%x, st = 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_dtm_receiver_test(uint8_t rx_chann);
+
+/**
+* @brief Start a test where the DUT generates test reference packets at a fixed interval.
+ The Controller shall transmit at maximum power.
+*
+* @param[in] tx_chann - channel to transmit packets.
+* @param[in] data_len - length in bytes of payload data in each packet.
+* @param[in] pkt_pl - the value of packet payload.
+*
+* @retval GAP_CAUSE_SUCCESS: Operation success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ tx_chann = (command & 0x3f00) >> 8;
+ data_len = up_2_bits << 6 | (command & 0xfc) >> 2;
+ pkt_pl = command & 0x03;
+ le_dtm_transmitter_test(tx_chann, data_len, pkt_pl);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_DTM_TRANSMITTER_TEST:
+ status = p_data->le_cause.cause;
+ if (status == 0)
+ {
+ APP_PRINT_INFO2("dtm_evt_trace: ev = 0x%x, st = 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("dtm_evt_trace: st = 0x%x, st = 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+
+T_GAP_CAUSE le_dtm_transmitter_test(uint8_t tx_chann, uint8_t data_len, uint8_t pkt_pl);
+
+/**
+* @brief Stop any test which is in progress.
+*
+* @retval GAP_CAUSE_SUCCESS: Operation success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ ...
+ le_dtm_test_end();
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_DTM_TEST_END:
+ status = p_data->p_le_dtm_test_end_rsp->cause;
+ if (status == 0)
+ {
+ event |= 1 << 15;
+ event |= p_data->p_le_dtm_test_end_rsp->num_pkts;
+ APP_PRINT_INFO2("dtm_evt_trace: ev = 0x%x, packet count = 0x%x", (event & 0x8000) >> 15,
+ event & 0x7fff);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("dtm_evt_trace: ev = 0x%x, st = 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_dtm_test_end(void);
+
+#if F_BT_LE_5_0_DTM_SUPPORT
+/**
+* @brief Start a test where the DUT receives test reference packets at a fixed interval.
+*
+* @param[in] rx_chann - channel to receive packets.
+* @param[in] phy - physical to receive packets.
+* @param[in] mod_idx - modulation index to receive packets.
+*
+* @retval GAP_CAUSE_SUCCESS: Operation success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ static uint8_t phy = 1;
+ static uint8_t mod_idx = 0;
+ rx_chann = (command & 0x3f00) >> 8;
+#if F_BT_LE_5_0_SUPPORT
+ if (le_dtm_enhanced_receiver_test(rx_chann, phy, mod_idx) != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR0("dtm_test_req: le_dtm_enhanced_receiver_test fail");
+ }
+#endif
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+#if F_BT_LE_5_0_SUPPORT
+ case GAP_MSG_LE_DTM_ENHANCED_RECEIVER_TEST:
+#endif
+ status = p_data->le_cause.cause;
+ if (status == 0)
+ {
+ APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_dtm_enhanced_receiver_test(uint8_t rx_chann, uint8_t phy, uint8_t mod_idx);
+
+/**
+* @brief Start a test where the DUT generates test reference packets at a fixed interval.
+*
+* @param[in] tx_chann - Channel to transmit packets.
+* @param[in] data_len - Length in bytes of payload data in each packet.
+* @param[in] pkt_pl - the value of packet payload.
+* @param[in] phy - physical to transmit packets.
+*
+* @retval GAP_CAUSE_SUCCESS: Operation success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ static uint8_t phy = 1;
+ tx_chann = (command & 0x3f00) >> 8;
+ data_len = up_2_bits << 6 | (command & 0xfc) >> 2;
+ pkt_pl = command & 0x03;;
+#if F_BT_LE_5_0_SUPPORT
+ if (le_dtm_enhanced_transmitter_test(tx_chann, data_len, pkt_pl, phy) != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR0("dtm_test_req: le_dtm_enhanced_transmitter_test fail");
+ }
+#endif
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+#if F_BT_LE_5_0_SUPPORT
+ case GAP_MSG_LE_DTM_ENHANCED_TRANSMITTER_TEST:
+#endif
+ status = p_data->le_cause.cause;
+ if (status == 0)
+ {
+ APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+
+ ...
+ }
+ * \endcode
+ */
+
+T_GAP_CAUSE le_dtm_enhanced_transmitter_test(uint8_t tx_chann, uint8_t data_len, uint8_t pkt_pl,
+ uint8_t phy);
+#endif
+
+#if F_BT_LE_5_1_DTM_SUPPORT
+/**
+* @brief Start a test where the DUT receives test reference packets at a fixed interval.
+*
+* @param[in] rx_chann - channel to receive packets.
+ Range: 0x00 to 0x27.
+* @param[in] phy - physical to receive packets: @ref T_GAP_PHYS_TYPE.
+* @param[in] modulation_index - modulation index to receive packets: @ref T_GAP_DTM_MODULATION_INDEX_TYPE.
+* @param[in] expected_cte_length - the expected length of the Constant Tone Extensions in received
+ test reference packets.
+ Range: 0x00 (No Constant Tone Extension expected (default)) or 0x02 to 0x14.
+ Units: 8 us.
+* @param[in] expected_cte_type - the expected type of the Constant Tone Extensions in received
+ test reference packets: @ref T_GAP_CTE_TYPE.
+* @param[in] slot_durations - modulation index to receive packets and shall be ignored when expected_cte_type
+ is not set to GAP_CTE_TYPE_AOA: @ref T_GAP_SLOT_DUATIONS_TYPE.
+* @param[in] switching_pattern_length - the number of Antenna IDs in the pattern and shall be ignored when
+ expected_cte_type is not set to GAP_CTE_TYPE_AOA.
+ Range: 0x02 to max_switching_pattern_length supported by controller
+ max_switching_pattern_length shall be less than or equal to 0x4B.
+* @param[in] p_antenna_ids - Antenna ID in the pattern and shall be ignored when expected_cte_type
+ is not set to GAP_CTE_TYPE_AOA.
+*
+* @retval GAP_CAUSE_SUCCESS: Send request success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ uint8_t rx_channel = 0;
+ T_GAP_PHYS_TYPE phy = GAP_PHYS_1M;
+ T_GAP_DTM_MODULATION_INDEX_TYPE modulation_index = GAP_DTM_MODULATION_INDEX_STANDARD;
+ uint8_t expected_cte_length = 2;
+ T_GAP_CTE_TYPE expected_cte_type = GAP_CTE_TYPE_AOA;
+ T_GAP_SLOT_DUATIONS_TYPE slot_durations = GAP_SLOT_DURATIONS_SWITCH_SAMPLE_1US;
+ uint8_t switching_pattern_length = 2;
+ uint8_t p_antenna_ids[2] = {0, 1};
+
+ le_dtm_receiver_test_v3(rx_channel, phy, modulation_index, expected_cte_length,
+ expected_cte_type, slot_durations,
+ switching_pattern_length, p_antenna_ids);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_DTM_RECEIVER_TEST_V3:
+ APP_PRINT_INFO1("GAP_MSG_LE_DTM_RECEIVER_TEST_V3: cause 0x%x",
+ p_data->le_cause.cause);
+ break;
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_dtm_receiver_test_v3(uint8_t rx_channel, T_GAP_PHYS_TYPE phy,
+ T_GAP_DTM_MODULATION_INDEX_TYPE modulation_index,
+ uint8_t expected_cte_length, T_GAP_CTE_TYPE expected_cte_type,
+ T_GAP_SLOT_DUATIONS_TYPE slot_durations,
+ uint8_t switching_pattern_length, uint8_t *p_antenna_ids);
+
+/**
+* @brief Start a test where the DUT transmits test reference packets at a fixed interval.
+*
+* @param[in] tx_channel - channel to transmit packets.
+ Range: 0x00 to 0x27.
+* @param[in] test_data_length - length in bytes of payload data in each packet.
+ Range: 0x00 to 0xFF.
+* @param[in] packet_payload - contents of the payload of the test reference packets:
+* @ref T_GAP_DTM_PACKET_PAYLOAD_TYPE.
+* @param[in] phy - physical to transmit packets: @ref T_GAP_DTM_PHYS_TYPE.
+* @param[in] cte_length - the length of the Constant Tone Extension in the test reference packets.
+ Range: 0x00 (Do not transmit a Constant Tone Extension) or 0x02 to 0x14.
+ Units: 8 us.
+* @param[in] cte_type - the type of the Constant Tone Extension in the test reference packets.
+ @ref T_GAP_CTE_TYPE.
+* @param[in] switching_pattern_length - the number of Antenna IDs in the pattern and shall be ignored when
+ cte_type is set to GAP_CTE_TYPE_AOA.
+ Range: 0x02 to max_switching_pattern_length supported by controller
+ max_switching_pattern_length shall be less than or equal to 0x4B.
+* @param[in] p_antenna_ids - Antenna ID in the pattern and shall be ignored when expected_cte_type
+* is set to GAP_CTE_TYPE_AOA.
+*
+* @retval GAP_CAUSE_SUCCESS: Send request success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ uint8_t tx_channel = 0;
+ uint8_t test_data_length = 2;
+ T_GAP_DTM_PACKET_PAYLOAD_TYPE packet_payload = GAP_DTM_PACKET_PAYLOAD_PRBS9;
+ T_GAP_DTM_PHYS_TYPE phy = GAP_DTM_PHYS_1M;
+ uint8_t cte_length = 2;
+ T_GAP_CTE_TYPE cte_type = GAP_CTE_TYPE_AOD_2US_SLOT;
+ uint8_t switching_pattern_length = 2;
+ uint8_t p_antenna_ids[2] = {0, 1};
+
+ le_dtm_transmitter_test_v3(tx_channel, test_data_length,
+ packet_payload, phy, cte_length, cte_type,
+ switching_pattern_length, p_antenna_ids);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_DTM_TRANSMITTER_TEST_V3:
+ APP_PRINT_INFO1("GAP_MSG_LE_DTM_TRANSMITTER_TEST_V3: cause 0x%x",
+ p_data->le_cause.cause);
+ break;
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_dtm_transmitter_test_v3(uint8_t tx_channel, uint8_t test_data_length,
+ T_GAP_DTM_PACKET_PAYLOAD_TYPE packet_payload, T_GAP_DTM_PHYS_TYPE phy,
+ uint8_t cte_length, T_GAP_CTE_TYPE cte_type,
+ uint8_t switching_pattern_length, uint8_t *p_antenna_ids);
+#endif
+
+#if F_BT_LE_5_2_DTM_SUPPORT
+/**
+* @brief Start a test where the DUT transmits test reference packets at a fixed interval.
+*
+* @param[in] tx_channel - channel to transmit packets.
+ N = (F-2402) / 2
+ Range: 0x00 to 0x27
+ Frequency Range: 2402 MHz to 2480 MHz.
+* @param[in] test_data_length - length in bytes of payload data in each packet.
+ Range: 0x00 to 0xFF.
+* @param[in] packet_payload - contents of the payload of the test reference packets:
+* @ref T_GAP_DTM_PACKET_PAYLOAD_TYPE.
+* @param[in] phy - physical to transmit packets: @ref T_GAP_DTM_PHYS_TYPE.
+* @param[in] cte_length - the length of the Constant Tone Extension in the test reference packets.
+ 0x00: Do not transmit a Constant Tone Extension
+ 0x02 to 0x14: Length of the Constant Tone Extension in 8 us units.
+* @param[in] cte_type - the type of the Constant Tone Extension in the test reference packets.
+ @ref T_GAP_CTE_TYPE.
+* @param[in] switching_pattern_length - the number of Antenna IDs in the pattern and shall be ignored when
+ cte_type is set to GAP_CTE_TYPE_AOA.
+ Range: 0x02 to max_switching_pattern_length supported by controller
+ max_switching_pattern_length shall be less than or equal to 0x4B.
+* @param[in] p_antenna_ids - Antenna ID in the pattern and shall be ignored when expected_cte_type
+* is set to GAP_CTE_TYPE_AOA.
+* @param[in] tx_power_level - set transmitter to the specified or the nearest transmit power level.
+ Range: -127 to +20.
+ Units: dBm.
+ Note: 0x7E Set transmitter to minimum transmit power level.
+ 0x7F Set transmitter to maximum transmit power level.
+*
+* @retval GAP_CAUSE_SUCCESS: Send request success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ uint8_t tx_channel = 0;
+ uint8_t test_data_length = 2;
+ T_GAP_DTM_PACKET_PAYLOAD_TYPE packet_payload = GAP_DTM_PACKET_PAYLOAD_PRBS9;
+ T_GAP_DTM_PHYS_TYPE phy = GAP_DTM_PHYS_1M;
+ uint8_t cte_length = 2;
+ T_GAP_CTE_TYPE cte_type = GAP_CTE_TYPE_AOD_2US_SLOT;
+ uint8_t switching_pattern_length = 2;
+ uint8_t p_antenna_ids[2] = {0, 1};
+ int8_t tx_power_level = 0x10;
+
+ le_dtm_transmitter_test_v3(tx_channel, test_data_length,
+ packet_payload, phy, cte_length, cte_type,
+ switching_pattern_length, p_antenna_ids, tx_power_level);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_DTM_TRANSMITTER_TEST_V4:
+ APP_PRINT_INFO1("GAP_MSG_LE_DTM_TRANSMITTER_TEST_V4: cause 0x%x",
+ p_data->le_cause.cause);
+ break;
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_dtm_transmitter_test_v4(uint8_t tx_channel, uint8_t test_data_length,
+ T_GAP_DTM_PACKET_PAYLOAD_TYPE packet_payload, T_GAP_DTM_PHYS_TYPE phy,
+ uint8_t cte_length, T_GAP_CTE_TYPE cte_type,
+ uint8_t switching_pattern_length, uint8_t *p_antenna_ids, int8_t tx_power_level);
+#endif
+/** End of GAP_LE_DTM_Exported_Functions
+ * @}
+ */
+
+/** End of GAP_LE_DTM
+ * @}
+ */
+#endif
+
+#endif /* GAP_DTM_H */
diff --git a/inc/bluetooth/gap/gap_ext_adv.h b/inc/bluetooth/gap/gap_ext_adv.h
new file mode 100644
index 0000000..2603645
--- /dev/null
+++ b/inc/bluetooth/gap/gap_ext_adv.h
@@ -0,0 +1,857 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_ext_adv.h
+* @brief Header file for Gap ext adv
+* @details This file defines extended advertising related API.
+* @author ranhui
+* @date 2016-02-18
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_EXT_ADV_H
+#define GAP_EXT_ADV_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#include "gap_le.h"
+
+#if F_BT_LE_5_0_AE_ADV_SUPPORT
+
+/** @addtogroup GAP GAP Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE GAP LE Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE_EXTENDED_ADV GAP LE Extended Adv Module
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GAP_LE_EXTENDED_ADV_Exported_Macros GAP LE Extended Adv Exported Macros
+ * @{
+ */
+
+/** @defgroup EXT_ADV_PARAM Extended Advertising Parameter flag
+ * @brief Use the combination of macro definitions to set extended advertising related parameters
+ for a specified advertising set by calling @ref le_ext_adv_start_setting.
+ * @{
+ */
+#define EXT_ADV_SET_AUTO 0x00 /**< Automatically set extended advertising related parameters (including advertising parameters,
+ advertising data and scan response data) according to advertising event properties. */
+#define EXT_ADV_SET_ADV_PARAS 0x01 /**< Set advertising parameters supplied by @ref le_ext_adv_set_adv_param. */
+#define EXT_ADV_SET_ADV_DATA 0x02 /**< Set advertising data supplied by @ref le_ext_adv_set_adv_data. */
+#define EXT_ADV_SET_SCAN_RSP_DATA 0x04 /**< Set scan response data supplied by @ref le_ext_adv_set_scan_response_data. */
+#define EXT_ADV_SET_RANDOM_ADDR 0x08 /**< Set random address supplied by @ref le_ext_adv_set_random. */
+/** End of EXT_ADV_PARAM
+ * @}
+ */
+
+/** @defgroup EXT_ADV_EVT_PROP Extended Advertising Event Properties flag
+ * @brief Use the combination of macro definitions to describe the type of advertising event.
+ Optional values: @ref T_LE_EXT_ADV_LEGACY_ADV_PROPERTY and @ref T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY.
+ * @{
+ */
+#define GAP_EXT_ADV_EVT_PROP_CONNECTABLE_ADV 0x01 /**< Connectable advertising. */
+#define GAP_EXT_ADV_EVT_PROP_SCANNABLE_ADV 0x02 /**< Scannable advertising. */
+#define GAP_EXT_ADV_EVT_PROP_DIRECTED_ADV 0x04 /**< Directed advertising. */
+#define GAP_EXT_ADV_EVT_PROP_HDC_DIRECTED_ADV 0x08 /**< High Duty Cycle Directed Connectable advertising. */
+#define GAP_EXT_ADV_EVT_PROP_USE_LEGACY_ADV 0x10 /**< Use legacy advertising PDUs. */
+#define GAP_EXT_ADV_EVT_PROP_OMIT_ADV_ADDR 0x20 /**< Omit advertiser's address from all PDUs ("anonymous advertising"). */
+#define GAP_EXT_ADV_EVT_PROP_INCLUDE_TX_POWER 0x40 /**< Include TxPower in the extended header of the advertising PDU. */
+/** End of EXT_ADV_EVT_PROP
+ * @}
+ */
+
+#define GAP_MAX_LEGACY_ADV_LEN 31
+
+#define GAP_INVALID_ADV_HANDLE 0xFF
+/** End of GAP_LE_EXTENDED_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_EXTENDED_ADV_Exported_Types GAP LE Extended Adv Exported Types
+ * @{
+ */
+
+/** @brief GAP extended advertising state. */
+typedef enum
+{
+ EXT_ADV_STATE_IDLE, /**< Idle, no advertising. */
+ EXT_ADV_STATE_START, /**< Start Advertising. A temporary state, haven't received the result. */
+ EXT_ADV_STATE_ADVERTISING, /**< Advertising. */
+ EXT_ADV_STATE_STOP, /**< Stop Advertising. A temporary state, haven't received the result. */
+} T_GAP_EXT_ADV_STATE;
+
+/** @brief Advertising Event Properties values for legacy advertising PDUs. */
+typedef enum
+{
+ LE_EXT_ADV_LEGACY_ADV_CONN_SCAN_UNDIRECTED = 0x13, /**< Connectable and scannable undirected. Advertising data or scan response data shall not exceed 31 bytes. */
+ LE_EXT_ADV_LEGACY_ADV_CONN_LOW_DUTY_DIRECTED = 0x15, /**< Connectable directed (low duty cycle). */
+ LE_EXT_ADV_LEGACY_ADV_CONN_HIGH_DUTY_DIRECTED = 0x1D, /**< Connectable directed (high duty cycle). */
+ LE_EXT_ADV_LEGACY_ADV_SCAN_UNDIRECTED = 0x12, /**< Scannable undirected. Advertising data or scan response data shall not exceed 31 bytes. */
+ LE_EXT_ADV_LEGACY_ADV_NON_SCAN_NON_CONN_UNDIRECTED = 0x10, /**< Non-connectable and non-scannable undirected. Advertising data shall not exceed 31 bytes. */
+} T_LE_EXT_ADV_LEGACY_ADV_PROPERTY;
+
+/** @brief Advertising Event Properties values for extended advertising PDUs. */
+typedef enum
+{
+ LE_EXT_ADV_EXTENDED_ADV_NON_SCAN_NON_CONN_UNDIRECTED = 0x00, /**< Non-connectable and non-scannable undirected. If only one advertising set is used, advertising data shall not exceed 1024 bytes. */
+ LE_EXT_ADV_EXTENDED_ADV_NON_SCAN_NON_CONN_DIRECTED = 0x04, /**< Non-connectable and non-scannable directed. If only one advertising set is used, advertising data shall not exceed 1024 bytes. */
+ LE_EXT_ADV_EXTENDED_ADV_CONN_UNDIRECTED = 0x01, /**< Connectable undirected. Advertising data shall not exceed 245 bytes. */
+ LE_EXT_ADV_EXTENDED_ADV_CONN_DIRECTED = 0x05, /**< Connectable directed. Advertising data shall not exceed 239 bytes. */
+ LE_EXT_ADV_EXTENDED_ADV_SCAN_UNDIRECTED = 0x02, /**< Scannable undirected. If only one advertising set is used, scan response data shall not exceed 991 bytes. */
+ LE_EXT_ADV_EXTENDED_ADV_SCAN_DIRECTED = 0x06, /**< Scannable directed. If only one advertising set is used, scan response data shall not exceed 991 bytes. */
+} T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY;
+
+/** @brief Supported advertising parameters type. */
+typedef enum
+{
+ GAP_PARAM_EXT_ADV_MAX_DATA_LEN = 0x330, /**< Maximum length of supported data for use as advertisement data or scan
+ response data. Read only. Size is 2 bytes. */
+ GAP_PARAM_EXT_ADV_MAX_SETS = 0x331, /**< Maximum number of supported advertising sets. Read only. Size is 1 byte. */
+} T_LE_EXT_ADV_PARAM_TYPE;
+
+/** End of GAP_LE_EXTENDED_ADV_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup GAP_LE_EXTENDED_ADV_Exported_Functions GAP LE Extended Adv Exported Functions
+ * @brief
+ * @{
+ */
+/**
+ * @brief Initialization the number of advertising sets.
+ *
+ * @param[in] adv_set_num Advertising sets number, range: 1 - 10.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_INVALID_PARAM Operation failure, invalid parameter.
+ * @retval GAP_CAUSE_NO_RESOURCE Operation failure, memory acquisition failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ le_ext_adv_init(6);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_adv_init(uint8_t adv_set_num);
+
+/**
+ * @brief Get a GAP extended advertising parameter.
+ *
+ * NOTE: You can call this function with a extended advertising parameter type and it will get a
+ * extended advertising parameter. Extended advertising parameters are defined in @ref T_LE_EXT_ADV_PARAM_TYPE.
+ *
+ * @param[in] param Advertising parameter type: @ref T_LE_EXT_ADV_PARAM_TYPE
+ * @param[in,out] p_value Pointer to the location to get the parameter value. This is dependent on
+ * the parameter type and will be cast to the appropriate data type (For example:
+ * if data type of param is uint16_t, p_value will be cast to pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_INVALID_PARAM Operation failure, invalid parameter.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint16_t max_adv_data_len;
+ le_ext_adv_get_param(GAP_PARAM_EXT_ADV_MAX_DATA_LEN, &max_adv_data_len);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_adv_get_param(T_LE_EXT_ADV_PARAM_TYPE param, void *p_value);
+
+/**
+ * @brief Create an advertising handle which is used to identify an advertising set.
+ *
+ * @return Advertising handle.
+ * @retval 0x00-0xFE Operation success.
+ * @retval 0xFF Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t adv_handle;
+ adv_handle = le_ext_adv_create_adv_handle();
+ }
+ * \endcode
+ */
+uint8_t le_ext_adv_create_adv_handle(void);
+
+/**
+ * @brief Get the connection ID from the adv handle.
+ *
+ * If the advertising ends because a connection was created,
+ * application can call le_ext_adv_get_conn_id_by_adv_handle() to get the connection ID
+ * when the advertising set state switches to EXT_ADV_STATE_IDLE.
+ *
+ * @param[in] adv_handle Identify an advertising set, which is assigned by @ref le_ext_adv_create_adv_handle.
+ * @return Connection ID.
+ * @retval 0-0xFE Operation success.
+ * @retval 0xFF Operation failure, Get connection ID failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t conn_id;
+ conn_id = le_ext_adv_get_conn_id_by_adv_handle(adv_handle);
+ }
+ * \endcode
+ */
+uint8_t le_ext_adv_get_conn_id_by_adv_handle(uint8_t adv_handle);
+
+/**
+ * @brief Get adv handle from connection ID.
+ *
+ * If the advertising ends because a connection was created,
+ * application can call le_ext_adv_get_adv_handle_by_conn_id() to get the adverting handle information
+ * when the advertising set state switches to EXT_ADV_STATE_IDLE.
+ *
+ * @param[in] conn_id Connection ID.
+ * @return adv_handle.
+ * @retval 0-0xFE Operation success.
+ * @retval 0xFF Operation failure, Get advertising handle failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t adv_handle;
+ adv_handle = le_ext_adv_get_adv_handle_by_conn_id(conn_id);
+ }
+ * \endcode
+ */
+uint8_t le_ext_adv_get_adv_handle_by_conn_id(uint8_t conn_id);
+
+/**
+ * @brief Set GAP extended advertising parameters for an advertising set.
+ *
+ * @param[in] adv_handle Identify an advertising set, which is assigned by @ref le_ext_adv_create_adv_handle.
+ * @param[in] adv_event_prop Type of advertising event.
+ Values for extended advertising PDUs: @ref T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY.
+ Values for legacy advertising PDUs: @ref T_LE_EXT_ADV_LEGACY_ADV_PROPERTY.
+ * @param[in] primary_adv_interval_min Minimum advertising interval for undirected and low duty directed advertising.
+ In units of 0.625ms, range: 0x000020 to 0xFFFFFF.
+ * @param[in] primary_adv_interval_max Maximum advertising interval for undirected and low duty directed advertising.
+ In units of 0.625ms, range: 0x000020 to 0xFFFFFF.
+ * @param[in] primary_adv_channel_map A bit field that indicates the advertising channels that shall be used when
+ transmitting advertising packets. @ref ADV_CHANNEL_MAP.
+ * @param[in] own_address_type Local address type, @ref T_GAP_LOCAL_ADDR_TYPE.
+ * @param[in] peer_address_type Remote address type, GAP_REMOTE_ADDR_LE_PUBLIC or GAP_REMOTE_ADDR_LE_RANDOM in @ref T_GAP_REMOTE_ADDR_TYPE.
+ GAP_REMOTE_ADDR_LE_PUBLIC: Public Device Address or Public Identity Address.
+ GAP_REMOTE_ADDR_LE_RANDOM: Random Device Address or Random(static) Identity Address.
+ * @param[in] p_peer_address Remote address.
+ * @param[in] filter_policy Advertising filter policy: @ref T_GAP_ADV_FILTER_POLICY.
+ * @param[in] tx_power Advertising Tx power.
+ * @param[in] primary_adv_phy Indicate the PHY on which the advertising packets are transmitted on the primary advertising channel.
+ @ref T_GAP_PHYS_PRIM_ADV_TYPE.
+ If legacy advertising PDUs are being used, the primary_adv_phy shall indicate the LE 1M PHY (@ref GAP_PHYS_PRIM_ADV_1M).
+ * @param[in] secondary_adv_max_skip Maximum number of advertising events that can be skipped. Usually set to zero.
+ * @param[in] secondary_adv_phy Indicate the PHY on which the advertising packets are transmitted on the secondary advertising channel.
+ @ref T_GAP_PHYS_TYPE.
+ * @param[in] adv_sid Specify the value to be transmitted in Advertising SID subfield of those advertising channel
+ PDUs that have this field. Usually set to zero.
+ * @param[in] scan_req_notification_enable Indicate whether Host will be notified upon the receipt of a scan request PDU.
+ Usually set to false.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_NOT_FIND Operation failure, the advertising handle is not found.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void le_init_ext_adv_params_ext_conn(void)
+ {
+ uint8_t adv_handle;
+ T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY adv_event_prop = LE_EXT_ADV_EXTENDED_ADV_CONN_UNDIRECTED;
+ uint32_t primary_adv_interval_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint32_t primary_adv_interval_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+ uint8_t primary_adv_channel_map = GAP_ADVCHAN_ALL;
+ T_GAP_LOCAL_ADDR_TYPE own_address_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+ T_GAP_REMOTE_ADDR_TYPE peer_address_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t p_peer_address[6] = {0};
+ T_GAP_ADV_FILTER_POLICY filter_policy = GAP_ADV_FILTER_ANY;
+ uint8_t tx_power = 127; //Host has no preference.
+ T_GAP_PHYS_PRIM_ADV_TYPE primary_adv_phy = GAP_PHYS_PRIM_ADV_1M;
+ uint8_t secondary_adv_max_skip = 0;
+ T_GAP_PHYS_TYPE secondary_adv_phy = GAP_PHYS_2M;
+ uint8_t adv_sid = 0;
+ bool scan_req_notification_enable = false;
+
+ adv_handle = le_ext_adv_create_adv_handle();
+ le_ext_adv_set_adv_param(adv_handle,
+ adv_event_prop,
+ primary_adv_interval_min,
+ primary_adv_interval_max,
+ primary_adv_channel_map,
+ own_address_type,
+ peer_address_type,
+ p_peer_address,
+ filter_policy,
+ tx_power,
+ primary_adv_phy,
+ secondary_adv_max_skip,
+ secondary_adv_phy,
+ adv_sid,
+ scan_req_notification_enable);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_adv_set_adv_param(uint8_t adv_handle, uint16_t adv_event_prop,
+ uint32_t primary_adv_interval_min, uint32_t primary_adv_interval_max,
+ uint8_t primary_adv_channel_map, T_GAP_LOCAL_ADDR_TYPE own_address_type,
+ T_GAP_REMOTE_ADDR_TYPE peer_address_type, uint8_t *p_peer_address,
+ T_GAP_ADV_FILTER_POLICY filter_policy, uint8_t tx_power,
+ T_GAP_PHYS_PRIM_ADV_TYPE primary_adv_phy, uint8_t secondary_adv_max_skip,
+ T_GAP_PHYS_TYPE secondary_adv_phy, uint8_t adv_sid,
+ bool scan_req_notification_enable);
+
+/**
+ * @brief Set GAP advertising data for an advertising set.
+ *
+ * NOTE: This function just saves the pointer of the advertising data and will not copy the advertising data.
+ * So application should the const array or the global array to save the advertising data.
+ * If application uses a dynamically requested buffer to save the advertising data, do not release it.
+ *
+ * @param[in] adv_handle Identify an advertising set, which is assigned by @ref le_ext_adv_create_adv_handle.
+ * @param[in] adv_data_len The length of advertising data.
+ * @param[in] p_adv_data Pointer to advertising data to write.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_NOT_FIND Operation failure, the advertising handle is not found.
+ * @retval GAP_CAUSE_INVALID_PARAM Operation failure, the length of advertising data exceeds
+ 1024 bytes(Maximum total length of GAP extended advertising data).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static const uint8_t ext_adv_data[] =
+ {
+ // Flags
+ 0x02,
+ GAP_ADTYPE_FLAGS,
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ // Local name
+ 0x13,
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'B', 'T', '5', '_', 'P', 'e', 'r', 'i', 'p', 'h', 'e', 'r', 'a', 'l',
+ // Manufacturer Specific Data
+ 0xdd,
+ GAP_ADTYPE_MANUFACTURER_SPECIFIC,
+ 0x5d, 0x00,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
+ 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3,
+ 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5,
+ 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
+ 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9,
+ 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb,
+ 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd
+ };
+
+ void test(void)
+ {
+ le_ext_adv_set_adv_data(adv_handle, sizeof(ext_adv_data), (uint8_t *)ext_adv_data);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_adv_set_adv_data(uint8_t adv_handle, uint16_t adv_data_len, uint8_t *p_adv_data);
+
+/**
+ * @brief Set GAP scan response data for an advertising set.
+ *
+ * @param[in] adv_handle Identify an advertising set, which is assigned by @ref le_ext_adv_create_adv_handle.
+ * @param[in] scan_data_len The length of scan response data.
+ * @param[in] p_scan_data Pointer to scan response data to write.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_NOT_FIND Operation failure, the advertising handle is not found.
+ * @retval GAP_CAUSE_INVALID_PARAM Operation failure, the length of advertising data exceeds
+ 1024 bytes(Maximum total length of GAP extended advertising data).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static const uint8_t ext_scan_rsp_data[] =
+ {
+ // Manufacturer Specific Data
+ 0xfc,
+ GAP_ADTYPE_MANUFACTURER_SPECIFIC,
+ 0x5d, 0x00,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
+ 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3,
+ 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5,
+ 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
+ 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9,
+ 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb,
+ 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd,
+ 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf
+ };
+
+ void test(void)
+ {
+ le_ext_adv_set_scan_response_data(adv_handle, sizeof(ext_scan_rsp_data), (uint8_t *)ext_scan_rsp_data);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_adv_set_scan_response_data(uint8_t adv_handle, uint16_t scan_data_len,
+ uint8_t *p_scan_data);
+
+/**
+ * @brief Set GAP random device address for an advertising set.
+ *
+ * @param[in] adv_handle Identify an advertising set, which is assigned by @ref le_ext_adv_create_adv_handle.
+ * @param[in] random_address Pointer to random address to write.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_NOT_FIND Operation failure, the advertising handle is not found.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t rand_addr[6];
+ le_gen_rand_addr(GAP_RAND_ADDR_STATIC, rand_addr);
+ le_ext_adv_set_random(adv_handle, rand_addr);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_adv_set_random(uint8_t adv_handle, uint8_t *random_address);
+
+/**
+ * @brief Set extended advertising parameters for an advertising set.
+ If request success, the result of setting extended advertising parameters will be returned by
+ @ref app_gap_callback with cb_type @ref GAP_MSG_LE_EXT_ADV_START_SETTING.
+ *
+ * @param[in] adv_handle Identify an advertising set, which is assigned by @ref le_ext_adv_create_adv_handle.
+ * @param[in] update_flags A bit field that indicates extended advertising parameters that shall be set. @ref EXT_ADV_PARAM.
+ Recommendation: if random address is not used, set update_flags to @ref EXT_ADV_SET_AUTO.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Set parameters request success.
+ * @retval GAP_CAUSE_NOT_FIND Set parameters request failed, the advertising handle is not found.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void le_init_ext_adv_params_ext(void)
+ {
+ T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY adv_event_prop =
+ LE_EXT_ADV_EXTENDED_ADV_NON_SCAN_NON_CONN_UNDIRECTED;
+ uint32_t primary_adv_interval_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint32_t primary_adv_interval_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+ uint8_t primary_adv_channel_map = GAP_ADVCHAN_ALL;
+ T_GAP_LOCAL_ADDR_TYPE own_address_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+ T_GAP_REMOTE_ADDR_TYPE peer_address_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t p_peer_address[6] = {0};
+ T_GAP_ADV_FILTER_POLICY filter_policy = GAP_ADV_FILTER_ANY;
+ uint8_t tx_power = 127; //Host has no preference.
+ T_GAP_PHYS_PRIM_ADV_TYPE primary_adv_phy = GAP_PHYS_PRIM_ADV_1M;
+ uint8_t secondary_adv_max_skip = 0;
+ T_GAP_PHYS_TYPE secondary_adv_phy = GAP_PHYS_2M;
+ uint8_t adv_sid = 0;
+ bool scan_req_notification_enable = false;
+
+ adv_handle = le_ext_adv_create_adv_handle();
+ le_ext_adv_set_adv_param(adv_handle,
+ adv_event_prop,
+ primary_adv_interval_min,
+ primary_adv_interval_max,
+ primary_adv_channel_map,
+ own_address_type,
+ peer_address_type,
+ p_peer_address,
+ filter_policy,
+ tx_power,
+ primary_adv_phy,
+ secondary_adv_max_skip,
+ secondary_adv_phy,
+ adv_sid,
+ scan_req_notification_enable);
+
+ le_ext_adv_set_adv_data(adv_handle, sizeof(ext_adv_data), (uint8_t *)ext_adv_data);
+ }
+
+ void test(void)
+ {
+ le_init_ext_adv_params_ext();
+ le_ext_adv_start_setting(adv_handle, EXT_ADV_SET_AUTO);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_EXT_ADV_START_SETTING:
+ APP_PRINT_INFO3("GAP_MSG_LE_EXT_ADV_START_SETTING:cause 0x%x, flag 0x%x, adv_handle %d",
+ p_data->p_le_ext_adv_start_setting_rsp->cause, p_data->p_le_ext_adv_start_setting_rsp->flag,
+ p_data->p_le_ext_adv_start_setting_rsp->adv_handle);
+
+ if (p_data->p_le_ext_adv_start_setting_rsp->cause == GAP_CAUSE_SUCCESS)
+ {
+ // Initialize enable parameters
+ le_init_ext_adv_enable_params(p_data->p_le_ext_adv_start_setting_rsp->adv_handle);
+ // Enable one advertising set
+ le_ext_adv_enable(1, &p_data->p_le_ext_adv_start_setting_rsp->adv_handle);
+ }
+ break;
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_adv_start_setting(uint8_t adv_handle, uint8_t update_flags);
+
+/**
+ * @brief Set GAP extended advertising enable parameters for an advertising set.
+ *
+ * @param[in] adv_handle Identify an advertising set, which is assigned by @ref le_ext_adv_create_adv_handle.
+ * @param[in] duration If non-zero, indicates the duration that advertising set is enabled.
+ 0x0000: No advertising duration.
+ 0x0001-0xFFFF: Advertising duration, in units of 10ms.
+ * @param[in] max_ext_adv_evt If non-zero, indicates the maximum extended advertising events that shall be
+ sent prior to disabling the extended advertising set.
+ 0x00: No maximum number of advertising events.
+ 0x01-0xFF: Maximum number of extended advertising events to send prior to terminating
+ the extended advertising.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_NOT_FIND Operartion failure, the advertising handle is not found.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint16_t duration = 0;
+ uint8_t max_ext_adv_evt = 0;
+
+ le_ext_adv_set_adv_enable_param(adv_handle, duration, max_ext_adv_evt);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_adv_set_adv_enable_param(uint8_t adv_handle, uint16_t duration,
+ uint8_t max_ext_adv_evt);
+
+/**
+ * @brief Enable extended advertising for one or more advertising sets.
+ If device changes to advertising state, @ref app_handle_ext_adv_state_evt will be called, and
+ @ref app_gap_callback with cb_type @ref GAP_MSG_LE_EXT_ADV_ENABLE will be called.
+ *
+ * @param[in] num_of_sets Number of advertising sets to enable.
+ * @param[in] adv_handle Pointer to advertising set to enable.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Enable request success.
+ * @retval GAP_CAUSE_NOT_FIND Enable request failed, the advertising handle is not found.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ case GAP_MSG_LE_EXT_ADV_START_SETTING:
+ APP_PRINT_INFO3("GAP_MSG_LE_EXT_ADV_START_SETTING:cause 0x%x, flag 0x%x, adv_handle %d",
+ p_data->p_le_ext_adv_start_setting_rsp->cause, p_data->p_le_ext_adv_start_setting_rsp->flag,
+ p_data->p_le_ext_adv_start_setting_rsp->adv_handle);
+
+ if (p_data->p_le_ext_adv_start_setting_rsp->cause == GAP_CAUSE_SUCCESS)
+ {
+ // Initialize enable parameters
+ le_init_ext_adv_enable_params(p_data->p_le_ext_adv_start_setting_rsp->adv_handle);
+ // Enable one advertising set
+ le_ext_adv_enable(1, &p_data->p_le_ext_adv_start_setting_rsp->adv_handle);
+ }
+ break;
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_EXT_ADV_ENABLE:
+ APP_PRINT_INFO1("GAP_MSG_LE_EXT_ADV_ENABLE:cause 0x%x", p_data->le_cause.cause);
+ break;
+ }
+ }
+
+ void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+ {
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_EXT_ADV_STATE_CHANGE:
+ {
+ app_handle_ext_adv_state_evt(gap_msg.msg_data.gap_ext_adv_state_change.adv_handle,
+ (T_GAP_EXT_ADV_STATE)gap_msg.msg_data.gap_ext_adv_state_change.new_state,
+ gap_msg.msg_data.gap_ext_adv_state_change.cause);
+ }
+ break;
+ }
+ }
+
+ void app_handle_ext_adv_state_evt(uint8_t adv_handle, T_GAP_EXT_ADV_STATE new_state, uint16_t cause)
+ {
+ for (int i = 0; i < APP_MAX_ADV_SET; i++)
+ {
+ if (ext_adv_state[i].adv_handle == adv_handle)
+ {
+ APP_PRINT_INFO2("app_handle_ext_adv_state_evt: adv_handle = %d oldState = %d",
+ ext_adv_state[i].adv_handle, ext_adv_state[i].ext_adv_state);
+ ext_adv_state[i].ext_adv_state = new_state;
+ break;
+ }
+ }
+ APP_PRINT_INFO2("app_handle_ext_adv_state_evt: adv_handle = %d newState = %d",
+ adv_handle, new_state);
+ switch (new_state)
+ {
+ // device is idle
+ case EXT_ADV_STATE_IDLE:
+ {
+ APP_PRINT_INFO2("EXT_ADV_STATE_IDLE: adv_handle %d, cause 0x%x", adv_handle, cause);
+ }
+ break;
+
+ // device is advertising
+ case EXT_ADV_STATE_ADVERTISING:
+ {
+ APP_PRINT_INFO2("EXT_ADV_STATE_ADVERTISING: adv_handle %d, cause 0x%x", adv_handle, cause);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_adv_enable(uint8_t num_of_sets, uint8_t *adv_handle);
+
+/**
+ * @brief Disable extended advertising for one or more advertising sets.
+ If device changes to idle state, @ref app_handle_ext_adv_state_evt will be called, and
+ @ref app_gap_callback with cb_type @ref GAP_MSG_LE_EXT_ADV_DISABLE will be called.
+ *
+ * @param[in] num_of_sets Number of advertising sets to enable.
+ * @param[in] adv_handle Pointer to advertising set to enable.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Disable request success.
+ * @retval GAP_CAUSE_NOT_FIND Disable request failed, the advertising handle is not found.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_stopeadv(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t adv_handle[4];
+ uint8_t num_of_sets = 1;
+ T_GAP_CAUSE cause;
+ adv_handle[0] = p_parse_value->dw_param[0];
+
+ cause = le_ext_adv_disable(num_of_sets, adv_handle);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_EXT_ADV_DISABLE:
+ APP_PRINT_INFO1("GAP_MSG_LE_EXT_ADV_DISABLE:cause 0x%x", p_data->le_cause.cause);
+ break;
+ }
+ }
+
+ void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+ {
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_EXT_ADV_STATE_CHANGE:
+ {
+ app_handle_ext_adv_state_evt(gap_msg.msg_data.gap_ext_adv_state_change.adv_handle,
+ (T_GAP_EXT_ADV_STATE)gap_msg.msg_data.gap_ext_adv_state_change.new_state,
+ gap_msg.msg_data.gap_ext_adv_state_change.cause);
+ }
+ break;
+ }
+ }
+
+ void app_handle_ext_adv_state_evt(uint8_t adv_handle, T_GAP_EXT_ADV_STATE new_state, uint16_t cause)
+ {
+ for (int i = 0; i < APP_MAX_ADV_SET; i++)
+ {
+ if (ext_adv_state[i].adv_handle == adv_handle)
+ {
+ APP_PRINT_INFO2("app_handle_ext_adv_state_evt: adv_handle = %d oldState = %d",
+ ext_adv_state[i].adv_handle, ext_adv_state[i].ext_adv_state);
+ ext_adv_state[i].ext_adv_state = new_state;
+ break;
+ }
+ }
+ APP_PRINT_INFO2("app_handle_ext_adv_state_evt: adv_handle = %d newState = %d",
+ adv_handle, new_state);
+ switch (new_state)
+ {
+ // device is idle
+ case EXT_ADV_STATE_IDLE:
+ {
+ APP_PRINT_INFO2("EXT_ADV_STATE_IDLE: adv_handle %d, cause 0x%x", adv_handle, cause);
+ }
+ break;
+
+ // device is advertising
+ case EXT_ADV_STATE_ADVERTISING:
+ {
+ APP_PRINT_INFO2("EXT_ADV_STATE_ADVERTISING: adv_handle %d, cause 0x%x", adv_handle, cause);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_adv_disable(uint8_t num_of_sets, uint8_t *adv_handle);
+
+/**
+ * @brief Remove all existing advertising sets.
+ The result of removing all existing advertising sets will be returned by
+ @ref app_gap_callback with cb_type @ref GAP_MSG_LE_EXT_ADV_CLEAR_SET.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Clear request success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ le_ext_adv_clear_set();
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_EXT_ADV_CLEAR_SET:
+ APP_PRINT_INFO1("GAP_MSG_LE_EXT_ADV_CLEAR_SET:cause 0x%x",
+ p_data->p_le_ext_adv_clear_set_rsp->cause);
+ break;
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_adv_clear_set(void);
+
+/**
+ * @brief Remove an advertising set.
+ If request success, the result of removing an advertising set will be returned by
+ @ref app_gap_callback with cb_type @ref GAP_MSG_LE_EXT_ADV_REMOVE_SET.
+ *
+ * @param[in] adv_handle Identify an advertising set.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Remove request success.
+ * @retval GAP_CAUSE_NOT_FIND Remove request failed, the advertising handle is not found.
+ * @retval GAP_CAUSE_INVALID_STATE Remove request failed, invalid state.
+ * @retval GAP_CAUSE_ALREADY_IN_REQ Remove request failed, operation is already in progress.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ le_ext_adv_remove_set(adv_handle);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_EXT_ADV_REMOVE_SET:
+ APP_PRINT_INFO2("GAP_MSG_LE_EXT_ADV_REMOVE_SET:cause 0x%x, adv_handle %d",
+ p_data->p_le_ext_adv_remove_set_rsp->cause, p_data->p_le_ext_adv_remove_set_rsp->adv_handle);
+ break;
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_adv_remove_set(uint8_t adv_handle);
+
+#if F_BT_LE_GAP_MSG_INFO_WAY
+void le_ext_adv_gap_msg_info_way(bool use_msg);
+#endif
+
+/** End of GAP_LE_EXTENDED_ADV_Exported_Functions
+ * @}
+ */
+
+/** End of GAP_LE_EXTENDED_ADV
+ * @}
+ */
+
+/** End of GAP_LE
+ * @}
+ */
+
+/** End of GAP
+ * @}
+ */
+
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_EXT_ADV_H */
diff --git a/inc/bluetooth/gap/gap_ext_scan.h b/inc/bluetooth/gap/gap_ext_scan.h
new file mode 100644
index 0000000..258b9ab
--- /dev/null
+++ b/inc/bluetooth/gap/gap_ext_scan.h
@@ -0,0 +1,447 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_ext_scan.h
+* @brief Header file for Gap ext scan
+* @details
+* @author jane
+* @date 2016-02-18
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+/* Define to prevent recursive inclusion **/
+#ifndef GAP_EXT_SCAN_H
+#define GAP_EXT_SCAN_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "upperstack_config.h"
+#include "gap_le.h"
+#if F_BT_LE_5_0_AE_SCAN_SUPPORT
+
+/** @addtogroup GAP GAP Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE GAP LE Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE_EXTENDED_SCAN GAP LE Extended Scan Module
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GAP_LE_EXTENDED_SCAN_Exported_Macros GAP LE Extended Scan Exported Macros
+ * @brief
+ * @{
+ */
+
+#define GAP_EXT_SCAN_MAX_PHYS_NUM 2 /**< Maximum number of scan PHYs. */
+
+/** @defgroup EXT_SCAN_PHY Extended Scan PHY
+ * @brief Indicate the PHY(s) on which the advertising packets should be received
+ on the primary advertising channel. LE 1M PHY and LE Coded PHY are primary
+ advertising channel.
+ * @{
+ */
+#define GAP_EXT_SCAN_PHYS_1M_BIT 0x01 /**< Scan advertisements on the LE 1M PHY. */
+#define GAP_EXT_SCAN_PHYS_CODED_BIT 0x04 /**< Scan advertisements on the LE Coded PHY. */
+#define GAP_EXT_SCAN_PHYS_ALL 0x05 /**< Scan advertisements on the LE 1M PHY and LE Coded PHY. */
+/** End of EXT_SCAN_PHY
+ * @}
+ */
+
+/** @defgroup EXT_ADV_REPORT Extended Advertising Report flag
+ * @brief Indicate properties of advertising event in extended advertising report.
+ When a scan response is received, bits 0-2 and 4 of event type shall
+ indicate the properties of the original advertising event.
+ * @{
+ */
+#define GAP_EXT_ADV_REPORT_BIT_CONNECTABLE_ADV 0x01 /**< Connectable advertising. */
+#define GAP_EXT_ADV_REPORT_BIT_SCANNABLE_ADV 0x02 /**< Scannable advertising. */
+#define GAP_EXT_ADV_REPORT_BIT_DIRECTED_ADV 0x04 /**< Directed advertising. */
+#define GAP_EXT_ADV_REPORT_BIT_SCAN_RESPONSE 0x08 /**< Scan response. */
+#define GAP_EXT_ADV_REPORT_BIT_USE_LEGACY_ADV 0x10 /**< Legacy advertising PDUs used. */
+/** End of EXT_ADV_REPORT
+ * @}
+ */
+
+/** End of GAP_LE_EXTENDED_SCAN_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_EXTENDED_SCAN_Exported_Types GAP LE Extended Scan Exported Types
+ * @brief
+ * @{
+ */
+/** @brief Scan PHY type used in @ref le_ext_scan_set_phy_param. */
+typedef enum
+{
+ LE_SCAN_PHY_LE_1M, /**< Set @ref T_GAP_LE_EXT_SCAN_PARAM for LE 1M PHY. */
+ LE_SCAN_PHY_LE_CODED, /**< Set @ref T_GAP_LE_EXT_SCAN_PARAM for LE Coded PHY. */
+} T_LE_EXT_SCAN_PHY_TYPE;
+
+/** @brief Extended scan parameter. */
+typedef struct
+{
+ T_GAP_SCAN_MODE
+ scan_type; /**< Scan type. Write only. Default is GAP_SCAN_MODE_ACTIVE, @ref T_GAP_SCAN_MODE. */
+ uint16_t
+ scan_interval; /**< Scan Interval. Write only. In units of 0.625ms, range: 0x0004 to 0xFFFF. Default is 0x40. */
+ uint16_t
+ scan_window; /**< Scan Window. Write only. In units of 0.625ms, range: 0x0004 to 0xFFFF. Default is 0x20. */
+} T_GAP_LE_EXT_SCAN_PARAM;
+
+/** @brief Extended scan parameter type. */
+typedef enum
+{
+ GAP_PARAM_EXT_SCAN_LOCAL_ADDR_TYPE = 0x340, /**< The type of address being used in the scan request packets. Read/Write. Size is uint8_t. Default is GAP_LOCAL_ADDR_LE_PUBLIC (@ref T_GAP_LOCAL_ADDR_TYPE). */
+ GAP_PARAM_EXT_SCAN_FILTER_POLICY = 0x341, /**< Scanning filter policy. Read/Write. Size is uint8_t. Default is GAP_SCAN_FILTER_ANY (@ref T_GAP_SCAN_FILTER_POLICY). */
+ GAP_PARAM_EXT_SCAN_PHYS = 0x342, /**< Scanning PHYs. window. Read/Write. Size is uint8_t. Default is GAP_EXT_SCAN_PHYS_1M_BIT (@ref EXT_SCAN_PHY). */
+ GAP_PARAM_EXT_SCAN_FILTER_DUPLICATES = 0x343, /**< Scan Filter Duplicates. Read/Write. Size is uint8_t. Default is GAP_SCAN_FILTER_DUPLICATE_ENABLE (@ref T_GAP_SCAN_FILTER_DUPLICATE). */
+ GAP_PARAM_EXT_SCAN_DURATION = 0x344, /**< Scan duration. Read/Write. Size is uint16_t. In units of 10ms, range: 0x0000~0xFFFF. Default is zero. */
+ GAP_PARAM_EXT_SCAN_PERIOD = 0x345, /**< Scan period. Read/Write. Size is uint16_t. In units of 1.28sec, range: 0x0000~0xFFFF. Default is zero. */
+} T_LE_EXT_SCAN_PARAM_TYPE;
+
+/** End of GAP_LE_EXTENDED_SCAN_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup GAP_LE_EXTENDED_SCAN_Exported_Functions GAP LE Extended Scan Exported Functions
+ * @brief
+ * @{
+ */
+#if F_BT_LE_GAP_SCAN_FILTER_SUPPORT
+/**
+ * @brief Set extended scan information filter.
+ *
+ * NOTE: This function can be called before @ref gap_start_bt_stack is invoked.
+ *
+ * @param[in] enable Whether to open the extend scan info filter function.
+ * @param[in] report_type A logical OR of the bit values that provide the list of report type to receive.
+ * @param[in] legacy_adv Whether to receive the legacy scan info.
+ * @return bool.
+ * @retval TRUE Operation success.
+ * @retval FALSE Operation Failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ le_ext_scan_report_filter(true,
+ GAP_EXT_ADV_REPORT_BIT_CONNECTABLE_ADV|GAP_EXT_ADV_REPORT_BIT_SCANNABLE_ADV, false);
+ }
+ * \endcode
+ */
+bool le_ext_scan_report_filter(bool enable, uint16_t report_type, bool legacy_adv);
+#endif
+
+/**
+ * @brief Set a GAP extended scan parameter.
+ *
+ * NOTE: You can call this function with a extended scan parameter type and it will set the
+ * extended scan parameter. Extended scan parameters are defined in @ref T_LE_EXT_SCAN_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the "p_value" field must
+ * point to a data with type "uint16".
+ * Combination of Duration parameter (@ref GAP_PARAM_EXT_SCAN_DURATION) and
+ * Period parameter(@ref GAP_PARAM_EXT_SCAN_PERIOD) determines scan mode,
+ * please refer to below code about scan_mode.
+ *
+ * @param[in] param Extended scan parameter type: @ref T_LE_EXT_SCAN_PARAM_TYPE
+ * @param[in] len Length of data to write.
+ * @param[in] p_value Pointer to data to write. This is dependent on the parameter type and will
+ be cast to the appropriate data type (For example: if data type param is uint16,
+ p_value will be cast to pointer of uint16_t).
+ *
+ * @return Set result
+ * @retval GAP_CAUSE_SUCCESS Set parameter success.
+ * @retval other Set parameter failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_escan(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ T_GAP_CAUSE cause;
+ T_GAP_LOCAL_ADDR_TYPE own_address_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+ T_GAP_SCAN_FILTER_POLICY ext_scan_filter_policy = GAP_SCAN_FILTER_ANY;
+ T_GAP_SCAN_FILTER_DUPLICATE ext_scan_filter_duplicate = GAP_SCAN_FILTER_DUPLICATE_ENABLE;
+ uint16_t ext_scan_duration;
+ uint16_t ext_scan_period;
+ uint8_t scan_phys = GAP_EXT_SCAN_PHYS_1M_BIT | GAP_EXT_SCAN_PHYS_CODED_BIT;
+ T_EXT_SCAN_MODE scan_mode = (T_EXT_SCAN_MODE)p_parse_value->dw_param[0];
+
+ link_mgr_clear_device_list();
+ if (scan_mode == SCAN_UNTIL_DISABLED)
+ {
+ // If Duration parameter is zero, continue scanning until scanning is disabled.
+ ext_scan_duration = 0;
+ ext_scan_period = 0;
+ }
+ else if (scan_mode == PERIOD_SCAN_UNTIL_DISABLED)
+ {
+ // If Duration and Period parameters are non-zero, scan for the duration within a scan period,
+ // and scan periods continue until scanning is disabled. Duration shall be less than Period.
+ ext_scan_duration = 500;
+ ext_scan_period = 8;
+ ext_scan_filter_duplicate = GAP_SCAN_FILTER_DUPLICATE_ENABLED_RESET_FOR_EACH_PERIOD;
+ }
+ else if (scan_mode == SCAN_UNTIL_DURATION_EXPIRED)
+ {
+ // If Duration parameter is non-zero and Period parameter is zero, continue scanning until duration has expired.
+ ext_scan_duration = 500;
+ ext_scan_period = 0;
+ }
+ if (p_parse_value->param_count > 1)
+ {
+ scan_phys = p_parse_value->dw_param[1];
+ }
+
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_LOCAL_ADDR_TYPE, sizeof(own_address_type), &own_address_type);
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_PHYS, sizeof(scan_phys), &scan_phys);
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_DURATION, sizeof(ext_scan_duration), &ext_scan_duration);
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_PERIOD, sizeof(ext_scan_period),&ext_scan_period);
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_FILTER_POLICY, sizeof(ext_scan_filter_policy), &ext_scan_filter_policy);
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_FILTER_DUPLICATES, sizeof(ext_scan_filter_duplicate), &ext_scan_filter_duplicate);
+
+ cause = le_ext_scan_start();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_scan_set_param(T_LE_EXT_SCAN_PARAM_TYPE param, uint8_t len, void *p_value);
+
+/**
+ * @brief Get a extended scan parameter.
+ *
+ * NOTE: You can call this function with a extended scan parameter type and it will get a
+ * extended scan parameter. Extended scan parameters are defined in @ref T_LE_EXT_SCAN_PARAM_TYPE.
+ *
+ * @param[in] param Extended scan parameter type: @ref T_LE_EXT_SCAN_PARAM_TYPE.
+ * @param[in,out] p_value Pointer to location to get the parameter value. This is dependent on
+ * the parameter type and will be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Get result
+ * @retval GAP_CAUSE_SUCCESS Get parameter success.
+ * @retval GAP_CAUSE_INVALID_PARAM Get parameter failed, invalid parameter.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint16_t scan_duration;
+ le_ext_scan_get_param(GAP_PARAM_EXT_SCAN_DURATION, &scan_duration);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_scan_get_param(T_LE_EXT_SCAN_PARAM_TYPE param, void *p_value);
+
+/**
+ * @brief Set a extended scan phy parameter including scan type, scan interval and scan window
+ for scan advertisements on LE 1M PHY or/and LE Coded PHY.
+ *
+ * @param[in] type Scan PHY type: @ref T_LE_EXT_SCAN_PHY_TYPE
+ * @param[in] p_param Pointer to data to write, @ref T_GAP_LE_EXT_SCAN_PARAM.
+ scan_type: Passive scanning or active scanning, @ref T_GAP_SCAN_MODE.
+ scan_interval: The frequency of scan, in units of 0.625ms, range: 0x0004 to 0xFFFF.
+ scan_window: The length of scan, in units of 0.625ms, range: 0x0004 to 0xFFFF.
+ *
+ * @return void
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_escan(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t scan_phys = GAP_EXT_SCAN_PHYS_1M_BIT | GAP_EXT_SCAN_PHYS_CODED_BIT;
+ T_GAP_LE_EXT_SCAN_PARAM extended_scan_param[GAP_EXT_SCAN_MAX_PHYS_NUM];
+ extended_scan_param[0].scan_type = GAP_SCAN_MODE_ACTIVE;
+ extended_scan_param[0].scan_interval = 400;
+ extended_scan_param[0].scan_window = 200;
+ extended_scan_param[1].scan_type = GAP_SCAN_MODE_ACTIVE;
+ extended_scan_param[1].scan_interval = 440;
+ extended_scan_param[1].scan_window = 220;
+
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_PHYS, sizeof(scan_phys), &scan_phys);
+
+ le_ext_scan_set_phy_param(LE_SCAN_PHY_LE_1M, &extended_scan_param[0]);
+ le_ext_scan_set_phy_param(LE_SCAN_PHY_LE_CODED, &extended_scan_param[1]);
+
+ return (RESULT_SUCCESS);
+ }
+ * \endcode
+ */
+void le_ext_scan_set_phy_param(T_LE_EXT_SCAN_PHY_TYPE type, T_GAP_LE_EXT_SCAN_PARAM *p_param);
+
+/**
+ * @brief Start a device discovery extended scan.
+ If device changes to scanning state, @ref app_handle_dev_state_evt will be called. And the
+ advertising data or scan response data will be returned by @ref app_gap_callback with
+ cb_type @ref GAP_MSG_LE_EXT_ADV_REPORT_INFO.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS: Start request success.
+ * @retval GAP_CAUSE_INVALID_STATE: Start request failed, invalid device state.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ le_ext_scan_start();
+ }
+
+ void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+ {
+ APP_PRINT_INFO5("app_handle_dev_state_evt: init state = %d scan state = %d adv state = %d conn state = %d cause = 0x%x",
+ new_state.gap_init_state,
+ new_state.gap_scan_state, new_state.gap_adv_state, new_state.gap_conn_state, cause);
+
+ if (gap_dev_state.gap_scan_state != new_state.gap_scan_state)
+ {
+ if (new_state.gap_scan_state == GAP_SCAN_STATE_IDLE)
+ {
+ APP_PRINT_INFO0("GAP scan stop");
+ data_uart_print("GAP scan stop\r\n");
+ }
+ else if (new_state.gap_scan_state == GAP_SCAN_STATE_SCANNING)
+ {
+ APP_PRINT_INFO0("GAP scan start");
+ data_uart_print("GAP scan start\r\n");
+ }
+ }
+
+ gap_dev_state = new_state;
+ }
+
+ //Received advertising or scan response data will be handled in app_gap_callback
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_EXT_ADV_REPORT_INFO:
+ APP_PRINT_INFO6("GAP_MSG_LE_EXT_ADV_REPORT_INFO:connectable %d, scannable %d, direct %d, scan response %d, legacy %d, data status 0x%x",
+ p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_CONNECTABLE_ADV,
+ p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_SCANNABLE_ADV,
+ p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_DIRECTED_ADV,
+ p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_SCAN_RESPONSE,
+ p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_USE_LEGACY_ADV,
+ p_data->p_le_ext_adv_report_info->data_status);
+ APP_PRINT_INFO5("GAP_MSG_LE_EXT_ADV_REPORT_INFO:event_type 0x%x, bd_addr %s, addr_type %d, rssi %d, data_len %d",
+ p_data->p_le_ext_adv_report_info->event_type,
+ TRACE_BDADDR(p_data->p_le_ext_adv_report_info->bd_addr),
+ p_data->p_le_ext_adv_report_info->addr_type,
+ p_data->p_le_ext_adv_report_info->rssi,
+ p_data->p_le_ext_adv_report_info->data_len);
+ APP_PRINT_INFO5("GAP_MSG_LE_EXT_ADV_REPORT_INFO:primary_phy %d, secondary_phy %d, adv_sid %d, tx_power %d, peri_adv_interval %d",
+ p_data->p_le_ext_adv_report_info->primary_phy,
+ p_data->p_le_ext_adv_report_info->secondary_phy,
+ p_data->p_le_ext_adv_report_info->adv_sid,
+ p_data->p_le_ext_adv_report_info->tx_power,
+ p_data->p_le_ext_adv_report_info->peri_adv_interval);
+ APP_PRINT_INFO2("GAP_MSG_LE_EXT_ADV_REPORT_INFO:direct_addr_type 0x%x, direct_addr %s",
+ p_data->p_le_ext_adv_report_info->direct_addr_type,
+ TRACE_BDADDR(p_data->p_le_ext_adv_report_info->direct_addr));
+
+ link_mgr_add_device(p_data->p_le_ext_adv_report_info->bd_addr,
+ p_data->p_le_ext_adv_report_info->addr_type);
+
+ #if APP_RECOMBINE_ADV_DATA
+ if (!(p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_USE_LEGACY_ADV))
+ {
+ app_handle_ext_adv_report(p_data->p_le_ext_adv_report_info->event_type,
+ p_data->p_le_ext_adv_report_info->data_status, p_data->p_le_ext_adv_report_info->bd_addr,
+ p_data->p_le_ext_adv_report_info->data_len, p_data->p_le_ext_adv_report_info->p_data);
+ }
+ #endif
+ break;
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_scan_start(void);
+
+/**
+ * @brief Stop a device discovery extended scan.
+ If device changes to idle state, @ref app_handle_dev_state_evt will be called.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS: Stop request success.
+ * @retval GAP_CAUSE_INVALID_STATE: Stop request failed. Invalid state, not in scan state.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ le_ext_scan_stop();
+ }
+
+ void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+ {
+ APP_PRINT_INFO5("app_handle_dev_state_evt: init state = %d scan state = %d adv state = %d conn state = %d cause = 0x%x",
+ new_state.gap_init_state,
+ new_state.gap_scan_state, new_state.gap_adv_state, new_state.gap_conn_state, cause);
+
+ if (gap_dev_state.gap_scan_state != new_state.gap_scan_state)
+ {
+ if (new_state.gap_scan_state == GAP_SCAN_STATE_IDLE)
+ {
+ APP_PRINT_INFO0("GAP scan stop");
+ data_uart_print("GAP scan stop\r\n");
+ }
+ else if (new_state.gap_scan_state == GAP_SCAN_STATE_SCANNING)
+ {
+ APP_PRINT_INFO0("GAP scan start");
+ data_uart_print("GAP scan start\r\n");
+ }
+ }
+
+ gap_dev_state = new_state;
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ext_scan_stop(void);
+
+#if F_BT_LE_GAP_MSG_INFO_WAY
+void le_ext_scan_gap_msg_info_way(bool use_msg);
+#endif
+/** End of GAP_LE_EXTENDED_SCAN_Exported_Functions
+ * @}
+ */
+
+/** End of GAP_LE_EXTENDED_SCAN
+ * @}
+ */
+
+/** End of GAP_LE
+ * @}
+ */
+
+/** End of GAP
+ * @}
+ */
+
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_EXT_SCAN_H */
diff --git a/inc/bluetooth/gap/gap_fix_chann_conn.h b/inc/bluetooth/gap/gap_fix_chann_conn.h
new file mode 100644
index 0000000..7b92df7
--- /dev/null
+++ b/inc/bluetooth/gap/gap_fix_chann_conn.h
@@ -0,0 +1,28 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file gap_fix_chann_conn.h
+* @brief header file of LE Fixed Channel Connection message handle.
+* @details none.
+* @author Tifnan
+* @date 2016-03-16
+* @version v0.1
+*********************************************************************************************************
+*/
+
+#ifndef _LE_FIX_CHANN_CONN_H_
+#define _LE_FIX_CHANN_CONN_H_
+
+#include "upperstack_config.h"
+#include "gap_le.h"
+#include "gap.h"
+
+#if F_BT_LE_FIX_CHANN_SUPPORT
+T_GAP_CAUSE le_fixed_chann_reg(uint16_t cid);
+
+T_GAP_CAUSE le_fixed_chann_data_send(uint8_t conn_id, uint16_t cid, uint8_t *p_data,
+ uint16_t data_len);
+#endif
+
+#endif /* _LE_FIX_CHANN_CONN_H_ */
diff --git a/inc/bluetooth/gap/gap_le.h b/inc/bluetooth/gap/gap_le.h
new file mode 100644
index 0000000..f74a754
--- /dev/null
+++ b/inc/bluetooth/gap/gap_le.h
@@ -0,0 +1,527 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gap_le.h
+ * @brief This file contains all the constants and functions prototypes for GAP protocol.
+ * @details
+ * @author jane
+ * @date 2016-02-18
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_LE_H
+#define GAP_LE_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#include "gap.h"
+#include "gap_callback_le.h"
+
+/** @addtogroup GAP_LE_COMMON GAP LE Common Module
+ * @brief GAP LE common module
+ * @{
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_Exported_Types GAP LE Exported Types
+ * @brief
+ * @{
+ */
+/** @brief GAP LE Parameter Types List.*/
+typedef enum
+{
+ GAP_PARAM_DEV_STATE = 0x220, //!< Device's current GAP device state. Read/Write. Size is sizeof(TGapDevState).
+ GAP_PARAM_APPEARANCE = 0x221, //!< Local Device's Appearance. Read/Write. size is uint16. Appearance value please refer to GAP Appearance Values.(@ref GAP_LE_APPEARANCE_VALUES)
+ GAP_PARAM_DEVICE_NAME = 0x222, //!< Local Device's Name. Write Only. Name string length is GAP_DEVICE_NAME_LEN.
+#if F_BT_LE_GAP_PERIPHERAL_SUPPORT
+ GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ = 0x223, //!< Slave initiate the GATT exchange MTU procedure. Write Only.
+#endif
+ GAP_PARAM_RANDOM_ADDR = 0x224, //!< Random address. Write Only.
+ GAP_PARAM_LATEST_CONN_BD_ADDR = 0x226, //!< Latest connected bluetooth devive address. Read Only.
+ GAP_PARAM_LATEST_CONN_BD_ADDR_TYPE = 0x227, //!< Latest connected bluetooth devive address type. Read Only.
+ GAP_PARAM_HANDLE_CREATE_CONN_IND = 0x228, //!< App handle the create connection indication message.
+#if F_BT_LE_5_0_SET_PHYS_SUPPORT
+ GAP_PARAM_DEFAULT_PHYS_PREFER = 0x229, //!< Preferred values for the transmitter PHY and receiver PHY to be used for all subsequent connections over the LE transport.
+ GAP_PARAM_DEFAULT_TX_PHYS_PREFER = 0x22a, //!< The transmitter PHYs that the Host prefers the Controller to use.
+ GAP_PARAM_DEFAULT_RX_PHYS_PREFER = 0x22b, //!< The receiver PHYs that the Host prefers the Controller to use.
+#endif
+#if F_BT_LE_5_0_AE_ADV_SUPPORT
+ GAP_PARAM_USE_EXTENDED_ADV = 0x22c, //!< Use LE Advertising Extensions.
+#endif
+ GAP_PARAM_SET_REM_MIN_SCA = 0x22d,
+#if F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT
+ GAP_PARAM_DEFAULT_DATA_LEN_MAX_TX_OCTETS = 0x22e,
+ GAP_PARAM_DEFAULT_DATA_LEN_MAX_TX_TIME = 0x22f,
+#endif
+ GAP_PARAM_LOCAL_FEATURES = 0x230, //!< Local supported features.
+ GAP_PARAM_DS_POOL_ID = 0x231, //!< Downstream PoolID. Read only. size is uint16.
+ GAP_PARAM_DS_DATA_OFFSET = 0x232, //!< Downstream pool buffer data offset. Read only. size is uint16.
+ GAP_PARAM_LE_REMAIN_CREDITS = 0x233, //!< Remain credits available for TX. Read only. size is uint16.
+ GAP_PARAM_MAX_WL_SIZE = 0x234, //!< Max white list size. Read only. size is uint16.
+#if F_BT_LE_5_0_READ_POWER_SUPPORT
+ GAP_PARAM_MIN_TX_POWER = 0x235, //!< The minimum transmit powers supported by the Controller.
+ GAP_PARAM_MAX_TX_POWER = 0x236, //!< The maximum transmit powers supported by the Controller.
+#endif
+#if F_BT_LE_5_2_ISOC_CIS_SUPPORT
+ GAP_PARAM_ISOCH_HOST_SUPPORT = 0x237, //!< Use CIS of LE Isochronous Channels.
+#endif
+} T_GAP_LE_PARAM_TYPE;
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+typedef T_APP_RESULT(*P_FUN_LE_APP_CB)(uint8_t cb_type, void *p_cb_data);
+/** End of GAP_LE_Exported_Types
+ * @}
+ */
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @defgroup GAP_LE_COMMON_Exported_Functions GAP LE Common Exported Functions
+ *
+ * @{
+ */
+
+/**
+ * @brief Initialize parameters of GAP.
+ * @param[in] link_num Initialize link number.
+ * @retval true Success.
+ * @retval false Failed because of invalid parameter.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ int main(void)
+ {
+ board_init();
+ driver_init();
+ le_gap_init(1);
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+ }
+ * \endcode
+ */
+bool le_gap_init(uint8_t link_num);
+
+/**
+ * @brief Set gap message inform way.
+ *
+ * Default value is true.
+ * 1. When use_msg is true, gap will send the gap message to io_queue registered by gap_start_bt_stack.
+ * Message type is @ref GAP_MSG_TYPE.
+ * 2. When use_msg is false, gap will send the gap message using callback function registered by le_register_app_cb.
+ * Message type is @ref GAP_MSG_LE_GAP_STATE_MSG.
+ *
+ * @param[in] use_msg Whether to use message.
+ * @retval void
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ int test(void)
+ {
+ le_gap_msg_info_way(false);
+ }
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: msgType = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_GAP_STATE_MSG:
+ APP_PRINT_INFO0("GAP_MSG_LE_GAP_STATE_MSG");
+ app_handle_gap_msg((T_IO_MSG *)cb_data->p_gap_state_msg);
+ break;
+ ...
+ }
+ }
+
+ * \endcode
+ */
+void le_gap_msg_info_way(bool use_msg);
+
+/**
+ * @brief Get max supported le link count.
+ * @retval max_link_num Max supported le link count.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ link_num = le_get_max_link_num();
+ le_gap_init(link_num);
+ }
+ * \endcode
+ */
+uint8_t le_get_max_link_num(void);
+
+/**
+ * @brief Register app callback from gap le.
+ * @param[in] app_callback callback
+ * @return void
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ le_register_app_cb(app_gap_callback);
+ client_init(1);
+ simple_ble_client_id = simp_ble_add_client(app_client_callback);
+ client_register_general_client_cb(app_client_callback);
+ }
+ * \endcode
+ */
+void le_register_app_cb(P_FUN_LE_APP_CB app_callback);
+
+/**
+ * @brief Set a GAP Common parameter.
+ *
+ * NOTE: You can call this function with a GAP Common Parameter ID and it will set the
+ * GAP Parameter. GAP Peripheral Parameters are defined in (gap.h).
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param Profile parameter ID: @ref T_GAP_LE_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter ID and WILL be cast to the appropriate
+ * data type (For example: if data type param is uint16, p_value will be cast to
+ * pointer of uint16_t).
+ * @return Set result
+ * @retval GAP_CAUSE_SUCCESS Set parameter success.
+ * @retval other Set parameter failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_gap_init(void)
+ {
+ ...
+ //device name and device appearance
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIP";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+
+ //Set device name and device appearance
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_set_gap_param(T_GAP_LE_PARAM_TYPE param, uint8_t len, void *p_value);
+
+/**
+ * @brief Get a GAP Common parameter.
+ *
+ * NOTE: You can call this function with a GAP Common Parameter ID and it will get a
+ * GAP Common Parameter. GAP Common Parameters are defined in (gap.h). Also, the
+ * "p_value" field must point to a "uint16".
+ *
+ * @param[in] param Profile parameter ID: @ref T_GAP_LE_PARAM_TYPE
+ * @param[in,out] p_value Pointer to location to get the parameter value. This is dependent on
+ * the parameter ID and will be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Get result
+ * @retval GAP_CAUSE_SUCCESS Get parameter success.
+ * @retval other Get parameter failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t addr_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t addr[GAP_BD_ADDR_LEN] = {0};
+
+ //get connected device address and address type
+ le_get_gap_param(GAP_PARAM_LATEST_CONN_BD_ADDR_TYPE, &addr_type);
+ le_get_gap_param(GAP_PARAM_LATEST_CONN_BD_ADDR, &addr);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_get_gap_param(T_GAP_LE_PARAM_TYPE param, void *p_value);
+
+/**
+ * @brief Modify local white list.
+ * NOTE: You can call this function to add, remove or clear whist list.
+ * This function can be called after @ref gap_start_bt_stack is invoked.
+ *
+ * @param[in] operation Bluetooth Device Random Address type, @ref T_GAP_RAND_ADDR_TYPE.
+ * @param[in] bd_addr Bluetooth Device Address.
+ * @param[in] bd_type Bluetooth Device Address type.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ T_GAP_WHITE_LIST_OP operation = GAP_WHITE_LIST_OP_ADD;
+ uint8_t *bd_addr = {0};
+ T_GAP_REMOTE_ADDR_TYPE bd_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ le_modify_white_list(operation, bd_addr, bd_type);
+ }
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation 0x%x, cause 0x%x",
+ cb_data.p_le_modify_white_list_rsp->operation,
+ cb_data.p_le_modify_white_list_rsp->cause);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_modify_white_list(T_GAP_WHITE_LIST_OP operation, uint8_t *bd_addr,
+ T_GAP_REMOTE_ADDR_TYPE bd_type);
+
+/**
+ * @brief Generate local random address.
+ * @param[in] rand_addr_type Bluetooth Device Random Address type, @ref T_GAP_RAND_ADDR_TYPE.
+ * @param[in,out] random_bd pointer to Bluetooth Device Address.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ T_GAP_RAND_ADDR_TYPE rand_addr_type = GAP_RAND_ADDR_RESOLVABLE;
+ uint8_t random_bd[BD_ADDR_SIZE] = {0};
+ le_gen_rand_addr(rand_addr_type, random_bd);
+ }
+ *
+ * \endcode
+ */
+T_GAP_CAUSE le_gen_rand_addr(T_GAP_RAND_ADDR_TYPE rand_addr_type, uint8_t *random_bd);
+
+/**
+ * @brief Set local random address.
+ *
+ * NOTE: This function can be called after @ref gap_start_bt_stack is invoked.
+ *
+ * @param[in] random_bd Bluetooth Device Address.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t random_bd[BD_ADDR_SIZE] = {0};
+ le_set_rand_addr(random_bd);
+ }
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_SET_RAND_ADDR:
+ APP_PRINT_INFO1("GAP_MSG_LE_SET_RAND_ADDR: cause 0x%x",
+ cb_data.p_le_set_rand_addr_rsp->cause);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_set_rand_addr(uint8_t *random_bd);
+
+/**
+ * @brief Configure local identity address.
+ *
+ * NOTE: This function can be called before @ref gap_start_bt_stack is invoked.
+ *
+ * @param[in] addr Bluetooth Device Address.
+ * @param[in] type Bluetooth Device Address type.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ T_GAP_IDENT_ADDR_TYPE type = GAP_IDENT_ADDR_PUBLIC;
+ uint8_t addr[BD_ADDR_SIZE] = {0};
+ le_cfg_local_identity_address(addr, type);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_cfg_local_identity_address(uint8_t *addr, T_GAP_IDENT_ADDR_TYPE type);
+
+/**
+* @brief Set the Host Channel Classification for master role.
+*
+* NOTE: This function can be called after @ref gap_start_bt_stack is invoked.
+*
+* @param[in] p_channel_map Channel bit map, the most 3 significant bits are reserved.
+*
+* @retval GAP_CAUSE_SUCCESS: Operation success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t channel_map = 0;
+ le_set_host_chann_classif(channel_map);
+ }
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_SET_HOST_CHANN_CLASSIF:
+ APP_PRINT_INFO1("GAP_MSG_LE_SET_HOST_CHANN_CLASSIF: cause 0x%x",
+ cb_data.p_le_set_host_chann_classif_rsp->cause);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_set_host_chann_classif(uint8_t *p_channel_map);
+
+#if F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT
+/**
+* @brief Specify suggested values for maximum transmission number of payload
+ octets and maximum packet transmission time for new connections.
+*
+* NOTE: This function can be called after @ref gap_start_bt_stack is invoked.
+*
+* @param[in] tx_octets maximum transmission number of payload octets, range: 0x001B-0x00FB
+* @param[in] tx_time maximum packet transmission time, range: 0x0148-0x4290
+*
+* @retval GAP_CAUSE_SUCCESS: Operation success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint16_t tx_octets = 0x00FB;
+ uint16_t tx_time = 0x0848;
+ le_write_default_data_len(tx_octets, tx_time);
+ }
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_WRITE_DEFAULT_DATA_LEN:
+ APP_PRINT_INFO1("GAP_MSG_LE_WRITE_DEFAULT_DATA_LEN: cause 0x%x",
+ cb_data->le_cause.cause);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_write_default_data_len(uint16_t tx_octets, uint16_t tx_time);
+#endif
+
+/**
+* @brief Set Minimum Remote SCA.
+*
+* NOTE: This function can be called after @ref gap_start_bt_stack is invoked.
+*
+* Set Min_sca to compare with M_sca sent by master (carried in CONNECT_REQ pdu).
+* The finally used master sca is set to MIN(Min_sca, M_sca).
+* The default Min_sca is 7.
+* The setting is used by all links in slave role, can set when boot up or link exist, and will reset to default value when HCI_RESET.
+*
+* @param[in] index Minimum Remote SCA Index.
+*
+* @retval GAP_CAUSE_SUCCESS: Operation success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ T_GAP_CAUSE cause;
+ T_GAP_SCA_FIELD_ENCODING index = GAP_SCA_76_TO_100_PPM;
+ cause = le_vendor_set_rem_min_sca(index);
+ }
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_VENDOR_SET_MIN_REM_SCA:
+ APP_PRINT_INFO1("GAP_MSG_LE_VENDOR_SET_MIN_REM_SCA: cause 0x%x",
+ p_data->le_cause.cause);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_vendor_set_rem_min_sca(T_GAP_SCA_FIELD_ENCODING min_sca);
+
+/** @} */ /* End of group GAP_LE_COMMON_Exported_Functions */
+/** @} */ /* End of group GAP_LE_COMMON */
+
+
+/*-------------------------------------------------------------------
+-------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_LE_H */
+
+
+
+
diff --git a/inc/bluetooth/gap/gap_le_rf.h b/inc/bluetooth/gap/gap_le_rf.h
new file mode 100644
index 0000000..4467c56
--- /dev/null
+++ b/inc/bluetooth/gap/gap_le_rf.h
@@ -0,0 +1,656 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_le_rf.h
+* @brief Head file for GAP RF
+* @details
+* @author
+* @date 2020-06-18
+* @version v0.8
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_LE_RF_H
+#define GAP_LE_RF_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#include "gap_le.h"
+
+/** @addtogroup GAP GAP Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE GAP LE Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE_RF GAP LE RF Module
+ * @{
+ */
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GAP_LE_RF_Exported_Macros GAP LE Rf Exported Macros
+ * @{
+ */
+
+/** @defgroup GAP_LE_RF_MSG_Types GAP LE RF Msg Types
+ * @{
+ */
+#define GAP_MSG_LE_RF_INFO 0xD1
+/** End of GAP_LE_RF_MSG_Types
+ * @}
+ */
+
+/** @defgroup GAP_LE_RF_MSG_Opcodes GAP LE RF Msg Opcodes
+ * @{
+ */
+#define GAP_LE_RF_READ_RF_PATH_COMPENSATION 0x0000 //!<Response msg opcode for le_rf_read_rf_path_compensation
+#define GAP_LE_RF_WRITE_RF_PATH_COMPENSATION 0x0001 //!<Response msg opcode for le_rf_write_rf_path_compensation
+
+#define GAP_LE_RF_ENHANCED_READ_TRANSMIT_POWER_LEVEL 0x0010 //!<Response msg opcode for le_rf_enhanced_read_transmit_power_level
+#define GAP_LE_RF_READ_REMOTE_TRANSMIT_POWER_LEVEL 0x0011 //!<Response msg opcode for le_rf_read_remote_transmit_power_level
+#define GAP_LE_RF_SET_TRANSMIT_POWER_REPORTING_ENABLE 0x0012 //!<Response msg opcode for le_rf_set_transmit_power_reporting_enable
+#define GAP_LE_RF_TRANSMIT_POWER_REPORTING_INFO 0x0013 //!<Notification msg opcode for le transmit power reporting
+
+#define GAP_LE_RF_SET_PATH_LOSS_REPORTING_PARAMS 0x0020 //!<Response msg opcode for le_rf_set_path_loss_reporting_params
+#define GAP_LE_RF_SET_PATH_LOSS_REPORTING_ENABLE 0x0021 //!<Response msg opcode for le_rf_set_path_loss_reporting_enable
+#define GAP_LE_RF_PATH_LOSS_THRESHOLD_INFO 0x0022 //!<Notification msg opcode for le path loss threshold
+/**
+ * @}
+ */
+
+/** @defgroup GAP_LE_RF_TRANSMIT_POWER_LEVEL_FLAG_BITS LE transmit power level flag Bits
+* @{
+ */
+#define GAP_LE_RF_TRANSMIT_POWER_LEVEL_FLAG_MIN_BIT 0x01 /**< Transmit power level is at minimum level. */
+#define GAP_LE_RF_TRANSMIT_POWER_LEVEL_FLAG_MAX_BIT 0x02 /**< Transmit power level is at maximum level. */
+/**
+ * @}
+ */
+
+/** End of GAP_LE_RF_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_RF_Exported_Types GAP LE RF Exported Types
+ * @brief
+ * @{
+ */
+typedef enum
+{
+ GAP_LE_RF_POWER_CONTROL_PHYS_1M = 0x01, /**< LE 1M PHY */
+ GAP_LE_RF_POWER_CONTROL_PHYS_2M = 0x02, /**< LE 2M PHY */
+ GAP_LE_RF_POWER_CONTROL_PHYS_CODED_S8 = 0x03, /**< LE Coded PHY with S=8 data coding */
+ GAP_LE_RF_POWER_CONTROL_PHYS_CODED_S2 = 0x04, /**< LE Coded PHY with S=2 data coding */
+} T_GAP_LE_RF_POWER_CONTROL_PHYS_TYPE;
+
+/** @defgroup GAP_LE_RF_CB_Msg_Exported_Types GAP RF Callback Msg Exported Types
+ * @{
+ */
+typedef struct
+{
+ uint16_t cause;
+} T_LE_RF_CAUSE;
+
+#if F_BT_LE_5_0_RF_PATH_SUPPORT
+/** @brief Response for read rf path compensation.*/
+typedef struct
+{
+ uint16_t cause;
+ int16_t rf_tx_path_comp_value;
+ /**< Range: -128.0 dB (0xFB00) to 128.0 dB (0x0500) Units: 0.1 dB */
+ int16_t rf_rx_path_comp_value;
+ /**< Range: -128.0 dB (0xFB00) to 128.0 dB (0x0500) Units: 0.1 dB */
+} T_LE_RF_READ_RF_PATH_COMPENSATION_RSP;
+#endif
+
+#if F_BT_LE_5_2_POWER_CONTROL_SUPPORT
+/** @brief Response for enhanced read transmit power level.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cause;
+ T_GAP_LE_RF_POWER_CONTROL_PHYS_TYPE phy;
+ int8_t cur_tx_power_level;
+ /**< Current transmit power level Range: -127 to 20 Units: dBm
+ Note: 0x7F Current transmit power level is unavailable */
+ int8_t max_tx_power_level;
+ /**< Maximum transmit power level Range: -127 to 20 Units: dBm */
+} T_LE_RF_ENHANCED_READ_TRANSMIT_POWER_LEVEL_RSP;
+
+typedef struct
+{
+ uint16_t cause;
+ uint8_t conn_id;
+} T_LE_RF_READ_REMOTE_TRANSMIT_POWER_LEVEL_RSP;
+
+/** @brief Response for set transmit power reporting enable.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cause;
+} T_LE_RF_SET_TRANSMIT_POWER_REPORTING_ENABLE_RSP;
+
+/** @brief Information for transmit power reporting.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cause;
+ uint8_t reason;
+ /**< 0x00: Local transmit power changed
+ 0x01: Remote transmit power changed
+ 0x02: le read remote transmit power level command completed */
+ T_GAP_LE_RF_POWER_CONTROL_PHYS_TYPE phy;
+ int8_t tx_power_level;
+ /**< Transmit power level Range: -127 to 20 Units: dBm
+ Note: 0x7E Remote device is not managing power levels on this PHY.
+ 0x7F Transmit power level is not available */
+ uint8_t tx_power_level_flag;
+ /**< @ref GAP_LE_RF_TRANSMIT_POWER_LEVEL_FLAG_BITS*/
+ int8_t delta;/**< Change in transmit power level Units: dB
+ positive indicates increased power, negative indicates
+ decreased power, zero indicates unchanged*/
+} T_LE_RF_TRANSMIT_POWER_REPORTING_INFO;
+#endif
+
+#if F_BT_LE_5_2_PATH_LOSS_MONITORING_SUPPORT
+/** @brief Response for set path loss reporting params rsp.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cause;
+} T_LE_RF_SET_PATH_LOSS_REPORTING_PARAMS_RSP;
+
+/** @brief Response for set path loss reporting enable rsp.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cause;
+} T_LE_RF_SET_PATH_LOSS_REPORTING_ENABLE_RSP;
+
+/** @brief Information for path loss threshold.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint8_t current_path_loss; /**< Current path loss Units: dB
+ always zero or positive
+ Note: 0xFF Unavailable */
+ uint8_t zone_entered;/**< 0x00: Entered low zone
+ 0x01: Entered middle zone
+ 0x02: Entered high zone */
+} T_LE_RF_PATH_LOSS_THRESHOLD_INFO;
+#endif
+
+/** @brief GAP RF Callback Data*/
+typedef union
+{
+ T_LE_RF_CAUSE le_rf_cause;
+
+#if F_BT_LE_5_0_RF_PATH_SUPPORT
+ T_LE_RF_READ_RF_PATH_COMPENSATION_RSP *p_le_rf_read_rf_path_compensation_rsp;
+#endif
+
+#if F_BT_LE_5_2_POWER_CONTROL_SUPPORT
+ T_LE_RF_ENHANCED_READ_TRANSMIT_POWER_LEVEL_RSP *p_le_rf_enhanced_read_transmit_power_level_rsp;
+ T_LE_RF_READ_REMOTE_TRANSMIT_POWER_LEVEL_RSP *p_le_rf_read_remote_transmit_power_level_rsp;
+ T_LE_RF_SET_TRANSMIT_POWER_REPORTING_ENABLE_RSP *p_le_rf_set_transmit_power_reporting_enable_rsp;
+ T_LE_RF_TRANSMIT_POWER_REPORTING_INFO *p_le_rf_transmit_power_reporting_info;
+#endif
+#if F_BT_LE_5_2_PATH_LOSS_MONITORING_SUPPORT
+ T_LE_RF_SET_PATH_LOSS_REPORTING_PARAMS_RSP *p_le_rf_set_path_loss_reporting_params_rsp;
+ T_LE_RF_SET_PATH_LOSS_REPORTING_ENABLE_RSP *p_le_rf_set_path_loss_reporting_enable_rsp;
+ T_LE_RF_PATH_LOSS_THRESHOLD_INFO *p_le_rf_path_loss_threshold_info;
+#endif
+} T_GAP_LE_RF_CB_DATA;
+
+typedef struct
+{
+ uint16_t opcode;
+ T_GAP_LE_RF_CB_DATA data;
+} T_GAP_LE_RF_CB;
+/** End of GAP_LE_RF_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup GAP_LE_RF_Exported_Functions GAP LE RF Exported Functions
+ * @brief
+ * @{
+ */
+#if F_BT_LE_5_0_RF_PATH_SUPPORT
+/**
+* @brief Read the RF path compensation Values parameter used in the Tx power level and RSSI calculation.
+* Read result will be returned by @ref app_gap_callback with cb_type @ref GAP_MSG_LE_RF_INFO with
+* opcode @ref GAP_LE_RF_READ_RF_PATH_COMPENSATION.
+*
+* @retval GAP_CAUSE_SUCCESS: Send request success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ T_GAP_CAUSE cause;
+ cause = le_rf_read_rf_path_compensation();
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+ T_GAP_LE_RF_CB *p_le_rf_cb = NULL;
+
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_RF_INFO:
+ APP_PRINT_INFO0("GAP_MSG_LE_RF_INFO");
+ p_le_rf_cb = (T_GAP_LE_RF_CB *)p_data->p_le_cb_data;
+
+ switch (p_le_rf_cb->opcode)
+ {
+ ...
+ #if F_BT_LE_5_0_RF_PATH_SUPPORT
+ case GAP_LE_RF_READ_RF_PATH_COMPENSATION:
+ APP_PRINT_INFO3("GAP_LE_RF_READ_RF_PATH_COMPENSATION:cause 0x%x, rf tx path comp value %d, rf rx path comp value %d",
+ p_le_rf_cb->data.p_le_rf_read_rf_path_compensation_rsp->cause,
+ p_le_rf_cb->data.p_le_rf_read_rf_path_compensation_rsp->rf_tx_path_comp_value,
+ p_le_rf_cb->data.p_le_rf_read_rf_path_compensation_rsp->rf_rx_path_comp_value);
+ break;
+ #endif
+ ...
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_rf_read_rf_path_compensation(void);
+
+/**
+* @brief Indicate the RF path gain or loss between the RF transceiver and the antenna contributed
+* by intermediate components.
+*
+* @param[in] rf_tx_path_comp_value RF Tx Path Compensation
+ Range: -128.0 dB (0xFB00) to 128.0 dB (0x0500)
+ Units: 0.1 dB
+* @param[in] rf_rx_path_comp_value RF Rx Path Compensation
+ Range: -128.0 dB (0xFB00) to 128.0 dB (0x0500)
+ Units: 0.1 dB
+* @retval GAP_CAUSE_SUCCESS: Send request success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ T_GAP_CAUSE cause;
+
+ cause = le_rf_write_rf_path_compensation(rf_tx_path_comp_value,
+ rf_rx_path_comp_value);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+ T_GAP_LE_RF_CB *p_le_rf_cb = NULL;
+
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_RF_INFO:
+ APP_PRINT_INFO0("GAP_MSG_LE_RF_INFO");
+ p_le_rf_cb = (T_GAP_LE_RF_CB *)p_data->p_le_cb_data;
+
+ switch (p_le_rf_cb->opcode)
+ {
+ ...
+ #if F_BT_LE_5_0_RF_PATH_SUPPORT
+ case GAP_LE_RF_WRITE_RF_PATH_COMPENSATION:
+ APP_PRINT_INFO1("GAP_LE_RF_WRITE_RF_PATH_COMPENSATION:cause 0x%x",
+ p_le_rf_cb->data.le_rf_cause.cause);
+ break;
+ #endif
+ ...
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_rf_write_rf_path_compensation(int16_t rf_tx_path_comp_value,
+ int16_t rf_rx_path_comp_value);
+#endif
+
+#if F_BT_LE_5_2_POWER_CONTROL_SUPPORT
+/**
+* @brief Read the current and maximum transmit power levels of the local Controller on the ACL connection and the PHY.
+* Read result will be returned by @ref app_gap_callback with cb_type @ref GAP_MSG_LE_RF_INFO with
+* opcode @ref GAP_LE_RF_ENHANCED_READ_TRANSMIT_POWER_LEVEL.
+*
+* @param[in] conn_id Connection ID
+* @param[in] phy phy physical: @ref T_GAP_LE_RF_POWER_CONTROL_PHYS_TYPE.
+* @retval GAP_CAUSE_SUCCESS: Send request success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail.
+* @retval GAP_CAUSE_NON_CONN: Set request sent fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ T_GAP_CAUSE cause;
+ uint8_t conn_id;
+
+ cause = le_rf_enhanced_read_transmit_power_level(conn_id, phy);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+ T_GAP_LE_RF_CB *p_le_rf_cb = NULL;
+
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_RF_INFO:
+ APP_PRINT_INFO0("GAP_MSG_LE_RF_INFO");
+ p_le_rf_cb = (T_GAP_LE_RF_CB *)p_data->p_le_cb_data;
+
+ switch (p_le_rf_cb->opcode)
+ {
+ ...
+ #if F_BT_LE_5_2_POWER_CONTROL_SUPPORT
+ case GAP_LE_RF_ENHANCED_READ_TRANSMIT_POWER_LEVEL:
+ APP_PRINT_INFO5("GAP_LE_RF_ENHANCED_READ_TRANSMIT_POWER_LEVEL:conn id %d, cause 0x%x, phy %d, cur trans power level %d, max trans power level %d",
+ p_le_rf_cb->data.p_le_rf_enhanced_read_transmit_power_level_rsp->conn_id,
+ p_le_rf_cb->data.p_le_rf_enhanced_read_transmit_power_level_rsp->cause,
+ p_le_rf_cb->data.p_le_rf_enhanced_read_transmit_power_level_rsp->phy,
+ p_le_rf_cb->data.p_le_rf_enhanced_read_transmit_power_level_rsp->cur_tx_power_level,
+ p_le_rf_cb->data.p_le_rf_enhanced_read_transmit_power_level_rsp->max_tx_power_level);
+ break;
+ #endif
+ ...
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_rf_enhanced_read_transmit_power_level(uint8_t conn_id,
+ T_GAP_LE_RF_POWER_CONTROL_PHYS_TYPE phy);
+
+/**
+* @brief Read the transmit power level used by the remote Controller on the ACL connection and the PHY.
+* Read result will be returned by @ref app_gap_callback with cb_type @ref GAP_MSG_LE_RF_INFO with
+* opcode @ref GAP_LE_RF_TRANSMIT_POWER_REPORTING_INFO.
+*
+* @param[in] conn_id Connection ID
+* @param[in] phy phy physical: @ref T_GAP_LE_RF_POWER_CONTROL_PHYS_TYPE.
+* @retval GAP_CAUSE_SUCCESS: Send request success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail.
+* @retval GAP_CAUSE_NON_CONN: Set request sent fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ T_GAP_CAUSE cause;
+ uint8_t conn_id;
+
+ cause = le_rf_read_remote_transmit_power_level(conn_id, phy);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+ T_GAP_LE_RF_CB *p_le_rf_cb = NULL;
+
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_RF_INFO:
+ APP_PRINT_INFO0("GAP_MSG_LE_RF_INFO");
+ p_le_rf_cb = (T_GAP_LE_RF_CB *)p_data->p_le_cb_data;
+
+ switch (p_le_rf_cb->opcode)
+ {
+ ...
+ #if F_BT_LE_5_2_POWER_CONTROL_SUPPORT
+ case GAP_LE_RF_READ_REMOTE_TRANSMIT_POWER_LEVEL:
+ APP_PRINT_INFO2("GAP_LE_RF_SET_TRANSMIT_POWER_REPORTING_ENABLE:conn id %d, cause 0x%x",
+ p_le_rf_cb->data.p_le_rf_read_remote_transmit_power_level_rsp->conn_id,
+ p_le_rf_cb->data.p_le_rf_read_remote_transmit_power_level_rsp->cause);
+ break;
+
+ case GAP_LE_RF_TRANSMIT_POWER_REPORTING_INFO:
+ APP_PRINT_INFO7("GAP_LE_RF_TRANSMIT_POWER_REPORTING_INFO:conn id %d, cause 0x%x, reason 0x%x, phy %d, transmit power level %d, transmit power level flag %d, delta %d",
+ p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->conn_id,
+ p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->cause,
+ p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->reason,
+ p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->phy,
+ p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->tx_power_level,
+ p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->tx_power_level_flag,
+ p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->delta);
+ break;
+ #endif
+ ...
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_rf_read_remote_transmit_power_level(uint8_t conn_id,
+ T_GAP_LE_RF_POWER_CONTROL_PHYS_TYPE phy);
+
+/**
+* @brief Enable or disable the reporting to the local Host of transmit power level changes
+* in the local and remote Controllers for the ACL connection.
+*
+* @param[in] conn_id Connection ID
+* @param[in] local_enable enable or disable local transmit power reports
+* @param[in] remote_enable enable or disable remote transmit power reports
+* @retval GAP_CAUSE_SUCCESS: Send request success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail.
+* @retval GAP_CAUSE_NON_CONN: Set request sent fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ T_GAP_CAUSE cause;
+ uint8_t conn_id;
+
+ cause = le_rf_set_transmit_power_reporting_enable(conn_id, local_enable, remote_enable);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+ T_GAP_LE_RF_CB *p_le_rf_cb = NULL;
+
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_RF_INFO:
+ APP_PRINT_INFO0("GAP_MSG_LE_RF_INFO");
+ p_le_rf_cb = (T_GAP_LE_RF_CB *)p_data->p_le_cb_data;
+
+ switch (p_le_rf_cb->opcode)
+ {
+ ...
+ #if F_BT_LE_5_2_POWER_CONTROL_SUPPORT
+ case GAP_LE_RF_SET_TRANSMIT_POWER_REPORTING_ENABLE:
+ APP_PRINT_INFO2("GAP_LE_RF_SET_TRANSMIT_POWER_REPORTING_ENABLE:conn id %d, cause 0x%x",
+ p_le_rf_cb->data.p_le_rf_set_transmit_power_reporting_enable_rsp->conn_id,
+ p_le_rf_cb->data.p_le_rf_set_transmit_power_reporting_enable_rsp->cause);
+ break;
+
+ case GAP_LE_RF_TRANSMIT_POWER_REPORTING_INFO:
+ APP_PRINT_INFO7("GAP_LE_RF_TRANSMIT_POWER_REPORTING_INFO:conn id %d, cause 0x%x, reason 0x%x, phy %d, transmit power level %d, transmit power level flag %d, delta %d",
+ p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->conn_id,
+ p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->cause,
+ p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->reason,
+ p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->phy,
+ p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->tx_power_level,
+ p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->tx_power_level_flag,
+ p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->delta);
+ break;
+ #endif
+ ...
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_rf_set_transmit_power_reporting_enable(uint8_t conn_id, uint8_t local_enable,
+ uint8_t remote_enable);
+#endif
+
+#if F_BT_LE_5_2_PATH_LOSS_MONITORING_SUPPORT
+/**
+* @brief Set the path loss threshold reporting parameters for the ACL connection
+*
+* @param[in] conn_id Connection ID
+* @param[in] high_threshold High threshold for the path loss
+ Units: dB
+ 0xFF: High Threshold unused
+* @param[in] high_hysteresis Hysteresis value for the high threshold
+ Units: dB
+* @param[in] low_threshold Low threshold for the path loss
+ Units: dB
+* @param[in] low_hysteresis Hysteresis value for the low threshold
+ Units: dB
+* @param[in] min_time_spent Minimum time in number of connection events to be observed once the
+ path crosses the threshold before an event is generated.
+* @retval GAP_CAUSE_SUCCESS: Send request success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail.
+* @retval GAP_CAUSE_NON_CONN: Set request sent fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ T_GAP_CAUSE cause;
+ uint8_t conn_id;
+
+ cause = le_rf_set_path_loss_reporting_params(conn_id, high_threshold, high_hysteresis,
+ low_threshold, low_hysteresis, min_time_spent);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+ T_GAP_LE_RF_CB *p_le_rf_cb = NULL;
+
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_RF_INFO:
+ APP_PRINT_INFO0("GAP_MSG_LE_RF_INFO");
+ p_le_rf_cb = (T_GAP_LE_RF_CB *)p_data->p_le_cb_data;
+
+ switch (p_le_rf_cb->opcode)
+ {
+ ...
+ #if F_BT_LE_5_2_PATH_LOSS_MONITORING_SUPPORT
+ case GAP_LE_RF_SET_PATH_LOSS_REPORTING_PARAMS:
+ APP_PRINT_INFO2("GAP_LE_RF_SET_PATH_LOSS_REPORTING_PARAMS:conn id %d, cause 0x%x",
+ p_le_rf_cb->data.p_le_rf_set_path_loss_reporting_params_rsp->conn_id,
+ p_le_rf_cb->data.p_le_rf_set_path_loss_reporting_params_rsp->cause);
+ break;
+ #endif
+ ...
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_rf_set_path_loss_reporting_params(uint8_t conn_id, uint8_t high_threshold,
+ uint8_t high_hysteresis, uint8_t low_threshold,
+ uint8_t low_hysteresis, uint16_t min_time_spent);
+
+/**
+* @brief Enable or disable path loss reporting.
+*
+* @param[in] conn_id Connection ID
+* @param[in] enable enable or disable path loss reporting
+* @retval GAP_CAUSE_SUCCESS: Send request success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail.
+* @retval GAP_CAUSE_NON_CONN: Set request sent fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ T_GAP_CAUSE cause;
+ uint8_t conn_id;
+
+ cause = le_rf_set_path_loss_reporting_enable(conn_id, enable);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+ T_GAP_LE_RF_CB *p_le_rf_cb = NULL;
+
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_RF_INFO:
+ APP_PRINT_INFO0("GAP_MSG_LE_RF_INFO");
+ p_le_rf_cb = (T_GAP_LE_RF_CB *)p_data->p_le_cb_data;
+
+ switch (p_le_rf_cb->opcode)
+ {
+ ...
+ #if F_BT_LE_5_2_PATH_LOSS_MONITORING_SUPPORT
+ case GAP_LE_RF_SET_PATH_LOSS_REPORTING_ENABLE:
+ APP_PRINT_INFO2("GAP_LE_RF_SET_PATH_LOSS_REPORTING_ENABLE:conn id %d, cause 0x%x",
+ p_le_rf_cb->data.p_le_rf_set_path_loss_reporting_enable_rsp->conn_id,
+ p_le_rf_cb->data.p_le_rf_set_path_loss_reporting_enable_rsp->cause);
+ break;
+
+ case GAP_LE_RF_PATH_LOSS_THRESHOLD_INFO:
+ APP_PRINT_INFO3("GAP_LE_RF_PATH_LOSS_THRESHOLD_INFO:conn id %d, current path loss %d, zone entered %d",
+ p_le_rf_cb->data.p_le_rf_path_loss_threshold_info->conn_id,
+ p_le_rf_cb->data.p_le_rf_path_loss_threshold_info->current_path_loss,
+ p_le_rf_cb->data.p_le_rf_path_loss_threshold_info->zone_entered);
+ break;
+ #endif
+ ...
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_rf_set_path_loss_reporting_enable(uint8_t conn_id, uint8_t enable);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_LE_RF_H */
diff --git a/inc/bluetooth/gap/gap_le_types.h b/inc/bluetooth/gap/gap_le_types.h
new file mode 100644
index 0000000..3d323f5
--- /dev/null
+++ b/inc/bluetooth/gap/gap_le_types.h
@@ -0,0 +1,486 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gap_le_types.h
+ * @brief This file contains all the constants and functions prototypes for GAP protocol.
+ * @details This file is used both bredr and le.
+ * @author jane
+ * @date 2016-02-18
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_LE_TYPES_H
+#define GAP_LE_TYPES_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdint.h>
+#include <stdbool.h>
+#include "upperstack_config.h"
+#include <bt_types.h>
+
+/** @addtogroup GAP_LE_TYPES GAP LE Related Definitions
+ * @brief Defines GAP related definitions.
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @addtogroup GAP_LE_TYPES_Exported_Macros
+ * @{
+ */
+#define GAP_LE_SUPPORTED_FEATURES_LEN 8 //!< LE supported feature length.
+
+/** @defgroup RANDOM_ADDR_MASK Random Address Mask
+ * @{
+ */
+#define RANDOM_ADDR_MASK_STATIC 0xC0 /**< Random address mask for static random address */
+#define RANDOM_ADDR_MASK_RESOLVABLE 0x40 /**< Random address mask for resolvable random address */
+#define RANDOM_ADDR_MASK_NON_RESOLVABLE 0x00 /**< Random address mask for non-resolvable random address */
+#define RANDOM_ADDR_MASK 0xC0 /**< Mask for random address */
+/** End of RANDOM_ADDR_MASK
+ * @}
+ */
+
+/** @defgroup ADV_CHANNEL_MAP Advertising Channel Map
+ * @{
+ */
+#define GAP_ADVCHAN_37 0x01 //!< Advertisement Channel 37
+#define GAP_ADVCHAN_38 0x02 //!< Advertisement Channel 38
+#define GAP_ADVCHAN_39 0x04 //!< Advertisement Channel 39
+#define GAP_ADVCHAN_ALL (GAP_ADVCHAN_37 | GAP_ADVCHAN_38 | GAP_ADVCHAN_39) //!< All Advertisement Channels Enabled
+/** End of ADV_CHANNEL_MAP
+ * @}
+ */
+
+
+/** @defgroup ADV_DATA_TYPE EIR Data Type, Advertising Data Type (AD Type) and OOB Data Type Definitions
+ * @{
+ */
+#define GAP_ADTYPE_FLAGS 0x01 //!< The Flags data type contains one bit Boolean flags. Please reference @ref ADV_TYPE_FLAGS for details.
+#define GAP_ADTYPE_16BIT_MORE 0x02 //!< Service: More 16-bit UUIDs available
+#define GAP_ADTYPE_16BIT_COMPLETE 0x03 //!< Service: Complete list of 16-bit UUIDs
+#define GAP_ADTYPE_32BIT_MORE 0x04 //!< Service: More 32-bit UUIDs available
+#define GAP_ADTYPE_32BIT_COMPLETE 0x05 //!< Service: Complete list of 32-bit UUIDs
+#define GAP_ADTYPE_128BIT_MORE 0x06 //!< Service: More 128-bit UUIDs available
+#define GAP_ADTYPE_128BIT_COMPLETE 0x07 //!< Service: Complete list of 128-bit UUIDs
+#define GAP_ADTYPE_LOCAL_NAME_SHORT 0x08 //!< Shortened local name
+#define GAP_ADTYPE_LOCAL_NAME_COMPLETE 0x09 //!< Complete local name
+#define GAP_ADTYPE_POWER_LEVEL 0x0A //!< TX Power Level: 0xXX: -127 to +127 dBm
+#define GAP_ADTYPE_OOB_CLASS_OF_DEVICE 0x0D //!< Simple Pairing OOB Tag: Class of device (3 octets)
+#define GAP_ADTYPE_OOB_SIMPLE_PAIRING_HASHC 0x0E //!< Simple Pairing OOB Tag: Simple Pairing Hash C (16 octets)
+#define GAP_ADTYPE_OOB_SIMPLE_PAIRING_RANDR 0x0F //!< Simple Pairing OOB Tag: Simple Pairing Randomizer R (16 octets)
+#define GAP_ADTYPE_SM_TK 0x10 //!< Security Manager TK Value
+#define GAP_ADTYPE_SM_OOB_FLAG 0x11 //!< Secutiry Manager OOB Flags
+#define GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE 0x12 //!< Min and Max values of the connection interval (2 octets Min, 2 octets Max) (0xFFFF indicates no conn interval min or max)
+#define GAP_ADTYPE_SIGNED_DATA 0x13 //!< Signed Data field
+#define GAP_ADTYPE_SERVICES_LIST_16BIT 0x14 //!< Service Solicitation: list of 16-bit Service UUIDs
+#define GAP_ADTYPE_SERVICES_LIST_128BIT 0x15 //!< Service Solicitation: list of 128-bit Service UUIDs
+#define GAP_ADTYPE_SERVICE_DATA 0x16 //!< Service Data
+#define GAP_ADTYPE_PUBLIC_TGT_ADDR 0x17 //!< Public Target Address
+#define GAP_ADTYPE_RANDOM_TGT_ADDR 0x18 //!< Random Target Address
+#define GAP_ADTYPE_APPEARANCE 0x19 //!< Appearance
+#define GAP_ADTYPE_ADV_INTERVAL 0x1A //!< Advertising Interval
+#define GAP_ADTYPE_LE_BT_ADDR 0x1B //!< LE Bluetooth Device Address
+#define GAP_ADTYPE_LE_ROLE 0x1C //!< LE Role
+#define GAP_ADTYPE_SP_HASH_C256 0x1D //!< Simple Pairing Hash C-256
+#define GAP_ADTYPE_SP_RAND_R256 0x1E //!< Simple Pairing Randomizer R-256
+#define GAP_ADTYPE_LIST_32BIT_SILI 0x1F //!< List of 32-bit Service Solicitation UUIDs
+#define GAP_ADTYPE_SERVICE_DATA_32BIT 0x20 //!< Service Data - 32-bit UUID
+#define GAP_ADTYPE_SERVICE_DATA_128BIT 0x21 //!< Service Data - 128-bit UUID
+#define GAP_ADTYPE_SC_CONF_VALUE 0x22 //!< LE Secure Connections Confirmation Value
+#define GAP_ADTYPE_SC_RAND_VALUE 0x23 //!< LE Secure Connections Random Value
+#define GAP_ADTYPE_URI 0x24 //!< URI
+#define GAP_ADTYPE_INDOOR_POSITION 0x25 //!< Indoor Positioning
+#define GAP_ADTYPE_TRANSPORT_DISCOVERY_DATA 0x26 //!< Transport Discovery Data
+#define GAP_ADTYPE_LE_SUPPORTED_FEATURES 0x27 //!< LE Supported Features
+#define GAP_ADTYPE_CHAN_MAP_UPDATE_IND 0x28 //!< Channel Map Update Indication
+#define GAP_ADTYPE_MESH_PB_ADV 0x29 //!< Mesh Pb-Adv
+#define GAP_ADTYPE_MESH_PACKET 0x2A //!< Mesh Packet
+#define GAP_ADTYPE_MESH_BEACON 0x2B //!< Mesh Beacon
+#define GAP_ADTYPE_3D_INFO_DATA 0x3D //!< 3D Information Data
+#define GAP_ADTYPE_MANUFACTURER_SPECIFIC 0xFF //!< Manufacturer Specific Data: first 2 octets contain the Company Identifier Code followed by the additional manufacturer specific data
+/** End of ADV_DATA_TYPE
+ * @}
+ */
+
+/** @defgroup ADV_TYPE_FLAGS The Flags data type
+ * @{
+ */
+#define GAP_ADTYPE_FLAGS_LIMITED 0x01 //!< Discovery Mode: LE Limited Discoverable Mode
+#define GAP_ADTYPE_FLAGS_GENERAL 0x02 //!< Discovery Mode: LE General Discoverable Mode
+#define GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED 0x04 //!< Discovery Mode: BR/EDR Not Supported
+#define GAP_ADTYPE_FLAGS_SIMULTANEOUS_LE_BREDR_CONTROLLER 0x08 //!< Discovery Mode: Simultaneous LE and BR/EDR Controller Supported
+#define GAP_ADTYPE_FLAGS_SIMULTANEOUS_LE_BREDR_HOST 0x10 //!< Discovery Mode: Simultaneous LE and BR/EDR Host Supported
+/** @} End ADV_TYPE_FLAGS */
+
+/** @defgroup GAP_LE_APPEARANCE_VALUES GAP Appearance Values
+ * @{
+ */
+#define GAP_GATT_APPEARANCE_UNKNOWN 0
+#define GAP_GATT_APPEARANCE_GENERIC_PHONE 64
+#define GAP_GATT_APPEARANCE_GENERIC_COMPUTER 128
+#define GAP_GATT_APPEARANCE_GENERIC_WATCH 192
+#define GAP_GATT_APPEARANCE_WATCH_SPORTS_WATCH 193
+
+#define GAP_GATT_APPEARANCE_GENERIC_CLOCK 256
+#define GAP_GATT_APPEARANCE_GENERIC_DISPLAY 320
+#define GAP_GATT_APPEARANCE_GENERIC_REMOTE_CONTROL 384
+#define GAP_GATT_APPEARANCE_GENERIC_EYE_GLASSES 448
+#define GAP_GATT_APPEARANCE_GENERIC_TAG 512
+#define GAP_GATT_APPEARANCE_GENERIC_KEYRING 576
+#define GAP_GATT_APPEARANCE_GENERIC_MEDIA_PLAYER 640
+#define GAP_GATT_APPEARANCE_GENERIC_BARCODE_SCANNER 704
+
+#define GAP_GATT_APPEARANCE_GENERIC_THERMOMETER 768
+#define GAP_GATT_APPEARANCE_THERMOMETER_EAR 769
+
+#define GAP_GATT_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832
+#define GAP_GATT_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833
+
+#define GAP_GATT_APPEARANCE_GENERIC_BLOOD_PRESSURE 896
+#define GAP_GATT_APPEARANCE_BLOOD_PRESSURE_ARM 897
+#define GAP_GATT_APPEARANCE_BLOOD_PRESSURE_WRIST 898
+
+#define GAP_GATT_APPEARANCE_HUMAN_INTERFACE_DEVICE 960
+#define GAP_GATT_APPEARANCE_KEYBOARD 961
+#define GAP_GATT_APPEARANCE_MOUSE 962
+#define GAP_GATT_APPEARANCE_JOYSTICK 963
+#define GAP_GATT_APPEARANCE_GAMEPAD 964
+#define GAP_GATT_APPEARANCE_DIGITIZER_TABLET 965
+#define GAP_GATT_APPEARANCE_CARD_READER 966
+#define GAP_GATT_APPEARANCE_DIGITAL_PEN 967
+#define GAP_GATT_APPEARANCE_BARCODE_SCANNER 968
+
+#define GAP_GATT_APPEARANCE_GENERIC_GLUCOSE_METER 1024
+
+#define GAP_GATT_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088
+#define GAP_GATT_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089
+#define GAP_GATT_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090
+#define GAP_GATT_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091
+
+#define GAP_GATT_APPEARANCE_GENERIC_CYCLING 1152
+#define GAP_GATT_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153
+#define GAP_GATT_APPEARANCE_CYCLING_SPEED_SENSOR 1154
+#define GAP_GATT_APPEARANCE_CYCLING_CADENCE_SENSOR 1155
+#define GAP_GATT_APPEARANCE_CYCLING_POWER_SENSOR 1156
+#define GAP_GATT_APPEARANCE_CYCLING_SPEED_AND_CADENCE_SENSOR 1157
+
+#define GAP_GATT_APPEARANCE_GENERIC_PULSE_OXIMETER 3136
+#define GAP_GATT_APPEARANCE_FINGERTIP 3137
+#define GAP_GATT_APPEARANCE_WRIST_WORN 3138
+#define GAP_GATT_APPEARANCE_GENERIC_WEIGHT_SCALE 3200
+
+#define GAP_GATT_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACTIVITY 5184
+#define GAP_GATT_APPEARANCE_LOCATION_DISPLAY_DEVICE 5185
+#define GAP_GATT_APPEARANCE_LOCATION_AND_NAVIGATION_DISPLAY_DEVICE 5186
+#define GAP_GATT_APPEARANCE_LOCATION_POD 5187
+#define GAP_GATT_APPEARANCE_LOCATION_AND_NAVIGATION_POD 5188
+/** @} End GAP_LE_APPEARANCE_VALUES */
+
+#define GAP_PHYS_PREFER_ALL 0
+#define GAP_PHYS_NO_PREFER_TX_BIT 0x01 /**< The Host has no preference among the transmitter PHYs supported by the Controller */
+#define GAP_PHYS_NO_PREFER_RX_BIT 0x02 /**< The Host has no preference among the receiver PHYs supported by the Controller */
+
+#define GAP_PHYS_PREFER_1M_BIT 0x01 /**< The Host prefers to use the LE 1M transmitter PHY (possibly among others) */
+#define GAP_PHYS_PREFER_2M_BIT 0x02 /**< The Host prefers to use the LE 2M transmitter PHY (possibly among others) */
+#define GAP_PHYS_PREFER_CODED_BIT 0x04 /**< The Host prefers to use the LE Coded transmitter PHY (possibly among others) */
+
+/** @defgroup GAP_PHYS_CONN_INIT Connection Initiating PHYs
+ * @{
+ */
+#define GAP_PHYS_CONN_INIT_1M_BIT 0x01/**< Scan connectable advertisements on the LE 1M PHY. Connection
+parameters for the LE 1M PHY are provided. */
+#define GAP_PHYS_CONN_INIT_2M_BIT 0x02 /**< Connection parameters for the LE 2M PHY are provided.*/
+#define GAP_PHYS_CONN_INIT_CODED_BIT 0x04 /**< Scan connectable advertisements on the LE Coded PHY. Connection
+parameters for the LE Coded PHY are provided.*/
+/** End of GAP_PHYS_CONN_INIT
+ * @}
+ */
+
+/** End of GAP_LE_TYPES_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @addtogroup GAP_LE_TYPES_Exported_Types
+ * @{
+ */
+
+/** @brief define local address type */
+typedef enum
+{
+ GAP_LOCAL_ADDR_LE_PUBLIC = 0x00, /**< Bluetooth low energy public address. */
+ GAP_LOCAL_ADDR_LE_RANDOM = 0x01, /**< Bluetooth low energy random address. */
+#if F_BT_LE_PRIVACY_SUPPORT
+ GAP_LOCAL_ADDR_LE_RAP_OR_PUBLIC = 0x02, /**< Controller generates the Resolvable Private Address based on the local
+IRK from the resolving list. If the resolving list contains no matching entry, then use the public address. */
+ GAP_LOCAL_ADDR_LE_RAP_OR_RAND = 0x03 /**< Controller generates the Resolvable Private Address based on the local
+IRK from the resolving list. If the resolving list contains no matching entry, then use the random address from the most recent successful LE_Set_Random_Address Command. */
+ /** @} End GAP_LE_LOCAL_ADDR_TYPE_DEFINES */
+#endif
+} T_GAP_LOCAL_ADDR_TYPE;
+
+/** @brief Define random address type */
+typedef enum
+{
+ GAP_RAND_ADDR_STATIC = 0x00,/**< Static random device address. */
+ GAP_RAND_ADDR_NON_RESOLVABLE = 0x01,/**< Non resolvable random device address. */
+ GAP_RAND_ADDR_RESOLVABLE = 0x02 /**< Resolvable random device address. */
+} T_GAP_RAND_ADDR_TYPE;
+
+/** @brief Define identify address type */
+typedef enum
+{
+ GAP_IDENT_ADDR_PUBLIC = 0x00, /* low energy public address. */
+ GAP_IDENT_ADDR_RAND = 0x01, /* low energy random address. */
+} T_GAP_IDENT_ADDR_TYPE;
+
+/** @brief Definition of LE direct address type.*/
+typedef enum
+{
+ GAP_DIRECT_ADDR_LE_PUBLIC = 0x00, /**< Public Device Address (default) */
+ GAP_DIRECT_ADDR_LE_RAND = 0x01, /**< Random Device Address */
+ GAP_DIRECT_ADDR_LE_PUBLIC_IDENT = 0x02, /**< Public Identity Address (Corresponds to Resolved Private Address ) */
+ GAP_DIRECT_ADDR_LE_RAND_IDENT = 0x03, /**< Random (static) Identity Address (Corresponds to Resolved Private Address) */
+ GAP_DIRECT_ADDR_LE_RAND_UNABLE_RESOLV = 0xFE /**< No address provided (anonymous advertisement) */
+} T_GAP_DIRECT_ADDR_TYPE;
+
+/** @brief Definition of LE white list operation.*/
+typedef enum
+{
+ GAP_WHITE_LIST_OP_CLEAR = 0x00, /**< Clear white list. */
+ GAP_WHITE_LIST_OP_ADD = 0x01, /**< Add a device to the white list. */
+ GAP_WHITE_LIST_OP_REMOVE = 0x02 /**< Remove a device from the white list. */
+} T_GAP_WHITE_LIST_OP;
+
+#if F_BT_LE_GAP_PERIPHERAL_SUPPORT
+/** @brief Advertising Event Types.*/
+typedef enum
+{
+ GAP_ADTYPE_ADV_IND = 0x00, //!< Connectable undirected advertisement
+ GAP_ADTYPE_ADV_HDC_DIRECT_IND = 0x01, //!< Connectable high duty cycle directed advertisement
+ GAP_ADTYPE_ADV_SCAN_IND = 0x02, //!< Scannable undirected advertisement
+ GAP_ADTYPE_ADV_NONCONN_IND = 0x03, //!< Non-Connectable undirected advertisement
+ GAP_ADTYPE_ADV_LDC_DIRECT_IND = 0x04, //!< Connectable low duty cycle directed advertisement
+} T_GAP_ADTYPE;
+
+/** @brief Definition of LE advertising filter policy.*/
+typedef enum
+{
+ GAP_ADV_FILTER_ANY = 0x00, /**< Process scan and connection requests from all devices (i.e., the White List is not in use) (default). */
+ GAP_ADV_FILTER_WHITE_LIST_SCAN = 0x01,/**< Process connection requests from all devices and only scan requests from
+devices that are in the White List. */
+ GAP_ADV_FILTER_WHITE_LIST_CONN = 0x02,/**< Process scan requests from all devices and only connection requests from
+devices that are in the White List. */
+ GAP_ADV_FILTER_WHITE_LIST_ALL = 0x03,/**< Process scan and connection requests only from devices in the White List. */
+} T_GAP_ADV_FILTER_POLICY;
+#endif
+
+#if F_BT_LE_GAP_SCAN_SUPPORT
+/** @brief Definition of LE scan type.*/
+typedef enum
+{
+ GAP_SCAN_MODE_PASSIVE = 0x00, /**< Passive Scanning. No scan request PDUs shall be sent. */
+ GAP_SCAN_MODE_ACTIVE = 0x01 /**< Active Scanning. Scan request PDUs may be sent. */
+} T_GAP_SCAN_MODE;
+
+/** @brief Definition of LE scan filter policy.*/
+typedef enum
+{
+ GAP_SCAN_FILTER_ANY = 0x00, /**< Accept all advertising packets except directed advertising packets not
+addressed to this device (default). */
+ GAP_SCAN_FILTER_WHITE_LIST = 0x01,/**< Accept only advertising packets from devices where the advertiser's
+address is in the White List. Directed advertising packets which are not
+addressed to this device shall be ignored. */
+ GAP_SCAN_FILTER_ANY_RPA = 0x02, /**< Accept all advertising packets except directed advertising packets
+where the initiator's identity address does not address this device.
+Note: Directed advertising packets where the initiator's address is a
+resolvable private address that cannot be resolved are also accepted. */
+ GAP_SCAN_FILTER_WHITE_LIST_RPA = 0x03,/**< Accept all advertising packets except:
+1) advertising packets where the advertiser's identity address is not in
+the White List; and
+2) directed advertising packets where the initiator's identity address
+does not address this device
+Note: Directed advertising packets where the initiator's address is a
+resolvable private address that cannot be resolved are also accepted. */
+} T_GAP_SCAN_FILTER_POLICY;
+
+/** @brief Definition of LE extended scan duplicate filter type.*/
+typedef enum
+{
+ GAP_SCAN_FILTER_DUPLICATE_DISABLE = 0x00, /**< Duplicate filtering disabled. */
+ GAP_SCAN_FILTER_DUPLICATE_ENABLE = 0x01, /**< Duplicate filtering enabled. */
+ GAP_SCAN_FILTER_DUPLICATE_ENABLED_RESET_FOR_EACH_PERIOD = 0x02, /**< Duplicate filtering enabled, reset for each scan period. */
+} T_GAP_SCAN_FILTER_DUPLICATE;
+
+/** This enum type describes adv type for T_GAP_ADV_EVT_TYPE. */
+typedef enum
+{
+ GAP_ADV_EVT_TYPE_UNDIRECTED = 0x00, /**< Connectable undirected advertising. */
+ GAP_ADV_EVT_TYPE_DIRECTED = 0x01, /**< Connectable directed advertising. */
+ GAP_ADV_EVT_TYPE_SCANNABLE = 0x02, /**< Scanable undirected advertising. */
+ GAP_ADV_EVT_TYPE_NON_CONNECTABLE = 0x03, /**< Nonconnectable undirected advertising. */
+ GAP_ADV_EVT_TYPE_SCAN_RSP = 0x04 /**< scan response. */
+} T_GAP_ADV_EVT_TYPE;
+#endif
+
+/** @brief Definition of security level. */
+typedef enum
+{
+ GAP_SEC_LEVEL_NO = 0x00,/**< No security (No authentication and no encryption).*/
+ GAP_SEC_LEVEL_UNAUTHEN = 0x04,/**< Unauthenticated pairing with encryption.*/
+ GAP_SEC_LEVEL_AUTHEN = 0x05,/**< Authenticated pairing with encryption.*/
+ GAP_SEC_LEVEL_SC_UNAUTHEN = 0x07,/**< Unuthenticated LE Secure Connections pairing with encryption using a 128-
+bit strength encryption key.*/
+ GAP_SEC_LEVEL_SC_AUTHEN = 0x08/**< Authenticated LE Secure Connections pairing with encryption using a 128-
+bit strength encryption key.*/
+} T_GAP_SEC_LEVEL;
+
+/** @brief Definition of adv tx power type. */
+typedef enum
+{
+ GAP_ADV_TX_POW_SET_1M, /**< Configure 1M adv tx power. */
+ GAP_ADV_TX_POW_SET_2M, /**< Configure 2M adv tx power. */
+ GAP_ADV_TX_POW_RESET_1M, /**< Reset 1M adv tx power to default value. */
+ GAP_ADV_TX_POW_RESET_2M, /**< Reset 2M adv tx power to default value. */
+} T_GAP_ADV_TX_POW_TYPE;
+
+/** @brief Definition of SCA field encoding. */
+typedef enum
+{
+ GAP_SCA_251_TO_500_PPM = 0, //!< Sleep Clock Accuracy: 251 - 500 ppm.
+ GAP_SCA_151_TO_250_PPM = 1, //!< Sleep Clock Accuracy: 151 - 250 ppm.
+ GAP_SCA_101_TO_150_PPM = 2, //!< Sleep Clock Accuracy: 101 - 150 ppm.
+ GAP_SCA_76_TO_100_PPM = 3, //!< Sleep Clock Accuracy: 76 - 100 ppm.
+ GAP_SCA_51_TO_75_PPM = 4, //!< Sleep Clock Accuracy: 51 - 75 ppm.
+ GAP_SCA_31_TO_50_PPM = 5, //!< Sleep Clock Accuracy: 31 - 50 ppm.
+ GAP_SCA_21_TO_30_PPM = 6, //!< Sleep Clock Accuracy: 21 - 30 ppm.
+ GAP_SCA_0_TO_20_PPM = 7, //!< Sleep Clock Accuracy: 0 - 20 ppm.
+ GAP_SCA_INVALID = 8 //!< Invalid Sleep Clock Accuracy.
+} T_GAP_SCA_FIELD_ENCODING;
+
+#if F_BT_LE_PRIVACY_SUPPORT
+/** @brief Definition of LE resolving list operation.*/
+typedef enum
+{
+ GAP_RESOLV_LIST_OP_CLEAR = 0x00, /**< Clear resolving list operation. */
+ GAP_RESOLV_LIST_OP_ADD = 0x01, /**< Add a device to the resolving list operation. */
+ GAP_RESOLV_LIST_OP_REMOVE = 0x02 /**< Remove a device from the resolving list operation. */
+} T_GAP_RESOLV_LIST_OP;
+
+/** @brief Definition of LE privacy mode.*/
+typedef enum
+{
+ GAP_PRIVACY_MODE_NETWORK = 0x00, /**< Network privacy mode. */
+ GAP_PRIVACY_MODE_DEVICE = 0x01 /**< Device privacy mode. */
+} T_GAP_PRIVACY_MODE;
+#endif
+
+/** @brief Definition of LE PHY type.*/
+typedef enum
+{
+ GAP_PHYS_1M = 0x01, /**< LE PHY 1M used. */
+ GAP_PHYS_2M = 0x02, /**< LE PHY 2M used. */
+ GAP_PHYS_CODED = 0x03 /**< LE Coded PHY used. */
+} T_GAP_PHYS_TYPE;
+
+/** @brief Definition of LE primary advertising PHY type.*/
+typedef enum
+{
+ GAP_PHYS_PRIM_ADV_1M = 0x01, /**< Primary advertisement PHY is LE 1M */
+ GAP_PHYS_PRIM_ADV_CODED = 0x03 /**< Primary advertisement PHY is LE Coded */
+} T_GAP_PHYS_PRIM_ADV_TYPE;
+
+/** @brief Definition of LE Coded PHY preference options.*/
+typedef enum
+{
+ GAP_PHYS_OPTIONS_CODED_PREFER_NO = 0x00,/**< Host has no preferred coding when transmitting on the LE Coded PHY */
+ GAP_PHYS_OPTIONS_CODED_PREFER_S2 = 0x01,/**< Host prefers that S=2 coding be used when transmitting on the LE Coded PHY */
+ GAP_PHYS_OPTIONS_CODED_PREFER_S8 = 0x02 /**< Host prefers that S=8 coding be used when transmitting on the LE Coded PHY */
+} T_GAP_PHYS_OPTIONS;
+
+#if F_BT_LE_5_0_AE_SCAN_SUPPORT
+typedef enum
+{
+ GAP_EXT_ADV_EVT_DATA_STATUS_COMPLETE = 0x00, /**< Data status: Complete */
+ GAP_EXT_ADV_EVT_DATA_STATUS_MORE = 0x01, /**< Data status: Incomplete, more data to come */
+ GAP_EXT_ADV_EVT_DATA_STATUS_TRUNCATED = 0x02, /**< Data status: Incomplete, data truncated, no more to come */
+ GAP_EXT_ADV_EVT_DATA_STATUS_RFU = 0x03 /**< Data status: Reserved for future use */
+} T_GAP_EXT_ADV_EVT_DATA_STATUS;
+#endif
+
+#if F_BT_LE_APP_KEY_MANAGER
+typedef enum
+{
+ GATT_STORE_OP_GET_CCC_BITS, /**< get CCC Bits for one <bd_addr,bdtype> */
+ GATT_STORE_OP_SET_CCC_BITS, /**< set CCC Bits for one <bd_addr,bdtype> */
+ GATT_STORE_OP_DELETE_ALL_CCC_BITS, /**< delete all CCC Bits for all peers */
+} T_GATT_STORE_OPCODE;
+#endif
+
+typedef enum
+{
+ GAP_CTE_TYPE_AOA = 0x00, /**< AoA Constant Tone Extension> */
+ GAP_CTE_TYPE_AOD_1US_SLOT = 0x01, /**< AoD Constant Tone Extension with 1 us slots> */
+ GAP_CTE_TYPE_AOD_2US_SLOT = 0x02, /**< AoD Constant Tone Extension with 2 us slots> */
+} T_GAP_CTE_TYPE;
+
+typedef enum
+{
+ GAP_SLOT_DURATIONS_SWITCH_SAMPLE_1US = 0x01, /**<Switching and sampling slots are 1 us each> */
+ GAP_SLOT_DURATIONS_SWITCH_SAMPLE_2US = 0x02, /**<Switching and sampling slots are 2 us each> */
+} T_GAP_SLOT_DUATIONS_TYPE;
+
+#if F_BT_LE_5_0_PA_SYNC_SUPPORT
+/** @brief Definition of LE periodic advertiser list operation.*/
+typedef enum
+{
+ GAP_PA_SYNC_PERIODIC_ADV_LIST_OP_CLEAR = 0x00, /**< Clear periodic advertiser list. */
+ GAP_PA_SYNC_PERIODIC_ADV_LIST_OP_ADD = 0x01, /**< Add an entry to the periodic advertiser list. */
+ GAP_PA_SYNC_PERIODIC_ADV_LIST_OP_REMOVE = 0x02 /**< Remove an entry from the periodic advertiser list. */
+} T_GAP_PA_SYNC_PERIODIC_ADV_LIST_OP;
+
+typedef enum
+{
+ GAP_PERIODIC_ADV_REPORT_DATA_STATUS_COMPLETE = 0x00, /**< Data complete */
+ GAP_PERIODIC_ADV_REPORT_DATA_STATUS_MORE = 0x01, /**< Data incomplete, more data to come */
+ GAP_PERIODIC_ADV_REPORT_DATA_STATUS_TRUNCATED = 0x02, /**< Data incomplete, data truncated, no more to come */
+} T_GAP_PERIODIC_ADV_REPORT_DATA_STATUS;
+
+typedef enum
+{
+ GAP_PERIODIC_ADV_REPORT_CTE_TYPE_AOA_CTE = 0x00, /**< AoA Constant Tone Extension */
+ GAP_PERIODIC_ADV_REPORT_CTE_TYPE_AOD_CTE_1US = 0x01, /**< AoD Constant Tone Extension with 1 μs slots */
+ GAP_PERIODIC_ADV_REPORT_CTE_TYPE_AOD_CTE_2US = 0x02, /**< AoD Constant Tone Extension with 2 μs slots */
+ GAP_PERIODIC_ADV_REPORT_CTE_TYPE_NO_CTE = 0xFF, /**< No Constant Tone Extension */
+} T_GAP_PERIODIC_ADV_REPORT_CTE_TYPE;
+#endif
+/** End of GAP_LE_TYPES_Exported_Types
+ * @}
+ */
+
+/** @} */ /* End of group GAP_LE_TYPES */
+
+
+/*-------------------------------------------------------------------
+-------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_H */
diff --git a/inc/bluetooth/gap/gap_lib/gap_config.h b/inc/bluetooth/gap/gap_lib/gap_config.h
new file mode 100644
index 0000000..27cfc0c
--- /dev/null
+++ b/inc/bluetooth/gap/gap_lib/gap_config.h
@@ -0,0 +1,280 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_config.h
+* @brief Header file for configuration of bt stack related features
+* @details This file defines configuration of bt stack related features related API.
+* @author ranhui
+* @date 2016-02-18
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_CONFIG_H
+#define GAP_CONFIG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "gap_le_types.h"
+#include "app_section.h"
+
+/** @addtogroup GAP GAP Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE GAP LE Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE_CONFIG GAP LE Config Module
+ * @{
+ */
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_CONFIG_Exported_Types GAP LE Config Exported Types
+ * @{
+ */
+
+/** @brief GAP gatt cccd not check. */
+typedef enum
+{
+ CONFIG_GATT_CCCD_CHECK, /**< Check cccd when server sends notification or indication. */
+ CONFIG_GATT_CCCD_NOT_CHECK, /**< Not check cccd when server sends notification or indication. */
+} T_GAP_CONFIG_GATT_CCCD_NOT_CHECK;
+
+/** @brief GAP set minimum remote SCA automatically in GAP initialization. */
+typedef enum
+{
+ CONFIG_LE_MIN_REM_SCA = 1, /**< Set minimum remote SCA automatically in GAP initialization. */
+} T_GAP_CONFIG_LE_MIN_REM_SCA_INIT;
+
+/** End of GAP_LE_CONFIG_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup GAP_LE_CONFIG_Exported_Functions GAP LE Config Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Configure whether to check cccd when server sends notification or indication.
+ *
+ * @param[in] cccd_not_check_flag Whether to check cccd: @ref T_GAP_CONFIG_GATT_CCCD_NOT_CHECK
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ APP_FLASH_TEXT_SECTION void bt_stack_config_init(void)
+ {
+ gap_config_cccd_not_check(CONFIG_GATT_CCCD_NOT_CHECK);
+ }
+ * \endcode
+ */
+APP_FLASH_TEXT_SECTION void gap_config_cccd_not_check(T_GAP_CONFIG_GATT_CCCD_NOT_CHECK
+ cccd_not_check_flag);
+
+/**
+ * @brief Configure whether to set minimum remote SCA automatically in GAP initialization.
+ *
+ * @param[in] le_min_rem_sca_flag whether to set minimum remote SCA automatically in GAP initialization, @ref T_GAP_CONFIG_LE_MIN_REM_SCA_INIT
+ * @param[in] le_min_rem_sca_encoding SCA field encoding, @ref T_GAP_SCA_FIELD_ENCODING
+ Note: The value is valid if le_min_rem_sca_flag is set to CONFIG_LE_MIN_REM_SCA, and will be replaced
+ if app calls @ref le_set_gap_param() with parameter @ref GAP_PARAM_SET_REM_MIN_SCA.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ APP_FLASH_TEXT_SECTION void bt_stack_config_init(void)
+ {
+ gap_config_le_min_rem_sca(CONFIG_LE_MIN_REM_SCA, GAP_SCA_31_TO_50_PPM);
+ }
+ * \endcode
+ */
+APP_FLASH_TEXT_SECTION void gap_config_le_min_rem_sca(T_GAP_CONFIG_LE_MIN_REM_SCA_INIT
+ le_min_rem_sca_flag,
+ T_GAP_SCA_FIELD_ENCODING le_min_rem_sca_encoding);
+
+/**
+ * @brief Configure bte pool size.
+ * NOTE: Default value of size is 4 * 1024.
+ *
+ * @param[in] bte_pool_size bte pool size in units of 1024, range: 4 ~ 10. NOTE: The range may be changed in future version.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ APP_FLASH_TEXT_SECTION void bt_stack_config_init(void)
+ {
+ //bte pool size is 6 * 1024
+ gap_config_bte_pool_size(6);
+ }
+ * \endcode
+ */
+APP_FLASH_TEXT_SECTION void gap_config_bte_pool_size(uint8_t bte_pool_size);
+
+/**
+ * @brief Configure bt report buffer number for observer role or central role.
+ * NOTE: Default value is 16.
+ *
+ * @param[in] bt_report_buf_num bt report buffer number
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ APP_FLASH_TEXT_SECTION void bt_stack_config_init(void)
+ {
+ gap_config_bt_report_buf_num(17);
+ }
+ * \endcode
+ */
+APP_FLASH_TEXT_SECTION void gap_config_bt_report_buf_num(uint8_t bt_report_buf_num);
+
+/**
+ * @brief Configure maximum server CCCD number and maximum storage CCCD number.
+ *
+ * @param[in] gatt_server_ccc_bits_count maximum server CCCD number, default value is 16.
+ * @param[in] gatt_storage_ccc_bits_count maximum storage CCCD number, default value is 16.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ APP_FLASH_TEXT_SECTION void bt_stack_config_init(void)
+ {
+ gap_config_ccc_bits_count(18, 18);
+ }
+ * \endcode
+ */
+APP_FLASH_TEXT_SECTION void gap_config_ccc_bits_count(uint8_t gatt_server_ccc_bits_count,
+ uint8_t gatt_storage_ccc_bits_count);
+
+/**
+ * @brief Configure maximum service table number for GATT server.
+ * NOTE: Default value is 12. The number of service table can be used by app is (gatt_max_attribute_table_count - 1).
+ *
+ * @param[in] gatt_max_attribute_table_count maximum service table number.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ APP_FLASH_TEXT_SECTION void bt_stack_config_init(void)
+ {
+ gap_config_max_attribute_table_count(14);
+ }
+ * \endcode
+ */
+APP_FLASH_TEXT_SECTION void gap_config_max_attribute_table_count(uint8_t
+ gatt_max_attribute_table_count);
+
+/**
+ * @brief Configure maximum size of Maximum Transmission Unit.
+ * NOTE: Default value is 247.
+ *
+ * @param[in] att_max_mtu_size maximum size of Maximum Transmission Unit.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ APP_FLASH_TEXT_SECTION void bt_stack_config_init(void)
+ {
+ gap_config_max_mtu_size(200);
+ }
+ * \endcode
+ */
+APP_FLASH_TEXT_SECTION void gap_config_max_mtu_size(uint16_t att_max_mtu_size);
+
+/**
+ * @brief Configure key storage flag to determine keys that need to be saved.
+ *
+ * NOTE: Storage bits are defined by group GAP_LE_STORAGE_BITS in gap_storage_le.h.
+ storage bit: 0-not save, 1-save.
+ Default value is 0xFF, which indicates all keys need to be saved.
+ *
+ * @param[in] le_key_storage_flag key storage flag to determine keys that need to be saved
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ APP_FLASH_TEXT_SECTION void bt_stack_config_init(void)
+ {
+ gap_config_le_key_storage_flag(LE_KEY_STORE_CCCD_DATA_BIT | LE_KEY_STORE_REMOTE_LTK_BIT | LE_KEY_STORE_REMOTE_BD_BIT);
+ }
+ * \endcode
+ */
+APP_FLASH_TEXT_SECTION void gap_config_le_key_storage_flag(uint16_t le_key_storage_flag);
+
+/**
+ * @brief Configure LE maximum bonded device number.
+ *
+ * NOTE: Default value is 1.
+ *
+ * @param[in] max_le_paired_device LE maximum bonded device number
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ APP_FLASH_TEXT_SECTION void bt_stack_config_init(void)
+ {
+ gap_config_max_le_paired_device(2);
+ }
+ * \endcode
+ */
+APP_FLASH_TEXT_SECTION void gap_config_max_le_paired_device(uint8_t max_le_paired_device);
+
+/**
+ * @brief Print parameters configured by app.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ gap_config_print_config_param();
+ }
+ * \endcode
+ */
+void gap_config_print_config_param(void);
+
+/**
+ * @brief Configure periodic advertising parameter.
+ *
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ APP_FLASH_TEXT_SECTION void bt_stack_config_init(void)
+ {
+ gap_config_pa_parameter();
+ }
+ * \endcode
+ */
+APP_FLASH_TEXT_SECTION void gap_config_pa_parameter(void);
+
+/** End of GAP_LE_CONFIG_Exported_Functions
+ * @}
+ */
+
+/** End of GAP_LE_CONFIG
+ * @}
+ */
+
+/** End of GAP_LE
+ * @}
+ */
+
+/** End of GAP
+ * @}
+ */
+
+
+#endif
+#ifdef __cplusplus
+}
+
+#endif /* GAP_CONFIG_H */
+
diff --git a/inc/bluetooth/gap/gap_lib/gap_vendor.h b/inc/bluetooth/gap/gap_lib/gap_vendor.h
new file mode 100644
index 0000000..e50bf11
--- /dev/null
+++ b/inc/bluetooth/gap/gap_lib/gap_vendor.h
@@ -0,0 +1,499 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gap_vendor.h
+ * @brief
+ * @details
+ * @author ranhui_xia
+ * @date 2017-08-02
+ * @version v1.0
+ ******************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ ******************************************************************************
+ */
+#ifndef GAP_VNR_H
+#define GAP_VNR_H
+
+#include <gap_le.h>
+
+/** @addtogroup GAP_LE_VENDOR GAP LE vendor command API.
+ * @brief GAP LE vendor command API provides extended function for controller.
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup Gap_LE_Vendor_Exported_Macros GAP LE Vendor Exported Macros
+ * @{
+ */
+
+/** @defgroup GAP_LE_MSG_Types GAP LE Msg Types
+ * @{
+ */
+#define GAP_MSG_LE_VENDOR_ADV_3_DATA_ENABLE 0xA0 //!<Response msg type for le_vendor_adv_3_data_enable
+#define GAP_MSG_LE_VENDOR_ADV_3_DATA_SET 0xA1 //!<Response msg type for le_vendor_adv_3_data_set
+#define GAP_MSG_LE_VENDOR_DROP_ACL_DATA 0xA4 //!<Response msg type for le_vendor_drop_acl_data
+#define GAP_MSG_GAP_SW_RESET 0xA5 //!<Response msg type for gap_sw_reset_req
+#define GAP_MSG_GAP_SET_LPS_BOOTUP_ACTIVE_TIME 0xA6 //!<Response msg type for gap_set_lps_bootup_active_time
+#define GAP_MSG_LE_AE_CODING_SCHEME 0xA7 //!<Response msg type for le_ae_coding_scheme
+#define GAP_MSG_LE_VENDOR_SET_PRIORITY 0xA8
+#define GAP_MSG_LE_VENDOR_AE_SCHEME 0xA9
+#define GAP_MSG_LE_VENDOR_MEASURE_MASTER_CLK_FREQ 0xAA
+#define GAP_MSG_LE_VENDOR_MORE_PRECISE_32K 0xAB
+#define GAP_MSG_LE_VENDOR_TRIGGER_INTERNAL_32K_CALIBRATION 0xAC
+
+/**
+ * @}
+ */
+
+/** @defgroup GAP_VENDOR_MSG_TYPE GAP Vendor Msg Types
+ * @{
+ */
+/*GAP Vendor Msg Types */
+#define GAP_MSG_GAP_VENDOR_READ_THERMAL_METER_DATA 0xAF
+#define GAP_MSG_GAP_VENDOR_SET_ANT_CTRL 0xB0
+
+/*GAP LE Vendor Msg Types */
+#define GAP_MSG_LE_VENDOR_UPDATE_CONN_PARAM 0xB1
+
+/**
+ * @}
+ */
+
+/** End of GAP_LE_Vendor_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_Vendor_Exported_Types GAP LE Vendor Exported Types
+ * @{
+ */
+
+typedef enum
+{
+ GAP_SW_RESET_WHEN_ADV = 1,
+} T_GAP_SW_RESET_MODE;
+
+/** @brief Coding scheme of LE Coded PHY when device uses LE Advertising Extensions.*/
+typedef enum
+{
+ GAP_AE_CODING_SCHEME_S8 = 2,
+ GAP_AE_CODING_SCHEME_S2 = 3,
+} T_GAP_AE_CODING_SCHEME;
+
+/** @brief Mode of setting priority. */
+typedef enum
+{
+ GAP_VENDOR_UPDATE_PRIORITY, //!< Set priority without operation of resetting priority
+ GAP_VENDOR_SET_PRIORITY, //!< Set priority after operation of resetting priority
+ GAP_VENDOR_RESET_PRIORITY, //!< Reset priority
+} T_GAP_VENDOR_SET_PRIORITY_MODE;
+
+/** @brief Definition of priority level. */
+typedef enum
+{
+ GAP_VENDOR_PRIORITY_LEVEL_0,
+ GAP_VENDOR_PRIORITY_LEVEL_1,
+ GAP_VENDOR_PRIORITY_LEVEL_2,
+ GAP_VENDOR_PRIORITY_LEVEL_3,
+ GAP_VENDOR_PRIORITY_LEVEL_4,
+ GAP_VENDOR_PRIORITY_LEVEL_5,
+ GAP_VENDOR_PRIORITY_LEVEL_6,
+ GAP_VENDOR_PRIORITY_LEVEL_7,
+ GAP_VENDOR_PRIORITY_LEVEL_8,
+ GAP_VENDOR_PRIORITY_LEVEL_9,
+ GAP_VENDOR_PRIORITY_LEVEL_10, //!< Highest priority
+ GAP_VENDOR_RESERVED_PRIORITY,
+} T_GAP_VENDOR_PRIORITY_LEVEL;
+
+/** @brief Mode of setting link priority. */
+typedef enum
+{
+ GAP_VENDOR_NOT_SET_LINK_PRIORITY, //!< Not set priority of link
+ GAP_VENDOR_SET_SPECIFIC_LINK_PRIORITY, //!< Set priority of specific links
+ GAP_VENDOR_SET_ALL_LINK_PRIORITY, //!< Set priority of all link
+} T_GAP_VENDOR_SET_LINK_PRIORITY_MODE;
+
+/** @brief Definition of common priority. */
+typedef struct
+{
+ bool set_priority_flag;
+ T_GAP_VENDOR_PRIORITY_LEVEL priority_level; /**< Priority is valid if set_priority_flag is true. */
+} T_GAP_VENDOR_COMMON_PRIORITY;
+
+/** @brief Definition of connection priority. */
+typedef struct
+{
+ uint8_t conn_id;
+ T_GAP_VENDOR_PRIORITY_LEVEL conn_priority_level;/**< Priority of specific connection. */
+} T_GAP_VENDOR_CONN_PRIORITY;
+
+/** @brief Parameters of setting priority.*/
+typedef struct
+{
+ T_GAP_VENDOR_SET_PRIORITY_MODE set_priority_mode;/**< Mode of setting priority.
+ (@ref T_GAP_VENDOR_SET_PRIORITY_MODE). */
+ T_GAP_VENDOR_COMMON_PRIORITY adv_priority;/**< Priority of advertising.
+ (@ref T_GAP_VENDOR_COMMON_PRIORITY). */
+ T_GAP_VENDOR_COMMON_PRIORITY scan_priority;/**< Priority of scan.
+ (@ref T_GAP_VENDOR_COMMON_PRIORITY). */
+ T_GAP_VENDOR_COMMON_PRIORITY initiate_priority;/**< Priority of initiating.
+ (@ref T_GAP_VENDOR_COMMON_PRIORITY). */
+ T_GAP_VENDOR_SET_LINK_PRIORITY_MODE link_priority_mode;/**< Mode of setting link priority.
+ (@ref T_GAP_VENDOR_SET_LINK_PRIORITY_MODE). */
+ T_GAP_VENDOR_PRIORITY_LEVEL link_priority_level;/**< Priority of all link is valid
+ if link_priority_mode is GAP_VENDOR_SET_ALL_LINK_PRIORITY. */
+ uint8_t num_conn_ids;/**< Number of specific links is valid if link_priority_mode is GAP_VENDOR_SET_SPECIFIC_LINK_PRIORITY. */
+ T_GAP_VENDOR_CONN_PRIORITY p_conn_id_list[1];/**< List of connection priority is valid
+ if link_priority_mode is GAP_VENDOR_SET_SPECIFIC_LINK_PRIORITY.
+ (@ref T_GAP_VENDOR_CONN_PRIORITY). */
+} T_GAP_VENDOR_PRIORITY_PARAM;
+
+typedef struct
+{
+ uint16_t cause;
+} T_GAP_VENDOR_CAUSE;
+
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cause;
+} T_LE_VENDOR_UPDATE_CONN_PARAM_RSP;
+
+typedef struct
+{
+ uint16_t cause;
+ int16_t thermal_celsius;
+} T_GAP_VENDOR_READ_THERMAL_METER_DATA_RSP;
+
+typedef union
+{
+ T_GAP_VENDOR_CAUSE gap_vendor_cause;
+ T_LE_VENDOR_UPDATE_CONN_PARAM_RSP *p_le_vendor_update_conn_param_rsp;
+ T_GAP_VENDOR_READ_THERMAL_METER_DATA_RSP *p_gap_vendor_read_thermal_meter_data_rsp;
+} T_GAP_VENDOR_CB_DATA;
+
+/** End of GAP_LE_Vendor_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/** @defgroup GAP_LE_VENDOR_Exported_Functions GAP LE vendor command Exported Functions
+ * @brief GAP LE vendor command Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Register callback to vendor command, when messages in @ref GAP_VENDOR_MSG_TYPE happens, it will callback to app.
+ * @param[in] vendor_callback Callback function provided by the APP to handle @ref GAP_VENDOR_MSG_TYPE messages sent from the GAP.
+ * @arg NULL -> Not send @ref GAP_VENDOR_MSG_TYPE messages to APP.
+ * @arg Other -> Use application defined callback function.
+ * @return void
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_gap_init(void)
+ {
+ ......
+ gap_register_vendor_cb(app_gap_vendor_callback);
+ }
+ void app_gap_vendor_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_GAP_VENDOR_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_GAP_VENDOR_CB_DATA));
+ APP_PRINT_INFO1("app_gap_vendor_callback: cb_type is %d", cb_type);
+ switch (cb_type)
+ {
+ case GAP_MSG_GAP_VENDOR_SET_ANT_CTRL:
+ APP_PRINT_INFO1("GAP_MSG_GAP_VENDOR_SET_ANT_CTRL: cause 0x%x",
+ cb_data.gap_vendor_cause.cause);
+ break;
+ default:
+ break;
+ }
+ return;
+ }
+ \endcode
+ */
+void gap_register_vendor_cb(P_FUN_GAP_APP_CB vendor_callback);
+
+/**
+ * @brief Enable 3 advertising channel advertising data.
+ * Set 3 adv data please reference to @ref le_vendor_adv_3_data_enable.
+ *
+ * @param[in] enable 0: disable, 1: enable each adv channel with diff data.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS: Operation success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void gap_vendor_test(bool enable)
+ {
+ ...
+ cause = le_vendor_adv_3_data_enable(enable);
+ return cause;
+ }
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_VENDOR_ADV_3_DATA_ENABLE:
+ APP_PRINT_INFO1("GAP_MSG_LE_VENDOR_ADV_3_DATA_ENABLE: cause 0x%x",
+ p_data->le_cause.cause);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_vendor_adv_3_data_enable(bool enable);
+
+/**
+ * @brief Set different advertising date or scan response data in 3 advertising channel.
+ * This command is used to set 38 / 39 channel data, set 37 channel data please use normal HCI command.
+ * It is necessary to enable 3 adv data with @ref le_vendor_adv_3_data_enable.
+ *
+ * @param[in] type LE vendor advertising data type @ref T_GAP_ADV_VENDOR_DATA_TYPE.
+ * @param[in] len The number of significant octets in the advertising data.
+ * @param[in] p_data Pointer to data to write
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS: Operation success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ * @retval GAP_CAUSE_INVALID_PARAM: Invalid parameter.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_GAP_CAUSE gap_vendor_test(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ T_GAP_CAUSE cause;
+ T_GAP_ADV_VENDOR_DATA_TYPE type = (T_GAP_ADV_VENDOR_DATA_TYPE)p_parse_value->dw_param[0];
+ uint8_t len = p_parse_value->dw_param[1];
+ uint8_t value = p_parse_value->dw_param[2];
+ uint8_t adv_data[31];
+ if (len > GAP_MAX_ADV_LEN)
+ {
+ return (RESULT_ERR);
+ }
+ memset(adv_data, value, len);
+
+ cause = le_vendor_adv_3_data_set((T_GAP_ADV_VENDOR_DATA_TYPE)type, len, adv_data);
+ return (T_GAP_CAUSE)cause;
+ }
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_VENDOR_ADV_3_DATA_SET:
+ APP_PRINT_INFO2("GAP_MSG_LE_VENDOR_ADV_3_DATA_SET: type %d, cause 0x%x",
+ p_data->p_le_vendor_adv_3_data_set_rsp->type,
+ p_data->p_le_vendor_adv_3_data_set_rsp->cause);
+ break;
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_vendor_adv_3_data_set(T_GAP_ADV_VENDOR_DATA_TYPE type,
+ uint8_t len, uint8_t *p_data);
+
+/**
+ * @brief LE Drop Acl Data
+ *
+ * Drop pending LE acl packet that assigned by user except the acl packet which is currently waiting for ack.
+ * The packet-dropping rule is cleared if link is disconnected or HCI_RESET.
+ *
+ * @param[in] conn_id Connection ID for this link.
+ * @param[in] mask Assign the mask to compare with data.
+ * @param[in] pattern Drop data that match pattern
+ * @param[in] offset The offset in bytes started from Data
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS: Operation success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_vdropdata(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ T_GAP_CAUSE cause;
+ uint8_t conn_id = p_parse_value->dw_param[0];
+
+ cause = le_vendor_drop_acl_data(conn_id, 0xffff, 0x0015, 5);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_VENDOR_DROP_ACL_DATA:
+ APP_PRINT_INFO1("GAP_MSG_LE_VENDOR_DROP_ACL_DATA: cause 0x%x",
+ p_data->le_cause.cause);
+ break;
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_vendor_drop_acl_data(uint8_t conn_id, uint16_t mask, uint16_t pattern,
+ uint8_t offset);
+
+/**
+ * @brief Modify BT LE Fw Policy
+ *
+ * Modify the firmware bt le policy
+ *
+ * @param[in] mask Assign the mask to compare with data.
+ * @param[in] mask Assign the mask to compare with data.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS: Operation success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ */
+T_GAP_CAUSE le_vendor_modify_bt_le_fw_policy(uint32_t mask, uint32_t value);
+
+/**
+ * @brief Reset BT controller
+ *
+ * @param[in] reset_mode GAP software reset mode @ref T_GAP_SW_RESET_MODE.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS: Operation success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_reset(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ T_GAP_CAUSE cause;
+ T_GAP_SW_RESET_MODE reset_mode = (T_GAP_SW_RESET_MODE)p_parse_value->dw_param[0];
+ cause = gap_sw_reset_req(reset_mode);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_GAP_SW_RESET:
+ APP_PRINT_INFO1("GAP_MSG_GAP_SW_RESET: cause 0x%x",
+ p_data->le_cause.cause);
+ break;
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gap_sw_reset_req(T_GAP_SW_RESET_MODE reset_mode);
+
+/**
+ * @brief Set platform bootup active time.
+ *
+ * Platform allowed to enter low power mode after this timeout value.
+ * Can use this command in any time even low power mode is set.
+ *
+ * @param[in] active_time Unit: 50msec, Range:0x03-0x800. Default value is 5 sec.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_lpstime(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint16_t active_time = p_parse_value->dw_param[0];
+
+ if(gap_set_lps_bootup_active_time(active_time))
+ {
+ return RESULT_SUCCESS;
+ }
+ else
+ {
+ return RESULT_GAP_CAUSE_INVALID_PARAM;
+ }
+ }
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_GAP_SET_LPS_BOOTUP_ACTIVE_TIME:
+ APP_PRINT_INFO1("GAP_MSG_GAP_SET_LPS_BOOTUP_ACTIVE_TIME: cause 0x%x",
+ p_data->le_cause.cause);
+ break;
+ ...
+ }
+ * \endcode
+ */
+bool gap_set_lps_bootup_active_time(uint16_t active_time);
+
+/**
+ * @brief Configure coding scheme of LE Coded PHY when device uses LE Advertising Extensions.
+ *
+ * NOTE: Advertiser should delete advertising set before changing coding scheme.
+ *
+ * @param[in] coding_scheme Coding scheme of LE Coded PHY when when device uses LE Advertising Extensions, @ref T_GAP_AE_CODING_SCHEME.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Send request success.
+ * @retval other Send request failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ le_ae_coding_scheme(GAP_AE_CODING_SCHEME_S8);
+ }
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_AE_CODING_SCHEME:
+ APP_PRINT_INFO1("GAP_MSG_LE_AE_CODING_SCHEME: cause 0x%x",
+ cb_data->le_cause.cause);
+ break;
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_ae_coding_scheme(T_GAP_AE_CODING_SCHEME coding_scheme);
+
+/** End of GAP_LE_VENDOR_Exported_Functions
+ * @}
+ */
+
+/** End of GAP_LE_VENDOR
+ * @}
+ */
+#endif /* GAP_VNR_H */
diff --git a/inc/bluetooth/gap/gap_lib/readme b/inc/bluetooth/gap/gap_lib/readme
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/inc/bluetooth/gap/gap_lib/readme
diff --git a/inc/bluetooth/gap/gap_msg.h b/inc/bluetooth/gap/gap_msg.h
new file mode 100644
index 0000000..14596fa
--- /dev/null
+++ b/inc/bluetooth/gap/gap_msg.h
@@ -0,0 +1,271 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gap_msg.h
+ * @brief This file contains function prototype for all GAP roles.
+ * @details
+ * @author ranhui
+ * @date 2016-02-18
+ * @version v0.1
+ * *************************************************************************************
+ */
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_MSG_H
+#define GAP_MSG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+
+/** @defgroup GAP_MSG_MODULE GAP Message
+ * @brief GAP message
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup Gap_Msg_Exported_Macros GAP Msg Exported Macros
+ * @{
+ */
+
+/** @defgroup GAP_MSG_TYPE GAP BT Message Type Definitions
+ * @brief Define the subtype of Message IO_MSG_TYPE_BT_STATUS.
+ * @{
+ */
+#define GAP_MSG_LE_DEV_STATE_CHANGE 0x01 //!< Device state change msg type.
+#define GAP_MSG_LE_CONN_STATE_CHANGE 0x02 //!< Connection state change msg type.
+#define GAP_MSG_LE_CONN_PARAM_UPDATE 0x03 //!< Connection parameter update changed msg type.
+#define GAP_MSG_LE_CONN_MTU_INFO 0x04 //!< Connection MTU size info msg type.
+
+#define GAP_MSG_LE_AUTHEN_STATE_CHANGE 0x05 //!< Authentication state change msg type.
+#define GAP_MSG_LE_BOND_PASSKEY_DISPLAY 0x06 //!< Bond passkey display msg type.
+#define GAP_MSG_LE_BOND_PASSKEY_INPUT 0x07 //!< Bond passkey input msg type.
+#define GAP_MSG_LE_BOND_OOB_INPUT 0x08 //!< Bond passkey oob input msg type.
+#define GAP_MSG_LE_BOND_USER_CONFIRMATION 0x09 //!< Bond user confirmation msg type.
+#define GAP_MSG_LE_BOND_JUST_WORK 0x0A //!< Bond user confirmation msg type.
+
+#if F_BT_LE_5_0_AE_ADV_SUPPORT
+#define GAP_MSG_LE_EXT_ADV_STATE_CHANGE 0x0B //!< Extended advertising state change msg type.
+#endif
+/**
+ * @}
+ */
+
+/** @defgroup GAP_DEVICE_STATE GAP Device State
+ * @{
+ */
+/** @defgroup GAP_INIT_STATE GAP Initial State
+ * @{
+ */
+#define GAP_INIT_STATE_INIT 0 //!< Waiting to be started
+#define GAP_INIT_STATE_STACK_READY 1 //!< Stack is ready
+/** @} End GAP_INIT_STATE */
+
+/** @defgroup GAP_ADV_STATE GAP Advertising State
+ * @{
+ */
+#define GAP_ADV_STATE_IDLE 0 //!< Idle, no advertising
+#define GAP_ADV_STATE_START 1 //!< Start Advertising. A temporary state, haven't received the result.
+#define GAP_ADV_STATE_ADVERTISING 2 //!< Advertising
+#define GAP_ADV_STATE_STOP 3 //!< Stop Advertising. A temporary state, haven't received the result.
+/** @} End GAP_ADV_STATE */
+
+/** @defgroup GAP_ADV_SUB_STATE GAP Advertising Substate
+ * @{
+ */
+#define GAP_ADV_TO_IDLE_CAUSE_STOP 0 //!<Advertising is stopped by user stop or high duty cycle directed advertising timeout
+#define GAP_ADV_TO_IDLE_CAUSE_CONN 1 //!<Advertising is stopped for link establishment
+/** @} End GAP_ADV_SUB_STATE */
+
+/** @defgroup GAP_SCAN_STATE GAP Scan State
+ * @{
+ */
+#define GAP_SCAN_STATE_IDLE 0 //!< Idle, no scanning
+#define GAP_SCAN_STATE_START 1 //!< Start scanning. A temporary state, haven't received the result.
+#define GAP_SCAN_STATE_SCANNING 2 //!< Scanning
+#define GAP_SCAN_STATE_STOP 3 //!< Stop scanning, A temporary state, haven't received the result.
+/** @} End GAP_SCAN_STATE */
+
+/** @defgroup GAP_CONN_STATE GAP Connection State
+ * @{
+ */
+#define GAP_CONN_DEV_STATE_IDLE 0 //!< Idle
+#define GAP_CONN_DEV_STATE_INITIATING 1 //!< Initiating Connection
+/** @} End GAP_CONN_STATE */
+
+/** @} End GAP_DEVICE_STATE */
+
+/** @defgroup BOND_PAIRING_STATE_DEFINES Authentication States
+ * @{
+ */
+#define GAP_AUTHEN_STATE_STARTED 0x00 //!< Authentication started
+#define GAP_AUTHEN_STATE_COMPLETE 0x01 //!< Authentication complete
+/** @} End BOND_PAIRING_STATE_DEFINES */
+
+/** @defgroup GAP_CONN_PARAM_UPDATE_STATUS Connection Parameter Update Status
+ * @{
+ */
+#define GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS 0 //!< Connection parameter update status success.
+#define GAP_CONN_PARAM_UPDATE_STATUS_FAIL 1 //!< Connection parameter update status failed.
+#define GAP_CONN_PARAM_UPDATE_STATUS_PENDING 2 //!< Connection parameter update status pending.
+/** End of GAP_CONN_PARAM_UPDATE_STATUS
+ * @}
+ */
+
+/** @brief GAP connection states*/
+typedef enum
+{
+ GAP_CONN_STATE_DISCONNECTED, //!< Disconnected.
+ GAP_CONN_STATE_CONNECTING, //!< Connecting.
+ GAP_CONN_STATE_CONNECTED, //!< Connected.
+ GAP_CONN_STATE_DISCONNECTING //!< Disconnecting.
+} T_GAP_CONN_STATE;
+
+/** End of Gap_Msg_Exported_Macros
+* @}
+*/
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup Gap_Msg_Exported_Types GAP Msg Exported Types
+ * @{
+ */
+/** @brief Device State.*/
+typedef struct
+{
+ uint8_t gap_init_state: 1; //!< @ref GAP_INIT_STATE
+ uint8_t gap_adv_sub_state: 1; //!< @ref GAP_ADV_SUB_STATE
+ uint8_t gap_adv_state: 2; //!< @ref GAP_ADV_STATE
+ uint8_t gap_scan_state: 2; //!< @ref GAP_SCAN_STATE
+ uint8_t gap_conn_state: 2; //!< @ref GAP_CONN_STATE
+} T_GAP_DEV_STATE;
+
+/** @brief The msg_data of GAP_MSG_LE_DEV_STATE_CHANGE.*/
+typedef struct
+{
+ T_GAP_DEV_STATE new_state;
+ uint16_t cause;
+} T_GAP_DEV_STATE_CHANGE;
+
+
+/** @brief The msg_data of GAP_MSG_LE_CONN_STATE_CHANGE.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint8_t new_state;
+ uint16_t disc_cause;
+} T_GAP_CONN_STATE_CHANGE;
+
+/** @brief The msg_data of GAP_MSG_LE_CONN_PARAM_UPDATE.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint8_t status;
+ uint16_t cause;
+} T_GAP_CONN_PARAM_UPDATE;
+
+/** @brief The msg_data of GAP_MSG_LE_AUTHEN_STATE_CHANGE.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint8_t new_state;
+ uint16_t status;
+} T_GAP_AUTHEN_STATE;
+
+/** @brief The msg_data of GAP_MSG_LE_BOND_PASSKEY_DISPLAY.*/
+typedef struct
+{
+ uint8_t conn_id;
+} T_GAP_BOND_PASSKEY_DISPLAY;
+
+/** @brief The msg_data of GAP_MSG_LE_BOND_USER_CONFIRMATION.*/
+typedef struct
+{
+ uint8_t conn_id;
+} T_GAP_BOND_USER_CONF;
+
+/** @brief The msg_data of T_GAP_BOND_JUST_WORK_CONF.*/
+typedef struct
+{
+ uint8_t conn_id;
+} T_GAP_BOND_JUST_WORK_CONF;
+/** @brief The msg_data of GAP_MSG_LE_BOND_PASSKEY_INPUT.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint8_t key_press;
+} T_GAP_BOND_PASSKEY_INPUT;
+
+/** @brief The msg_data of GAP_MSG_LE_BOND_OOB_INPUT.*/
+typedef struct
+{
+ uint8_t conn_id;
+} T_GAP_BOND_OOB_INPUT;
+
+/** @brief The msg_data of GAP_MSG_LE_CONN_MTU_INFO.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t mtu_size;
+} T_GAP_CONN_MTU_INFO;
+
+/** @brief The msg_data of GAP_MSG_LE_EXT_ADV_STATE_CHANGE.*/
+#if F_BT_LE_5_0_AE_ADV_SUPPORT
+typedef struct
+{
+ uint8_t adv_handle;
+ uint8_t new_state;
+ uint16_t cause;
+} T_GAP_EXT_ADV_STATE_CHANGE;
+#endif
+/** @brief The msg_data of T_LE_GAP_MSG. */
+typedef union
+{
+ T_GAP_DEV_STATE_CHANGE gap_dev_state_change;
+ T_GAP_CONN_STATE_CHANGE gap_conn_state_change;
+ T_GAP_CONN_PARAM_UPDATE gap_conn_param_update;
+ T_GAP_CONN_MTU_INFO gap_conn_mtu_info;
+
+ T_GAP_AUTHEN_STATE gap_authen_state;
+ T_GAP_BOND_PASSKEY_DISPLAY gap_bond_passkey_display;
+ T_GAP_BOND_PASSKEY_INPUT gap_bond_passkey_input;
+ T_GAP_BOND_OOB_INPUT gap_bond_oob_input;
+ T_GAP_BOND_USER_CONF gap_bond_user_conf;
+ T_GAP_BOND_JUST_WORK_CONF gap_bond_just_work_conf;
+#if F_BT_LE_5_0_AE_ADV_SUPPORT
+ T_GAP_EXT_ADV_STATE_CHANGE gap_ext_adv_state_change;
+#endif
+} T_LE_GAP_MSG_DATA;
+
+/** @brief As the param of T_IO_MSG. type is IO_MSG_TYPE_BT_STATUS. */
+typedef struct
+{
+ T_LE_GAP_MSG_DATA msg_data;
+} T_LE_GAP_MSG;
+
+/** End of Gap_Msg_Exported_Types
+* @}
+*/
+
+/** End of GAP_MSG_MODULE
+* @}
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_MSG_H */
diff --git a/inc/bluetooth/gap/gap_pa_adv.h b/inc/bluetooth/gap/gap_pa_adv.h
new file mode 100644
index 0000000..0c844a7
--- /dev/null
+++ b/inc/bluetooth/gap/gap_pa_adv.h
@@ -0,0 +1,157 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_pa_adv.h
+* @brief Header file for Gap pa adv
+* @details This file defines periodic advertising related API.
+* @author ranhui
+* @date 2020-10-18
+* @version v0.7
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_PA_ADV_H
+#define GAP_PA_ADV_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#include "gap_le.h"
+
+#if F_BT_LE_5_0_PA_ADV_SUPPORT
+
+/** @addtogroup GAP GAP Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE GAP LE Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE_PA_ADV GAP LE PA Adv Module
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GAP_LE_PERIODIC_ADV_Exported_Macros GAP LE Periodic Adv Exported Macros
+ * @{
+ */
+
+/** @defgroup PA_ADV_PARAM Periodic Advertising Parameter flag
+ * @brief Use the combination of macro definitions to set periodic advertising related parameters
+ for a specified advertising set by calling @ref le_pa_adv_start_setting.
+ * @{
+ */
+#define PA_ADV_SET_PERIODIC_ADV_PARAS 0x01 /**< Set advertising parameters supplied by @ref le_pa_adv_set_periodic_adv_param. */
+#define PA_ADV_SET_PERIODIC_ADV_DATA 0x02 /**< Set advertising data supplied by @ref le_pa_adv_set_periodic_adv_data. */
+/** End of PA_ADV_PARAM
+ * @}
+ */
+
+/** @defgroup PERIODIC_ADV_PROP Periodic Advertising Properties flag
+ * @brief Use the combination of macro definitions to indicate which fields should be included in the advertising packet.
+ * @{
+ */
+#define PA_ADV_PROP_INCLUDE_TX_POWER 0x0040 /**< Include TxPower in the periodic header of the advertising PDU. */
+/** End of PERIODIC_ADV_PROP
+ * @}
+ */
+
+/** @defgroup PA_ADV_ENABLE Periodic Advertising Enable flag
+ * @brief Use the combination of macro definitions to describe the enable parameters.
+ * @{
+ */
+#define PA_ADV_ENABLE_ENABLE_PERIODIC_ADVERTISING 0x01 /**< Enable periodic advertising. */
+#define PA_ADV_ENABLE_INCLUDE_ADI 0x02 /**< Include the ADI field in AUX_SYNC_IND PDUs. */
+/** End of PA_ADV_ENABLE
+ * @}
+ */
+/** End of GAP_LE_PA_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_PA_ADV_Exported_Types GAP LE PA Adv Exported Types
+ * @{
+ */
+
+/** @brief GAP periodic advertising adv state. */
+typedef enum
+{
+ PA_ADV_STATE_IDLE, /**< Idle, no advertising. */
+ PA_ADV_STATE_START_EXT_ADV_STATE_IDLE, /**< Start Advertising when periodic advertising of specific advertising set is disabled. A temporary state, haven't received the result. */
+ PA_ADV_STATE_WAIT_EXT_ADV_STATE_ADVERTISING, /**< Periodic Advertising is not started until the periodic advertising of specific advertising set is enabled. */
+ PA_ADV_STATE_START, /**< Start Advertising when periodic advertising of specific advertising set is enabled. A temporary state, haven't received the result. */
+ PA_ADV_STATE_ADVERTISING, /**< Periodic Advertising. */
+ PA_ADV_STATE_STOP, /**< Stop Advertising. A temporary state, haven't received the result. */
+} T_GAP_PA_ADV_STATE;
+
+/** End of GAP_LE_PA_ADV_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup GAP_LE_PA_ADV_Exported_Functions GAP LE PA Adv Exported Functions
+ * @brief
+ * @{
+ */
+T_GAP_CAUSE le_pa_adv_init(uint8_t adv_set_num);
+
+/*
+ pa_update_flags: @ref PA_ADV_PARAM
+*/
+T_GAP_CAUSE le_pa_adv_start_setting(uint8_t adv_handle, uint8_t pa_update_flags);
+
+/*
+ periodic_adv_prop: @ref PERIODIC_ADV_PROP
+*/
+T_GAP_CAUSE le_pa_adv_set_periodic_adv_param(uint8_t adv_handle, uint16_t periodic_adv_interval_min,
+ uint16_t periodic_adv_interval_max, uint16_t periodic_adv_prop);
+
+T_GAP_CAUSE le_pa_adv_set_periodic_adv_data(uint8_t adv_handle, uint16_t periodic_adv_data_len,
+ uint8_t *p_periodic_adv_data, bool pa_unchanged_data_flag);
+
+/*
+ enable: @ref PA_ADV_ENABLE
+*/
+T_GAP_CAUSE le_pa_adv_set_periodic_adv_enable(uint8_t adv_handle, uint8_t enable);
+
+/** End of GAP_LE_PA_ADV_Exported_Functions
+ * @}
+ */
+
+/** End of GAP_LE_PA_ADV
+ * @}
+ */
+
+/** End of GAP_LE
+ * @}
+ */
+
+/** End of GAP
+ * @}
+ */
+
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_PA_ADV_H */
diff --git a/inc/bluetooth/gap/gap_pa_sync.h b/inc/bluetooth/gap/gap_pa_sync.h
new file mode 100644
index 0000000..0a03ba3
--- /dev/null
+++ b/inc/bluetooth/gap/gap_pa_sync.h
@@ -0,0 +1,181 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_pa_sync.h
+* @brief Header file for Gap pa sync
+* @details
+* @author
+* @date 2020-10-18
+* @version v0.6
+* *********************************************************************************************************
+*/
+
+/* Define to prevent recursive inclusion **/
+#ifndef GAP_PA_SYNC_H
+#define GAP_PA_SYNC_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "upperstack_config.h"
+#include "gap_le.h"
+
+#if F_BT_LE_5_0_PA_SYNC_SUPPORT
+#define GAP_INVALID_CONN_ID 0xFF
+#define GAP_INVALID_SYNC_ID 0xFF
+#define GAP_INVALID_SYNC_HANDLE 0xFFFF
+
+/** @defgroup PA_SYNC_CREATE_SYNC_OPTIONS Synchronization State of Periodic Advertising Create Sync Options
+ * @brief Use the combination of macro definitions to determine whether the Periodic Advertiser List is used,
+ whether periodic advertising report for this periodic advertising train are initially enabled or disabled.
+ * @{
+ */
+#define PA_SYNC_CREATE_SYNC_OPTIONS_USE_PERIODIC_ADV_LIST 0x01 /**< Use the Periodic Advertiser List to determine which advertiser to listen to.
+ Otherwise, Use the Advertising_SID, AdvertisierAdvertiser_Address_Type, and
+ Advertiser_Address parameters to determine which advertiser to listen to.*/
+#define PA_SYNC_CREATE_SYNC_OPTIONS_REPORT_INITIALLY_DISABLED 0x02 /**< Reporting initially disabled.
+ Otherwise, Reporting initially enabled.*/
+#define PA_SYNC_CREATE_SYNC_OPTIONS_DUPLICATE_FILTER_INITIALLY_ENABLED 0x04 /**< Duplicate filtering initially enabled.
+ Otherwise, Duplicate filtering initially disabled.*/
+/** End of PA_SYNC_CREATE_SYNC_OPTIONS
+ * @}
+ */
+
+/** @defgroup PA_SYNC_CREATE_SYNC_SYNC_CTE_TYPE Synchronization State of Periodic Advertising Create Sync Sync CTE Type
+ * @brief Use the combination of macro definitions to
+ * @{
+ */
+#define PA_SYNC_CREATE_SYNC_CTE_TYPE_CTE_IRRELEVANT 0x00 /**< A value of 0 (i.e. all bits clear) indicates that the presence or absence of
+ a Constant Tone Extension is irrelevant. */
+#define PA_SYNC_CREATE_SYNC_CTE_TYPE_NOT_SYNC_WITH_AOA_CTE 0x01 /**< Do not sync to packets with an AoA Constant Tone Extension */
+#define PA_SYNC_CREATE_SYNC_CTE_TYPE_NOT_SYNC_WITH_AOD_CTE_1US 0x02 /**< Do not sync to packets with an AoD Constant Tone Extension with 1 μs slots*/
+#define PA_SYNC_CREATE_SYNC_CTE_TYPE_NOT_SYNC_WITH_AOD_CTE_2US 0x04 /**< Do not sync to packets with an AoD Constant Tone Extension with 2 μs slots*/
+#define PA_SYNC_CREATE_SYNC_CTE_TYPE_NOT_SYNC_WITH_TYPE_3_CTE 0x08 /**< Do not sync to packets with a type 3 Constant Tone Extension (currently
+ reserved for future use)*/
+#define PA_SYNC_CREATE_SYNC_CTE_TYPE_NOT_SYNC_WITHOUT_CTE 0x10 /**< Do not sync to packets without a Constant Tone Extension*/
+/** End of PA_SYNC_CREATE_SYNC_SYNC_CTE_TYPE
+ * @}
+ */
+
+#if ((F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_SUPPORT) || F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT)
+/** @defgroup PA_SYNC_PA_RECEIVE_ENABLE_PARAM Enable parameter of Periodic Advertising Receive Enable
+ * @brief Use the combination of macro definitions to determine whether reporting and duplicate filtering
+ are enabled or disabled.
+ * @{
+ */
+#define PA_SYNC_PA_RECEIVE_ENABLE_PARAM_REPORT_ENABLED 0x01 /**< Reporting enabled */
+#define PA_SYNC_PA_RECEIVE_ENABLE_PARAM_DUPLICATE_FILTER_ENABLED 0x02 /**< Duplicate filtering enabled*/
+/** End of PA_SYNC_PA_RECEIVE_ENABLE_PARAM
+ * @}
+ */
+#endif
+
+/** @defgroup GAP_PA_TERMINATE_SYNC_DEV_STATE GAP periodic advertising synchronization and scan device State
+ * @{
+ */
+#define GAP_PA_TERMINATE_SYNC_DEV_STATE_IDLE 0 //!< Idle
+#define GAP_PA_TERMINATE_SYNC_DEV_STATE_TERMINATING 1 //!< Terminating
+/** @} End GAP_PA_SYNC_SCAN_DEV_STATE */
+
+#if F_BT_LE_5_0_PA_SYNC_SCAN_SUPPORT
+/** @defgroup GAP_PA_CREATE_SYNC_DEV_STATE GAP periodic advertising synchronization and scan device State
+ * @{
+ */
+#define GAP_PA_CREATE_SYNC_DEV_STATE_IDLE 0 //!< Idle
+#define GAP_PA_CREATE_SYNC_DEV_STATE_SYNCHRONIZING 1 //!< Synchronizing
+/** @} End GAP_PA_SYNC_SCAN_DEV_STATE */
+#endif
+
+#if ((F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_SUPPORT) || F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT)
+/** @defgroup GAP_PA_RECEIVE_ENABLE_DEV_STATE GAP periodic advertising synchronization and scan device State
+ * @{
+ */
+#define GAP_PA_RECEIVE_ENABLE_DEV_STATE_IDLE 0 //!< Idle
+#define GAP_PA_RECEIVE_ENABLE_DEV_STATE_ENABLING 1 //!< Enabling
+/** @} End GAP_PA_RECEIVE_ENABLE_DEV_STATE */
+#endif
+
+/** @brief GAP periodic advertising synchronization states*/
+typedef enum
+{
+ GAP_PA_SYNC_STATE_TERMINATED = 0x00, //!< Terminated.
+#if F_BT_LE_5_0_PA_SYNC_SCAN_SUPPORT
+ GAP_PA_SYNC_STATE_SYNCHRONIZING_SCAN_IDLE = 0x01, //!< Start synchronizing when extended scanning is disabled. A temporary state, haven't received the result.
+ GAP_PA_SYNC_STATE_SYNCHRONIZING_WAIT_SCANNING = 0x02, //!< No attempt to synchronize will take place when extended scanning is disabled.
+#endif
+ GAP_PA_SYNC_STATE_SYNCHRONIZING = 0x03, //!< Start synchronizing when extended scanning is enabled.
+ GAP_PA_SYNC_STATE_SYNCHRONIZED = 0x04, //!< Synchronized
+ GAP_PA_SYNC_STATE_TERMINATING = 0x05,//!< Terminate synchronization.
+} T_GAP_PA_SYNC_STATE;
+
+/** @brief LE periodic advertising sync parameter types */
+typedef enum
+{
+ PA_SYNC_PARAM_PERIODIC_ADV_LIST_SIZE = 0x2A0, //!< Periodic advertiser list size. Read only.
+ PA_SYNC_PARAM_SYNCHRONIZED_PARAM = 0x2A1, //!< PA synchronized parameters. Read only. Identifier is sync_id.
+} T_GAP_PA_SYNC_PARAM_TYPE;
+
+typedef struct
+{
+ uint16_t sync_handle;
+ uint8_t adv_sid;
+ uint8_t adv_addr_type;
+ uint8_t adv_addr[GAP_BD_ADDR_LEN]; /* current remote BD */
+ uint16_t skip; /* Range: 0x0000 to 0x01F3 */
+ uint16_t sync_timeout; /* Range: 0x000A to 0x4000*/
+ uint8_t sync_cte_type;
+ T_GAP_PHYS_TYPE adv_phy;
+ uint8_t adv_clock_accuracy;
+ uint16_t periodic_adv_interval;
+ bool sync_transfer_received_flag;
+} T_GAP_PA_SYNC_COMMON_SYNC_PARAM;
+
+#if F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t service_data;
+} T_GAP_PAST_SYNC_TRANSFER_RECEIVED_PARAM;
+#endif
+
+#if F_BT_LE_5_0_PA_SYNC_SCAN_SUPPORT
+typedef struct
+{
+ uint8_t options; /* @ref PA_SYNC_CREATE_SYNC_OPTIONS */
+ uint8_t sync_cte_type; /* @ref PA_SYNC_CREATE_SYNC_SYNC_CTE_TYPE */
+ uint8_t adv_sid;
+ T_GAP_PA_SYNC_ADV_ADDR_TYPE
+ adv_addr_type; /* @ref Only PA_SYNC_ADV_ADDR_PUBLIC and PA_SYNC_ADV_ADDR_RANDOM can be used. */
+ uint8_t adv_addr[GAP_BD_ADDR_LEN];
+ uint16_t skip;
+ uint16_t sync_timeout;
+} T_GAP_PA_SYNC_CREATE_SYNC_PARAM;
+#endif
+
+T_GAP_CAUSE le_pa_sync_init(uint8_t sync_handle_num);
+T_GAP_CAUSE le_pa_sync_get_param(T_GAP_PA_SYNC_PARAM_TYPE param, void *p_value, uint8_t sync_id);
+T_GAP_CAUSE le_pa_sync_terminate_sync(uint8_t sync_id);
+T_GAP_CAUSE le_pa_sync_modify_periodic_adv_list(T_GAP_PA_SYNC_PERIODIC_ADV_LIST_OP operation,
+ uint8_t *adv_addr,
+ T_GAP_PA_SYNC_ADV_ADDR_TYPE adv_addr_type, uint8_t adv_sid);
+
+#if F_BT_LE_5_0_PA_SYNC_SCAN_SUPPORT
+T_GAP_CAUSE le_pa_sync_create_sync(T_GAP_PA_SYNC_CREATE_SYNC_PARAM *p_pa_sync_create_sync_param,
+ uint8_t *p_sync_id);
+#endif
+
+#if ((F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_SUPPORT) || F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT)
+/*
+ enable: @ref PA_SYNC_PA_RECEIVE_ENABLE_PARAM
+*/
+T_GAP_CAUSE le_pa_sync_set_periodic_adv_receive_enable(uint8_t sync_id, uint8_t enable);
+#endif
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_PA_SYNC_H */
diff --git a/inc/bluetooth/gap/gap_past_recipient.h b/inc/bluetooth/gap/gap_past_recipient.h
new file mode 100644
index 0000000..b10edea
--- /dev/null
+++ b/inc/bluetooth/gap/gap_past_recipient.h
@@ -0,0 +1,101 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_past_recipient.h
+* @brief Header file for Gap past recipient
+* @details
+* @author
+* @date 2020-10-18
+* @version v0.4
+* *********************************************************************************************************
+*/
+
+/* Define to prevent recursive inclusion **/
+#ifndef GAP_PAST_RECIPIENT_H
+#define GAP_PAST_RECIPIENT_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "upperstack_config.h"
+#include "gap_le.h"
+
+#if F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GAP_LE_PAST_RECIPIENT_Exported_Macros GAP LE PAST Recipient Exported Macros
+ * @{
+ */
+
+/** End of GAP_LE_PAST_RECIPIENT_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_PAST_RECIPIENT_Exported_Types GAP LE PAST Recipient Exported Types
+ * @{
+ */
+
+/** @brief GAP PAST recipient periodic adv sync transfer mode. */
+typedef enum
+{
+ PERIODIC_ADV_SYNC_TRANSFER_MODE_NO_ATTEMPT_TO_SYNCHRONIZE = 0x00, /**< No attempt is made to synchronize to the periodic advertising and
+ no HCI_LE_Periodic_Advertising_Sync_Transfer_Received event is sent to the Host (default). */
+ PERIODIC_ADV_SYNC_TRANSFER_MODE_PERIODIC_ADV_REPORT_DISABLED = 0x01, /**< An HCI_LE_Periodic_Advertising_Sync_Transfer_Received event is
+sent to the Host. HCI_LE_Periodic_Advertising_Report events will be disabled. */
+ PERIODIC_ADV_SYNC_TRANSFER_MODE_PERIODIC_ADV_REPORT_ENABLED_WITH_DUPLICATE_FILTER_DISABLED = 0x02, /**< An HCI_LE_Periodic_Advertising_Sync_Transfer_Received event is
+sent to the Host. HCI_LE_Periodic_Advertising_Report events will be enabled with duplicate filtering disabled. */
+ PERIODIC_ADV_SYNC_TRANSFER_MODE_PERIODIC_ADV_REPORT_ENABLED_WITH_DUPLICATE_FILTER_ENABLED = 0x03, /**< An HCI_LE_Periodic_Advertising_Sync_Transfer_Received event is
+sent to the Host. HCI_LE_Periodic_Advertising_Report events will be enabled with duplicate filtering enabled. */
+} T_GAP_PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_MODE;
+
+/** End of GAP_LE_PAST_RECIPIENT_Exported_Types
+ * @}
+ */
+
+/** @defgroup PAST_RECIPIENT_CREATE_SYNC_SYNC_CTE_TYPE Synchronization State of Periodic Advertising Create Sync Sync CTE Type
+ * @brief Use the combination of macro definitions to specifies whether to only synchronize to periodic
+ advertising with certain types of Constant Tone Extension.
+ * @{
+ */
+#define PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_CTE_TYPE_CTE_IRRELEVANT 0x00 /**< A value of 0 (i.e. all bits clear) indicates that the presence or absence of
+ a Constant Tone Extension is irrelevant. */
+#define PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_CTE_TYPE_NOT_SYNC_WITH_AOA_CTE 0x01 /**< Do not sync to packets with an AoA Constant Tone Extension */
+#define PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_CTE_TYPE_NOT_SYNC_WITH_AOD_CTE_1US 0x02 /**< Do not sync to packets with an AoD Constant Tone Extension with 1 μs slots*/
+#define PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_CTE_TYPE_NOT_SYNC_WITH_AOD_CTE_2US 0x04 /**< Do not sync to packets with an AoD Constant Tone Extension with 2 μs slots*/
+#define PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_CTE_TYPE_NOT_SYNC_WITHOUT_CTE 0x10 /**< Do not sync to packets without a Constant Tone Extension*/
+/** End of PAST_RECIPIENT_CREATE_SYNC_SYNC_CTE_TYPE
+ * @}
+ */
+typedef struct
+{
+ T_GAP_PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_MODE mode;
+ uint8_t cte_type; /* @ref PAST_RECIPIENT_CREATE_SYNC_SYNC_CTE_TYPE */
+ uint16_t skip;
+ uint16_t sync_timeout;
+} T_GAP_PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_PARAM;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup GAP_LE_PAST_SENDER_Exported_Functions GAP LE PAST Recipient Exported Functions
+ * @brief
+ * @{
+ */
+T_GAP_CAUSE le_past_recipient_set_default_periodic_adv_sync_transfer_params(
+ T_GAP_PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_PARAM *p_periodic_adv_sync_transfer_param);
+
+T_GAP_CAUSE le_past_recipient_set_periodic_adv_sync_transfer_params(uint8_t conn_id,
+ T_GAP_PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_PARAM *p_periodic_adv_sync_transfer_param);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_PAST_RECIPIENT_H */
diff --git a/inc/bluetooth/gap/gap_past_sender.h b/inc/bluetooth/gap/gap_past_sender.h
new file mode 100644
index 0000000..ea2ee1b
--- /dev/null
+++ b/inc/bluetooth/gap/gap_past_sender.h
@@ -0,0 +1,105 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_pa_adv.h
+* @brief Header file for Gap past sender
+* @details This file defines sender of PAST related API.
+* @author
+* @date 2020-10-18
+* @version v0.4
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_PAST_SENDER_H
+#define GAP_PAST_SENDER_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#include "gap_le.h"
+
+#if F_BT_LE_5_1_PAST_SENDER_SUPPORT
+
+/** @addtogroup GAP GAP Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE GAP LE Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE_PAST_SENDER GAP LE PAST Sender Module
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GAP_LE_PAST_SENDER_Exported_Macros GAP LE PAST Sender Exported Macros
+ * @{
+ */
+
+/** End of GAP_LE_PAST_SENDER_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_PAST_SENDER_Exported_Types GAP LE PAST Sender Exported Types
+ * @{
+ */
+
+/** End of GAP_LE_PAST_SENDER_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup GAP_LE_PAST_SENDER_Exported_Functions GAP LE PAST Sender Exported Functions
+ * @brief
+ * @{
+ */
+#if F_BT_LE_5_1_PAST_SENDER_ADV_SUPPORT
+T_GAP_CAUSE le_past_sender_periodic_adv_set_info_transfer(uint8_t conn_id, uint16_t service_data,
+ uint8_t adv_handle);
+#endif
+
+#if F_BT_LE_5_1_PAST_SENDER_SYNC_SUPPORT
+T_GAP_CAUSE le_past_sender_periodic_adv_sync_transfer(uint8_t conn_id, uint16_t service_data,
+ uint8_t sync_id);
+#endif
+/** End of GAP_LE_PAST_SENDER_Exported_Functions
+ * @}
+ */
+
+/** End of GAP_LE_PAST_SENDER
+ * @}
+ */
+
+/** End of GAP_LE
+ * @}
+ */
+
+/** End of GAP
+ * @}
+ */
+
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_PAST_SENDER_H */
diff --git a/inc/bluetooth/gap/gap_ping_le.h b/inc/bluetooth/gap/gap_ping_le.h
new file mode 100644
index 0000000..3620226
--- /dev/null
+++ b/inc/bluetooth/gap/gap_ping_le.h
@@ -0,0 +1,193 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_ping_le.h
+* @brief Head file for GAP PING
+* @details
+* @author
+* @date 2020-06-18
+* @version v0.8
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_PING_LE_H
+#define GAP_PING_LE_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#include "gap_le.h"
+#include "gap_le_types.h"
+
+
+/** @addtogroup GAP GAP Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE GAP LE Module
+ * @{
+ */
+
+/** @addtogroup GAP_LE_PING GAP LE PING Module
+ * @{
+ */
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GAP_LE_PING_Exported_Macros GAP LE AoX Exported Macros
+ * @{
+ */
+
+/** @defgroup GAP_LE_PING_MSG_Types APP LE RF Msg Types
+ * @{
+ */
+#define GAP_MSG_LE_PING_INFO 0xD0
+/** End of GAP_LE_PING_MSG_Types
+ * @}
+ */
+
+/** @defgroup GAP_LE_PING_MSG_Opcodes APP LE PING Msg Opcodes
+ * @{
+ */
+#define GAP_LE_PING_WRITE_AUTHEN_PAYLOAD_TIMEOUT 0x0000 //!<Response msg opcode for p_le_write_authen_payload_timeout_rsp
+/**
+ * @}
+ */
+
+/** End of GAP_LE_PING_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_PING_Exported_Types GAP LE PING Exported Types
+ * @brief
+ * @{
+ */
+#if F_BT_LE_4_1_WRITE_AUTHEN_PAYLOAD_TIMEOUT_SUPPORT
+/** @brief Response for writing authenticated payload timeout.*/
+typedef struct
+{
+ uint8_t conn_id;
+ uint16_t cause;
+} T_LE_WRITE_AUTHEN_PAYLOAD_TIMEOUT_RSP;
+#endif
+
+/** @brief GAP LE PING Callback Data*/
+typedef union
+{
+#if F_BT_LE_4_1_WRITE_AUTHEN_PAYLOAD_TIMEOUT_SUPPORT
+ T_LE_WRITE_AUTHEN_PAYLOAD_TIMEOUT_RSP *p_le_write_authen_payload_timeout_rsp;
+#endif
+} T_GAP_LE_PING_CB_DATA;
+
+typedef struct
+{
+ uint16_t opcode;
+ T_GAP_LE_PING_CB_DATA data;
+} T_GAP_LE_PING_CB;
+/** End of GAP_LE_PING_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup GAP_LE_PING_Exported_Functions GAP LE PING Exported Functions
+ * @brief
+ * @{
+ */
+
+#if F_BT_LE_4_1_WRITE_AUTHEN_PAYLOAD_TIMEOUT_SUPPORT
+/**
+ * @brief Writes the authenticated payload timeout parameter for the connection identified by the conn_id parameter.
+ * Operation result will be returned by @ref app_gap_callback with cb_type @ref GAP_MSG_LE_WRITE_AUTHEN_PAYLOAD_TIMEOUT.
+ *
+ * @param[in] conn_id Connection ID
+ * @param[in] authen_payload_timeout Maximum amount of time specified between packets authenticated by a valid MIC.
+ * Range: 0x0001 to 0xFFFF
+ * Time = N * 10 ms
+ * Time Range: 10 ms to 655350 ms
+ * @return Read request result.
+ * @retval GAP_CAUSE_SUCCESS: Send request success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED: Send request sent fail.
+ * @retval GAP_CAUSE_NON_CONN: Failed. No connection
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ le_write_authen_payload_timeout(conn_id, authen_payload_timeout);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_PING_INFO:
+ {
+ APP_PRINT_INFO0("GAP_MSG_LE_PING_INFO");
+ T_GAP_LE_PING_CB *p_le_ping_cb;
+ p_le_ping_cb = (T_GAP_LE_PING_CB *)p_data->p_le_cb_data;
+
+ switch (p_le_ping_cb->opcode)
+ {
+ case GAP_LE_PING_WRITE_AUTHEN_PAYLOAD_TIMEOUT:
+ APP_PRINT_INFO2("GAP_LE_PING_WRITE_AUTHEN_PAYLOAD_TIMEOUT: conn_id %d, cause 0x%x",
+ p_le_ping_cb->data.p_le_write_authen_payload_timeout_rsp->conn_id,
+ p_le_ping_cb->data.p_le_write_authen_payload_timeout_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_ping_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+
+ break;
+ }
+ ...
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_write_authen_payload_timeout(uint8_t conn_id, uint16_t authen_payload_timeout);
+#endif
+
+/** End of GAP_LE_PING_Exported_Functions
+ * @}
+ */
+
+/** End of GAP_LE_PING
+ * @}
+ */
+
+/** End of GAP_LE
+ * @}
+ */
+
+/** End of GAP
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_PING_LE_H */
diff --git a/inc/bluetooth/gap/gap_privacy.h b/inc/bluetooth/gap/gap_privacy.h
new file mode 100644
index 0000000..bf05561
--- /dev/null
+++ b/inc/bluetooth/gap/gap_privacy.h
@@ -0,0 +1,271 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gap_privacy.h
+ * @brief This file contains all the functions prototypes for the GAP bond and pairing
+ * related functions.
+ * @details
+ * @author ranhui
+ * @date 2016-02-18
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_PRIVACY_H
+#define GAP_PRIVACY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#if F_BT_LE_PRIVACY_SUPPORT
+#include "gap_le.h"
+#include "gap_conn_le.h"
+#include "gap_storage_le.h"
+
+/** @defgroup GAP_PRIVACY_MODULE GAP LE Privacy
+ * @brief GAP LE privacy
+ * @{
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup Gap_Privacy_Exported_Types GAP Privacy Exported Types
+ * @{
+ */
+
+/** @brief Define the privacy callback type */
+#define GAP_MSG_LE_PRIVACY_RESOLUTION_STATUS_INFO 0x00 //!<Notification msg type for resolution status
+#define GAP_MSG_LE_PRIVACY_SET_RESOLV_PRIV_ADDR_TIMEOUT 0x01 //!<response msg type for le_privacy_set_resolv_priv_addr_timeout
+#define GAP_MSG_LE_PRIVACY_MODIFY_RESOLV_LIST 0x02 //!<response msg type for le_privacy_modify_resolv_list
+#define GAP_MSG_LE_PRIVACY_READ_PEER_RESOLV_ADDR 0x03 //!<response msg type for le_privacy_read_peer_resolv_addr
+#define GAP_MSG_LE_PRIVACY_READ_LOCAL_RESOLV_ADDR 0x04 //!<response msg type for le_privacy_read_local_resolv_addr
+#define GAP_MSG_LE_PRIVACY_SET_MODE 0x05 //!<response msg type for le_privacy_set_mode
+
+
+/** @brief Define the subtype of Message IO_MSG_TYPE_BT_STATUS */
+typedef enum
+{
+ GAP_PARAM_PRIVACY_TIMEOUT = 0x300, //!< Timeout value for privacy
+ GAP_PARAM_PRIVACY_RESOLUTION_STATE = 0x301, //!< Resolution state
+ GAP_PARAM_PRIVACY_RESOLV_LIST_SIZE = 0x302, //!< Resolvable list size
+} T_LE_PRIVACY_PARAM_TYPE;
+
+/** @brief Define the privacy state */
+typedef enum
+{
+ LE_PRIVACY_RESOLUTION_DISABLED,
+ LE_PRIVACY_RESOLUTION_DISABLING,
+ LE_PRIVACY_RESOLUTION_ENABLING,
+ LE_PRIVACY_RESOLUTION_ENABLED
+} T_LE_PRIVACY_STATE;
+
+/** @brief LE resolution status info */
+typedef struct
+{
+ T_LE_PRIVACY_STATE status;
+ uint16_t cause;
+} T_LE_PRIVACY_RESOLUTION_STATUS_INFO;
+
+/** @brief Response of le set resolvable private address timeout request.*/
+typedef struct
+{
+ uint16_t cause;
+} T_LE_PRIVACY_SET_RESOLV_PRIV_ADDR_TIMEOUT_RSP;
+
+/** @brief Response of le modify resolvable list request.*/
+typedef struct
+{
+ T_GAP_RESOLV_LIST_OP operation;
+ uint16_t cause;
+} T_LE_PRIVACY_MODIFY_RESOLV_LIST_RSP;
+
+/** @brief Response of le read peer resolvable address request.*/
+typedef struct
+{
+ uint16_t cause;
+ uint8_t peer_resolv_addr[6];
+} T_LE_PRIVACY_READ_PEER_RESOLV_ADDR_RSP;
+
+/** @brief Response of le read local resolvable address request.*/
+typedef struct
+{
+ uint16_t cause;
+ uint8_t local_resolv_addr[6];
+} T_LE_PRIVACY_READ_LOCAL_RESOLV_ADDR_RSP;
+
+/** @brief Response of set privacy mode.*/
+typedef struct
+{
+ uint16_t cause;
+} T_LE_PRIVACY_SET_MODE_RSP;
+
+/** @brief LE privacy callback data */
+typedef union
+{
+ T_LE_PRIVACY_RESOLUTION_STATUS_INFO le_privacy_resolution_status_info;
+ T_LE_PRIVACY_SET_RESOLV_PRIV_ADDR_TIMEOUT_RSP *p_le_privacy_set_resolv_priv_addr_timeout_rsp;
+ T_LE_PRIVACY_MODIFY_RESOLV_LIST_RSP *p_le_privacy_modify_resolv_list_rsp;
+ T_LE_PRIVACY_READ_PEER_RESOLV_ADDR_RSP *p_le_privacy_read_peer_resolv_addr_rsp;
+ T_LE_PRIVACY_READ_LOCAL_RESOLV_ADDR_RSP *p_le_privacy_read_local_resolv_addr_rsp;
+ T_LE_PRIVACY_SET_MODE_RSP *p_le_privacy_set_mode_rsp;
+} T_LE_PRIVACY_CB_DATA;
+
+/**
+ * @brief Callback for gap to notify app
+ * @param[in] msg_type Callback msy type
+ * @param[in] msg_data Message data @ref T_LE_PRIVACY_CB_DATA.
+ * @return result
+ * @retval results @ref T_APP_RESULT
+ */
+
+typedef T_APP_RESULT(*P_FUN_PRIVACY_CB)(uint8_t msg_type, T_LE_PRIVACY_CB_DATA msg_data);
+
+/** End of Gap_Privacy_Exported_Types
+* @}
+*/
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup Gap_Privacy_Exported_Functions GAP Privacy Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Set a LE privacy parameter.
+ *
+ * NOTE: You can call this function with a LE Privacy Parameter type and it will set the
+ * LE Privacy Parameter. LE Privacy Parameters are defined in @ref T_LE_PRIVACY_PARAM_TYPE.
+ * @param[in] param LE Privacy parameter type: @ref T_LE_PRIVACY_PARAM_TYPE.
+ * @param[in] len Length of data to write.
+ * @param[in] p_value Pointer to data to write.
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ */
+T_GAP_CAUSE le_privacy_set_param(T_LE_PRIVACY_PARAM_TYPE param, uint8_t len, void *p_value);
+
+/**
+ * @brief Get a LE privacy parameter.
+ *
+ * NOTE: You can call this function with a LE Privacy Parameter type and it will get a
+ * LE Privacy Parameter. LE Privacy Parameters are defined in @ref T_LE_PRIVACY_PARAM_TYPE.
+ *
+ * @param[in] param GAP parameter type: @ref T_LE_PRIVACY_PARAM_TYPE
+ * @param[in,out] p_value Pointer to location to get the parameter value. This is dependent on
+ * the parameter ID and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ */
+T_GAP_CAUSE le_privacy_get_param(T_LE_PRIVACY_PARAM_TYPE param, void *p_value);
+
+/**
+ * @brief Register privacy callback to stack.
+ * @param[in] p_privacy_cb Callback function provided by the APP to handle le privacy messages sent from the BT Stack.
+ * @arg NULL -> Use gap default callback function.
+ * @arg Other -> Use application defined callback function.
+ * @return none
+ */
+void le_privacy_register_cb(P_FUN_PRIVACY_CB p_privacy_cb);
+
+/**
+ * @brief Enable/disable le privacy address resolution mode.
+ * @param[in] enable Enable or disable address resolution.
+ * @return Operation result
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ */
+T_GAP_CAUSE le_privacy_set_addr_resolution(bool enable);
+
+/**
+ * @brief Read peer resolvable random address.
+ * @param[in] peer_identity_address_type Peer identity address type.
+ * @param[in] peer_identity_address Peer identity address.
+ * @return Operation result
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ */
+T_GAP_CAUSE le_privacy_read_peer_resolv_addr(T_GAP_IDENT_ADDR_TYPE peer_identity_address_type,
+ uint8_t *peer_identity_address);
+
+/**
+ * @brief Read local resolvable random address.
+ * @param[in] peer_identity_address_type Peer identity address type.
+ * @param[in] peer_identity_address Peer identity address.
+ * @return Operation result
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ */
+T_GAP_CAUSE le_privacy_read_local_resolv_addr(T_GAP_IDENT_ADDR_TYPE peer_identity_address_type,
+ uint8_t *peer_identity_address);
+
+/**
+ * @brief Set resolvable private address timeout.
+ * @return Operation result
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ */
+T_GAP_CAUSE le_privacy_set_resolv_priv_addr_timeout(void);
+
+
+/**
+ * @brief Modicy local resolvable device list.
+ * NOTE: You can call this function to add, remove or clear the resolvable list
+ *
+ * @param[in] operation type, @ref T_GAP_RESOLV_LIST_OP.
+ * @param[in] peer_identity_address_type Peer identity address type.
+ * @param[in] peer_identity_address Peer identity address.
+ * @return Operation result
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ */
+T_GAP_CAUSE le_privacy_modify_resolv_list(T_GAP_RESOLV_LIST_OP operation,
+ T_GAP_IDENT_ADDR_TYPE peer_identity_address_type,
+ uint8_t *peer_identity_address);
+
+/**
+ * @brief Set privacy mode.
+ * @param[in] peer_identity_address_type Peer identity address type.
+ * @param[in] peer_identity_address Peer identity address.
+ * @param[in] privacy_mode Privacy mode @ref T_GAP_PRIVACY_MODE.
+ * @return Operation result
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_SEND_REQ_FAILED Operation failure.
+ */
+T_GAP_CAUSE le_privacy_set_mode(T_GAP_IDENT_ADDR_TYPE peer_identity_address_type,
+ uint8_t *peer_identity_address,
+ T_GAP_PRIVACY_MODE privacy_mode);
+
+/**
+ * @brief Convert remote bluetooth device address type to identity address type.
+ * @param[in] type Bluetooth device address type @ref T_GAP_REMOTE_ADDR_TYPE.
+ * @return Identity address type @ref T_GAP_IDENT_ADDR_TYPE
+ * @retval GAP_IDENT_ADDR_PUBLIC Public identity address.
+ * @retval GAP_IDENT_ADDR_RAND Random identity address.
+ */
+T_GAP_IDENT_ADDR_TYPE le_privacy_convert_addr_type(T_GAP_REMOTE_ADDR_TYPE type);
+
+/** @} */ /* End of group Gap_Privacy_Exported_Functions */
+/** @} */ /* End of group GAP_PRIVACY_MODULE */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_PRIVACY_H */
diff --git a/inc/bluetooth/gap/gap_scan.h b/inc/bluetooth/gap/gap_scan.h
new file mode 100644
index 0000000..7b71c26
--- /dev/null
+++ b/inc/bluetooth/gap/gap_scan.h
@@ -0,0 +1,307 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_scan.h
+* @brief Head file for Gap Observer role
+* @details
+* @author jane
+* @date 2016-02-18
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef GAP_SCAN_H
+#define GAP_SCAN_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#if F_BT_LE_GAP_SCAN_SUPPORT
+#include "gap_le.h"
+
+
+/** @defgroup Observer_Role GAP Observer Role
+ * @brief GAP observer role
+ * @{
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup Observer_Exported_Types GAP Observer Exported Types
+ * @{
+ */
+
+/** @brief LE scan parameter type */
+typedef enum
+{
+ GAP_PARAM_SCAN_LOCAL_ADDR_TYPE = 0x240, //!< The type of address being used in the scan request packets. Read/Write.
+ GAP_PARAM_SCAN_MODE = 0x241, //!< Scan mode. Read/Write. Size is uint8. Default is GAP_SCAN_MODE_ACTIVE (@ref T_GAP_SCAN_MODE).
+ GAP_PARAM_SCAN_INTERVAL = 0x242, //!< Scan Interval. Read/Write. Size is uint16_t. Default is 0x10. Value range: 0x0004 - 0x4000 (2.5ms - 10240ms 0.625ms/step).
+ GAP_PARAM_SCAN_WINDOW = 0x243, //!< Scan Window. Read/Write. Size is uint16_t. Default is 0x10. Value range: 0x0004 - 0x4000 (2.5ms - 10240ms 0.625ms/step).
+ GAP_PARAM_SCAN_FILTER_POLICY = 0x244, //!< Scan Filter Policy.Read/Write. Size is uint8_t. Default is GAP_SCAN_FILTER_ANY (@ref T_GAP_SCAN_FILTER_POLICY).
+ GAP_PARAM_SCAN_FILTER_DUPLICATES = 0x245 //!< Scan Filter Duplicates.Read/Write. Size is uint8_t. Default is GAP_SCAN_FILTER_DUPLICATE_DISABLE (@ref T_GAP_SCAN_FILTER_DUPLICATE).
+} T_LE_SCAN_PARAM_TYPE;
+
+
+/** End of Observer_Exported_Types
+ * @}
+ */
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup Observer_Exported_Functions GAP Observer Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Set a scan parameter.
+ *
+ * NOTE: You can call this function with a scan parameter type and it will set the
+ * scan parameter. Scan parameters are defined in @ref T_LE_SCAN_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the "p_value" field must
+ * point to a data with type "uint16".
+ *
+ * @param[in] param Scan parameter type: @ref T_LE_SCAN_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and will be cast to the appropriate
+ * data type (For example: if data type param is uint16, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Set result
+ * @retval GAP_CAUSE_SUCCESS Set parameter success.
+ * @retval other Set parameter failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_gap_init()
+ {
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BBPro_central";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+
+ uint8_t scan_mode = GAP_SCAN_MODE_ACTIVE;
+ uint16_t scan_interval = DEFAULT_SCAN_INTERVAL;
+ uint16_t scan_window = DEFAULT_SCAN_WINDOW;
+ uint8_t scan_filter_policy = GAP_SCAN_FILTER_ANY;
+ uint8_t scan_filter_duplicate = GAP_SCAN_FILTER_DUPLICATE_ENABLE;
+
+ uint8_t pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t oob_enable = false;
+ uint32_t passkey = 0;
+ uint8_t fix_passkey_enable = false;
+
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(uint8_t), &pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(uint16_t), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(uint8_t), &io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(uint8_t), &oob_enable);
+
+ le_scan_set_param(GAP_PARAM_SCAN_MODE, sizeof(scan_mode), &scan_mode);
+ le_scan_set_param(GAP_PARAM_SCAN_INTERVAL, sizeof(scan_interval), &scan_interval);
+ le_scan_set_param(GAP_PARAM_SCAN_WINDOW, sizeof(scan_window), &scan_window);
+ le_scan_set_param(GAP_PARAM_SCAN_FILTER_POLICY, sizeof(scan_filter_policy),
+ &scan_filter_policy);
+ le_scan_set_param(GAP_PARAM_SCAN_FILTER_DUPLICATES, sizeof(scan_filter_duplicate),
+ &scan_filter_duplicate);
+
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(uint32_t), &passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(uint8_t), &fix_passkey_enable);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_scan_set_param(T_LE_SCAN_PARAM_TYPE param, uint8_t len, void *p_value);
+
+/**
+ * @brief Get a scan parameter.
+ *
+ * NOTE: You can call this function with a scan parameter type and it will get a
+ * scan parameter. Scan parameters are defined in @ref T_LE_SCAN_PARAM_TYPE.
+ * Also, the "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param Scan parameter type: @ref T_LE_SCAN_PARAM_TYPE.
+ * @param[in,out] p_value Pointer to location to get the parameter value. This is dependent on
+ * the parameter type and will be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Get result
+ * @retval GAP_CAUSE_SUCCESS Get parameter success.
+ * @retval Others Get parameter failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint16_t scan_interval;
+ le_scan_get_param(GAP_PARAM_SCAN_INTERVAL, &scan_interval);
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_scan_get_param(T_LE_SCAN_PARAM_TYPE param, void *p_value);
+
+/**
+ * @brief Start a device discovery scan. If device changes to scanning state, @ref app_handle_dev_state_evt
+ * will be called. And the advertising data or scan response data will be returned by @ref app_gap_callback
+ * with cb_type @ref GAP_MSG_LE_SCAN_INFO.
+ *
+ * NOTE: This function can be called after @ref gap_start_bt_stack is invoked.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS: Operation success, scan started.
+ * @retval GAP_CAUSE_ALREADY_IN_REQ: Operation failure, scan state is GAP_SCAN_STATE_START.
+ * @retval GAP_CAUSE_INVALID_STATE: Operation failure, invalid device state.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ le_scan_start();
+ }
+
+ void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+ {
+ APP_PRINT_INFO5("app_handle_dev_state_evt: init state = %d scan state = %d adv state = %d conn state = %d cause = 0x%x",
+ new_state.gap_init_state,
+ new_state.gap_scan_state, new_state.gap_adv_state, new_state.gap_conn_state, cause);
+
+ if (gap_dev_state.gap_scan_state != new_state.gap_scan_state)
+ {
+ if (new_state.gap_scan_state == GAP_SCAN_STATE_IDLE)
+ {
+ APP_PRINT_INFO0("GAP scan stop");
+ data_uart_print("GAP scan stop\r\n");
+ }
+ else if (new_state.gap_scan_state == GAP_SCAN_STATE_SCANNING)
+ {
+ APP_PRINT_INFO0("GAP scan start");
+ data_uart_print("GAP scan start\r\n");
+ }
+ }
+ }
+ //Received advertising or scan rsp data will be handled in app_gap_callback
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_SCAN_INFO:
+ APP_PRINT_INFO5("GAP_MSG_LE_SCAN_INFO:adv_type 0x%x, bd_addr %s, remote_addr_type %d, rssi %d, data_len %d",
+ cb_data.p_le_scan_info->adv_type,
+ TRACE_BDADDR(cb_data.p_le_scan_info->bd_addr),
+ cb_data.p_le_scan_info->remote_addr_type,
+ cb_data.p_le_scan_info->rssi,
+ cb_data.p_le_scan_info->data_len);
+ break;
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_scan_start(void);
+
+/**
+ * @brief Cancel a device discovery scan.
+ *
+ * NOTE: This function can be called after @ref gap_start_bt_stack is invoked.
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS: Operation success, Cancel started.
+ * @retval GAP_CAUSE_INVALID_STATE: Operation Failure. Invalid state, not in scan mode.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ le_scan_stop();
+ }
+ void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+ {
+ APP_PRINT_INFO5("app_handle_dev_state_evt: init state = %d scan state = %d adv state = %d conn state = %d cause = 0x%x",
+ new_state.gap_init_state,
+ new_state.gap_scan_state, new_state.gap_adv_state, new_state.gap_conn_state, cause);
+
+ if (gap_dev_state.gap_scan_state != new_state.gap_scan_state)
+ {
+ if (new_state.gap_scan_state == GAP_SCAN_STATE_IDLE)
+ {
+ APP_PRINT_INFO0("GAP scan stop");
+ data_uart_print("GAP scan stop\r\n");
+ }
+ else if (new_state.gap_scan_state == GAP_SCAN_STATE_SCANNING)
+ {
+ APP_PRINT_INFO0("GAP scan start");
+ data_uart_print("GAP scan start\r\n");
+ }
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_scan_stop(void);
+
+#if F_BT_LE_GAP_SCAN_FILTER_SUPPORT
+/**
+ * @brief Set scan information filter.
+ *
+ * NOTE: This function can be called before @ref gap_start_bt_stack is invoked.
+ *
+ * @param[in] enable Whether to open the scan info comparison function.
+ * @param[in] offset The start offset of the scan info to compare.
+ * @param[in] len Length of data to compare
+ * @param[in] p_filter Point the data to compare with the scan info.
+ * @return bool.
+ * @retval TRUE Operation success.
+ * @retval FALSE Operation Failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_scanf(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t type = p_parse_value->dw_param[0];
+ uint8_t offset = 0;
+ uint8_t len = 0;
+ uint8_t filter_data[31];
+ if(type == 0)
+ {
+ le_scan_info_filter(false, offset, len, filter_data);
+ }
+ else
+ {
+ offset = 5;
+ len = 2;
+ filter_data[0] = LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ filter_data[1] = HI_WORD(GATT_UUID_SIMPLE_PROFILE);
+ le_scan_info_filter(true, offset, len, filter_data);
+ }
+ return RESULT_SUCCESS;
+ }
+ * \endcode
+ */
+bool le_scan_info_filter(bool enable, uint8_t offset, uint8_t len, uint8_t *p_filter);
+#endif
+/** @} */ /* End of group Observer_Exported_Functions */
+/** @} */ /* End of group Observer_Role */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GAP_SCAN_H */
diff --git a/inc/bluetooth/gap/gap_storage_le.h b/inc/bluetooth/gap/gap_storage_le.h
new file mode 100644
index 0000000..7378e91
--- /dev/null
+++ b/inc/bluetooth/gap/gap_storage_le.h
@@ -0,0 +1,708 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gap_storage_le.h
+* @brief key storage function.
+* @details
+* @author jane
+* @date 2016-02-18
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef FLASH_KEY_MGR_LE_H
+#define FLASH_KEY_MGR_LE_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#include "gap.h"
+#include "gap_le_types.h"
+
+/** @defgroup GAP_LE_STORAGE GAP LE Storage
+ * @brief GAP LE Storage
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GAP_LE_STORAGE_Exported_Macros GAP LE Storage Exported Macros
+ * @{
+ */
+
+/** @defgroup GAP_LE_STORAGE_BITS LE Key Storage Bits
+* @{
+ */
+#define LE_KEY_STORE_REMOTE_BD_BIT 0x01
+#define LE_KEY_STORE_LOCAL_LTK_BIT 0x02
+#define LE_KEY_STORE_REMOTE_LTK_BIT 0x04
+#define LE_KEY_STORE_REMOTE_IRK_BIT 0x08
+#define LE_KEY_STORE_LOCAL_CSRK_BIT 0x10
+#define LE_KEY_STORE_REMOTE_CSRK_BIT 0x20
+#define LE_KEY_STORE_CCCD_DATA_BIT 0x40
+#define LE_KEY_STORE_LOCAL_IRK_BIT 0x80
+#define LE_KEY_STORE_REMOTE_CLIENT_SUPPORTED_FEATURES_BIT 0x0100
+#define LE_KEY_STORE_REMOTE_SRV_CHANGE_AWARE_STATE_BIT 0x0200
+#define LE_KEY_STORE_LOCAL_BD_BIT 0x8000
+
+/**
+ * @}
+ */
+
+/** End of GAP_LE_STORAGE_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_STORAGE_Exported_Types GAP LE Storage Exported Types
+ * @{
+ */
+
+/** @brief Local Device Name */
+typedef struct
+{
+ uint8_t local_name[40];
+} T_LOCAL_NAME;
+
+/** @brief Local Device Appearance */
+typedef struct
+{
+ uint16_t local_appearance;
+ uint8_t padding[2];
+} T_LOCAL_APPEARANCE;
+
+/** @brief Local IRK */
+typedef struct
+{
+ uint8_t local_irk[16];
+} T_LOCAL_IRK;
+
+/** @brief Remote Bluetooth device address info */
+typedef struct
+{
+ uint8_t addr[6];
+ uint8_t remote_bd_type;
+ uint8_t bond_flags;
+} T_LE_REMOTE_BD;
+
+#if F_BT_LE_PRIVACY_SUPPORT
+/** @brief LE privacy information */
+typedef struct
+{
+ bool is_discov;
+ bool central_addr_resolv;
+ bool resolv_addr_only;
+} T_LE_PRIVACY_INFO;
+#endif
+
+/** @brief LE CCCD info */
+typedef struct
+{
+ uint16_t handle;
+ uint16_t ccc_bits;
+} T_LE_CCCD_ELEM;
+
+typedef struct
+{
+ uint8_t data_length;
+ uint8_t padding[3];
+ uint8_t data[1];
+} T_LE_CCCD;
+
+/** @brief LE Key Type */
+typedef enum
+{
+ LE_KEY_UNAUTHEN = 0x04, /**< SSP generated link key without MITM protection. */
+ LE_KEY_AUTHEN = 0x05, /**< SSP generated link key with MITM protection. */
+ LE_KEY_UNAUTHEN_P256 = 0x07, /**< Security Connections generated link key without MITM protection. */
+ LE_KEY_AUTHEN_P256 = 0x08, /**< Security Connections link key with MITM protection. */
+} T_LE_KEY_TYPE;
+
+/** @brief LE key entry */
+typedef struct
+{
+ bool is_used;
+ uint8_t idx;
+ uint16_t flags;
+ uint8_t local_bd_type;
+ uint8_t app_data;
+ uint8_t reserved[2];
+ T_LE_REMOTE_BD remote_bd;
+ T_LE_REMOTE_BD resolved_remote_bd;
+ uint8_t local_bd_addr[6];
+} T_LE_KEY_ENTRY;
+
+typedef struct
+{
+ uint16_t flags;
+ T_LE_REMOTE_BD remote_bd;
+ uint8_t local_ltk[32];
+ uint8_t remote_ltk[32];
+ uint8_t remote_irk[24];
+} T_LE_DEV_INFO;
+
+typedef struct
+{
+ uint8_t link_key_length;
+ uint8_t padding[3];
+ uint8_t key[28];
+} T_LE_LTK;
+
+/** End of GAP_LE_STORAGE_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @defgroup GAP_LE_STORAGE_EXPORT_Functions GAP LE Storage Exported Functions
+ *
+ * @{
+ */
+
+/**
+ * @brief Save local device name to flash.
+ * @param[in] p_data pointer to local device name
+ * @return Operation result.
+ * @retval 0 Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_APP_RESULT gap_service_callback(T_SERVER_ID service_id, void *p_para)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_GAPS_CALLBACK_DATA *p_gap_data = (T_GAPS_CALLBACK_DATA *)p_para;
+ APP_PRINT_INFO2("gap_service_callback conn_id = %d msg_type = %d\n", p_gap_data->conn_id,
+ p_gap_data->msg_type);
+ if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE)
+ {
+ switch (p_gap_data->msg_data.opcode)
+ {
+ case GAPS_WRITE_DEVICE_NAME:
+ {
+ T_LOCAL_NAME device_name;
+ memcpy(device_name.local_name, p_gap_data->msg_data.p_value, p_gap_data->msg_data.len);
+ device_name.local_name[p_gap_data->msg_data.len] = 0;
+ flash_save_local_name(&device_name);
+ }
+ break;
+
+ case GAPS_WRITE_APPEARANCE:
+ {
+ uint16_t appearance_val;
+ T_LOCAL_APPEARANCE appearance;
+
+ LE_ARRAY_TO_UINT16(appearance_val, p_gap_data->msg_data.p_value);
+ appearance.local_appearance = appearance_val;
+ flash_save_local_appearance(&appearance);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION)
+ {
+ if (p_gap_data->msg_data.opcode == GATT_SERVICE_CHANGE_CCCD_ENABLE)
+ {
+ APP_PRINT_INFO0("GATT_SERVICE_CHANGE_CCCD_ENABLE");
+ }
+ }
+ return result;
+ }
+ * \endcode
+ */
+uint32_t flash_save_local_name(T_LOCAL_NAME *p_data);
+
+/**
+ * @brief Load local device name from flash.
+ * @param[in] p_data pointer to local device name
+ * @return Operation result.
+ * @retval 0 Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BB3_GapTest";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t appearance_prop = GAPS_PROPERTY_WRITE_ENABLE;
+ uint8_t device_name_prop = GAPS_PROPERTY_WRITE_ENABLE;
+ T_LOCAL_APPEARANCE appearance_local;
+ T_LOCAL_NAME local_device_name;
+ if (flash_load_local_appearance(&appearance_local) == 0)
+ {
+ if (appearance_local.local_appearance != 0xffff)
+ {
+ appearance = appearance_local.local_appearance;
+ }
+ }
+
+ if (flash_load_local_name(&local_device_name) == 0)
+ {
+ if (local_device_name.local_name[0] != 0xff)
+ {
+ memcpy(device_name, local_device_name.local_name, GAP_DEVICE_NAME_LEN);
+ }
+ }
+ }
+ * \endcode
+ */
+uint32_t flash_load_local_name(T_LOCAL_NAME *p_data);
+
+/**
+ * @brief Save local device appearance to flash.
+ * @param[in] p_data Pointer to local device name
+ * @return Operation result
+ * @retval 0 Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_APP_RESULT gap_service_callback(T_SERVER_ID service_id, void *p_para)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_GAPS_CALLBACK_DATA *p_gap_data = (T_GAPS_CALLBACK_DATA *)p_para;
+ APP_PRINT_INFO2("gap_service_callback conn_id = %d msg_type = %d\n", p_gap_data->conn_id,
+ p_gap_data->msg_type);
+ if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE)
+ {
+ switch (p_gap_data->msg_data.opcode)
+ {
+ case GAPS_WRITE_DEVICE_NAME:
+ {
+ T_LOCAL_NAME device_name;
+ memcpy(device_name.local_name, p_gap_data->msg_data.p_value, p_gap_data->msg_data.len);
+ device_name.local_name[p_gap_data->msg_data.len] = 0;
+ flash_save_local_name(&device_name);
+ }
+ break;
+
+ case GAPS_WRITE_APPEARANCE:
+ {
+ uint16_t appearance_val;
+ T_LOCAL_APPEARANCE appearance;
+
+ LE_ARRAY_TO_UINT16(appearance_val, p_gap_data->msg_data.p_value);
+ appearance.local_appearance = appearance_val;
+ flash_save_local_appearance(&appearance);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION)
+ {
+ if (p_gap_data->msg_data.opcode == GATT_SERVICE_CHANGE_CCCD_ENABLE)
+ {
+ APP_PRINT_INFO0("GATT_SERVICE_CHANGE_CCCD_ENABLE");
+ }
+ }
+ return result;
+ }
+ * \endcode
+ */
+uint32_t flash_save_local_appearance(T_LOCAL_APPEARANCE *p_data);
+
+/**
+ * @brief Load local device appearance from flash.
+ * @param[in] p_data Pointer to local device name
+ * @return Operation result
+ * @retval 0 Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BB3_GapTest";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t appearance_prop = GAPS_PROPERTY_WRITE_ENABLE;
+ uint8_t device_name_prop = GAPS_PROPERTY_WRITE_ENABLE;
+ T_LOCAL_APPEARANCE appearance_local;
+ T_LOCAL_NAME local_device_name;
+ if (flash_load_local_appearance(&appearance_local) == 0)
+ {
+ if (appearance_local.local_appearance != 0xffff)
+ {
+ appearance = appearance_local.local_appearance;
+ }
+ }
+
+ if (flash_load_local_name(&local_device_name) == 0)
+ {
+ if (local_device_name.local_name[0] != 0xff)
+ {
+ memcpy(device_name, local_device_name.local_name, GAP_DEVICE_NAME_LEN);
+ }
+ }
+ }
+ * \endcode
+ */
+uint32_t flash_load_local_appearance(T_LOCAL_APPEARANCE *p_data);
+
+#if F_BT_LE_LOCAL_IRK_SETTING_SUPPORT
+/**
+ * @brief Save local IRK to flash.
+ * @param[in] p_data Pointer to local device name
+ * @return Operation result
+ * @retval 0 Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ T_LOCAL_IRK irk = {0x01,0x02,0x03,};
+ flash_save_local_irk(&irk);
+ }
+ * \endcode
+ */
+uint32_t flash_save_local_irk(T_LOCAL_IRK *p_data);
+
+/**
+ * @brief Load local IRK from flash.
+ * @param[in] p_data Pointer to local device name
+ * @return Operation result
+ * @retval 0 Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test()
+ {
+ T_LOCAL_IRK irk;
+ flash_load_local_irk(&irk);
+ }
+ * \endcode
+ */
+uint32_t flash_load_local_irk(T_LOCAL_IRK *p_data);
+#endif
+
+/**
+ * @brief Find key entry by bluetooth device address and address type.
+ *
+ * @param[in] bd_addr Remote bluetooth device address.
+ * @param[in] bd_type Remote bluetooth device address type.
+ * @return p_entry Pointer to the found key entry.
+ * @retval null No entry found.
+ * @retval others Pointer to the found key entry.
+ */
+T_LE_KEY_ENTRY *le_find_key_entry(uint8_t *bd_addr, T_GAP_REMOTE_ADDR_TYPE bd_type);
+
+/**
+ * @brief Find key entry by index.
+ *
+ * @param[in] idx Key entry index.
+ * @return p_entry Pointer to the found key entry.
+ * @retval null No entry found.
+ * @retval Others Pointer to the found key entry.
+ */
+T_LE_KEY_ENTRY *le_find_key_entry_by_idx(uint8_t idx);
+
+/**
+ * @brief Get the bonded device count.
+ *
+ * Note: You can call this function after @ref le_gap_init is invoked.
+ *
+ * @return num Bonded device count.
+ */
+uint8_t le_get_bond_dev_num(void);
+
+/**
+ * @brief Get the low priority bond device key entry.
+ *
+ * Note: You can call this function after @ref le_gap_init is invoked.
+ *
+ * @return p_entry Pointer to the found key entry.
+ * @retval null No entry found.
+ * @retval Others Pointer to the found key entry.
+ */
+T_LE_KEY_ENTRY *le_get_low_priority_bond(void);
+
+/**
+ * @brief Get the high priority bond device key entry.
+ *
+ * Note: You can call this function after @ref le_gap_init is invoked.
+ *
+ * @return p_entry Pointer to the found key entry.
+ * @retval null No entry found.
+ * @retval others Pointer to the found key entry.
+ */
+T_LE_KEY_ENTRY *le_get_high_priority_bond(void);
+
+/**
+ * @brief Make the specified bonded device with the high priority.
+ *
+ * @param[in] bd_addr Remote bluetooth device address.
+ * @param[in] bd_type Remote bluetooth device address type.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ */
+bool le_set_high_priority_bond(uint8_t *bd_addr, T_GAP_REMOTE_ADDR_TYPE bd_type);
+
+/**
+ * @brief Resolve the specified bonded device.
+ *
+ * @param[in] unresolved_addr Unresolved remote bluetooth device address.
+ * @param[in,out] resolved_addr Resolved remote bluetooth device address.
+ * @param[in,out] resolved_addr_type Resolved remote bluetooth device address type.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t status)
+ {
+ APP_PRINT_INFO1("app_handle_authen_state_evt:conn_id %d", conn_id);
+ switch (new_state)
+ {
+ ...
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ APP_PRINT_INFO1("GAP_MSG_LE_AUTHEN_STATE_CHANGE:(GAP_AUTHEN_STATE_COMPLETE) status 0x%x",
+ status);
+ if (status == 0)
+ {
+ APP_PRINT_INFO0("GAP_MSG_LE_AUTHEN_STATE_CHANGE pair success");
+ {
+ uint8_t addr[6];
+ T_GAP_REMOTE_ADDR_TYPE bd_type;
+ uint8_t resolved_addr[6];
+ T_GAP_IDENT_ADDR_TYPE resolved_bd_type;
+ le_get_conn_addr(conn_id, addr, &bd_type);
+ if (bd_type == GAP_REMOTE_ADDR_LE_RANDOM)
+ {
+ if (le_resolve_random_address(addr, resolved_addr, &resolved_bd_type))
+ {
+ APP_PRINT_INFO2("GAP_AUTHEN_STATE_COMPLETE: resolved_addr %s, resolved_addr_type %d",
+ TRACE_BDADDR(resolved_addr), resolved_bd_type);
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP_AUTHEN_STATE_COMPLETE: resolved addr failed");
+ }
+ }
+ }
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP_MSG_LE_AUTHEN_STATE_CHANGE pair failed");
+ }
+ }
+ break;
+ ...
+ }
+ }
+ * \endcode
+ */
+bool le_resolve_random_address(uint8_t *unresolved_addr, uint8_t *resolved_addr,
+ T_GAP_IDENT_ADDR_TYPE *resolved_addr_type);
+
+/**
+ * @brief Get the cccd information of the bonded device.
+ *
+ * @param[in] p_entry Pointer the key entry of the bonded device.
+ * @param[out] p_data Pointer to ccccd data to read.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ T_GAP_REMOTE_ADDR_TYPE remote_addr_type;
+ uint8_t bd_addr[6];
+ uint8_t conn_id = 0;
+ uint8_t ccc_bits_count = 16;
+ T_LE_CCCD *p_cccd_data = os_mem_alloc(RAM_TYPE_DATA_ON, 4 + ccc_bits_count * 4);
+ T_LE_KEY_ENTRY *p_entry = NULL;
+ if(le_get_conn_addr(conn_id, bd_addr, &remote_addr_type))
+ {
+ p_entry = le_find_key_entry(bd_addr, remote_addr_type);
+ if (p_entry)
+ {
+ if (le_get_cccd_data(p_entry, p_cccd_data))
+ {
+ APP_PRINT_INFO2("Get cccd data: len %d, data %s", p_cccd_data->data_length,
+ TRACE_BINARY(p_cccd_data->data_length, p_cccd_data->data));
+ }
+ }
+ }
+ os_mem_free(p_cccd_data);
+ }
+ * \endcode
+ */
+bool le_get_cccd_data(T_LE_KEY_ENTRY *p_entry, T_LE_CCCD *p_data);
+
+/**
+ * @brief Generate a new bonded device information by APP.
+ *
+ * @param[in] bd_addr Remote bluetooth device address.
+ * @param[in] bd_type Remote bluetooth device address type.
+ * @param[in] local_bd_type Local bluetooth device address type.
+ * @param[in] ltk_length LTK length.
+ * @param[in] p_ltk Pointer to LTK to write.
+ * @param[in] p_cccd Pointer to cccd data to write.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ T_GAP_REMOTE_ADDR_TYPE remote_addr_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t bd_addr[6] = {0x11,0x22,0x33,0x44,0x55,0x66};
+ uint8_t ltk_length = 16;
+ uint8_t ltk[16] = {0x0, 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
+ T_LE_KEY_TYPE key_type = LE_KEY_UNAUTHEN;
+ uint8_t ccc_bits_count = 16;
+ T_LE_CCCD *p_cccd_data = os_mem_alloc(RAM_TYPE_DATA_ON, 4 + ccc_bits_count * 4);
+
+ p_cccd_data->data_length = 4;
+ p_cccd_data->data[0] = 0x04;
+ p_cccd_data->data[1] = 0x00;
+ p_cccd_data->data[2] = 0x02;
+ p_cccd_data->data[3] = 0x00;
+
+ if(le_gen_bond_dev(bd_addr, remote_addr_type, GAP_LOCAL_ADDR_LE_PUBLIC,
+ ltk_length, ltk, key_type, p_cccd_data))
+ {
+ APP_PRINT_INFO0("Generate bond device success");
+ }
+
+ os_mem_free(p_cccd_data);
+ }
+ * \endcode
+ */
+bool le_gen_bond_dev(uint8_t *bd_addr, T_GAP_REMOTE_ADDR_TYPE bd_type,
+ T_GAP_LOCAL_ADDR_TYPE local_bd_type,
+ uint8_t ltk_length, uint8_t *p_ltk, T_LE_KEY_TYPE key_type, T_LE_CCCD *p_cccd);
+
+#if F_BT_LE_PRIVACY_SUPPORT
+/**
+ * @brief Save privacy information.
+ *
+ * @param[in] p_entry Pointer to the key entry of bonded device.
+ * @param[in] p_privacy_info Pointer to privacy information to write.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ */
+bool le_set_privacy_info(T_LE_KEY_ENTRY *p_entry, T_LE_PRIVACY_INFO *p_privacy_info);
+
+/**
+ * @brief Get privacy information.
+ *
+ * @param[in] p_entry Pointer to the key entry of bonded device.
+ * @param[out] p_privacy_info Pointer to privacy information to read.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ */
+bool le_get_privacy_info(T_LE_KEY_ENTRY *p_entry, T_LE_PRIVACY_INFO *p_privacy_info);
+
+/**
+ * @brief Check the bonded device whether it is a privacy device.
+ *
+ * @param[in] p_entry Pointer to the key entry of bonded device.
+ * @return Operation result.
+ * @retval true This bonded device is a privacy device.
+ * @retval false This bonded device is not a privacy device.
+ */
+bool le_check_privacy_bond(T_LE_KEY_ENTRY *p_entry);
+#endif
+
+/**
+ * @brief Get length of device bond information.
+ *
+ * @return Length of device bond information.
+ */
+uint16_t le_get_dev_bond_info_len(void);
+
+/**
+ * @brief Get device bond information.
+ *
+ * @param[in] p_entry Pointer to the key entry of bonded device.
+ * @param[in] p_data Pointer to bond information to read.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ */
+bool le_get_dev_bond_info(T_LE_KEY_ENTRY *p_entry, uint8_t *p_data);
+
+/**
+ * @brief Set device bond information.
+ *
+ * @param[in] length Length of device bond information.
+ * @param[in] p_data Pointer to bond information to write.
+ * @param[in,out] exist Indicate whether bond information of the device is existed.
+ * @return p_entry Pointer to the key entry.
+ * @retval null No entry, operation failure.
+ * @retval others Pointer to the key entry. If parameter exist is false, operation success. If parameter exist is true, bond information of the device is existed.
+ */
+T_LE_KEY_ENTRY *le_set_dev_bond_info(uint16_t length, uint8_t *p_data, bool *exist);
+
+/**
+ * @brief Get maximum pairing information number that can be stored.
+ *
+ * NOTE: This function can be called after @ref le_gap_init is invoked.
+ *
+ * @return Maximum number of LE paired device information that can be stored.
+ */
+uint8_t le_get_max_le_paired_device_num(void);
+
+/**
+ * @brief Get device information.
+ *
+ * @param[in] p_entry Pointer to the key entry of bonded device.
+ * @param[out] p_data Pointer to bond information to read.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ */
+bool le_get_dev_info(T_LE_KEY_ENTRY *p_entry, T_LE_DEV_INFO *p_info);
+
+/**
+ * @brief Modify local LTK.
+ *
+ * @param[in] p_entry Pointer to the key entry of bonded device.
+ * @param[in] key_length key length, Range: 7 to 16.
+ * @param[in] p_ltk Pointer to local ltk to save.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ */
+bool le_set_local_ltk(T_LE_KEY_ENTRY *p_entry, uint8_t key_length, uint8_t *p_ltk);
+/** @} */ /* End of group GAP_LE_STORAGE_EXPORT_Functions */
+/** @} */ /* End of group GAP_LE_STORAGE */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FLASH_KEY_MGR_LE_H */
diff --git a/inc/bluetooth/leaudio/bap.h b/inc/bluetooth/leaudio/bap.h
new file mode 100644
index 0000000..5bfe78b
--- /dev/null
+++ b/inc/bluetooth/leaudio/bap.h
@@ -0,0 +1,127 @@
+#ifndef _BAP_H_
+#define _BAP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "ble_audio_def.h"
+#include "pacs_client.h"
+#include "codec_qos.h"
+//#include "ascs_def.h"
+
+#define BAP_BROADCAST_SOURCE_ROLE 0x01
+#define BAP_BROADCAST_SINK_ROLE 0x02
+#define BAP_BROADCAST_ASSISTANT_ROLE 0x04
+#define BAP_SCAN_DELEGATOR_ROLE 0x08
+#define BAP_UNICAST_CLT_SRC_ROLE 0x10
+#define BAP_UNICAST_CLT_SNK_ROLE 0x20
+#define BAP_UNICAST_SRV_SRC_ROLE 0x40
+#define BAP_UNICAST_SRV_SNK_ROLE 0x80
+
+typedef struct
+{
+ uint8_t role_mask;
+ uint8_t brs_num; //use isoc_big_receiver_num
+
+ uint8_t snk_ase_num;
+ uint8_t src_ase_num;
+
+ bool init_gap;
+//for BAP_UNICAST_CLT_SRC_ROLE, BAP_UNICAST_CLT_SNK_ROLE
+ uint8_t isoc_cig_max_num;
+
+//for BAP_UNICAST_CLT_SRC_ROLE, BAP_UNICAST_CLT_SNK_ROLE, BAP_UNICAST_SRV_SRC_ROLE, BAP_UNICAST_SRV_SNK_ROLE
+ uint8_t isoc_cis_max_num;
+
+//for BAP_BROADCAST_SOURCE_ROLE
+ uint8_t pa_adv_num;
+ uint8_t isoc_big_broadcaster_num;
+ uint8_t isoc_bis_broadcaster_num;
+
+//for BAP_BROADCAST_SINK_ROLE and BAP_BROADCAST_ASSISTANT_ROLE
+ uint8_t pa_sync_num;
+ uint8_t isoc_big_receiver_num;
+ uint8_t isoc_bis_receiver_num;
+} T_BAP_ROLE_INFO;
+
+#if LE_AUDIO_PACS_CLIENT_SUPPORT
+#define PACS_AUDIO_AVAILABLE_CONTEXTS_EXIST 0x01
+#define PACS_AUDIO_SUPPORTED_CONTEXTS_EXIST 0x02
+#define PACS_SINK_AUDIO_LOC_EXIST 0x04
+#define PACS_SINK_PAC_EXIST 0x08
+#define PACS_SOURCE_AUDIO_LOC_EXIST 0x10
+#define PACS_SOURCE_PAC_EXIST 0x20
+
+typedef struct
+{
+ uint16_t value_exist;
+ uint8_t sink_pac_num;
+ uint8_t source_pac_num;
+ uint32_t snk_audio_loc;
+ uint32_t src_audio_loc;
+ uint16_t snk_sup_context;
+ uint16_t src_sup_context;
+ uint16_t snk_avail_context;
+ uint16_t src_avail_context;
+} T_BAP_PACS_INFO;
+
+typedef struct
+{
+ uint8_t codec_id[CODEC_ID_LEN];
+ uint16_t handle;
+ uint16_t pref_audio_contexts;
+ T_CODEC_CAP codec_cap;
+ uint32_t lc3_sup_cfg_bits;
+} T_BAP_PAC_RECORD;
+
+//LE_AUDIO_MSG_BAP_PACS_DIS_DONE
+typedef struct
+{
+ uint16_t conn_handle;
+ bool is_found;
+ uint8_t sink_pac_num;
+ uint8_t source_pac_num;
+} T_BAP_PACS_DIS_DONE;
+
+//LE_AUDIO_MSG_BAP_PAC_NOTIFY
+typedef struct
+{
+ uint16_t conn_handle;
+ uint16_t handle;
+} T_BAP_PAC_NOTIFY;
+
+bool bap_pacs_get_info(uint16_t conn_handle, T_BAP_PACS_INFO *p_pacs_info);
+bool bap_pacs_get_pac_record(uint16_t conn_handle, T_AUDIO_DIRECTION direction, uint8_t *p_pac_num,
+ T_BAP_PAC_RECORD *p_pac_tbl);
+bool bap_pacs_get_pac_record_by_handle(uint16_t conn_handle, uint16_t handle, uint8_t *p_pac_num,
+ T_BAP_PAC_RECORD *p_pac_tbl);
+uint32_t bap_pacs_get_lc3_snk_table_msk(uint16_t conn_handle, uint16_t prefer_context,
+ uint8_t chl_cnt,
+ uint8_t block_num);
+uint32_t bap_pacs_get_lc3_src_table_msk(uint16_t conn_handle, uint16_t prefer_context,
+ uint8_t chl_cnt,
+ uint8_t block_num);
+#endif
+
+#if LE_AUDIO_ASCS_CLIENT_SUPPORT
+#define ASE_ID_MAX_NUM 8
+//LE_AUDIO_MSG_BAP_ASCS_DIS_DONE
+typedef struct
+{
+ uint16_t conn_handle;
+ bool is_found;
+ uint8_t sink_ase_num;
+ uint8_t sink_ase_id[ASE_ID_MAX_NUM];
+ uint8_t source_ase_num;
+ uint8_t source_ase_id[ASE_ID_MAX_NUM];
+} T_BAP_ASCS_DIS_DONE;
+#endif
+
+bool bap_role_init(T_BAP_ROLE_INFO *p_role_info);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/base_data_parse.h b/inc/bluetooth/leaudio/base_data_parse.h
new file mode 100644
index 0000000..2d1842c
--- /dev/null
+++ b/inc/bluetooth/leaudio/base_data_parse.h
@@ -0,0 +1,53 @@
+#ifndef _BASE_DATA_PARSE_H_
+#define _BASE_DATA_PARSE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdint.h>
+#include "codec_def.h"
+
+#if LE_AUDIO_BASE_DATA_PARSE
+
+typedef struct
+{
+ uint8_t subgroup_idx;
+ uint8_t bis_index;
+ uint8_t codec_id[CODEC_ID_LEN];
+ T_CODEC_CFG bis_codec_cfg;
+} T_BASE_DATA_BIS_PARAM;
+
+typedef struct
+{
+ uint8_t subgroup_idx;
+ uint8_t num_bis;
+ uint8_t metadata_len;
+ uint32_t bis_array;
+ uint8_t *p_metadata;
+ T_BASE_DATA_BIS_PARAM *p_bis_param;
+} T_BASE_DATA_SUBGROUP_PARAM;
+
+typedef struct
+{
+ uint8_t num_bis;
+ uint8_t num_subgroups;
+ uint32_t presentation_delay;
+ //Level2 param
+ T_BASE_DATA_SUBGROUP_PARAM *p_subgroup;
+} T_BASE_DATA_MAPPING;
+
+void base_data_print(T_BASE_DATA_MAPPING *p_mapping);
+T_BASE_DATA_MAPPING *base_data_parse_data(uint16_t pa_data_len, uint8_t *p_pa_data);
+bool base_data_cmp(T_BASE_DATA_MAPPING *p_mapping_a, T_BASE_DATA_MAPPING *p_mapping_b);
+bool base_data_get_bis_codec_cfg(T_BASE_DATA_MAPPING *p_mapping, uint8_t bis_idx,
+ T_CODEC_CFG *p_cfg);
+void base_data_free(T_BASE_DATA_MAPPING *p_mapping);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/bass_client.h b/inc/bluetooth/leaudio/bass_client.h
new file mode 100644
index 0000000..4a7c397
--- /dev/null
+++ b/inc/bluetooth/leaudio/bass_client.h
@@ -0,0 +1,80 @@
+#ifndef _BASS_CLIENT_H_
+#define _BASS_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "bass_def.h"
+#include "ble_audio_sync.h"
+//#include "broadcast_source_sm.h"
+
+#if LE_AUDIO_BASS_CLIENT_SUPPORT
+//LE_AUDIO_MSG_BASS_CLIENT_DIS_DONE
+typedef struct
+{
+ uint16_t conn_handle;
+ bool is_found;
+ bool load_form_ftl;
+ uint8_t brs_char_num;
+} T_BASS_CLIENT_DIS_DONE;
+
+//LE_AUDIO_MSG_BASS_CLIENT_BRS_DATA
+typedef struct
+{
+ uint16_t conn_handle;
+ bool notify;
+ uint16_t read_cause;
+ uint8_t instance_id;
+ T_BASS_BRS_DATA *p_brs_data;
+} T_BASS_CLIENT_BRS_DATA;
+
+//LE_AUDIO_MSG_BASS_CLIENT_SYNC_INFO_REQ
+typedef struct
+{
+ uint16_t conn_handle;
+ uint8_t instance_id;
+ T_BASS_BRS_DATA *p_brs_data;
+} T_BASS_CLIENT_SYNC_INFO_REQ;
+
+//LE_AUDIO_MSG_BASS_CLIENT_CP_RESULT
+typedef struct
+{
+ uint16_t conn_handle;
+ uint16_t cause;
+} T_BASS_CLIENT_CP_RESULT;
+
+//LE_AUDIO_MSG_BASS_CLIENT_CCCD
+typedef struct
+{
+ uint16_t conn_handle;
+ uint16_t cause;
+} T_BASS_CLIENT_CCCD;
+
+bool bass_enable_cccd(uint16_t conn_handle);
+bool bass_read_brs_value(uint16_t conn_handle, uint8_t instance_id);
+
+bool bass_cp_remote_scan_stop(uint16_t conn_handle, bool is_req);
+bool bass_cp_remote_scan_start(uint16_t conn_handle, bool is_req);
+bool bass_cp_add_source(uint16_t conn_handle, T_BASS_CP_ADD_SOURCE *p_cp_data, bool is_req);
+bool bass_cp_modify_source(uint16_t conn_handle, T_BASS_CP_MODIFY_SOURCE *p_cp_data, bool is_req);
+bool bass_cp_set_broadcast_code(uint16_t conn_handle, T_BASS_CP_SET_BROADCAST_CODE *p_cp_data,
+ bool is_req);
+bool bass_cp_remove_source(uint16_t conn_handle, T_BASS_CP_REMOVE_SOURCE *p_cp_data, bool is_req);
+T_BASS_BRS_DATA *bass_get_brs_data(uint16_t conn_handle, uint8_t instance_id);
+
+bool bass_cp_add_source_by_sync_info(T_BLE_AUDIO_SYNC_HANDLE handle, uint16_t conn_handle,
+ T_BASS_PA_SYNC pa_sync, uint32_t bis_array, bool is_req);
+bool bass_cp_modify_source_by_sync_info(T_BLE_AUDIO_SYNC_HANDLE handle, uint16_t conn_handle,
+ uint8_t source_id,
+ T_BASS_PA_SYNC pa_sync, uint32_t bis_array, bool is_req);
+
+bool bass_transfer_syncinfo_of_remote_src(T_BLE_AUDIO_SYNC_HANDLE handle, uint16_t conn_handle,
+ T_BASS_PAST_SRV_DATA srv_data);
+
+#endif
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/bass_def.h b/inc/bluetooth/leaudio/bass_def.h
new file mode 100644
index 0000000..047ba88
--- /dev/null
+++ b/inc/bluetooth/leaudio/bass_def.h
@@ -0,0 +1,154 @@
+#ifndef _BASS_DEF_H_
+#define _BASS_DEF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "gap.h"
+#include "metadata_def.h"
+#include "ble_audio_def.h"
+
+#define ATT_ERR_BASS_OPCODE_NOT_SUPPORT 0x80
+#define ATT_ERR_BASS_INVALID_SRC_ID 0x81
+
+#define BASS_FAILED_TO_SYNC_TO_BIG 0xFFFFFFFF
+#define BASS_CP_BIS_SYNC_NO_PREFER 0xFFFFFFFF
+#define BASS_PA_INTERVAL_UNKNOWN 0xFFFF
+
+#define BASS_BRS_DATA_MIN_LEN 15
+// BASS CP minimum possible total length
+#define BASS_CP_OP_MIN_LEN 1
+#define BASS_CP_OP_REMOTE_SCAN_STOP_LEN 1
+#define BASS_CP_OP_REMOTE_SCAN_START_LEN 1
+#define BASS_CP_OP_ADD_SOURCE_MIN_LEN 16
+#define BASS_CP_OP_MODIFY_SOURCE_MIN_LEN 6
+#define BASS_CP_OP_SET_BROADCAST_CODE_LEN 18
+#define BASS_CP_OP_REMOVE_SOURCE_LEN 2
+
+#define BASS_BRA_INC_BST_CODE_LEN 31
+
+#define BASS_BRS_CHAR_MAX_NUM 4
+#define GATT_UUID_BASS 0x184F
+#define BASS_UUID_CHAR_BROADCAST_AUDIO_SCAN_CP 0x2BC7
+#define BASS_UUID_CHAR_BROADCAST_RECEIVE_STATE 0x2BC8
+
+typedef enum
+{
+ PA_SYNC_STATE_NOT_SYNC = 0x00,
+ PA_SYNC_STATE_SYNCINFO_REQ = 0x01,
+ PA_SYNC_STATE_SYNC = 0x02,
+ PA_SYNC_STATE_FAILED = 0x03,
+ PA_SYNC_STATE_NO_PAST = 0x04,
+} T_PA_SYNC_STATE;
+
+typedef enum
+{
+ BIG_NOT_ENCRYPTED = 0x00,
+ BIG_BROADCAST_CODE_REQUIRED = 0x01,
+ BIG_DECRYPTING = 0x02,
+ BIG_BAD_CODE = 0x03,
+} T_BIG_ENCRYPTION_STATE;
+
+typedef enum
+{
+ BASS_CP_OP_REMOTE_SCAN_STOP = 0x00,
+ BASS_CP_OP_REMOTE_SCAN_START = 0x01,
+ BASS_CP_OP_ADD_SOURCE = 0x02,
+ BASS_CP_OP_MODIFY_SOURCE = 0x03,
+ BASS_CP_OP_SET_BROADCAST_CODE = 0x04,
+ BASS_CP_OP_REMOVE_SOURCE = 0x05,
+} T_BASS_CP_OP;
+
+typedef enum
+{
+ BASS_PA_NOT_SYNC = 0x00,
+ BASS_PA_SYNC_PAST = 0x01,
+ BASS_PA_SYNC_NO_PAST = 0x02,
+} T_BASS_PA_SYNC;
+
+typedef struct
+{
+ uint8_t adv_a_match_ext_adv; //AdvA in PAST matches AdvA in ADB_EXT_IND, 0b0=Yes, 0b1=No/Do't know
+ uint8_t adv_a_match_src;//AdvA in PAST matches Source_Address, 0b0=Yes, 0b1=No/Do't know
+ uint8_t source_id;
+} T_BASS_PAST_SRV_DATA;
+
+typedef struct
+{
+ uint32_t bis_sync;
+ uint8_t metadata_len;
+ uint8_t *p_metadata;
+} T_BASS_CP_BIS_INFO;
+
+typedef struct
+{
+ bool brs_is_used;
+ //Broadcast Receive State Field
+ uint8_t source_id;
+ uint8_t source_address_type;
+ uint8_t source_address[GAP_BD_ADDR_LEN];
+ uint8_t source_adv_sid;
+ uint8_t broadcast_id[BROADCAST_ID_LEN];
+ T_PA_SYNC_STATE pa_sync_state;
+ uint32_t bis_sync_state;
+ T_BIG_ENCRYPTION_STATE big_encryption;
+ uint8_t bad_code[BROADCAST_CODE_LEN];
+ uint8_t num_subgroups;
+ uint16_t bis_info_size;
+ T_BASS_CP_BIS_INFO *p_cp_bis_info;
+} T_BASS_BRS_DATA;
+
+typedef struct
+{
+ uint8_t advertiser_address_type;
+ uint8_t advertiser_address[GAP_BD_ADDR_LEN];
+ uint8_t advertiser_sid;
+ uint8_t broadcast_id[BROADCAST_ID_LEN];
+ T_BASS_PA_SYNC pa_sync;
+ uint16_t pa_interval;
+ uint8_t num_subgroups;
+ uint16_t bis_info_size;
+ T_BASS_CP_BIS_INFO *p_cp_bis_info;
+} T_BASS_CP_ADD_SOURCE;
+
+typedef struct
+{
+ uint8_t source_id;
+ T_BASS_PA_SYNC pa_sync;
+ uint16_t pa_interval;
+ uint8_t num_subgroups;
+ uint16_t bis_info_size;
+ T_BASS_CP_BIS_INFO *p_cp_bis_info;
+} T_BASS_CP_MODIFY_SOURCE;
+
+typedef struct
+{
+ uint8_t source_id;
+ uint8_t broadcast_code[BROADCAST_CODE_LEN];
+} T_BASS_CP_SET_BROADCAST_CODE;
+
+typedef struct
+{
+ uint8_t source_id;
+} T_BASS_CP_REMOVE_SOURCE;
+
+typedef union
+{
+ T_BASS_CP_ADD_SOURCE add_source;
+ T_BASS_CP_MODIFY_SOURCE modify_source;
+ T_BASS_CP_SET_BROADCAST_CODE set_broadcast_code;
+ T_BASS_CP_REMOVE_SOURCE remove_source;
+} T_BASS_CP_PARAM;
+
+typedef struct
+{
+ T_BASS_CP_OP opcode;
+ T_BASS_CP_PARAM param;
+} T_BASS_CP_DATA;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/ble_audio.h b/inc/bluetooth/leaudio/ble_audio.h
new file mode 100644
index 0000000..9ac02d3
--- /dev/null
+++ b/inc/bluetooth/leaudio/ble_audio.h
@@ -0,0 +1,85 @@
+#ifndef _BLE_AUDIO_H_
+#define _BLE_AUDIO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "gap_msg.h"
+#include "gap.h"
+#include "app_msg.h"
+//#include "profile_server_def.h"
+
+typedef enum
+{
+ LE_AUDIO_MSG_GROUP_BASS = 0x0000,
+ LE_AUDIO_MSG_GROUP_BASS_CLIENT = 0x0100,
+ LE_AUDIO_MSG_GROUP_PACS = 0x0200,
+ LE_AUDIO_MSG_GROUP_PACS_CLIENT = 0x0300,
+ LE_AUDIO_MSG_GROUP_CSIS = 0x0400,
+ LE_AUDIO_MSG_GROUP_CSIS_CLIENT = 0x0500,
+
+ LE_AUDIO_MSG_GROUP_CAP = 0x2000,
+ LE_AUDIO_MSG_GROUP_BAP = 0x2100,
+} T_LE_AUDIO_MSG_GROUP;
+
+typedef enum
+{
+ //bass_client.h
+ LE_AUDIO_MSG_BASS_CLIENT_DIS_DONE = LE_AUDIO_MSG_GROUP_BASS_CLIENT | 0x00,
+ LE_AUDIO_MSG_BASS_CLIENT_CCCD = LE_AUDIO_MSG_GROUP_BASS_CLIENT | 0x01,
+ LE_AUDIO_MSG_BASS_CLIENT_CP_RESULT = LE_AUDIO_MSG_GROUP_BASS_CLIENT | 0x02,
+ LE_AUDIO_MSG_BASS_CLIENT_BRS_DATA = LE_AUDIO_MSG_GROUP_BASS_CLIENT | 0x03,
+ LE_AUDIO_MSG_BASS_CLIENT_SYNC_INFO_REQ = LE_AUDIO_MSG_GROUP_BASS_CLIENT | 0x04,
+
+ //pacs_client.h
+ LE_AUDIO_MSG_PACS_CLIENT_DIS_DONE = LE_AUDIO_MSG_GROUP_PACS_CLIENT | 0x00,
+ LE_AUDIO_MSG_PACS_CLIENT_CCCD = LE_AUDIO_MSG_GROUP_PACS_CLIENT | 0x01,
+ LE_AUDIO_MSG_PACS_CLIENT_WRITE_SINK_LOC_RESULT = LE_AUDIO_MSG_GROUP_PACS_CLIENT | 0x02,
+ LE_AUDIO_MSG_PACS_CLIENT_WRITE_SOURCE_LOC_RESULT = LE_AUDIO_MSG_GROUP_PACS_CLIENT | 0x03,
+ LE_AUDIO_MSG_PACS_CLIENT_READ_RESULT = LE_AUDIO_MSG_GROUP_PACS_CLIENT | 0x04,
+ LE_AUDIO_MSG_PACS_CLIENT_NOTIFY = LE_AUDIO_MSG_GROUP_PACS_CLIENT | 0x05,
+
+ //csis_client.h
+ LE_AUDIO_MSG_CSIS_CLIENT_DIS_DONE = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x00,
+ LE_AUDIO_MSG_CSIS_CLIENT_SEARCH_TIMEOUT = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x01,
+ LE_AUDIO_MSG_CSIS_CLIENT_SEARCH_DONE = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x02,
+ LE_AUDIO_MSG_CSIS_CLIENT_SET_MEM_FOUND = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x04,
+ LE_AUDIO_MSG_CSIS_CLIENT_COOR_SET_DEL = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x05,
+ LE_AUDIO_MSG_CSIS_CLIENT_LOCK_REQ_DONE = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x06,
+ LE_AUDIO_MSG_CSIS_CLIENT_UNLOCK_REQ_DONE = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x07,
+ LE_AUDIO_MSG_CSIS_CLIENT_LOCK_STATE_CHANGE = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x08,
+ LE_AUDIO_MSG_CSIS_CLIENT_READ_RESULT = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x09,
+ LE_AUDIO_MSG_CSIS_CLIENT_SIRK_CHANGE = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x0a,
+
+ //bap.h
+ LE_AUDIO_MSG_BAP_PACS_DIS_DONE = LE_AUDIO_MSG_GROUP_BAP | 0x00,
+ LE_AUDIO_MSG_BAP_PAC_NOTIFY = LE_AUDIO_MSG_GROUP_BAP | 0x01,
+ LE_AUDIO_MSG_BAP_ASCS_DIS_DONE = LE_AUDIO_MSG_GROUP_BAP | 0x02,
+
+ //cap.h
+ LE_AUDIO_MSG_CAP_DIS_DONE = LE_AUDIO_MSG_GROUP_CAP | 0x00,
+} T_LE_AUDIO_MSG;
+
+typedef T_APP_RESULT(*P_FUN_BLE_AUDIO_CB)(T_LE_AUDIO_MSG msg, void *buf);
+
+typedef struct
+{
+ P_FUN_BLE_AUDIO_CB p_fun_cb;
+ void *evt_queue_handle;
+ void *io_queue_handle;
+} T_BLE_AUDIO_PARAMS;
+
+bool ble_audio_init(T_BLE_AUDIO_PARAMS *p_param);
+bool ble_audio_check_remote_features(uint16_t conn_handle, uint8_t array_index,
+ uint8_t feature_mask);
+
+void ble_audio_handle_msg(T_IO_MSG *p_io_msg);
+void ble_audio_handle_gap_msg(uint16_t subtype, T_LE_GAP_MSG gap_msg);
+void ble_audio_handle_gap_cb(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/ble_audio_def.h b/inc/bluetooth/leaudio/ble_audio_def.h
new file mode 100644
index 0000000..609acbf
--- /dev/null
+++ b/inc/bluetooth/leaudio/ble_audio_def.h
@@ -0,0 +1,80 @@
+#ifndef _BLE_AUDIO_DEF_H_
+#define _BLE_AUDIO_DEF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#define BROADCAST_ID_LEN 3
+#define BROADCAST_CODE_LEN 16
+
+#define BROADCAST_AUDIO_ANNOUNCEMENT_SRV_UUID 0x1852
+#define BASIC_AUDIO_ANNOUNCEMENT_SRV_UUID 0x1851
+
+#define AUDIO_DEFAULT_PRESENTATION_DELAY 40000
+
+#define ADV_TARGETED_ANNOUNCEMENT 0x01
+#define ADV_GENERAL_ANNOUNCEMENT 0x00
+
+#define AUDIO_LOCATION_MONO 0x00000000
+#define AUDIO_LOCATION_FL 0x00000001
+#define AUDIO_LOCATION_FR 0x00000002
+#define AUDIO_LOCATION_FC 0x00000004
+#define AUDIO_LOCATION_LFE1 0x00000008
+#define AUDIO_LOCATION_BL 0x00000010
+#define AUDIO_LOCATION_BR 0x00000020
+#define AUDIO_LOCATION_FLC 0x00000040
+#define AUDIO_LOCATION_FRC 0x00000080
+#define AUDIO_LOCATION_BC 0x00000100
+#define AUDIO_LOCATION_LFE2 0x00000200
+#define AUDIO_LOCATION_SIL 0x00000400
+#define AUDIO_LOCATION_SIR 0x00000800
+#define AUDIO_LOCATION_TPFL 0x00001000
+#define AUDIO_LOCATION_TPFR 0x00002000
+#define AUDIO_LOCATION_TPFC 0x00004000
+#define AUDIO_LOCATION_TPC 0x00008000
+#define AUDIO_LOCATION_TPBL 0x00010000
+#define AUDIO_LOCATION_TPBR 0x00020000
+#define AUDIO_LOCATION_TPSIL 0x00040000
+#define AUDIO_LOCATION_TPSIR 0x00080000
+#define AUDIO_LOCATION_TPBC 0x00100000
+#define AUDIO_LOCATION_BTFC 0x00200000
+#define AUDIO_LOCATION_BTFL 0x00400000
+#define AUDIO_LOCATION_BTFR 0x00800000
+#define AUDIO_LOCATION_FLW 0x01000000
+#define AUDIO_LOCATION_FRW 0x02000000
+#define AUDIO_LOCATION_LS 0x04000000
+#define AUDIO_LOCATION_RS 0x08000000
+#define AUDIO_LOCATION_RFU 0xF0000000
+#define AUDIO_LOCATION_MASK 0x0FFFFFFF
+
+typedef enum
+{
+ AUDIO_UNFRAMED = 0x00,
+ AUDIO_FRAMED = 0x01,
+} T_AUDIO_FRAMING;
+
+typedef enum
+{
+ SERVER_AUDIO_SINK = 0x01,
+ SERVER_AUDIO_SOURCE = 0x02,
+} T_AUDIO_DIRECTION;
+
+typedef enum
+{
+ UNSPEC_AUDIO_INPUT = 0x00,
+ BLUETOOTH_AUDIO_INPUT = 0x01,
+ MICROPHONE_AUDIO_INPUT = 0x02,
+ ANLOG_AUDIO_INPUT = 0x03,
+ DIGITAL_AUDIO_INPUT = 0x04,
+ RADIO_AUDIO_INPUT = 0x05,
+ STREAMING_AUDIO_INPUT = 0x06,
+} T_AUDIO_INPUT_TYPE;
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/ble_audio_flags.h b/inc/bluetooth/leaudio/ble_audio_flags.h
new file mode 100644
index 0000000..9e419e2
--- /dev/null
+++ b/inc/bluetooth/leaudio/ble_audio_flags.h
@@ -0,0 +1,56 @@
+#ifndef _BLE_AUDIO_FLAGS_H_
+#define _BLE_AUDIO_FLAGS_H_
+
+#define LE_AUDIO_DEBUG 1
+
+#define MAX_BLE_LINK_NUM 2
+#define MAX_BLE_SRV_NUM 16
+
+#define LE_AUDIO_PACS_SUPPORT 0
+#define LE_AUDIO_ASCS_SUPPORT 0
+#define LE_AUDIO_BASS_SUPPORT 0
+
+#define LE_AUDIO_VCS_SUPPORT 0
+#define LE_AUDIO_VOCS_SUPPORT 0
+#define LE_AUDIO_AICS_SUPPORT 0
+#define LE_AUDIO_AICS_NUM 0
+#define LE_AUDIO_MICS_SUPPORT 0
+
+#define LE_AUDIO_CSIS_SUPPORT 0
+#define LE_AUDIO_CAS_SUPPORT 0
+
+#define LE_AUDIO_TBS_SUPPORT 0
+#define LE_AUDIO_TMAS_SUPPORT 0
+#define LE_AUDIO_HAS_SUPPORT 0
+
+#define LE_AUDIO_MCS_SERV_SUPPORT 0
+#define LE_AUDIO_OTS_SERV_SUPPORT 0
+
+#define LE_AUDIO_CAP_SUPPORT 0
+#define LE_AUDIO_BAP_SUPPORT 1
+
+#define LE_AUDIO_PACS_CLIENT_SUPPORT 1
+#define LE_AUDIO_ASCS_CLIENT_SUPPORT 0
+#define LE_AUDIO_BASS_CLIENT_SUPPORT 1
+#define LE_AUDIO_MCS_CLIENT_SUPPORT 0
+#define LE_AUDIO_OTS_CLIENT_SUPPORT 0
+
+#define LE_AUDIO_VCS_CLIENT_SUPPORT 0
+#define LE_AUDIO_VOCS_CLIENT_SUPPORT 0
+#define LE_AUDIO_AICS_CLIENT_SUPPORT 0
+#define LE_AUDIO_MICS_CLIENT_SUPPORT 0
+
+#define LE_AUDIO_CSIS_CLIENT_SUPPORT 0
+#define LE_AUDIO_TBS_CLIENT_SUPPORT 0
+#define LE_AUDIO_TMAP_CLIENT_SUPPORT 0
+#define LE_AUDIO_HAS_CLIENT_SUPPORT 0
+
+#define LE_AUDIO_BROADCAST_SOURCE_ROLE 0
+#define LE_AUDIO_BROADCAST_SINK_ROLE 0
+#define LE_AUDIO_SCAN_DELEGATOR_ROLE 0
+#define LE_AUDIO_BROADCAST_ASSISTANT_ROLE 1
+
+#define LE_AUDIO_BASE_DATA_GENERATE (LE_AUDIO_BROADCAST_SOURCE_ROLE)
+#define LE_AUDIO_BASE_DATA_PARSE (LE_AUDIO_BROADCAST_SINK_ROLE || LE_AUDIO_BROADCAST_ASSISTANT_ROLE)
+
+#endif
diff --git a/inc/bluetooth/leaudio/ble_audio_group.h b/inc/bluetooth/leaudio/ble_audio_group.h
new file mode 100644
index 0000000..67c0125
--- /dev/null
+++ b/inc/bluetooth/leaudio/ble_audio_group.h
@@ -0,0 +1,89 @@
+#ifndef _BLE_AUDIO_GROUP_H_
+#define _BLE_AUDIO_GROUP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "gap.h"
+#include "gap_msg.h"
+
+typedef void *T_BLE_AUDIO_GROUP_HANDLE;
+typedef void *T_BLE_AUDIO_DEV_HANDLE;
+
+typedef enum
+{
+ AUDIO_GROUP_MSG_BAP_STATE = 0x01,
+ AUDIO_GROUP_MSG_BAP_SESSION_REMOVE = 0x02,
+ AUDIO_GROUP_MSG_BAP_START_QOS_CFG = 0x04,
+ AUDIO_GROUP_MSG_BAP_CREATE_CIS = 0x05,
+ AUDIO_GROUP_MSG_BAP_START_METADATA_CFG = 0x06,
+ AUDIO_GROUP_MSG_BAP_SETUP_DATA_PATH = 0x07,
+ AUDIO_GROUP_MSG_BAP_REMOVE_DATA_PATH = 0x08,
+ AUDIO_GROUP_MSG_BAP_METADATA_UPDATE = 0x09,
+ AUDIO_GROUP_MSG_BAP_CIS_DISCONN = 0x0A,
+
+ AUDIO_GROUP_MSG_DEV_CONN = 0x20,
+ AUDIO_GROUP_MSG_DEV_DISCONN = 0x21,
+} T_AUDIO_GROUP_MSG;
+
+//AUDIO_GROUP_MSG_DEV_CONN
+typedef struct
+{
+ T_BLE_AUDIO_DEV_HANDLE dev_handle;
+} T_AUDIO_GROUP_MSG_DEV_CONN;
+
+//AUDIO_GROUP_MSG_DEV_DISCONN
+typedef struct
+{
+ T_BLE_AUDIO_DEV_HANDLE dev_handle;
+ uint16_t cause;
+} T_AUDIO_GROUP_MSG_DEV_DISCONN;
+
+#if 0
+typedef enum
+{
+ AUDIO_GROUP_RESULT_SUCCESS,
+ AUDIO_GROUP_RESULT_FAILED,
+ AUDIO_GROUP_RESULT_TIMEOUT_FAILED,
+ AUDIO_GROUP_RESULT_TIMEOUT_PARTIAL_SUCCESS,
+} T_AUDIO_GROUP_RESULT;
+#endif
+
+typedef struct
+{
+ bool is_used;
+ T_BLE_AUDIO_DEV_HANDLE dev_handle;
+ T_GAP_CONN_STATE conn_state;
+ T_GAP_REMOTE_ADDR_TYPE addr_type;
+ uint8_t bd_addr[6];
+} T_AUDIO_DEV_INFO;
+
+typedef T_APP_RESULT(*P_FUN_AUDIO_GROUP_CB)(T_AUDIO_GROUP_MSG msg, T_BLE_AUDIO_GROUP_HANDLE handle,
+ void *buf);
+
+T_BLE_AUDIO_GROUP_HANDLE ble_audio_group_allocate(void);
+bool ble_audio_group_reg_cb(T_BLE_AUDIO_GROUP_HANDLE group_handle, P_FUN_AUDIO_GROUP_CB p_fun_cb);
+bool ble_audio_group_release(T_BLE_AUDIO_GROUP_HANDLE group_handle);
+T_BLE_AUDIO_DEV_HANDLE ble_audio_group_add_dev(T_BLE_AUDIO_GROUP_HANDLE group_handle,
+ uint8_t *p_bd_addr, uint8_t addr_type);
+bool ble_audio_group_remove_dev(T_BLE_AUDIO_GROUP_HANDLE group_handle,
+ T_BLE_AUDIO_DEV_HANDLE dev_handle);
+T_BLE_AUDIO_DEV_HANDLE ble_audio_group_find_dev(T_BLE_AUDIO_GROUP_HANDLE group_handle,
+ uint8_t *bd_addr, uint8_t addr_type);
+T_BLE_AUDIO_DEV_HANDLE ble_audio_group_find_dev_by_conn_handle(T_BLE_AUDIO_GROUP_HANDLE
+ group_handle,
+ uint16_t conn_handle);
+bool ble_audio_group_get_dev_info(T_BLE_AUDIO_GROUP_HANDLE group_handle,
+ T_BLE_AUDIO_DEV_HANDLE dev_handle,
+ T_AUDIO_DEV_INFO *p_info);
+uint8_t ble_audio_group_get_used_dev_num(T_BLE_AUDIO_GROUP_HANDLE group_handle);
+uint8_t ble_audio_group_get_dev_num(T_BLE_AUDIO_GROUP_HANDLE group_handle);
+bool ble_audio_group_get_info(T_BLE_AUDIO_GROUP_HANDLE group_handle, uint8_t *p_dev_num,
+ T_AUDIO_DEV_INFO *p_dev_tbl);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/ble_audio_sync.h b/inc/bluetooth/leaudio/ble_audio_sync.h
new file mode 100644
index 0000000..e9b9bd3
--- /dev/null
+++ b/inc/bluetooth/leaudio/ble_audio_sync.h
@@ -0,0 +1,126 @@
+#ifndef _BLE_AUDIO_SYNC_H_
+#define _BLE_AUDIO_SYNC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#if (LE_AUDIO_BROADCAST_SINK_ROLE | LE_AUDIO_BROADCAST_ASSISTANT_ROLE)
+#include "gap.h"
+#include "gap_pa_sync.h"
+#include "gap_past_recipient.h"
+#include "ble_audio_def.h"
+#include "base_data_parse.h"
+
+typedef void *T_BLE_AUDIO_SYNC_HANDLE;
+
+#define MSG_BLE_AUDIO_PA_SYNC_STATE 0x01
+#define MSG_BLE_AUDIO_PA_REPORT_INFO 0x02
+#define MSG_BLE_AUDIO_BASE_DATA_MODIFY_INFO 0x03
+#define MSG_BLE_AUDIO_PA_BIGINFO 0x04
+
+#define MSG_BLE_AUDIO_SYNC_HANDLE_RELEASED 0x20
+#define MSG_BLE_AUDIO_ADDR_UPDATE 0x21
+
+typedef enum
+{
+ BLE_AUDIO_ACTION_ROLE_IDLE = 0x00,
+ BLE_AUDIO_ACTION_ROLE_LOCAL_API = 0x01,
+#if LE_AUDIO_BASS_SUPPORT
+ BLE_AUDIO_ACTION_ROLE_BASS = 0x02,
+#endif
+} T_BLE_AUDIO_ACTION_ROLE;
+
+typedef struct
+{
+ T_BASE_DATA_MAPPING *p_base_mapping;
+} T_BLE_AUDIO_BASE_DATA_MODIFY_INFO;
+
+typedef enum
+{
+ BLE_AUDIO_PA_IDLE = 0x00,
+ BLE_AUDIO_PA_SYNC = 0x01,
+ BLE_AUDIO_PA_TERMINATE = 0x02,
+ BLE_AUDIO_PA_LOST = 0x03,
+} T_BLE_AUDIO_PA_ACTION;
+
+typedef struct
+{
+ T_GAP_PA_SYNC_STATE sync_state;
+ T_BLE_AUDIO_PA_ACTION action;
+ T_BLE_AUDIO_ACTION_ROLE action_role;
+ uint16_t cause;
+} T_BLE_AUDIO_PA_SYNC_STATE;
+
+typedef struct
+{
+ T_BLE_AUDIO_ACTION_ROLE action_role;
+} T_BLE_AUDIO_SYNC_HANDLE_RELEASED;
+
+typedef struct
+{
+ uint8_t *advertiser_address;
+} T_BLE_AUDIO_ADDR_UPDATE;
+
+typedef union
+{
+ T_BLE_AUDIO_PA_SYNC_STATE *p_pa_sync_state;
+ T_LE_PERIODIC_ADV_REPORT_INFO *p_le_periodic_adv_report_info;
+ T_BLE_AUDIO_BASE_DATA_MODIFY_INFO *p_base_data_modify_info;
+
+ T_LE_BIGINFO_ADV_REPORT_INFO *p_le_biginfo_adv_report_info;
+
+ T_BLE_AUDIO_SYNC_HANDLE_RELEASED *p_sync_handle_released;
+ T_BLE_AUDIO_ADDR_UPDATE *p_addr_update;
+} T_BLE_AUDIO_SYNC_CB_DATA;
+
+typedef struct
+{
+ uint8_t advertiser_address_type;
+ uint8_t advertiser_address[GAP_BD_ADDR_LEN];
+ uint8_t adv_sid;
+ uint8_t broadcast_id[BROADCAST_ID_LEN];
+ //PA info
+ uint8_t sync_id;
+ T_GAP_PA_SYNC_STATE pa_state;
+ uint16_t pa_interval;
+ T_BASE_DATA_MAPPING *p_base_mapping;
+ bool big_info_received;
+ T_LE_BIGINFO_ADV_REPORT_INFO big_info;
+} T_BLE_AUDIO_SYNC_INFO;
+
+typedef void(*P_FUN_BLE_AUDIO_SYNC_CB)(T_BLE_AUDIO_SYNC_HANDLE handle, uint8_t cb_type,
+ void *p_cb_data);
+
+T_BLE_AUDIO_SYNC_HANDLE ble_audio_sync_create(P_FUN_BLE_AUDIO_SYNC_CB cb_pfn,
+ uint8_t advertiser_address_type,
+ uint8_t *advertiser_address, uint8_t adv_sid,
+ uint8_t broadcast_id[BROADCAST_ID_LEN]);
+bool ble_audio_sync_update_cb(T_BLE_AUDIO_SYNC_HANDLE handle,
+ P_FUN_BLE_AUDIO_SYNC_CB cb_pfn);
+bool ble_audio_sync_update_addr(T_BLE_AUDIO_SYNC_HANDLE handle,
+ uint8_t *advertiser_address);
+
+T_BLE_AUDIO_SYNC_HANDLE ble_audio_sync_find(uint8_t advertiser_address_type,
+ uint8_t adv_sid, uint8_t broadcast_id[BROADCAST_ID_LEN]);
+bool ble_audio_sync_get_info(T_BLE_AUDIO_SYNC_HANDLE handle, T_BLE_AUDIO_SYNC_INFO *p_info);
+bool ble_audio_sync_realese(T_BLE_AUDIO_SYNC_HANDLE handle);
+
+bool ble_audio_pa_sync_establish(T_BLE_AUDIO_SYNC_HANDLE handle, uint8_t options,
+ uint8_t sync_cte_type,
+ uint16_t skip, uint16_t sync_timeout);
+bool ble_audio_pa_terminate(T_BLE_AUDIO_SYNC_HANDLE handle);
+
+bool ble_audio_set_default_past_recipient_param(
+ T_GAP_PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_PARAM *p_param);
+bool ble_audio_set_past_recipient_param(uint16_t conn_handle,
+ T_GAP_PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_PARAM *p_param);
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/bt_bond_mgr.h b/inc/bluetooth/leaudio/bt_bond_mgr.h
new file mode 100644
index 0000000..d6e7c74
--- /dev/null
+++ b/inc/bluetooth/leaudio/bt_bond_mgr.h
@@ -0,0 +1,51 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+*/
+
+#ifndef _BT_BOND_MGR_
+#define _BT_BOND_MGR_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef bool (*P_BT_BOND_CHECK)(uint8_t *bd_addr, uint8_t bd_type, uint16_t conn_handle);
+
+typedef bool (*P_BT_BOND_GET_KEY)(uint8_t *bd_addr, uint8_t bd_type, uint16_t conn_handle,
+ bool remote, uint8_t *p_key_len, uint8_t *p_key);
+
+typedef uint8_t (*P_BT_BOND_GET_MAX_NUM)(bool is_le);
+
+typedef bool (*P_BT_BOND_GET_ADDR)(bool is_le, uint8_t bond_idx, uint8_t *bd_addr,
+ uint8_t *p_bd_type, uint8_t *local_bd_addr,
+ uint8_t *p_local_bd_type);
+
+typedef bool (*P_BT_BOND_SET_CCCD_FLAG)(uint8_t *bd_addr, uint8_t bd_type, uint8_t *local_bd_addr,
+ uint8_t local_bd_type,
+ uint16_t cccd_handle, uint16_t flags);
+typedef bool (*P_BT_BOND_CLEAR_CCCD_FLAG)(uint8_t *bd_addr, uint8_t bd_type, uint16_t conn_handle,
+ uint16_t cccd_handle);
+
+typedef bool (*P_BT_BOND_LE_RESOLVE_RPA)(uint8_t *unresolved_addr, uint8_t *identity_addr,
+ uint8_t *p_identity_addr_type);
+
+typedef struct
+{
+ P_BT_BOND_CHECK bond_check;
+ P_BT_BOND_GET_KEY bond_get_key;
+ P_BT_BOND_GET_MAX_NUM bond_get_max_num;
+ P_BT_BOND_GET_ADDR bond_get_addr;
+ P_BT_BOND_SET_CCCD_FLAG bond_set_cccd_flag;
+ P_BT_BOND_CLEAR_CCCD_FLAG bond_clear_cccd_flag;
+ P_BT_BOND_LE_RESOLVE_RPA bond_le_resolve_rpa;
+} T_BT_BOND_MGR;
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/inc/bluetooth/leaudio/bt_gatt_client.h b/inc/bluetooth/leaudio/bt_gatt_client.h
new file mode 100644
index 0000000..fee3389
--- /dev/null
+++ b/inc/bluetooth/leaudio/bt_gatt_client.h
@@ -0,0 +1,192 @@
+#ifndef _BT_GATT_CLIENT_H_
+#define _BT_GATT_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "gap.h"
+#include "profile_client.h"
+#include "gap_conn_le.h"
+
+
+typedef enum
+{
+ GATTC_STORAGE_STATE_IDLE = 0x00,
+ GATTC_STORAGE_STATE_DISCOVERY = 0x01,
+ GATTC_STORAGE_STATE_DONE = 0x02,
+ GATTC_STORAGE_STATE_FAILED = 0x03,
+} T_GATTC_STORAGE_STATE;
+
+#define GATT_CLT_CONFIG_DISABLE 0x00
+#define GATT_CLT_CONFIG_NOTIFICATION 0x01
+#define GATT_CLT_CONFIG_INDICATION 0x02
+#define GATT_CLT_CONFIG_ALL 0x03
+#define ATTR_INSTANCE_NUM_MAX 20
+
+typedef enum
+{
+ GATT_STORAGE_EVENT_SRV_TBL_GET_IND = 0x01,
+ GATT_STORAGE_EVENT_SRV_TBL_SET_IND = 0x02,
+} T_GATT_STORAGE_EVENT;
+
+typedef enum
+{
+ GATT_DISCOV_MODE_CLOSED = 0x00,
+ GATT_DISCOV_MODE_REG_SRV = 0x01,
+ GATT_DISCOV_MODE_ALL = 0x02,
+} T_GATT_DISCOV_MODE;
+
+//GATT_STORAGE_EVENT_SRV_TBL_GET_IND
+typedef struct
+{
+ uint8_t addr[6];
+ uint8_t remote_bd_type;
+ uint16_t data_len;
+ uint8_t *p_data;
+} T_GATT_STORAGE_SRV_TBL_GET_IND;
+
+//GATT_STORAGE_EVENT_SRV_TBL_SET_IND
+typedef struct
+{
+ uint8_t addr[6];
+ uint8_t remote_bd_type;
+ uint16_t data_len;
+ uint8_t *p_data;
+} T_GATT_STORAGE_SRV_TBL_SET_IND;
+
+typedef enum
+{
+ GATT_CLIENT_EVENT_DIS_DONE = 0x01,
+ GATT_CLIENT_EVENT_READ_RESULT = 0x02,
+ GATT_CLIENT_EVENT_WRITE_RESULT = 0x03,
+ GATT_CLIENT_EVENT_NOTIFY_IND = 0x04,
+ GATT_CLIENT_EVENT_CCCD_CFG = 0x05,
+ GATT_CLIENT_EVENT_DIS_ALL_STATE = 0x06,
+ GATT_CLIENT_EVENT_CONN_DEL = 0x07,
+} T_GATT_CLIENT_EVENT;
+
+typedef struct
+{
+ bool is_uuid16;
+ uint8_t instance_id;
+ union
+ {
+ uint16_t uuid16;
+ uint8_t uuid128[16];
+ } p;
+} T_ATTR_UUID;
+
+typedef struct
+{
+ T_GATTC_STORAGE_STATE state;
+ bool load_form_ftl;
+} T_GATT_CLIENT_DIS_ALL_DONE;
+
+typedef struct
+{
+ bool is_found;
+ bool load_form_ftl;
+ uint8_t srv_instance_num;
+} T_GATT_CLIENT_DIS_DONE;
+
+typedef struct
+{
+ bool is_cccd_desc;
+ uint8_t srv_instance_id;
+ T_ATTR_UUID char_uuid;
+ uint16_t cause;
+ uint16_t handle;
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_GATT_CLIENT_READ_RESULT;
+
+typedef struct
+{
+ bool is_cccd_desc;
+ uint8_t srv_instance_id;
+ T_ATTR_UUID char_uuid;
+ uint16_t cause;
+ T_GATT_WRITE_TYPE type;
+ uint16_t handle;
+} T_GATT_CLIENT_WRITE_RESULT;
+
+typedef struct
+{
+ uint8_t srv_instance_id;
+ T_ATTR_UUID char_uuid;
+ bool notify;
+ uint16_t handle;
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_GATT_CLIENT_NOTIFY_IND;
+
+typedef struct
+{
+ bool srv_cfg;
+ uint8_t srv_instance_id;
+ uint16_t cccd_data;
+ uint16_t cause;
+ T_ATTR_UUID uuid;
+} T_GATT_CLIENT_CCCD_CFG;
+
+typedef union
+{
+ T_GATT_CLIENT_DIS_DONE dis_done;
+ T_GATT_CLIENT_READ_RESULT read_result;
+ T_GATT_CLIENT_WRITE_RESULT write_result;
+ T_GATT_CLIENT_NOTIFY_IND notify_ind;
+ T_GATT_CLIENT_CCCD_CFG cccd_cfg;
+} T_GATT_CLIENT_DATA;
+
+typedef union
+{
+ T_GATT_CLIENT_DATA *p_gatt_data;
+} T_GATTC_DATA;
+
+typedef struct
+{
+ uint8_t instance_num;
+ uint8_t instance_id[ATTR_INSTANCE_NUM_MAX];
+} T_ATTR_INSTANCE;
+
+typedef T_APP_RESULT(*P_FUN_GATT_CLIENT_CB)(uint16_t conn_handle, T_GATT_CLIENT_EVENT type,
+ void *p_data);
+typedef T_APP_RESULT(*P_FUN_GATT_STORAGE_CB)(T_GATT_STORAGE_EVENT type, void *p_data);
+
+T_GAP_CAUSE gatt_client_start_discovery_all(uint16_t conn_handle, P_FUN_GATT_CLIENT_CB p_dis_cb);
+T_GAP_CAUSE gatt_client_enable_srv_cccd(uint16_t conn_handle, T_ATTR_UUID *p_srv_uuid,
+ uint8_t cccd_cfg);
+T_GAP_CAUSE gatt_client_enable_char_cccd(uint16_t conn_handle, T_ATTR_UUID *p_srv_uuid,
+ uint16_t char_uuid16, uint8_t cccd_cfg);
+T_GAP_CAUSE gatt_client_enable_uuid128_char_cccd(uint16_t conn_handle, T_ATTR_UUID *p_srv_uuid,
+ uint8_t *p_uuid128, uint8_t cccd_cfg);
+T_GAP_CAUSE gatt_client_read(uint16_t conn_handle, uint16_t handle, P_FUN_GATT_CLIENT_CB p_req_cb);
+T_GAP_CAUSE gatt_client_read_uuid(uint16_t conn_handle, uint16_t start_handle,
+ uint16_t end_handle, uint16_t uuid16, P_FUN_GATT_CLIENT_CB p_req_cb);
+T_GAP_CAUSE gatt_client_write(uint16_t conn_handle, T_GATT_WRITE_TYPE write_type,
+ uint16_t handle, uint16_t length, uint8_t *p_data, P_FUN_GATT_CLIENT_CB p_req_cb);
+
+T_GAP_CAUSE gatt_spec_client_register(T_ATTR_UUID *p_srv_uuid, P_FUN_GATT_CLIENT_CB p_fun_cb);
+
+//find info about service
+bool gatt_client_find_char_handle(uint16_t conn_handle, T_ATTR_UUID *p_srv_uuid,
+ T_ATTR_UUID *p_char_uuid, uint16_t *p_handle);
+bool gatt_client_find_primary_srv_by_include(uint16_t conn_handle, T_ATTR_UUID *p_included_srv,
+ T_ATTR_UUID *p_primary_srv);
+bool gatt_client_find_include_srv_by_primary(uint16_t conn_handle, T_ATTR_UUID *p_primary_srv,
+ T_ATTR_UUID *p_included_srv,
+ T_ATTR_INSTANCE *p_attr_instance);
+uint8_t gatt_client_get_char_num(uint16_t conn_handle, T_ATTR_UUID *p_srv_uuid,
+ T_ATTR_UUID *p_char_uuid);
+bool gatt_client_get_char_prop(uint16_t conn_handle, T_ATTR_UUID *p_srv_uuid,
+ T_ATTR_UUID *p_char_uuid, uint16_t *p_properties);
+
+bool gatt_client_init(T_GATT_DISCOV_MODE mode);
+bool gatt_storage_register(P_FUN_GATT_STORAGE_CB p_fun_cb);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/cap.h b/inc/bluetooth/leaudio/cap.h
new file mode 100644
index 0000000..ec21059
--- /dev/null
+++ b/inc/bluetooth/leaudio/cap.h
@@ -0,0 +1,86 @@
+#ifndef _CAP_H_
+#define _CAP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "ble_audio_group.h"
+#include "csis_def.h"
+
+#if LE_AUDIO_CAP_SUPPORT
+#define CAP_ACCEPTOR_ROLE 0x01
+#define CAP_INITIATOR_ROLE 0x02
+#define CAP_CAMMANDER_ROLE 0x04
+
+#define GATT_UUID_CAS 0x1853
+
+typedef struct
+{
+ uint8_t default_volume_settings;
+ uint8_t default_mute;
+ uint8_t default_mic_mute;
+} T_CAP_DEFAULT_PARAM;
+
+typedef struct
+{
+ uint8_t cap_role;
+ bool cas_client;
+ bool csip_set_coordinator;
+ uint8_t csis_num;
+ struct
+ {
+ bool enable;
+ T_CSIS_SIRK_TYPE csis_sirk_type;
+ uint8_t csis_size;
+ uint8_t csis_rank;
+ uint8_t csis_feature;
+ uint8_t *csis_sirk;
+ } cas;
+ struct
+ {
+ bool vcp_volume_controller;
+ bool micp_mic_controller;
+ uint8_t default_volume_settings;
+ uint8_t default_mute;
+ uint8_t default_mic_mute;
+ } vcp_micp;
+
+ bool ccp_call_control_client;
+ struct
+ {
+ bool ccp_call_control_server;
+ uint8_t tbs_num;
+ } tbs;
+ bool mcp_media_control_client;
+ struct
+ {
+ bool mcp_media_control_server;
+ uint8_t mcs_num;
+ uint8_t ots_num;
+ } mcs;
+} T_CAP_INIT_PARAMS;
+
+typedef struct
+{
+ uint16_t conn_handle;
+ bool is_found;
+ bool load_form_ftl;
+ uint8_t srv_num;
+} T_CAP_DIS_DONE;
+
+bool cap_change_volume_by_address(uint8_t *bd_addr, uint8_t addr_type, uint8_t volume_setting);
+bool cap_change_volume(T_BLE_AUDIO_GROUP_HANDLE group_handle, uint8_t volume_setting);
+bool cap_change_mute_by_address(uint8_t *bd_addr, uint8_t addr_type, uint8_t mute);
+bool cap_change_mute(T_BLE_AUDIO_GROUP_HANDLE group_handle, uint8_t mute);
+bool cap_change_mic_mute_by_address(uint8_t *bd_addr, uint8_t addr_type, uint8_t mute);
+bool cap_change_input_gain_by_address(uint8_t *bd_addr, uint8_t addr_type, int8_t gain);
+bool cap_init(T_CAP_INIT_PARAMS *p_param);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/codec_def.h b/inc/bluetooth/leaudio/codec_def.h
new file mode 100644
index 0000000..73c052d
--- /dev/null
+++ b/inc/bluetooth/leaudio/codec_def.h
@@ -0,0 +1,122 @@
+#ifndef _CODEC_DEF_H_
+#define _CODEC_DEF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define TRANSPARENT_CODEC_ID 0x03
+#define LC3_CODEC_ID 0x06
+#define VENDOR_CODEC_ID 0xFF
+#define CODEC_ID_LEN 5
+
+/* Codec_Specific_Capabilities parameters*/
+//Codec Specific Capability Types
+#define CODEC_CAP_TYPE_SUPPORTED_SAMPLING_FREQUENCIES 0x01
+#define CODEC_CAP_TYPE_SUPPORTED_FRAME_DURATIONS 0x02
+#define CODEC_CAP_TYPE_AUDIO_CHANNEL_COUNTS 0x03
+/*4 octets.
+Octet 0-1: Minimum number of octets supported per codec frame
+Octet 2-3: Maximum number of octets supported per codec frame*/
+#define CODEC_CAP_TYPE_SUPPORTED_OCTETS_PER_CODEC_FRAME 0x04
+#define CODEC_CAP_TYPE_MAX_SUPPORTED_FRAMES_PER_SDU 0x05
+
+#define SAMPLING_FREQUENCY_8K 0x0001
+#define SAMPLING_FREQUENCY_11K 0x0002
+#define SAMPLING_FREQUENCY_16K 0x0004
+#define SAMPLING_FREQUENCY_22K 0x0008
+#define SAMPLING_FREQUENCY_24K 0x0010
+#define SAMPLING_FREQUENCY_32K 0x0020
+#define SAMPLING_FREQUENCY_44_1K 0x0040
+#define SAMPLING_FREQUENCY_48K 0x0080
+#define SAMPLING_FREQUENCY_88K 0x0100
+#define SAMPLING_FREQUENCY_96K 0x0200
+#define SAMPLING_FREQUENCY_176K 0x0400
+#define SAMPLING_FREQUENCY_192K 0x0800
+#define SAMPLING_FREQUENCY_384K 0x1000
+#define SAMPLING_FREQUENCY_MASK 0x1FFF
+
+#define FRAME_DURATION_7_5_MS_BIT 0x01
+#define FRAME_DURATION_10_MS_BIT 0x02
+#define FRAME_DURATION_PREFER_7_5_MS_BIT 0x10
+#define FRAME_DURATION_PREFER_10_MS_BIT 0x20
+
+#define AUDIO_CHANNEL_COUNTS_1 0x01
+#define AUDIO_CHANNEL_COUNTS_2 0x02
+#define AUDIO_CHANNEL_COUNTS_3 0x04
+#define AUDIO_CHANNEL_COUNTS_4 0x08
+#define AUDIO_CHANNEL_COUNTS_5 0x10
+#define AUDIO_CHANNEL_COUNTS_6 0x20
+#define AUDIO_CHANNEL_COUNTS_7 0x40
+#define AUDIO_CHANNEL_COUNTS_8 0x80
+
+//Config Codec operation
+#define CODEC_CFG_TYPE_SAMPLING_FREQUENCY 0x01
+#define CODEC_CFG_TYPE_FRAME_DURATION 0x02
+#define CODEC_CFG_TYPE_AUDIO_CHANNEL_ALLOCATION 0x03
+#define CODEC_CFG_TYPE_OCTET_PER_CODEC_FRAME 0x04
+#define CODEC_CFG_TYPE_BLOCKS_PER_SDU 0x05
+
+#define SAMPLING_FREQUENCY_CFG_8K 0x01
+#define SAMPLING_FREQUENCY_CFG_11K 0x02
+#define SAMPLING_FREQUENCY_CFG_16K 0x03
+#define SAMPLING_FREQUENCY_CFG_22K 0x04
+#define SAMPLING_FREQUENCY_CFG_24K 0x05
+#define SAMPLING_FREQUENCY_CFG_32K 0x06
+#define SAMPLING_FREQUENCY_CFG_44_1K 0x07
+#define SAMPLING_FREQUENCY_CFG_48K 0x08
+#define SAMPLING_FREQUENCY_CFG_88K 0x09
+#define SAMPLING_FREQUENCY_CFG_96K 0x0A
+#define SAMPLING_FREQUENCY_CFG_176K 0x0B
+#define SAMPLING_FREQUENCY_CFG_192K 0x0C
+#define SAMPLING_FREQUENCY_CFG_384K 0x0D
+
+#define FRAME_DURATION_CFG_7_5_MS 0x00
+#define FRAME_DURATION_CFG_10_MS 0x01
+
+
+
+#define CODEC_CAP_SUPPORTED_SAMPLING_FREQUENCIES_EXIST 0x0001
+#define CODEC_CAP_SUPPORTED_FRAME_DURATIONS_EXIST 0x0002
+#define CODEC_CAP_AUDIO_CHANNEL_COUNTS_EXIST 0x0004
+#define CODEC_CAP_SUPPORTED_OCTETS_PER_CODEC_FRAME_EXIST 0x0008
+#define CODEC_CAP_MAX_SUPPORTED_FRAMES_PER_SDU_EXIST 0x0010
+
+#define CODEC_CFG_SAMPLING_FREQUENCY_EXIST 0x0001
+#define CODEC_CFG_FRAME_DURATION_EXIST 0x0002
+#define CODEC_CFG_AUDIO_CHANNEL_ALLOCATION_EXIST 0x0004
+#define CODEC_CFG_OCTET_PER_CODEC_FRAME_EXIST 0x0008
+#define CODEC_CFG_TYPE_BLOCKS_PER_SDU_EXIST 0x0010
+
+typedef struct
+{
+ uint16_t type_exist;
+ uint16_t supported_sampling_frequencies;
+ uint8_t supported_frame_durations;
+ uint8_t audio_channel_counts;
+ uint8_t max_supported_codec_frames_per_sdu;
+ uint16_t min_octets_per_codec_frame;
+ uint16_t max_octets_per_codec_frame;
+} T_CODEC_CAP;
+
+typedef struct
+{
+ uint16_t type_exist;
+ uint8_t frame_duration;
+ uint8_t sample_frequency;
+ uint8_t codec_frame_blocks_per_sdu;
+ uint16_t octets_per_codec_frame;
+ uint32_t audio_channel_allocation;
+ uint32_t presentation_delay;
+} T_CODEC_CFG;
+
+uint8_t count_bits_1(uint32_t value);
+bool codec_cap_parse(uint8_t len, uint8_t *p_data, T_CODEC_CAP *p_cap);
+bool codec_cfg_parse(uint8_t len, uint8_t *p_data, T_CODEC_CFG *p_cfg);
+bool codec_cfg_gen(uint8_t *p_len, uint8_t *p_data, T_CODEC_CFG *p_cfg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/codec_qos.h b/inc/bluetooth/leaudio/codec_qos.h
new file mode 100644
index 0000000..82ea6dc
--- /dev/null
+++ b/inc/bluetooth/leaudio/codec_qos.h
@@ -0,0 +1,101 @@
+#ifndef _CODEC_QOS_H_
+#define _CODEC_QOS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "ble_audio_def.h"
+#include "codec_def.h"
+
+typedef enum
+{
+ CODEC_CFG_ITEM_8_1 = 0,
+ CODEC_CFG_ITEM_8_2 = 1,
+ CODEC_CFG_ITEM_16_1 = 2,
+ CODEC_CFG_ITEM_16_2 = 3,
+ CODEC_CFG_ITEM_24_1 = 4,
+ CODEC_CFG_ITEM_24_2 = 5,
+ CODEC_CFG_ITEM_32_1 = 6,
+ CODEC_CFG_ITEM_32_2 = 7,
+ CODEC_CFG_ITEM_441_1 = 8,
+ CODEC_CFG_ITEM_441_2 = 9,
+ CODEC_CFG_ITEM_48_1 = 10,
+ CODEC_CFG_ITEM_48_2 = 11,
+ CODEC_CFG_ITEM_48_3 = 12,
+ CODEC_CFG_ITEM_48_4 = 13,
+ CODEC_CFG_ITEM_48_5 = 14,
+ CODEC_CFG_ITEM_48_6 = 15,
+ CODEC_CFG_ITEM_LC3_MAX,
+
+ CODEC_CFG_ITEM_VENDOR = 0xff,
+} T_CODEC_CFG_ITEM;
+
+
+#define CODEC_CFG_ITEM_8_1_BIT (1 << CODEC_CFG_ITEM_8_1)
+#define CODEC_CFG_ITEM_8_2_BIT (1 << CODEC_CFG_ITEM_8_2)
+#define CODEC_CFG_ITEM_16_1_BIT (1 << CODEC_CFG_ITEM_16_1)
+#define CODEC_CFG_ITEM_16_2_BIT (1 << CODEC_CFG_ITEM_16_2)
+#define CODEC_CFG_ITEM_24_1_BIT (1 << CODEC_CFG_ITEM_24_1)
+#define CODEC_CFG_ITEM_24_2_BIT (1 << CODEC_CFG_ITEM_24_2)
+#define CODEC_CFG_ITEM_32_1_BIT (1 << CODEC_CFG_ITEM_32_1)
+#define CODEC_CFG_ITEM_32_2_BIT (1 << CODEC_CFG_ITEM_32_2)
+#define CODEC_CFG_ITEM_441_1_BIT (1 << CODEC_CFG_ITEM_441_1)
+#define CODEC_CFG_ITEM_441_2_BIT (1 << CODEC_CFG_ITEM_441_2)
+#define CODEC_CFG_ITEM_48_1_BIT (1 << CODEC_CFG_ITEM_48_1)
+#define CODEC_CFG_ITEM_48_2_BIT (1 << CODEC_CFG_ITEM_48_2)
+#define CODEC_CFG_ITEM_48_3_BIT (1 << CODEC_CFG_ITEM_48_3)
+#define CODEC_CFG_ITEM_48_4_BIT (1 << CODEC_CFG_ITEM_48_4)
+#define CODEC_CFG_ITEM_48_5_BIT (1 << CODEC_CFG_ITEM_48_5)
+#define CODEC_CFG_ITEM_48_6_BIT (1 << CODEC_CFG_ITEM_48_6)
+
+#define SAMPLE_FREQ_8K_TABLE_MASK (CODEC_CFG_ITEM_8_1_BIT|CODEC_CFG_ITEM_8_2_BIT)
+#define SAMPLE_FREQ_16K_TABLE_MASK (CODEC_CFG_ITEM_16_1_BIT|CODEC_CFG_ITEM_16_2_BIT)
+#define SAMPLE_FREQ_24K_TABLE_MASK (CODEC_CFG_ITEM_24_1_BIT|CODEC_CFG_ITEM_24_2_BIT)
+#define SAMPLE_FREQ_32K_TABLE_MASK (CODEC_CFG_ITEM_32_1_BIT|CODEC_CFG_ITEM_32_2_BIT)
+#define SAMPLE_FREQ_441K_TABLE_MASK (CODEC_CFG_ITEM_441_1_BIT|CODEC_CFG_ITEM_441_2_BIT)
+#define SAMPLE_FREQ_48K_TABLE_MASK (CODEC_CFG_ITEM_48_1_BIT|CODEC_CFG_ITEM_48_2_BIT| \
+ CODEC_CFG_ITEM_48_3_BIT|CODEC_CFG_ITEM_48_4_BIT| \
+ CODEC_CFG_ITEM_48_5_BIT|CODEC_CFG_ITEM_48_6_BIT)
+
+#define FREAM_DUIATION_7_5M_TALBLE_MASK (CODEC_CFG_ITEM_8_1_BIT|CODEC_CFG_ITEM_16_1_BIT| \
+ CODEC_CFG_ITEM_24_1_BIT|CODEC_CFG_ITEM_32_1_BIT| \
+ CODEC_CFG_ITEM_441_1_BIT|CODEC_CFG_ITEM_48_1_BIT| \
+ CODEC_CFG_ITEM_48_3_BIT|CODEC_CFG_ITEM_48_5_BIT)
+#define FREAM_DUIATION_10M_TALBLE_MASK (CODEC_CFG_ITEM_8_2_BIT|CODEC_CFG_ITEM_16_2_BIT| \
+ CODEC_CFG_ITEM_24_2_BIT|CODEC_CFG_ITEM_32_2_BIT| \
+ CODEC_CFG_ITEM_441_2_BIT|CODEC_CFG_ITEM_48_2_BIT| \
+ CODEC_CFG_ITEM_48_4_BIT|CODEC_CFG_ITEM_48_6_BIT)
+
+typedef enum
+{
+ QOS_CFG_CIS_LOW_LATENCY,
+ QOS_CFG_CIS_HIG_RELIABILITY,
+ QOS_CFG_BIS_LOW_LATENCY,
+ QOS_CFG_BIS_HIG_RELIABILITY,
+} T_QOS_CFG_TYPE;
+
+typedef struct
+{
+ uint32_t sdu_interval;
+ uint8_t framing;
+ uint16_t max_sdu;
+ uint8_t retransmission_number;
+ uint16_t max_transport_latency;
+ uint32_t presentation_delay;
+} T_QOS_CFG_PREFERRED;
+
+bool codec_preferred_cfg_get(T_CODEC_CFG_ITEM item, T_CODEC_CFG *p_cfg);
+bool qos_preferred_cfg_get(T_CODEC_CFG_ITEM item, T_QOS_CFG_TYPE type, T_QOS_CFG_PREFERRED *p_qos);
+bool qos_cfg_find_by_codec_cfg(T_CODEC_CFG *p_cfg, uint8_t target_latency,
+ T_QOS_CFG_PREFERRED *p_qos);
+bool get_max_sdu_len_by_codec_cfg(T_CODEC_CFG *p_cfg, uint16_t *p_max_len);
+bool get_sdu_interval_by_codec_cfg(T_CODEC_CFG *p_cfg, uint32_t *p_sdu_int);
+bool codec_cap_get_cfg_bits(uint32_t *p_cfg_bits, T_CODEC_CAP *p_cap);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/csis_def.h b/inc/bluetooth/leaudio/csis_def.h
new file mode 100644
index 0000000..7752e7b
--- /dev/null
+++ b/inc/bluetooth/leaudio/csis_def.h
@@ -0,0 +1,49 @@
+#ifndef _CSIS_DEF_H_
+#define _CSIS_DEF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define SET_MEMBER_LOCK_EXIST 0x01
+#define SET_MEMBER_SIZE_EXIST 0x02
+#define SET_MEMBER_RANK_EXIST 0x04
+#define SET_MEMBER_SIRK_NOTIFY_SUPPORT 0x10
+#define SET_MEMBER_SIZE_NOTIFY_SUPPORT 0x20
+
+#define ATT_ERR_CSIS_LOCK_DENIED 0x80
+#define ATT_ERR_CSIS_LOCK_RELEASE_NOT_ALLOWED 0x81
+#define ATT_ERR_CSIS_INVALID_LOCK_VALUE 0x82
+#define ATT_ERR_CSIS_OOB_SIRK_ONLY 0x83
+#define ATT_ERR_CSIS_LOCK_ALREADY_GRANTED 0x84
+
+//coordinated set identification service
+#define GATT_UUID_CSIS 0x1846
+
+#define CSIS_UUID_CHAR_SET_IRK 0x2B84
+#define CSIS_UUID_CHAR_SIZE 0x2B85
+#define CSIS_UUID_CHAR_LOCK 0x2B86
+#define CSIS_UUID_CHAR_RANK 0x2B87
+
+#define CSI_SIRK_LEN 16
+
+#define CSI_LOCK_DEFAULT_TIMEOUT 60000
+#define CSIP_DISCOVERY_TIMEOUT 10000
+typedef enum
+{
+ CSIS_NONE_LOCK = 0,
+ CSIS_UNLOCKED = 0x01,
+ CSIS_LOCKED = 0x02,
+} T_CSIS_LOCK;
+
+typedef enum
+{
+ CSIS_SIRK_ENC = 0x00,
+ CSIS_SIRK_PLN = 0x01,
+} T_CSIS_SIRK_TYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/csis_rsi.h b/inc/bluetooth/leaudio/csis_rsi.h
new file mode 100644
index 0000000..dd131fb
--- /dev/null
+++ b/inc/bluetooth/leaudio/csis_rsi.h
@@ -0,0 +1,24 @@
+#ifndef _CSIS_RSI_H_
+#define _CSIS_RSI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#define GAP_ADTYPE_RSI 0x2E
+
+#define CSI_RSI_LEN 6
+
+#if (LE_AUDIO_CSIS_CLIENT_SUPPORT|LE_AUDIO_CSIS_SUPPORT)
+bool csis_gen_rsi(const uint8_t *p_sirk, uint8_t *p_rsik);
+bool csis_resolve_rsi(const uint8_t *p_sirk, uint8_t *p_rsik);
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/metadata_def.h b/inc/bluetooth/leaudio/metadata_def.h
new file mode 100644
index 0000000..673b3aa
--- /dev/null
+++ b/inc/bluetooth/leaudio/metadata_def.h
@@ -0,0 +1,54 @@
+#ifndef _METADATA_DEF_H_
+#define _METADATA_DEF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*The Preferred_Audio_Contexts LTV structure is typically included
+in the Metadata field of PAC records exposed by Unicast Servers and Broadcast Sinks. */
+#define METADATA_TYPE_PREFERRED_AUDIO_CONTEXTS 0x01
+
+/*The Streaming_Audio_Contexts LTV structure is typically included in a Metadata parameter value
+when initiating the Enable or Update Metadata ASE Control operations for unicast Audio Streams,
+or in the Metadata parameter value included in a BASE structure for broadcast Audio Streams.*/
+#define METADATA_TYPE_STREAMING_AUDIO_CONTEXTS 0x02
+/*Title and/or summary of Audio Stream content: UTF-8 format. */
+#define METADATA_TYPE_PROGRAM_INFO 0x03
+/*3-byte, lower case language code as defined in ISO 639-3. */
+#define METADATA_TYPE_LANGUAGE 0x04
+/*Array of CCID values. */
+#define METADATA_TYPE_CCCD_LIST 0x05
+/*Parental_Rating. */
+#define METADATA_TYPE_PARENTAL_RATING 0x06
+/*A UTF-8 formatted URL link used to present more information about Program_Info. */
+#define METADATA_TYPE_PROGRAM_INFO_URI 0x07
+/*Extended Metadata. */
+#define METADATA_TYPE_EXTENDED 0xFE
+/*Vendor_Specific. */
+#define METADATA_TYPE_VENDOR_SPECIFIC 0xFF
+
+
+//BAPS_Assigned_Numbers_v7, different with IOP
+#define AUDIO_CONTEXT_UNSPECIFIED 0x0001
+#define AUDIO_CONTEXT_CONVERSATIONAL 0x0002
+#define AUDIO_CONTEXT_MEDIA 0x0004
+#define AUDIO_CONTEXT_GAME 0x0008
+#define AUDIO_CONTEXT_INSTRUCTIONAL 0x0010
+#define AUDIO_CONTEXT_VOICE_ASSISTANTS 0x0020
+#define AUDIO_CONTEXT_LIVE 0x0040
+#define AUDIO_CONTEXT_SOUND_EFFECTS 0x0080
+#define AUDIO_CONTEXT_NOTIFICATIONS 0x0100
+#define AUDIO_CONTEXT_RINGTONE 0x0200
+#define AUDIO_CONTEXT_ALERTS 0x0400
+#define AUDIO_CONTEXT_EMERGENCY_ALERT 0x0800
+#define AUDIO_CONTEXT_MASK 0x0FFF
+
+#define MCS_CCID_PRE_IDX 0x80
+#define TBS_CCID_PRE_IDX 0x40
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/pacs_client.h b/inc/bluetooth/leaudio/pacs_client.h
new file mode 100644
index 0000000..4d829fd
--- /dev/null
+++ b/inc/bluetooth/leaudio/pacs_client.h
@@ -0,0 +1,102 @@
+#ifndef _PACS_CLIENT_H_
+#define _PACS_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef enum
+{
+ PACS_OP_SINK,
+ PACS_OP_SOURCE,
+ PACS_OP_ALL
+} T_PACS_CCCD_OP_TYPE;
+
+typedef enum
+{
+ PACS_AUDIO_AVAILABLE_CONTEXTS,
+ PACS_AUDIO_SUPPORTED_CONTEXTS,
+ PACS_SINK_AUDIO_LOC,
+ PACS_SINK_PAC,
+ PACS_SOURCE_AUDIO_LOC,
+ PACS_SOURCE_PAC,
+} T_PACS_TYPE;
+
+//LE_AUDIO_MSG_PACS_CLIENT_DIS_DONE
+typedef struct
+{
+ uint16_t conn_handle;
+ bool is_found;
+ bool load_form_ftl;
+ uint8_t sink_pac_num;
+ uint8_t source_pac_num;
+ bool sink_loc_writable;
+ bool sink_loc_exist;
+ bool source_loc_writable;
+ bool source_loc_exist;
+} T_PACS_CLIENT_DIS_DONE;
+
+//LE_AUDIO_MSG_PACS_CLIENT_CCCD
+typedef struct
+{
+ uint16_t conn_handle;
+ T_PACS_CCCD_OP_TYPE type;
+ uint16_t cause;
+} T_PACS_CLIENT_CCCD;
+
+//LE_AUDIO_MSG_PACS_CLIENT_WRITE_SINK_LOC_RESULT
+//LE_AUDIO_MSG_PACS_CLIENT_WRITE_SOURCE_LOC_RESULT
+typedef struct
+{
+ uint16_t conn_handle;
+ uint16_t cause;
+} T_PACS_CLIENT_WRITE_RESULT;
+
+typedef struct
+{
+ bool is_complete;
+ uint16_t handle;
+ uint16_t pac_record_len;
+ uint8_t *p_record;
+} T_PAC_CHAR_DATA;
+
+typedef struct
+{
+ uint16_t sink_contexts;
+ uint16_t source_contexts;
+} T_AUDIO_CONTEXTS_DATA;
+
+typedef union
+{
+ T_AUDIO_CONTEXTS_DATA contexts_data;
+ uint32_t audio_locations;
+ T_PAC_CHAR_DATA pac_data;
+} T_PACS_DATA;
+
+//LE_AUDIO_MSG_PACS_CLIENT_READ_RESULT
+typedef struct
+{
+ uint16_t conn_handle;
+ T_PACS_TYPE type;
+ uint16_t cause;
+ T_PACS_DATA data;
+} T_PACS_CLIENT_READ_RESULT;
+
+//LE_AUDIO_MSG_PACS_CLIENT_NOTIFY
+typedef struct
+{
+ uint16_t conn_handle;
+ T_PACS_TYPE type;
+ T_PACS_DATA data;
+} T_PACS_CLIENT_NOTIFY;
+
+bool pacs_read_char_value(uint16_t conn_handle, T_PACS_TYPE type);
+bool pacs_enable_cccd(uint16_t conn_handle, T_PACS_CCCD_OP_TYPE type);
+bool pacs_write_sink_audio_locations(uint16_t conn_handle, uint32_t sink_audio_location);
+bool pacs_write_source_audio_locations(uint16_t conn_handle, uint32_t source_audio_location);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/leaudio/set_coordinator_client.h b/inc/bluetooth/leaudio/set_coordinator_client.h
new file mode 100644
index 0000000..a7124bc
--- /dev/null
+++ b/inc/bluetooth/leaudio/set_coordinator_client.h
@@ -0,0 +1,132 @@
+#ifndef _SET_COORDINATOR_TEST_H_
+#define _SET_COORDINATOR_TEST_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#if LE_AUDIO_CSIS_CLIENT_SUPPORT
+#include "csis_rsi.h"
+#include "csis_def.h"
+#include "ble_audio_group.h"
+#include "os_queue.h"
+
+#define CSIS_SIZE_UNKNOWN 0
+
+#define CSIS_LOCK_FLAG 0x01
+#define CSIS_SIRK_FLAG 0x02
+#define CSIS_SIZE_FLAG 0x04
+#define CSIS_RANK_FLAG 0x08
+
+typedef struct
+{
+ uint16_t conn_handle;
+ bool is_found;
+ bool load_form_ftl;
+ uint8_t srv_num;
+} T_CSIS_CLIENT_DIS_DONE;
+
+typedef struct
+{
+ uint16_t conn_handle;
+ uint16_t cause;
+ T_BLE_AUDIO_GROUP_HANDLE group_handle;
+} T_CSIS_MEMBER_LOCK_REQ_DONE;
+
+typedef struct
+{
+ uint16_t conn_handle;
+ uint16_t cause;
+ T_BLE_AUDIO_GROUP_HANDLE group_handle;
+} T_CSIS_MEMBER_UNLOCK_REQ_DONE;
+
+typedef struct
+{
+ uint16_t conn_handle;
+ uint16_t srv_uuid;
+ uint8_t srv_instance_id;
+ T_BLE_AUDIO_GROUP_HANDLE group_handle;
+ uint8_t lock;
+} T_CSIS_MEMBER_LOCK_STATE;
+
+typedef struct
+{
+ T_BLE_AUDIO_GROUP_HANDLE group_handle;
+} T_CSIS_COOR_SET_DEL;
+
+typedef struct
+{
+ uint8_t set_size;
+ uint8_t size;
+ bool search_done;
+} T_CSIS_SEARCH_RESULT;
+
+typedef struct
+{
+ T_BLE_AUDIO_GROUP_HANDLE group_handle;
+ T_BLE_AUDIO_DEV_HANDLE dev_handle;
+ uint8_t bd_addr[6];
+ uint8_t addr_type;
+ uint16_t srv_uuid;
+ uint8_t rank;
+ uint8_t size;
+ uint8_t sirk[CSI_SIRK_LEN];
+} T_CSIS_SET_MEM_FOUND;
+
+typedef struct
+{
+ uint16_t cause;
+ uint16_t conn_handle;
+ T_BLE_AUDIO_GROUP_HANDLE group_handle;
+ T_BLE_AUDIO_DEV_HANDLE dev_handle;
+ uint8_t bd_addr[6];
+ uint8_t addr_type;
+ uint16_t srv_uuid;
+ uint8_t srv_instance_id;
+ uint8_t char_exit;
+ uint8_t rank;
+ uint8_t size;
+ uint8_t sirk[CSI_SIRK_LEN];
+} T_CSIS_READ_RESULT;
+
+//LE_AUDIO_MSG_CSIS_CLIENT_SIRK_CHANGE
+typedef struct
+{
+ T_BLE_AUDIO_GROUP_HANDLE group_handle;
+ uint8_t sirk[CSI_SIRK_LEN];
+} T_CSIS_SIRK_CHANGE;
+
+typedef struct
+{
+ uint16_t serv_uuid;
+ uint8_t srv_instance_id;
+ uint8_t dev_num;
+ uint8_t set_mem_size;
+ uint8_t sirk[CSI_SIRK_LEN];
+} T_CSIS_GROUP_INFO;
+
+void coordinator_read_csis_chars(uint16_t conn_handle, uint8_t instance_id);
+bool csis_client_parse_ext_adv(uint8_t report_data_len, uint8_t *p_report_data,
+ uint8_t *p_bd_addr, uint8_t addr_type);
+bool set_discover_members_state(T_BLE_AUDIO_GROUP_HANDLE group_handle);
+bool csis_client_get_info(T_BLE_AUDIO_GROUP_HANDLE group_handle, T_CSIS_GROUP_INFO *p_info);
+bool set_lock_of_coor_set(T_BLE_AUDIO_GROUP_HANDLE group_handle);
+bool set_unlock_of_coor_set(T_BLE_AUDIO_GROUP_HANDLE group_handle);
+T_BLE_AUDIO_GROUP_HANDLE coordinator_set_find_by_rsi(uint8_t *p_rsik);
+T_BLE_AUDIO_GROUP_HANDLE coordinator_set_find_by_sirk(uint8_t *p_sirk);
+T_BLE_AUDIO_GROUP_HANDLE coordinator_set_find_by_addr(uint8_t *bd_addr, uint8_t addr_type,
+ uint16_t serv_uuid);
+T_BLE_AUDIO_DEV_HANDLE set_member_find_by_conn_handle(T_BLE_AUDIO_GROUP_HANDLE group_handle,
+ uint16_t conn_handle);
+bool coordinator_or_member_find_by_addr(uint8_t *bd_addr, uint8_t addr_type, uint16_t serv_uuid,
+ T_BLE_AUDIO_GROUP_HANDLE *p_group_handle, T_BLE_AUDIO_DEV_HANDLE *p_dev_handle);
+bool set_member_info_find_by_dev_handle(T_BLE_AUDIO_DEV_HANDLE *p_dev_handle,
+ T_CSIS_SET_MEM_FOUND *set_mem_info);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/profile/client/ams_client.h b/inc/bluetooth/profile/client/ams_client.h
new file mode 100644
index 0000000..dc0ef40
--- /dev/null
+++ b/inc/bluetooth/profile/client/ams_client.h
@@ -0,0 +1,419 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ams_client.h
+ * @brief
+ * @details
+ * @author
+ * @date
+ * @version v1.0
+ * *************************************************************************************
+*/
+
+#ifndef _AMS_CLIENT_H_
+#define _AMS_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "profile_client.h"
+
+
+/** @defgroup AMS_CLIENT AMS Client
+* @brief AMS client
+* @{
+*/
+
+
+/** @addtogroup AMS_CLIENT_Exported_Macros AMS Client Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @brief Define links number. range: 0-4 */
+#define AMS_MAX_LINKS 4
+
+
+/** End of AMS_CLIENT_Exported_Macros
+* @}
+*/
+
+
+
+/** @defgroup AMS_CLIENT_Exported_Types AMS Client Exported Types
+ * @brief
+ * @{
+ */
+
+
+/** @brief AMS client remote command id*/
+typedef enum
+{
+ REMOTE_CMD_ID_PLAY = 0,
+ REMOTE_CMD_ID_PAUSE = 1,
+ REMOTE_CMD_ID_TOGGLE_PLAY_PAUSE = 2,
+ REMOTE_CMD_ID_NEXT_TRACK = 3,
+ REMOTE_CMD_ID_PREVIOUS_TRACK = 4,
+ REMOTE_CMD_ID_VOLUME_UP = 5,
+ REMOTE_CMD_ID_VOLUME_DOWN = 6,
+ REMOTE_CMD_ID_ADVANCE_REPEAT_MODE = 7,
+ REMOTE_CMD_ID_ADVANCE_SHUFFLE_MODE = 8,
+ REMOTE_CMD_ID_SKIP_FORWARD = 9,
+ REMOTE_CMD_ID_SKIP_BACKWARD = 10,
+ REMOTE_CMD_ID_LIKE_TRACK = 11,
+ REMOTE_CMD_ID_DISLIKE_TRACK = 12,
+ REMOTE_CMD_ID_BOOK_MARK_TRACK = 13,
+ REMOTE_CMD_ID_RESERVED = 255
+} T_AMS_REMOTE_CMD_ID;
+
+/** @brief AMS client entity id*/
+typedef enum
+{
+ ENTITY_ID_PLAYER = 0,
+ ENTITY_ID_QUEUE = 1,
+ ENTITY_ID_TRACK = 2,
+ ENTITY_ID_RESERVED = 255
+} T_AMS_ENTITY_ID;
+
+/** @brief AMS client entity player attribute id*/
+typedef enum
+{
+ PLAYER_ATTR_IDPLAYER_ATTR_ID_VOLUME_NAME = 0,
+ PLAYER_ATTR_ID_PLAYBACK_INFO = 1,
+ PLAYER_ATTR_ID_VOLUME = 2,
+ PLAYER_ATTR_ID_RESERVED = 255
+} T_AMS_ENTITY_PLAYER_ATTR_ID;
+
+/** @brief AMS client entity queue attribute id*/
+typedef enum
+{
+ QUEUE_ATTR_ID_INDEX = 0,
+ QUEUE_ATTR_ID_COUNT = 1,
+ QUEUE_ATTR_ID_SHUFFLE_MODE = 2,
+ QUEUE_ATTR_ID_REPEAT_MODE = 3,
+ QUEUE_ATTR_ID_RESERVED = 255
+} T_AMS_ENTITY_QUEUE_ATTR_ID;
+
+/** @brief AMS client entity track attribute id*/
+typedef enum
+{
+ TRACK_ATTR_ID_ARTIST = 0,
+ TRACK_ATTR_ID_ALBUM = 1,
+ TRACK_ATTR_ID_TITLE = 2,
+ TRACK_ATTR_ID_DURATION = 3,
+ TRACK_ATTR_ID_RESERVED = 255
+} T_AMS_ENTITY_TRACK_ATTR_ID;
+
+/** @brief AMS client entity attribute id*/
+typedef union
+{
+ T_AMS_ENTITY_PLAYER_ATTR_ID player_atrr_id;
+ T_AMS_ENTITY_QUEUE_ATTR_ID queue_attr_id;
+ T_AMS_ENTITY_TRACK_ATTR_ID track_attr_id;
+} T_AMS_ENTITY_ATTR_ID;
+
+/** @brief AMS client entity attribute*/
+typedef struct
+{
+ T_AMS_ENTITY_ID entity_id;
+ T_AMS_ENTITY_ATTR_ID attr_id;
+} T_AMS_ENTITY_ATTR;
+
+
+/** @brief AMS client handle type*/
+typedef enum
+{
+ AMS_HDL_SRV_START, //!< service start handle
+ AMS_HDL_SRV_END, //!< service end handle
+ AMS_HDL_REMOTE_CMD_VALUE, //!< remote command characteristic value handle
+ AMS_HDL_REMOTE_CMD_CCCD, //!< remote command characteristic CCCD handle
+ AMS_HDL_ENTITY_UPD_VALUE, //!< entity update characteristic value handle
+ AMS_HDL_ENTITY_UPD_CCCD, //!< entity update characteristic CCCD handle
+ AMS_HDL_ENTITY_ATTR_VALUE, //!< entity attribute characteristic value handle
+ AMS_HDL_CACHE_LEN, //!< handle cache length
+} T_AMS_HANDLE_TYPE;
+
+
+/** @brief AMS client discovery state*/
+typedef enum
+{
+ AMS_DISC_IDLE,
+ AMS_DISC_START,
+ AMS_DISC_DONE,
+ AMS_DISC_FAILED
+} T_AMS_DISC_STATE;
+
+/** @brief AMS client write type*/
+typedef enum
+{
+ AMS_WRITE_REMOTE_CMD_VALUE,
+ AMS_WRITE_REMOTE_CMD_NOTIFY_ENABLE,
+ AMS_WRITE_REMOTE_CMD_NOTIFY_DISABLE,
+ AMS_WRITE_ENTITY_UPD_VALUE,
+ AMS_WRITE_ENTITY_UPD_NOTIFY_ENABLE,
+ AMS_WRITE_ENTITY_UPD_NOTIFY_DISABLE,
+ AMS_WRITE_ENTITY_ATTR_VALUE
+} T_AMS_WRITE_TYPE;
+
+/** @brief AMS client write result*/
+typedef struct
+{
+ T_AMS_WRITE_TYPE type;
+ uint16_t cause;
+} T_AMS_WRITE_RESULT;
+
+/** @brief AMS client data type*/
+typedef enum
+{
+ AMS_NOTIFY_FROM_REMOTE_CMD,
+ AMS_NOTIFY_FROM_ENTITY_UPD,
+ AMS_NOTIFY_FROM_ENTITY_ATTR,
+} T_AMS_NOTIFY_DATA_TYPE;
+
+/** @brief AMS client data type*/
+typedef enum
+{
+ AMS_READ_FROM_ENTITY_UPD,
+} T_AMS_READ_DATA_TYPE;
+
+
+/** @brief AMS client notification data*/
+typedef struct
+{
+ T_AMS_READ_DATA_TYPE type;
+ uint16_t cause;
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_AMS_READ_DATA;
+
+/** @brief AMS client notification data*/
+typedef struct
+{
+ T_AMS_NOTIFY_DATA_TYPE type;
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_AMS_NOTIFY_DATA;
+
+
+/** @brief AMS client callback content*/
+typedef union
+{
+ T_AMS_DISC_STATE disc_state;
+ T_AMS_READ_DATA read_data;
+ T_AMS_WRITE_RESULT write_result;
+ T_AMS_NOTIFY_DATA notify_data;
+} T_AMS_CB_CONTENT;
+
+/** @brief AMS client callback type*/
+typedef enum
+{
+ AMS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state
+ AMS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request result
+ AMS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail
+ AMS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server
+ AMS_CLIENT_CB_TYPE_DISCONNECT_INFO, //!< LE link disconnect
+ AMS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage
+} T_AMS_CB_TYPE;
+
+/** @brief AMS client callback data*/
+typedef struct
+{
+ T_AMS_CB_TYPE cb_type;
+ T_AMS_CB_CONTENT cb_content;
+} T_AMS_CB_DATA;
+
+/** @defgroup AMS_CLIENT_Exported_Functions AMS Client Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add ams client.
+ *
+ * @param[in] app_cb Callbackto notify client read/write/notify/indicate events.
+ * @param[in] link_num Initialize link number
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void ams_init(uint8_t link_num)
+ {
+ ams_client = ams_add_client(ams_client_cb, link_num);
+ }
+ * \endcode
+ */
+T_CLIENT_ID ams_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num);
+
+
+/**
+ * @brief Used by application, to start the discovery procedure of AMS.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT test(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = ams_start_discovery(conn_id);
+ }
+ * \endcode
+ */
+bool ams_start_discovery(uint8_t conn_id);
+
+/**
+ * @brief Used by application, to set the notification flag of remote command.
+ * @param[in] conn_id connection ID.
+ * @param[in] subscribe value to enable or disable notify.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ams_subscribe_remote_cmd(uint8_t conn_id, bool subscribe);
+
+/**
+ * @brief Used by application, to set the notification flag of entity update.
+ * @param[in] conn_id connection ID.
+ * @param[in] subscribe value to enable or disable notify.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ams_subscribe_entity_upd(uint8_t conn_id, bool subscribe);
+
+/**
+ * @brief Used by application, to send remote command.
+ * @param[in] conn_id connection ID.
+ * @param[in] cmd_id Remote Command ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_amscmd(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint8_t cmd_id = p_parse_value->dw_param[1];
+ bool ret = ams_write_remote_cmd(conn_id, (T_AMS_REMOTE_CMD_ID)cmd_id);
+ }
+ * \endcode
+ */
+bool ams_write_remote_cmd(uint8_t conn_id, T_AMS_REMOTE_CMD_ID cmd_id);
+
+/**
+ * @brief Used by application, to write the Entity Update characteristic.
+ *
+ * The Entity Update characteristic is the characteristic by which an MR can inform the MS
+ * which entity/attribute pairs it is interested in, and be informed about changes on these whenever they occur.
+ * For example, the MR can be informed about the title of the currently loaded track, or the name of the active media app.
+ *
+ * @param[in] conn_id connection ID.
+ * @param[in] p_value entity/attribute pairs.
+ * @param[in] value_len value length of p_value.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_amswrite(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint8_t type = p_parse_value->dw_param[1];
+ bool ret = false;
+
+ if (type == 0)
+ {
+ uint8_t cmd[3];
+ cmd[0] = ENTITY_ID_TRACK;
+ cmd[1] = TRACK_ATTR_ID_TITLE;
+ cmd[2] = TRACK_ATTR_ID_DURATION;
+ ret = ams_write_entity_upd_cmd(conn_id, cmd, 3);
+ }
+ }
+ * \endcode
+ */
+bool ams_write_entity_upd_cmd(uint8_t conn_id, uint8_t *p_value, uint8_t value_len);
+
+/**
+ * @brief Used by application, to write the Entity Attribute characteristic.
+ *
+ * This characteristic should ideally only be used if the value of an entity/attribute pair was marked as truncated
+ * in the corresponding Entity Update notification, and the MR wants to display more of the associated value.
+ *
+ * @param[in] conn_id connection ID.
+ * @param[in] entity_attr Entity Attribute command.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_amswrite(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint8_t type = p_parse_value->dw_param[1];
+ bool ret = false;
+
+ if (type == 1)
+ {
+ T_AMS_ENTITY_ATTR entity;
+ entity.entity_id = ENTITY_ID_TRACK;
+ entity.attr_id.track_attr_id = TRACK_ATTR_ID_TITLE;
+ ret = ams_write_entity_attr(conn_id, entity);
+ }
+ }
+ * \endcode
+ */
+bool ams_write_entity_attr(uint8_t conn_id, T_AMS_ENTITY_ATTR entity_attr);
+
+/**
+ * @brief Used by application, to read the Entity Attribute characteristic.
+ *
+ * This characteristic should ideally only be used if the value of an entity/attribute pair was marked as truncated
+ * in the corresponding Entity Update notification, and the MR wants to display more of the associated value.
+ *
+ * @param[in] conn_id connection ID.
+ * @param[in] entity_attr Entity Attribute command.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_amsread(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_AMS_ENTITY_ATTR entity;
+ bool ret;
+ entity.entity_id = ENTITY_ID_TRACK;
+ entity.attr_id.track_attr_id = TRACK_ATTR_ID_TITLE;
+ ret = ams_read_entity_attr(conn_id, entity);
+ }
+ * \endcode
+ */
+bool ams_read_entity_attr(uint8_t conn_id, T_AMS_ENTITY_ATTR entity_attr);
+
+
+/**
+ * @brief Get the handle for gatt characteristic
+ * @param[in] conn_id Connection ID.
+ * @param[in] handle_type Pre-defined Handle Type.
+ * @retval the handle value of a GATT characteristic.
+ */
+uint16_t ams_search_handle(uint8_t conn_id, T_AMS_HANDLE_TYPE handle_type);
+
+
+/** @} End of AMS_CLIENT_Exported_Functions */
+
+/** @} End of AMS_CLIENT */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/inc/bluetooth/profile/client/ancs_client.h b/inc/bluetooth/profile/client/ancs_client.h
new file mode 100644
index 0000000..164edb9
--- /dev/null
+++ b/inc/bluetooth/profile/client/ancs_client.h
@@ -0,0 +1,300 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs_client.h
+ * @brief Head file for using ANCS Client.
+ * @details
+ * @author jane
+ * @date 2016-02-18
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _ANCS_CLIENT_H_
+#define _ANCS_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include <profile_client.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+
+/** @defgroup ANCS_CLIENT ANCS Client
+* @brief ANCS client
+* @{
+*/
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @addtogroup ANCS_CLIENT_Exported_Macros ANCS Client Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @brief Define links number. range: 0-4 */
+#define ANCS_MAX_LINKS 4
+
+
+/** End of ANCS_CLIENT_Exported_Macros
+* @}
+*/
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup ANCS_CLIENT_Exported_Types ANCS Client Exported Types
+ * @brief
+ * @{
+ */
+
+/** @brief ANCS client handle type*/
+typedef enum
+{
+ HDL_ANCS_SRV_START, //!< start handle of ANCS
+ HDL_ANCS_SRV_END, //!< end handle of ANCS
+ HDL_ANCS_CONTROL_POINT, //!< control point characteristic value handle
+ HDL_ANCS_NOTIFICATION_SOURCE, //!< notification source characteristic value handle
+ HDL_ANCS_NOTIFICATION_SOURCE_CCCD, //!< notification source characteristic CCCD handle
+ HDL_ANCS_DATA_SOURCE, //!< data source characteristic value handle
+ HDL_ANCS_DATA_SOURCE_CCCD, //!< data source characteristic CCCD handle
+ HDL_ANCS_CACHE_LEN //!< handle cache length
+} T_ANCS_HANDLE_TYPE;
+
+/** @brief ANCS client control command id*/
+typedef enum
+{
+ CP_CMD_ID_GET_NOTIFICATION_ATTR = 0,
+ CP_CMD_ID_GET_APP_ATTR = 1,
+ CP_CMD_ID_PERFORM_NOTIFICATION_ACTION = 2,
+ CP_CMD_ID_RESERVED = 255
+} T_ANCS_CP_CMD_ID;
+
+/** @brief ANCS client discovery state*/
+typedef enum
+{
+ DISC_ANCS_IDLE,
+ DISC_ANCS_START,
+ DISC_ANCS_DONE,
+ DISC_ANCS_FAILED
+} T_ANCS_DISC_STATE;
+
+/** @brief ANCS client data type*/
+typedef enum
+{
+ ANCS_FROM_DATA_SOURCE,
+ ANCS_FROM_NOTIFICATION_SOURCE,
+} T_ANCS_DATA_TYPE;
+
+/** @brief ANCS client notification data struct*/
+typedef struct
+{
+ T_ANCS_DATA_TYPE type;
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_ANCS_NOTIFY_DATA;
+
+/** @brief ANCS client write type*/
+typedef enum
+{
+ ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE,
+ ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE,
+ ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE,
+ ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE,
+ ANCS_WRITE_CONTROL_POINT,
+} T_ANCS_WRITE_TYPE;
+
+/** @brief ANCS client write result*/
+typedef struct
+{
+ T_ANCS_WRITE_TYPE type;
+ uint16_t cause;
+} T_ANCS_WRITE_RESULT;
+
+/** @brief ANCS client callback type*/
+typedef enum
+{
+ ANCS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending.
+ ANCS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail.
+ ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server.
+ ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO,
+ ANCS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage.
+} T_ANCS_CB_TYPE;
+
+/** @brief ANCS client callback content*/
+typedef union
+{
+ T_ANCS_DISC_STATE disc_state;
+ T_ANCS_NOTIFY_DATA notify_data;
+ T_ANCS_WRITE_RESULT write_result;
+} T_ANCS_CB_CONTENT;
+
+/** @brief ANCS client callback data*/
+typedef struct
+{
+ T_ANCS_CB_TYPE cb_type;
+ T_ANCS_CB_CONTENT cb_content;
+} T_ANCS_CB_DATA;
+/** End of ANCS_CLIENT_Exported_Types
+* @}
+*/
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup ANCS_CLIENT_Exported_Functions ANCS Client Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add ancs client.
+ *
+ * @param[in] app_cb Callbackto notify client read/write/notify/indicate events.
+ * @param[in] link_num Initialize link number
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void ancs_init(uint8_t link_num)
+ {
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+ }
+ * \endcode
+ */
+T_CLIENT_ID ancs_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num);
+
+
+/**
+ * @brief Used by application, to start the discovery procedure of ANCS.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ancs_start_discovery(uint8_t conn_id);
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_ancshdl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t hdl_cache[HDL_ANCS_CACHE_LEN];
+ bool ret = ancs_get_hdl_cache(conn_id, hdl_cache,
+ sizeof(uint16_t) * HDL_ANCS_CACHE_LEN);
+ ......
+ }
+ * \endcode
+ */
+bool ancs_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_discov_services(uint8_t conn_id, bool start)
+ {
+ ......
+ if (app_srvs_table.srv_found_flags & APP_DISCOV_ANCS_FLAG)
+ {
+ ancs_set_hdl_cache(conn_id, app_srvs_table.ancs_hdl_cache, sizeof(uint16_t) * HDL_ANCS_CACHE_LEN);
+ }
+ ......
+ }
+ * \endcode
+ */
+bool ancs_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to set the notification flag of notification source.
+ * @param[in] conn_id connection ID.
+ * @param[in] notify value to enable or disable notify.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ancs_set_notification_source_notify(uint8_t conn_id, bool notify);
+
+/**
+ * @brief Used by application, to set the notification flag of data source.
+ * @param[in] conn_id connection ID.
+ * @param[in] notify value to enable or disable notify.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ancs_set_data_source_notify(uint8_t conn_id, bool notify);
+
+/**
+ * @brief Used by application, to get the notification attribute.
+ * @param[in] conn_id connection ID.
+ * @param[in] notification_uid value to enable or disable notify.
+ * @param[in] p_attribute_ids Pointer to attribute ids.
+ * @param[in] attribute_ids_len Length of attribute ids.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ancs_get_notification_attr(uint8_t conn_id, uint32_t notification_uid,
+ uint8_t *p_attribute_ids, uint8_t attribute_ids_len);
+/**
+ * @brief Used by application, to get the app attribute.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_app_identifier value to enable or disable notify.
+ * @param[in] p_attribute_ids Pointer to attribute ids.
+ * @param[in] attribute_ids_len Length of attribute ids.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ancs_get_app_attr(uint8_t conn_id, char *p_app_identifier, uint8_t *p_attribute_ids,
+ uint8_t attribute_ids_len);
+
+/**
+ * @brief Used by application, to perfome the notication action.
+ * @param[in] conn_id Connection ID.
+ * @param[in] notification_uid Notification UUID.
+ * @param[in] action_id Action id.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ancs_perform_notification_action(uint8_t conn_id, uint32_t notification_uid,
+ uint8_t action_id);
+
+/**
+ * @brief Get the handle for gatt characteristic
+ * @param[in] conn_id Connection ID.
+ * @param[in] handle_type Pre-defined Handle Type.
+ * @retval the handle value of a GATT characteristic.
+ */
+uint16_t ancs_search_handle(uint8_t conn_id, T_ANCS_HANDLE_TYPE handle_type);
+
+/** @} End of ANCS_CLIENT_Exported_Functions */
+
+/** @} End of ANCS_CLIENT */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _ANCS_CLIENT_H_ */
diff --git a/inc/bluetooth/profile/client/bas_client.h b/inc/bluetooth/profile/client/bas_client.h
new file mode 100644
index 0000000..1eed7d1
--- /dev/null
+++ b/inc/bluetooth/profile/client/bas_client.h
@@ -0,0 +1,337 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file bas_client.h
+ * @brief Head file for using battery service client.
+ * @details Battery service client data structs and external functions declaration.
+ * @author jane
+ * @date 2016-02-18
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _BAS_CLIENT_H_
+#define _BAS_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include <profile_client.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+
+
+/** @defgroup BAS_CLIENT Battery Service Client
+ * @brief BAS client
+ * @details
+ Application shall register bas client when initialization through @ref bas_add_client function.
+
+ Application can start discovery battery service through @ref bas_start_discovery function.
+
+ Application can read battery level characteristic value through @ref bas_read_battery_level function.
+
+ Application can config and read the notification flag through @ref bas_set_notify and @ref bas_read_notify function.
+
+ Application shall handle callback function registered by bas_add_client.
+ * \code{.c}
+ T_APP_RESULT app_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ if (client_id == bas_client_id)
+ {
+ T_BAS_CLIENT_CB_DATA *p_bas_cb_data = (T_BAS_CLIENT_CB_DATA *)p_data;
+ switch (p_bas_cb_data->cb_type)
+ {
+ case BAS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_bas_cb_data->cb_content.disc_state)
+ {
+ case DISC_BAS_DONE:
+ ......
+ }
+ }
+ * \endcode
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @addtogroup BAS_CLIENT_Exported_Macros BAS Client Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @brief Define links number. range: 0-4 */
+#define BAS_MAX_LINKS 4
+
+/** End of BAS_CLIENT_Exported_Macros
+* @}
+*/
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup BAS_CLIENT__Exported_Types BAS Client Exported Types
+ * @brief
+ * @{
+ */
+
+/** @brief BAS client handle type*/
+typedef enum
+{
+ HDL_BAS_SRV_START, //!< start handle of battery service
+ HDL_BAS_SRV_END, //!< end handle of battery service
+ HDL_BAS_BATTERY_LEVEL, //!< battery level characteristic value handle
+ HDL_BAS_BATTERY_LEVEL_CCCD, //!< battery level characteristic CCCD handle
+ HDL_BAS_CACHE_LEN //!< handle cache length
+} T_BAS_HANDLE_TYPE;
+
+/** @brief BAS client discovery state*/
+typedef enum
+{
+ DISC_BAS_IDLE,
+ DISC_BAS_START,
+ DISC_BAS_DONE,
+ DISC_BAS_FAILED
+} T_BAS_DISC_STATE;
+
+/** @brief BAS client notification data struct*/
+typedef struct
+{
+ uint8_t battery_level;
+} T_BAS_NOTIFY_DATA;
+
+/** @brief BAS client write type*/
+typedef enum
+{
+ BAS_WRITE_NOTIFY_ENABLE,
+ BAS_WRITE_NOTIFY_DISABLE,
+} T_BAS_WRITE_TYPE;
+
+/** @brief BAS client write result*/
+typedef struct
+{
+ T_BAS_WRITE_TYPE type;
+ uint16_t cause;
+} T_BAS_WRITE_RESULT;
+
+/** @brief BAS client read data */
+typedef union
+{
+ uint8_t battery_level;
+ bool notify;
+} T_BAS_READ_DATA;
+
+/** @brief BAS client read type*/
+typedef enum
+{
+ BAS_READ_NOTIFY,
+ BAS_READ_BATTERY_LEVEL,
+} T_BAS_READ_TYPE;
+
+/** @brief BAS client read result*/
+typedef struct
+{
+ T_BAS_READ_TYPE type;
+ T_BAS_READ_DATA data;
+ uint16_t cause;
+} T_BAS_READ_RESULT;
+
+/** @brief BAS client callback type*/
+typedef enum
+{
+ BAS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending.
+ BAS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server.
+ BAS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail.
+ BAS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server.
+ BAS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage.
+} T_BAS_CLIENT_CB_TYPE;
+
+/** @brief BAS client callback content*/
+typedef union
+{
+ T_BAS_DISC_STATE disc_state;
+ T_BAS_READ_RESULT read_result;
+ T_BAS_NOTIFY_DATA notify_data;
+ T_BAS_WRITE_RESULT write_result;
+} T_BAS_CLIENT_CB_CONTENT;
+
+/** @brief BAS client callback data*/
+typedef struct
+{
+ T_BAS_CLIENT_CB_TYPE cb_type;
+ T_BAS_CLIENT_CB_CONTENT cb_content;
+} T_BAS_CLIENT_CB_DATA;
+/** End of BAS_CLIENT_Exported_Types
+* @}
+*/
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup BAS_CLIENT_Exported_Functions BAS Client Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add bas client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ bas_client_id = bas_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID bas_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num);
+
+/**
+ * @brief Used by application, to start the discovery procedure of battery service.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_basdis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = bas_start_discovery(conn_id);
+ ......
+ }
+ * \endcode
+ */
+bool bas_start_discovery(uint8_t conn_id);
+
+/**
+ * @brief Used by application, to set the notification flag.
+ * @param[in] conn_id connection ID.
+ * @param[in] notify value to enable or disable notify.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_bascccd(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool notify = p_parse_value->dw_param[1];
+ bool ret;
+ ret = bas_set_notify(conn_id, notify);
+ ......
+ }
+ * \endcode
+ */
+bool bas_set_notify(uint8_t conn_id, bool notify);
+
+/**
+ * @brief Used by application, to read the notification flag.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_basread(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = false;
+ ret = bas_read_notify(conn_id);
+ ......
+ }
+ * \endcode
+ */
+bool bas_read_notify(uint8_t conn_id);
+
+/**
+ * @brief Used by application, to read battery level.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_basread(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = false;
+ ret = bas_read_battery_level(conn_id);
+ ......
+ }
+ * \endcode
+ */
+bool bas_read_battery_level(uint8_t conn_id);
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_bashdl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t hdl_cache[HDL_BAS_CACHE_LEN];
+ bool ret = bas_get_hdl_cache(conn_id, hdl_cache,
+ sizeof(uint16_t) * HDL_BAS_CACHE_LEN);
+
+ ......
+ }
+ * \endcode
+ */
+bool bas_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_discov_services(uint8_t conn_id, bool start)
+ {
+ ......
+ if (app_srvs_table.srv_found_flags & APP_DISCOV_BAS_FLAG)
+ {
+ bas_set_hdl_cache(conn_id, app_srvs_table.bas_hdl_cache, sizeof(uint16_t) * HDL_BAS_CACHE_LEN);
+ }
+ ......
+ }
+ * \endcode
+ */
+bool bas_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/** @} End of BAS_CLIENT_Exported_Functions */
+
+/** @} End of BAS_CLIENT */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _BAS_CLIENT_H_ */
diff --git a/inc/bluetooth/profile/client/dfu_client.h b/inc/bluetooth/profile/client/dfu_client.h
new file mode 100644
index 0000000..5ff1019
--- /dev/null
+++ b/inc/bluetooth/profile/client/dfu_client.h
@@ -0,0 +1,319 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file dfu_client.h
+ * @brief Head file for using dfu service Client.
+ * @details Data structs and external functions declaration.
+ * @author bill
+ * @date 2018-4-17
+ * @version v2.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _DFU_CLIENT_H_
+#define _DFU_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Add Includes here */
+#include "patch_header_check.h"
+#include "profile_client.h"
+#include "dfu_api.h"
+
+/** @defgroup DFU_Client DFU Service Client
+ * @brief DFU client
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @addtogroup DFU_Client_Exported_Macros DFU Client Exported Macros
+ * @brief
+ * @{
+ */
+/** @brief Define links number. range: 0-4 */
+#define DFU_MAX_LINKS 4
+/** End of DFU_Client_Exported_Macros * @} */
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup DFU_Client_Exported_Types DFU Client Exported Types
+ * @brief
+ * @{
+ */
+/** @brief Handle cache for intrested UUIDs */
+typedef enum
+{
+ HDL_DFU_SRV_START, // start handle of dfu service
+ HDL_DFU_SRV_END, // end handle of dfu service
+ HDL_DFU_DATA,
+ HDL_DFU_CP,
+ HDL_DFU_CP_CCCD,
+ HDL_DFU_CACHE_LEN
+} T_DFU_HANDLE_TYPE;
+
+/** @brief used to inform app the discovery procedure is done or pending */
+typedef enum
+{
+ DISC_DFU_IDLE,
+ DISC_DFU_START,
+ DISC_DFU_DONE,
+ DISC_DFU_FAIL,
+} T_DFU_DISC_STATE;
+
+/** @brief read request type, used by app to send read request */
+typedef enum
+{
+ DFU_READ_CP_CCCD
+} T_DFU_READ_TYPE;
+
+/** @brief read content, used to inform app read response data content */
+typedef union
+{
+ bool dfu_cp_cccd;
+} T_DFU_READ_DATA;
+
+/** @brief read data, used to inform app read response data */
+typedef struct
+{
+ T_DFU_READ_TYPE type;
+ T_DFU_READ_DATA data;
+ uint16_t cause;
+} T_DFU_READ_RESULT;
+
+/** @brief write request result */
+typedef enum
+{
+ DFU_WRITE_CP,
+ DFU_WRITE_CP_CCCD,
+ DFU_WRITE_DATA
+} T_DFU_WRITE_TYPE;
+
+typedef struct
+{
+ T_DFU_WRITE_TYPE type;
+ uint16_t cause;
+} T_DFU_WRITE_RESULT;
+
+/** @brief notif/ind receive type */
+typedef enum
+{
+ DFU_RECEIVE_CP_NOTIFY,
+} T_DFU_NOTIFY_INDICATE_TYPE;
+
+/** @brief notif/ind receive content */
+typedef struct
+{
+ uint16_t len;
+ uint8_t *pdata;
+} T_DFU_NOTIFY_INDICATE_VAL;
+
+/** @brief The notif/ind data received by the client from the server */
+typedef struct
+{
+ T_DFU_NOTIFY_INDICATE_TYPE type;
+ T_DFU_NOTIFY_INDICATE_VAL value;
+} T_DFU_NOTIFY_INDICATE_DATA;
+
+/** @brief Event type to inform app */
+typedef enum
+{
+ DFU_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending.
+ DFU_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server.
+ DFU_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail.
+ DFU_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server.
+ DFU_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage.
+} T_DFU_CLIENT_CB_TYPE;
+
+/** @brief Callback content sent to application from the client */
+typedef union
+{
+ T_DFU_DISC_STATE disc_state;
+ T_DFU_READ_RESULT read_result;
+ T_DFU_WRITE_RESULT write_result;
+ T_DFU_NOTIFY_INDICATE_DATA notif_ind_data;
+} T_DFU_CLIENT_CB_CONTENT;
+
+/** @brief Callback data sent to application from the client, include type and content */
+typedef struct
+{
+ T_DFU_CLIENT_CB_TYPE cb_type;
+ T_DFU_CLIENT_CB_CONTENT cb_content;
+} T_DFU_CLIENT_CB_DATA;
+
+
+typedef enum
+{
+ DFU_FSM_WRITE_IDLE,
+ DFU_FSM_WRITE_CCCD_ENABLE,
+ DFU_FSM_WRITE_DFU_DATA,
+ DFU_FSM_WRITE_WAIT_WRITE_RESP
+} T_DFU_CLIENT_FSM_WRITE;
+
+typedef enum
+{
+ DFU_CB_START,
+ DFU_CB_END,
+ DFU_CB_FAIL,
+ DFU_CB_MAX
+} T_DFU_CB_TYPE;
+
+typedef enum
+{
+ DFU_SUCCESS,
+ DFU_FAIL_START_DFU,
+ DFU_FAIL_BUF_CHECK,
+ DFU_FAIL_VALIDATE_FW,
+} T_DFU_FAIL_TYPE;
+
+typedef union
+{
+ T_DFU_FAIL_TYPE dfu_fail_reason;
+} T_DFU_CB_DATA;
+
+/** Dfu service data to inform application */
+typedef struct
+{
+ uint8_t conn_id;
+ T_DFU_CB_TYPE type;
+ T_DFU_CB_DATA data;
+} T_DFU_CLIENT_CB_MSG;
+
+typedef enum
+{
+ DFU_FEATURE_USER_DEFINED_DFU,
+ DFU_FEATURE_AUTO_COPY_DFU,
+
+} T_DFU_CLIENT_FEATURE_TYPE;
+
+typedef enum
+{
+ DFU_SET_FEATURE,
+ DFU_SET_MODE_VALUE,
+ DFU_SET_MAX_BUF_SIZE,
+ DFU_SET_DFU_IMG_ADDR,
+ DFU_SET_DFU_IMG_VER,
+ DFU_SET_NORMAL_OTA_FLAG,
+} T_DFU_SET_CLIENT_CTX_TYPE;
+
+typedef struct
+{
+ T_IMG_CTRL_HEADER_FORMAT dfu_ctrl_header;
+
+ T_OTA_MODE ota_mode;
+ T_DFU_CLIENT_FEATURE_TYPE dfu_feature;
+ T_DFU_CLIENT_FSM_WRITE dfu_fsm_write;
+ bool is_normal_ota;
+
+ uint16_t mtu_size;
+ uint16_t max_buffer_size;
+
+ uint32_t dfu_img_start_addr;
+ uint32_t dfu_img_version;
+ uint32_t dfu_img_total_length;
+
+ uint32_t curr_offset;
+ uint32_t target_img_version;
+
+ uint16_t dfu_buf_check_crc_val;
+ uint16_t dfu_buf_check_size;
+
+ /*ctx used when enable or disable buffer check*/
+ uint16_t dfu_pkt_num;
+ uint16_t dfu_pkt_counter;
+ uint16_t dfu_last_pkt_size;
+} T_DFU_CTX;
+
+
+typedef void (*P_FUN_DFU_CLIENT_INIT_APP_CB)(void);
+
+/** End of DFU_Client_Exported_Types * @} */
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup DFU_Client_Exported_Functions DFU Client Exported Functions
+ * @{
+ */
+bool dfu_encrypt(uint8_t image[16]);
+uint16_t dfu_client_crc_cal(uint8_t *buf, uint32_t length, uint16_t checksum16);
+
+void dfu_client_set_dfu_ctx_value(T_DFU_SET_CLIENT_CTX_TYPE type, void *p_value);
+
+/**
+ * @brief start the service discovery
+ *
+ * contains the service/characteristic/cccd declaration
+ * @param[in] conn_id: the connection id
+ * @return the operation result
+ */
+bool dfu_client_start_discovery(uint8_t conn_id);
+
+/**
+ * @brief Used by application, to set the handles in Dfu handle cache.
+ * @param handle_type: handle types of this specific profile.
+ * @param handle_value: handle value to set.
+ * @retval true--set success.
+ * false--set failed.
+ */
+bool dfu_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool dfu_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic.
+ * @param command: 0--disable the notification, 1--enable the notification.
+ * @retval true--send request to upper stack success.
+ * false--send request to upper stack failed.
+ */
+bool dfu_client_cp_cccd_set(uint8_t conn_id, bool command);
+
+/**
+ * @brief Used internal, to send write request to peer server's V5 Control Point Characteristic.
+ * @param ctl_pnt_ptr: pointer of control point data to write.
+ * @retval true--send request to upper stack success.
+ * false--send request to upper stack failed.
+ */
+bool dfu_client_cp_write(uint8_t conn_id, uint8_t *pdata, uint16_t length);
+
+/**
+ * @brief Used internal, to send write request to peer server's V5 Control Point Characteristic.
+ * @param ctl_pnt_ptr: pointer of control point data to write.
+ * @retval true--send request to upper stack success.
+ * false--send request to upper stack failed.
+ */
+bool dfu_client_data_write(uint8_t conn_id, uint8_t *pdata, uint16_t length);
+
+/**
+ * @brief add Dfu client to application.
+ * @param appCB: pointer of app callback function to handle specific client module data.
+ * @retval Client ID of the specific client module.
+ */
+T_CLIENT_ID dfu_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num);
+
+
+/** @} End of DFU_Client_Exported_Functions */
+
+/** @} End of DFU_Client */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DFU_CLIENT_H_ */
diff --git a/inc/bluetooth/profile/client/dis_client.h b/inc/bluetooth/profile/client/dis_client.h
new file mode 100644
index 0000000..8514719
--- /dev/null
+++ b/inc/bluetooth/profile/client/dis_client.h
@@ -0,0 +1,304 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file dis_client.h
+ * @brief Head file for using DIS Client.
+ * @details dis data structs and external functions declaration.
+ * @author ken
+ * @date 2017-12-05
+ * @version v0.1
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _DIS_CLIENT_H_
+#define _DIS_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include <profile_client.h>
+
+
+/** @defgroup DIS_Client dis service client
+ * @brief dis service client
+ * @details
+ dis Profile is a customized BLE-based Profile. Dis ble service please refer to @ref DIS_Service .
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup DIS_Client_Exported_Macros DIS Client Exported Macros
+ * @brief
+ * @{
+ */
+/** @defgroup DIS UUIDs
+ * @brief Dis BLE Profile UUID definitions
+ * @{
+ */
+#define GATT_UUID_DEVICE_INFORMATION_SERVICE 0x180A
+
+#define GATT_UUID_CHAR_SYSTEM_ID 0x2A23
+#define GATT_UUID_CHAR_MODEL_NUMBER 0x2A24
+#define GATT_UUID_CHAR_SERIAL_NUMBER 0x2A25
+#define GATT_UUID_CHAR_FIRMWARE_REVISION 0x2A26
+#define GATT_UUID_CHAR_HARDWARE_REVISION 0x2A27
+#define GATT_UUID_CHAR_SOFTWARE_REVISION 0x2A28
+#define GATT_UUID_CHAR_MANUFACTURER_NAME 0x2A29
+#define GATT_UUID_CHAR_IEEE_CERTIF_DATA_LIST 0x2A2A
+#define GATT_UUID_CHAR_PNP_ID 0x2A50
+/** @} End of DIS_UUIDs */
+
+/** @brief Define links number. range: 0-4 */
+#define DIS_MAX_LINKS 2
+/** End of DIS_Client_Exported_Macros
+ * @}
+ */
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup DIS_Exported_Types DIS Client Exported Types
+ * @brief
+ * @{
+ */
+
+/** @brief DIS client handle type*/
+typedef enum
+{
+ HDL_DIS_SRV_START, //!< start handle of lls service
+ HDL_DIS_SRV_END, //!< end handle of lls service
+ HDL_DIS_SYSTEM_ID, //!< DIS system id read characteristic value handle
+ HDL_DIS_MODEL_NUMBER, //!< DIS model number read characteristic value handle
+ HDL_DIS_SERIAL_NUMBER, //!< DIS serial number read characteristic value handle
+ HDL_DIS_FIRMWARE_REVISION, //!< DIS firmware revision read characteristic value handle
+ HDL_DIS_HARDWARE_REVISION, //!< DIS hardware revision read characteristic value handle
+ HDL_DIS_SOFTWARE_REVISION, //!< DIS software revision read characteristic value handle
+ HDL_DIS_MANUFACTURER_NAME, //!< DIS manufacturer name read characteristic value handle
+ HDL_DIS_IEEE_CERTIF_DATA_LIST,//!< DIS ieee certif data list read characteristic value handle
+ HDL_DIS_PNP_ID, //!< DIS pnp id read characteristic value handle
+ HDL_DIS_CACHE_LEN //!< handle cache length
+} T_DIS_HANDLE_TYPE;
+
+/** @brief DIS client discovery state*/
+typedef enum
+{
+ DISC_DIS_IDLE,
+ DISC_DIS_START,
+ DISC_DIS_DONE,
+ DISC_DIS_FAILED
+} T_DIS_DISC_STATE;
+
+/** @brief dis client read type*/
+typedef enum
+{
+ DIS_READ_SYSTEM_ID,
+ DIS_READ_MODEL_NUMBER,
+ DIS_READ_SERIAL_NUMBER,
+ DIS_READ_FIRMWARE_REVISION,
+ DIS_READ_HARDWARE_REVISION,
+ DIS_READ_SOFTWARE_REVISION,
+ DIS_READ_MANUFACTURER_NAME,
+ DIS_READ_IEEE_CERTIF_DATA_LIST,
+ DIS_READ_PNP_ID
+} T_DIS_READ_TYPE;
+
+/** @brief DIS client read value*/
+typedef struct
+{
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_DIS_READ_VALUE;
+
+/** @brief DIS client read data*/
+typedef union
+{
+ T_DIS_READ_VALUE v1_read;
+// bool v3_notify_cccd;
+// bool v4_indicate_cccd;
+} T_DIS_READ_DATA;
+
+/** @brief DIS client read result*/
+typedef struct
+{
+ T_DIS_READ_TYPE type;
+ T_DIS_READ_DATA data;
+ uint16_t cause;
+} T_DIS_READ_RESULT;
+
+
+///** @brief LLS client write type*/
+//typedef enum
+//{
+// LLS_WRITE_PARA,
+//} T_LLS_WRITE_TYPE;
+
+///** @brief LLS client write result*/
+//typedef struct
+//{
+// T_LLS_WRITE_TYPE type;
+// uint16_t cause;
+//} T_LLS_WRITE_RESULT;
+
+/** @brief LLS client notif/ind receive type*/
+//typedef enum
+//{
+// LLS_KEY_NOTIFY,
+//} T_LLS_NOTIF_IND_TYPE;
+
+///** @brief LLS client notif/ind receive data*/
+//typedef struct
+//{
+// uint16_t value_size;
+// uint8_t *p_value;
+//} T_LLS_NOTIF_IND_VALUE;
+
+/** @brief LLS client notif/ind receive content*/
+//typedef struct
+//{
+// T_LLS_NOTIF_IND_TYPE type;
+// T_LLS_NOTIF_IND_VALUE data;
+//} T_LLS_NOTIF_IND_DATA;
+
+/** @brief DIS client callback type*/
+typedef enum
+{
+ DIS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending.
+ DIS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server.
+ //LLS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail.
+ //LLS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server.
+ DIS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage.
+} T_DIS_CLIENT_CB_TYPE;
+
+/** @brief DIS client callback content*/
+typedef union
+{
+ T_DIS_DISC_STATE disc_state;
+ T_DIS_READ_RESULT read_result;
+ //T_DIS_WRITE_RESULT write_result;
+ //T_LLS_NOTIF_IND_DATA notif_ind_data;
+} T_DIS_CLIENT_CB_CONTENT;
+
+/** @brief DIS client callback data*/
+typedef struct
+{
+ T_DIS_CLIENT_CB_TYPE cb_type;
+ T_DIS_CLIENT_CB_CONTENT cb_content;
+} T_DIS_CLIENT_CB_DATA;
+
+/** End of DIS_Client_Exported_Types * @} */
+
+/** @defgroup DIS_Client_Exported_Functions DIS Client Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Add dis service client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ dis_client_id = dis_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID dis_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num);
+
+/**
+ * @brief Used by application, to start the discovery procedure of dis server.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool dis_client_start_discovery(uint8_t conn_id);
+
+/**
+ * @brief Used by application, to read data from server by using handles.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool dis_client_read_by_handle(uint8_t conn_id, T_DIS_READ_TYPE read_type);
+
+/**
+ * @brief Used by application, to read data from server by using UUIDs.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool dis_client_read_by_uuid(uint8_t conn_id, T_DIS_READ_TYPE read_type);
+
+/**
+ * @brief Used by application, to write data of write Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] length write data length
+ * @param[in] p_value point the value to write
+ * @param[in] type write type.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool dis_client_write_char(uint8_t conn_id, uint16_t length, uint8_t *p_value,
+// T_GATT_WRITE_TYPE type);
+
+/**
+ * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] notify 0--disable the notification, 1--enable the notification.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool lls_client_set_v3_notify(uint8_t conn_id, bool notify);
+
+/**
+ * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] ind 0--disable the indication, 1--enable the indication.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool lls_client_set_v4_ind(uint8_t conn_id, bool ind);
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool dis_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool dis_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/** @} End of DIS_Client_Exported_Functions */
+
+/** @} End of DIS_Client */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _DIS_CLIENT_H_ */
diff --git a/inc/bluetooth/profile/client/gaps_client.h b/inc/bluetooth/profile/client/gaps_client.h
new file mode 100644
index 0000000..b3dc3e5
--- /dev/null
+++ b/inc/bluetooth/profile/client/gaps_client.h
@@ -0,0 +1,276 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gaps_client.h
+ * @brief Head file for using GAP service client.
+ * @details GAP service client data structs and external functions declaration.
+ * @author jane
+ * @date 2016-02-18
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _GAPS_CLIENT_H_
+#define _GAPS_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include <profile_client.h>
+
+
+
+/** @defgroup GAPS_Client GAP Service Client
+ * @brief GAP service client
+ * @details
+ Application shall register gaps client when initialization through @ref gaps_add_client function.
+
+ Application can start discovery GAP service through @ref gaps_start_discovery function.
+
+ Application can read GAP service referenced values through @ref gaps_read function.
+ * \code{.c}
+ T_APP_RESULT app_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+ {
+ if (client_id == gaps_client_id)
+ {
+ T_GAPS_CLIENT_CB_DATA *p_gaps_cb_data = (T_GAPS_CLIENT_CB_DATA *)p_data;
+ switch (p_gaps_cb_data->cb_type)
+ {
+ case GAPS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_gaps_cb_data->cb_content.disc_state)
+ {
+ case DISC_GAPS_DONE:
+ ......
+ }
+ }
+ * \endcode
+ * @{
+ */
+
+/** @defgroup GAPS_Client_Exported_Macros GAPS Client Exported Macros
+ * @brief
+ * @{
+ */
+/** @brief Define links number. range: 0-4 */
+#define GAPS_MAX_LINKS 4
+
+/** @brief GAP service UUID */
+#define GATT_UUID_GAP 0x1800
+/** @brief Resolvable private address only characteristic UUID */
+#define GATT_UUID_CHAR_RESOLVABLE_PRIVATE_ADDRESS_ONLY 0x2AC9
+/** End of GAPS_Client_Exported_Macros * @} */
+
+
+/** @defgroup GAPS_Client_Exported_Types GAPS Client Exported Types
+ * @brief
+ * @{
+ */
+/** @brief GAPS client handle type */
+typedef enum
+{
+ HDL_GAPS_SRV_START, //!< start handle of gap service
+ HDL_GAPS_SRV_END, //!< end handle of gap service
+ HDL_GAPS_DEVICE_NAME, //!< device name value handle
+ HDL_GAPS_APPEARANCE, //!< appearance value handle
+ HDL_GAPS_CENTRAL_ADDR_RESOLUTION, //!< central address resolution value handle
+ HDL_GAPS_RESOLVABLE_PRIVATE_ADDR_ONLY,//!< resolvable private address only value handle
+ HDL_GAPS_CACHE_LEN //!< handle cache length
+} T_GAP_CLIENT_HANDLE_TYPE;
+
+
+/** @brief GAPS client discovery state */
+typedef enum
+{
+ DISC_GAPS_IDLE,
+ DISC_GAPS_START,
+ DISC_GAPS_DONE,
+ DISC_GAPS_FAILED
+} T_GAPS_DISC_STATE;
+
+
+/** @brief GAPS client read type */
+typedef enum
+{
+ GAPS_READ_DEVICE_NAME,
+ GAPS_READ_APPEARANCE,
+ GAPS_READ_CENTRAL_ADDR_RESOLUTION,
+} T_GAPS_READ_TYPE;
+
+/** @brief Device name value */
+typedef struct
+{
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_DEVICE_NAME;
+
+/** @brief GAPS client read content */
+typedef union
+{
+ uint16_t appearance;
+ T_DEVICE_NAME device_name;
+ uint8_t central_addr_res;
+} T_GAPS_READ_DATA;
+
+/** @brief GAPS client read data, used to inform app read response data */
+typedef struct
+{
+ T_GAPS_READ_TYPE type;
+ T_GAPS_READ_DATA data;
+ uint16_t cause;
+} T_GAPS_READ_RESULT;
+
+
+/** @brief GAPS client callback type */
+typedef enum
+{
+ GAPS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending.
+ GAPS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server.
+ GAPS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage.
+} T_GAPS_CLIENT_CB_TYPE;
+
+/** @brief GAPS client callback content */
+typedef union
+{
+ T_GAPS_DISC_STATE disc_state;
+ T_GAPS_READ_RESULT read_result;
+} T_GAPS_CLIENT_CB_CONTENT;
+
+
+/** @brief GAPS client callback data */
+typedef struct
+{
+ T_GAPS_CLIENT_CB_TYPE cb_type;
+ T_GAPS_CLIENT_CB_CONTENT cb_content;
+} T_GAPS_CLIENT_CB_DATA;
+
+/** End of GAPS_Client_Exported_Types * @} */
+
+/** @defgroup GPAS_Client_Exported_Functions GAPS Client Exported Functions
+ * @brief
+ * @{
+ */
+/**
+ * @brief Add gap service client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ gaps_client_id = gaps_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID gaps_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num);
+
+/**
+ * @brief Used by application, to start the discovery procedure of GAP service.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_gapdis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = gaps_start_discovery(conn_id);
+ ......
+ }
+ * \endcode
+ */
+bool gaps_start_discovery(uint8_t conn_id);
+
+/**
+ * @brief Used by application, to read data from server by using handles.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_gapread(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAPS_READ_TYPE read_type = (T_GAPS_READ_TYPE)p_parse_value->dw_param[1];
+ bool ret = gaps_read(conn_id, read_type);
+ ......
+ }
+ * \endcode
+ */
+bool gaps_read(uint8_t conn_id, T_GAPS_READ_TYPE read_type);
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in,out] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_gaphdl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t hdl_cache[HDL_GAPS_CACHE_LEN];
+ uint8_t hdl_idx;
+ bool ret = gaps_get_hdl_cache(conn_id, hdl_cache, sizeof(uint16_t) * HDL_GAPS_CACHE_LEN);
+ ......
+ }
+ * \endcode
+ */
+bool gaps_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_discov_services(uint8_t conn_id, bool start)
+ {
+ ......
+ if (app_srvs_table.srv_found_flags & APP_DISCOV_GAPS_FLAG)
+ {
+ gaps_set_hdl_cache(conn_id, app_srvs_table.gaps_hdl_cache, sizeof(uint16_t) * HDL_GAPS_CACHE_LEN);
+ }
+ ......
+ }
+ * \endcode
+ */
+bool gaps_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to check Resolvable Private Address Only Characteristics whether existing.
+ * @param[in] conn_id connection ID.
+ * @param[in,out] p_is_exist whether existing
+ * @retval true success.
+ * @retval false failed.
+ */
+bool gaps_check_resolvable_private_addr_only_char(uint8_t conn_id, bool *p_is_exist);
+
+/** @} End of GAPS_Client_Exported_Functions */
+
+/** @} End of GAPS_Client */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _GAPS_CLIENT_H_ */
diff --git a/inc/bluetooth/profile/client/gatts_client.h b/inc/bluetooth/profile/client/gatts_client.h
new file mode 100644
index 0000000..4a99573
--- /dev/null
+++ b/inc/bluetooth/profile/client/gatts_client.h
@@ -0,0 +1,276 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gatts_client.h
+ * @brief Head file for using GATT service client.
+ * @details GATT service client data structs and external functions declaration.
+ * @author
+ * @date 2019-05-27
+ * @version v0.1
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _GATTS_CLIENT_H_
+#define _GATTS_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include <profile_client.h>
+
+/** @defgroup GATTS_Client GATT Service Client
+ * @brief GATT service client
+ * @details
+ Application shall register gatts client when initialization through @ref gatts_add_client function.
+
+ Application can start discovery GATT service through @ref gatts_start_discovery function.
+
+ * \code{.c}
+ T_APP_RESULT app_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+ {
+ if (client_id == gatts_client_id)
+ {
+ T_GATTS_CLIENT_CB_DATA *p_gatts_cb_data = (T_GATTS_CLIENT_CB_DATA *)p_data;
+ switch (p_gatts_cb_data->cb_type)
+ {
+ case GATTS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_gatts_cb_data->cb_content.disc_state)
+ {
+ case DISC_GATTS_DONE:
+ ......
+ }
+ }
+ * \endcode
+ * @{
+ */
+
+/** @defgroup GATTS_Client_Exported_Macros GATTS Client Exported Macros
+ * @brief
+ * @{
+ */
+/** @brief Define links number. range: 0-4 */
+#define GATTS_MAX_LINKS 4
+
+/** @brief GATT service UUID */
+#define GATT_UUID_GATT 0x1801
+/** End of GATTS_Client_Exported_Macros * @} */
+
+/** @defgroup GATTS_Client_Exported_Types GATTS Client Exported Types
+ * @brief
+ * @{
+ */
+/** @brief GATTS client handle type */
+typedef enum
+{
+ HDL_GATTS_SRV_START, //!< start handle of gap service
+ HDL_GATTS_SRV_END, //!< end handle of gap service
+ HDL_GATTS_SERVICE_CHANGED, //!< service changed handle
+ HDL_GATTS_SERVICE_CHANGED_CCCD, //!< service changed CCCD handle
+ HDL_GATTS_CACHE_LEN, //!< handle cache length
+} T_GATTS_CLIENT_HANDLE_TYPE;
+
+/** @brief GATTS client discovery state */
+typedef enum
+{
+ DISC_GATTS_IDLE,
+ DISC_GATTS_START,
+ DISC_GATTS_DONE,
+ DISC_GATTS_FAILED,
+} T_GATTS_DISC_STATE;
+
+/** @brief Client Supported Features value */
+typedef struct
+{
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_CLIENT_SUPPORTED_FEATURES;
+
+/** @brief GATTS client read content */
+typedef union
+{
+ T_CLIENT_SUPPORTED_FEATURES client_supported_features;
+ uint8_t database_hash[GATTS_DATABASE_HASH_LEN];
+} T_GATTS_READ_DATA;
+
+/** @brief GATTS client write type*/
+typedef enum
+{
+ GATTS_WRITE_SERVICE_CHANGED_IND_ENABLE,
+ GATTS_WRITE_SERVICE_CHANGED_IND_DISABLE,
+ GATTS_WRITE_CLIENT_SUPPORTED_FEATURES,
+} T_GATTS_WRITE_TYPE;
+
+/** @brief GATTS client write result*/
+typedef struct
+{
+ T_GATTS_WRITE_TYPE type;
+ uint16_t cause;
+} T_GATTS_WRITE_RESULT;
+
+/** @brief GATTS client notif/ind receive type*/
+typedef enum
+{
+ GATTS_SERVICE_CHANGED_INDICATE,
+} T_GATTS_NOTIF_IND_TYPE;
+
+/** @brief GATTS client notif/ind receive data */
+typedef struct
+{
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_GATTS_NOTIF_IND_VALUE;
+
+/** @brief GATTS client notif/ind receive content*/
+typedef struct
+{
+ T_GATTS_NOTIF_IND_TYPE type;
+ T_GATTS_NOTIF_IND_VALUE data;
+} T_GATTS_NOTIF_IND_DATA;
+
+/** @brief GATTS client callback type */
+typedef enum
+{
+ GATTS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending.
+ GATTS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail.
+ GATTS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server.
+ GATTS_CLIENT_CB_TYPE_INVALID, //!< Invalid callback type, no practical usage.
+} T_GATTS_CLIENT_CB_TYPE;
+
+/** @brief GATTS client callback content */
+typedef union
+{
+ T_GATTS_DISC_STATE disc_state;
+ T_GATTS_WRITE_RESULT write_result;
+ T_GATTS_NOTIF_IND_DATA notif_ind_data;
+} T_GATTS_CLIENT_CB_CONTENT;
+
+/** @brief GATTS client callback data */
+typedef struct
+{
+ T_GATTS_CLIENT_CB_TYPE cb_type;
+ T_GATTS_CLIENT_CB_CONTENT cb_content;
+} T_GATTS_CLIENT_CB_DATA;
+
+/** End of GATTS_Client_Exported_Types * @} */
+
+/** @defgroup GATTS_Client_Exported_Functions GATTS Client Exported Functions
+ * @brief
+ * @{
+ */
+/**
+ * @brief Add gatts service client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ gatts_client_id = gatts_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID gatts_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num);
+
+/**
+ * @brief Used by application, to start the discovery procedure of GATT service.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_gattsdis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = gatts_start_discovery(conn_id);
+ ......
+ }
+ * \endcode
+ */
+bool gatts_start_discovery(uint8_t conn_id);
+
+/**
+ * @brief Used by application, to set the indication flag of service changed characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] ind value to enable or disable indication.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_srvchgcccd(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ind = p_parse_value->dw_param[1];
+ bool ret;
+ ret = gatts_client_set_service_changed_ind(conn_id, ind);
+ ......
+ }
+ * \endcode
+ */
+bool gatts_client_set_service_changed_ind(uint8_t conn_id, bool ind);
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in,out] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_gattshdl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t hdl_cache[HDL_GATTS_CACHE_LEN];
+ uint8_t hdl_idx;
+ bool ret = gatts_get_hdl_cache(conn_id, hdl_cache, sizeof(uint16_t) * HDL_GATTS_CACHE_LEN);
+ ......
+ }
+ * \endcode
+ */
+bool gatts_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_discov_services(uint8_t conn_id, bool start)
+ {
+ ......
+ if (app_srvs_table.srv_found_flags & APP_DISCOV_GATTS_FLAG)
+ {
+ gatts_set_hdl_cache(conn_id, app_srvs_table.gatts_hdl_cache, sizeof(uint16_t) * HDL_GATTS_CACHE_LEN);
+ }
+ ......
+ }
+ * \endcode
+ */
+bool gatts_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/** @} End of GATTS_Client_Exported_Functions */
+
+/** @} End of GATTS_Client */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _GATTS_CLIENT_H_ */
diff --git a/inc/bluetooth/profile/client/gcs_client.h b/inc/bluetooth/profile/client/gcs_client.h
new file mode 100644
index 0000000..08ac0df
--- /dev/null
+++ b/inc/bluetooth/profile/client/gcs_client.h
@@ -0,0 +1,626 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gcs_client.h
+ * @brief Head file for using General Common Services client.
+ * @details General common services client data structs and external functions declaration.
+ * @author jane
+ * @date 2018-12-13
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _GCS_CLIENT_H_
+#define _GCS_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include <profile_client.h>
+
+/** @defgroup GCS_Client General Common Services Client
+ * @brief GCS service client
+ * @details
+ Application shall register gcs client when initialization through @ref gcs_add_client function.
+ * \code{.c}
+ T_APP_RESULT gcs_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ APP_PRINT_INFO2("gcs_client_callback: client_id %d, conn_id %d",
+ client_id, conn_id);
+ if (client_id == gcs_client_id)
+ {
+ T_GCS_CLIENT_CB_DATA *p_gcs_cb_data = (T_GCS_CLIENT_CB_DATA *)p_data;
+ switch (p_gcs_cb_data->cb_type)
+ {
+ case GCS_CLIENT_CB_TYPE_DISC_RESULT:
+ ......
+ }
+ }
+ * \endcode
+ * @{
+ */
+
+/** @defgroup GCS_Client_Exported_Macros GCS Client Exported Macros
+ * @brief
+ * @{
+ */
+/** @brief Define maximum links number. range: 0-4 */
+#define GCS_MAX_LINKS 4
+
+/** End of GCS_Client_Exported_Macros * @} */
+
+/** @defgroup GCS_Client_Exported_Types GCS Client Exported Types
+ * @brief
+ * @{
+ */
+
+/** @brief Discovery result type.*/
+typedef enum
+{
+ GCS_ALL_PRIMARY_SRV_DISCOV, //!<Response type for gcs_all_primary_srv_discovery
+ GCS_BY_UUID128_SRV_DISCOV, //!<Response type for gcs_by_uuid128_srv_discovery
+ GCS_BY_UUID_SRV_DISCOV, //!<Response type for gcs_by_uuid_srv_discovery
+ GCS_ALL_CHAR_DISCOV, //!<Response type for gcs_all_char_discovery
+ GCS_BY_UUID_CHAR_DISCOV, //!<Response type for gcs_by_uuid_char_discovery
+ GCS_BY_UUID128_CHAR_DISCOV, //!<Response type for gcs_by_uuid128_char_discovery
+ GCS_ALL_CHAR_DESC_DISCOV, //!<Response type for gcs_all_char_descriptor_discovery
+} T_GCS_DISCOV_TYPE;
+
+/** @brief Discovery result element.*/
+typedef union
+{
+ T_GATT_SERVICE_ELEM16 srv_uuid16_disc_data;
+ T_GATT_SERVICE_ELEM128 srv_uuid128_disc_data;
+ T_GATT_SERVICE_BY_UUID_ELEM srv_disc_data;
+ T_GATT_CHARACT_ELEM16 char_uuid16_disc_data;
+ T_GATT_CHARACT_ELEM128 char_uuid128_disc_data;
+ T_GATT_CHARACT_DESC_ELEM16 char_desc_uuid16_disc_data;
+ T_GATT_CHARACT_DESC_ELEM128 char_desc_uuid128_disc_data;
+} T_GCS_DISCOV_RESULT_DATA;
+
+/** @brief GCS discovery table element.*/
+typedef struct
+{
+ T_DISCOVERY_RESULT_TYPE result_type;
+ T_GCS_DISCOV_RESULT_DATA result_data;
+} T_GCS_DISCOV_RESULT;
+
+/** @brief GCS client discovery result */
+typedef struct
+{
+ bool is_success;
+ T_GCS_DISCOV_TYPE discov_type;
+ uint16_t result_num;
+ T_GCS_DISCOV_RESULT *p_result_table;
+} T_GCS_DISCOVERY_RESULT;
+
+/** @brief GCS client read data, used to inform app read response data */
+typedef struct
+{
+ uint16_t cause;
+ uint16_t handle;
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_GCS_READ_RESULT;
+
+/** @brief GCS client write result, used to inform app write response data */
+typedef struct
+{
+ uint16_t cause;
+ uint16_t handle;
+ T_GATT_WRITE_TYPE type;
+} T_GCS_WRITE_RESULT;
+
+/** @brief GCS client notification/indication*/
+typedef struct
+{
+ bool notify;
+ uint16_t handle;
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_GCS_NOTIF_IND;
+
+/** @brief GCS client callback type */
+typedef enum
+{
+ GCS_CLIENT_CB_TYPE_DISC_RESULT, //!< Discovery procedure state, done or pending.
+ GCS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server.
+ GCS_CLIENT_CB_TYPE_WRITE_RESULT,
+ GCS_CLIENT_CB_TYPE_NOTIF_IND,
+ GCS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage.
+} T_GCS_CLIENT_CB_TYPE;
+
+/** @brief GCS client callback content */
+typedef union
+{
+ T_GCS_DISCOVERY_RESULT discov_result;
+ T_GCS_READ_RESULT read_result;
+ T_GCS_WRITE_RESULT write_result;
+ T_GCS_NOTIF_IND notif_ind;
+} T_GCS_CLIENT_CB_CONTENT;
+
+/** @brief GCS client callback data */
+typedef struct
+{
+ T_GCS_CLIENT_CB_TYPE cb_type;
+ T_GCS_CLIENT_CB_CONTENT cb_content;
+} T_GCS_CLIENT_CB_DATA;
+
+/** End of GCS_Client_Exported_Types * @} */
+
+/** @defgroup GCS_Client_Exported_Functions GCS Client Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Send discovery all primary services request.
+ * @param[in] conn_id Connection ID
+ * @retval GAP_CAUSE_SUCCESS Discovery request success.
+ * @retval other Discovery request failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_USER_CMD_PARSE_RESULT cmd_gsrvdis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAP_CAUSE cause = gcs_all_primary_srv_discovery(conn_id);
+
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result)
+ {
+ uint16_t i;
+ T_GCS_DISCOV_RESULT *p_result_table;
+ uint16_t properties;
+ switch (discov_result.discov_type)
+ {
+ case GCS_ALL_PRIMARY_SRV_DISCOV:
+ ......
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gcs_all_primary_srv_discovery(uint8_t conn_id);
+
+/**
+ * @brief Send discovery services by 128 bit UUID request.
+ * @param[in] conn_id Connection ID
+ * @param[in] p_uuid128 128 bit UUID.
+ * @retval GAP_CAUSE_SUCCESS Discovery request success.
+ * @retval other Discovery request failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_USER_CMD_PARSE_RESULT cmd_srvuuid(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ ......
+ cause = gcs_by_uuid128_srv_discovery(conn_id, uuid128);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result)
+ {
+ uint16_t i;
+ T_GCS_DISCOV_RESULT *p_result_table;
+ uint16_t properties;
+ switch (discov_result.discov_type)
+ {
+ case GCS_BY_UUID128_SRV_DISCOV:
+ ......
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gcs_by_uuid128_srv_discovery(uint8_t conn_id, uint8_t *p_uuid128);
+
+/**
+ * @brief Send discovery services by 16 bit UUID request.
+ * @param[in] conn_id Connection ID
+ * @param[in] uuid16 16 bit UUID.
+ * @retval GAP_CAUSE_SUCCESS Discovery request success.
+ * @retval other Discovery request failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_USER_CMD_PARSE_RESULT cmd_srvuuid(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ ......
+ cause = gcs_by_uuid_srv_discovery(conn_id, uuid16);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result)
+ {
+ uint16_t i;
+ T_GCS_DISCOV_RESULT *p_result_table;
+ uint16_t properties;
+ switch (discov_result.discov_type)
+ {
+ case GCS_BY_UUID_SRV_DISCOV:
+ ......
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gcs_by_uuid_srv_discovery(uint8_t conn_id, uint16_t uuid16);
+
+/**
+ * @brief Send discovery characteristics request.
+ * @param[in] conn_id Connection ID
+ * @param[in] start_handle Start handle of range to be searched.
+ * @param[in] end_handle End handle of range to be searched.
+ * @retval GAP_CAUSE_SUCCESS Discovery request success.
+ * @retval other Discovery request failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_USER_CMD_PARSE_RESULT cmd_chardis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t start_handle = p_parse_value->dw_param[1];
+ uint16_t end_handle = p_parse_value->dw_param[2];
+
+ T_GAP_CAUSE cause = gcs_all_char_discovery(conn_id, start_handle, end_handle);
+
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result)
+ {
+ uint16_t i;
+ T_GCS_DISCOV_RESULT *p_result_table;
+ uint16_t properties;
+ switch (discov_result.discov_type)
+ {
+ case GCS_ALL_CHAR_DISCOV:
+ ......
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gcs_all_char_discovery(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle);
+
+/**
+ * @brief Send discovery characteristics request by caracteristic uuid.
+ * @param[in] conn_id Connection ID
+ * @param[in] start_handle Start handle of range to be searched.
+ * @param[in] end_handle End handle of range to be searched.
+ * @param[in] uuid16 16bit characteristic uuid to be searched.
+ * @retval GAP_CAUSE_SUCCESS Discovery request success.
+ * @retval other Discovery request failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_USER_CMD_PARSE_RESULT cmd_charuuid(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ ......
+ T_GAP_CAUSE cause = gcs_by_uuid_char_discovery(conn_id, start_handle, end_handle,
+ uuid16);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result)
+ {
+ uint16_t i;
+ T_GCS_DISCOV_RESULT *p_result_table;
+ uint16_t properties;
+ switch (discov_result.discov_type)
+ {
+ case GCS_BY_UUID_CHAR_DISCOV:
+ ......
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gcs_by_uuid_char_discovery(uint8_t conn_id, uint16_t start_handle,
+ uint16_t end_handle, uint16_t uuid16);
+/**
+ * @brief Send discovery characteristics request by caracteristic uuid.
+ * @param[in] conn_id Connection ID
+ * @param[in] start_handle Start handle of range to be searched.
+ * @param[in] end_handle End handle of range to be searched.
+ * @param[in] p_uuid128 128bit characteristic uuid to be searched.
+ * @retval GAP_CAUSE_SUCCESS Discovery request success.
+ * @retval other Discovery request failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_USER_CMD_PARSE_RESULT cmd_charuuid(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ ......
+ T_GAP_CAUSE cause = gcs_by_uuid128_char_discovery(conn_id, start_handle,
+ end_handle,
+ uuid128);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result)
+ {
+ uint16_t i;
+ T_GCS_DISCOV_RESULT *p_result_table;
+ uint16_t properties;
+ switch (discov_result.discov_type)
+ {
+ case GCS_BY_UUID128_CHAR_DISCOV:
+ ......
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gcs_by_uuid128_char_discovery(uint8_t conn_id, uint16_t start_handle,
+ uint16_t end_handle, uint8_t *p_uuid128);
+/**
+ * @brief Send discovery characteristics descriptor request.
+ * @param[in] conn_id Connection ID
+ * @param[in] start_handle Start handle of range to be searched.
+ * @param[in] end_handle End handle of range to be searched.
+ * @retval GAP_CAUSE_SUCCESS Discovery request success.
+ * @retval other Discovery request failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_USER_CMD_PARSE_RESULT cmd_charddis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t start_handle = p_parse_value->dw_param[1];
+ uint16_t end_handle = p_parse_value->dw_param[2];
+
+ T_GAP_CAUSE cause = gcs_all_char_descriptor_discovery(conn_id, start_handle,
+ end_handle);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result)
+ {
+ uint16_t i;
+ T_GCS_DISCOV_RESULT *p_result_table;
+ uint16_t properties;
+ switch (discov_result.discov_type)
+ {
+ case GCS_ALL_CHAR_DESC_DISCOV:
+ ......
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gcs_all_char_descriptor_discovery(uint8_t conn_id, uint16_t start_handle,
+ uint16_t end_handle);
+/**
+ * @brief Read characteristic by handle request.
+ * @param[in] conn_id Connection ID
+ * @param[in] handle Request handle.
+ * @retval GAP_CAUSE_SUCCESS Read request success.
+ * @retval other Read request failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_USER_CMD_PARSE_RESULT cmd_read(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t handle = p_parse_value->dw_param[1];
+ T_GAP_CAUSE cause = GAP_CAUSE_SUCCESS;
+
+ if (p_parse_value->param_count <= 2)
+ {
+ cause = gcs_attr_read(conn_id, handle);
+ }
+
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ T_APP_RESULT gcs_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ APP_PRINT_INFO2("gcs_client_callback: client_id %d, conn_id %d",
+ client_id, conn_id);
+ if (client_id == gcs_client_id)
+ {
+ T_GCS_CLIENT_CB_DATA *p_gcs_cb_data = (T_GCS_CLIENT_CB_DATA *)p_data;
+ switch (p_gcs_cb_data->cb_type)
+ {
+ case GCS_CLIENT_CB_TYPE_READ_RESULT:
+ APP_PRINT_INFO3("READ RESULT: cause 0x%4x, handle 0x%4x, value_len %d",
+ p_gcs_cb_data->cb_content.read_result.cause,
+ p_gcs_cb_data->cb_content.read_result.handle,
+ p_gcs_cb_data->cb_content.read_result.value_size);
+ APP_PRINT_INFO1("READ VALUE: %b",
+ TRACE_BINARY(p_gcs_cb_data->cb_content.read_result.value_size,
+ p_gcs_cb_data->cb_content.read_result.p_value));
+ break;
+ ......
+ }
+ }
+ return result;
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gcs_attr_read(uint8_t conn_id, uint16_t handle);
+
+/**
+ * @brief Read characteristic by 16 bit UUID request.
+ * @param[in] conn_id Connection ID
+ * @param[in] start_handle Start handle of range to be searched.
+ * @param[in] end_handle End handle of range to be searched.
+ * @param[in] uuid16 Request 16 bit UUID.
+ * @retval GAP_CAUSE_SUCCESS Read request success.
+ * @retval other Read request failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_USER_CMD_PARSE_RESULT cmd_readu(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ ......
+ cause = gcs_attr_read_using_uuid16(conn_id, start_handle, end_handle, uuid16);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ T_APP_RESULT gcs_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ APP_PRINT_INFO2("gcs_client_callback: client_id %d, conn_id %d",
+ client_id, conn_id);
+ if (client_id == gcs_client_id)
+ {
+ T_GCS_CLIENT_CB_DATA *p_gcs_cb_data = (T_GCS_CLIENT_CB_DATA *)p_data;
+ switch (p_gcs_cb_data->cb_type)
+ {
+ case GCS_CLIENT_CB_TYPE_READ_RESULT:
+ APP_PRINT_INFO3("READ RESULT: cause 0x%4x, handle 0x%4x, value_len %d",
+ p_gcs_cb_data->cb_content.read_result.cause,
+ p_gcs_cb_data->cb_content.read_result.handle,
+ p_gcs_cb_data->cb_content.read_result.value_size);
+ APP_PRINT_INFO1("READ VALUE: %b",
+ TRACE_BINARY(p_gcs_cb_data->cb_content.read_result.value_size,
+ p_gcs_cb_data->cb_content.read_result.p_value));
+ break;
+ ......
+ }
+ }
+ return result;
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gcs_attr_read_using_uuid16(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle,
+ uint16_t uuid16);
+/**
+ * @brief Read characteristic by 128 bit UUID request.
+ * @param[in] conn_id Connection ID
+ * @param[in] start_handle Start handle of range to be searched.
+ * @param[in] end_handle End handle of range to be searched.
+ * @param[in] p_uuid128 Request 128 bit UUID.
+ * @retval GAP_CAUSE_SUCCESS Read request success.
+ * @retval other Read request failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_USER_CMD_PARSE_RESULT cmd_readu(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ ......
+ cause = gcs_attr_read_using_uuid128(conn_id, start_handle, end_handle, uuid128);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ T_APP_RESULT gcs_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ APP_PRINT_INFO2("gcs_client_callback: client_id %d, conn_id %d",
+ client_id, conn_id);
+ if (client_id == gcs_client_id)
+ {
+ T_GCS_CLIENT_CB_DATA *p_gcs_cb_data = (T_GCS_CLIENT_CB_DATA *)p_data;
+ switch (p_gcs_cb_data->cb_type)
+ {
+ case GCS_CLIENT_CB_TYPE_READ_RESULT:
+ APP_PRINT_INFO3("READ RESULT: cause 0x%4x, handle 0x%4x, value_len %d",
+ p_gcs_cb_data->cb_content.read_result.cause,
+ p_gcs_cb_data->cb_content.read_result.handle,
+ p_gcs_cb_data->cb_content.read_result.value_size);
+ APP_PRINT_INFO1("READ VALUE: %b",
+ TRACE_BINARY(p_gcs_cb_data->cb_content.read_result.value_size,
+ p_gcs_cb_data->cb_content.read_result.p_value));
+ break;
+ ......
+ }
+ }
+ return result;
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gcs_attr_read_using_uuid128(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle,
+ uint8_t *p_uuid128);
+/**
+ * @brief Confirm from application when receive indication from server.
+ * @param[in] conn_id Connection ID indicate which link is.
+ * @retval GAP_CAUSE_SUCCESS: Success.
+ * @retval other: Failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_USER_CMD_PARSE_RESULT cmd_indconf(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ T_GAP_CAUSE ret;
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ ret = gcs_attr_ind_confirm(conn_id);
+ return (T_USER_CMD_PARSE_RESULT)ret;
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gcs_attr_ind_confirm(uint8_t conn_id);
+
+/**
+ * @brief Write characteristic request.
+ * @param[in] conn_id Connection ID
+ * @param[in] write_type Type of write.
+ * @param[in] handle Attribute handle.
+ * @param[in] length Length of data to be written.
+ If write_type is GATT_WRITE_TYPE_REQ, range of length is from 0 to 512.
+ If write_type is GATT_WRITE_TYPE_CMD, range of length is from 0 to (mtu_size - 3).
+ uint16_t mtu_size is acquired by le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id).
+ * @param[in] p_data Point to the data to be written.
+ * @retval GAP_CAUSE_SUCCESS: Write request success.
+ * @retval other: Write request failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_USER_CMD_PARSE_RESULT cmd_write(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ ......
+
+ T_GAP_CAUSE ret = gcs_attr_write(conn_id, (T_GATT_WRITE_TYPE)write_type, handle,
+ length, data);
+ return (T_USER_CMD_PARSE_RESULT)ret;
+ }
+ T_APP_RESULT gcs_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ APP_PRINT_INFO2("gcs_client_callback: client_id %d, conn_id %d",
+ client_id, conn_id);
+ if (client_id == gcs_client_id)
+ {
+ T_GCS_CLIENT_CB_DATA *p_gcs_cb_data = (T_GCS_CLIENT_CB_DATA *)p_data;
+ switch (p_gcs_cb_data->cb_type)
+ {
+ case GCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ APP_PRINT_INFO3("WRITE RESULT: cause 0x%4x ,handle 0x%4x, type %d",
+ p_gcs_cb_data->cb_content.write_result.cause,
+ p_gcs_cb_data->cb_content.write_result.handle,
+ p_gcs_cb_data->cb_content.write_result.type);
+ break;
+ ......
+ }
+ }
+
+ return result;
+ }
+ * \endcode
+ */
+T_GAP_CAUSE gcs_attr_write(uint8_t conn_id, T_GATT_WRITE_TYPE write_type, uint16_t handle,
+ uint16_t length, uint8_t *p_data);
+
+/**
+ * @brief Add general services client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @param[in] config the discovery table number per link.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ gcs_client_id = gcs_add_client(gcs_client_callback, APP_MAX_LINKS, APP_MAX_DISCOV_TABLE_NUM);
+ }
+ * \endcode
+ */
+T_CLIENT_ID gcs_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num,
+ uint16_t max_discov_table_size);
+
+/** @} End of GCS_Client_Exported_Functions */
+
+/** @} End of GCS_Client */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _GCS_CLIENT_H_ */
diff --git a/inc/bluetooth/profile/client/hids_client.h b/inc/bluetooth/profile/client/hids_client.h
new file mode 100644
index 0000000..f541cb7
--- /dev/null
+++ b/inc/bluetooth/profile/client/hids_client.h
@@ -0,0 +1,355 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hids_client.h
+ * @brief Head file for using hid service client.
+ * @details HID client data structs and external functions declaration.
+ * @author jane
+ * @date 2016-02-18
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _HIDS_CLIENT_H_
+#define _HIDS_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include <profile_client.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+/** @defgroup HIDS_CLIENT HID Service Client
+ * @brief HIDS client
+ * @details
+ Application shall register hid host when initialization through @ref hids_add_client function.
+
+ Application can start discovery battery service through @ref hids_start_discovery function.
+
+ Application shall handle callback function registered by hids_add_client.
+ * \code{.c}
+ T_APP_RESULT app_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ if (client_id == hid_host_id)
+ {
+ T_HIDS_CLIENT_CB_DATA *p_hids_client_cb_data = (T_HIDS_CLIENT_CB_DATA *)p_data;
+ switch (p_hids_client_cb_data->cb_type)
+ {
+ case HIDS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_hids_client_cb_data->cb_content.disc_state)
+ {
+ case DISC_HIDS_DONE:
+ ......
+ }
+ }
+ * \endcode
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @addtogroup HIDS_CLIENT_Exported_Macros HOGP Client Exported Macros
+ * @brief
+ * @{
+ */
+/** @brief Define links number. range: 0-4 */
+#define HIDS_CLIENT_MAX_LINKS 4
+
+/** @brief Define report number. */
+#define HIDS_CLIENT_MAX_REPORT_NUM 10
+
+/** @brief Bit field of HIDS read flag. */
+#define HIDS_READ_HID_INFO_BIT 0x01
+#define HIDS_READ_PROTOCOL_MODE_BIT 0x02
+#define HIDS_READ_REPORT_MAP_BIT 0x04
+#define HIDS_READ_REPORT_REF_BIT 0x08
+
+/** @defgroup HID UUIDs
+ * @brief HID UUID definitions
+ * @{
+ */
+#define GATT_UUID_HID 0x1812
+#define GATT_UUID_CHAR_HID_INFO 0x2A4A
+#define GATT_UUID_CHAR_REPORT_MAP 0x2A4B
+#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C
+#define GATT_UUID_CHAR_REPORT 0x2A4D
+#define GATT_UUID_CHAR_PROTOCOL_MODE 0x2A4E
+
+#define GATT_UUID_CHAR_BOOT_KB_IN_REPORT 0x2A22 // boot keyboard input report
+#define GATT_UUID_CHAR_BOOT_KB_OUT_REPORT 0x2A32 // boot keyboard output report
+#define GATT_UUID_CHAR_BOOT_MS_IN_REPORT 0x2A33 // boot mouse input report
+
+/** @} End of Hid UUIDs */
+
+/** End of HIDS_CLIENT_Exported_Macros
+* @}
+*/
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup HIDS_CLIENT__Exported_Types HOGP Client Exported Types
+ * @brief
+ * @{
+ */
+
+/** @brief HID host handle type*/
+typedef enum
+{
+ HDL_HIDS_SRV_START, //!< start handle of hid service
+ HDL_HIDS_SRV_END, //!< end handle of hid service
+ HDL_HIDS_CHAR_HID_INFO, //!< hid information characteristic value handle
+ HDL_HIDS_CHAR_REPORT_MAP, //!< report map characteristic value handle
+ HDL_HIDS_CHAR_HID_CONTROL_POINT, //!< hid control point characteristic value handle
+ HDL_HIDS_CHAR_PROTOCOL_MODE, //!< protocol mode characteristic value handle
+ HDL_HIDS_CACHE_LEN //!< handle cache length
+} T_HIDS_CLIENT_HANDLE_TYPE;
+
+/** @brief HID host discovery state*/
+typedef enum
+{
+ DISC_HIDS_IDLE,
+ DISC_HIDS_START,
+ DISC_HIDS_DONE,
+ DISC_HIDS_FAILED
+} T_HIDS_CLIENT_DISC_STATE;
+
+/** @brief HID host report type*/
+typedef enum
+{
+ HIDS_RESERVED_REPORT,
+ HIDS_INPUT_REPORT,
+ HIDS_OUTPUT_REPORT,
+ HIDS_FEATURE_REPORT,
+} T_HIDS_REPORT_TYPE;
+
+/** @brief HID host report reference data*/
+typedef struct
+{
+ uint8_t report_id;
+ T_HIDS_REPORT_TYPE report_type;
+} T_HIDS_REPORT_REF_DATA;
+
+/** @brief HID host report*/
+typedef struct
+{
+ uint16_t hdl_report_value;
+ uint16_t hdl_report_cccd;
+ uint16_t hdl_report_reference;
+ T_HIDS_REPORT_REF_DATA report_ref;
+} T_HIDS_CLIENT_REPORT;
+
+
+typedef struct
+{
+ uint8_t CountryCode;
+ uint8_t bFlags;
+ uint16_t BcdHID;
+} HID_INFO_ATTRB;
+
+/** @brief HID host read type*/
+typedef enum
+{
+ HIDS_READ_PROTOCOL_MODE,
+ HIDS_READ_REPORT_MAP,
+ HIDS_READ_HID_INFO,
+} T_HIDS_READ_TYPE;
+
+/** @brief HID host read value */
+typedef struct
+{
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_HIDS_READ_VALUE;
+
+#if 0
+/** @brief HID host read data */
+typedef union
+{
+ T_HIDS_READ_VALUE report_map;
+ T_HIDS_READ_VALUE report_ref;
+} T_HIDS_READ_DATA;
+#endif
+
+/** @brief HID host read result type */
+typedef enum
+{
+ HIDS_READ_RESULT_RESERVED,
+ HIDS_READ_RESULT_REPORT_MAP,
+} T_HIDS_READ_RESULT_TYPE;
+
+/** @brief HID host read result */
+typedef struct
+{
+ T_HIDS_READ_RESULT_TYPE type;
+ uint16_t cause;
+} T_HIDS_CLIENT_READ_RESULT;
+
+/** @brief HID host write type*/
+typedef enum
+{
+ HIDS_WRITE_REPORT,
+ HIDS_WRITE_ALL_REPORT_CCCD,
+ //HIDS_WRITE_PROTOCOL_MODE,//write command
+ //HIDS_WRITE_HID_CONTROL_POINT,//write command
+} T_HIDS_WRITE_TYPE;
+
+typedef struct
+{
+ uint8_t report_id;
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_HIDS_WRITE_REPORT_DATA;
+
+/** @brief HID host write result*/
+typedef struct
+{
+ T_HIDS_WRITE_TYPE type;
+ uint16_t cause;
+ T_HIDS_REPORT_REF_DATA report_ref; //just used for HIDS_WRITE_REPORT
+} T_HIDS_CLIENT_WRITE_RESULT;
+
+/** @brief HID host notification receive type*/
+typedef enum
+{
+ HIDS_REPORT_NOTIFY,
+} T_HIDS_NOTIF_TYPE;
+
+/** @brief HID host notification receive data*/
+typedef struct
+{
+ uint8_t report_id;
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_HIDS_NOTIF_VALUE;
+
+/** @brief HID host notification receive content*/
+typedef struct
+{
+ T_HIDS_NOTIF_TYPE type;
+ T_HIDS_NOTIF_VALUE data;
+} T_HIDS_CLIENT_NOTIF_DATA;
+
+/** @brief HOGP client callback type*/
+typedef enum
+{
+ HIDS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending.
+ HIDS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server.
+ HIDS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail.
+ HIDS_CLIENT_CB_TYPE_NOTIF_RESULT, //!< Notification or indication data received from server.
+ HIDS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage.
+} T_HIDS_CLIENT_CB_TYPE;
+
+/** @brief HOGP client callback content*/
+typedef union
+{
+ T_HIDS_CLIENT_DISC_STATE disc_state;
+ T_HIDS_CLIENT_READ_RESULT read_result;
+ T_HIDS_CLIENT_NOTIF_DATA notify_data;
+ T_HIDS_CLIENT_WRITE_RESULT write_result;
+} T_HIDS_CLIENT_CB_CONTENT;
+
+/** @brief HOGP client callback data*/
+typedef struct
+{
+ T_HIDS_CLIENT_CB_TYPE cb_type;
+ T_HIDS_CLIENT_CB_CONTENT cb_content;
+} T_HIDS_CLIENT_CB_DATA;
+
+/** @brief HID Host storage information block definition. */
+typedef struct
+{
+ uint8_t read_flags;
+ uint8_t protocol_mode;
+ uint8_t report_num;
+ HID_INFO_ATTRB hids_info;
+ uint16_t hdl_cache[HDL_HIDS_CACHE_LEN];
+ T_HIDS_CLIENT_REPORT report[HIDS_CLIENT_MAX_REPORT_NUM];
+} T_HIDS_CLIENT_STORAGE_INFO;
+/** End of HIDS_CLIENT_Exported_Types
+* @}
+*/
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup HIDS_CLIENT_Exported_Functions HOGP Client Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add hid host to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ hids_client_client_id = hids_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID hids_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num);
+
+/**
+ * @brief Used by application, to start the discovery procedure of battery service.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_hidhostdis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = hids_start_discovery(conn_id);
+ ......
+ }
+ * \endcode
+ */
+bool hids_start_discovery(uint8_t conn_id);
+
+bool hids_write_report(uint8_t conn_id, uint8_t report_id, T_HIDS_REPORT_TYPE report_type,
+ uint16_t length, uint8_t *p_value, T_GATT_WRITE_TYPE type);
+
+bool hids_enable_all_cccd(uint8_t conn_id);
+
+bool hids_read_saved_data(uint8_t conn_id, T_HIDS_READ_TYPE read_type, T_HIDS_READ_VALUE *p_value);
+
+bool hids_get_hdl_cache(uint8_t conn_id, T_HIDS_CLIENT_STORAGE_INFO *p_storage_info);
+
+bool hids_set_hdl_cache(uint8_t conn_id, T_HIDS_CLIENT_STORAGE_INFO *p_storage_info);
+
+bool hids_read_report_map(uint8_t conn_id);
+
+bool hids_set_report_map(uint8_t conn_id, uint16_t value_size, uint8_t *p_value);
+
+void hids_print_infos(uint8_t conn_id);
+
+/** @} End of HIDS_CLEINT_Exported_Functions */
+
+/** @} End of HIDS_CLEINT */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _HIDS_CLIENT_H_ */
diff --git a/inc/bluetooth/profile/client/ias_client.h b/inc/bluetooth/profile/client/ias_client.h
new file mode 100644
index 0000000..16a7266
--- /dev/null
+++ b/inc/bluetooth/profile/client/ias_client.h
@@ -0,0 +1,284 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ias_client.h
+ * @brief Head file for using Ias BLE Client.
+ * @details Ias data structs and external functions declaration.
+ * @author ken
+ * @date 2017-12-04
+ * @version v0.1
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _IAS_CLIENT_H_
+#define _IAS_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include <profile_client.h>
+
+
+/** @defgroup IAS_Client Ias service client
+ * @brief ias service client
+ * @details
+ Ias Profile is a customized BLE-based Profile. Ias ble service please refer to @ref IAS_Service .
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup IAS_Client_Exported_Macros IAS Client Exported Macros
+ * @brief
+ * @{
+ */
+/** @defgroup IAS UUIDs
+ * @brief Ias BLE Profile UUID definitions
+ * @{
+ */
+
+#define GATT_UUID_IMMEDIATE_ALERT_SERVICE 0x1802
+#define GATT_UUID_CHAR_ALERT_LEVEL 0x2A06
+
+/** @} End of SIMP_UUIDs */
+
+/** @brief Define links number. range: 0-4 */
+#define IAS_MAX_LINKS 2
+/** End of IAS_Client_Exported_Macros
+ * @}
+ */
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup IAS_Client_Exported_Types IAS Client Exported Types
+ * @brief
+ * @{
+ */
+
+/** @brief IAS client handle type*/
+typedef enum
+{
+ HDL_IAS_SRV_START, //!< start handle of simple ble service
+ HDL_IAS_SRV_END, //!< end handle of simple ble service
+ HDL_IAS_WRITE, //!< V2 write characteristic value handle
+ HDL_IAS_CACHE_LEN //!< handle cache length
+} T_IAS_HANDLE_TYPE;
+
+/** @brief IAS client discovery state*/
+typedef enum
+{
+ DISC_IAS_IDLE,
+ DISC_IAS_START,
+ DISC_IAS_DONE,
+ DISC_IAS_FAILED
+} T_IAS_DISC_STATE;
+
+///** @brief ias client read type*/
+//typedef enum
+//{
+// IAS_READ_V1_READ,
+// IAS_READ_V3_NOTIFY_CCCD,
+// IAS_READ_V4_INDICATE_CCCD,
+//} T_IAS_READ_TYPE;
+
+///** @brief IAS client read value*/
+//typedef struct
+//{
+// uint16_t value_size;
+// uint8_t *p_value;
+//} T_IAS_READ_VALUE;
+
+///** @brief IAS client read data*/
+//typedef union
+//{
+// T_IAS_READ_VALUE v1_read;
+// bool v3_notify_cccd;
+// bool v4_indicate_cccd;
+//} T_IAS_READ_DATA;
+
+///** @brief IAS client read result*/
+//typedef struct
+//{
+// T_IAS_READ_TYPE type;
+// T_IAS_READ_DATA data;
+// uint16_t cause;
+//} T_IAS_READ_RESULT;
+
+
+/** @brief IAS client write type*/
+typedef enum
+{
+ IAS_WRITE_ALERT,
+} T_IAS_WRITE_TYPE;
+
+/** @brief IAS client write result*/
+typedef struct
+{
+ T_IAS_WRITE_TYPE type;
+ uint16_t cause;
+} T_IAS_WRITE_RESULT;
+
+///** @brief IAS client notif/ind receive type*/
+//typedef enum
+//{
+// IAS_V3_NOTIFY,
+// IAS_V4_INDICATE,
+//} T_IAS_NOTIF_IND_TYPE;
+
+///** @brief IAS client notif/ind receive data*/
+//typedef struct
+//{
+// uint16_t value_size;
+// uint8_t *p_value;
+//} T_IAS_NOTIF_IND_VALUE;
+
+///** @brief IAS client notif/ind receive content*/
+//typedef struct
+//{
+// T_IAS_NOTIF_IND_TYPE type;
+// T_IAS_NOTIF_IND_VALUE data;
+//} T_IAS_NOTIF_IND_DATA;
+
+/** @brief IAS client callback type*/
+typedef enum
+{
+ IAS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending.
+ //IAS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server.
+ IAS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail.
+ // IAS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server.
+ IAS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage.
+} T_IAS_CLIENT_CB_TYPE;
+
+/** @brief IAS client callback content*/
+typedef union
+{
+ T_IAS_DISC_STATE disc_state;
+ //T_IAS_READ_RESULT read_result;
+ T_IAS_WRITE_RESULT write_result;
+ //T_IAS_NOTIF_IND_DATA notif_ind_data;
+} T_IAS_CLIENT_CB_CONTENT;
+
+/** @brief IAS client callback data*/
+typedef struct
+{
+ T_IAS_CLIENT_CB_TYPE cb_type;
+ T_IAS_CLIENT_CB_CONTENT cb_content;
+} T_IAS_CLIENT_CB_DATA;
+
+/** End of IAS_Client_Exported_Types * @} */
+
+/** @defgroup IAS_Client_Exported_Functions IAS Client Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Add ias service client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ ias_client_id = ias_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID ias_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num);
+
+/**
+ * @brief Used by application, to start the discovery procedure of ias server.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ias_client_start_discovery(uint8_t conn_id);
+
+/**
+ * @brief Used by application, to read data from server by using handles.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool ias_client_read_by_handle(uint8_t conn_id, T_IAS_READ_TYPE read_type);
+
+/**
+ * @brief Used by application, to read data from server by using UUIDs.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool ias_client_read_by_uuid(uint8_t conn_id, T_IAS_READ_TYPE read_type);
+
+/**
+ * @brief Used by application, to write data of Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] length write data length
+ * @param[in] p_value point the value to write
+ * @param[in] type write type.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ias_client_write_char(uint8_t conn_id, uint16_t length, uint8_t *p_value,
+ T_GATT_WRITE_TYPE type);
+
+/**
+ * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] notify 0--disable the notification, 1--enable the notification.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool simp_ble_client_set_v3_notify(uint8_t conn_id, bool notify);
+
+/**
+ * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] ind 0--disable the indication, 1--enable the indication.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool simp_ble_client_set_v4_ind(uint8_t conn_id, bool ind);
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool ias_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool ias_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/** @} End of IAS_Client_Exported_Functions */
+
+/** @} End of IAS_Client */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _IAS_CLIENT_H_ */
diff --git a/inc/bluetooth/profile/client/ipss_client.h b/inc/bluetooth/profile/client/ipss_client.h
new file mode 100644
index 0000000..3aa5348
--- /dev/null
+++ b/inc/bluetooth/profile/client/ipss_client.h
@@ -0,0 +1,74 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ipss_client.c
+ * @brief Source file for client of internet protocol support service.
+ * @details Global data and function implement.
+ * @author Jeff_Zheng
+ * @date 2017-12-05
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+
+#ifndef _IPSS_CLIENT_H_
+#define _IPSS_CLIENT_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup IPSS_CLIENT Internet Protocol Support Service Client
+ * @brief Internet Protocol Support Service Client
+ * @details
+
+ IPSS client is used to discover Internet Protocol Support Service, this file could be used if application need to find IPSS.
+
+ Application shall register IPSS client when initialization through @ref ipss_add_client function.
+
+ Application can start discovery IPSS service through @ref ipss_find_srv_dcl function.
+
+ * @{
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup IPSS_CLIENT_Exported_Functions Internet Protocol Support Service Client Exported Functions
+ * @brief
+ * @{
+ */
+
+
+/**
+ * @brief add IPS service client.
+ *
+ * @param[in] p_func pointer of app callback function called by client.
+ * @return client id.
+ */
+uint8_t ipss_add_client(void *p_func);
+
+/**
+ * @brief discover IPS service by service uuid .
+ *
+ * @param[in] conn_id connection id.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ */
+bool ipss_find_srv_dcl(uint8_t conn_id);
+
+/** @} End of IPSS_CLIENT_Exported_Functions */
+
+/** @} End of IPSS_CLIENT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/inc/bluetooth/profile/client/kns_client.h b/inc/bluetooth/profile/client/kns_client.h
new file mode 100644
index 0000000..1aae42c
--- /dev/null
+++ b/inc/bluetooth/profile/client/kns_client.h
@@ -0,0 +1,289 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file kns_client.h
+ * @brief Head file for using KNS Client.
+ * @details kns data structs and external functions declaration.
+ * @author ken
+ * @date 2017-12-04
+ * @version v0.1
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _KNS_CLIENT_H_
+#define _KNS_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include <profile_client.h>
+
+
+/** @defgroup KNS_Client Kns service client
+ * @brief kns service client
+ * @details
+ kns Profile is a customized BLE-based Profile. Kns ble service please refer to @ref KNS_Service .
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup KNS_Client_Exported_Macros KNS Client Exported Macros
+ * @brief
+ * @{
+ */
+/** @defgroup KNS UUIDs
+ * @brief Kns BLE Profile UUID definitions
+ * @{
+ */
+//#define GATT_UUID_EXS 0xFFD0
+//#define GATT_UUID_CHAR_PARAM 0xFFD1
+//#define GATT_UUID_CHAR_KEY 0xFFD2
+extern uint8_t GATT_UUID128_KNS_SERVICE[16];
+#define GATT_UUID128_KNS 0xA6, 0xF6, 0xF6, 0x07, 0x4D, 0xC4, 0x9D, 0x98, 0x6D, 0x45, 0x29, 0xBB, 0xD0, 0xFF, 0x00, 0x00,
+#define GATT_UUID128_CHAR_PARAM 0xA6, 0xF6, 0xF6, 0x07, 0x4D, 0xC4, 0x9D, 0x98, 0x6D, 0x45, 0x29, 0xBB, 0xD1, 0xFF, 0x00, 0x00,
+#define GATT_UUID128_CHAR_KEY 0xA6, 0xF6, 0xF6, 0x07, 0x4D, 0xC4, 0x9D, 0x98, 0x6D, 0x45, 0x29, 0xBB, 0xD2, 0xFF, 0x00, 0x00,
+
+/** @} End of KNS_UUIDs */
+
+/** @brief Define links number. range: 0-4 */
+#define KNS_MAX_LINKS 2
+/** End of KNS_Client_Exported_Macros
+ * @}
+ */
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup KNS_Exported_Types KNS Client Exported Types
+ * @brief
+ * @{
+ */
+
+/** @brief KNS client handle type*/
+typedef enum
+{
+ HDL_KNS_SRV_START, //!< start handle of kns service
+ HDL_KNS_SRV_END, //!< end handle of kns service
+ HDL_KNS_PARA, //!< KNS parameter read/write characteristic value handle
+ HDL_KNS_NOTIFY_KEY, //!< key notify characteristic value handle
+ HDL_KNS_NOTIFY_KEY_CCCD, //!< key notify characteristic CCCD handle
+ HDL_KNS_CACHE_LEN //!< handle cache length
+} T_KNS_HANDLE_TYPE;
+
+/** @brief KNS client discovery state*/
+typedef enum
+{
+ DISC_KNS_IDLE,
+ DISC_KNS_START,
+ DISC_KNS_DONE,
+ DISC_KNS_FAILED
+} T_KNS_DISC_STATE;
+
+/** @brief kns client read type*/
+typedef enum
+{
+ KNS_READ_PARAM,
+ KNS_READ_KEY_NOTIFY_CCCD,
+} T_KNS_READ_TYPE;
+
+/** @brief KNS client read value*/
+typedef struct
+{
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_KNS_READ_VALUE;
+
+/** @brief KNS client read data*/
+typedef union
+{
+ T_KNS_READ_VALUE v1_read;
+ bool v3_notify_cccd;
+ bool v4_indicate_cccd;
+} T_KNS_READ_DATA;
+
+/** @brief KNS client read result*/
+typedef struct
+{
+ T_KNS_READ_TYPE type;
+ T_KNS_READ_DATA data;
+ uint16_t cause;
+} T_KNS_READ_RESULT;
+
+
+/** @brief KNS client write type*/
+typedef enum
+{
+ KNS_WRITE_PARAM,
+ KNS_WRITE_KEY_NOTIFY_CCCD,
+} T_KNS_WRITE_TYPE;
+
+/** @brief KNS client write result*/
+typedef struct
+{
+ T_KNS_WRITE_TYPE type;
+ uint16_t cause;
+} T_KNS_WRITE_RESULT;
+
+/** @brief KNS client notif/ind receive type*/
+typedef enum
+{
+ KNS_KEY_NOTIFY,
+} T_KNS_NOTIF_IND_TYPE;
+
+/** @brief KNS client notif/ind receive data*/
+typedef struct
+{
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_KNS_NOTIF_IND_VALUE;
+
+/** @brief KNS client notif/ind receive content*/
+typedef struct
+{
+ T_KNS_NOTIF_IND_TYPE type;
+ T_KNS_NOTIF_IND_VALUE data;
+} T_KNS_NOTIF_IND_DATA;
+
+/** @brief KNS client callback type*/
+typedef enum
+{
+ KNS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending.
+ KNS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server.
+ KNS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail.
+ KNS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server.
+ KNS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage.
+} T_KNS_CLIENT_CB_TYPE;
+
+/** @brief KNS client callback content*/
+typedef union
+{
+ T_KNS_DISC_STATE disc_state;
+ T_KNS_READ_RESULT read_result;
+ T_KNS_WRITE_RESULT write_result;
+ T_KNS_NOTIF_IND_DATA notif_ind_data;
+} T_KNS_CLIENT_CB_CONTENT;
+
+/** @brief KNS client callback data*/
+typedef struct
+{
+ T_KNS_CLIENT_CB_TYPE cb_type;
+ T_KNS_CLIENT_CB_CONTENT cb_content;
+} T_KNS_CLIENT_CB_DATA;
+
+/** End of KNS_Client_Exported_Types * @} */
+
+/** @defgroup KNS_Client_Exported_Functions KNS Client Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Add kns service client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ kns_client_id = kns_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID kns_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num);
+
+/**
+ * @brief Used by application, to start the discovery procedure of ias server.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool kns_client_start_discovery(uint8_t conn_id);
+
+/**
+ * @brief Used by application, to read data from server by using handles.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool kns_client_read_by_handle(uint8_t conn_id, T_KNS_READ_TYPE read_type);
+
+/**
+ * @brief Used by application, to read data from server by using UUIDs.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool kns_client_read_by_uuid(uint8_t conn_id, T_KNS_READ_TYPE read_type);
+
+/**
+ * @brief Used by application, to write data of V2 write Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] length write data length
+ * @param[in] p_value point the value to write
+ * @param[in] type write type.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool kns_client_write_v2_char(uint8_t conn_id, uint16_t length, uint8_t *p_value,
+ T_GATT_WRITE_TYPE type);
+
+/**
+ * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] notify 0--disable the notification, 1--enable the notification.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool kns_client_set_v3_notify(uint8_t conn_id, bool notify);
+
+/**
+ * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] ind 0--disable the indication, 1--enable the indication.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool kns_client_set_v4_ind(uint8_t conn_id, bool ind);
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool kns_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool kns_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/** @} End of KNS_Client_Exported_Functions */
+
+/** @} End of KNS_Client */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _KNS_CLIENT_H_ */
diff --git a/inc/bluetooth/profile/client/lls_client.h b/inc/bluetooth/profile/client/lls_client.h
new file mode 100644
index 0000000..2602706
--- /dev/null
+++ b/inc/bluetooth/profile/client/lls_client.h
@@ -0,0 +1,279 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file lls_client.h
+ * @brief Head file for using LLS Client.
+ * @details lls data structs and external functions declaration.
+ * @author ken
+ * @date 2017-12-05
+ * @version v0.1
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _LLS_CLIENT_H_
+#define _LLS_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include <profile_client.h>
+
+
+/** @defgroup LLS_Client lls service client
+ * @brief lls service client
+ * @details
+ lls Profile is a customized BLE-based Profile. Lls ble service please refer to @ref LLS_Service .
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup LLS_Client_Exported_Macros LLS Client Exported Macros
+ * @brief
+ * @{
+ */
+/** @defgroup LLS UUIDs
+ * @brief Lls BLE Profile UUID definitions
+ * @{
+ */
+#define GATT_UUID_LINK_LOSS_SERVICE 0x1803
+#define GATT_UUID_CHAR_ALERT_LEVEL 0x2A06
+/** @} End of LLS_UUIDs */
+
+/** @brief Define links number. range: 0-4 */
+#define LLS_MAX_LINKS 2
+/** End of LLS_Client_Exported_Macros
+ * @}
+ */
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup LLS_Exported_Types LLS Client Exported Types
+ * @brief
+ * @{
+ */
+
+/** @brief LLS client handle type*/
+typedef enum
+{
+ HDL_LLS_SRV_START, //!< start handle of lls service
+ HDL_LLS_SRV_END, //!< end handle of lls service
+ HDL_LLS_PARA, //!< LLS parameter read/write characteristic value handle
+ HDL_LLS_CACHE_LEN //!< handle cache length
+} T_LLS_HANDLE_TYPE;
+
+/** @brief LLS client discovery state*/
+typedef enum
+{
+ DISC_LLS_IDLE,
+ DISC_LLS_START,
+ DISC_LLS_DONE,
+ DISC_LLS_FAILED
+} T_LLS_DISC_STATE;
+
+/** @brief lls client read type*/
+typedef enum
+{
+ LLS_READ_PARA,
+} T_LLS_READ_TYPE;
+
+/** @brief LLS client read value*/
+typedef struct
+{
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_LLS_READ_VALUE;
+
+/** @brief LLS client read data*/
+typedef union
+{
+ T_LLS_READ_VALUE v1_read;
+// bool v3_notify_cccd;
+// bool v4_indicate_cccd;
+} T_LLS_READ_DATA;
+
+/** @brief LLS client read result*/
+typedef struct
+{
+ T_LLS_READ_TYPE type;
+ T_LLS_READ_DATA data;
+ uint16_t cause;
+} T_LLS_READ_RESULT;
+
+
+/** @brief LLS client write type*/
+typedef enum
+{
+ LLS_WRITE_PARA,
+} T_LLS_WRITE_TYPE;
+
+/** @brief LLS client write result*/
+typedef struct
+{
+ T_LLS_WRITE_TYPE type;
+ uint16_t cause;
+} T_LLS_WRITE_RESULT;
+
+/** @brief LLS client notif/ind receive type*/
+//typedef enum
+//{
+// LLS_KEY_NOTIFY,
+//} T_LLS_NOTIF_IND_TYPE;
+
+///** @brief LLS client notif/ind receive data*/
+//typedef struct
+//{
+// uint16_t value_size;
+// uint8_t *p_value;
+//} T_LLS_NOTIF_IND_VALUE;
+
+/** @brief LLS client notif/ind receive content*/
+//typedef struct
+//{
+// T_LLS_NOTIF_IND_TYPE type;
+// T_LLS_NOTIF_IND_VALUE data;
+//} T_LLS_NOTIF_IND_DATA;
+
+/** @brief LLS client callback type*/
+typedef enum
+{
+ LLS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending.
+ LLS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server.
+ LLS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail.
+ //LLS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server.
+ LLS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage.
+} T_LLS_CLIENT_CB_TYPE;
+
+/** @brief LLS client callback content*/
+typedef union
+{
+ T_LLS_DISC_STATE disc_state;
+ T_LLS_READ_RESULT read_result;
+ T_LLS_WRITE_RESULT write_result;
+ //T_LLS_NOTIF_IND_DATA notif_ind_data;
+} T_LLS_CLIENT_CB_CONTENT;
+
+/** @brief LLS client callback data*/
+typedef struct
+{
+ T_LLS_CLIENT_CB_TYPE cb_type;
+ T_LLS_CLIENT_CB_CONTENT cb_content;
+} T_LLS_CLIENT_CB_DATA;
+
+/** End of LLS_Client_Exported_Types * @} */
+
+/** @defgroup LLS_Client_Exported_Functions LLS Client Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Add lls service client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ lls_client_id = lls_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID lls_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num);
+
+/**
+ * @brief Used by application, to start the discovery procedure of lls server.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool lls_client_start_discovery(uint8_t conn_id);
+
+/**
+ * @brief Used by application, to read data from server by using handles.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool lls_client_read_by_handle(uint8_t conn_id, T_LLS_READ_TYPE read_type);
+
+/**
+ * @brief Used by application, to read data from server by using UUIDs.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool lls_client_read_by_uuid(uint8_t conn_id, T_LLS_READ_TYPE read_type);
+
+/**
+ * @brief Used by application, to write data of write Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] length write data length
+ * @param[in] p_value point the value to write
+ * @param[in] type write type.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool lls_client_write_char(uint8_t conn_id, uint16_t length, uint8_t *p_value,
+ T_GATT_WRITE_TYPE type);
+
+/**
+ * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] notify 0--disable the notification, 1--enable the notification.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool lls_client_set_v3_notify(uint8_t conn_id, bool notify);
+
+/**
+ * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] ind 0--disable the indication, 1--enable the indication.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool lls_client_set_v4_ind(uint8_t conn_id, bool ind);
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool lls_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool lls_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/** @} End of LLS_Client_Exported_Functions */
+
+/** @} End of LLS_Client */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LLS_CLIENT_H_ */
diff --git a/inc/bluetooth/profile/client/ota_client.h b/inc/bluetooth/profile/client/ota_client.h
new file mode 100644
index 0000000..7875887
--- /dev/null
+++ b/inc/bluetooth/profile/client/ota_client.h
@@ -0,0 +1,254 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ota_client.h
+ * @brief Head file for using ota service Client.
+ * @details Data structs and external functions declaration.
+ * @author
+ * @date
+ * @version
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _OTA_CLIENT_H_
+#define _OTA_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Add Includes here */
+#include "profile_client.h"
+#include "dfu_api.h"
+
+/** @defgroup OTA_Client OTA Service Client
+ * @{
+ */
+
+/*============================================================================*
+* Macros
+*============================================================================*/
+/** @addtogroup OTA_Client_Exported_Macros OTA Client Exported Macros
+ * @brief
+ * @{
+ */
+/** @defgroup OTA UUIDs
+ * @brief ota BLE Profile UUID definitions
+ * @{
+ */
+#define GATT_UUID_OTA_SERVICE 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0xFF, 0xD0, 0x00, 0x00
+
+#define GATT_UUID_OTA_PROFILE
+
+#define GATT_UUID_CHAR_OTA 0xFFD1 //1, write
+#define GATT_UUID_CHAR_MAC 0xFFD2 //2
+#define GATT_UUID_CHAR_PATCH 0xFFD3 //3
+#define GATT_UUID_CHAR_APP_VERSION 0xFFD4 //4
+#define GATT_UUID_CHAR_PATCH_EXTENSION 0xFFD5 //5
+#define GATT_UUID_CHAR_TEST_MODE 0xFFD8 //6, write
+
+#define GATT_UUID_CHAR_DEVICE_INFO 0xFFF1 //7
+#define GATT_UUID_CHAR_IMAGE_COUNT_TO_UPDATE 0xFFF2 //8, write
+#define GATT_UUID_CHAR_IMAGE_VERSION 0xFFE0
+/** @} End of OTA_UUIDs */
+
+
+#define OTA_WRITE_OTA_CMD_CHAR_VAL 0x01
+#define OTA_WRITE_TEST_MODE_CHAR_VAL 0x02
+#define OTA_WRITE_OTA_IMG_COUNTER_CHAR_VAL 0x03
+
+
+/** @brief Define links number. range: 0-4 */
+#define OTA_MAX_LINKS 4
+/** End of OTA_Client_Exported_Macros * @} */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup OTA_Client_Exported_Types OTA Client Exported Types
+ * @brief
+ * @{
+ */
+/** @brief OTA client device info*/
+typedef struct _T_OTA_DEVICE_INFO
+{
+ uint8_t ictype;
+ uint8_t ota_version;
+ uint8_t secure_version;
+ T_OTA_MODE ota_mode;
+
+ uint16_t max_buffer_size;
+ uint16_t rsvd;
+
+ uint32_t img_indicator;
+} T_OTA_DEVICE_INFO, *P_OTA_DEVICE_INFO;
+
+/** @brief OTA client handle type*/
+typedef enum
+{
+ HDL_OTA_SRV_START, //!< start handle of battery service
+ HDL_OTA_SRV_END, //!< end handle of battery service
+ HDL_OTA_CMD, //!< OTA CMD characteristic value handle
+ HDL_OTA_DEVICE_MAC,
+ HDL_OTA_PATCH_VER,
+ HDL_OTA_APP_VER,
+ HDL_OTA_PATCH_EXT_VER,
+ HDL_OTA_TEST_MODE, //!< OTA test mode characteristic handle
+ HDL_OTA_DEVICE_INFO,
+ HDL_OTA_IMG_COUNTER, //!<OTA IMAGE COUNT TO UPDATE characteristic handle
+ HDL_OTA_IMG_VER,
+ HDL_OTA_CACHE_LEN //!< handle cache length
+} T_OTA_HANDLE_TYPE;
+
+/** @brief OTA client discovery state*/
+typedef enum
+{
+ DISC_OTA_IDLE,
+ DISC_OTA_START,
+ DISC_OTA_DONE,
+ DISC_OTA_FAILED
+} T_OTA_DISC_STATE;
+
+/** @brief OTA client read type*/
+typedef enum
+{
+ OTA_READ_DEVICE_MAC,
+ OTA_READ_PATCH_VER,
+ OTA_READ_APP_VER,
+ OTA_READ_PATCH_EXT_VER,
+ OTA_READ_DEVICE_INFO,
+ OTA_READ_IMG_VER
+} T_OTA_READ_TYPE;
+
+/** @brief OTA client read data */
+typedef struct
+{
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_OTA_READ_DATA;
+
+/** @brief OTA client read result*/
+typedef struct
+{
+ T_OTA_READ_TYPE type;
+ T_OTA_READ_DATA data;
+ uint16_t cause;
+} T_OTA_READ_RESULT;
+
+/** @brief OTA client write type*/
+typedef enum
+{
+ OTA_WRITE_CMD,
+ OTA_WRITE_TEST_MODE,
+ OTA_WRITE_IMG_COUNTER
+} T_OTA_WRITE_TYPE;
+
+/** @brief OTA client write result*/
+typedef struct
+{
+ T_OTA_WRITE_TYPE type;
+ uint16_t cause;
+} T_OTA_WRITE_RESULT;
+
+/** @brief OTA client callback type*/
+typedef enum
+{
+ OTA_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending.
+ OTA_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server.
+ OTA_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail.
+ OTA_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage.
+} T_OTA_CLIENT_CB_TYPE;
+
+/** @brief OTA client callback content*/
+typedef union
+{
+ T_OTA_DISC_STATE disc_state;
+ T_OTA_READ_RESULT read_result;
+ T_OTA_WRITE_RESULT write_result;
+} T_OTA_CLIENT_CB_CONTENT;
+
+/** @brief OTA client callback data*/
+typedef struct
+{
+ T_OTA_CLIENT_CB_TYPE cb_type;
+ T_OTA_CLIENT_CB_CONTENT cb_content;
+} T_OTA_CLIENT_CB_DATA;
+/** End of OTA_Client_Exported_Types * @} */
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup OTA_Client_Exported_Functions OTA Client Exported Functions
+ * @{
+ */
+/**
+ * @brief Used by application, to read data from server by using handles.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ota_client_read_by_handle(uint8_t conn_id, T_OTA_READ_TYPE read_type);
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool ota_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool ota_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to write ota cmd write Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] length write data length
+ * @param[in] p_value point the value to write
+ * @param[in] type write type.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ota_client_write_char(uint8_t conn_id, T_OTA_WRITE_TYPE write_type);
+
+/**
+ * @brief ota client connect target device.
+ * @param p_le_scan_info: filtered scan info
+ */
+void ota_client_connect_device(T_LE_SCAN_INFO *p_le_scan_info);
+/**
+ * @brief Used by application, to start the discovery procedure of OTA server.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ota_client_start_discovery(uint8_t conn_id);
+
+/**
+ * @brief add OTA client to application.
+ * @param appCB: pointer of app callback function to handle specific client module data.
+ * @retval Client ID of the specific client module.
+ */
+T_CLIENT_ID ota_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num);
+/** @} End of OTA_Client_Exported_Functions */
+
+/** @} End of OTA_Client */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OTA_CLIENT_H_ */
diff --git a/inc/bluetooth/profile/client/simple_ble_client.h b/inc/bluetooth/profile/client/simple_ble_client.h
new file mode 100644
index 0000000..b5271e4
--- /dev/null
+++ b/inc/bluetooth/profile/client/simple_ble_client.h
@@ -0,0 +1,292 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file simple_ble_client.h
+ * @brief Head file for using Simple BLE Client.
+ * @details Simple BLE data structs and external functions declaration.
+ * @author jane
+ * @date 2016-02-18
+ * @version v0.1
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _SIMPLE_BLE_CLIENT_H_
+#define _SIMPLE_BLE_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include <profile_client.h>
+
+
+/** @defgroup SIMP_Client Simple BLE Service Client
+ * @brief Simple BLE service client
+ * @details
+ Simple BLE Profile is a customized BLE-based Profile. Simple ble service please refer to @ref SIMP_Service .
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup SIMP_Client_Exported_Macros SIMP Client Exported Macros
+ * @brief
+ * @{
+ */
+/** @defgroup SIMP_UUIDs SIMP UUIDs
+ * @brief Simple BLE Profile UUID definitions
+ * @{
+ */
+#define GATT_UUID_SIMPLE_PROFILE 0xA00A
+#define GATT_UUID_CHAR_SIMPLE_V1_READ 0xB001
+#define GATT_UUID_CHAR_SIMPLE_V2_WRITE 0xB002
+#define GATT_UUID_CHAR_SIMPLE_V3_NOTIFY 0xB003
+#define GATT_UUID_CHAR_SIMPLE_V4_INDICATE 0xB004
+/** @} End of SIMP_UUIDs */
+
+/** @brief Define links number. range: 0-4 */
+#define SIMP_MAX_LINKS 4
+/** End of SIMP_Client_Exported_Macros
+ * @}
+ */
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup SIMP_Client_Exported_Types SIMP Client Exported Types
+ * @brief
+ * @{
+ */
+
+/** @brief SIMP client handle type*/
+typedef enum
+{
+ HDL_SIMBLE_SRV_START, //!< start handle of simple ble service
+ HDL_SIMBLE_SRV_END, //!< end handle of simple ble service
+ HDL_SIMBLE_V1_READ, //!< V1 read characteristic value handle
+ HDL_SIMBLE_V2_WRITE, //!< V2 write characteristic value handle
+ HDL_SIMBLE_V3_NOTIFY, //!< V3 notify characteristic value handle
+ HDL_SIMBLE_V3_NOTIFY_CCCD, //!< V3 notify characteristic CCCD handle
+ HDL_SIMBLE_V4_INDICATE, //!< V4 indicate characteristic value handle
+ HDL_SIMBLE_V4_INDICATE_CCCD, //!< V4 indicate characteristic CCCD handle
+ HDL_SIMBLE_CACHE_LEN //!< handle cache length
+} T_SIMP_HANDLE_TYPE;
+
+/** @brief SIMP client discovery state*/
+typedef enum
+{
+ DISC_SIMP_IDLE,
+ DISC_SIMP_START,
+ DISC_SIMP_DONE,
+ DISC_SIMP_FAILED
+} T_SIMP_DISC_STATE;
+
+/** @brief SIMP client read type*/
+typedef enum
+{
+ SIMP_READ_V1_READ,
+ SIMP_READ_V3_NOTIFY_CCCD,
+ SIMP_READ_V4_INDICATE_CCCD,
+} T_SIMP_READ_TYPE;
+
+/** @brief SIMP client read value*/
+typedef struct
+{
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_SIMP_READ_VALUE;
+
+/** @brief SIMP client read data*/
+typedef union
+{
+ T_SIMP_READ_VALUE v1_read;
+ bool v3_notify_cccd;
+ bool v4_indicate_cccd;
+} T_SIMP_READ_DATA;
+
+/** @brief SIMP client read result*/
+typedef struct
+{
+ T_SIMP_READ_TYPE type;
+ T_SIMP_READ_DATA data;
+ uint16_t cause;
+} T_SIMP_READ_RESULT;
+
+
+/** @brief SIMP client write type*/
+typedef enum
+{
+ SIMP_WRITE_V2_WRITE,
+ SIMP_WRITE_V3_NOTIFY_CCCD,
+ SIMP_WRITE_V4_INDICATE_CCCD,
+} T_SIMP_WRITE_TYPE;
+
+/** @brief SIMP client write result*/
+typedef struct
+{
+ T_SIMP_WRITE_TYPE type;
+ uint16_t cause;
+} T_SIMP_WRITE_RESULT;
+
+/** @brief SIMP client notif/ind receive type*/
+typedef enum
+{
+ SIMP_V3_NOTIFY,
+ SIMP_V4_INDICATE,
+} T_SIMP_NOTIF_IND_TYPE;
+
+/** @brief SIMP client notif/ind receive data*/
+typedef struct
+{
+ uint16_t value_size;
+ uint8_t *p_value;
+} T_SIMP_NOTIF_IND_VALUE;
+
+/** @brief SIMP client notif/ind receive content*/
+typedef struct
+{
+ T_SIMP_NOTIF_IND_TYPE type;
+ T_SIMP_NOTIF_IND_VALUE data;
+} T_SIMP_NOTIF_IND_DATA;
+
+/** @brief SIMP client callback type*/
+typedef enum
+{
+ SIMP_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending.
+ SIMP_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server.
+ SIMP_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail.
+ SIMP_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server.
+ SIMP_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage.
+} T_SIMP_CLIENT_CB_TYPE;
+
+/** @brief SIMP client callback content*/
+typedef union
+{
+ T_SIMP_DISC_STATE disc_state;
+ T_SIMP_READ_RESULT read_result;
+ T_SIMP_WRITE_RESULT write_result;
+ T_SIMP_NOTIF_IND_DATA notif_ind_data;
+} T_SIMP_CLIENT_CB_CONTENT;
+
+/** @brief SIMP client callback data*/
+typedef struct
+{
+ T_SIMP_CLIENT_CB_TYPE cb_type;
+ T_SIMP_CLIENT_CB_CONTENT cb_content;
+} T_SIMP_CLIENT_CB_DATA;
+
+/** End of SIMP_Client_Exported_Types * @} */
+
+/** @defgroup SIMP_Client_Exported_Functions SIMP Client Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Add simple ble service client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ simple_ble_client_id = simp_ble_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID simp_ble_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num);
+
+/**
+ * @brief Used by application, to start the discovery procedure of Simple BLE server.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool simp_ble_client_start_discovery(uint8_t conn_id);
+
+/**
+ * @brief Used by application, to read data from server by using handles.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool simp_ble_client_read_by_handle(uint8_t conn_id, T_SIMP_READ_TYPE read_type);
+
+/**
+ * @brief Used by application, to read data from server by using UUIDs.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool simp_ble_client_read_by_uuid(uint8_t conn_id, T_SIMP_READ_TYPE read_type);
+
+/**
+ * @brief Used by application, to write data of V2 write Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] length write data length
+ * @param[in] p_value point the value to write
+ * @param[in] type write type.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool simp_ble_client_write_v2_char(uint8_t conn_id, uint16_t length, uint8_t *p_value,
+ T_GATT_WRITE_TYPE type);
+
+/**
+ * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] notify 0--disable the notification, 1--enable the notification.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool simp_ble_client_set_v3_notify(uint8_t conn_id, bool notify);
+
+/**
+ * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] ind 0--disable the indication, 1--enable the indication.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool simp_ble_client_set_v4_ind(uint8_t conn_id, bool ind);
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool simp_ble_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool simp_ble_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/** @} End of SIMP_Client_Exported_Functions */
+
+/** @} End of SIMP_Client */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _SIMPLE_BLE_CLIENT_H_ */
diff --git a/inc/bluetooth/profile/client/tps_client.h b/inc/bluetooth/profile/client/tps_client.h
new file mode 100644
index 0000000..68ec51a
--- /dev/null
+++ b/inc/bluetooth/profile/client/tps_client.h
@@ -0,0 +1,273 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file tps_client.h
+ * @brief Head file for using TPS Client.
+ * @details tps data structs and external functions declaration.
+ * @author ken
+ * @date 2017-12-05
+ * @version v0.1
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _TPS_CLIENT_H_
+#define _TPS_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include <profile_client.h>
+
+
+/** @defgroup TPS_Client tps service client
+ * @brief tps service client
+ * @details
+ tps Profile is a customized BLE-based Profile. Tps ble service please refer to @ref TPS_Service .
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup TPS_Client_Exported_Macros TPS Client Exported Macros
+ * @brief
+ * @{
+ */
+/** @defgroup TPS UUIDs
+ * @brief Tps BLE Profile UUID definitions
+ * @{
+ */
+#define GATT_UUID_TX_POWER_SERVICE 0x1804
+#define GATT_UUID_CHAR_TX_LEVEL 0x2A07
+/** @} End of TPS_UUIDs */
+
+/** @brief Define links number. range: 0-4 */
+#define TPS_MAX_LINKS 2
+/** End of TPS_Client_Exported_Macros
+ * @}
+ */
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup TPS_Exported_Types TPS Client Exported Types
+ * @brief
+ * @{
+ */
+
+/** @brief TPS client handle type*/
+typedef enum
+{
+ HDL_TPS_SRV_START, //!< start handle of tps service
+ HDL_TPS_SRV_END, //!< end handle of tps service
+ HDL_TPS_PARA, //!< TPS parameter read/write characteristic value handle
+ HDL_TPS_CACHE_LEN //!< handle cache length
+} T_TPS_HANDLE_TYPE;
+
+/** @brief TPS client discovery state*/
+typedef enum
+{
+ DISC_TPS_IDLE,
+ DISC_TPS_START,
+ DISC_TPS_DONE,
+ DISC_TPS_FAILED
+} T_TPS_DISC_STATE;
+
+/** @brief tps client read type*/
+typedef enum
+{
+ TPS_READ_PARA,
+} T_TPS_READ_TYPE;
+
+
+/** @brief TPS client read data */
+typedef union
+{
+ uint8_t txpower_level;
+} T_TPS_READ_DATA;
+
+
+/** @brief TPS client read result*/
+typedef struct
+{
+ T_TPS_READ_TYPE type;
+ T_TPS_READ_DATA data;
+ uint16_t cause;
+} T_TPS_READ_RESULT;
+
+/** @brief LLS client write type*/
+//typedef enum
+//{
+// LLS_WRITE_PARA,
+//} T_LLS_WRITE_TYPE;
+
+///** @brief LLS client write result*/
+//typedef struct
+//{
+// T_LLS_WRITE_TYPE type;
+// uint16_t cause;
+//} T_LLS_WRITE_RESULT;
+
+/** @brief LLS client notif/ind receive type*/
+//typedef enum
+//{
+// LLS_KEY_NOTIFY,
+//} T_LLS_NOTIF_IND_TYPE;
+
+///** @brief LLS client notif/ind receive data*/
+//typedef struct
+//{
+// uint16_t value_size;
+// uint8_t *p_value;
+//} T_LLS_NOTIF_IND_VALUE;
+
+/** @brief LLS client notif/ind receive content*/
+//typedef struct
+//{
+// T_LLS_NOTIF_IND_TYPE type;
+// T_LLS_NOTIF_IND_VALUE data;
+//} T_LLS_NOTIF_IND_DATA;
+
+/** @brief TPS client callback type*/
+typedef enum
+{
+ TPS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending.
+ TPS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server.
+ //LLS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail.
+ //LLS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server.
+ TPS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage.
+} T_TPS_CLIENT_CB_TYPE;
+
+/** @brief TPS client callback content*/
+typedef union
+{
+ T_TPS_DISC_STATE disc_state;
+ T_TPS_READ_RESULT read_result;
+ //T_TPS_WRITE_RESULT write_result;
+ //T_LLS_NOTIF_IND_DATA notif_ind_data;
+} T_TPS_CLIENT_CB_CONTENT;
+
+/** @brief TPS client callback data*/
+typedef struct
+{
+ T_TPS_CLIENT_CB_TYPE cb_type;
+ T_TPS_CLIENT_CB_CONTENT cb_content;
+} T_TPS_CLIENT_CB_DATA;
+
+/** End of TPS_Client_Exported_Types * @} */
+
+/** @defgroup TPS_Client_Exported_Functions TPS Client Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Add tps service client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ tps_client_id = tps_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID tps_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num);
+
+/**
+ * @brief Used by application, to start the discovery procedure of ias server.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool tps_start_discovery(uint8_t conn_id);
+
+/**
+ * @brief Used by application, to read power level from server.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool tps_read_power_level(uint8_t conn_id);
+
+
+//bool tps_client_read_by_handle(uint8_t conn_id, T_TPS_READ_TYPE read_type);
+
+///**
+// * @brief Used by application, to read data from server by using UUIDs.
+// * @param[in] conn_id connection ID.
+// * @param[in] read_type one of characteristic that has the readable property.
+// * @retval true send request to upper stack success.
+// * @retval false send request to upper stack failed.
+// */
+//bool tps_client_read_by_uuid(uint8_t conn_id, T_TPS_READ_TYPE read_type);
+
+/**
+ * @brief Used by application, to write data of write Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] length write data length
+ * @param[in] p_value point the value to write
+ * @param[in] type write type.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool tps_client_write_char(uint8_t conn_id, uint16_t length, uint8_t *p_value,
+// T_GATT_WRITE_TYPE type);
+
+/**
+ * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] notify 0--disable the notification, 1--enable the notification.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool lls_client_set_v3_notify(uint8_t conn_id, bool notify);
+
+/**
+ * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] ind 0--disable the indication, 1--enable the indication.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool lls_client_set_v4_ind(uint8_t conn_id, bool ind);
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool tps_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool tps_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len);
+
+/** @} End of LLS_Client_Exported_Functions */
+
+/** @} End of LLS_Client */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _KNS_CLIENT_H_ */
diff --git a/inc/bluetooth/profile/gatt.h b/inc/bluetooth/profile/gatt.h
new file mode 100644
index 0000000..d250150
--- /dev/null
+++ b/inc/bluetooth/profile/gatt.h
@@ -0,0 +1,275 @@
+#ifndef _GATT_H_
+#define _GATT_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*============================================================================*
+* Macros
+*============================================================================*/
+
+/**
+
+ * \addtogroup GATT_SERVER_API GATT Server API
+ *
+ * \defgroup GATT_ATTRIBUTE GATT Attribute
+ *
+ * \brief GATT Attribute Definitions
+ *
+ * \ingroup GATT_SERVER_API
+ */
+
+/**
+ * gatt.h
+ *
+ * \name GATT_DECLARATIONS_UUID
+ * \brief GATT declarations uuid.
+ * \anchor GATT_DECLARATIONS_UUID
+ */
+/**
+ * \ingroup GATT_ATTRIBUTE
+ */
+#define GATT_UUID_PRIMARY_SERVICE 0x2800 /**< GATT Primary Service Declaration. */
+#define GATT_UUID_SECONDARY_SERVICE 0x2801 /**< GATT Secondary Service Declaration. */
+#define GATT_UUID_INCLUDE 0x2802 /**< GATT Include Declaration. */
+#define GATT_UUID_CHARACTERISTIC 0x2803 /**< GATT Characteristic Declaration. */
+
+/**
+ * gatt.h
+ *
+ * \name GATT_DESCRIPTORS_UUID
+ * \brief GATT descriptors uuid.
+ * \anchor GATT_DESCRIPTORS_UUID
+ */
+/**
+ * \ingroup GATT_ATTRIBUTE
+ */
+#define GATT_UUID_CHAR_EXTENDED_PROP 0x2900 /**< Characteristic Extended Properties. */
+#define GATT_UUID_CHAR_USER_DESCR 0x2901 /**< Characteristic User Description. */
+#define GATT_UUID_CHAR_CLIENT_CONFIG 0x2902 /**< Client Characteristic Configuration. */
+#define GATT_UUID_CHAR_SERVER_CONFIG 0x2903 /**< Server Characteristic Configuration. */
+#define GATT_UUID_CHAR_FORMAT 0x2904 /**< Characteristic Presentation Format. */
+#define GATT_UUID_CHAR_AGGR_FORMAT 0x2905 /**< Characteristic Aggregate Format. */
+#define GATT_UUID_CHAR_VALID_RANGE 0x2906 /**< Valid Range. */
+#define GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE 0x2907 /**< External Report Reference. */
+#define GATT_UUID_CHAR_REPORT_REFERENCE 0x2908 /**< Report Reference. */
+#define GATT_UUID_CHAR_DESCRIPTOR_NUM_OF_DIGITALS 0x2909 /**< Number of Digitals. */
+#define GATT_UUID_CHAR_DESCRIPTOR_VALUE_TRIGGER_SETTING 0x290A /**< Value Trigger Setting. */
+#define GATT_UUID_CHAR_SENSING_CONFIGURATION 0x290B /**< Environmental Sensing Configuration. */
+#define GATT_UUID_CHAR_SENSING_MEASUREMENT 0x290C /**< Environmental Sensing Measurement. */
+#define GATT_UUID_CHAR_SENSING_TRIGGER_SETTING 0x290D /**< Environmental Sensing Trigger Setting. */
+#define GATT_UUID_CHAR_DESCRIPTOR_TIME_TRIGGER_SETTING 0x290E /**< Time Trigger Setting. */
+
+/**
+ * gatt.h
+ *
+ * \name GATT_CHARACTERISTICS_UUID
+ * \brief GATT characteristics uuid.
+ * \anchor GATT_CHARACTERISTICS_UUID
+ */
+/**
+ * \ingroup GATT_ATTRIBUTE
+ */
+#define GATT_UUID_CHAR_DEVICE_NAME 0x2A00 /**< Device Name. */
+#define GATT_UUID_CHAR_APPEARANCE 0x2A01 /**< Appearance. */
+#define GATT_UUID_CHAR_PER_PRIV_FLAG 0x2A02 /**< Peripheral Privacy Flag. */
+#define GATT_UUID_CHAR_RECONN_ADDRESS 0x2A03 /**< Reconnection Address. */
+#define GATT_UUID_CHAR_PER_PREF_CONN_PARAM 0x2A04 /**< Peripheral Preferred Connection Parameters. */
+#define GATT_UUID_CHAR_SERVICE_CHANGED 0x2A05 /**< Service Changed. */
+#define GATT_UUID_CHAR_CENTRAL_ADDRESS_RESOLUTION 0x2AA6 /**< Central Address Resolution. */
+#define GATT_UUID_CHAR_RESOLVABLE_PRIVATE_ADDRESS_ONLY 0x2AC9 /**< Resolvable Private Address Only. */
+#define GATT_UUID_CHAR_CLIENT_SUPPORTED_FEATURES 0x2B29 /**< Client Supported Features. */
+#define GATT_UUID_CHAR_DATABASE_HASH 0x2B2A /**< Database Hash. */
+
+/** @brief GATT Service Client Supported Features length. variable length, 1 is used in Core Spec v5.2. */
+#define GATTS_CLIENT_SUPPORTED_FEATURES_LEN 1
+
+/** @brief GATT Service Database Hash length. */
+#define GATTS_DATABASE_HASH_LEN 16
+
+/**
+ * gatt.h
+ *
+ * \name GATT_SERVICE_UUID
+ * \brief GATT services uuid.
+ * \anchor GATT_SERVICE_UUID
+ */
+/**
+ * \ingroup GATT_ATTRIBUTE
+ */
+#define GATT_UUID_GAP 0x1800 /**< Generic Access. */
+#define GATT_UUID_GATT 0x1801 /**< Generic Attribute. */
+
+/**
+ * gatt.h
+ *
+ * \name GATT_ATTRIBUTE_PERMISSIONS
+ * \brief Attribute read/write permissions, encryption key size.
+ * \anchor GATT_ATTRIBUTE_PERMISSIONS
+ */
+/**
+ * \ingroup GATT_ATTRIBUTE
+ */
+#define GATT_PERM_NONE 0x00
+#define GATT_PERM_ALL 0x01 /**< bits 0..1 (rd), 4..5 (wr), 8..9 (notif/ind) */
+#define GATT_PERM_AUTHEN_REQ 0x02
+#define GATT_PERM_AUTHEN_MITM_REQ 0x03
+#define GATT_PERM_AUTHOR_REQ 0x04 /**< bits 2 (rd), 6 (wr), 10 (notif/ind) */
+#define GATT_PERM_ENCRYPTED_REQ 0x08 /**< bits 3 (rd), 7 (wr), 11 (notif/ind) */
+#define GATT_PERM_AUTHEN_SC_REQ 0x00010000
+
+/** @brief read (bits 0..3) */
+#define GATT_PERM_READ GATT_PERM_ALL
+#define GATT_PERM_READ_AUTHEN_REQ GATT_PERM_AUTHEN_REQ
+#define GATT_PERM_READ_AUTHEN_MITM_REQ GATT_PERM_AUTHEN_MITM_REQ
+#define GATT_PERM_READ_AUTHOR_REQ GATT_PERM_AUTHOR_REQ
+#define GATT_PERM_READ_ENCRYPTED_REQ GATT_PERM_ENCRYPTED_REQ
+#define GATT_PERM_READ_AUTHEN_SC_REQ GATT_PERM_AUTHEN_SC_REQ
+
+#define GATT_PERM_READ_AUTHEN_GET(x) (x & 0x03)
+#define GATT_PERM_READ_AUTHOR_GET(x) (x & 0x04)
+#define GATT_PERM_READ_ENCRYPT_GET(x) (x & 0x08)
+#define GATT_PERM_READ_AUTHEN_SC_GET(x) (x & 0x00010000)
+
+/** @brief write (bits 4..7) */
+#define GATT_PERM_WRITE (GATT_PERM_ALL << 4)
+#define GATT_PERM_WRITE_AUTHEN_REQ (GATT_PERM_AUTHEN_REQ << 4)
+#define GATT_PERM_WRITE_AUTHEN_MITM_REQ (GATT_PERM_AUTHEN_MITM_REQ << 4)
+#define GATT_PERM_WRITE_AUTHOR_REQ (GATT_PERM_AUTHOR_REQ << 4)
+#define GATT_PERM_WRITE_ENCRYPTED_REQ (GATT_PERM_ENCRYPTED_REQ << 4)
+#define GATT_PERM_WRITE_AUTHEN_SC_REQ (GATT_PERM_AUTHEN_SC_REQ<<4)
+
+#define GATT_PERM_WRITE_AUTHEN_GET(x) ((x >> 4) & 0x03)
+#define GATT_PERM_WRITE_AUTHOR_GET(x) ((x >> 4) & 0x04)
+#define GATT_PERM_WRITE_ENCRYPT_GET(x) ((x >> 4) & 0x08)
+#define GATT_PERM_WRITE_AUTHEN_SC_GET(x) ((x>>4) & 0x00010000)
+
+/** @brief notification/indication (bits 8..11) */
+#define GATT_PERM_NOTIF_IND (GATT_PERM_ALL << 8)
+#define GATT_PERM_NOTIF_IND_AUTHEN_REQ (GATT_PERM_AUTHEN_REQ << 8)
+#define GATT_PERM_NOTIF_IND_AUTHEN_MITM_REQ (GATT_PERM_AUTHEN_MITM_REQ << 8)
+#define GATT_PERM_NOTIF_IND_AUTHOR_REQ (GATT_PERM_AUTHOR_REQ << 8)
+#define GATT_PERM_NOTIF_IND_ENCRYPTED_REQ (GATT_PERM_ENCRYPTED_REQ << 8)
+#define GATT_PERM_NOTIF_IND_AUTHEN_SC_REQ (GATT_PERM_AUTHEN_SC_REQ<<8)
+
+#define GATT_PERM_NOTIF_IND_AUTHEN_GET(x) ((x >> 8) & 0x03)
+#define GATT_PERM_NOTIF_IND_AUTHOR_GET(x) ((x >> 8) & 0x04)
+#define GATT_PERM_NOTIF_IND_ENCRYPT_GET(x) ((x >> 8) & 0x08)
+#define GATT_PERM_NOTIF_IND_AUTHEN_SC_GET(x) ((x>>8) & 0x00010000)
+
+/** @brief key size - 1 (bits 12..15) */
+#define GATT_PERM_KEYSIZE(size) ((size-1) << 12)
+#define GATT_PERM_KEYSIZE_GET(x, size) { \
+ size = ((x >> 12) & 0x0F); \
+ if ( size > 0 ) \
+ size++; \
+ }
+
+/**
+ * gatt.h
+ *
+ * \name GATT_CHARACTERISTIC_PROPERTIES
+ * \brief GATT characteristic properties.
+ * \anchor GATT_CHARACTERISTIC_PROPERTIES
+ */
+/**
+ * \ingroup GATT_ATTRIBUTE
+ */
+#define GATT_CHAR_PROP_BROADCAST 0x01 /**< If set, permits broadcasts of the Characteristic Value using
+Server Characteristic Configuration Descriptor. */
+#define GATT_CHAR_PROP_READ 0x02 /**< If set, permits reads of the Characteristic Value */
+#define GATT_CHAR_PROP_WRITE_NO_RSP 0x04 /**< If set, permit writes of the Characteristic Value without response */
+#define GATT_CHAR_PROP_WRITE 0x08 /**< If set, permits writes of the Characteristic Value with response */
+#define GATT_CHAR_PROP_NOTIFY 0x10 /**< If set, permits notifications of a Characteristic Value without acknowledgment */
+#define GATT_CHAR_PROP_INDICATE 0x20 /**< If set, permits indications of a Characteristic Value with acknowledgment */
+#define GATT_CHAR_PROP_WRITE_AUTHEN_SIGNED 0x40 /**< If set, permits signed writes to the Characteristic Value */
+#define GATT_CHAR_PROP_EXT_PROP 0x80 /**< If set, additional characteristic properties are defined in the Characteristic
+Extended Properties Descriptor */
+
+/** @brief GATT client characteristic configuration bit field */
+#define GATT_CLIENT_CHAR_CONFIG_DEFAULT 0x0000 /**< The Characteristic Value shall be neither indicated nor notified. */
+#define GATT_CLIENT_CHAR_CONFIG_NOTIFY 0x0001 /**< The Characteristic Value shall be notified. */
+#define GATT_CLIENT_CHAR_CONFIG_INDICATE 0x0002 /**< The Characteristic Value shall be indicated. */
+#define GATT_CLIENT_CHAR_CONFIG_NOTIFY_INDICATE 0x0003 /**< The Characteristic Value shall be both indicated and notified. */
+
+#define GATT_CLIENT_CHAR_NOTIF_IND_DATA_PENGDING 0x8000
+
+/** @brief GATT server characteristic configuration bit field */
+#define GATT_SERVER_CHAR_CONFIG_BROADCAST 0x0001 /**< The Characteristic Value shall be broadcast. */
+
+
+/**
+ * gatt.h
+ *
+ * \name GATT_UUID_SIZE
+ * \brief GATT uuid size.
+ * \anchor GATT_UUID_SIZE
+ */
+/**
+ * \ingroup GATT_ATTRIBUTE
+ */
+#define UUID_16BIT_SIZE 2 /**< 16 bits UUID size. */
+#define UUID_128BIT_SIZE 16 /**< 128 bits UUID size. */
+
+#define ATT_ATTRIBUTE_MAX_LENGTH 512 /**< Attribute Max length. */
+
+#define HI_WORD(x) ((uint8_t)((x & 0xFF00) >> 8))
+#define LO_WORD(x) ((uint8_t)(x))
+
+
+/*---------------------------------------------------------------------------
+ * GATT server attribute descriptor
+ *--------------------------------------------------------------------------*/
+
+/**
+ * gatt.h
+ *
+ * \name GATT_ATTRIBUTE_FLAG
+ * \brief GATT attribute flag.
+ * \anchor GATT_ATTRIBUTE_FLAG
+ */
+/**
+ * \ingroup GATT_ATTRIBUTE
+ */
+#define ATTRIB_FLAG_VOID 0x0000 /**< Attribute value neither supplied by application
+nor included following 16bit UUID. Attribute value is pointed by p_value_context
+and value_len shall be set to the length of attribute value. */
+#define ATTRIB_FLAG_UUID_128BIT 0x0001 /**< Attribute uses 128 bit UUID */
+#define ATTRIB_FLAG_VALUE_INCL 0x0002 /**< Attribute value is included following 16 bit UUID */
+#define ATTRIB_FLAG_VALUE_APPL 0x0004 /**< Application has to supply write value */
+#define ATTRIB_FLAG_ASCII_Z 0x0008 /**< Attribute value is ASCII_Z string */
+#define ATTRIB_FLAG_CCCD_APPL 0x0010 /**< Application will be informed about CCCD value is changed */
+#define ATTRIB_FLAG_CCCD_NO_FILTER 0x0020 /**< Application will be informed about CCCD value
+when CCCD is write by client, no matter it is changed or not */
+#define ATTRIB_FLAG_INCLUDE_MULTI 0x0040
+#define ATTRIB_FLAG_LE 0x0800 /**< Used only for primary service declaration attributes if GATT over BLE is supported */
+
+/**
+ * gatt.h
+ *
+ * \name GATT_ATTRIBUTE_APPL
+ * \brief GATT attribute definition.
+ * \anchor GATT_ATTRIBUTE_APPL
+ */
+/**
+ * \ingroup GATT_ATTRIBUTE
+ */
+typedef struct
+{
+ uint16_t flags; /**< Attribute flags @ref GATT_ATTRIBUTE_FLAG */
+ uint8_t type_value[2 + 14]; /**< 16 bit UUID + included value or 128 bit UUID */
+ uint16_t value_len; /**< Length of value */
+ void *p_value_context; /**< Pointer to value if @ref ATTRIB_FLAG_VALUE_INCL
+ and @ref ATTRIB_FLAG_VALUE_APPL not set */
+ uint32_t permissions; /**< Attribute permission @ref GATT_ATTRIBUTE_PERMISSIONS */
+} T_ATTRIB_APPL;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GATT_H_ */
diff --git a/inc/bluetooth/profile/gatt_builtin_services.h b/inc/bluetooth/profile/gatt_builtin_services.h
new file mode 100644
index 0000000..28130e3
--- /dev/null
+++ b/inc/bluetooth/profile/gatt_builtin_services.h
@@ -0,0 +1,276 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gatt_builtin_services.h
+ * @brief Head file for using builtin services, including GAP service and GATT service.
+ * @details GAPS data structs and external functions declaration.
+ * @author jane
+ * @date 2015-5-12
+ * @version v0.1
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _BUILTIN_SERVICES_H_
+#define _BUILTIN_SERVICES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "upperstack_config.h"
+#include "profile_server.h"
+
+/** @defgroup GAP_GATT_SERVICE GAP and GATT Inbox Services
+ * @brief GAP and GATT inbox services
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GAP_GATT_SERVICE_Exported_Macros GAP and GATT Service Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @defgroup GAPS_Write_PROPERTY GAP Service Write Property
+ * @brief GAP service write property.
+ * @{
+ */
+#define GAPS_PROPERTY_WRITE_DISABLE 0
+#define GAPS_PROPERTY_WRITE_ENABLE 1
+/** @} */
+
+
+/** @defgroup GAPS_WRITE_TYPE GAP and GATT Service Write Type
+ * @brief GAP and GATT Service Write Type.
+ * @{
+ */
+#define GAPS_WRITE_DEVICE_NAME 1
+#define GAPS_WRITE_APPEARANCE 2
+#define GATT_SERVICE_CHANGE_CCCD_ENABLE 3
+#define GATT_SERVICE_CHANGE_CCCD_DISABLE 4
+#define GATT_SERVICE_WRITE_CLIENT_SUPPORTED_FEATURES 5
+/** @} */
+
+/** @brief GATT Service Client Supported Features bit field. */
+#define GATTS_CLIENT_SUPPORTED_FEAUTRES_DEFAULT_VALUE 0x00 /**< Server shall not use any of the features associated with that bit when communicating with this client. */
+#define GATTS_CLIENT_SUPPORTED_FEAUTRES_ROBUST_CACHING_BIT 0x01 /**< The client supports robust caching. */
+#define GATTS_CLIENT_SUPPORTED_FEAUTRES_EATT_BEARER_BIT 0x02 /**< The client supports Enhanced ATT bearer. */
+#define GATTS_CLIENT_SUPPORTED_FEAUTRES_MULTI_NOTIF_BIT 0x04 /**< The client supports receiving ATT_MULTIPLE_HANDLE_VALUE_NTF PDUs. */
+
+/** End of GAP_GATT_SERVICE_Exported_Macros
+* @}
+*/
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_GATT_SERVICE_Exported_Types GAP and GATT Service Exported Types
+ * @brief
+ * @{
+ */
+
+/** @brief GAPS parameter type */
+typedef enum
+{
+ GAPS_PARAM_DEVICE_NAME = 0x00,
+ GAPS_PARAM_APPEARANCE = 0x01,
+#if F_BT_LE_PRIVACY_SUPPORT
+ GAPS_PARAM_CENTRAL_ADDRESS_RESOLUTION = 0x02,
+#endif
+ GAPS_PARAM_DEVICE_NAME_PROPERTY = 0x03,
+ GAPS_PARAM_APPEARANCE_PROPERTY = 0x04,
+} T_GAPS_PARAM_TYPE;
+
+/** @brief Builtin services data struct for notification data to application. */
+typedef struct
+{
+ uint8_t opcode; //!< ref: @ref GAPS_WRITE_TYPE
+ uint16_t len;
+ uint8_t *p_value;
+} T_GAPS_UPSTREAM_MSG_DATA;
+
+/** @brief Builtin services callback data to inform application */
+typedef struct
+{
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ uint8_t conn_id;
+ T_GAPS_UPSTREAM_MSG_DATA msg_data;
+} T_GAPS_CALLBACK_DATA;
+
+/** End of GAP_GATT_SERVICE_Exported_Types
+* @}
+*/
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup GAP_GATT_SERVICE_Exported_Functions GAP and GATT Service Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Register callback to builtin services.
+ *
+ * @param[in] p_func Callback to notify app.
+ * @return none.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t appearance_prop = GAPS_PROPERTY_WRITE_ENABLE;
+ uint8_t device_name_prop = GAPS_PROPERTY_WRITE_ENABLE;
+ gaps_set_parameter(GAPS_PARAM_APPEARANCE_PROPERTY, sizeof(appearance_prop), &appearance_prop);
+ gaps_set_parameter(GAPS_PARAM_DEVICE_NAME_PROPERTY, sizeof(device_name_prop), &device_name_prop);
+ gatt_register_callback(gap_service_callback);
+ }
+ T_APP_RESULT gap_service_callback(T_SERVER_ID service_id, void *p_para)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_GAPS_CALLBACK_DATA *p_gap_data = (T_GAPS_CALLBACK_DATA *)p_para;
+ APP_PRINT_INFO2("gap_service_callback conn_id = %d msg_type = %d\n", p_gap_data->conn_id,
+ p_gap_data->msg_type);
+ if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE)
+ {
+ switch (p_gap_data->msg_data.opcode)
+ {
+ case GAPS_WRITE_DEVICE_NAME:
+ {
+ T_LOCAL_NAME device_name;
+ memcpy(device_name.local_name, p_gap_data->msg_data.p_value, p_gap_data->msg_data.len);
+ device_name.local_name[p_gap_data->msg_data.len] = 0;
+ flash_save_local_name(&device_name);
+ }
+ break;
+
+ case GAPS_WRITE_APPEARANCE:
+ {
+ uint16_t appearance_val;
+ T_LOCAL_APPEARANCE appearance;
+
+ LE_ARRAY_TO_UINT16(appearance_val, p_gap_data->msg_data.p_value);
+ appearance.local_appearance = appearance_val;
+ flash_save_local_appearance(&appearance);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION)
+ {
+ if (p_gap_data->msg_data.opcode == GATT_SERVICE_CHANGE_CCCD_ENABLE)
+ {
+ APP_PRINT_INFO0("GATT_SERVICE_CHANGE_CCCD_ENABLE");
+ }
+ }
+ return result;
+ }
+ * \endcode
+ */
+void gatt_register_callback(void *p_func);
+
+/**
+ * @brief Set GAP service parameter.
+ *
+ * @param[in] param_type parameter type to set: @ref T_GAPS_PARAM_TYPE
+ * @param[in] length value length to be set.
+ * @param[in] p_value value to set.
+ * @return parameter set result.
+ * @retval 0 false
+ * @retval 1 true
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t appearance_prop = GAPS_PROPERTY_WRITE_ENABLE;
+ uint8_t device_name_prop = GAPS_PROPERTY_WRITE_ENABLE;
+ gaps_set_parameter(GAPS_PARAM_APPEARANCE_PROPERTY, sizeof(appearance_prop), &appearance_prop);
+ gaps_set_parameter(GAPS_PARAM_DEVICE_NAME_PROPERTY, sizeof(device_name_prop), &device_name_prop);
+ gatt_register_callback(gap_service_callback);
+ }
+ * \endcode
+ */
+bool gaps_set_parameter(T_GAPS_PARAM_TYPE param_type, uint8_t length, void *p_value);
+
+
+/**
+ * @brief Set the preferred connection parameter.
+ *
+ * @param[in] conn_interval_min Defines minimum value for the connection interval in the
+ following manner:
+ connIntervalmin = Conn_Interval_Min * 1.25 ms
+ Conn_Interval_Min range: 0x0006 to 0x0C80
+ Value of 0xFFFF indicates no specific minimum.
+ Values outside the range (except 0xFFFF) are reserved for
+ future use.
+ * @param[in] conn_interval_max Defines maximum value for the connection interval in the
+ following manner:
+ connIntervalmax = Conn_Interval_Max * 1.25 ms
+ Conn_Interval_Max range: 0x0006 to 0x0C80
+ Shall be equal to or greater than the Conn_Interval_Min.
+ Value of 0xFFFF indicates no specific maximum.
+ Values outside the range (except 0xFFFF) are reserved for
+ future use.
+ * @param[in] slave_latency Defines the slave latency for the connection in number of
+ connection events.
+ Slave latency range: 0x0000 to 0x01F3
+ Values outside the range are reserved for future use.
+ * @param[in] supervision_timeout Defines the connection supervisor timeout multiplier as amultiple of 10ms.
+ Range: 0xFFFF indicates no specific value requested.
+ Range: 0x000A to 0x0C80
+ Time = N * 10 ms
+ Time Range: 100 ms to 32 seconds
+ Values outside the range (except 0xFFFF) are reserved for
+ future use.
+ * @return none
+ */
+void gaps_set_peripheral_preferred_conn_param(uint16_t conn_interval_min,
+ uint16_t conn_interval_max,
+ uint16_t slave_latency,
+ uint16_t supervision_timeout);
+
+/**
+ * @brief Send service changed indication.
+ *
+ * @param[in] conn_id Connection id
+ * @param[in] start_handle Start of Affected Attribute Handle Range
+ * @param[in] end_handle End of Affected Attribute Handle Range
+ * @return parameter set result.
+ * @retval 0 false
+ * @retval 1 true
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t conn_id = 0;
+ uint16_t start_handle = 0x05;
+ uint16_t end_handle = 0xFF;
+ gatts_service_changed_indicate(conn_id, start_handle, end_handle);
+ }
+ * \endcode
+ */
+bool gatts_service_changed_indicate(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle);
+
+/** End of GAP_GATT_SERVICE_Exported_Functions
+* @}
+*/
+
+/** End of GAP_GATT_SERVICE
+* @}
+*/
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _BUILTIN_SERVICES_H_ */
diff --git a/inc/bluetooth/profile/profile_client.h b/inc/bluetooth/profile/profile_client.h
new file mode 100644
index 0000000..ce0ab96
--- /dev/null
+++ b/inc/bluetooth/profile/profile_client.h
@@ -0,0 +1,611 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file profile_client.h
+ * @brief Head file for profile client structure.
+ * @details Common data struct definition.
+ * @author ethan_su
+ * @date 2016-02-18
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef PROFILE_CLIENT_H
+#define PROFILE_CLIENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#if F_BT_LE_GATT_CLIENT_SUPPORT
+#include "gatt.h"
+#include <bt_types.h>
+#include "gap_le.h"
+
+
+/** @defgroup GATT_CLIENT_API GATT Client API
+ * @brief GATT client API
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GATT_Client_Exported_Macros GATT Client Exported Macros
+ * @{
+ */
+#define CLIENT_PROFILE_GENERAL_ID 0xff //!< General Client ID used by application, when directly calls the APIs of profile client layer. Distinguish with other specific client module.
+
+/** End of GATT_Client_Exported_Macros
+* @}
+*/
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GATT_Client_Exported_Types GATT Client Exported Types
+ * @{
+ */
+
+typedef uint8_t T_CLIENT_ID; //!< Client ID
+
+/* callback related data to inform application. */
+
+
+/** @brief Discovery state during discovery procedure.*/
+typedef enum
+{
+ DISC_STATE_IDLE,
+ DISC_STATE_SRV,
+ DISC_STATE_SRV_DONE,
+ DISC_STATE_RELATION,
+ DISC_STATE_RELATION_DONE,
+ DISC_STATE_CHAR,
+ DISC_STATE_CHAR_DONE,
+ DISC_STATE_CHAR_UUID16_DONE,
+ DISC_STATE_CHAR_UUID128_DONE,
+ DISC_STATE_CHAR_DESCRIPTOR,
+ DISC_STATE_CHAR_DESCRIPTOR_DONE,
+ DISC_STATE_FAILED
+} T_DISCOVERY_STATE;
+
+/** @brief Discovery result type*/
+typedef enum
+{
+ DISC_RESULT_ALL_SRV_UUID16,
+ DISC_RESULT_ALL_SRV_UUID128,
+ DISC_RESULT_SRV_DATA,
+ DISC_RESULT_CHAR_UUID16,
+ DISC_RESULT_CHAR_UUID128,
+ DISC_RESULT_CHAR_DESC_UUID16,
+ DISC_RESULT_CHAR_DESC_UUID128,
+ DISC_RESULT_RELATION_UUID16,
+ DISC_RESULT_RELATION_UUID128,
+ DISC_RESULT_BY_UUID16_CHAR,
+ DISC_RESULT_BY_UUID128_CHAR,
+} T_DISCOVERY_RESULT_TYPE;
+
+/** @brief GATT write type*/
+typedef enum
+{
+ GATT_WRITE_TYPE_REQ = 0x01, /**< ATT "Write Request" */
+ GATT_WRITE_TYPE_CMD = 0x02, /**< ATT "Write Command" */
+ GATT_WRITE_TYPE_SIGNED_CMD = 0x04 /**< ATT "Signed Write Command" */
+} T_GATT_WRITE_TYPE;
+
+typedef struct
+{
+ uint16_t att_handle; /**< The handle for the service declaration */
+ uint16_t end_group_handle; /**< The handle of the last attribute
+ within the service definition */
+ uint16_t uuid16; /**< 16 bit UUID */
+} T_GATT_SERVICE_ELEM16;
+
+typedef struct
+{
+ uint16_t att_handle; /**< The handle for the service declaration */
+ uint16_t end_group_handle;
+ /**< The handle of the last attribute within the service definition */
+ uint8_t uuid128[16]; /**< 128 bit UUID */
+} T_GATT_SERVICE_ELEM128;
+
+
+typedef struct
+{
+ uint16_t att_handle; /**< The handle for the service declaration */
+ uint16_t end_group_handle;
+ /**< The handle of the last attribute within the service definition */
+} T_GATT_SERVICE_BY_UUID_ELEM;
+
+/** @brief Characteristic declaration for 16 bit UUID.*/
+typedef struct
+{
+ uint16_t decl_handle; /**< Attribute handle */
+ uint16_t properties; /**< Characteristic Properties, high nibble is reserved */
+ uint16_t value_handle; /**< Characteristic Value Handle */
+ uint16_t uuid16; /**< 16-bit Bluetooth UUID for Characteristic Value */
+} T_GATT_CHARACT_ELEM16;
+
+/** @brief Characteristic declaration for 128 bit UUID.*/
+typedef struct
+{
+ uint16_t decl_handle; /**< Attribute handle */
+ uint16_t properties; /**< Characteristic Properties, high nibble is reserved */
+ uint16_t value_handle; /**< Characteristic Value Handle */
+ uint8_t uuid128[16]; /**< 128-bit UUID for Characteristic Value */
+} T_GATT_CHARACT_ELEM128;
+
+/** @brief Characteristic descriptor for 16 bit UUID.*/
+typedef struct
+{
+ uint16_t handle; /**< Attribute handle */
+ uint16_t uuid16; /**< 16 bit UUID */
+} T_GATT_CHARACT_DESC_ELEM16;
+
+/** @brief Characteristic descriptor for 128 bit UUID.*/
+typedef struct
+{
+ uint16_t handle; /**< Attribute handle */
+ uint8_t uuid128[16]; /**< 128 bit UUID */
+} T_GATT_CHARACT_DESC_ELEM128;
+
+/** @brief Relationship discovery for 16 bit UUID.*/
+typedef struct
+{
+ uint16_t decl_handle;
+ uint16_t att_handle;
+ uint16_t end_group_handle;
+ uint16_t uuid16;
+} T_GATT_RELATION_ELEM16;
+
+/** @brief Relationship discovery for 128 bit UUID.*/
+typedef struct
+{
+ uint16_t decl_handle;
+ uint16_t att_handle;
+ uint16_t end_group_handle;
+ uint8_t uuid128[16];
+} T_GATT_RELATION_ELEM128;
+
+/** @brief Discovery result data*/
+typedef union
+{
+ T_GATT_SERVICE_ELEM16 *p_srv_uuid16_disc_data;
+ T_GATT_SERVICE_ELEM128 *p_srv_uuid128_disc_data;
+ T_GATT_SERVICE_BY_UUID_ELEM *p_srv_disc_data;
+ T_GATT_CHARACT_ELEM16 *p_char_uuid16_disc_data;
+ T_GATT_CHARACT_ELEM128 *p_char_uuid128_disc_data;
+ T_GATT_CHARACT_DESC_ELEM16 *p_char_desc_uuid16_disc_data;
+ T_GATT_CHARACT_DESC_ELEM128 *p_char_desc_uuid128_disc_data;
+ T_GATT_RELATION_ELEM16 *p_relation_uuid16_disc_data;
+ T_GATT_RELATION_ELEM128 *p_relation_uuid128_disc_data;
+} T_DISCOVERY_RESULT_DATA;
+
+/** @defgroup General_cb_data General Client Callback Data
+ * @{
+ */
+/** @brief The callback data of CLIENT_APP_CB_TYPE_DISC_STATE.
+ *
+ * Discovery procedure related data to inform application
+ */
+typedef struct
+{
+ T_DISCOVERY_STATE disc_state;
+} T_DISC_STATE_CB_DATA;
+
+/** @brief The callback data of CLIENT_APP_CB_TYPE_DISC_RESULT.
+ *
+ * Discovery result data will be sent to upper through the callback
+ */
+typedef struct
+{
+ T_DISCOVERY_RESULT_TYPE result_type;
+ T_DISCOVERY_RESULT_DATA result_data;
+} T_DISC_RESULT_CB_DATA;
+
+
+/** @brief The callback type of T_CLIENT_APP_CB_DATA.
+ *
+ * Message data type, when data sent to app directly
+ */
+typedef enum
+{
+ CLIENT_APP_CB_TYPE_DISC_STATE,
+ CLIENT_APP_CB_TYPE_DISC_RESULT
+} T_CLIENT_CB_TYPE;
+
+/** @brief The callback data of T_CLIENT_APP_CB_DATA.
+ *
+ * Client received data from server, when no specific client registered, will be sent to app directly
+ */
+typedef union
+{
+ T_DISC_STATE_CB_DATA disc_state_data;
+ T_DISC_RESULT_CB_DATA disc_result_data;
+} T_CLIENT_CB_DATA;
+
+/** @brief The General Client Callback Data Struct.
+ *
+ * Callback data sent to application directly from client, include type and content
+ */
+typedef struct
+{
+ T_CLIENT_CB_TYPE cb_type;
+ T_CLIENT_CB_DATA cb_content;
+} T_CLIENT_APP_CB_DATA;
+/** End of General_cb_data
+ * @}
+ */
+
+
+/** @defgroup pfnSpecificClientAppCB_t1 General Client Callback Function Point Definition
+ * @{ function ponter used in each specific profile, to send events to application
+ */
+typedef T_APP_RESULT(*P_FUN_GENERAL_APP_CB)(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data);
+/** End of pfnSpecificClientAppCB_t1
+ * @}
+ */
+
+
+/** @defgroup Specific_cb Specific Client Callback Function Point Definition
+ * @{ Function ponter used in each specific client module, to send events to specific client module.
+ */
+typedef void (*P_FUN_DISCOVER_STATE_CB)(uint8_t conn_id, T_DISCOVERY_STATE discovery_state);
+typedef void (*P_FUN_DISCOVER_RESULT_CB)(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data);
+typedef void (*P_FUN_READ_RESULT_CB)(uint8_t conn_id, uint16_t cause, uint16_t handle,
+ uint16_t value_size, uint8_t *p_value);
+typedef void (*P_FUN_WRITE_RESULT_CB)(uint8_t conn_id, T_GATT_WRITE_TYPE type, uint16_t handle,
+ uint16_t cause, uint8_t credits);
+typedef T_APP_RESULT(*P_FUN_NOTIFY_IND_RESULT_CB)(uint8_t conn_id, bool notify, uint16_t handle,
+ uint16_t value_size, uint8_t *p_value);
+typedef void (*P_FUN_DISCONNECT_CB)(uint8_t conn_id);
+/** End of Specific_cb
+ * @}
+ */
+
+/** @defgroup T_FUN_CLIENT_CBS Specific Client Callback Functions Struct
+ * @{
+ */
+typedef struct
+{
+ P_FUN_DISCOVER_STATE_CB discover_state_cb; //!< Discovery state callback function pointer
+ P_FUN_DISCOVER_RESULT_CB discover_result_cb; //!< Discovery reault callback function pointer
+ P_FUN_READ_RESULT_CB read_result_cb; //!< Read response callback function pointer
+ P_FUN_WRITE_RESULT_CB write_result_cb; //!< Write result callback function pointer
+ P_FUN_NOTIFY_IND_RESULT_CB notify_ind_result_cb;//!< Notify Indication callback function pointer
+ P_FUN_DISCONNECT_CB disconnect_cb; //!< Disconnection callback function pointer
+} T_FUN_CLIENT_CBS;
+/** End of T_FUN_CLIENT_CBS * @} */
+
+/** End of GATT_Client_Exported_Types
+* @}
+*/
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup GATT_Client_Exported_Functions GATT Client Exported Functions
+ * @{
+ */
+/**
+ * @brief Initialize parameters of GATT client.
+ *
+ * @param[in] client_num Set the number of clients that needs to register.
+ * @retval None
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ simple_ble_client_id = simp_ble_add_client(app_client_callback);
+ client_register_general_client_cb(app_client_callback);
+ }
+ * \endcode
+ */
+void client_init(uint8_t client_num);
+
+/**
+ * @brief Used by application, register general client callback.
+ * @param[in] p_fun_cb Function offered by application.
+ * @retval None
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ simple_ble_client_id = simp_ble_add_client(app_client_callback);
+ client_register_general_client_cb(app_client_callback);
+ }
+ * \endcode
+ */
+void client_register_general_client_cb(P_FUN_GENERAL_APP_CB p_fun_cb);
+
+/**
+ * @brief Used by specific client, register callback.
+ * @param[in,out] p_out_client_id Client ID generated for registered specific client module.
+ * @param[in] client_cbs Callback functions implemented in specific client module.
+ * @retval true Register successful.
+ * @retval false Register failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+
+ T_CLIENT_ID simp_ble_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+ {
+ uint16_t size;
+ if (link_num > SIMP_MAX_LINKS)
+ {
+ APP_PRINT_ERROR1("simp_ble_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&simp_client, &simp_ble_client_cbs))
+ {
+ simp_client = CLIENT_PROFILE_GENERAL_ID;
+ APP_PRINT_ERROR0("simp_ble_add_client failed");
+ return simp_client;
+ }
+ APP_PRINT_INFO1("simp_ble_add_client: simp_client %d", simp_client);
+
+ simp_client_cb = app_cb;
+ simp_link_num = link_num;
+ size = simp_link_num * sizeof(T_SIMP_LINK);
+ simp_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ return simp_client;
+ }
+ * \endcode
+ */
+bool client_register_spec_client_cb(T_CLIENT_ID *p_out_client_id,
+ const T_FUN_CLIENT_CBS *client_cbs);
+
+/**
+ * @brief Send discovery all primary services request.
+ * @param[in] conn_id Connection ID
+ * @param[in] client_id Client ID of specific client module.
+ * @retval GAP_CAUSE_SUCCESS Discovery request success.
+ * @retval other Discovery request failed.
+ */
+T_GAP_CAUSE client_all_primary_srv_discovery(uint8_t conn_id, T_CLIENT_ID client_id);
+
+/**
+ * @brief Send discovery services by 16 bit UUID request.
+ * @param[in] conn_id Connection ID
+ * @param[in] client_id Client ID of specific client module.
+ * @param[in] uuid16 16 bit UUID.
+ * @retval GAP_CAUSE_SUCCESS Discovery request success.
+ * @retval other Discovery request failed.
+ */
+T_GAP_CAUSE client_by_uuid_srv_discovery(uint8_t conn_id, T_CLIENT_ID client_id, uint16_t uuid16);
+
+/**
+ * @brief Send discovery services by 128 bit UUID request.
+ * @param[in] conn_id Connection ID
+ * @param[in] client_id Client ID of specific client module.
+ * @param[in] p_uuid128 128 bit UUID.
+ * @retval GAP_CAUSE_SUCCESS Discovery request success.
+ * @retval other Discovery request failed.
+ */
+T_GAP_CAUSE client_by_uuid128_srv_discovery(uint8_t conn_id, T_CLIENT_ID client_id,
+ uint8_t *p_uuid128);
+
+/**
+ * @brief Send discovery relationship services request.
+ * @param[in] conn_id Connection ID
+ * @param[in] client_id Client ID of specific client module.
+ * @param[in] start_handle Start handle of range to be searched.
+ * @param[in] end_handle End handle of range to be searched.
+ * @retval GAP_CAUSE_SUCCESS Discovery request success.
+ * @retval other Discovery request failed.
+ */
+T_GAP_CAUSE client_relationship_discovery(uint8_t conn_id, T_CLIENT_ID client_id,
+ uint16_t start_handle, uint16_t end_handle);
+
+/**
+ * @brief Send discovery characteristics request.
+ * @param[in] conn_id Connection ID
+ * @param[in] client_id Client ID of specific client module.
+ * @param[in] start_handle Start handle of range to be searched.
+ * @param[in] end_handle End handle of range to be searched.
+ * @retval GAP_CAUSE_SUCCESS Discovery request success.
+ * @retval other Discovery request failed.
+ */
+T_GAP_CAUSE client_all_char_discovery(uint8_t conn_id, T_CLIENT_ID client_id, uint16_t start_handle,
+ uint16_t end_handle);
+
+/**
+ * @brief Send discovery characteristics request by caracteristic uuid.
+ * @param[in] conn_id Connection ID
+ * @param[in] client_id Client ID of specific client module.
+ * @param[in] start_handle Start handle of range to be searched.
+ * @param[in] end_handle End handle of range to be searched.
+ * @param[in] uuid16 16bit characteristic uuid to be searched.
+ * @retval GAP_CAUSE_SUCCESS Discovery request success.
+ * @retval other Discovery request failed.
+ */
+T_GAP_CAUSE client_by_uuid_char_discovery(uint8_t conn_id, T_CLIENT_ID client_id,
+ uint16_t start_handle,
+ uint16_t end_handle, uint16_t uuid16);
+/**
+ * @brief Send discovery characteristics request by caracteristic uuid.
+ * @param[in] conn_id Connection ID
+ * @param[in] client_id Client ID of specific client module.
+ * @param[in] start_handle Start handle of range to be searched.
+ * @param[in] end_handle End handle of range to be searched.
+ * @param[in] p_uuid128 128bit characteristic uuid to be searched.
+ * @retval GAP_CAUSE_SUCCESS Discovery request success.
+ * @retval other Discovery request failed.
+ */
+T_GAP_CAUSE client_by_uuid128_char_discovery(uint8_t conn_id, T_CLIENT_ID client_id,
+ uint16_t start_handle,
+ uint16_t end_handle, uint8_t *p_uuid128);
+/**
+ * @brief Send discovery characteristics descriptor request.
+ * @param[in] conn_id Connection ID
+ * @param[in] client_id Client ID of specific client module.
+ * @param[in] start_handle Start handle of range to be searched.
+ * @param[in] end_handle End handle of range to be searched.
+ * @retval GAP_CAUSE_SUCCESS Discovery request success.
+ * @retval other Discovery request failed.
+ */
+T_GAP_CAUSE client_all_char_descriptor_discovery(uint8_t conn_id, T_CLIENT_ID client_id,
+ uint16_t start_handle, uint16_t end_handle);
+
+/**
+ * @brief Read characteristic by handle request.
+ * @param[in] conn_id Connection ID
+ * @param[in] client_id Client ID of specific client module.
+ * @param[in] handle Request handle.
+ * @retval GAP_CAUSE_SUCCESS Read request success.
+ * @retval other Read request failed.
+ */
+T_GAP_CAUSE client_attr_read(uint8_t conn_id, T_CLIENT_ID client_id, uint16_t handle);
+
+/**
+ * @brief Read characteristic by 16 bit UUID request.
+ * @param[in] conn_id Connection ID
+ * @param[in] client_id Client ID of specific client module.
+ * @param[in] start_handle Start handle of range to be searched.
+ * @param[in] end_handle End handle of range to be searched.
+ * @param[in] uuid16 Request 16 bit UUID.
+ * @param[in] p_uuid128 Request 128 bit UUID.
+ * @retval GAP_CAUSE_SUCCESS Read request success.
+ * @retval other Read request failed.
+ */
+T_GAP_CAUSE client_attr_read_using_uuid(uint8_t conn_id, T_CLIENT_ID client_id,
+ uint16_t start_handle,
+ uint16_t end_handle, uint16_t uuid16, uint8_t *p_uuid128);
+/**
+ * @brief Write characteristic request.
+ * @param[in] conn_id Connection ID
+ * @param[in] client_id Client ID of specific client module.
+ * @param[in] write_type Type of write.
+ * @param[in] handle Attribute handle.
+ * @param[in] length Length of data to be written.
+ If write_type is GATT_WRITE_TYPE_REQ, range of length is from 0 to 512.
+ If write_type is GATT_WRITE_TYPE_CMD, range of length is from 0 to (mtu_size - 3).
+ If write_type is GATT_WRITE_TYPE_SIGNED_CMD, range of length is from 0 to (mtu_size - 15).
+ uint16_t mtu_size is acquired by le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id).
+ * @param[in] p_data Point to the data to be written.
+ * @retval GAP_CAUSE_SUCCESS: Write request success.
+ * @retval other: Write request failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ //if write_type is GATT_WRITE_TYPE_SIGNED_CMD, GAP_MSG_LE_GATT_SIGNED_STATUS_INFO will be notified to app
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA));
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_GATT_SIGNED_STATUS_INFO:
+ APP_PRINT_INFO5("GAP_MSG_LE_GATT_SIGNED_STATUS_INFO:conn_id %d, cause 0x%x, update_local %d, local_sign_count %d,remote_sign_count %d",
+ cb_data.p_le_gatt_signed_status_info->conn_id,
+ cb_data.p_le_gatt_signed_status_info->cause,
+ cb_data.p_le_gatt_signed_status_info->update_local,
+ cb_data.p_le_gatt_signed_status_info->local_sign_count,
+ cb_data.p_le_gatt_signed_status_info->remote_sign_count);
+ break;
+ ...
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE client_attr_write(uint8_t conn_id, T_CLIENT_ID client_id,
+ T_GATT_WRITE_TYPE write_type,
+ uint16_t handle, uint16_t length, uint8_t *p_data);
+
+/**
+ * @brief Confirm from application when receive indication from server.
+ * @param[in] conn_id Connection ID indicate which link is.
+ * @retval true: Confirm OK.
+ * @retval false: Confirm failed.
+ */
+T_GAP_CAUSE client_attr_ind_confirm(uint8_t conn_id);
+
+/**
+ * @brief Get the header point of the notification data buffer.
+ * This function is used to get the header buffer point of the notification command data.
+ * This function only can be called in notify_ind_result_cb.
+ *
+ * @param[in] conn_id Connection id indicate which link is.
+ * @param[in,out] pp_buffer Pointer to the address of the buffer.
+ * @param[in,out] p_offset Pointer to the offset of the data.
+ * @return Buffer get result
+ * @retval true Success.
+ * @retval false Failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ uint8_t *p_data_buf;
+ uint16_t data_offset;
+ static T_APP_RESULT simp_ble_client_notif_ind_result_cb(uint8_t conn_id, bool notify,
+ uint16_t handle,
+ uint16_t value_size, uint8_t *p_value)
+ {
+ ......
+ client_get_notify_data_buffer(conn_id, &p_data_buf, &data_offset);
+ return APP_RESULT_NOT_RELEASE;
+ }
+ void release(void)
+ {
+ if(p_data_buf != NULL)
+ {
+ gap_buffer_free(p_data_buf);
+ p_data_buf = NULL;
+ }
+ }
+ * \endcode
+ */
+bool client_get_notify_data_buffer(uint8_t conn_id, uint8_t **pp_buffer, uint16_t *p_offset);
+
+/**
+ * @brief Send the exchange MTU request.
+ * This function is used to send the exchange MTU request.
+ *
+ * @param[in] conn_id Connection id indicate which link is.
+ * @retval GAP_CAUSE_SUCCESS: Write request success.
+ * @retval other: Write request failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ uint8_t *p_data_buf;
+ uint16_t data_offset;
+ static T_USER_CMD_PARSE_RESULT cmd_send_mtu_req(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ T_GAP_CAUSE cause;
+ uint8_t conn_id = p_parse_value->dw_param[0];
+
+ cause = client_send_exchange_mtu_req(conn_id);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ * \endcode
+ */
+T_GAP_CAUSE client_send_exchange_mtu_req(uint8_t conn_id);
+
+/** End of GATT_Client_Exported_Functions
+* @}
+*/
+
+/** End of GATT_CLIENT_API
+* @}
+*/
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* PROFILE_CLIENT_H */
+
diff --git a/inc/bluetooth/profile/profile_server.h b/inc/bluetooth/profile/profile_server.h
new file mode 100644
index 0000000..f6b380a
--- /dev/null
+++ b/inc/bluetooth/profile/profile_server.h
@@ -0,0 +1,452 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file profile_server.h
+ * @brief Head file for server structure.
+ * @details Common data struct definition.
+ * @author
+ * @date 2017-02-18
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef PROFILE_SERVER_H
+#define PROFILE_SERVER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "upperstack_config.h"
+#if F_BT_LE_GATT_SERVER_SUPPORT
+#include <bt_types.h>
+#include "gatt.h"
+#include "gap_le.h"
+
+
+/** @defgroup GATT_SERVER_API GATT Server API
+ * @brief GATT Server API
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GATT_SERVER_Exported_Macros GATT Server Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @defgroup General_Service_ID General Service ID
+ * @brief Service ID for general profile events.
+ * @{
+ */
+#define SERVICE_PROFILE_GENERAL_ID 0xff
+/** @} */
+
+/** End of GATT_SERVER_Exported_Macros
+ * @}
+ */
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GATT_SERVER_Exported_Types GATT Server Exported Types
+ * @brief
+ * @{
+ */
+
+typedef uint8_t T_SERVER_ID; //!< Service ID
+
+/** @brief GATT write data type*/
+typedef enum
+{
+ WRITE_REQUEST, /**< Write request. */
+ WRITE_WITHOUT_RESPONSE, /**< Write without response. */
+ WRITE_SIGNED_WITHOUT_RESPONSE, /**< Signed write without response. */
+ WRITE_LONG, /**< Write long request. */
+} T_WRITE_TYPE;
+
+/** @brief GATT PDU type*/
+typedef enum
+{
+ GATT_PDU_TYPE_ANY = 0x00, /**< Any PDU type. */
+ GATT_PDU_TYPE_NOTIFICATION = 0x01, /**< Notification PDU type. */
+ GATT_PDU_TYPE_INDICATION = 0x02 /**< Indication PDU type. */
+} T_GATT_PDU_TYPE;
+
+/** @brief Event type to inform app*/
+typedef enum
+{
+ SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION = 1, /**< CCCD update event */
+ SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE = 2, /**< client read event */
+ SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE = 3, /**< client write event */
+} T_SERVICE_CALLBACK_TYPE;
+
+/** @defgroup GATT_SERVER_CB_DATA App Callback data
+ * @brief data for profile to inform application.
+ * @{
+ */
+/** @brief Event ID */
+typedef enum
+{
+ PROFILE_EVT_SRV_REG_COMPLETE, /**< Services register complete event
+ when application calls server_add_service before calling gap_start_bt_stack. */
+ PROFILE_EVT_SEND_DATA_COMPLETE, /**< Notification or indication data send complete event. */
+ PROFILE_EVT_SRV_REG_AFTER_INIT_COMPLETE, /**< Services register complete event
+ when application calls server_add_service after receiving @ref GAP_INIT_STATE_STACK_READY. */
+} T_SERVER_CB_TYPE;
+
+/** @brief The callback data of PROFILE_EVT_SRV_REG_COMPLETE */
+typedef enum
+{
+ GATT_SERVER_SUCCESS,
+ GATT_SERVER_FAIL
+} T_SERVER_RESULT;
+
+/** @brief The callback data of PROFILE_EVT_SRV_REG_AFTER_INIT_COMPLETE */
+typedef struct
+{
+ T_SERVER_RESULT result;
+ T_SERVER_ID service_id;
+ uint16_t cause;
+} T_SERVER_REG_AFTER_INIT_RESULT;
+
+/** @brief The callback data of PROFILE_EVT_SEND_DATA_COMPLETE */
+typedef struct
+{
+ uint16_t credits;
+ uint8_t conn_id;
+ T_SERVER_ID service_id;
+ uint16_t attrib_idx;
+ uint16_t cause;
+} T_SEND_DATA_RESULT;
+
+/** @brief Service callback data */
+typedef union
+{
+ T_SERVER_RESULT service_reg_result;
+ T_SEND_DATA_RESULT send_data_result;
+ T_SERVER_REG_AFTER_INIT_RESULT server_reg_after_init_result;
+} T_SERVER_CB_DATA;
+
+typedef struct
+{
+ T_SERVER_CB_TYPE eventId; /**< @brief EventId defined upper */
+ T_SERVER_CB_DATA event_data; /**< @brief Event data */
+} T_SERVER_APP_CB_DATA;
+/** @} End of GATT_SERVER_CB_DATA */
+
+
+
+/** @defgroup P_FUN_WRITE_IND_POST_PROC TGATTDWriteIndPostProc
+ * @brief Call back function to execute some post procedure after handle write request from client.
+ * @{
+ */
+typedef void (* P_FUN_WRITE_IND_POST_PROC)(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index, uint16_t length,
+ uint8_t *p_value);
+/** @} End of P_FUN_WRITE_IND_POST_PROC */
+
+/** @defgroup Specific_srv_cb Specific Service Callback Function Point Definition
+ * @{ Function ponter used in each specific service module, to send events to specific service module.
+ */
+typedef T_APP_RESULT(*P_FUN_GATT_READ_ATTR_CB)(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value);
+typedef T_APP_RESULT(*P_FUN_GATT_WRITE_ATTR_CB)(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index, T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_post_proc);
+typedef void (*P_FUN_GATT_CCCD_UPDATE_CB)(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index, uint16_t ccc_bits);
+/** End of Specific_srv_cb
+ * @}
+ */
+
+/** @defgroup P_FUN_SERVER_GENERAL_CB General Server Callback Function Point Definition
+ * @brief function ponter Type used to generate Call back, to send events to application.
+ * @{
+ */
+typedef T_APP_RESULT(*P_FUN_SERVER_GENERAL_CB)(T_SERVER_ID service_id, void *p_para);
+/** @} End of pfnAPPHandleInfoCB_t1 */
+
+
+/** @brief GATT service callbacks */
+typedef struct
+{
+ P_FUN_GATT_READ_ATTR_CB read_attr_cb; /**< Read callback function pointer.
+ Return value: @ref T_APP_RESULT. */
+ P_FUN_GATT_WRITE_ATTR_CB write_attr_cb; /**< Write callback function pointer.
+ Return value: @ref T_APP_RESULT. */
+ P_FUN_GATT_CCCD_UPDATE_CB cccd_update_cb; /**< Update cccd callback function pointer. */
+} T_FUN_GATT_SERVICE_CBS;
+
+/** End of GATT_SERVER_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup GATT_SERVER_Exported_Functions GATT Server Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Initialize parameters of GATT Server.
+ *
+ * @param[in] service_num Set the number of services that needs to register.
+ * @retval None
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ server_init(1);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+ }
+ * \endcode
+ */
+void server_init(uint8_t service_num);
+
+/**
+ * @brief Register builtin services including GAP and GATT service.
+ *
+ * If application does not need to register GAP and GATT service.
+ * Application shall call server_builtin_service_reg(false) before server_init().
+ *
+ * @param[in] reg Whether to register builtin services. Default value is true.
+ * @retval None
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ server_builtin_service_reg(false);
+ server_init(1);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+ }
+ * \endcode
+ */
+void server_builtin_service_reg(bool reg);
+
+/**
+ * @brief Register specific service without start handle
+ *
+ * Add specific service information to gatt_svc_table struct, will be registered to GATT later.
+ *
+ * @param[in,out] p_out_service_id Service ID of specific service.
+ * @param[in] p_database Database pointer of specific service.
+ * @param[in] length Length of Database of specific service.
+ * @param[in] srv_cbs Service callback functions of specific service.
+ * @retval true Add service success
+ * @retval false Add service failed
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_SERVER_ID bas_add_service(void *p_func)
+ {
+ T_SERVER_ID service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)bas_attr_tbl,
+ bas_attr_tbl_size,
+ bas_cbs))
+ {
+ APP_PRINT_ERROR1("bas_add_service: service_id %d", service_id);
+ service_id = 0xff;
+ }
+ pfn_bas_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+ }
+ * \endcode
+ */
+bool server_add_service(T_SERVER_ID *p_out_service_id, uint8_t *p_database, uint16_t length,
+ const T_FUN_GATT_SERVICE_CBS srv_cbs);
+
+/**
+ * @brief Register specific service with start handle
+ *
+ * Add specific service information to gatt_svc_table struct, will be registered to GATT later.
+ *
+ * @param[in,out] p_out_service_id Service ID of specific service.
+ * @param[in] p_database Database pointer of specific service.
+ * @param[in] length Length of Database of specific service.
+ * @param[in] srv_cbs Service callback functions of specific service.
+ * @param[in] start_handle Start handle of this service.
+ * @retval true Add service success
+ * @retval false Add service failed
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_SERVER_ID bas_add_service(void *p_func)
+ {
+ T_SERVER_ID service_id;
+ if (false == server_add_service_by_start_handle(&service_id,
+ (uint8_t *)bas_attr_tbl,
+ bas_attr_tbl_size,
+ bas_cbs, 0x00f0))
+ {
+ APP_PRINT_ERROR1("bas_add_service: service_id %d", service_id);
+ service_id = 0xff;
+ }
+ pfn_bas_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+ }
+ * \endcode
+ */
+bool server_add_service_by_start_handle(uint8_t *p_out_service_id, uint8_t *p_database,
+ uint16_t length,
+ const T_FUN_GATT_SERVICE_CBS srv_cbs, uint16_t start_handle);
+/**
+ * @brief Register callback function to send events to application.
+ *
+ * @param[in] p_fun_cb Callback function.
+ * @retval None
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ server_init(1);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+ }
+ * \endcode
+ */
+void server_register_app_cb(P_FUN_SERVER_GENERAL_CB p_fun_cb);
+
+/**
+ * @brief Confirm from application when receive read Request from client.
+ * @param[in] conn_id Connection id indicate which link is.
+ * @param[in] service_id Service ID.
+ * @param[in] attrib_index Attribute index of attribute to read confirm from application.
+ * @param[in] p_data Point to the readed value.
+ * @param[in] length The length of the data.
+ * @param[in] cause Cause for read confirm. @ref T_APP_RESULT
+ * @retval true: confirm from app OK.
+ * @retval false: confirm from app failed.
+ */
+bool server_attr_read_confirm(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint8_t *p_data, uint16_t length, T_APP_RESULT cause);
+/**
+ * @brief Confirm from application when receive Execute Write Request from client.
+ * @param[in] conn_id Connection id indicate which link is.
+ * @param[in] cause Cause for execute write confirm. @ref T_APP_RESULT
+ * @param[in] handle Gatt attribute handle.
+ * @retval true: confirm from app OK.
+ * @retval false: confirm from app failed.
+ */
+bool server_exec_write_confirm(uint8_t conn_id, uint16_t cause, uint16_t handle);
+
+/**
+ * @brief Confirm from application when receive Write Request from client.
+ * @param[in] conn_id Connection id indicate which link is.
+ * @param[in] service_id Service ID.
+ * @param[in] attrib_index Attribute index of attribute to write confirm from application.
+ * @param[in] cause Write request app handle result, APP_RESULT_SUCCESS or other. @ref T_APP_RESULT
+ * @retval true: confirm from app OK.
+ * @retval false: confirm from app failed.
+ */
+bool server_attr_write_confirm(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index, T_APP_RESULT cause);
+
+/**
+ * @brief Send characteristic value to peer device.
+ *
+ * @param[in] conn_id Connection id indicate which link is.
+ * @param[in] service_id Service ID.
+ * @param[in] attrib_index Attribute index of characteristic.
+ * @param[in] p_data Point to data to be sent.
+ * @param[in] data_len Length of value to be sent, range: 0~(mtu_size - 3).
+ uint16_t mtu_size is acquired by le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id).
+ * @param[in] type GATT pdu type.
+ * @return Data sent result
+ * @retval true Success.
+ * @retval false Failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ bool bas_battery_level_value_notify(uint8_t conn_id, uint8_t service_id, uint8_t battery_level)
+ {
+ return server_send_data(conn_id, service_id, GATT_SVC_BAS_BATTERY_LEVEL_INDEX, &battery_level,
+ sizeof(battery_level), GATT_PDU_TYPE_ANY);
+ }
+ * \endcode
+ */
+bool server_send_data(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint8_t *p_data, uint16_t data_len, T_GATT_PDU_TYPE type);
+
+uint16_t server_get_start_handle(T_SERVER_ID service_id);
+/**
+ * @brief Get the header point of the write command data buffer.
+ * This function is used to get the buffer point of the write command data.
+ * This function only can be called in write_attr_cb.
+ *
+ * @param[in] conn_id Connection id indicate which link is.
+ * @param[in,out] pp_buffer Pointer to the address of the buffer.
+ * @param[in,out] p_offset Pointer to the offset of the data.
+ * @return Buffer get result
+ * @retval true Success.
+ * @retval false Failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ uint8_t *p_data_buf;
+ uint16_t data_offset;
+ T_APP_RESULT simp_ble_service_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index, T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value,
+ P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+ {
+ ......
+ server_get_write_cmd_data_buffer(conn_id, &p_data_buf, &data_offset);
+ return APP_RESULT_NOT_RELEASE;
+ }
+ void release(void)
+ {
+ if(p_data_buf != NULL)
+ {
+ gap_buffer_free(p_data_buf);
+ p_data_buf = NULL;
+ }
+ }
+ * \endcode
+ */
+bool server_get_write_cmd_data_buffer(uint8_t conn_id, uint8_t **pp_buffer, uint16_t *p_offset);
+
+/**
+ * @brief Get the start handle of the service
+ *
+ * @param[in] service_id Service ID.
+ * @return Start handle
+ * @retval 0 Failed.
+ * @retval other Success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint16_t start_handle;
+ start_handle = server_get_start_handle(simp_srv_id);
+ }
+ * \endcode
+ */
+uint16_t server_get_start_handle(T_SERVER_ID service_id);
+
+/** @} End of GATT_SERVER_Exported_Functions */
+
+/** @} End of GATT_SERVER_API */
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* PROFILE_SERVER_H */
diff --git a/inc/bluetooth/profile/server/atvv_service.h b/inc/bluetooth/profile/server/atvv_service.h
new file mode 100644
index 0000000..8ce2552
--- /dev/null
+++ b/inc/bluetooth/profile/server/atvv_service.h
@@ -0,0 +1,227 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file atvv_service.h
+ * @brief Head file for using ATV voice service.
+ * @details ATVV data structs and external functions declaration.
+ * @author Chenjie Jin
+ * @date 2017-12-8
+ * @version v0.1
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _ATVV_H_
+#define _ATVV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "profile_server.h"
+
+/** @defgroup ATVV ATV Voice Service
+ * @brief ATV voice service
+ * @{
+ */
+
+/** @defgroup ATVV_Exported_Constants ATVV Exported Constants
+ * @brief macros that other .c files may use all defined here
+ * @{
+ */
+
+///@cond
+#define ATVV_VERSION_1_0 0x0100
+#define ATVV_VERSION_0_4 0x0004
+
+#define ATTV_CODEC_MASK_8K_ADPCM 0x0001
+#define ATTV_CODEC_MASK_16K_ADPCM 0x0002
+#define ATTV_CODEC_MASK_OPUS 0x0004
+
+#define ATVV_CHAR_RX_DATA_LEN 20
+#define ATVV_CHAR_CTL_DATA_LEN 20
+#define ATVV_CHAR_WRITE_DATA_LEN 20
+
+/** @brief ATVV related services UUIDs */
+#define GATT_UUID_ATV_CHAR_TX 0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0x02, 0x00, 0x5E, 0xAB
+#define GATT_UUID_ATV_CHAR_RX 0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0x03, 0x00, 0x5E, 0xAB
+#define GATT_UUID_ATV_CHAR_CTL 0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0x04, 0x00, 0x5E, 0xAB
+
+/** @brief Index defines for Characteristic's value */
+#define GATT_SVC_ATVV_CHAR_TX_VALUE_INDEX 2
+#define GATT_SVC_ATVV_CHAR_RX_VALUE_INDEX 4
+#define GATT_SVC_ATVV_CHAR_RX_CCCD_INDEX 5
+#define GATT_SVC_ATVV_CHAR_CTL_VALUE_INDEX 7
+#define GATT_SVC_ATVV_CHAR_CTL_CCCD_INDEX 8
+///@endcond
+
+/** @} End of ATVV_Exported_Constants */
+
+/** @defgroup ATVV_Exported_Types IAS Exported Types
+ * @brief types that other .c files may use all defined here
+ * @{
+ */
+/* Add all public types here */
+/** @defgroup ATVV_Callback_Data ATTB Callback Data
+ * @brief ATVV data struct for notification data to application.
+ * @{
+ */
+
+/** @defgroup ATVV_Read_Info ATVV Read Info
+ * @brief Parameter for read characteristic value.
+ * @{
+ */
+#define ATVV_READ_CHAR_RX_INDEX 1
+#define ATVV_READ_CHAR_CTL_INDEX 2
+/** @} */
+
+/** @defgroup ATVV_Write_Info ATVV Write Info
+ * @brief Parameter for write characteristic value.
+ * @{
+ */
+#define ATVV_WRITE_CHAR_TX_INDEX 1
+/** @} */
+
+/** @defgroup ATVV_Notify_Indicate_Info ATVV Notify Indicate Info
+ * @brief Parameter for enable or disable notification or indication.
+ * @{
+ */
+#define ATVV_CHAR_RX_NOTIFY_ENABLE 1
+#define ATVV_CHAR_RX_NOTIFY_DISABLE 2
+#define ATVV_CHAR_CTL_NOTIFY_ENABLE 3
+#define ATVV_CHAR_CTL_NOTIFY_DISABLE 4
+
+/** @defgroup ATT MTU zie and Date length extantion
+ * @brief GATT client negotiate ATT MTU and send DLE
+ * @{
+ */
+#define ATVV_DLE_AND_MTU_UPDATE_DISABLE 0
+#define ATVV_DLE_ENABLE_MTU_SIZE_UPDATE 1
+
+/** Message content */
+typedef union
+{
+ struct
+ {
+ uint8_t len;
+ uint8_t *report;
+ } report_data;
+} T_ATVV_WRITE_PARAMETER;
+
+/** @struct _TATVV_WRITE_MSG
+ * @brief write message
+ */
+typedef struct
+{
+ uint8_t write_type; /**< ref: @ref ATVV_RmC_Write_Info */
+ T_ATVV_WRITE_PARAMETER write_parameter;
+} T_ATVV_WRITE_MSG;
+
+typedef union _TATVV_UPSTREAM_MSG_DATA
+{
+ uint8_t notification_indification_index; /**< ref: @ref ATVV_RmC_Notify_Indicate_Info */
+ uint8_t read_value_index; /**< ref: @ref ATVV_RmC_Read_Info */
+ T_ATVV_WRITE_MSG write;
+} T_ATVV_UPSTREAM_MSG_DATA;
+
+/** ATVV service data to inform application */
+typedef struct
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_ATVV_UPSTREAM_MSG_DATA msg_data;
+} T_ATVV_CALLBACK_DATA;
+/** @} */
+
+typedef enum
+{
+ ATV_TX_OPCODE_GET_CAPS = 0x0A,
+ ATV_TX_OPCODE_MIC_OPEN = 0x0C,
+ ATV_TX_OPCODE_MIC_CLOSE = 0x0D,
+ ATV_TX_OPCODE_EXTEND = 0x0E,
+} ATV_CHAR_TX_OPCODE;
+
+#define ATV_TX_OPCODE_GET_CAPS_LEN 5
+#define ATV_TX_OPCODE_MIC_OPEN_LEN 5
+
+typedef enum
+{
+ ATV_CTL_OPCODE_AUDIO_STOP = 0x00,
+ ATV_CTL_OPCODE_AUDIO_START = 0x04,
+ ATV_CTL_OPCODE_DPAD_SELECT = 0x07,
+ ATV_CTL_OPCODE_START_SEARCH = 0x08,
+ ATV_CTL_OPCODE_AUDIO_SYNC = 0x0A,
+ ATV_CTL_OPCODE_GET_CAPS_RESP = 0x0B,
+ ATV_CTL_OPCODE_MIC_OPEN_ERROR = 0x0C,
+} ATV_CHAR_CTL_CMD_OPCODE;
+
+typedef enum
+{
+ ATV_START_REASON_MIC_OPEN_REQUEST = 0x00,
+ ATV_START_REASON_PTT = 0x01,
+ ATV_START_REASON_HTT = 0x03,
+ ATV_START_REASON_INVALID = 0xFF
+} ATV_AUDIO_START_REASON;
+
+typedef enum
+{
+ ATV_STOP_REASON_MIC_CLOSE_MESSAGE = 0x00,
+ ATV_STOP_REASON_HTT = 0x02,
+ ATV_STOP_REASON_AUDIO_START_COMMAND = 0x04,
+ ATV_STOP_REASON_AUDIO_TRANSFER_TIMEOUT = 0x08,
+ ATV_STOP_REASON_ATVV_CHAR_AUDIO_DISABLE = 0x10,
+ ATV_STOP_REASON_OTHERS = 0x80,
+} ATV_AUDIO_STOP_REASON;
+
+typedef enum
+{
+ ATV_MIC_OPEN_ERROR_RESERVED = 0x0f01,
+ ATV_MIC_OPEN_ERROR_REMOTE_IS_NOT_ACTIVE = 0x0f02,
+ ATV_MIC_OPEN_ERROR_ATVV_CHAR_AUDIO_IS_DISABLE = 0x0f03,
+ ATV_MIC_OPEN_ERROR_PTT_HTT_IS_IN_PROGRESS = 0x0f80,
+ ATV_MIC_OPEN_ERROR_INTERNAL_ERROR = 0x0fff,
+} ATV_MIC_OPEN_ERROR;
+
+typedef enum
+{
+ ATV_ASSISTANT_INTERACTION_MODEL_ON_REQUEST = 0x00,
+ ATV_ASSISTANT_INTERACTION_MODEL_PRESS_TO_TALK = 0x01,
+ ATV_ASSISTANT_INTERACTION_MODEL_HOLD_TO_TALK = 0x03,
+} ATV_ASSISTANT_INTERACTION_MODEL;
+
+/** @} End of IAS_Exported_Types */
+
+typedef struct
+{
+ uint16_t app_support_version;
+ uint16_t codec_support;
+ uint16_t codec_used;
+ uint8_t atv_start_reason;
+ uint8_t assistant_interaction_model;
+ uint8_t audio_consumption_mode;
+ uint8_t stream_id;
+ uint8_t char_rx_data_buff[ATVV_CHAR_RX_DATA_LEN];
+ uint8_t char_ctl_data_buff[ATVV_CHAR_RX_DATA_LEN];
+ uint8_t char_write_dat_buff[ATVV_CHAR_WRITE_DATA_LEN];
+} T_ATVV_GLOBAL_DATA;
+
+extern T_ATVV_GLOBAL_DATA atvv_global_data;
+
+/** @defgroup ATVV_Exported_Functions IAS Exported Functions
+ * @brief functions that other .c files may use all defined here.
+ * @{
+ */
+uint8_t atvv_add_service(void *p_func);
+/** @} End of ATVV_Exported_Functions */
+
+/** @} End of ATVV */
+
+#endif /* (VOICE_FLOW_SEL == ATV_GOOGLE_VOICE_FLOW) */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
diff --git a/inc/bluetooth/profile/server/bas.h b/inc/bluetooth/profile/server/bas.h
new file mode 100644
index 0000000..7eee3d4
--- /dev/null
+++ b/inc/bluetooth/profile/server/bas.h
@@ -0,0 +1,230 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file bas.h
+ * @brief Head file for using battery service.
+ * @details BAS data structs and external functions declaration.
+ * @author
+ * @date
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _BAS_H_
+#define _BAS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "profile_server.h"
+
+
+/** @defgroup BAS Battery Service
+ * @brief Battery service
+ * @details
+
+ The Battery Service exposes the state of a battery within a device.
+
+ Battery Service generally makes up a profile with some other services, and it can provide the state of a battery within a device.
+
+ The default supported feature provided by BAS is the notify property of battery level characteristic,
+ and the application developers can modify the feature supported by BAS according to their own requirements.
+ The specific configuration process can be achieved by modifying file @ref bas_config.h.
+
+ * <b>Example usage</b>
+ * \code{.c}
+
+ #define BAS_BATTERY_LEVEL_NOTIFY_SUPPORT 1
+
+ * \endcode
+
+ Application shall register battery service when initialization through @ref bas_add_service function.
+
+ Application can set the battery level of BAS through @ref bas_set_parameter function.
+
+ Application can send the battery level value of BAS to the client with a notification through @ref bas_battery_level_value_notify function.
+
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup BAS_Exported_Macros BAS Exported Macros
+ * @brief
+ * @{
+ */
+
+#define BAS_READ_BATTERY_LEVEL 1
+#define BAS_NOTIFY_BATTERY_LEVEL_ENABLE 1
+#define BAS_NOTIFY_BATTERY_LEVEL_DISABLE 2
+
+/** End of BAS_Exported_Macros
+* @}
+*/
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup BAS_Exported_Types BAS Exported Types
+ * @brief
+ * @{
+ */
+
+/**
+* @brief Battery service parameter type
+*/
+typedef enum
+{
+ BAS_PARAM_BATTERY_LEVEL = 0x01,
+} T_BAS_PARAM_TYPE;
+
+/**
+* @brief set battery service parameter upstream message data
+*/
+typedef union
+{
+ uint8_t notification_indification_index;
+ uint8_t read_value_index;
+} T_BAS_UPSTREAM_MSG_DATA;
+
+/**
+* @brief set battery service parameter upstream callback data
+*/
+typedef struct
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_BAS_UPSTREAM_MSG_DATA msg_data;
+} T_BAS_CALLBACK_DATA;
+
+/** End of BAS_Exported_Types
+* @}
+*/
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup BAS_Exported_Functions BAS Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add battery service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ bas_id = bas_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID bas_add_service(void *p_func);
+
+/**
+ * @brief Set a battery service parameter.
+ *
+ * NOTE: You can call this function with a battery service parameter type and it will set the
+ * battery service parameter. Battery service parameters are defined in @ref T_BAS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Battery service parameter type: @ref T_BAS_PARAM_TYPE
+ * @param[in] length Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ the parameter type and will be cast to the appropriate data type.
+ If param_type is set to @ref BAS_PARAM_BATTERY_LEVEL, p_value pointer to the current
+ charge level of a battery. Unit is org.bluetooth.unit.percentage. Minimum value is 0,
+ and maximum value is 100. 100% represents fully charged while 0% represents fully discharged.
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t battery_level = 80;
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ * \endcode
+ */
+bool bas_set_parameter(T_BAS_PARAM_TYPE param_type, uint8_t length, uint8_t *p_value);
+
+
+/**
+ * @brief Send notify battery level notification data .
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] battery_level The current charge level of a battery.
+ Unit is org.bluetooth.unit.percentage. Minimum value is 0, and maximum value is 100.
+ 100% represents fully charged while 0% represents fully discharged.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t battery_level = 90;
+ bas_battery_level_value_notify(conn_id, bas_id, battery_level);
+ }
+ * \endcode
+ */
+bool bas_battery_level_value_notify(uint8_t conn_id, T_SERVER_ID service_id, uint8_t battery_level);
+
+
+/**
+ * @brief Confirm for read battery level value request.
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] battery_level The current charge level of a battery.
+ Unit is org.bluetooth.unit.percentage. Minimum value is 0, and maximum value is 100.
+ 100% represents fully charged while 0% represents fully discharged.
+
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t battery_level = 90;
+ bas_battery_level_value_read_confirm(conn_id, bas_id, battery_level);
+ }
+ * \endcode
+ */
+bool bas_battery_level_value_read_confirm(uint8_t conn_id, T_SERVER_ID service_id,
+ uint8_t battery_level);
+
+/** @} End of BAS_Exported_Functions */
+
+/** @} End of BAS */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _BAS_H_ */
diff --git a/inc/bluetooth/profile/server/bas_config.h b/inc/bluetooth/profile/server/bas_config.h
new file mode 100644
index 0000000..6be3546
--- /dev/null
+++ b/inc/bluetooth/profile/server/bas_config.h
@@ -0,0 +1,39 @@
+#ifndef _BAS_CONFIG_H_
+#define _BAS_CONFIG_H_
+
+
+/** @defgroup BAS Battery Service
+ * @brief Battery service
+ * @{
+ */
+
+
+/** @defgroup BAS_CONFIG Battery Service Config
+ * @brief Battery service configuration file
+ * @{
+ */
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup BAS_Common_Exported_Macros BAS Common Exported Macros
+ * @{
+ */
+
+/** @details
+ Set BAS_BATTERY_LEVEL_NOTIFY_SUPPORT to 1 to support Battery level notification feature,
+ otherwise set it to 0.
+*/
+#define BAS_BATTERY_LEVEL_NOTIFY_SUPPORT 1
+
+
+/** @} End of BAS_Common_Exported_Macros */
+
+/** @} End of BAS_CONFIG */
+
+/** @} End of BAS */
+
+
+
+#endif
diff --git a/inc/bluetooth/profile/server/cscs.h b/inc/bluetooth/profile/server/cscs.h
new file mode 100644
index 0000000..7af191a
--- /dev/null
+++ b/inc/bluetooth/profile/server/cscs.h
@@ -0,0 +1,433 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file csc_service.h
+ * @brief Variables and interfaces for Cycling Speed and Cadence Service.
+ * @details CSC service data structs and functions.
+ * @author ethan_su
+ * @date 2017-10-13
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _CSCS_SERVICE_DEF_H
+#define _CSCS_SERVICE_DEF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "profile_server.h"
+#include "cscs_config.h"
+
+
+/** @defgroup CSCS Cycling Speed and Cadence Service
+ * @brief Cycling Speed and Cadence Service
+ * @details
+
+ The Cycling Speed and Cadence (CSC) Service exposes speed-related data and/or
+ cadence-related data while using the Cycling Speed and Cadence sensor (Server).
+ CSC Measurement, CSC Measurement Client Characteristic Configuration descriptor and CSC Feature characteristic are mandatory
+ exposed in the Cycling Speed and Cadence Service.
+ if the Multiple Sensor Locations feature is supported, CSC Feature will be mandatory, otherwise optional.
+ if at least one SC Control Point procedure is supported, SC Control Point and SC Control Point Client
+ Characteristic Configuration Descriptor will be mandatory, otherwise excluded.
+
+ The CSC Measurement characteristic is used to send speed-related data and/or cadence-related data.
+ The CSC Feature characteristic shall be used to describe the supported features of the Server.
+ The Sensor Location characteristic of the device may be used to describe the physical location of the Server when correctly fitted.
+
+ If the SC Control Point is supported, profiles utilizing this service are required to ensure that the Client configures the
+ SC Control Point characteristic for indications (i.e. via the Client Characteristic Configuration descriptor) at the first connection.
+
+ Application shall register Cycling Speed and Cadence service when initialization through @ref cscs_add_service function.
+
+ Application can set the Cycling Speed and Cadence parameters through @ref cscs_set_parameter function.
+
+ Application can send the measurement value through @ref cscs_meas_value_notify function.
+
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup CSCS_Exported_Constants CSC Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @defgroup CSCS_Optional_Features CSC Optional Features
+ * @brief CSC Service optional features bit mask
+ * @{
+ */
+
+/** @defgroup CSCS_Measurement_Flags CSC Measurement Flags
+ * @brief CSC measurement 'Flags' present bit mask
+ * @{
+ */
+#define CSCS_INC_WHEEL_REVOL_MASK (1)
+#define CSCS_INC_CRANK_REVOL_MASK (1<<1)
+#define CSCS_INC_ALL_PRESENTS (0x03)
+/** @} */
+
+/** @defgroup CSCS_Features CSC Features
+ * @brief CSC features bit mask
+ * @{
+ */
+#define CSCS_SUPPORT_WHEEL_REVOL_MASK (1)
+#define CSCS_SUPPORT_CRANK_REVOL_MASK (1<<1)
+#define CSCS_SUPPORT_MULTI_SENSOR_MASK (1<<2)
+#define CSCS_ALL_FEATURE_SUPPORTED (0x07)
+/** @} */
+
+/** @defgroup CSCS_Sensor_Location CSC Sensor Location
+ * @brief CSC supported sensor location bit mask
+ * @{
+ */
+#define CSCS_SENS_LOC_OTHER_MASK (1)
+#define CSCS_SENS_LOC_TOP_OF_SHOE_MASK (1<<1)
+#define CSCS_SENS_LOC_IN_SHOE_MASK (1<<2)
+#define CSCS_SENS_LOC_HIP_MASK (1<<3)
+#define CSCS_SENS_LOC_FRONT_WHEEL_MASK (1<<4)
+#define CSCS_SENS_LOC_LEFT_CRANK_MASK (1<<5)
+#define CSCS_SENS_LOC_RIGHT_CRANK_MASK (1<<6)
+#define CSCS_SENS_LOC_LEFT_PEDAL_MASK (1<<7)
+#define CSCS_SENS_LOC_RIGHT_PEDAL_MASK (1<<8)
+#define CSCS_SENS_LOC_FRONT_HUB_MASK (1<<9)
+#define CSCS_SENS_LOC_REAR_DROPOUT_MASK (1<<10)
+#define CSCS_SENS_LOC_CHAINSTAY_MASK (1<<11)
+#define CSCS_SENS_LOC_REAR_WHEEL_MASK (1<<12)
+#define CSCS_SENS_LOC_REAR_HUB_MASK (1<<13)
+#define CSCS_SENS_LOC_CHEST_MASK (1<<14)
+#define CSCS_ALL_SENS_LOC_SUPPORTED (0x7FFF)
+/** @} */
+
+/** @} End of CSCS_Optional_Features */
+
+/**
+* @brief CSC service parameter type
+*/
+typedef enum
+{
+ CSCS_PARAM_CSCS_FEATURE = 0x01,
+ CSCS_PARAM_INC_FLAG = 0x11,
+ CSCS_PARAM_WHEEL_REVOL,
+ CSCS_PARAM_WHEEL_EVT_TIME,
+ CSCS_PARAM_CRANK_REVOL,
+ CSCS_PARAM_CRANK_EVT_TIME,
+ CSCS_PARAM_CTL_PNT_PROG_CLR = 0x17,
+ CSCS_PARAM_SENSOR_LOC = 0x21,
+} T_CSCS_PARAM_TYPE;
+
+
+/** @defgroup CSCS_Upstream_Message CSC Upstream Message
+ * @brief Upstream message used to inform application.
+ * @{
+ */
+
+/** @defgroup CSCS_Read_Info CSC Read Info
+ * @brief Parameter for reading characteristic value.
+ * @{
+ */
+#define CSCS_READ_CSCS_FEATURE 1
+#define CSCS_READ_SENSOR_LOCATION 2
+/** @} */
+
+/** @defgroup CSCS_Notify_Indicate_Info CSC Notify Indicate Info
+ * @brief Parameter for enable or disable notification or indication.
+ * @{
+ */
+#define CSCS_NOTIFY_INDICATE_MEASUREMENT_ENABLE 1
+#define CSCS_NOTIFY_INDICATE_MEASUREMENT_DISABLE 2
+#define CSCS_NOTIFY_INDICATE_SC_CP_ENABLE 3
+#define CSCS_NOTIFY_INDICATE_SC_CP_DISABLE 4
+/** @} */
+
+/** @} End of CSCS_Upstream_Message */
+
+/** @defgroup CSCS_Control_Point CSC Control Point
+ * @brief Control Point
+ * @{
+ */
+
+/** @defgroup CSCS_Control_Point_OpCodes CSC Control Point OpCodes
+ * @brief Control Point OpCodes
+ * @{
+ */
+#define CSCS_CP_OPCODE_RESERVED 0x00
+#define CSCS_CP_OPCODE_SET_CUMULATIVE 0x01
+#define CSCS_CP_OPCODE_UPDATE_SENS_LOC 0x03
+#define CSCS_CP_OPCODE_REQ_SENS_LOC_LIST 0x04
+#define CSCS_CP_OPCODE_RSP_CODE 0x10
+/** @} */
+
+/** @defgroup CSCS_Control_Point_Response_Codes CSC Control Point Response Codes
+ * @brief Control Point Response Codes
+ * @{
+ */
+#define CSCS_CP_RSPCODE_RESERVED 0x00
+#define CSCS_CP_RSPCODE_SUCCESS 0x01
+#define CSCS_CP_RSPCODE_OPCODE_UNSUPPORT 0x02
+#define CSCS_CP_RSPCODE_INVALID_PARAMETER 0x03
+#define CSCS_CP_RSPCODE_OPERATION_FAILED 0x04
+/** @} */
+
+///@cond
+/** @brief Judge CSC Control Point operation is available or not. */
+#define CSCS_CTL_PNT_OPERATE_ACTIVE(x) \
+ ( (x == CSCS_CP_OPCODE_SET_CUMULATIVE) || \
+ (x == CSCS_CP_OPCODE_UPDATE_SENS_LOC) || \
+ (x == CSCS_CP_OPCODE_REQ_SENS_LOC_LIST) || \
+ (x == CSCS_CP_OPCODE_RSP_CODE) )
+///@endcond
+
+/** @} End of CSCS_Control_Point */
+
+/**
+ * @brief CSC sensor locations.
+ *
+ * All CSC sensor locations defined in spec.
+*/
+typedef enum
+{
+ CSCS_SENSOR_LOC_OTHER = 0,
+ CSCS_SENSOR_LOC_TOP_OF_SHOE = 1,
+ CSCS_SENSOR_LOC_IN_SHOE = 2,
+ CSCS_SENSOR_LOC_HIP = 3,
+ CSCS_SENSOR_LOC_FRONT_WHEEL = 4,
+ CSCS_SENSOR_LOC_LEFT_CRANK = 5,
+ CSCS_SENSOR_LOC_RIGHT_CRANK = 6,
+ CSCS_SENSOR_LOC_LEFT_PEDAL = 7,
+ CSCS_SENSOR_LOC_RIGHT_PEDAL = 8,
+ CSCS_SENSOR_LOC_FRONT_HUB = 9,
+ CSCS_SENSOR_LOC_REAR_DROPOUT = 10,
+ CSCS_SENSOR_LOC_CHAINSTAY = 11,
+ CSCS_SENSOR_LOC_REAL_WHEEL = 12,
+ CSCS_SENSOR_LOC_REAL_HUB = 13,
+ CSCS_SENSOR_LOC_CHEST = 14,
+ CSCS_SENSOR_LOC_MAX
+} T_CSCS_SENSOR_LOCATION;
+
+///@cond
+/** @brief Error codes defined in CSC service. */
+#define CSCS_ERR_PROC_ALREADY_IN_PROG 0x80
+#define CSCS_ERR_CCCD_IMPROPERLY_CFG 0x81
+
+/** @brief Max bytes of CSC Measurement data. */
+#define CSCS_MAX_MEASUREMENT_VALUE 11
+/** @brief Max bytes of CSC Control Point data. */
+#define CSCS_MAX_CTL_PNT_VALUE 18
+///@endcond
+
+/** @} End of CSCS_Exported_Constants */
+
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup CSCS_Exported_Types CSC Exported Types
+ * @brief
+ * @{
+ */
+
+/* Add all public types here */
+/** @defgroup CSCS_Callback_Data CSC Callback Data
+ * @brief CSC data struct for notification data to application.
+ * @{
+ */
+typedef union
+{
+ uint8_t sensor_location_value;
+ uint32_t cumulative_value;
+
+} T_CSCS_CP_PARAMETER;
+
+typedef struct
+{
+ uint8_t opcode; //!< ref: @ref CSCS_Control_Point_OpCodes
+ T_CSCS_CP_PARAMETER cp_parameter;
+} T_CSCS_WRITE_MSG;
+
+typedef union
+{
+ uint8_t notification_indification_index; //!< ref: @ref CSCS_Notify_Indicate_Info
+ uint8_t read_value_index; //!< ref: @ref CSCS_Read_Info
+ T_CSCS_WRITE_MSG write;
+} T_CSCS_UPSTREAM_MSG_DATA;
+
+/** CSC service data to inform application */
+typedef struct
+{
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_CSCS_UPSTREAM_MSG_DATA msg_data;
+} T_CSCS_CALLBACK_DATA;
+/** @} */
+
+/** @brief CSC measurement data, variable length during connection, max can reach 11 bytes */
+typedef struct
+{
+ uint8_t cur_length; /**< length of current CSC measurement data. */
+ uint8_t value[CSCS_MAX_MEASUREMENT_VALUE];/**< value of current CSC measurement data. */
+} T_CSCS_MEASUREMENT;
+
+/**
+ * @brief CSC Control Point data, variable length during connection, max can reach 17 bytes.
+ *
+ * CSC Control Point data used to store the Control Point Command received from the client.
+*/
+typedef struct
+{
+ uint8_t cur_length; /**< length of current CSC Control Point data, . */
+ uint8_t
+ value[CSCS_MAX_CTL_PNT_VALUE]; /**< value of current CSC Control Point data, . */
+} T_CSCS_CONTROL_POINT;
+/** @} End of CSCS_Exported_Types */
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/** @defgroup CSCS_Exported_Functions CSC Exported Functions
+ * @brief
+ * @{
+ */
+
+
+/**
+ * @brief Add cycling speed and cadence service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ cscs_id = cscs_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID cscs_add_service(void *p_func);
+
+/**
+ * @brief Set a cycling speed and cadence service parameter.
+ *
+ * NOTE: You can call this function with a cycling speed and cadence service parameter type and it will set the
+ * cycling speed and cadence service parameter. Cycling speed and cadence service parameters are defined in @ref T_CSCS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Cycling speed and cadence service parameter type: @ref T_CSCS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and will be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ cscs_set_parameter(CSCS_PARAM_CTL_PNT_PROG_CLR, 0, NULL);
+ }
+ * \endcode
+ */
+bool cscs_set_parameter(T_CSCS_PARAM_TYPE param_type, uint8_t len, void *p_value);
+
+/**
+ * @brief Get a cycling speed and cadence parameter.
+ *
+ * NOTE: You can call this function with a cycling speed and cadence parameter type and it will get a
+ * gulcose parameter. Cycling speed and cadence service parameters are defined in @ref T_CSCS_PARAM_TYPE.
+ *
+ * @param[in] param_type Cycling speed and cadence parameter type: @ref T_CSCS_PARAM_TYPE
+ * @param[in,out] p_value Pointer to the location to get the parameter value. This is dependent on
+ * the parameter type and will be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_INVALID_PARAM Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ int record_num;
+ gls_get_parameter(GLS_PARAM_RECORD_NUM, &len, &record_num);
+ }
+ * \endcode
+ */
+bool cscs_get_parameter(T_CSCS_PARAM_TYPE param_type, void *p_value);
+
+
+/**
+ * @brief Send measurement value notification data .
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ bool op_result;
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ cscs_set_parameter(CSCS_PARAM_WHEEL_REVOL, sizeof(cscs_cul_value), &cscs_cul_value);
+ op_result = cscs_meas_value_notify(conn_id, cscs_id);
+ }
+ * \endcode
+ */
+bool cscs_meas_value_notify(uint8_t conn_id, T_SERVER_ID service_id);
+
+
+
+/**
+ * @brief Send control point indication.
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] op_code Op code.
+ * @param[in] rsp_code Response code.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ */
+bool cscs_ctl_pnt_indicate(uint8_t conn_id, T_SERVER_ID service_id, uint8_t op_code,
+ uint8_t rsp_code);
+
+
+
+
+/** @} End of CSCS_Exported_Functions */
+
+/** @} End of CSC */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _CSCS_DEF_H */
+
diff --git a/inc/bluetooth/profile/server/cscs_config.h b/inc/bluetooth/profile/server/cscs_config.h
new file mode 100644
index 0000000..7b0d3d6
--- /dev/null
+++ b/inc/bluetooth/profile/server/cscs_config.h
@@ -0,0 +1,40 @@
+#ifndef _CSCS_CONFIG_H_
+#define _CSCS_CONFIG_H_
+
+
+
+/** @defgroup CSCS Cycling Speed and Cadence Service
+ * @brief Cycling Speed and Cadence Service
+ * @{
+ */
+
+/** @defgroup CSCS_CONFIG Cycling Speed and Cadence Service Config
+ * @brief Cycling Speed and Cadence service configuration file
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup CSCS_Common_Exported_Macros CSCS Common Exported Macros
+ * @{
+ */
+
+#define CSCS_MULTIPLE_SENSOR_LOCATIONS_SUPPORT
+#define CSCS_SC_CONTROL_POINT_SUPPORT
+
+/** @brief Index of each characteristic in CSC service database. */
+#define GATT_SVC_CSCS_MEASUREMENT_INDEX 2
+#define GATT_SVC_CSCS_FEATURE_INDEX 5
+#define GATT_SVC_CSCS_SENS_LOC_INDEX 7
+#define GATT_SVC_CSCS_CTL_PNT_INDEX 9
+#define GATT_SVC_CSCS_MEAS_CCCD_INDEX (GATT_SVC_CSCS_MEASUREMENT_INDEX + 1)
+#define GATT_SVC_CSCS_CTL_PNT_CCCD_INDEX (GATT_SVC_CSCS_CTL_PNT_INDEX + 1)
+
+/** @} End of CSCS_Common_Exported_Macros */
+
+/** @} End of CSCS_CONFIG */
+
+/** @} End of CSCS */
+
+#endif
diff --git a/inc/bluetooth/profile/server/dfu_service.h b/inc/bluetooth/profile/server/dfu_service.h
new file mode 100644
index 0000000..a5af29f
--- /dev/null
+++ b/inc/bluetooth/profile/server/dfu_service.h
@@ -0,0 +1,117 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file dfu_service.h
+* @brief
+* @details
+* @author ken_mei
+* @date 02-09-2016
+* @version v1.0.0
+******************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2015 Realtek Semiconductor Corporation</center></h2>
+******************************************************************************
+*/
+
+#ifndef _DFU_SERVICE_H_
+#define _DFU_SERVICE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "profile_server.h"
+#include "patch_header_check.h"
+#include "dfu_api.h"
+
+#define DFU_NOTIFY_ENABLE 1
+#define DFU_NOTIFY_DISABLE 2
+
+/*attribut index*/
+#define INDEX_DFU_PACKET_VALUE 0x02
+#define INDEX_DFU_CONTROL_POINT_CHAR_VALUE 0x04
+#define INDEX_DFU_CHAR_CCCD_INDEX 0x05
+
+
+
+typedef struct _T_DFU_CTRL_POINT
+{
+ uint8_t opcode;
+ T_IMG_CTRL_HEADER_FORMAT start_dfu; /* start dfu trans first 12 bytes ctrl header*/
+} T_DFU_CTRL_POINT, * P_DFU_CTRL_POINT;
+
+typedef struct
+{
+ T_IMG_CTRL_HEADER_FORMAT ctrl_header;
+ uint32_t image_total_length;
+ uint32_t origin_image_version;
+ uint32_t cur_offset;
+ uint8_t mtu_size;
+ bool dfu_conn_para_update_in_progress;
+ uint16_t dfu_conn_interval;
+ uint16_t dfu_conn_lantency;
+} T_DFU_PARA;
+
+typedef struct
+{
+ T_IMG_ID image_id;
+ uint32_t image_size;
+ uint32_t image_offset;
+} T_TEMP_IMAGE_INFO;
+
+typedef enum
+{
+ DFU_FAIL_UPDATE_FLASH,
+ DFU_FAIL_SYSTEM_RESET_CMD,
+ DFU_FAIL_EXCEED_MAX_BUFFER_SIZE,
+ DFU_FAIL_EXCEED_IMG_TOTAL_LEN,
+
+} T_DFU_FAIL_REASON;
+
+typedef enum
+{
+ DFU_WRITE_ATTR_ENTER,
+ DFU_WRITE_ATTR_EXIT,
+ DFU_WRITE_START,
+ DFU_WRITE_DOING,
+ DFU_WRITE_END,
+ DFU_WRITE_FAIL,
+} T_DFU_WRITE_OPCODE;
+
+
+typedef struct
+{
+ uint8_t opcode;
+ uint8_t write_attrib_index;
+ uint16_t length;
+ uint8_t *p_value;
+} T_DFU_WRITE_MSG;
+
+typedef union _TDFU_UPSTREAM_MSG_DATA
+{
+ uint8_t notification_indification_index;
+ T_DFU_WRITE_MSG write;
+} T_DFU_UPSTREAM_MSG_DATA;
+
+/** Dfu service data to inform application */
+typedef struct _TDFU_CALLBACK_DATA
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_DFU_UPSTREAM_MSG_DATA msg_data;
+} T_DFU_CALLBACK_DATA;
+
+extern uint8_t *p_ota_temp_buffer_head;
+extern uint16_t g_ota_tmp_buf_used_size;
+extern T_DFU_PARA g_dfu_para;
+
+extern void dfu_notify_conn_para_update_req(uint8_t conn_id, T_DFU_ARV_ERROR_CODE error_code);
+extern void dfu_service_handle_valid_fw(uint8_t conn_id);
+extern uint8_t dfu_add_service(void *pFunc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/inc/bluetooth/profile/server/dis.h b/inc/bluetooth/profile/server/dis.h
new file mode 100644
index 0000000..a56df39
--- /dev/null
+++ b/inc/bluetooth/profile/server/dis.h
@@ -0,0 +1,228 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file dis.h
+ * @brief Head file for using device information service.
+ * @details DIS data structs and external functions declaration.
+ * @author
+ * @date
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _DEVICE_INFO_SERVICE_H_
+#define _DEVICE_INFO_SERVICE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "profile_server.h"
+
+
+/**
+ * @defgroup DIS Device Information Service
+ * @brief Device information service
+ * @details
+ The Device Information Service exposes manufacturer and/or vendor information about a device.
+ This module implements the Device Information Service.
+ The Device Information Service may expose one or more of the characteristics. It can be
+ configured in file @ref dis_config.h.
+
+ Application shall register device information service when initialization.
+
+ * Sample code:
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ dis_service_id = dis_add_service(app_profile_callback);
+ }
+ * \endcode
+
+ When characteristic value was read, write or cccd updated by remote device, @ref app_profile_callback will be
+ called.
+ Application shall set dis parameter value by call @ref dis_set_parameter.
+
+ * Sample code:
+ * \code{.c}
+ T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+ {
+ ...
+ if (dis_service_id == service_id)
+ {
+ T_DIS_CALLBACK_DATA *p_dis_cb_data = (T_DIS_CALLBACK_DATA *)p_data;
+ switch (p_dis_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_dis_cb_data->msg_data.read_value_index == DIS_READ_MANU_NAME_INDEX)
+ {
+ const uint8_t dis_manufacture_name[] = "Realtek BT";
+ dis_set_parameter(DIS_PARAM_MANUFACTURER_NAME,
+ sizeof(dis_manufacture_name),
+ (void *)dis_manufacture_name);
+ }
+ else if (p_dis_cb_data->msg_data.read_value_index == DIS_READ_MODEL_NUM_INDEX)
+ {
+ const uint8_t dis_model_number[] = "Model Num 1.0";
+ dis_set_parameter(DIS_PARAM_MODEL_NUMBER,
+ sizeof(dis_model_number),
+ (void *)dis_model_number);
+ }
+ ...
+ ...
+
+ }
+
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ * \endcode
+
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup DIS_Exported_Macros DIS Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @defgroup DIS_READ_INFO_INDEX DIS Read Informatio Index
+ * @brief Read characteristic value index.
+ * @{
+ */
+#define DIS_READ_MANU_NAME_INDEX 1
+#define DIS_READ_MODEL_NUM_INDEX 2
+#define DIS_READ_SERIAL_NUM_INDEX 3
+#define DIS_READ_HARDWARE_REV_INDEX 4
+#define DIS_READ_FIRMWARE_REV_INDEX 5
+#define DIS_READ_SOFTWARE_REV_INDEX 6
+#define DIS_READ_SYSTEM_ID_INDEX 7
+#define DIS_READ_IEEE_CERT_STR_INDEX 8
+#define DIS_READ_PNP_ID_INDEX 9
+/** @} */
+
+#define DIS_SYSTEM_ID_LENGTH 8
+#define DIS_PNP_ID_LENGTH 7
+
+/** @} End of DIS_Exported_Macros */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup DIS_Exported_Types DIS Exported Types
+ * @brief
+ * @{
+ */
+/** @defgroup DIS_PARAM_TYPE DIS parameter type
+* @brief Type of parameters set/got from application.
+* @{
+*/
+typedef enum
+{
+ DIS_PARAM_MANUFACTURER_NAME,
+ DIS_PARAM_MODEL_NUMBER,
+ DIS_PARAM_SERIAL_NUMBER,
+ DIS_PARAM_HARDWARE_REVISION,
+ DIS_PARAM_FIRMWARE_REVISION,
+ DIS_PARAM_SOFTWARE_REVISION,
+ DIS_PARAM_SYSTEM_ID,
+ DIS_PARAM_IEEE_DATA_LIST,
+ DIS_PARAM_PNP_ID
+} T_DIS_PARAM_TYPE;
+/** @} */
+
+/** DIS upstream message data*/
+typedef union
+{
+ uint8_t read_value_index;
+} T_DIS_UPSTREAM_MSG_DATA;
+
+/** DIS callback data*/
+typedef struct
+{
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ uint8_t conn_id;
+ T_DIS_UPSTREAM_MSG_DATA msg_data;
+} T_DIS_CALLBACK_DATA;
+
+/** @} End of DIS_Exported_Types */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup DIS_Exported_Functions DIS Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Set a device information service parameter.
+ *
+ * NOTE: You can call this function with a device information service parameter type and it will set the
+ * device information service parameter. Device information service parameters are defined in @ref T_DIS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Device information service parameter type: @ref T_DIS_PARAM_TYPE
+ * @param[in] length Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ const uint8_t dis_manufacture_name[] = "Realtek BT";
+ dis_set_parameter(DIS_PARAM_MANUFACTURER_NAME,
+ sizeof(dis_manufacture_name),
+ (void *)dis_manufacture_name);
+ }
+ * \endcode
+ */
+bool dis_set_parameter(T_DIS_PARAM_TYPE param_type, uint8_t length, void *p_value);
+
+/**
+ * @brief Add device information service to the BLE stack database.
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ dis_id = dis_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+
+T_SERVER_ID dis_add_service(void *p_func);
+
+/** @} End of DIS_Exported_Functions */
+
+/** @} End of DIS */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _DEVICE_INFO_SERVICE_H_ */
diff --git a/inc/bluetooth/profile/server/dis_config.h b/inc/bluetooth/profile/server/dis_config.h
new file mode 100644
index 0000000..3c36523
--- /dev/null
+++ b/inc/bluetooth/profile/server/dis_config.h
@@ -0,0 +1,155 @@
+#ifndef _DIS_CONFIG_H_
+#define _DIS_CONFIG_H_
+
+
+
+/** @defgroup DIS Device Information Service
+ * @brief Device information service
+ * @{
+ */
+
+
+/** @defgroup DIS_CONFIG Device Information Service Config
+ * @brief Device information service config
+ * @{
+ */
+
+/** @defgroup DIS_Common_Exported_Macros Device Information Service Config Common Exported Macros
+ * @{
+ */
+
+
+/** @defgroup DIS_Config_Supported_Features Device Information Service Config Supported Features
+ * @brief
+ The Device Information Service may expose one or more of the characteristics, user can
+ config DIS_CHAR_XXX_SUPPORT to 1 to support it, otherwise set it to 0.
+ * @{
+ */
+
+/** @details
+ Set DIS_CHAR_MANUFACTURER_NAME_SUPPORT to 1 to support Manufacturer Name String characteristic,
+ otherwise set it to 0.
+*/
+#define DIS_CHAR_MANUFACTURER_NAME_SUPPORT 1
+
+/** @details
+ Set DIS_CHAR_MODEL_NUMBER_SUPPORT to 1 to support Model Number String characteristic,
+ otherwise set it to 0.
+*/
+#define DIS_CHAR_MODEL_NUMBER_SUPPORT 1
+
+/** @details
+ Set DIS_CHAR_SERIAL_NUMBER_SUPPORT to 1 to support Serial Number String characteristic,
+ otherwise set it to 0.
+*/
+#define DIS_CHAR_SERIAL_NUMBER_SUPPORT 1
+
+/** @details
+ Set DIS_CHAR_FIRMWARE_REVISION_SUPPORT to 1 to support Firmware Revision String characteristic,
+ otherwise set it to 0.
+*/
+#define DIS_CHAR_FIRMWARE_REVISION_SUPPORT 1
+
+/** @details
+ Set DIS_CHAR_HARDWARE_REVISION_SUPPORT to 1 to support Hardware Revision String characteristic,
+ otherwise set it to 0.
+*/
+#define DIS_CHAR_HARDWARE_REVISION_SUPPORT 1
+
+/** @details
+ Set DIS_CHAR_SOFTWARE_REVISION_SUPPORT to 1 to support Software Revision String characteristic,
+ otherwise set it to 0.
+*/
+#define DIS_CHAR_SOFTWARE_REVISION_SUPPORT 1
+
+
+/** @details
+ Set DIS_CHAR_SYSTEM_ID_SUPPORT to 1 to support System ID characteristic,
+ otherwise set it to 0.
+*/
+#define DIS_CHAR_SYSTEM_ID_SUPPORT 1
+
+
+/** @details
+ Set DIS_CHAR_IEEE_CERTIF_DATA_LIST_SUPPORT to 1 to support IEEE 11073-20601 Regulatory Certification Data List characteristic,
+ otherwise set it to 0.
+*/
+#define DIS_CHAR_IEEE_CERTIF_DATA_LIST_SUPPORT 1
+
+/** @details
+ Set DIS_CHAR_PNP_ID_SUPPORT to 1 to support PnP ID characteristic,
+ otherwise set it to 0.
+*/
+#define DIS_CHAR_PNP_ID_SUPPORT 1
+/**
+ * @}
+ */
+
+
+
+/** @defgroup DIS_Config_Max_Char_Value_Length Device Information Service Config Supported Value Length
+ * @brief
+ The max length of characteristic value can be configured here.
+ * @{
+ */
+#ifdef DIS_CHAR_MANUFACTURER_NAME_SUPPORT
+#define DIS_CHAR_MANUFACTURER_NAME_STR_MAX_LENGTH 20 /**< Max length of Manufacturer Name String characteristic value*/
+#endif
+
+#ifdef DIS_CHAR_MODEL_NUMBER_SUPPORT
+#define DIS_CHAR_MODEL_NUMBER_STR_MAX_LENGTH 20 /**< Max length of Model Number String characteristic value*/
+#endif
+
+#ifdef DIS_CHAR_SERIAL_NUMBER_SUPPORT
+#define DIS_CHAR_SERIAL_NUMBER_STR_MAX_LENGTH 20 /**< Max length of Serial Number String characteristic value*/
+#endif
+
+#ifdef DIS_CHAR_FIRMWARE_REVISION_SUPPORT
+#define DIS_CHAR_FIRMWARE_REVISION_STR_MAX_LENGTH 20 /**< Max length of Firmware Revision String characteristic value*/
+#endif
+
+#ifdef DIS_CHAR_HARDWARE_REVISION_SUPPORT
+#define DIS_CHAR_HARDWARE_REVISION_STR_MAX_LENGTH 20 /**< Max length of Hardware Revision String scharacteristic value*/
+#endif
+
+#ifdef DIS_CHAR_SOFTWARE_REVISION_SUPPORT
+#define DIS_CHAR_SOFTWARE_REVISION_STR_MAX_LENGTH 20 /**< Max length of Software Revision String characteristic value*/
+#endif
+
+
+#ifdef DIS_CHAR_IEEE_CERTIF_DATA_LIST_SUPPORT
+#define DIS_CHAR_IEEE_CERTIF_DATA_LIST_MAX_LENGTH 30 /**< Max length of IEEE 11073-20601 Regulatory Certification Data List characteristic value*/
+#endif
+/**
+ * @}
+ */
+
+
+
+/** @defgroup DIS_Config_Char_Value_Index Device Information Service Config Characteristic Value Index
+ * @brief
+ Attribute index value of each characteristic shall be configured by characteristic supported. If some
+ * @{
+ */
+#define GATT_SVC_DIS_MANU_NAME_INDEX 2 /**< Attribute index of Manufacturer Name String characteristic */
+#define GATT_SVC_DIS_MODEL_NUM_INDEX 4 /**< Attribute index of Model Number String characteristic */
+#define GATT_SVC_DIS_SERIAL_NUM_INDEX 6 /**< Attribute index of Serial Number String characteristic */
+#define GATT_SVC_DIS_HARDWARE_REV_INDEX 8 /**< Attribute index of Hardware Revision String characteristic */
+#define GATT_SVC_DIS_FIRMWARE_REV_INDEX 10 /**< Attribute index of Firmware Revision String characteristic */
+#define GATT_SVC_DIS_SOFTWARE_REV_INDEX 12 /**< Attribute index of Software Revision String characteristic */
+#define GATT_SVC_DIS_SYSTEM_ID_INDEX 14 /**< Attribute index of System ID characteristic */
+#define GATT_SVC_DIS_IEEE_CERT_STR_INDEX 16 /**< Attribute index of IEEE 11073-20601 Regulatory Certification Data List characteristic */
+#define GATT_SVC_DIS_PNP_ID_INDEX 18 /**< Attribute index of Pnp ID characteristic */
+/**
+ * @}
+ */
+
+
+/** @} End of DIS_Common_Exported_Macros */
+
+/** @} End of DIS_CONFIG */
+
+/** @} End of DIS */
+
+
+#endif
diff --git a/inc/bluetooth/profile/server/gls.h b/inc/bluetooth/profile/server/gls.h
new file mode 100644
index 0000000..363598c
--- /dev/null
+++ b/inc/bluetooth/profile/server/gls.h
@@ -0,0 +1,638 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gls.h
+ * @brief Head file for using glucose service.
+ * @details Glusose data types and external functions declaration.
+ * @author bill
+ * @date 2017-6-8
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _GLS_H
+#define _GLS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "profile_server.h"
+#include "gls_config.h"
+
+
+/** @defgroup GLS Glucose Service
+ * @brief Glucose service
+ * @details
+
+ The Glucose Service exposes glucose and other data related to a personal glucose sensor for
+ consumer healthcare applications and is not designed for clinical use.
+ Glucose Measurement, Glucose Measurement - Client Characteristic Configuration descriptor,
+ Glucose Feature, Record Access Control Point, Record Access Control Point - Client Characteristic Configuration descriptor
+ are mandatory exposed in the Glucose Service.
+ Glucose Measurement Context is optional, and if the Glucose Measurement Context characteristic is supported,
+ Glucose Measurement Context - Client Characteristic Configuration descriptor shall be mandatory.
+
+ The Glucose Measurement characteristic shall be used to send glucose measurements.
+ The Glucose Measurement Context characteristic may be used to send additional contextual information relative to
+ a Glucose Measurement characteristic.
+ The Glucose Feature characteristic shall be used to describe the supported features of the Server.
+ For this service to operate, profiles or other applications utilizing this service will need to ensure that
+ the Client configures the Record Access Control Point (RACP) characteristic for indications.
+ The Client must perform a write to the Record Access Control Point to execute a desired procedure at the Server.
+
+ Application shall register glucose service when initialization through @ref gls_add_service function.
+
+ Application can set the glucose service parameters through @ref gls_set_parameter function.
+
+ Application can send the glucose measurements through @ref gls_glc_measurement_notify function.
+
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+
+/** @defgroup GLS_Exported_Macros GLS Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @defgroup GLS_Feature GLS Feature
+ * @brief glucose feature bits.
+ * @{
+ */
+#define GLC_FEATURES_LOW_BATTERY 0x0001
+#define GLC_FEATURES_SENSOR_MALFUNCTION 0x0002
+#define GLC_FEATURES_SENSOR_SAMPLE_SIZE 0x0004
+#define GLC_FEATURES_SENSOR_STRIP_INS_ERROR 0x0008
+#define GLC_FEATURES_SENSOR_STRIP_TYPE_ERROR 0x0010
+#define GLC_FEATURES_SENSOR_RESULT_HIGH_LOW 0x0020
+#define GLC_FEATURES_SENSOR_TEMP_HIGH_LOW 0x0040
+#define GLC_FEATURES_SENSOR_READ_INTERRUPT 0x0080
+#define GLC_FEATURES_GENERAL_DEVICE_FAULT 0x0100
+#define GLC_FEATURES_TIME_FAULT 0x0200
+#define GLC_FEATURES_MULTIPLE_BOND 0x0400
+
+/** GLC features supported: */
+#define GLC_FEATURES (GLC_FEATURES_LOW_BATTERY | \
+ GLC_FEATURES_SENSOR_STRIP_INS_ERROR)
+/** @} */
+
+/**
+* @brief Gulcose service parameter type
+*/
+typedef enum
+{
+ /** glucose measurement parameters */
+ GLS_PARAM_GLC_MS_FLAG = 0x01,
+ GLS_PARAM_GLC_MS_BASE_TIME,
+ GLS_PARAM_GLC_MS_TIME_OFFSET,
+ GLS_PARAM_GLC_MS_CONCENTRATION,
+ GLS_PARAM_GLC_MS_CONCENTRATION_UNITS,
+ GLS_PARAM_GLC_MS_TYPE_SAMPLE_LOCATION,
+ GLS_PARAM_GLC_MS_SENSOR_STATUS_ANNUNCIATION,
+
+ /** glucose measurement context parameters */
+ GLS_PARAM_GLC_MS_CT_FLAG,
+ GLS_PARAM_GLC_MS_CT_CARBOHYDRATE_ID,
+ GLS_PARAM_GLC_MS_CT_CARBOHYDRATE,
+ GLS_PARAM_GLC_MS_CT_MEAL,
+ GLS_PARAM_GLC_MS_CT_TESTER_HEALTH,
+ GLS_PARAM_GLC_MS_CT_EXERCISE_DURATION,
+ GLS_PARAM_GLC_MS_CT_EXERCISE_INTENSITY,
+ GLS_PARAM_GLC_MS_CT_MEDICATION_ID,
+ GLS_PARAM_GLC_MS_CT_MEDICATION,
+ GLS_PARAM_GLC_MS_CT_MEDICATION_UNITS,
+ GLS_PARAM_GLC_MS_CT_HbA1c,
+
+ /** Parameters that can be get by application */
+ GLS_PARAM_GLC_FEATURES,
+ GLS_PARAM_CTL_PNT_PROG_CLR,
+ GLS_PARAM_RECORD_NUM,
+ GLS_PARAM_RECORD_SEQ_NUM
+} T_GLS_PARAM_TYPE;
+
+
+/** @defgroup GLS_Upstream_Message GLS Upstream Message
+ * @brief Upstream message used to inform application.
+ * @{
+ */
+
+/** @defgroup GLS_Read_Info GLS Read Info
+ * @brief Parameter for read characteristic value.
+ * @{
+ */
+#define GLS_EVT_READ_FEATURE 0x01
+/** @} */
+
+/** @defgroup GLS_Notify_Indicate_Info GLS Notify Indicate Info
+ * @brief Parameter for enable or disable notification or indication.
+ * @{
+ */
+#define GLS_EVT_GLC_MEASUREMENT_NOTIFY_ENABLE 0x01
+#define GLS_EVT_GLC_MEASUREMENT_NOTIFY_DISABLE 0x02
+#define GLS_EVT_GLC_MEASUREMENT_CONTEXT_NOTIFY_ENABLE 0x03
+#define GLS_EVT_GLC_MEASUREMENT_CONTEXT_NOTIFY_DISABLE 0x04
+#define GLS_EVT_GLC_RACP_INDICATE_ENABLE 0x05
+#define GLS_EVT_GLC_RACP_INDICATE_DISABLE 0x06
+/** @} */
+
+/** @} End of GLS_Upstream_Message */
+
+/** @defgroup GLS_Control_Point GLS Control Point
+ * @brief glucose record access control point
+ * @{
+ */
+
+/** @brief Glucose Record Access Control Point OpCodes. */
+typedef enum
+{
+ GLC_RACP_OPCODE_RESERVED = 0x00,
+ GLC_RACP_OPCODE_REPORT_RECS = 0x01,
+ GLC_RACP_OPCODE_DELETE_RECS = 0x02,
+ GLC_RACP_OPCODE_ABORT_OPERATION = 0x03,
+ GLC_RACP_OPCODE_REPORT_NBR_OF_RECS = 0x04,
+ GLC_RACP_OPCODE_NBR_OF_RECS_RESP = 0x05,
+ GLC_RACP_OPCODE_RESP_CODE = 0x06
+} T_GLC_CTRL_POINT_OPCODE;
+
+/** @brief Check glucose Record Access Control Point operation is available or not. */
+#define GLC_RACP_OPERATION_ACTIVE(x) \
+ ((x >= GLC_RACP_OPCODE_REPORT_RECS) && \
+ (x <= GLC_RACP_OPCODE_RESP_CODE))
+
+/** @brief Glucose Record Access Control Point Operator. */
+typedef enum
+{
+ GLC_RACP_OPERATOR_NULL = 0x00,
+ GLC_RACP_OPERATOR_ALL_RECS = 0x01,
+ GLC_RACP_OPERATOR_LT_EQ = 0x02,
+ GLC_RACP_OPERATOR_GT_EQ = 0x03,
+ GLC_RACP_OPERATOR_RANGE = 0x04,
+ GLC_RACP_OPERATOR_FIRST = 0x05,
+ GLC_RACP_OPERATOR_LAST = 0x06
+} T_GLC_CTRL_POINT_OPERATOR;
+
+/** @brief Filter Type values. */
+typedef enum
+{
+ GLC_RACP_FILTER_TYPE_RESERVED = 0x00,
+ GLC_RACP_FILTER_TYPE_SEQ_NBR = 0x01,
+ GLC_RACP_FILTER_TYPE_TIME = 0x02
+} T_GLC_CTRL_POINT_FILTER_TYPE;
+
+/** @brief Glucose Record Access Control Point Response Codes. */
+typedef enum
+{
+ GLC_RACP_RESP_RESERVED = 0x00,
+ GLC_RACP_RESP_SUCCESS = 0x01,
+ GLC_RACP_RESP_OPCODE_NOT_SUPPORTED = 0x02,
+ GLC_RACP_RESP_INVALID_OPERATOR = 0x03,
+ GLC_RACP_RESP_OPERATOR_NOT_SUPPORTED = 0x04,
+ GLC_RACP_RESP_INVALID_OPERAND = 0x05,
+ GLC_RACP_RESP_NO_RECS_FOUND = 0x06,
+ GLC_RACP_RESP_ABORT_UNSUCCESSFUL = 0x07,
+ GLC_RACP_RESP_PROC_NOT_COMPLETED = 0x08,
+ GLC_RACP_RESP_OPERAND_NOT_SUPPORTED = 0x09
+} T_GLC_CTRL_POINT_RESP_CODES;
+
+/** @brief profile specific attribute protocol application error codes */
+#define GLC_ERR_PROC_ALREADY_IN_PROGRESS 0x80
+#define GLC_ERR_CCCD_IMPROPERLY_CONFIGURED 0x81
+/** @} */
+
+/** @brief concentration unit */
+#define GLC_FLAGS_UNITS_MOL_L_ON 1
+#define GLC_FLAGS_UNITS_KG_L_ON 0
+
+/** @brief medication unit */
+#define GLC_FLAGS_MEDICATION_UNITS_LITERS_ON 1
+#define GLC_FLAGS_MEDICATION_UNITS_KG_ON 0
+
+/** GLC sensor status annunciation bits */
+#define GLC_SS_ANNUNC_LOW_BATTERY 0x0001
+
+/** special short float values */
+#define SFLOAT_VALUE_NaN 0x07ff /**< not a number */
+#define SFLOAT_VALUE_NRes 0x0800 /**< not at this resolution */
+#define SFLOAT_VALUE_PlusINFINITY 0x07fe /**< + INFINITY */
+#define SFLOAT_VALUE_MinusINFINITY 0x0802 /**< - INFINITY */
+#define SFLOAT_VALUE_RFU 0x0801 /**< reserved for future use */
+
+/** @brief RACP database parameters */
+#define GLC_RACP_DATABASE_SIZE (GLC_RACP_MAX_NBR_OF_STORED_RECS + 1)
+#define GLC_RACP_INIT_SEQ_NBR_DEFAULT 0
+
+/** @} End of GLS_Exported_Macros */
+
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/** @defgroup GLS_Exported_Types GLS Exported Types
+ * @brief
+ * @{
+ */
+
+/* Add all public types here */
+
+/** GLC measurement flag bits */
+typedef struct
+{
+ uint8_t time_offset: 1; /**< time offset */
+ uint8_t con_ts_loc: 1; /**< concentration, time/sample location */
+ uint8_t con_units: 1; /**< 0: kg/L, 1: mol/L */
+ uint8_t ss_annuciation: 1; /**< sensor status annunciation */
+ uint8_t ctxt_info_follows: 1; /**< context information */
+ uint8_t rfu: 3;
+} T_GLC_MEASUREMENT_FLAG;
+
+/** GLC measurement context flag bits */
+typedef struct
+{
+ uint8_t carbohydrate: 1; /**< Carbohydrates ID and field */
+ uint8_t meal: 1; /**< Meal ID and field */
+ uint8_t tester_health: 1; /**< Tester-Health field */
+ uint8_t exercise: 1; /**< Exercise Duration and Intensity field */
+ uint8_t medication: 1; /**< Medication ID and field */
+ uint8_t medication_units: 1; /**< Medication units 0:kg, 1:liter */
+ uint8_t hb_a1c: 1; /**< hb_a1c field */
+ uint8_t ext_flags: 1; /**< extended flag */
+} T_GLC_MSR_CTXT_FLAG;
+
+typedef uint8_t TIMESTAMP[7];
+typedef uint8_t SFLOAT[2]; /* 4 bit (MSB) exponent, 12 bit mantissa */
+
+typedef struct
+{
+ T_GLC_MEASUREMENT_FLAG flags;
+ uint16_t seq_num;
+ TIMESTAMP base_time;
+#if (GLC_INCLUDE_TIME_OFFSET)
+ int16_t time_offset; //minutes
+#endif
+#if (GLC_INCLUDE_CONC_TS_LOC)
+ SFLOAT concentration;
+ uint8_t type_sample_location;
+#endif
+#if (GLC_INCLUDE_SS_ANNUNC)
+ uint16_t ss_annunciation;
+#endif
+} T_GLC_MEASUREMENT_VALUE;
+
+typedef struct
+{
+ T_GLC_MSR_CTXT_FLAG flags;
+ uint16_t seq_num;
+#if (GLC_INCLUDE_EXT_FLAGS)
+ uint8_t ext_flags;
+#endif
+#if (GLC_INCLUDE_CARBOHYDRATE)
+ uint8_t carbohydrate_ID;
+ SFLOAT carbohydrate;
+#endif
+#if (GLC_INCLUDE_MEAL)
+ uint8_t meal;
+#endif
+#if (GLC_INCLUDE_TESTER_HEALTH)
+ uint8_t tester_health;
+#endif
+#if (GLC_INCLUDE_EXERCISE)
+ uint16_t exercise_duration;
+ uint8_t exercise_intensity;
+#endif
+#if (GLC_INCLUDE_MEDICATION)
+ uint8_t medication_ID;
+ SFLOAT medication;
+#endif
+#if (GLC_INCLUDE_HbA1c)
+ SFLOAT hb_a1c;
+#endif
+} T_GLC_MEASUREMENT_CONTEXT;
+
+typedef struct
+{
+ T_GLC_CTRL_POINT_OPCODE op_code;
+ T_GLC_CTRL_POINT_OPERATOR op; /**< operator */
+ uint8_t operand[18];
+} T_GLC_CONTROL_POINT;
+
+typedef struct
+{
+ T_GLC_MEASUREMENT_VALUE glc_measurement_value;
+#if GLC_MEASUREMENT_CONTEXT_SUPPORT
+ T_GLC_MEASUREMENT_CONTEXT glc_measurement_context;
+#endif
+} T_PATIENT_RECORD;
+
+typedef struct
+{
+ T_PATIENT_RECORD records[GLC_RACP_DATABASE_SIZE];
+ uint8_t record_num;
+ /**
+ The tail points to an empty record who plays a role as a guard.
+ 1. empty tail == head
+ 2. one (tail - head + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE == 1
+ 3. full (head - tail + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE == 1
+ */
+ uint8_t head;
+ uint8_t tail;
+ uint16_t seq_num; /**< sequence number of latest record */
+} T_RECORD_DATA_BASE;
+
+typedef struct
+{
+ T_GLC_CONTROL_POINT ctrl_point;
+ uint8_t cp_length; /**< length of current operand of control point */
+ T_RECORD_DATA_BASE record_db;
+} T_GLC_RACP;
+
+/** Flags indicate CCCD */
+typedef struct
+{
+ uint8_t GLC_measurement_notify_enable: 1;
+ uint8_t GLC_measurement_context_notify_enable: 1;
+ uint8_t GLC_RACP_indicate_enable: 1;
+ uint8_t rfu: 5;
+} T_GLC_NOTIFY_INDICATE_FLAG;
+
+/** @defgroup GLS_Callback_Data GLS Callback Data
+ * @brief GLS data struct for notification data to application.
+ * @{
+ */
+typedef union
+{
+ uint8_t notify_indicate_index;
+ uint8_t read_value_index;
+ T_GLC_CONTROL_POINT write;
+} T_GLS_UPSTREAM_MSG_DATA;
+
+typedef struct
+{
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_GLS_UPSTREAM_MSG_DATA msg_data;
+} T_GLS_CALLBACK_DATA;
+/** @} */
+
+/** @} End of GLS_Exported_Types */
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/** @defgroup GLS_Exported_Functions GLS Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add gulcose service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ gls_id = gls_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID gls_add_service(void *p_func);
+
+
+/**
+ * @brief Set a GLS parameter.
+ *
+ * NOTE: You can call this function with a gulcose service parameter type and it will set the
+ * gulcose service parameter. Gulcose service parameters are defined in @ref T_GLS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Gulcose service parameter type: @ref T_GLS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ T_GLC_MEASUREMENT_FLAG ms_flag =
+ {
+ 1, //time_offset
+ 1, //con_ts_loc
+ GLC_FLAGS_UNITS_MOL_L_ON, //con_units
+ 1, //ss_annuciation
+ 0, //ctxt_info_follows
+ 0 //rfu
+ };
+ gls_set_parameter(GLS_PARAM_GLC_MS_FLAG, 1, &ms_flag);
+ }
+ * \endcode
+ */
+bool gls_set_parameter(T_GLS_PARAM_TYPE param_type, uint8_t len, void *p_value);
+
+
+/**
+ * @brief Get a GLS parameter.
+ *
+ * NOTE: You can call this function with a gulcose parameter type and it will get a
+ * gulcose parameter. Gulcose parameters are defined in @ref T_GLS_PARAM_TYPE.
+ *
+ * @param[in] param_type Gulcose parameter type: @ref T_GLS_PARAM_TYPE
+ * @param[in,out] len Pointer to the location to get the length of data.
+ * @param[in,out] p_value Pointer to the location to get the parameter value. This is dependent on
+ * the parameter type and will be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_INVALID_PARAM Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ int record_num;
+ gls_get_parameter(GLS_PARAM_RECORD_NUM, &len, &record_num);
+ }
+ * \endcode
+ */
+bool gls_get_parameter(T_GLS_PARAM_TYPE param_type, uint8_t *len, void *p_value);
+
+
+/**
+ * @brief Send measurement notification data .
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] index Index.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t battery_level = 90;
+ bas_battery_level_value_notify(conn_id, bas_id, battery_level);
+ }
+ * \endcode
+ */
+bool gls_glc_measurement_notify(uint8_t conn_id, T_SERVER_ID service_id, uint8_t index);
+
+#if GLC_MEASUREMENT_CONTEXT_SUPPORT
+
+/**
+ * @brief Send measurement context notification data .
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] index Index.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t battery_level = 90;
+ bas_battery_level_value_notify(conn_id, bas_id, battery_level);
+ }
+ * \endcode
+ */
+bool gls_glc_measurement_context_notify(uint8_t conn_id, T_SERVER_ID service_id, uint8_t index);
+#endif
+
+
+/**
+ * @brief Indicate control point data response to client from application
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] rsp_code Response code.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ */
+bool gls_racp_response(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code);
+
+/**
+ * @brief Indicate control point data number response to client from application
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] num Number of glucose records.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ */
+bool gls_racp_num_response(uint8_t conn_id, T_SERVER_ID service_i, uint16_t num);
+
+/**
+ * @brief Prepare a new record in database.
+ * @return void.
+ *
+ */
+void gls_prepare_new_record(void);
+
+
+/**
+ * @brief Push a new record into database.
+ * @return void.
+ *
+ */
+void gls_push_new_record(void);
+
+/**
+ * @brief Report records sub procedure.
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t battery_level = 90;
+ bas_battery_level_value_notify(conn_id, bas_id, battery_level);
+ }
+ * \endcode
+ */
+bool gls_report_records_task(uint8_t conn_id, T_SERVER_ID service_id);
+
+/**
+ * @brief Calculate user facing time by adding basetime and timeoffset.
+ *
+ *
+ * @param[in] time_in Connection id.
+ * @param[in] time_offset Service id.
+ * @param[in] time_out Battery level value.
+ * @return void.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ user_face_time(time, 30, time);
+ }
+ * \endcode
+ */
+
+void user_face_time(TIMESTAMP time_in, int16_t time_offset, TIMESTAMP time_out);
+
+/**
+ * @brief Abort RACP procedure by app.
+ *
+ * @return void.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ gls_abort_racp_procedure();
+ }
+ * \endcode
+ */
+void gls_abort_racp_procedure(void);
+
+/** @} End of GLS_Exported_Functions */
+
+/** @} End of GLS */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GLUCOSE_SERVICE_H */
diff --git a/inc/bluetooth/profile/server/gls_config.h b/inc/bluetooth/profile/server/gls_config.h
new file mode 100644
index 0000000..d16b3d0
--- /dev/null
+++ b/inc/bluetooth/profile/server/gls_config.h
@@ -0,0 +1,102 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gls_config.h
+ * @brief glucose service configuration file.
+ * @details Configure the optional characteristic and fields in the glucose service.
+ * @author bill
+ * @date 2017-6-8
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#ifndef _GLS_CONFIG_H_
+#define _GLS_CONFIG_H_
+
+/** @defgroup GLS Glucose Service
+ * @brief Glucose service
+ * @{
+ */
+
+
+/** @defgroup GLS_CONFIG Glusose Service Config
+ * @brief Glusose service configuration file
+ * @{
+ */
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup GLS_Common_Exported_Macros GLS Common Exported Macros
+ * @{
+ */
+
+/** @brief glucose maximum number of records in database */
+#define GLC_RACP_MAX_NBR_OF_STORED_RECS 10
+
+/** @defgroup GLS_Optional_Characteristic GLS Optional Characteristic
+ * @brief glucose optional characteristic configuration
+ * @{
+ */
+#define GLC_MEASUREMENT_CONTEXT_SUPPORT 1
+/** @} */
+
+/** @defgroup GLS_Optional_Field GLS Optional Field
+ * @brief glucose optional field.
+ * @{
+ */
+/** glucose measurement optional fields configuration */
+#define GLC_INCLUDE_TIME_OFFSET 1
+#define GLC_INCLUDE_CONC_TS_LOC 1
+#define GLC_INCLUDE_SS_ANNUNC 1
+
+/** glucose measurement context optional fields configuration */
+#if (GLC_MEASUREMENT_CONTEXT_SUPPORT)
+#define GLC_INCLUDE_CARBOHYDRATE 1
+#define GLC_INCLUDE_MEAL 1
+#define GLC_INCLUDE_TESTER_HEALTH 1
+#define GLC_INCLUDE_EXERCISE 1
+#define GLC_INCLUDE_MEDICATION 1
+#define GLC_INCLUDE_HbA1c 1
+#define GLC_INCLUDE_EXT_FLAGS 0
+
+#define GLC_MS_CTXT_INCLUDE_XXX (GLC_INCLUDE_CARBOHYDRATE + \
+ GLC_INCLUDE_MEAL + \
+ GLC_INCLUDE_TESTER_HEALTH + \
+ GLC_INCLUDE_EXERCISE + \
+ GLC_INCLUDE_MEDICATION + \
+ GLC_INCLUDE_HbA1c)
+#if (GLC_MS_CTXT_INCLUDE_XXX == 0)
+#error "Glucose measurement context characteristic value shall include at least one field, in addition to the Flags field and Sequence Number field!"
+#endif
+#endif
+/** @} */
+
+/** @defgroup GLS_Attribute_Index GLS Attribute Index
+ * @brief Index of each characteristic in service database
+ * @{
+ */
+#define INDEX_OFFSET0 (0)
+#define GLS_CHAR_GLC_MEASUREMENT_INDEX (INDEX_OFFSET0+0x02)
+#define GLS_CHAR_GLC_MEASUREMENT_CCCD_INDEX (GLS_CHAR_GLC_MEASUREMENT_INDEX + 1)
+
+#if (GLC_MEASUREMENT_CONTEXT_SUPPORT)
+#define GLS_CHAR_GLC_MEASUREMENT_CONTEXT_INDEX (INDEX_OFFSET0+0x05)
+#define GLS_CHAR_GLC_MEASUREMENT_CONTEXT_CCCD_INDEX (GLS_CHAR_GLC_MEASUREMENT_CONTEXT_INDEX + 1)
+#endif
+
+#define INDEX_OFFSET1 (INDEX_OFFSET0+GLC_MEASUREMENT_CONTEXT_SUPPORT*3)
+#define GLS_CHAR_GLC_FEATURE_INDEX (INDEX_OFFSET1+0x05)
+#define GLS_CHAR_GLC_RACP_INDEX (INDEX_OFFSET1+0x07)
+#define GLS_CHAR_GLC_RACP_CCCD_INDEX (GLS_CHAR_GLC_RACP_INDEX + 1)
+/** @} */
+
+
+/** @} End of GLS_Common_Exported_Macros */
+
+/** @} End of GLS_CONFIG */
+
+/** @} End of GLS */
+#endif
diff --git a/inc/bluetooth/profile/server/hids.h b/inc/bluetooth/profile/server/hids.h
new file mode 100644
index 0000000..80843d3
--- /dev/null
+++ b/inc/bluetooth/profile/server/hids.h
@@ -0,0 +1,283 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hids.h
+ * @brief Head file for using Human Interface Device Service.
+ * @details HIDS data structs and external functions declaration.
+ * @author Jeff_Zheng
+ * @date 2017-12-01
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#ifndef _HIDS_H_
+#define _HIDS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "profile_server.h"
+
+/** @defgroup HIDS Human Interface Device Service
+ * @brief Human Interface Device Service
+ * @details
+
+ The HID Service exposes data and associated formatting for HID Devices and HID Hosts.
+
+ Application shall register HID service when initialization through @ref hids_add_service function.
+
+ Application can set the HID service through @ref hids_set_parameter function.
+
+ Application can send report data of HID service to the client with a notification through @ref hids_send_report function.
+
+ * @{
+ */
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup HIDS_Exported_Macros HIDS Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @defgroup HIDS_Index HIDS Attribute Index
+ * @brief Index defines for Characteristic's value in HID Device
+ * @{
+ */
+#define GATT_SVC_HID_PROTOCOL_MODE_INDEX (2)
+#define GATT_SVC_HID_REPORT_INPUT_INDEX (4)
+#define GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX (GATT_SVC_HID_REPORT_INPUT_INDEX+1)
+#define GATT_SVC_HID_REPORT_OUTPUT_INDEX (8)
+#define GATT_SVC_HID_REPORT_FEATURE_INDEX (11)
+#define GATT_SVC_HID_REPORT_MAP_INDEX (14)
+#define GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX (GATT_SVC_HID_REPORT_MAP_INDEX+1)
+#define GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX (17)
+#define GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX (GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX+1)
+#define GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX (20)
+#define GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX (22)
+#define GATT_SVC_HID_BOOT_MS_IN_REPORT_CCCD_INDEX (GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX+1)
+#define GATT_SVC_HID_INFO_INDEX (25)
+#define GATT_SVC_HID_CONTROL_POINT_INDEX (27)
+/** @} */
+
+/** End of HIDS_Exported_Macros
+* @}
+*/
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup HIDS_Exported_Types HIDS Exported Types
+ * @brief
+ * @{
+ */
+
+/**
+* @brief Human Interface Device Service parameter type
+*/
+typedef enum
+{
+ HID_PROTOCOL_MODE = 0x01,
+ HID_REPORT_INPUT,
+ HID_REPORT_OUTPUT,
+ HID_REPORT_FEATURE,
+ HID_REPORT_MAP,
+ HID_EXTERNAL_REPORT_REFER,
+ HID_BOOT_KB_IN_REPORT,
+ HID_BOOT_KB_OUT_REPORT,
+ HID_BOOT_MS_IN_REPORT,
+ HID_INFO,
+ HID_CONTROL_POINT,
+} T_HIDS_PARAM_TYPE;
+
+/**
+* @brief Human Interface Device Service information
+*/
+typedef struct
+{
+ uint8_t b_country_code;
+ uint8_t flags;
+ uint16_t bcd_hid;
+} T_HID_INFO;
+
+/**
+* @brief Human Interface Device Service report type
+*/
+typedef enum
+{
+ HID_INPUT_TYPE = 1,
+ HID_OUTPUT_TYPE = 2,
+ HID_FEATURE_TYPE = 3
+} T_PROFILE_HID_REPORT_TYPE;
+
+/**
+* @brief Human Interface Device Service control point
+*/
+typedef enum
+{
+ HID_SUSPEND = 0,
+ HID_EXIT_SUSPEND = 1,
+} T_HID_CTL_POINT;
+
+/**
+* @brief Human Interface Device Service protocol mode
+*/
+typedef enum
+{
+ BOOT_PROTOCOL_MODE = 0,
+ REPORT_PROCOCOL_MODE = 1
+} T_HID_PROTOCOL_MODE;
+
+/** @defgroup HIDS_Upstream_Message HIDS Upstream Message
+ * @brief Upstream message used to inform application.
+ * @{
+ */
+typedef enum
+{
+ NOTIFY_ENABLE,
+ NOTIFY_DISABLE
+} T_HID_NOTIFY;
+
+typedef union
+{
+ uint8_t voice_enable;
+ uint8_t protocol_mode;
+ uint8_t suspend_mode;
+ struct
+ {
+ uint8_t reportLen;
+ uint8_t *report;
+ } report_data;
+} T_HID_WRITE_PARAMETER;
+
+typedef struct
+{
+ uint8_t write_type;
+ T_HID_WRITE_PARAMETER write_parameter;
+} T_HID_WRITE_MSG;
+
+typedef struct
+{
+ uint8_t index;
+ T_HID_NOTIFY value;
+} T_HID_NOT_IND_DATA;
+
+typedef union
+{
+ uint8_t read_value_index;
+ T_HID_WRITE_MSG write_msg;
+ T_HID_NOT_IND_DATA not_ind_data;
+} T_HID_UPSTREAM_MSG_DATA;
+
+typedef struct
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_HID_UPSTREAM_MSG_DATA msg_data;
+} T_HID_CALLBACK_DATA;
+
+/** @} End of HIDS_Upstream_Message */
+
+
+/** End of HIDS_Exported_Types
+* @}
+*/
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup HIDS_Exported_Functions HIDS Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add HID service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ hids_id = hids_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID hids_add_service(void *p_func);
+
+/**
+ * @brief Set a HID service parameter.
+ *
+ * NOTE: You can call this function with a HID service parameter type and it will set the
+ * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE.
+ *
+ * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t mode = 1;
+ hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode);
+ }
+ * \endcode
+ */
+bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t len, void *p_value);
+
+/**
+ * @brief Send HIDS notification data .
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] index hids characteristic index.
+ * @param[in] p_data report value pointer.
+ * @param[in] data_len length of report data.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t conn_id = 0;
+ T_SERVER_ID service_id = hids_id;
+ uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
+ hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_INPUT_INDEX, hid_report_input, sizeof(hid_report_input));
+ }
+ * \endcode
+ */
+bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data,
+ uint16_t data_len);
+
+
+/** @} End of HIDS_Exported_Functions */
+
+/** @} End of HIDS */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/profile/server/hids_kb.h b/inc/bluetooth/profile/server/hids_kb.h
new file mode 100644
index 0000000..6f55e23
--- /dev/null
+++ b/inc/bluetooth/profile/server/hids_kb.h
@@ -0,0 +1,281 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hids_kb.h
+ * @brief Head file for using Human Interface Device Service.
+ * @details HIDS data structs and external functions declaration.
+ * @author Jeff_Zheng
+ * @date 2017-12-01
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#ifndef _HIDS_KB_H_
+#define _HIDS_KB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "profile_server.h"
+
+/** @defgroup HIDS_KB Human Interface Device Service of Keyboard
+ * @brief Human Interface Device Service
+ * @details
+
+ The HID Service exposes data and associated formatting for HID Devices and HID Hosts.
+
+ Application shall register HID service when initialization through @ref hids_add_service function.
+
+ Application can set the HID service through @ref hids_set_parameter function.
+
+ Application can send report data of HID service to the client with a notification through @ref hids_send_report function.
+
+ * @{
+ */
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup HIDS_KB_Exported_Macros HIDS Keyboard Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @defgroup HIDS_KB_Index HIDS Keyboard Attribute Index
+ * @brief Index defines for Characteristic's value in HID Device
+ * @{
+ */
+#define GATT_SVC_HID_PROTOCOL_MODE_INDEX (2)
+#define GATT_SVC_HID_REPORT_INPUT_INDEX (4)
+#define GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX (GATT_SVC_HID_REPORT_INPUT_INDEX+1)
+#define GATT_SVC_HID_REPORT_OUTPUT_INDEX (8)
+#define GATT_SVC_HID_REPORT_FEATURE_INDEX (11)
+#define GATT_SVC_HID_REPORT_MAP_INDEX (14)
+#define GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX (GATT_SVC_HID_REPORT_MAP_INDEX+1)
+#define GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX (17)
+#define GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX (GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX+1)
+#define GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX (20)
+#define GATT_SVC_HID_INFO_INDEX (22)
+#define GATT_SVC_HID_CONTROL_POINT_INDEX (24)
+/** @} */
+
+/** End of HIDS_KB_Exported_Macros
+* @}
+*/
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup HIDS_KB_Exported_Types HIDS Keyboard Exported Types
+ * @brief
+ * @{
+ */
+
+/**
+* @brief Human Interface Device Service parameter type
+*/
+typedef enum
+{
+ HID_PROTOCOL_MODE = 0x01,
+ HID_REPORT_INPUT,
+ HID_REPORT_OUTPUT,
+ HID_REPORT_FEATURE,
+ HID_REPORT_MAP,
+ HID_EXTERNAL_REPORT_REFER,
+ HID_BOOT_KB_IN_REPORT,
+ HID_BOOT_KB_OUT_REPORT,
+ HID_INFO,
+ HID_CONTROL_POINT,
+} T_HIDS_PARAM_TYPE;
+
+/**
+* @brief Human Interface Device Service information
+*/
+typedef struct
+{
+ uint8_t b_country_code;
+ uint8_t flags;
+ uint16_t bcd_hid;
+} T_HID_INFO;
+
+/**
+* @brief Human Interface Device Service report type
+*/
+typedef enum
+{
+ HID_INPUT_TYPE = 1,
+ HID_OUTPUT_TYPE = 2,
+ HID_FEATURE_TYPE = 3
+} T_PROFILE_HID_REPORT_TYPE;
+
+/**
+* @brief Human Interface Device Service control point
+*/
+typedef enum
+{
+ HID_SUSPEND = 0,
+ HID_EXIT_SUSPEND = 1,
+} T_HID_CTL_POINT;
+
+/**
+* @brief Human Interface Device Service protocol mode
+*/
+typedef enum
+{
+ BOOT_PROTOCOL_MODE = 0,
+ REPORT_PROCOCOL_MODE = 1
+} T_HID_PROTOCOL_MODE;
+
+/** @defgroup HIDS_KB_Upstream_Message HIDS Keyboard Upstream Message
+ * @brief Upstream message used to inform application.
+ * @{
+ */
+typedef enum
+{
+ NOTIFY_ENABLE,
+ NOTIFY_DISABLE
+} T_HID_NOTIFY;
+
+typedef union
+{
+ uint8_t voice_enable;
+ uint8_t protocol_mode;
+ uint8_t suspend_mode;
+ uint8_t output;
+ struct
+ {
+ uint8_t reportLen;
+ uint8_t *report;
+ } report_data;
+} T_HID_WRITE_PARAMETER;
+
+typedef struct
+{
+ uint8_t write_type;
+ T_HID_WRITE_PARAMETER write_parameter;
+} T_HID_WRITE_MSG;
+
+typedef struct
+{
+ uint8_t index;
+ T_HID_NOTIFY value;
+} T_HID_NOT_IND_DATA;
+
+typedef struct
+{
+ uint8_t read_value_index;
+ T_HID_WRITE_MSG write_msg;
+ T_HID_NOT_IND_DATA not_ind_data;
+} T_HID_UPSTREAM_MSG_DATA;
+
+typedef struct
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_HID_UPSTREAM_MSG_DATA msg_data;
+} T_HID_CALLBACK_DATA;
+
+/** @} End of HIDS_KB_Upstream_Message */
+
+
+/** End of HIDS_KB_Exported_Types
+* @}
+*/
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup HIDS_KB_Exported_Functions HIDS Keyboard Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add HID service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ hids_id = hids_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID hids_add_service(void *p_func);
+
+/**
+ * @brief Set a HID service parameter.
+ *
+ * NOTE: You can call this function with a HID service parameter type and it will set the
+ * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE.
+ *
+ * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t mode = 1;
+ hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode);
+ }
+ * \endcode
+ */
+bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t len, void *p_value);
+
+/**
+ * @brief Send HIDS notification data .
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] index hids characteristic index.
+ * @param[in] p_data report value pointer.
+ * @param[in] data_len length of report data.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t conn_id = 0;
+ T_SERVER_ID service_id = hids_id;
+ uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
+ hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_INPUT_INDEX, hid_report_input, sizeof(hid_report_input));
+ }
+ * \endcode
+ */
+bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data,
+ uint16_t data_len);
+
+
+/** @} End of HIDS_KB_Exported_Functions */
+
+/** @} End of HIDS_KB */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/profile/server/hids_ms.h b/inc/bluetooth/profile/server/hids_ms.h
new file mode 100644
index 0000000..de69532
--- /dev/null
+++ b/inc/bluetooth/profile/server/hids_ms.h
@@ -0,0 +1,280 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hids_ms.h
+ * @brief Head file for using Human Interface Device Service.
+ * @details HIDS data structs and external functions declaration.
+ * @author Jeff_Zheng
+ * @date 2017-12-01
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#ifndef _HIDS_MS_H_
+#define _HIDS_MS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "profile_server.h"
+
+/** @defgroup HIDS_MS Human Interface Device Service of Mouse
+ * @brief Human Interface Device Service
+ * @details
+
+ The HID Service exposes data and associated formatting for HID Devices and HID Hosts.
+
+ Application shall register HID service when initialization through @ref hids_add_service function.
+
+ Application can set the HID service through @ref hids_set_parameter function.
+
+ Application can send report data of HID service to the client with a notification through @ref hids_send_report function.
+
+ * @{
+ */
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup HIDS_MS_Exported_Macros HIDS Mouse Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @defgroup HIDS_MS_Index HIDS Mouse Attribute Index
+ * @brief Index defines for Characteristic's value in HID Device
+ * @{
+ */
+#define GATT_SVC_HID_PROTOCOL_MODE_INDEX (2)
+#define GATT_SVC_HID_REPORT_MOUSE_INPUT_INDEX (4)
+#define GATT_SVC_HID_REPORT_MOUSE_INPUT_CCCD_INDEX (GATT_SVC_HID_REPORT_MOUSE_INPUT_INDEX+1)
+#define GATT_SVC_HID_REPORT_VENDOR_INPUT_INDEX (8)
+#define GATT_SVC_HID_REPORT_VNEDOR_INPUT_CCCD_INDEX (GATT_SVC_HID_REPORT_VENDOR_INPUT_INDEX+1)
+#define GATT_SVC_HID_REPORT_OUTPUT_INDEX (12)
+#define GATT_SVC_HID_REPORT_FEATURE_INDEX (15)
+#define GATT_SVC_HID_REPORT_MAP_INDEX (18)
+#define GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX (GATT_SVC_HID_REPORT_MAP_INDEX+1)
+#define GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX (21)
+#define GATT_SVC_HID_BOOT_MS_IN_REPORT_CCCD_INDEX (GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX+1)
+#define GATT_SVC_HID_INFO_INDEX (24)
+#define GATT_SVC_HID_CONTROL_POINT_INDEX (26)
+/** @} */
+
+/** End of HIDS_MS_Exported_Macros
+* @}
+*/
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup HIDS_MS_Exported_Types HIDS Mouse Exported Types
+ * @brief
+ * @{
+ */
+
+/**
+* @brief Human Interface Device Service parameter type
+*/
+typedef enum
+{
+ HID_PROTOCOL_MODE = 0x01,
+ HID_REPORT_INPUT,
+ HID_REPORT_OUTPUT,
+ HID_REPORT_FEATURE,
+ HID_REPORT_MAP,
+ HID_EXTERNAL_REPORT_REFER,
+ HID_BOOT_MS_IN_REPORT,
+ HID_INFO,
+ HID_CONTROL_POINT,
+} T_HIDS_PARAM_TYPE;
+
+/**
+* @brief Human Interface Device Service information
+*/
+typedef struct
+{
+ uint8_t b_country_code;
+ uint8_t flags;
+ uint16_t bcd_hid;
+} T_HID_INFO;
+
+/**
+* @brief Human Interface Device Service report type
+*/
+typedef enum
+{
+ HID_INPUT_TYPE = 1,
+ HID_OUTPUT_TYPE = 2,
+ HID_FEATURE_TYPE = 3
+} T_PROFILE_HID_REPORT_TYPE;
+
+/**
+* @brief Human Interface Device Service control point
+*/
+typedef enum
+{
+ HID_SUSPEND = 0,
+ HID_EXIT_SUSPEND = 1,
+} T_HID_CTL_POINT;
+
+/**
+* @brief Human Interface Device Service protocol mode
+*/
+typedef enum
+{
+ BOOT_PROTOCOL_MODE = 0,
+ REPORT_PROCOCOL_MODE = 1
+} T_HID_PROTOCOL_MODE;
+
+/** @defgroup HIDS_MS_Upstream_Message HIDS Mouse Upstream Message
+ * @brief Upstream message used to inform application.
+ * @{
+ */
+typedef enum
+{
+ NOTIFY_ENABLE,
+ NOTIFY_DISABLE
+} T_HID_NOTIFY;
+
+typedef union
+{
+ uint8_t voice_enable;
+ uint8_t protocol_mode;
+ uint8_t suspend_mode;
+ struct
+ {
+ uint8_t reportLen;
+ uint8_t *report;
+ } report_data;
+} T_HID_WRITE_PARAMETER;
+
+typedef struct
+{
+ uint8_t write_type;
+ T_HID_WRITE_PARAMETER write_parameter;
+} T_HID_WRITE_MSG;
+
+typedef struct
+{
+ uint8_t index;
+ T_HID_NOTIFY value;
+} T_HID_NOT_IND_DATA;
+
+typedef union
+{
+ uint8_t read_value_index;
+ T_HID_WRITE_MSG write_msg;
+ T_HID_NOT_IND_DATA not_ind_data;
+} T_HID_UPSTREAM_MSG_DATA;
+
+typedef struct
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_HID_UPSTREAM_MSG_DATA msg_data;
+} T_HID_CALLBACK_DATA;
+
+/** @} End of HIDS_MS_Upstream_Message */
+
+
+/** End of HIDS_MS_Exported_Types
+* @}
+*/
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup HIDS_MS_Exported_Functions HIDS Mouse Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add HID service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ hids_id = hids_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID hids_add_service(void *p_func);
+
+/**
+ * @brief Set a HID service parameter.
+ *
+ * NOTE: You can call this function with a HID service parameter type and it will set the
+ * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE.
+ *
+ * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t mode = 1;
+ hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode);
+ }
+ * \endcode
+ */
+bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t len, void *p_value);
+
+/**
+ * @brief Send HIDS notification data .
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] index hids characteristic index.
+ * @param[in] p_data report value pointer.
+ * @param[in] data_len length of report data.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t conn_id = 0;
+ T_SERVER_ID service_id = hids_id;
+ uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
+ hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_MOUSE_INPUT_INDEX, hid_report_input, sizeof(hid_report_input));
+ }
+ * \endcode
+ */
+bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data,
+ uint16_t data_len);
+
+
+/** @} End of HIDS_MS_Exported_Functions */
+
+/** @} End of HIDS_MS */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/profile/server/hids_mulkb.h b/inc/bluetooth/profile/server/hids_mulkb.h
new file mode 100644
index 0000000..6cab7b6
--- /dev/null
+++ b/inc/bluetooth/profile/server/hids_mulkb.h
@@ -0,0 +1,284 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hids_kb.h
+ * @brief Head file for using Human Interface Device Service.
+ * @details HIDS data structs and external functions declaration.
+ * @author Jeff_Zheng
+ * @date 2017-12-01
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#ifndef _HIDS_KB_H_
+#define _HIDS_KB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "profile_server.h"
+
+/** @defgroup HIDS_KB Human Interface Device Service of Keyboard
+ * @brief Human Interface Device Service
+ * @details
+
+ The HID Service exposes data and associated formatting for HID Devices and HID Hosts.
+
+ Application shall register HID service when initialization through @ref hids_add_service function.
+
+ Application can set the HID service through @ref hids_set_parameter function.
+
+ Application can send report data of HID service to the client with a notification through @ref hids_send_report function.
+
+ * @{
+ */
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup HIDS_KB_Exported_Macros HIDS Keyboard Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @defgroup HIDS_KB_Index HIDS Keyboard Attribute Index
+ * @brief Index defines for Characteristic's value in HID Device
+ * @{
+ */
+#define GATT_SVC_HID_PROTOCOL_MODE_INDEX (2)
+#define GATT_SVC_HID_REPORTID1_INPUT_INDEX (4)
+#define GATT_SVC_HID_REPORTID1_INPUT_CCCD_INDEX (GATT_SVC_HID_REPORTID1_INPUT_INDEX+1)
+#define GATT_SVC_HID_REPORT_OUTPUT_INDEX (8)
+#define GATT_SVC_HID_REPORTID3_INPUT_INDEX (11)
+#define GATT_SVC_HID_REPORTID3_INPUT_CCCD_INDEX (GATT_SVC_HID_REPORTID3_INPUT_INDEX+1)
+#define GATT_SVC_HID_REPORT_VENDOR_INPUT_INDEX (15)
+#define GATT_SVC_HID_REPORT_VNEDOR_INPUT_CCCD_INDEX (GATT_SVC_HID_REPORT_VENDOR_INPUT_INDEX+1)
+#define GATT_SVC_HID_REPORT_MAP_INDEX (19)
+#define GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX (GATT_SVC_HID_REPORT_MAP_INDEX+1)
+//#define GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX (17)
+//#define GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX (GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX+1)
+//#define GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX (20)
+#define GATT_SVC_HID_INFO_INDEX (21)
+#define GATT_SVC_HID_CONTROL_POINT_INDEX (23)
+/** @} */
+
+/** End of HIDS_KB_Exported_Macros
+* @}
+*/
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup HIDS_KB_Exported_Types HIDS Keyboard Exported Types
+ * @brief
+ * @{
+ */
+
+/**
+* @brief Human Interface Device Service parameter type
+*/
+typedef enum
+{
+ HID_PROTOCOL_MODE = 0x01,
+ HID_REPORT_INPUT,
+ HID_REPORT_OUTPUT,
+ HID_REPORT_FEATURE,
+ HID_REPORT_MAP,
+ HID_EXTERNAL_REPORT_REFER,
+ HID_BOOT_KB_IN_REPORT,
+ HID_BOOT_KB_OUT_REPORT,
+ HID_INFO,
+ HID_CONTROL_POINT,
+} T_HIDS_PARAM_TYPE;
+
+/**
+* @brief Human Interface Device Service information
+*/
+typedef struct
+{
+ uint8_t b_country_code;
+ uint8_t flags;
+ uint16_t bcd_hid;
+} T_HID_INFO;
+
+/**
+* @brief Human Interface Device Service report type
+*/
+typedef enum
+{
+ HID_INPUT_TYPE = 1,
+ HID_OUTPUT_TYPE = 2,
+ HID_FEATURE_TYPE = 3
+} T_PROFILE_HID_REPORT_TYPE;
+
+/**
+* @brief Human Interface Device Service control point
+*/
+typedef enum
+{
+ HID_SUSPEND = 0,
+ HID_EXIT_SUSPEND = 1,
+} T_HID_CTL_POINT;
+
+/**
+* @brief Human Interface Device Service protocol mode
+*/
+typedef enum
+{
+ BOOT_PROTOCOL_MODE = 0,
+ REPORT_PROCOCOL_MODE = 1
+} T_HID_PROTOCOL_MODE;
+
+/** @defgroup HIDS_KB_Upstream_Message HIDS Keyboard Upstream Message
+ * @brief Upstream message used to inform application.
+ * @{
+ */
+typedef enum
+{
+ NOTIFY_ENABLE,
+ NOTIFY_DISABLE
+} T_HID_NOTIFY;
+
+typedef union
+{
+ uint8_t voice_enable;
+ uint8_t protocol_mode;
+ uint8_t suspend_mode;
+ uint8_t output;
+ struct
+ {
+ uint8_t reportLen;
+ uint8_t *report;
+ } report_data;
+} T_HID_WRITE_PARAMETER;
+
+typedef struct
+{
+ uint8_t write_type;
+ T_HID_WRITE_PARAMETER write_parameter;
+} T_HID_WRITE_MSG;
+
+typedef struct
+{
+ uint8_t index;
+ T_HID_NOTIFY value;
+} T_HID_NOT_IND_DATA;
+
+typedef struct
+{
+ uint8_t read_value_index;
+ T_HID_WRITE_MSG write_msg;
+ T_HID_NOT_IND_DATA not_ind_data;
+} T_HID_UPSTREAM_MSG_DATA;
+
+typedef struct
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_HID_UPSTREAM_MSG_DATA msg_data;
+} T_HID_CALLBACK_DATA;
+
+/** @} End of HIDS_KB_Upstream_Message */
+
+
+/** End of HIDS_KB_Exported_Types
+* @}
+*/
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup HIDS_KB_Exported_Functions HIDS Keyboard Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add HID service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ hids_id = hids_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID hids_add_service(void *p_func);
+
+/**
+ * @brief Set a HID service parameter.
+ *
+ * NOTE: You can call this function with a HID service parameter type and it will set the
+ * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE.
+ *
+ * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t mode = 1;
+ hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode);
+ }
+ * \endcode
+ */
+bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t len, void *p_value);
+
+/**
+ * @brief Send HIDS notification data .
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] index hids characteristic index.
+ * @param[in] p_data report value pointer.
+ * @param[in] data_len length of report data.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t conn_id = 0;
+ T_SERVER_ID service_id = hids_id;
+ uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
+ hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_INPUT_INDEX, hid_report_input, sizeof(hid_report_input));
+ }
+ * \endcode
+ */
+bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data,
+ uint16_t data_len);
+
+
+/** @} End of HIDS_KB_Exported_Functions */
+
+/** @} End of HIDS_KB */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/inc/bluetooth/profile/server/hids_rmc.h b/inc/bluetooth/profile/server/hids_rmc.h
new file mode 100644
index 0000000..ccd3986
--- /dev/null
+++ b/inc/bluetooth/profile/server/hids_rmc.h
@@ -0,0 +1,252 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hids_rmc.h
+ * @brief Head file for using Human Interface Device Service Remote Controller.
+ * @details HIDS RMC data structs and external functions declaration.
+ * @author Chenjie Jin
+ * @date 2018-5-7
+ * @version v1.1
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _HIDS_RMC_H
+#define _HIDS_RMC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "profile_server.h"
+#include "board.h"
+
+/** @defgroup HIDS_RmC HIDS Human Interface Device Service of Remote Controller
+ * @brief Human Interface Device Service Remote Controller
+ * @{
+ */
+
+/** @defgroup HIDS_RmC_Exported_Constants HIDS RmC Exported Constants
+ * @brief macros that other .c files may use all defined here
+ * @{
+ */
+
+/** @brief HIDS Report Id Definition. */
+#define HIDS_KB_REPORT_ID 1
+#if FEATURE_SUPPORT_MULTIMEDIA_KEYBOARD
+#define HIDS_MM_KB_REPORT_ID 2
+#endif
+#if (VOICE_ENC_TYPE == SW_MSBC_ENC)
+#define HIDS_VOICE_REPORT_ID 0x5A // input and output
+#elif (VOICE_ENC_TYPE == SW_SBC_ENC)
+#define HIDS_VOICE_REPORT_ID 0x5B // input and output
+#else
+#define HIDS_VOICE_REPORT_ID 0x5A // input and output
+#endif
+
+
+/** @defgroup HIDS_RmC_Application_Parameters HIDS RmC Application Parameters
+ * @brief Type of parameters set/got from application.
+ * @{
+ */
+#define HIDS_PARAM_PROTOCOL_MODE 1
+#define HIDS_PARAM_SUSPEND_MODE 2
+#define HIDS_PARAM_HID_INFO 3
+#define HIDS_PARAM_REPORT 4
+/** @} */
+
+///@cond
+/** @brief HIDS_RmC related UUIDs. */
+#define GATT_UUID_HID 0x1812
+#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C
+#define GATT_UUID_CHAR_HID_INFO 0x2A4A
+#define GATT_UUID_CHAR_REPORT 0x2A4D
+#define GATT_UUID_CHAR_REPORT_MAP 0x2A4B
+#define GATT_UUID_CHAR_RECORD_ACCESS_POINT 0x2A52
+#define GATT_UUID_CHAR_PROTOCOL_MODE 0x2A4E
+#define GATT_UUID_CHAR_BOOT_KB_IN_REPORT 0x2A22
+#define GATT_UUID_CHAR_BOOT_KB_OUT_REPORT 0x2A32
+#define GATT_UUID_CHAR_BOOT_MOUSE_IN_REPORT 0x2A33
+#define GATT_UUID_CHAR_REPORT_REFERENCE 0x2908
+#define GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE 0x2907
+
+///@endcond
+
+/** @defgroup HIDS_RmC_Attribute_Index HIDS RmC Attribute Index
+ * @brief Index defines for Characteristic's value in HID Device
+ * @{
+ */
+#define GATT_SRV_HID_INDEX_MAX 23
+#define GATT_SVC_HID_INFO_INDEX (2) /**< @brief Index for HID Information chars's value */
+#define GATT_SVC_HID_CONTROL_POINT_INDEX (4) /**< @brief Index for HID Control Point chars's value */
+#define GATT_SVC_HID_PROTOCOL_MODE_INDEX (6) /**< @brief Index for HID Protocol Mode chars's value */
+#define GATT_SVC_HID_REPORT_MAP_INDEX (8) /**< @brief Index for HID Report Map chars's value */
+
+#define GATT_SRV_HID_KB_INPUT_INDEX (10)
+#define GATT_SRV_HID_KB_CCCD_INDEX (GATT_SRV_HID_KB_INPUT_INDEX + 1)
+
+#if SUPPORT_VOICE_FEATURE
+#define GATT_SRV_HID_VOICE_INPUT_INDEX (14)
+#define GATT_SRV_HID_VOICE_INPUT_CCCD_INDEX (GATT_SRV_HID_VOICE_INPUT_INDEX + 1)
+#define GATT_SRV_HID_VOICE_OUTPUT_INDEX (18)
+#endif
+
+#if FEATURE_SUPPORT_MULTIMEDIA_KEYBOARD
+#if SUPPORT_VOICE_FEATURE
+#define GATT_SRV_HID_MM_KB_INPUT_INDEX (21)
+#define GATT_SRV_HID_MM_KB_INPUT_CCCD_INDEX (GATT_SRV_HID_MM_KB_INPUT_INDEX + 1)
+#else
+#define GATT_SRV_HID_MM_KB_INPUT_INDEX (14)
+#define GATT_SRV_HID_MM_KB_INPUT_CCCD_INDEX (GATT_SRV_HID_MM_KB_INPUT_INDEX + 1)
+#endif
+#endif
+/** @} */
+
+/** @defgroup HIDS_RmC_Upstream_Message HIDS RmC Upstream Message
+ * @brief Upstream message used to inform application.
+ * @{
+ */
+
+/** @defgroup HIDS_RmC_Read_Info HIDS RmC Read Info
+ * @brief Parameter for read characteristic value.
+ * @{
+ */
+#define HIDS_READ_PARAM_PROTOCOL_MODE 1
+#define HIDS_READ_PARAM_SUSPEND_MODE 2
+#define HIDS_READ_PARAM_HID_INFO 3
+#define HIDS_READ_PARAM_REPORT 4
+/** @} */
+
+/** @defgroup HIDS_RmC_Write_Info HIDS RmC Write Info
+ * @brief Parameter for write characteristic value.
+ * @{
+ */
+#define HID_WRITE_VIOCE_CMD 1
+#define HID_WRITE_PROTOCOL_MODE 2
+#define HID_WRITE_SUSPEND_MODE 3
+#define HID_WRITE_OUTPUT 4
+#define HID_WRITE_INPUT_REPORT 5
+/** @} */
+
+/** @defgroup HIDS_RmC_Notify_Indicate_Info HIDS RmC Notify Indicate Info
+ * @brief Parameter for enable or disable notification or indication.
+ * @{
+ */
+#define HID_NOTIFY_INDICATE_KB_ENABLE 1
+#define HID_NOTIFY_INDICATE_KB_DISABLE 2
+#define HID_NOTIFY_INDICATE_VOICE_ENABLE 3
+#define HID_NOTIFY_INDICATE_VOICE_DISABLE 4
+#define HID_NOTIFY_INDICATE_MM_KB_ENABLE 5
+#define HID_NOTIFY_INDICATE_MM_KB_DISABLE 6
+
+/** @} */
+
+/** @} End of HIDS_RmC_Upstream_Message */
+
+/** @} End of HIDS_RmC_Exported_Constants */
+
+/** @defgroup HIDS_RmC_Exported_Types HIDS RmC Exported Types
+ * @brief types that other.c files may use all defined here
+ * @{
+ */
+
+/* Add all public types here */
+
+/** @struct _HID_INFO_ATTRB hids_rmc.h "hids_rmc.h"
+ * @brief type define for value of HID information
+ */
+typedef struct _HID_INFO_ATTRB
+{
+ uint8_t CountryCode;
+ uint8_t bFlags;
+ uint16_t BcdHID;
+} HID_INFO_ATTRB;
+
+/** @brief enum for TProfile_HIDReportType*/
+typedef enum
+{
+ HID_INPUT_TYPE = 1, /**< @enum Input report */
+ HID_OUTPUT_TYPE = 2, /**< @enum Output report */
+ HID_FEATURE_TYPE = 3 /**< @enum Feature report */
+} TProfile_HIDReportType;
+
+/** @struct _TProfile_REPORT_REFE_TABLE hids_rmc.h "hids_rmc.h"
+ * @brief type define for info reference to report data
+ */
+typedef struct _TProfile_REPORT_REFE_TABLE
+{
+ uint8_t report_size; /**< @brief report size according to value of Report Map value, byte */
+ uint8_t report_id; /**< @brief report ID defined in value of Report Map Char, byte */
+ uint8_t report_type; /**< @brief report Type(Input,Output,Feature), ref: @ref TProfile_HIDReportType */
+} TProfile_REPORT_REFE_TABLE;
+
+/** @defgroup HIDS_RmC_Callback_Data HIDS RmC Callback Data
+ * @brief HIDS RmC data struct for notification data to application.
+ * @{
+ */
+
+/** @brief value for HID protocol mode characteristic */
+enum TProfile_HID_PROTOCOL_MODE
+{
+ BOOT_PROTOCOL_MODE = 0, /**< @enum boot protocol mode */
+ REPORT_PROCOCOL_MODE = 1 /**< @enum report protocol mode */
+};
+
+typedef union _THID_WRITE_PARAMETER
+{
+ uint8_t voice_enable;
+ uint8_t protocol_mode; /**< ref: @ref TProfile_HID_PROTOCOL_MODE */
+ uint8_t suspend_mode;
+ struct
+ {
+ uint8_t reportLen;
+ uint8_t *report;
+ } report_data;
+} THID_WRITE_PARAMETER;
+
+/** @struct _THID_WRITE_MSG hids_rmc.h "hids_rmc.h"
+ * @brief write message
+ */
+typedef struct _THID_WRITE_MSG
+{
+ uint8_t write_type; /**< ref: @ref HIDS_RmC_Write_Info */
+ THID_WRITE_PARAMETER write_parameter;
+} THID_WRITE_MSG;
+
+typedef union _THID_UPSTREAM_MSG_DATA
+{
+ uint8_t notification_indification_index; /**< ref: @ref HIDS_RmC_Notify_Indicate_Info */
+ uint8_t read_value_index; /**< ref: @ref HIDS_RmC_Read_Info */
+ THID_WRITE_MSG write;
+} THID_UPSTREAM_MSG_DATA;
+
+/** @struct _T_HID_CALLBACK_DATA hids_rmc.h "hids_rmc.h"
+ * @brief callback data
+ */
+typedef struct _T_HID_CALLBACK_DATA
+{
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ THID_UPSTREAM_MSG_DATA msg_data;
+} T_HID_CALLBACK_DATA;
+/** @} End of HIDS_RmC_Callback_Data */
+
+/** @} End of HIDS_RmC_Exported_Types */
+
+/** @defgroup HIDS_RmC_Exported_Functions HIDS RmC Exported Functions
+ * @brief functions that other .c files may use all defined here
+ * @{
+ */
+bool hids_set_parameter(uint8_t param_type, uint8_t length, void *value_ptr);
+uint8_t hids_add_service(void *p_func);
+/** @} End of HIDS_RmC_Exported_Functions */
+
+/** @} End of HIDS_RmC */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _HIDS_RMC_H */
diff --git a/inc/bluetooth/profile/server/hrs.h b/inc/bluetooth/profile/server/hrs.h
new file mode 100644
index 0000000..9825b1b
--- /dev/null
+++ b/inc/bluetooth/profile/server/hrs.h
@@ -0,0 +1,296 @@
+/*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hrs.h
+ * @brief Variables and interfaces for using Heart Rate Service.
+ * @details Heart Rate Service data structs and functions.
+ * @author
+ * @date 2017-09-21
+ * @version v0.1
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _HRS_SERVICE_DEF_H
+#define _HRS_SERVICE_DEF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "profile_server.h"
+
+
+/** @defgroup HRS Heart Rate Service
+ * @brief Heart Rate Service
+ * @details
+
+ The Heart Rate Service exposes heart rate and other data related to a heart rate sensor intended for fitness applications.
+
+ Application shall register heart rate service when initialization through @ref hrs_add_service function.
+
+ The Heart Rate Measurement characteristic is used to send a heart rate measurement. Included in the characteristic are a Flags field (for showing the presence of optional fields and features
+ supported), a heart rate measurement value field and, depending upon the contents of the Flags field, an Energy Expended field and an RR-Interval field. The RR-Interval represents the time between
+ two consecutive R waves in an Electrocardiogram (ECG) waveform.
+ Application can send heart rate measurement value through @ref hrs_heart_rate_measurement_value_notify function.
+
+ The Body Sensor Location characteristic of the device is used to describe the intended location of the heart rate measurement for the device.
+ The value of the Body Sensor Location characteristic is static while in a connection.
+
+ The Heart Rate Control Point characteristic is used to enable a Client to write control points to a Server to control behavior.
+ Support for this characteristic is mandatory if the Server supports the Energy Expended feature.
+
+ Application can set heart rate measurement parameter and location of the heart rate measurement for the device through @ref hrs_set_parameter function.
+
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup HRS_Exported_Macros HRS Exported Macros
+ * @brief
+ * @{
+ */
+
+
+/** @defgroup HRS_Read_Info HRS Read Info
+ * @brief Parameter for reading characteristic value.
+ * @{
+ */
+#define HRS_READ_BODY_SENSOR_LOCATION_VALUE 1
+/** @} */
+
+/** @defgroup HRS_Notify_Indicate_Info HRS Notify Indicate Info
+ * @brief Parameter for enable or disable notification or indication.
+ * @{
+ */
+#define HRS_NOTIFY_INDICATE_MEASUREMENT_VALUE_ENABLE 1
+#define HRS_NOTIFY_INDICATE_MEASUREMENT_VALUE_DISABLE 2
+/** @} */
+
+
+
+/** @defgroup HRS_Sensor_Location HRS Sensor Location
+ * @brief Body Sensor Location Value
+ * @{
+ */
+#define BODY_SENSOR_LOCATION_VALUE_OTHER 0
+#define BODY_SENSOR_LOCATION_VALUE_CHEST 1
+#define BODY_SENSOR_LOCATION_VALUE_WRIST 2
+#define BODY_SENSOR_LOCATION_VALUE_FINGER 3
+#define BODY_SENSOR_LOCATION_VALUE_HAND 4
+#define BODY_SENSOR_LOCATION_VALUE_EAR_LOBE 5
+#define BODY_SENSOR_LOCATION_VALUE_FOOT 6
+/** @} */
+
+#define HRS_MAX_CTL_PNT_VALUE 1
+
+/** End of HRS_Exported_Macros
+* @}
+*/
+
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup HRS_Exported_Types HRS Exported Types
+ * @brief
+ * @{
+ */
+
+typedef enum
+{
+ HRS_HEART_RATE_MEASUREMENT_PARAM_FLAG = 0x01,
+ HRS_HEART_RATE_MEASUREMENT_PARAM_MEASUREMENT_VALUE,
+ HRS_HEART_RATE_MEASUREMENT_PARAM_ENERGY_EXPENDED,
+ HRS_HEART_RATE_MEASUREMENT_PARAM_RR_INTERVAL,
+ HRS_BODY_SENSOR_LOCATION_PARAM_VALUE = 0x10,
+} T_HRS_PARAM_TYPE;
+
+typedef enum
+{
+ HRS_HEART_RATE_CP_OPCODE_RESERVED = 0,
+ HRS_HEART_RATE_CP_OPCODE_RESET_ENERGY_EXPENDED = 1
+} T_HRS_HEART_RATE_CP_OPCODE;
+
+
+/** notification indification flag */
+typedef struct
+{
+ uint8_t heart_rate_measurement_notify_enable: 1;
+ uint8_t rfu: 7;
+} HRS_NOTIFY_INDICATE_FLAG;
+
+/** Heart Rate Measurement Value Flag */
+typedef struct
+{
+ uint8_t heart_rate_value_format_bit: 1;
+ uint8_t sensor_contact_status_bits: 2;
+ uint8_t energy_expended_status_bit: 1;
+ uint8_t rr_interval_bit: 1;
+ uint8_t rfu: 3;
+} T_HEART_RATE_MEASUREMENT_VALUE_FLAG;
+
+/** Heart Rate Measurement Value */
+typedef struct
+{
+ T_HEART_RATE_MEASUREMENT_VALUE_FLAG flag;
+ uint16_t heart_rate_measurement_value;
+ uint16_t energy_expended;
+ uint16_t rr_interval;
+} T_HEART_RATE_MEASUREMENT_VALUE;
+
+/**
+ * @brief HRS Control Point data, variable length during connection, max can reach 17 bytes.
+ *
+ * HRS Control Point data used to store the Control Point Command received from the client.
+*/
+typedef struct
+{
+ uint8_t cur_length; /**< length of current CSC Control Point data . */
+ uint8_t value[HRS_MAX_CTL_PNT_VALUE]; /**< value of current CSC Control Point data . */
+} T_HRS_CONTROL_POINT;
+
+typedef struct
+{
+ T_HRS_HEART_RATE_CP_OPCODE opcode;
+} T_HRS_WRITE_MSG;
+
+typedef union
+{
+ uint8_t notification_indification_index;
+ uint8_t read_value_index;
+ T_HRS_WRITE_MSG write;
+} T_HRS_UPSTREAM_MSG_DATA;
+
+typedef struct
+{
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_HRS_UPSTREAM_MSG_DATA msg_data;
+} T_HRS_CALLBACK_DATA;
+/** End of HRS_Exported_Types
+* @}
+*/
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup HRS_Exported_Functions HRS Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add heart rate service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ hrs_id = hrs_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+uint8_t hrs_add_service(void *p_func);
+
+
+/**
+ * @brief Set a heart rate service parameter.
+ *
+ * NOTE: You can call this function with a heart rate service parameter type and it will set the
+ * heart rate service parameter. Heart rate service parameters are defined
+ * in @ref T_HTS_TEMPERATURE_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Health thermometer service parameter type: @ref T_HRS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ T_HEART_RATE_MEASUREMENT_VALUE_FLAG flag;
+ flag.heart_rate_value_format_bit = 1;
+ flag.sensor_contact_status_bits = 3;
+ if (p_parse_value->param_count >= 1)
+ {
+ flag.sensor_contact_status_bits = p_parse_value->dw_param[1];
+ }
+
+ flag.energy_expended_status_bit = 1;
+ flag.rr_interval_bit = 1;
+ flag.rfu = 0;
+
+ hrs_set_parameter(HRS_HEART_RATE_MEASUREMENT_PARAM_FLAG, 1, &flag);
+ }
+ * \endcode
+ */
+
+bool hrs_set_parameter(T_HRS_PARAM_TYPE param_type, uint8_t len, void *p_value);
+
+/**
+ * @brief Send heart rate measurement value notification data.
+ * Application shall call @ref hrs_set_parameter to set heart rate measurement value first,
+ * and the call this api to send the notication value.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ *
+ * @return service id @ref T_SERVER_ID.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ bool op_result;
+
+ T_HEART_RATE_MEASUREMENT_VALUE_FLAG flag;
+ flag.heart_rate_value_format_bit = 1;
+ flag.sensor_contact_status_bits = 3;
+ if (p_parse_value->param_count >= 1)
+ {
+ flag.sensor_contact_status_bits = p_parse_value->dw_param[1];
+ }
+
+ flag.energy_expended_status_bit = 1;
+ flag.rr_interval_bit = 1;
+ flag.rfu = 0;
+
+ hrs_set_parameter(HRS_HEART_RATE_MEASUREMENT_PARAM_FLAG, 1, &flag);
+
+ op_result = hrs_heart_rate_measurement_value_notify(p_parse_value->dw_param[0], hrs_id);
+ }
+ * \endcode
+ */
+bool hrs_heart_rate_measurement_value_notify(uint8_t conn_id, T_SERVER_ID service_id);
+
+/** @} End of HRS_Exported_Functions */
+
+/** @} End of HRS */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HRS_SERVICE_DEF_H */
+
diff --git a/inc/bluetooth/profile/server/hts.h b/inc/bluetooth/profile/server/hts.h
new file mode 100644
index 0000000..179642d
--- /dev/null
+++ b/inc/bluetooth/profile/server/hts.h
@@ -0,0 +1,349 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hts.h
+ * @brief Variables and interfaces for using Health Thermometer Service.
+ * @details Health Thermometer Service data structs and functions.
+ * @author
+ * @date 2017-09-20
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _HTS_SERVICE_DEF_H
+#define _HTS_SERVICE_DEF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "stdint.h"
+#include "profile_server.h"
+#include "rtl876x.h"
+
+
+/** @defgroup HTS Health Thermometer Service
+ * @brief Health Thermometer Service
+ * @details
+
+ The Health Thermometer Service exposes temperature and other data related to a thermometer used for healthcare applications.
+ Application shall register Health Thermometer Service when initialization through @ref hts_add_service function.
+
+ The Temperature Measurement characteristic is used to send a temperature measurement.
+ Application can send a temperature measurement through @ref hts_measurement_value_indicate function.
+
+ The Intermediate Temperature characteristic is used to send intermediate temperature values to a device
+ for display purposes while the measurement is in progress.
+ Application can send intermediate temperature values through @ref hts_intermediate_temperature_value_notify function.
+
+ The Measurement Interval characteristic is used to enable and control the interval
+ between consecutive temperature measurements.
+ Application can send interval through @ref hts_measurement_interval_notify function.
+
+
+
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup HTS_Exported_Macros HTS Exported Macros
+ * @brief
+ * @{
+ */
+
+#define HTS_READ_TEMPERATURE_TYPE_VALUE 1
+#define HTS_READ_MEASUREMENT_INTERVAL_VALUE 2
+#define HTS_READ_VALID_RANGE_VALUE 3
+
+
+#define HTS_WRITE_MEASUREMENT_INTERVAL_VALUE 1
+
+/** @defgroup HTS_Notify_Indicate_Info HTS Notify Indicate Info
+ * @brief Parameter for enable or disable notification or indication.
+ * @{
+ */
+#define HTS_NOTIFY_INDICATE_TEMPERATURE_MEASUREMENT_VALUE_ENABLE 1
+#define HTS_NOTIFY_INDICATE_TEMPERATURE_MEASUREMENT_VALUE_DISABLE 2
+#define HTS_NOTIFY_INDICATE_INTERMEDIATE_TEMPERATURE_VALUE_ENABLE 3
+#define HTS_NOTIFY_INDICATE_INTERMEDIATE_TEMPERATURE_VALUE_DISABLE 4
+#define HTS_NOTIFY_INDICATE_MEASUREMENT_INTERVAL_VALUE_ENABLE 5
+#define HTS_NOTIFY_INDICATE_MEASUREMENT_INTERVAL_VALUE_DISABLE 6
+/** @} */
+
+/** @defgroup HTS_Measurement_Flag HTS Measurement Flag
+ * @{
+ */
+#define HTS_FLAG_MEASUREMENT_UINT_BIT BIT0
+#define HTS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT BIT1
+#define HTS_FLAG_MEASUREMENT_TYPE_PRESENT_BIT BIT2
+/** @} */
+
+/** End of HTS_Exported_Macros
+* @}
+*/
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup HTS_Exported_Types HTS Exported Types
+ * @brief
+ * @{
+ */
+
+/**
+* @brief Health Thermometer parameter type
+*/
+typedef enum
+{
+ HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG = 1,
+ HTS_PARAM_MEASUREMENT_TEMPERATUER_VALUE,
+ HTS_PARAM_MEASUREMENT_TIME_STAMP,
+ HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE,
+ HTS_PARAM_MEASUREMENT_INTERVAL,
+ HTS_PARAM_VALID_RANGE
+} T_HTS_PARAM_TYPE;
+
+/**
+* @brief Health Thermometer temperature type
+*/
+typedef enum
+{
+ HTS_TEMPERATURE_TYPE_ARMPIT = 1,
+ HTS_TEMPERATURE_TYPE_BODY,
+ HTS_TEMPERATURE_TYPE_EAR,
+ HTS_TEMPERATURE_TYPE_FINGER,
+ HTS_TEMPERATURE_TYPE_GASTRO_INTESTINAL_TRACT,
+ HTS_TEMPERATURE_TYPE_MOUTH,
+ HTS_TEMPERATURE_TYPE_RECTUM,
+ HTS_TEMPERATURE_TYPE_TOE,
+ HTS_TEMPERATURE_TYPE_TYMPANUM,
+ HTS_TEMPERATURE_TYPE_RESERVED,
+} T_HTS_TEMPERATURE_TYPE;
+
+/**
+* @brief Health Thermometer Measurement Value Flag
+*/
+typedef struct
+{
+ uint8_t temp_value_units_bit: 1;
+ uint8_t temp_time_stamp_present_bit: 1;
+ uint8_t temp_type_present_bit: 1;
+ uint8_t rfu: 5;
+} T_HEALTH_THERMOMETER_MEASUREMENT_VALUE_FLAG;
+
+typedef struct
+{
+ uint16_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t hours;
+ uint8_t minutes;
+ uint8_t seconds;
+} T_TIME_STAMP;
+
+typedef struct
+{
+ uint16_t lower_value;
+ uint16_t upper_value;
+} T_HTS_MEASUREMENT_INTERVAL_VALID_RANGE;
+
+typedef struct
+{
+ uint8_t write_index;
+ uint16_t measurement_interval;
+} T_HTS_WRITE_MSG;
+
+/**
+* @brief Health Thermometer Service upper stream message data
+*/
+typedef union
+{
+ uint8_t notification_indification_index;
+ uint8_t read_value_index;
+ T_HTS_WRITE_MSG write;
+} T_HTS_UPSTREAM_MSG_DATA;
+
+/**
+* @brief Health Thermometer Service callback data
+*/
+typedef struct
+{
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_HTS_UPSTREAM_MSG_DATA msg_data;
+} T_HTS_CALLBACK_DATA;
+
+/** End of HTS_Exported_Types
+* @}
+*/
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup HTS_Exported_Functions HTS Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add health thermometer service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ hts_id = hts_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+uint8_t hts_add_service(void *p_func);
+
+
+/**
+ * @brief Set a health thermometer service parameter.
+ *
+ * NOTE: You can call this function with a health thermometer service parameter type and it will set the
+ * health thermometer service parameter. Health thermometer service parameters are defined
+ * in @ref T_HTS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Health thermometer service parameter type: @ref T_HTS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t hts_flag = HTS_FLAG_MEASUREMENT_UINT_BIT | HTS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT |
+ HTS_FLAG_MEASUREMENT_TYPE_PRESENT_BIT;
+ T_HTS_TEMPERATURE_TYPE temperature_type = HTS_TEMPERATURE_TYPE_ARMPIT;
+
+ hts_measure_time_stamp.seconds += hts_measurement_interval;
+
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG, sizeof(hts_flag), &hts_flag);
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(hts_measure_time_stamp),
+ &hts_measure_time_stamp);
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE, 1, &temperature_type);
+ }
+ * \endcode
+ */
+
+bool hts_set_parameter(T_HTS_PARAM_TYPE param_type, uint8_t len, void *p_value);
+
+/**
+ * @brief Send measurement value indication data .
+ * Application shall call @ref hts_set_parameter to set intermediate temperature value first,
+ * and the call this api to send the notication value.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ *
+ * @return service id @ref T_SERVER_ID.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t hts_flag = HTS_FLAG_MEASUREMENT_UINT_BIT | HTS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT |
+ HTS_FLAG_MEASUREMENT_TYPE_PRESENT_BIT;
+ T_HTS_TEMPERATURE_TYPE temperature_type = HTS_TEMPERATURE_TYPE_ARMPIT;
+
+ hts_measure_time_stamp.seconds += hts_measurement_interval;
+
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG, sizeof(hts_flag), &hts_flag);
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(hts_measure_time_stamp),
+ &hts_measure_time_stamp);
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE, 1, &temperature_type);
+
+ hts_measurement_value_indicate(p_parse_value->dw_param[0], hts_id);
+ }
+ * \endcode
+ */
+bool hts_measurement_value_indicate(uint8_t conn_id, uint8_t service_id);
+
+/**
+ * @brief Send intermediate temperature notification data.
+ * Application shall call @ref hts_set_parameter to set intermediate temperature value first,
+ * and the call this api to send the notication value.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ *
+ * @return service id @ref T_SERVER_ID.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t hts_flag = HTS_FLAG_MEASUREMENT_UINT_BIT
+ | HTS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT
+ | HTS_FLAG_MEASUREMENT_TYPE_PRESENT_BIT;
+ T_HTS_TEMPERATURE_TYPE temperature_type = HTS_TEMPERATURE_TYPE_ARMPIT;
+
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG, sizeof(hts_flag), &hts_flag);
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(hts_measure_time_stamp),
+ &hts_measure_time_stamp);
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE, 1, &temperature_type);
+
+ hts_intermediate_temperature_value_notify(p_parse_value->dw_param[0], hts_id);
+
+ return RESULT_SUCCESS;
+
+ }
+ * \endcode
+ */
+bool hts_intermediate_temperature_value_notify(uint8_t conn_id, uint8_t service_id);
+
+
+/**
+ * @brief Send measurement interval notification data.
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] seconds Measurement interval.
+ *
+ * @return service id @ref T_SERVER_ID.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint16_t interval = 90;
+ hts_measurement_interval_notify(p_parse_value->dw_param[0], hts_id, interval);
+ }
+ * \endcode
+ */
+bool hts_measurement_interval_notify(uint8_t conn_id, uint8_t service_id, uint16_t seconds);
+
+/** @} End of HTS_Exported_Functions */
+
+/** @} End of HTS */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _HTS_SERVICE_DEF_H
+
diff --git a/inc/bluetooth/profile/server/ias.h b/inc/bluetooth/profile/server/ias.h
new file mode 100644
index 0000000..3e30cf3
--- /dev/null
+++ b/inc/bluetooth/profile/server/ias.h
@@ -0,0 +1,102 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ias.h
+ * @brief Head file for using immediate alert service.
+ * @details IAS data structs and external functions declaration.
+ * @author
+ * @date
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _IAS_H_
+#define _IAS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "profile_server.h"
+
+
+/** @defgroup IAS Immediate Alert Service
+ * @brief Immediate alert service
+ * @details
+
+ The Immediate Alert Service (IAS) exposes a control point to allow a peer device to cause the device to immediately alert.
+
+ Immediate Alert Service contains an Alert Level characteristic, to which any value other than "No Alert" being written will trigger alarm in the device.
+
+ Immediate Alert Service generally constitutes a profile collectively with other Services, such as Proximity or Find Me etc., which enables immediate alert in device.
+
+ Application shall register Immediate Alert Service when initialization through @ref ias_add_service function.
+
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/** @defgroup IAS_Exported_Types IAS Exported Types
+ * @brief
+ * @{
+ */
+/** Message content */
+typedef union
+{
+ uint8_t write_alert_level;
+} T_IAS_UPSTREAM_MSG_DATA;
+
+/** IAS service data to inform application */
+typedef struct
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_IAS_UPSTREAM_MSG_DATA msg_data;
+} T_IAS_CALLBACK_DATA;
+
+/** @} End of IAS_Exported_Types */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/** @defgroup IAS_Exported_Functions IAS Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add immediate alert service to the BLE stack database.
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ ias_id = ias_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID ias_add_service(void *p_func);
+
+/** @} End of IAS_Exported_Functions */
+
+/** @} End of IAS */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif //_IAS_H
+
diff --git a/inc/bluetooth/profile/server/ipss.h b/inc/bluetooth/profile/server/ipss.h
new file mode 100644
index 0000000..3589c3d
--- /dev/null
+++ b/inc/bluetooth/profile/server/ipss.h
@@ -0,0 +1,77 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ipss.h
+ * @brief Head file for using internet protocol support service.
+ * @details HIDS data structs and external functions declaration.
+ * @author Jeff_Zheng
+ * @date 2017-12-01
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#ifndef _IPSS_H_
+#define _IPSS_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup IPSS Internet Protocol Support Service
+ * @brief Internet Protocol Support Service
+ * @details
+
+ The Internet Protocol Support Profile (IPSP) allows devices to discover and communicate to
+ other devices that support IPSP. The communication between the devices that support IPSP
+ is done using IPv6 packets over the Bluetooth Low Energy transport.
+
+ Application shall register IPS service when initialization through @ref ipss_add_service function.
+
+ * @{
+ */
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup IPSS_Exported_Macros IPSS Exported Macros
+ * @brief
+ * @{
+ */
+#define GATT_UUID_IPSS 0x1820
+
+/** End of IPSS_Exported_Macros
+* @}
+*/
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup IPSS_Exported_Functions IPSS Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief add ipss service to application.
+ *
+ * @param[in] p_func pointer of app callback function called by profile.
+ * @return service id auto generated by profile layer.
+ * @retval service id
+ */
+uint8_t ipss_add_service(void *p_func);
+
+/** @} End of IPSS_Exported_Functions */
+
+/** @} End of IPSS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/inc/bluetooth/profile/server/lls.h b/inc/bluetooth/profile/server/lls.h
new file mode 100644
index 0000000..4036bbb
--- /dev/null
+++ b/inc/bluetooth/profile/server/lls.h
@@ -0,0 +1,159 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file lls.h
+ * @brief Head file for using link loss service.
+ * @details LLS data structs and external functions declaration.
+ * @author
+ * @date
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _LLS_H_
+#define _LLS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "profile_server.h"
+
+/** @defgroup LLS Link Loss Service
+ * @brief Link loss service
+ * @details
+
+ The Link Loss Service (LLS) defines behavior when a link is lost between two devices.
+
+ The Link Loss Service uses the Alert Level characteristic to cause an alert in the device
+ when the link is lost.
+
+ Link Loss Service generally constitutes a profile collectively with other Services, such
+ as Proximity or Find Me etc., which enables device to cause an alert when the link is lost.
+
+ Application shall register link loss service when initialization through @ref lls_add_service function.
+
+ Application can set LLS alert level value through @ref lls_set_parameter function.
+
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup LLS_Exported_Macros LLS Service Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @defgroup LLS_Read_Info LLS Read Info
+ * @brief Read characteristic value.
+ * @{
+ */
+#define LLS_READ_ALERT_LEVEL 1
+/** @} */
+
+/** @} End of LLS_Exported_Macros */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/** @defgroup LLS_Exported_Types LLS Exported Types
+ * @brief
+ * @{
+ */
+
+/** @defgroup LLS_PARAM_TYPE LLS Parameter Type
+* @brief Type of parameters set from application.
+* @{
+*/
+typedef enum
+{
+ LLS_PARAM_LINK_LOSS_ALERT_LEVEL
+} T_LLS_PARAM_TYPE;
+/** @} */
+
+/** @defgroup LLS_Callback_Data LLS Callback Data
+ * @brief LLS data struct for notification data to application.
+ * @{
+ */
+/** Message content: @ref T_LLS_CALLBACK_DATA */
+typedef union
+{
+ uint8_t read_value_index;
+ uint8_t write_alert_level;
+} T_LLS_UPSTREAM_MSG_DATA;
+
+/** LLSdata service data to inform application */
+typedef struct
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_LLS_UPSTREAM_MSG_DATA msg_data;
+} T_LLS_CALLBACK_DATA;
+/** @} */
+
+/** @} End of LLS_Exported_Types */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/** @defgroup LLS_Exported_Functions LLS Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Set a link loss service parameter.
+ *
+ * NOTE: You can call this function with a link loss service parameter type and it will set the
+ * link loss service parameter. Link loss service parameters are defined in @ref T_LLS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Link loss service parameter type: @ref T_LLS_PARAM_TYPE
+ * @param[in] length Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ */
+bool lls_set_parameter(T_LLS_PARAM_TYPE param_type, uint8_t length, void *p_value);
+
+/**
+ * @brief Add link loss service to the BLE stack database.
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ lls_id = lls_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID lls_add_service(void *p_func);
+/** @} End of LLS_Exported_Functions */
+
+/** @} End of LLS*/
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/inc/bluetooth/profile/server/lns.h b/inc/bluetooth/profile/server/lns.h
new file mode 100644
index 0000000..d4cf795
--- /dev/null
+++ b/inc/bluetooth/profile/server/lns.h
@@ -0,0 +1,484 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file lns.h
+ * @brief Variables and interfaces for using Location And Navigation Service.
+ * @details Location And Navigation Service data structs and functions.
+ * @author ranhui
+ * @date 2017-09-20
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _LNS_SERVICE_DEF_H
+#define _LNS_SERVICE_DEF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "profile_server.h"
+
+/** @defgroup LNS Location And Navigation Service
+ * @brief Location And Navigation service
+ * @details
+
+ The Location and Navigation Service (LN Service) exposes location and navigation-related data from a
+ Location and Navigation sensor (Server) intended for outdoor activity applications.
+
+ Application shall register LN Service when initialization through @ref lns_add_service function.
+
+ The LN Feature characteristic shall be used to describe the supported features of the Server.
+ Reserved for Future Use (RFU) bits in the LN Feature characteristic value shall be set to 0.
+
+ The Location and Speed characteristic is used to send location and speed related data.
+
+ Application can send location and speed related data through @ref lns_location_and_speed_value_notify function.
+
+ The Position Quality characteristic is used to send position quality-related data.
+
+ If the LN Control Point is supported, profiles utilizing this service are required to ensure that the Client configures the LN Control Point characteristic for indications (i.e., via the Client
+ Characteristic Configuration descriptor) at the first connection.
+ Support for this characteristic is mandatory if the Server supports any of the features requiring control point procedures.
+
+ The Navigation characteristic is used to send navigation-related data.
+ Application can send navigation-related data through @ref lns_navigation_value_notify function.
+
+ Application can set the parameters of LNS through @ref lns_set_parameter function.
+
+
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup LNS_Exported_Macros LNS Exported Macros
+ * @brief
+ * @{
+ */
+
+
+/** @defgroup LNS_LN_Feature LNS LN Feature
+ * @{
+ */
+#define LN_FEATURE_INSTANTANEOUS_SPEED_SUPPORTED BIT0
+#define LN_FEATURE_TOTAL_DISTANCE_SUPPORTED BIT1
+#define LN_FEATURE_LOCATION_SUPPORTED BIT2
+#define LN_FEATURE_ELEVATION_SUPPORTED BIT3
+#define LN_FEATURE_HEADING_SUPPORTED BIT4
+#define LN_FEATURE_ROLLING_TIME_SUPPORTED BIT5
+#define LN_FEATURE_UTC_TIME_SUPPORTED BIT6
+#define LN_FEATURE_REMAINING_DISTANCE_SUPPORTED BIT7
+#define LN_FEATURE_REMAINING_VERTICAL_DISTANCE_SUPPORTED BIT8
+#define LN_FEATURE_ESTIMATED_TIME_OF_ARRIVAL_SUPPORTED BIT9
+#define LN_FEATURE_NUMBER_OF_BEACONS_IN_SOLUTION_SUPPORTED BIT10
+#define LN_FEATURE_NUMBER_OF_BEACONS_IN_VIEW_SUPPORTED BIT11
+#define LN_FEATURE_TIME_TO_FIRST_FIX_SUPPORTED BIT12
+#define LN_FEATURE_ESTIMATED_HORIZONTAL_POSITION_ERROR_SUPPORTED BIT13
+#define LN_FEATURE_ESTIMATED_VERTICAL_POSITION_ERROR_SUPPORTED BIT14
+#define LN_FEATURE_HORIZONTAL_DILUTION_OF_PRECISION_SUPPORTED BIT15
+#define LN_FEATURE_VERTICAL_DILUTION_OF_PRECISION_SUPPORTED BIT16
+#define LN_FEATURE_LOCATION_AND_SPEED_CHARACTERISTIC_CONTENT_MASKING_SUPPORTED BIT17
+#define LN_FEATURE_FIX_RATE_SETTING_SUPPORTED BIT18
+#define LN_FEATURE_ELEVATION_SETTING_SUPPORTED BIT19
+#define LN_FEATURE_POSITION_STATUS_SUPPORTED BIT20
+#define LN_FEATURE_RFU BIT21
+/** @} */
+
+#define LNS_READ_POSITION_QUALITY_VALUE 1
+
+#define LNS_NOTIFY_INDICATE_LOCATION_AND_SPEED_ENABLE 1
+#define LNS_NOTIFY_INDICATE_LOCATION_AND_SPEED_DISABLE 2
+#define LNS_NOTIFY_INDICATE_CP_ENABLE 3
+#define LNS_NOTIFY_INDICATE_CP_DISABLE 4
+#define LNS_NOTIFY_INDICATE_NAVIGATION_ENABLE 5
+#define LNS_NOTIFY_INDICATE_NAVIGATION_DISABLE 6
+
+#define LNS_MAX_CTL_PNT_VALUE 17
+
+/** End of LNS_Exported_Macros
+* @}
+*/
+
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup LNS_Exported_Types LNS Exported Types
+ * @brief
+ * @{
+ */
+
+typedef enum
+{
+ LNS_LAS_PARAM_INC_FLAG = 0x01,
+ LNS_LAS_PARAM_INSTANTANEOUS_SPEED,
+ LNS_LAS_PARAM_TOTAL_DISTANCE,
+ LNS_LAS_PARAM_LOCATION_LATITUDE,
+ LNS_LAS_PARAM_LOCATION_LONGITUDE,
+ LNS_LAS_PARAM_ELEVATION,
+ LNS_LAS_PARAM_HEADING,
+ LNS_LAS_PARAM_ROLLING_TIME,
+ LNS_LAS_PARAM_UTC_TIME,
+ LNS_LAS_PARAM_POSITION_STATUS,
+ LNS_LAS_PARAM_SPEED_AND_DISTANCE_FORMAT,
+ LNS_LAS_PARAM_ELEVATION_SOURCE,
+ LNS_LAS_PARAM_HEADING_SOURCE,
+
+ LNS_NAVIGATION_PARAM_INC_FLAG = 0x11,
+ LNS_NAVIGATION_PARAM_BEARING,
+ LNS_NAVIGATION_PARAM_HEADING,
+ LNS_NAVIGATION_PARAM_REMAINING_DISTANCE,
+ LNS_NAVIGATION_PARAM_REMAINING_VERTICAL_DISTANCE,
+ LNS_NAVIGATION_PARAM_ESTIMATED_TIME_OF_ARRIVAL,
+ LNS_NAVIGATION_PARAM_POSITION_STATUS,
+ LNS_NAVIGATION_PARAM_HEADING_SOURCE,
+ LNS_NAVIGATION_PARAM_NAVIGATION_INDICATOR_TYPE,
+ LNS_NAVIGATION_PARAM_WAYPOINT_REACHED,
+ LNS_NAVIGATION_PARAM_DESTINATION_REACHED,
+
+ LNS_PQ_PARAM_INC_FLAG = 0x20,
+ LNS_PQ_PARAM_NUMBER_OF_BEACONS_IN_SOLUTION,
+ LNS_PQ_PARAM_NUMBER_OF_BEACONS_IN_VIEW,
+ LNS_PQ_PARAM_TIME_TO_FIRST_FIX,
+ LNS_PQ_PARAM_EHPE,
+ LNS_PQ_PARAM_EVPE,
+ LNS_PQ_PARAM_HDOP,
+ LNS_PQ_PARAM_VDOP,
+
+ LNS_PARAM_LN_FEATURE_SUPPORT = 0x30,
+
+ LNS_CP_PARA_NUMBER_OF_ROUTE = 0x41,
+ LNS_CP_PARA_NAME_OF_ROUTE,
+
+ LNS_PARAM_CTL_PNT_PROG_CLR = 0x51,
+} T_LNS_PARAM_TYPE;
+
+/* Add all public types here */
+typedef struct
+{
+ uint16_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t hours;
+ uint8_t minutes;
+ uint8_t seconds;
+} T_DATE_TIME;
+
+/** Position Quality Value Flag */
+typedef struct
+{
+ uint16_t number_of_beacons_in_solution_present: 1;
+ uint16_t number_of_beacons_in_view_present: 1;
+ uint16_t time_to_first_fix_present: 1;
+ uint16_t ehpe_present: 1;
+ uint16_t evpe_present: 1;
+ uint16_t hdop_present: 1;
+ uint16_t vdop_present: 1;
+ uint16_t position_status: 2;
+ uint16_t rfu: 7;
+} T_POSITION_QUALITY_VALUE_FLAG;
+
+/** Position Quality Value */
+typedef struct
+{
+ T_POSITION_QUALITY_VALUE_FLAG flag;
+ uint8_t number_of_beacons_in_solution;
+ uint8_t number_of_beacons_in_view;
+ uint16_t time_to_first_fix;
+ uint32_t ehpe;
+ uint32_t evpe;
+ uint8_t hdop;
+ uint8_t vdop;
+} T_POSITION_QUALITY_VALUE;
+
+typedef struct
+{
+ uint8_t location_and_speed_notify_enable: 1;
+ uint8_t ln_cp_indicate_enable: 1;
+ uint8_t navigation_enable: 1;
+ uint8_t rfu: 5;
+} T_LNS_NOTIFY_INDICATE_FLAG;
+
+typedef struct
+{
+ uint16_t instantaneous_speed_present: 1;
+ uint16_t total_distance_present: 1;
+ uint16_t location_present: 1;
+ uint16_t elevation_present: 1;
+ uint16_t heading_present: 1;
+ uint16_t rolling_time_present: 1;
+ uint16_t utc_time_present: 1;
+ uint16_t position_status: 2;
+ uint16_t speed_and_distance_format: 1;
+ uint16_t elevation_source: 2;
+ uint16_t heading_source: 1;
+ uint16_t rfu: 3;
+} T_LOCATION_AND_SPEED_VALUE_FLAG;
+
+/** Location and Speed Value */
+typedef struct
+{
+ T_LOCATION_AND_SPEED_VALUE_FLAG flag;
+ uint16_t instantaneous_speed;
+ uint32_t total_distance; //uint24
+ int32_t location_latitude; //sint32
+ int32_t location_longitude;
+ int32_t elevation;//sint24
+ uint16_t heading;
+ uint8_t rolling_time;
+ T_DATE_TIME utc_time;
+} LOCATION_AND_SPEED_VALUE;
+
+/** Navigation Value */
+typedef struct
+{
+ uint16_t remaining_distance_present: 1;
+ uint16_t remaining_vertical_distance_present: 1;
+ uint16_t estimated_time_of_arrival_present: 1;
+ uint16_t position_status: 2;
+ uint16_t heading_source: 1;
+ uint16_t navigation_indicator_type: 1;
+ uint16_t waypoint_reached: 1;
+ uint16_t destination_reached: 1;
+ uint16_t rfus: 7;
+} T_NAVIGATION_VALUE_FLAG;
+
+typedef struct
+{
+ T_NAVIGATION_VALUE_FLAG flag;
+ uint16_t bearing;
+ uint16_t heading;
+ uint32_t reamining_distance;
+ int32_t reamining_vertical_distance;
+ T_DATE_TIME estimated_time_of_arrival;
+} T_NAVIGATION_VALUE;
+
+typedef enum
+{
+ LN_CP_OPCODE_RESERVED = 0,
+ LN_CP_OPCODE_SET_CUMULATIVE_VALUE = 1,
+ LN_CP_OPCODE_MASK_LOCATION_AND_SPEED_CHAR_CONTENT = 2,
+ LN_CP_OPCODE_NAVIGATION_CONTROL = 3,
+ LN_CP_OPCODE_REQUEST_NUMBER_OF_ROUTES = 4,
+ LN_CP_OPCODE_REQUEST_NAME_OF_ROUTE = 5,
+ LN_CP_OPCODE_SELECT_ROUTE = 6,
+ LN_CP_OPCODE_SET_FIX_RATE = 7,
+ LN_CP_OPCODE_SET_ELEVATION = 8,
+ LN_CP_OPCODE_RESPONSE_CODE = 32
+} T_LN_CP_OPCODE;
+
+
+/**
+ * @brief CSC Control Point data, variable length during connection, max can reach 17 bytes.
+ *
+ * CSC Control Point data used to store the Control Point Command received from the client.
+*/
+typedef struct
+{
+ uint8_t cur_length; /**< length of current LNS Control Point data, . */
+ uint8_t
+ value[LNS_MAX_CTL_PNT_VALUE]; /**< value of current LNS Control Point data, . */
+} T_LNS_CONTROL_POINT;
+
+/** @defgroup LNS_Callback_Data LNS Callback Data
+ * @brief LNS data struct for notification data to application.
+ * @{
+ */
+typedef union
+{
+ uint32_t cumulative_total_distance; //uint24
+ uint16_t mask_location_and_speed;
+ uint8_t navigation_control;
+ uint16_t number_of_desired_route; //request_name_of_route
+ uint16_t select_route_desired_route_number;
+ uint8_t set_fix_rate;
+ int32_t set_elevation; //sint24
+} T_LNS_CP_PARAMETER;
+
+typedef struct
+{
+ T_LN_CP_OPCODE opcode;
+ T_LNS_CP_PARAMETER cp_parameter;
+} T_LNS_WRITE_MSG;
+
+typedef union
+{
+ uint8_t notification_indification_index;
+ uint8_t read_value_index;
+ T_LNS_WRITE_MSG write;
+} T_LNS_UPSTREAM_MSG_DATA;
+
+/** LNS service data to inform application */
+typedef struct
+{
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_LNS_UPSTREAM_MSG_DATA msg_data;
+} T_LNS_CALLBACK_DATA;
+/** @} */
+
+/** End of LNS_Exported_Types
+* @}
+*/
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup LNS_Exported_Functions LNS Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add location and navigation service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ lns_id = lns_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+uint8_t lns_add_service(void *p_func);
+
+/**
+ * @brief Set a Location And Navigation service parameter.
+ *
+ * NOTE: You can call this function with a Location And Navigation service parameter type and it will set the
+ * Location And Navigation service parameter. Location And Navigation service parameters are defined
+ * in @ref T_LNS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Location And Navigation service parameter type: @ref T_LNS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ T_LOCATION_AND_SPEED_VALUE_FLAG flag;
+ flag.instantaneous_speed_present = 1;
+ flag.total_distance_present = 1;
+ flag.location_present = 1;
+ flag.elevation_present = 1;
+ flag.heading_present = 1;
+ flag.rolling_time_present = 1;
+ flag.utc_time_present = 1;
+ flag.position_status = 1;
+ flag.speed_and_distance_format = 1;
+ flag.elevation_source = 1;
+ flag.heading_source = 1;
+ flag.rfu = 0;
+
+ lns_set_parameter(LNS_LAS_PARAM_INC_FLAG, 2, &flag);
+ }
+ * \endcode
+ */
+bool lns_set_parameter(T_LNS_PARAM_TYPE param_type, uint8_t len, void *p_value);
+
+/**
+ * @brief Send location and speed value notification data.
+ * Application shall call @ref lns_set_parameter to set location and speed value first,
+ * and the call this api to send the notication value.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ *
+ * @return service id @ref T_SERVER_ID.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ bool op_result;
+ T_LOCATION_AND_SPEED_VALUE_FLAG flag;
+ flag.instantaneous_speed_present = 1;
+ flag.total_distance_present = 1;
+ flag.location_present = 1;
+ flag.elevation_present = 1;
+ flag.heading_present = 1;
+ flag.rolling_time_present = 1;
+ flag.utc_time_present = 1;
+ flag.position_status = 1;
+ flag.speed_and_distance_format = 1;
+ flag.elevation_source = 1;
+ flag.heading_source = 1;
+ flag.rfu = 0;
+
+ lns_set_parameter(LNS_LAS_PARAM_INC_FLAG, 2, &flag);
+
+ op_result = lns_location_and_speed_value_notify(p_parse_value->dw_param[0], lns_id);
+ }
+ * \endcode
+ */
+bool lns_location_and_speed_value_notify(uint8_t conn_id, T_SERVER_ID service_id);
+
+/**
+ * @brief Send navigation value notification data.
+ * Application shall call @ref lns_set_parameter to set navigation value first,
+ * and the call this api to send the notication value.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ *
+ * @return service id @ref T_SERVER_ID.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ bool op_result;
+
+ T_NAVIGATION_VALUE_FLAG flag;
+ flag.remaining_distance_present = 1;
+ flag.remaining_vertical_distance_present = 1;
+ flag.estimated_time_of_arrival_present = 1;
+ flag.position_status = 1;
+ flag.heading_source = 1;
+ flag.navigation_indicator_type = 1;
+ flag.waypoint_reached = 1;
+ flag.destination_reached = 1;
+ flag.rfus = 0;
+
+ lns_set_parameter(LNS_NAVIGATION_PARAM_INC_FLAG, 2, &flag);
+
+ op_result = lns_navigation_value_notify(p_parse_value->dw_param[0], lns_id);
+
+ }
+ * \endcode
+ */
+bool lns_navigation_value_notify(uint8_t conn_id, T_SERVER_ID service_id);
+
+/** @} End of LNS_Exported_Functions */
+
+/** @} End of LNS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _LNS_SERVICE_DEF_H
+
diff --git a/inc/bluetooth/profile/server/ota_service.h b/inc/bluetooth/profile/server/ota_service.h
new file mode 100644
index 0000000..9f4e0dc
--- /dev/null
+++ b/inc/bluetooth/profile/server/ota_service.h
@@ -0,0 +1,142 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ota_service.h
+* @brief
+* @details
+* @author hunter_shuai
+* @date 14-July-2015
+* @version v1.0.0
+******************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2015 Realtek Semiconductor Corporation</center></h2>
+******************************************************************************
+*/
+
+#ifndef _OTA_SERVICE_H_
+#define _OTA_SERVICE_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "profile_server.h"
+#include "dfu_api.h"
+/** @brief Demo Profile service related UUIDs. */
+
+#define GATT_UUID_CHAR_OTA 0xFFD1 //1
+#define GATT_UUID_CHAR_MAC 0xFFD2 //2
+#define GATT_UUID_CHAR_PATCH 0xFFD3 //3
+#define GATT_UUID_CHAR_APP_VERSION 0xFFD4 //4
+#define GATT_UUID_CHAR_PATCH_EXTENSION 0xFFD5 //5
+#define GATT_UUID_CHAR_TEST_MODE 0xFFD8 //6
+
+#define GATT_UUID_CHAR_DEVICE_INFO 0xFFF1 //7
+#define GATT_UUID_CHAR_IMAGE_COUNT_TO_UPDATE 0xFFF2 //8
+#define GATT_UUID_CHAR_IMAGE_VERSION0 0xFFE0 //mandatory when OTA version >= 1
+#define GATT_UUID_CHAR_IMAGE_VERSION1 0xFFE1
+#define GATT_UUID_CHAR_IMAGE_VERSION2 0xFFE2
+#define GATT_UUID_CHAR_PROTOCOL_TYPE 0xFFF3
+
+/** @brief Index of each characteristic in Demo Profile service database. */
+#define BLE_SERVICE_CHAR_OTA_INDEX 0x02 /**< attr write */
+#define BLE_SERVICE_CHAR_MAC_ADDRESS_INDEX 0x04 /**< attr read */
+#define BLE_SERVICE_CHAR_PATCH_INDEX 0x06 /**< attr read */
+#define BLE_SERVICE_CHAR_APP_VERSION_INDEX 0x08 /**< attr read */
+#define BLE_SERVICE_CHAR_PATCH_EXTENSION_INDEX 0x0a /**< attr read */
+#define BLE_SERVICE_CHAR_TEST_MODE_INDEX 0x0c /**< attr write */
+#define BLE_SERVICE_CHAR_DEVICE_INFO_INDEX 0x0e /**< attr read */
+#define BLE_SERVICE_CHAR_IMAGE_COUNT_INDEX 0x10 /**< attr write */
+#define BLE_SERVICE_CHAR_IMAGE_VERSION0_INDEX 0x12 /**< attr read */
+#define BLE_SERVICE_CHAR_IMAGE_VERSION1_INDEX 0x14 /**< attr read */
+#define BLE_SERVICE_CHAR_IMAGE_VERSION2_INDEX 0x16 /**< attr read */
+#define BLE_SERVICE_CHAR_PROTOCOL_TYPE_INDEX 0x18 /**< attr read */
+
+/** @brief OTA Read callback data type definition.*/
+#define OTA_READ_CHAR_MAC_ADDRESS_INDEX 0x01
+#define OTA_READ_CHAR_PATCH_INDEX 0x02
+#define OTA_READ_CHAR_APP_VERSION_INDEX 0x03
+#define OTA_READ_CHAR_PATCH_EXTENSION_INDEX 0x04
+#define OTA_READ_CHAR_DEVICE_INFO_INDEX 0x05
+#define OTA_READ_CHAR_IMAGE_VERSION_INDEX 0x06
+#define OTA_READ_CHAR_PROTOCOL_TYPE_INDEX 0x07
+
+
+/** @brief OTA Write callback data type definition.*/
+#define OTA_WRITE_CHAR_VAL 0x01 /**< switch ota mode write opcode */
+#define OTA_VALUE_ENTER 0x01 /**< switch ota mode write value */
+
+/** @brief OTA Write callback data type definition.*/
+#define OTA_WRITE_TEST_MODE_CHAR_VAL 0x02 /**< test mode write opcode */
+
+/** @brief OTA Write callback data type definition.*/
+#define OTA_WRITE_IMAGE_COUNT_VAL 0x02 /**< image count write opcode */
+#define OTA_VALUE_IMAGE_COUNT_APP_ONLY 0x01
+#define OTA_VALUE_IMAGE_COUNT_PATCH_ONLY 0x02
+#define OTA_VALUE_IMAGE_COUNT_APP_AND_PATCH 0x03
+
+#define OTA_CHAR_IMAGE_COUNT_LEN 5
+
+#define CHAR2SHORT(p) (((*(p)) & 0xff) + ((*((p)+1)) << 8))
+
+typedef struct _T_DFU_DEVICE_INFO
+{
+ uint8_t ic_type;
+ uint8_t ota_version;
+ uint8_t secure_version;
+ T_OTA_MODE ota_mode;
+
+ uint16_t max_buffer_size;
+ uint8_t temp_bank_size; //Unit:4K, 0x00:No Limitation of OTA Temp Buffer Size,Only available when Updating Multi Image at a time is supported.
+ uint8_t rsvd;
+ uint32_t img_indicator;
+
+} T_DFU_DEVICE_INFO, * P_DFU_DEVICE_INFO;
+
+typedef struct _T_OTA_UPDATE_IMAGE_INFO
+{
+ uint8_t image_count;
+ uint16_t update_patch_version;
+ uint16_t update_app_version;
+} T_OTA_UPDATE_IMAGE_INFO;
+
+typedef struct _T_OTA_WRITE_MSG
+{
+ uint8_t opcode;
+ union
+ {
+ uint8_t value;
+ T_OTA_UPDATE_IMAGE_INFO update_image_info;
+ } u;
+} T_OTA_WRITE_MSG;
+
+typedef union _T_OTA_UPSTREAM_MSG_DATA
+{
+ uint8_t notification_indification_index;
+ uint8_t read_value_index;
+ T_OTA_WRITE_MSG write;
+} T_OTA_UPSTREAM_MSG_DATA;
+
+/**
+ * @brief OTA servic data struct for notification data to application.
+ *
+ * OTA service data to inform application.
+*/
+typedef struct _T_OTA_CALLBACK_DATA
+{
+ T_SERVICE_CALLBACK_TYPE msg_type; /**< @brief EventId defined upper */
+ T_OTA_UPSTREAM_MSG_DATA msg_data;
+} T_OTA_CALLBACK_DATA;
+
+
+extern uint8_t ota_add_service(void *pFunc);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/inc/bluetooth/profile/server/plxs.h b/inc/bluetooth/profile/server/plxs.h
new file mode 100644
index 0000000..85a40ce
--- /dev/null
+++ b/inc/bluetooth/profile/server/plxs.h
@@ -0,0 +1,401 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file plxs.h
+ * @brief Head file for using Pulse Oximeter Service .
+ * @details Pulse Oximeter Service data types and external functions declaration.
+ * @author danni
+ * @date 2018-12-27
+ * @version v1.0
+ * *************************************************************************************
+ */
+/* Define to prevent recursive inclusion */
+#ifndef _PLXS_H
+#define _PLXS_H
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "profile_server.h"
+#include "plxs_config.h"
+
+/** @defgroup PLXS Pulse Oximeter Service
+ * @brief Pulse Oximeter Service
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PLXS_Exported_Macros PLXS Exported Macros
+ * @brief
+ * @{
+ */
+#define PLXS_SPOT_CHECK_MEASUREMENT_INDICATION_ENABLE 1 /**< spot check measurement indication cccd enable */
+#define PLXS_SPOT_CHECK_MEASUREMENT_INDICATION_DISABLE 2 /**< spot check measurement indication cccd disable */
+#define PLXS_CONTINUOUS_MEASUREMENT_NOTIFY_ENABLE 3 /**< continuous measurement notify cccd enable */
+#define PLXS_CONTINUOUS_MEASUREMENT_NOTIFY_DISABLE 4 /**< continuous measurement notify cccd disable */
+#define PLXS_RACP_INDICATION_ENABLE 5 /**< racp indication cccd enable*/
+#define PLXS_RACP_INDICATION_DISABLE 6 /**< racp indication cccd disable*/
+
+#define PLXS_SFLOAT_VALUE_NaN 0x07ff /**< not a number */
+#define PLXS_SFLOAT_VALUE_NRes 0x0800 /**< not at this resolution */
+#define PLXS_SFLOAT_VALUE_PlusINFINITY 0x07fe /**< + INFINITY */
+#define PLXS_SFLOAT_VALUE_MinusINFINITY 0x0802 /**< - INFINITY */
+#define PLXS_SFLOAT_VALUE_RFU 0x0801 /**< reserved for future use */
+/** @} End of PLXS_Exported_Macros */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PLXS_Exported_Types PLXS Exported Types
+ * @brief
+ * @{
+ */
+/** @brief define PLXS_TIMESTAMP type to store date time data,PLXS_TIMESTAMP[0] = LSO,PLXS_TIMESTAMP[6]=MSO*/
+typedef uint8_t PLXS_TIMESTAMP[7];
+
+/** @brief define PLXS_SFLOAT type to store spo2,pr,Pulse Amplitude Index value,PLXS_SFLOAT[0] = LSO,PLXS_SFLOAT[1] = MSO*/
+typedef uint8_t PLXS_SFLOAT[2];
+
+/** @brief plxs service parameter type*/
+typedef enum
+{
+ PLXS_PARAM_SPOT_CHECK_MEASUREMENT_FLAGS = 0x01,
+ PLXS_PARAM_CONTINUOUS_MEASUREMENT_FLAGS,
+ PLXS_PARAM_FEATURE_FLAGS
+} T_PLXS_PARAM_TYPE;
+
+/** @brief spot check measurement vaule indicate, continuous measurement vaule notify or racp procedure status */
+typedef enum
+{
+ PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_IDLE = 0x00,/**< function plxs_spot_check_measurement_value_indicate() never be called and in initialization state*/
+ PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DOING,/**< function plxs_spot_check_measurement_value_indicate() be called success, but PROFILE_EVT_SEND_DATA_COMPLETE was not received*/
+ PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DONE,/**< function plxs_spot_check_measurement_value_indicate() be called success, and PROFILE_EVT_SEND_DATA_COMPLETE was received*/
+ PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_IDLE,/**< function plxs_continuous_measurement_value_notify() never be called and in initialization state*/
+ PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DOING,/**< function plxs_continuous_measurement_value_notify() be called success, but PROFILE_EVT_SEND_DATA_COMPLETE was not received*/
+ PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DONE,/**< function plxs_continuous_measurement_value_notify() be called success, and PROFILE_EVT_SEND_DATA_COMPLETE was received*/
+ PLXS_STATUS_REPORT_RECORDS_INDICATION_IDLE,/**< function plxs_spot_check_measurement_value_store_indicate() never be called and in initialization state*/
+ PLXS_STATUS_REPORT_RECORDS_INDICATION_DOING,/**< function plxs_spot_check_measurement_value_store_indicate() be called success, but PROFILE_EVT_SEND_DATA_COMPLETE was not received*/
+ PLXS_STATUS_REPORT_RECORDS_INDICATION_DONE,/**< function plxs_spot_check_measurement_value_store_indicate() be called success and PROFILE_EVT_SEND_DATA_COMPLETE was received*/
+ PLXS_STATUS_NOT_SUPPORT,/**< status not supported*/
+} T_PLXS_DATA_SEND_STATUS;
+
+/** @brief APP Return Result List */
+typedef enum
+{
+ PLXS_APP_RESULT_SUCCESS = 0x00,/**< plx service return result success*/
+ PLXS_APP_RESULT_PENDING,/**< if plx service return pending, means that report stored records procedure is in progress,please send data later*/
+ PLXS_APP_RESULT_QUEUE_NULL,/**< plx service return result empty*/
+ PLXS_APP_RESULT_NOT_SUPPORT,/**< plx service return result procedure not support*/
+ PLXS_APP_RESULT_INVALID_VALUE_SIZE,/**< plx service return result invalid value size*/
+ PLXS_APP_RESULT_INVALID_TYPE,/**< plx service return result invalid type*/
+ PLXS_APP_RESULT_INVALID_OFFSET,/**< plx service return result invalid offset*/
+ PLXS_APP_RESULT_POINTER_NULL,/**< plx service return result pointer is null*/
+ PLXS_APP_RESULT_FAIL,/**< plx service return result fail for other reasons*/
+ PLXS_APP_RESULT_CCCD_NOT_ENABLED/**< plx service return result cccd not enable*/
+} T_PLXS_APP_RESULT;
+
+/** @brief measurement status bits*/
+typedef struct
+{
+ uint16_t rfu: 5;
+ uint16_t measurement_ongoing: 1;
+ uint16_t early_estimated_data: 1;
+ uint16_t validated_data: 1;
+ uint16_t fully_qualified_data: 1;
+ uint16_t data_from_measurement_storage: 1;
+ uint16_t data_for_demonstration: 1;
+ uint16_t data_for_testing: 1;
+ uint16_t calibration_ongoing: 1;
+ uint16_t measurement_unavailable: 1;
+ uint16_t questionable_measurement_detected: 1;
+ uint16_t invalid_measurement_detected: 1;
+} T_PLXS_MEASUREMENT_STATE;
+/** @brief device and sensor status bits*/
+typedef struct
+{
+ uint8_t extended_display_update_ongoing: 1;
+ uint8_t equipment_malfunction_detected: 1;
+ uint8_t signal_processing_irregularity_detected: 1;
+ uint8_t inadequate_signal_detected: 1;
+ uint8_t poor_signal_detected: 1;
+ uint8_t low_perfusion_detected: 1;
+ uint8_t erratic_signal_detected: 1;
+ uint8_t nonPulsatile_signal_detected: 1;
+ uint8_t questionable_pulse_detected: 1;
+ uint8_t signal_analysis_ongoing: 1;
+ uint8_t sensor_interference_detected: 1;
+ uint8_t sensor_unconnected_to_user: 1;
+ uint8_t unknown_sensor_connected: 1;
+ uint8_t sensor_displaced: 1;
+ uint8_t sensor_malfunctioning: 1;
+ uint8_t sensor_disconnected: 1;
+ uint8_t rfu: 8;
+} T_PLXS_DEVICE_AND_SENSOR_STATE;
+
+/** @brief typedef spot check measurement value*/
+typedef struct
+{
+ PLXS_SFLOAT spo2;
+ PLXS_SFLOAT pr;
+#if PLXS_SPOT_CHECK_MEASUREMENT_TIMESTAMP_SUPPORT
+ PLXS_TIMESTAMP time;
+#endif
+
+#if PLXS_MEASUREMENT_STATE_SUPPORT
+ T_PLXS_MEASUREMENT_STATE measurement_status;
+#endif
+
+#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT
+ T_PLXS_DEVICE_AND_SENSOR_STATE device_and_sensor_status;
+#endif
+
+#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT
+ PLXS_SFLOAT pulse_amplitude_index;
+#endif
+} T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE;
+
+/** @brief typedef spo2PR*/
+typedef struct
+{
+ PLXS_SFLOAT spo2;
+ PLXS_SFLOAT pr;
+} T_SPO2PR;
+
+/**@brief typedef continuous measurement value*/
+typedef struct
+{
+ T_SPO2PR spo2pr_normal;
+
+#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_FAST_SUPPORT
+ T_SPO2PR spo2pr_fast;
+#endif
+
+#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_SLOW_SUPPORT
+ T_SPO2PR spo2pr_slow;
+#endif
+
+#if PLXS_MEASUREMENT_STATE_SUPPORT
+ T_PLXS_MEASUREMENT_STATE measurement_status;
+#endif
+
+#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT
+ T_PLXS_DEVICE_AND_SENSOR_STATE device_and_sensor_status;
+#endif
+
+#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT
+ PLXS_SFLOAT pulse_amplitude_index;
+#endif
+} T_PLXS_CONTINUOUS_MEASUREMENT_VALUE;
+
+/** @brief typedef features value */
+typedef struct
+{
+ uint16_t supported_features;
+
+#if PLXS_MEASUREMENT_STATE_SUPPORT
+ uint16_t measurement_status_support_bits;
+#endif
+
+#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT
+ uint32_t device_and_sensor_status_support_bits;
+#endif
+} T_PLXS_FEATURES_VALUE;
+
+/** @} End of PLXS_Exported_Types */
+
+/** @defgroup PLXS_Callback_Data PLXS Callback Data
+ * @brief PLXS data struct for notification data to application.
+ * @{
+ */
+typedef union
+{
+ uint8_t notify_indicate_index;
+} T_PLXS_UPSTREAM_MSG_DATA;
+
+typedef struct
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_PLXS_UPSTREAM_MSG_DATA msg_data;
+} T_PLXS_CALLBACK_DATA;
+/** @} End of PLXS_Callback_Data */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PLXS_Exported_Functions PLXS Exported Functions
+ * @brief
+ * @{
+ */
+/**
+ * @brief Add PLX service to the BLE stack database.
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init()
+ {
+ server_init(1);
+ plxs_srv_id = plxs_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID plxs_add_service(void *p_func);
+/**
+ * @brief get plxs parameters such as spot check measurement flags,continuous measurement flags or features supports @ref T_PLXS_PARAM_TYPE
+ *
+ * @param[in] param_type @ref T_PLXS_PARAM_TYPE
+ * @param[in,out] p_value get spot check measurement flags,continuous measurement flags or features supports
+ * @return plxs_get_parameter result
+ * @retval PLXS_APP_RESULT_SUCCESS Operation success.
+ * @retval others Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_plxs_feature_flags_set(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ T_PLXS_FEATURES_VALUE plxs_features;
+ plxs_get_parameter(PLXS_PARAM_FEATURE_FLAGS, &plxs_features);
+ if (p_parse_value->dw_param[0] == 1)
+ {
+ //both measurement status and device sensor status not support
+ plxs_features.supported_features = plxs_features.supported_features & 0xFFFC;
+ }
+ ......
+ }
+ * \endcode
+ */
+T_PLXS_APP_RESULT plxs_get_parameter(T_PLXS_PARAM_TYPE param_type, void *p_value);
+/**
+ * @brief send plxs spot check measurement characteristic indication
+ *
+ * @param[in] conn_id connection index
+ * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID.
+ * @param[in] p_spot_check_measurement_value @ref T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE
+ * @return plxs_spot_check_measurement_value_indicate result
+ * @retval PLXS_APP_RESULT_SUCCESS Operation success.
+ * @retval others Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test_plxs(void)
+ {
+ T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE plxs_spot_check_measure_value;
+ ......//plxs_spot_check_measure_value initialization
+ bool result = plxs_spot_check_measurement_value_indicate(conn_id,plxs_srv_id,&plxs_spot_check_measure_value);
+ if(result == PLXS_APP_RESULT_SUCCESS)
+ {
+ }
+ }
+ * \endcode
+ */
+#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT
+T_PLXS_APP_RESULT plxs_spot_check_measurement_value_indicate(uint8_t conn_id, uint8_t service_id,
+ T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE *p_spot_check_measurement_value);
+#endif
+/**
+ * @brief send plxs continuous measurement characteristic notification
+ *
+ * @param[in] conn_id connection index
+ * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID.
+ * @param[in] plxs_continuous_measurement_value @ref T_PLXS_CONTINUOUS_MEASUREMENT_VALUE
+ * @return plxs_continuous_measurement_value_notify result
+ * @retval PLXS_APP_RESULT_SUCCESS Operation success.
+ * @retval others Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test_plxs(void)
+ {
+ ......//plxs_continuous_measurement_value initialization
+ bool result = plxs_continuous_measurement_value_notify( conn_id, plxs_srv_id,&plxs_continuous_measurement_value);
+ if(result == PLXS_APP_RESULT_SUCCESS)
+ {
+ PROFILE_PRINT_INFO0("plxs_continuous_measurement_value_notify notify data send success!");
+ }
+ }
+ * \endcode
+ */
+#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT
+T_PLXS_APP_RESULT plxs_continuous_measurement_value_notify(uint8_t conn_id, T_SERVER_ID service_id,
+ T_PLXS_CONTINUOUS_MEASUREMENT_VALUE *p_plxs_continuous_measurement_value);
+#endif
+
+/**
+ * @brief clear flags if procedure fail or disconnect
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+ {
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))&& (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+ plxs_flags_clear();//when disconnect clear plxs flags
+ le_adv_start();
+ }
+ break;
+ }
+ }
+ * \endcode
+ */
+void plxs_flags_clear(void);
+/**
+ * @brief plxs check report data send procedure to enable flow control of notification or indication
+ * @param[in] conn_id connection index
+ * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID.
+ * @param[in] attribute_index attribute_index
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_APP_RESULT app_handle_profile_message(T_SERVER_ID service_id, void *p_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_para = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_para->eventId)
+ {
+ ......
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ ......
+ else if (p_para->event_data.send_data_result.service_id == plxs_srv_id)
+ {
+ uint8_t conn_id = p_para->event_data.send_data_result.conn_id;
+ if (p_para->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ plxs_check_report_data_send_procedure(conn_id, plxs_srv_id,p_para->event_data.send_data_result.attrib_idx);
+ }
+ else
+ {
+ APP_PRINT_ERROR1("PROFILE_EVT_SEND_DATA_COMPLETE failed,cause %x", p_para->event_data.send_data_result.cause);
+ }
+ }
+ break;
+ }
+ }
+ }
+ * \endcode
+ */
+void plxs_check_report_data_send_procedure(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attribute_index);
+/** @} End of PLXS_Exported_Functions */
+/** @} End of PLXS */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PULSE_OXIMETER_SERVICE_H */
diff --git a/inc/bluetooth/profile/server/plxs_config.h b/inc/bluetooth/profile/server/plxs_config.h
new file mode 100644
index 0000000..9fe6a00
--- /dev/null
+++ b/inc/bluetooth/profile/server/plxs_config.h
@@ -0,0 +1,128 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file plxs_config.h
+ * @brief Pulse Oximeter Service configuration file.
+ * @details Configure the optional characteristic and fields in the Pulse Oximeter Service.
+ * @author danni
+ * @date 2018-12-27
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion **/
+#ifndef _PLXS_CONFIG_H_
+#define _PLXS_CONFIG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup PLXS Pulse Oximeter Service
+* @brief Pulse Oximeter Service
+* @{
+*/
+
+/** @defgroup PLXS_Service_CONFIG PLXS Service Config
+* @brief PLXS service configuration file
+* @{
+*/
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PLXS_Common_Exported_Macros PLXS Common Exported Macros
+ * @{
+ */
+#define PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT 1 /**< if this value set to 1 means PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT*/
+#define PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT (PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT && 1) /**< if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT is set to 1 then PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT and PLXS_SPOT_CHECK_MEASUREMENT_TIMESTAMP_SUPPORT must be set to 1*/
+#define PLXS_SPOT_CHECK_MEASUREMENT_TIMESTAMP_SUPPORT (PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT && 1) /**< flags to show timestamp field support or not*/
+#define PLXS_DEVICE_CLOCK_NOT_SET (PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT && 1) /**< flags to show clock set or not*/
+
+#define PLXS_MEASUREMENT_STATE_SUPPORT 1 /**< flags to show measurement status field support or not*/
+#define PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT 1 /**< flags to show device and sensor status field support or not*/
+#define PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT 1 /**< flags to show pulse amplitude index field support or not*/
+#define PLXS_MULTIPLE_BONDS_SUPPORT 0 /**< flags to show multiple bonds field support or not*/
+
+#define PLXS_CONTINUOUS_MEASUREMENT_SUPPORT 1 /**< if this value set to 1 means PLXS_CONTINUOUS_MEASUREMENT_SUPPORT*/
+#define PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_FAST_SUPPORT (PLXS_CONTINUOUS_MEASUREMENT_SUPPORT && 1)/**< flags to show spo2pr fast measurement field support or not*/
+#define PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_SLOW_SUPPORT (PLXS_CONTINUOUS_MEASUREMENT_SUPPORT && 1)/**< flags to show spo2pr slow measurement field support or not*/
+
+#define PLXS_RACP_MAX_NBR_OF_STORED_RECS 30 /**< the maximum records to be stored*/
+
+/** @brief The Measurement Status Support field*/
+#define PLXS_FEATURES_MEASUREMENT_STATUS_ONGOING_SUPPORT 0x0020 /**< Measurement Ongoing bit supported*/
+#define PLXS_FEATURES_MEASUREMENT_STATUS_EARLY_ESTIMATED_DATA_SUPPORT 0x0040 /**< Early Estimated Data bit supported*/
+#define PLXS_FEATURES_MEASUREMENT_STATUS_VALIDATED_DATA_SUPPORT 0x0080 /**< Validated Data bit supported*/
+#define PLXS_FEATURES_MEASUREMENT_STATUS_FULLY_QUALIFIED_DATA_SUPPORT 0x0100 /**< Fully Qualified Data bit supported*/
+#define PLXS_FEATURES_MEASUREMENT_STATUS_DATA_FROM_MEASUREMENT_STORAGE_SUPPORT 0x0200 /**< Data from Measurement Storage bit supported*/
+#define PLXS_FEATURES_MEASUREMENT_STATUS_DATA_FOR_DEMONSTRATION_SUPPORT 0x0400 /**< Data for Demonstration bit supported*/
+#define PLXS_FEATURES_MEASUREMENT_STATUS_DATA_FOR_TEST_SUPPORT 0x0800 /**< Data for Testing bit supported*/
+#define PLXS_FEATURES_MEASUREMENT_STATUS_CALIBRATION_ONGOING_SUPPORT 0x1000 /**< Calibration Ongoing bit supported*/
+#define PLXS_FEATURES_MEASUREMENT_STATUS_MEASUREMENT_UNAVAILABLE_SUPPORT 0x2000 /**< Measurement Unavailable bit supported*/
+#define PLXS_FEATURES_MEASUREMENT_STATUS_QUESTIONABLE_MEASUREMENT_DETECTED_SUPPORT 0x4000 /**< Questionable Measurement Detected bit supported*/
+#define PLXS_FEATURES_MEASUREMENT_STATUS_INVALID_MEASUREMENT_DETECTED_SUPPORT 0x8000 /**< Invalid Measurement Detected bit supported*/
+
+/** @brief define plx service features which measurement status are supported. this macro according user needs to add,
+ * for example:
+ * #define PLXS_FEATURES_MEASUREMENT_STATUS_SUPPORTS PLXS_FEATURES_MEASUREMENT_STATUS_ONGOING_SUPPORT|PLXS_FEATURES_MEASUREMENT_STATUS_FULLY_QUALIFIED_DATA_SUPPORT
+ * means both support PLXS_FEATURES_MEASUREMENT_STATUS_ONGOING_SUPPORT and PLXS_FEATURES_MEASUREMENT_STATUS_FULLY_QUALIFIED_DATA_SUPPORT,if you want add other supports,
+ * please @ref The Measurement Status Support field above
+ */
+#define PLXS_FEATURES_MEASUREMENT_STATUS_SUPPORTS (PLXS_FEATURES_MEASUREMENT_STATUS_ONGOING_SUPPORT | PLXS_FEATURES_MEASUREMENT_STATUS_FULLY_QUALIFIED_DATA_SUPPORT)
+
+/** @brief Device and Sensor Status Support field*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_EXTENDED_DISPLAY_UPDATE_ONGOING_SUPPORT 0x000001 /**< Extended Display Update Ongoing bit supported*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_EQUIPMENT_MALFUNCTION_DETECTED_SUPPORT 0x000002 /**< Equipment Malfunction Detected bit supported*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SIGNAL_PROCESSING_IRREGULARITY_DETECTED_SUPPORT 0x000004 /**< Signal Processing Irregularity Detected bit supported*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_INADEQUATE_SIGNAL_DETECTED_SUPPORT 0x000008 /**< Inadequate Signal Detected bit supported*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_POOR_SIGNAL_DETECTED_SUPPORT 0x000010 /**< Poor Signal Detected bit supported*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_LOW_PERFUSION_DETECTED_SUPPORT 0x000020 /**< Low Perfusion Detected bit supported*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_ERRATIC_SIGNAL_DETECTED_SUPPORT 0x000040 /**< Erratic Signal Detected bit supported*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_NONPULSATILE_SIGNAL_DETECTED_SUPPORT 0x000080 /**< Nonpulsatile Signal Detected bit supported*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_QUESTIONABLE_PULSE_DETECTED_SUPPORT 0x000100 /**< Questionable Pulse Detected bit supported*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SIGNAL_ANALYSIS_ONGOING_SUPPORT 0x000200 /**< Signal Analysis Ongoing bit supported*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_INTERFERENCE_DETECTED_SUPPORT 0x000400 /**< Sensor Interference Detected bit supported*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_UNCONNECTED_USER_SUPPORT 0x000800 /**< Sensor Unconnected to User bit supported*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_UNKNOWN_SENSOR_CONNECTED_SUPPORT 0x001000 /**< Unknown Sensor Connected bit supported*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_DISPLACED_SUPPORT 0x002000 /**< Sensor Displaced bit supported*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_MALFUNCTIONING_SUPPORT 0x004000 /**< Sensor Malfunctioning bit supported*/
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_DISCONNECTED_SUPPORT 0x008000 /**< Sensor Disconnected bit supported*/
+
+/** @brief define plx service features which device and sensor status are supported.according user needs to add,
+ * for example:
+ * #define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SUPPORTS PLXS_FEATURES_DEVICE_SENSOR_STATUS_EXTENDED_DISPLAY_UPDATE_ONGOING_SUPPORT|PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_DISCONNECTED_SUPPORT
+ * means both support PLXS_FEATURES_DEVICE_SENSOR_STATUS_EXTENDED_DISPLAY_UPDATE_ONGOING_SUPPORT and PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_DISCONNECTED_SUPPORT,if you want add other supports,
+ * please @ref Device and Sensor Status Support field above
+ */
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SUPPORTS (PLXS_FEATURES_DEVICE_SENSOR_STATUS_EXTENDED_DISPLAY_UPDATE_ONGOING_SUPPORT | PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_DISCONNECTED_SUPPORT)
+
+/** @defgroup PLXS_Service_ATTI_INDEX PLXS Service attribute index
+* @brief PLXS Service attribute index
+* @{
+*/
+#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT
+#define PLXS_CHAR_SPOT_CHECK_MENSUREMENT_INDEX 0x02
+#define PLXS_CHAR_SPOT_CHECK_MENSUREMENT_CCCD_INDEX 0x03
+#endif
+
+#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT
+#define PLXS_CHAR_CONTINUOUS_MEASUREMENT_INDEX ((PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT*3) + 2 )//0x05
+#define PLXS_CHAR_CONTINUOUS_MEASUREMENT_CCCD_INDEX ((PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT*3) + 3 )//0x06
+#endif
+
+#define PLXS_CHAR_FEATURE_INDEX ((PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT*3) + (PLXS_CONTINUOUS_MEASUREMENT_SUPPORT*3)+ 2)//0x05//0x08
+
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+#define PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_INDEX ((PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT*3) + (PLXS_CONTINUOUS_MEASUREMENT_SUPPORT*3)+ 4)//0x07//0x0A
+#define PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_CCCD_INDEX ((PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT*3) + (PLXS_CONTINUOUS_MEASUREMENT_SUPPORT*3)+ 5)//0x08//0x0B
+#endif
+/** @} End of PLXS_Service_ATTI_INDEX */
+/** @} End of PLXS_Common_Exported_Macros */
+/** @} End of PLXS_Service_CONFIG */
+/** @} End of PLXS */
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/inc/bluetooth/profile/server/rcu_dfu_service.h b/inc/bluetooth/profile/server/rcu_dfu_service.h
new file mode 100644
index 0000000..02a522e
--- /dev/null
+++ b/inc/bluetooth/profile/server/rcu_dfu_service.h
@@ -0,0 +1,256 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file dfu_service.h
+* @brief
+* @details
+* @author ken_mei
+* @date 02-09-2016
+* @version v1.0.0
+******************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2015 Realtek Semiconductor Corporation</center></h2>
+******************************************************************************
+*/
+
+#ifndef _DFU_SERVICE_H_
+#define _DFU_SERVICE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "profile_server.h"
+#include "flash_device.h"
+
+#define GATT_UUID128_DFU_PACKET 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0x87, 0x63, 0x00, 0x00
+#define GATT_UUID128_DFU_CONTROL_POINT 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0x87, 0x64, 0x00, 0x00
+
+#define DFU_OPCODE_MIN 0x00
+#define DFU_OPCODE_START_DFU 0x01
+#define DFU_OPCODE_RECEIVE_FW_IMAGE_INFO 0x02
+#define DFU_OPCODE_VALID_FW 0x03
+#define DFU_OPCODE_ACTIVE_IMAGE_RESET 0x04
+#define DFU_OPCODE_SYSTEM_RESET 0x05
+#define DFU_OPCODE_REPORT_TARGET_INFO 0x06
+#define DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ 0x07
+
+#define DFU_OPCODE_PKT_RX_NOTIFICATION_VOICE 0x08
+#define DFU_OPCODE_BUFFER_CHECK_EN 0x09 /*report current ota function version information*/
+#define DFU_OPCODE_REPORT_BUFFER_CRC 0x0a /*report current buffer CRC*/
+
+#define DFU_OPCODE_RECEIVE_IC_TYPE 0x0b
+#define DFU_OPCODE_COPY_IMG 0x0c
+#define DFU_OPCODE_MAX 0x0d
+
+
+#define DFU_OPCODE_NOTIF 0x10
+
+/*length of each control point procedure*/
+#define DFU_LENGTH_START_DFU (1+12)
+#define DFU_LENGTH_RECEIVE_FW_IMAGE_INFO (1+2+4)
+#define DFU_LENGTH_VALID_FW (1+2)
+#define DFU_LENGTH_ACTIVE_IMAGE_RESET 0x01
+#define DFU_LENGTH_SYSTEM_RESET 0x01
+#define DFU_LENGTH_REPORT_TARGET_INFO (1+2)
+#define DFU_LENGTH_PKT_RX_NOTIF_REQ (1+2)
+#define DFU_LENGTH_CONN_PARA_TO_UPDATE_REQ (1+2+2+2+2)
+
+#define DFU_NOTIFY_LENGTH_ARV 3
+#define DFU_NOTIFY_LENGTH_REPORT_TARGET_INFO (3+2+4)
+#define DFU_NOTIFY_LENGTH_PKT_RX_NOTIF (3+2)
+
+
+#define INDEX_DFU_PACKET_VALUE 0x02
+#define INDEX_DFU_CONTROL_POINT_CHAR_VALUE 0x04
+
+#define DFU_OPCODE_MIN 0x00
+#define DFU_OPCODE_START_DFU 0x01
+#define DFU_OPCODE_RECEIVE_FW_IMAGE_INFO 0x02
+#define DFU_OPCODE_VALID_FW 0x03
+#define DFU_OPCODE_ACTIVE_IMAGE_RESET 0x04
+#define DFU_OPCODE_SYSTEM_RESET 0x05
+#define DFU_OPCODE_REPORT_TARGET_INFO 0x06
+#define DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ 0x07
+#define DFU_OPCODE_PKT_RX_NOTIFICATION_VOICE 0x08
+#define DFU_OPCODE_REPORT_FUNCTION_TYPE 0x09 /*report current ota function version information*/
+#define DFU_OPCODE_REPORT_BUFFER_SIZE 0x0a /*report current buffer size information*/
+//#define DFU_OPCODE_REPORT_BUFFER_CRC 0x0b /*report current buffer CRC*/
+#define DFU_OPCODE_INDICATE_BUFFER_IS_VALID 0x0c /*indicate current buffer data if valid*/
+//#define DFU_OPCODE_RECEIVE_IC_TYPE 0x0d
+
+//#define DFU_OPCODE_MAX 0x0e
+
+#define INDEX_DFU_PACKET_VALUE 0x02
+#define INDEX_DFU_CONTROL_POINT_CHAR_VALUE 0x04
+#define INDEX_DFU_CHAR_CCCD_INDEX 0x05
+
+#define DFU_OPCODE_NOTIFICATION 0x10
+//------------------------DFU_LENGTH DEFINE------------------------------
+
+#define DFU_ARV_SUCCESS 0x01
+#define DFU_ARV_FAIL_INVALID_PARAMETER 0x02
+#define DFU_ARV_FAIL_OPERATION 0x03
+#define DFU_ARV_FAIL_DATA_SIZE_EXCEEDS_LIMIT 0x04
+#define DFU_ARV_FAIL_CRC_ERROR 0x05
+#define DFU_ARV_FAIL_LENGTH_ERROR 0x06
+#define DFU_ARV_FAIL_PROG_ERROR 0x07
+#define DFU_ARV_FAIL_ERASE_ERROR 0x08
+#define DFU_ARV_FAIL_SYS_STATE_ERROR 0x09
+
+
+#define DFU_NOTIFY_LENGTH_FUNC_VERSION (1+1+1+2)
+#define DFU_NOTIFY_LENGTH_BUFFER_SIZE (1+1+1+4)
+#define DFU_NOTIFY_LENGTH_BUFFER_CRC (1+1+1+2)
+#define DFU_NOTIFY_LENGTH_BUFFER_IS_VALID (1+1)/*opCode + valid flag*/
+
+typedef struct _T_START_DFU_PARA
+{
+ uint8_t ic_type;
+ uint8_t secure_version;
+ union
+ {
+ uint16_t value;
+ struct
+ {
+ uint16_t xip: 1; // payload is executed on flash
+ uint16_t enc: 1; // all the payload is encrypted
+ uint16_t load_when_boot: 1; // load image when boot
+ uint16_t enc_load: 1; // encrypt load part or not
+ uint16_t enc_key_select: 3; // referenced to ENC_KEY_SELECT
+ uint16_t not_ready : 1; //for copy image in ota
+ uint16_t not_obsolete : 1; //for copy image in ota
+ uint16_t rsvd: 7;
+ };
+ } ctrl_flag;
+ uint16_t signature;
+ uint16_t crc16;
+ uint32_t image_length;
+} T_START_DFU_PARA;
+
+typedef struct _T_PKT_RX_NOTIF_REQ
+{
+ uint16_t packet_num;
+} T_PKT_RX_NOTIF_REQ;
+
+
+typedef struct _T_DFU_CTRL_POINT
+{
+ uint8_t opcode;
+ union
+ {
+ T_START_DFU_PARA start_dfu;
+ T_PKT_RX_NOTIF_REQ pkt_rx_notify_req;
+ } p;
+} T_DFU_CTRL_POINT, * P_DFU_CTRL_POINT;
+
+/**
+* @note: the definition of this struct is accordant with rom define, and if you
+* change the order of members, it will cause crc error when ota complete.
+*/
+typedef struct
+{
+ uint32_t origin_image_version;
+
+ uint32_t nCurOffSet;
+ uint32_t image_total_length;
+
+ uint8_t ic_type;
+ uint8_t secure_version;
+ union
+ {
+ uint16_t value;
+ struct
+ {
+ uint16_t xip: 1; // payload is executed on flash
+ uint16_t enc: 1; // all the payload is encrypted
+ uint16_t load_when_boot: 1; // load image when boot
+ uint16_t enc_load: 1; // encrypt load part or not
+ uint16_t enc_key_select: 3; // referenced to ENC_KEY_SELECT
+ uint16_t not_ready : 1; //for copy image in ota
+ uint16_t not_obsolete : 1; //for copy image in ota
+ uint16_t rsvd: 7;
+ };
+ } ctrl_flag;
+ uint16_t signature;
+ uint16_t crc16;
+ uint32_t image_length;
+
+ bool ota_conn_para_upd_in_progress;
+ uint8_t mtu_size;
+ bool is_dfu_progressing;
+} TDFU_CB;
+
+
+/*Notifications defined here*/
+
+typedef struct _TNOTIFICATION_TARGET_IMAGE_INFO
+{
+
+ uint16_t nOrigFwVersion;
+ uint32_t nImageUpdateOffset;
+} TNOTIFICATION_TARGET_IMAGE_INFO;
+
+typedef struct _TNOTIFICATION_REPORT_PKT_NUM
+{
+ uint16_t PacketNum;
+} TNOTIFICATION_REPORT_PKT_NUM;
+
+typedef struct _TNOTIFICATION_REPORT_OTA_FUNC
+{
+ uint16_t OtaFuncVersion;
+ uint32_t invalid;
+} TNOTIFICATION_REPORT_OTA_FUNC;
+
+
+typedef enum _TNOTIFICATION_REPORT_FUNC_VERSION
+{
+ NORMAL_FUNCTION = 0x0000, /*normal function*/
+ IMAGE_CHECK_FUNCTION = 0x0001 /*image check function*/
+} TNOTIFICATION_REPORT_FUNC_VERSION;
+
+typedef enum _DFU_BUFFER_IS_VALID
+{
+ DFU_BUFFER_VALID = 0x00,
+ DFU_BUFFER_INVALID = 0x01
+} DFU_BUFFER_IS_VALID;
+
+typedef struct _DFUNotification
+{
+ uint8_t opCode;
+ uint8_t reqOpCode;
+ uint8_t respValue;
+ union
+ {
+ TNOTIFICATION_TARGET_IMAGE_INFO NotifyTargetImageInfo;
+ TNOTIFICATION_REPORT_PKT_NUM NotifyPktNum;
+ } p;
+} TDFUNotification, * PDFUNotification;
+
+#define DFU_NOTIFY_ENABLE 1
+#define DFU_NOTIFY_DISABLE 2
+typedef union _TDFU_UPSTREAM_MSG_DATA
+{
+ uint8_t notification_indification_index;
+ uint8_t write_value_index;
+} TDFU_UPSTREAM_MSG_DATA;
+/** Dfu service data to inform application */
+typedef struct _TDFU_CALLBACK_DATA
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ TDFU_UPSTREAM_MSG_DATA msg_data;
+} TDFU_CALLBACK_DATA;
+
+/*============================================================================*
+ * Dfu Interface API
+ *============================================================================*/
+extern uint8_t dfu_add_service(void *p_func);
+extern bool dfu_check_working(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/inc/bluetooth/profile/server/rcu_ota_service.h b/inc/bluetooth/profile/server/rcu_ota_service.h
new file mode 100644
index 0000000..1f970c7
--- /dev/null
+++ b/inc/bluetooth/profile/server/rcu_ota_service.h
@@ -0,0 +1,153 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ota_service.h
+* @brief
+* @details
+* @author hunter_shuai
+* @date 14-July-2015
+* @version v1.0.0
+******************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2015 Realtek Semiconductor Corporation</center></h2>
+******************************************************************************
+*/
+
+#ifndef _OTA_SERVICE_H_
+#define _OTA_SERVICE_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "profile_server.h"
+/** @brief Demo Profile service related UUIDs. */
+
+#define GATT_UUID_CHAR_OTA 0xFFD1 //1
+#define GATT_UUID_CHAR_MAC 0xFFD2 //2
+#define GATT_UUID_CHAR_PATCH 0xFFD3 //3
+#define GATT_UUID_CHAR_APP_VERSION 0xFFD4 //4
+#define GATT_UUID_CHAR_PATCH_EXTENSION 0xFFD5 //5
+#define GATT_UUID_CHAR_TEST_MODE 0xFFD8 //6
+
+#define GATT_UUID_CHAR_DEVICE_INFO 0xFFF1 //7
+#define GATT_UUID_CHAR_IMAGE_COUNT_TO_UPDATE 0xFFF2 //8
+#define GATT_UUID_CHAR_IMAGE_VERSION 0xFFE0
+
+
+//vendor featture for some customers
+
+#define EFLASH_SAVE_OTA_PROCESSING_OFFSET 0x208
+
+
+
+
+/** @brief Index of each characteristic in Demo Profile service database. */
+#define BLE_SERVICE_CHAR_OTA_INDEX 0x02
+#define BLE_SERVICE_CHAR_MAC_ADDRESS_INDEX 0x04
+#define BLE_SERVICE_CHAR_PATCH_INDEX 0x06
+#define BLE_SERVICE_CHAR_APP_VERSION_INDEX 0x08
+#define BLE_SERVICE_CHAR_PATCH_EXTENSION_INDEX 0x0a
+#define BLE_SERVICE_CHAR_TEST_MODE_INDEX 0x0c
+#define BLE_SERVICE_CHAR_DEVICE_INFO_INDEX 0x0e
+#define BLE_SERVICE_CHAR_IMAGE_COUNT_INDEX 0x10
+#define BLE_SERVICE_CHAR_IMAGE_VERSION_INDEX 0x12
+
+/** @brief OTA Write callback data type definition.*/
+#define OTA_WRITE_CHAR_VAL 0x01
+#define OTA_WRITE_TEST_MODE_CHAR_VAL 0x02
+
+/** @brief OTA Write callback data type definition.*/
+#define OTA_WRITE_CHAR_VAL 0x01
+#define OTA_VALUE_ENTER 0x01
+
+#define OTA_WRITE_IMAGE_COUNT_VAL 0x02
+#define OTA_VALUE_IMAGE_COUNT_APP_ONLY 0x01
+#define OTA_VALUE_IMAGE_COUNT_PATCH_ONLY 0x02
+#define OTA_VALUE_IMAGE_COUNT_APP_AND_PATCH 0x03
+
+typedef struct _TOTA_UPDATE_IMAGE_INFO
+{
+ uint8_t image_count;
+ uint16_t update_patch_version;
+ uint16_t update_app_version;
+} TOTA_UPDATE_IMAGE_INFO;
+
+typedef struct _T_DFU_DEVICE_INFO
+{
+ uint8_t ictype;
+ uint8_t ota_version;
+ uint8_t secure_version;
+
+ union
+ {
+ uint8_t value;
+ struct
+ {
+ uint8_t buffercheck: 1; // 1:support, 0:don't support
+ uint8_t aesflg: 1; // 1:aes encrypt when ota, 0:not encrypt
+ uint8_t aesmode: 1; // 1:all data is encrypted, 0:only encrypt 16byte
+ //uint8_t verify_algo: 1; // 1:sha256, 0:crc
+ uint8_t copy_img: 1; //1:support ,0:don't support
+ uint8_t multi_img: 1; //1:support(update multi img at a time) ,0:don't support(one img at a time)
+ uint8_t rsvd: 3;
+ };
+ } mode;
+
+ uint16_t maxbuffersize;
+ uint16_t res;
+
+ uint32_t img_indicator;
+} T_DFU_DEVICE_INFO, * P_DFU_DEVICE_INFO;
+
+
+#define OTA_UPDATE_IMAGE_INFO_LEN 5
+
+#define CHAR2SHORT(p) (((*(p)) & 0xff) + ((*((p)+1)) << 8))
+
+typedef struct _TOTA_WRITE_MSG
+{
+ uint8_t opcode;
+ union
+ {
+ uint8_t value;
+ TOTA_UPDATE_IMAGE_INFO update_image_info;
+ } u;
+} TOTA_WRITE_MSG;
+
+typedef union _TOTA_UPSTREAM_MSG_DATA
+{
+ uint8_t notification_indification_index;
+ uint8_t read_value_index;
+ TOTA_WRITE_MSG write;
+} TOTA_UPSTREAM_MSG_DATA;
+
+/**
+ * @brief OTA servic data struct for notification data to application.
+ *
+ * OTA service data to inform application.
+*/
+typedef struct _TOTA_CALLBACK_DATA
+{
+ T_SERVICE_CALLBACK_TYPE msg_type; /**< @brief EventId defined upper */
+ TOTA_UPSTREAM_MSG_DATA msg_data;
+} TOTA_CALLBACK_DATA;
+
+
+extern uint8_t ota_add_service(void *p_func);
+
+typedef enum _BANK_NUM
+{
+ BANK0 = 0,
+ BANK1 = 1,
+ BANK_UNKNOWN = 2
+} BANK_NUM;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/inc/bluetooth/profile/server/rscs.h b/inc/bluetooth/profile/server/rscs.h
new file mode 100644
index 0000000..cd7d324
--- /dev/null
+++ b/inc/bluetooth/profile/server/rscs.h
@@ -0,0 +1,446 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file rsc_service.h
+ * @brief Head file for using Running Speed and Cadence Service.
+ * @details RSC data structs and external functions declaration.
+ * @author ethan_su
+ * @date 2017-10-10
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _RSCS_SERVICE_DEF_H
+#define _RSCS_SERVICE_DEF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "profile_server.h"
+
+
+
+/** @defgroup RSCS Running Speed and Cadence Service
+ * @brief Running Speed and Cadence Service
+ * @details
+
+ The Running Speed and Cadence (RSC) Service exposes speed, cadence and other data related to fitness applications
+ such as the stride length and the total distance the user has traveled while using the Running Speed and Cadence sensor (Server).
+
+ Application shall register Running Speed and Cadence service when initialization through @ref rscs_add_service function.
+
+ The RSC Measurement characteristic is used to send speed and cadence measurements. Included in the characteristic value are
+ a Flags field (for showing the presence of optional fields and, if supported by the Server, whether the user is walking or running),
+ an Instantaneous Speed field, an Instantaneous Cadence field, depending upon the contents of the Flags field, an Instantaneous
+ Stride Length field and a Total Distance field.
+
+ The Server measures the instantaneous speed at which the user is moving. The cadence represents the number of times per minute
+ the foot with the sensor hits the ground. The stride length represents the distance between two successive contacts of the same foot
+ to the ground and the total distance represents the distance the user has travelled with the sensor since the last reset of the total
+ distance.
+
+ Application can set a running speed and cadence service parameter through @ref rscs_set_parameter function.
+
+ Application can get a running speed and cadence service parameter through @ref rscs_get_parameter function.
+
+ After set service parameter, running speed and cadence service can send notification data to client through @ref rscs_meas_value_notify function.
+
+ Running speed and cadence service can indicate result of calibration to client through @ref rscs_calib_result_indicate function.
+
+ * @{
+ */
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup RSCS_Exported_Macros RSCS Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @defgroup RSCS_Measurement_Flag_Bit_Mask RSC Measurement Flag Bit Mask
+ * @brief RSC measurement 'Flags' present bit mask.
+ * @{
+ */
+#define RSCS_INC_STRIDE_LENGTH_MASK (1) /**< Instantaneous Stride Length Present. */
+#define RSCS_INC_TOTAL_DISTANCE_MASK (1<<1) /**< Total Distance Present. */
+#define RSCS_INC_RUNNING_STATUS_MASK (1<<2) /**< Walking or Running Status bits. */
+#define RSCS_INC_ALL_PRESENTS (0x07)
+/** @} */
+
+/** @defgroup RSCS_Feature_Bit_Mask RSC Feature Bit Mask
+ * @brief RSC features bit mask.
+ * @{
+ */
+#define RSCS_SUPPORT_STRIDE_LENGTH_MASK (1)
+#define RSCS_SUPPORT_TOTAL_DISTANCE_MASK (1<<1)
+#define RSCS_SUPPORT_RUNNING_STATUS_MASK (1<<2)
+#define RSCS_SUPPORT_CALIBRATE_MASK (1<<3)
+#define RSCS_SUPPORT_MULTI_SENSOR_MASK (1<<4)
+#define RSCS_ALL_FEATURE_SUPPORTED (0x1F)
+/** @} */
+
+/** @defgroup RSCS_Sensor_Location_Bit_Mask RSC Sensor Location Bit Mask
+ * @brief RSC supported sensor location bit mask.
+ * @{
+ */
+#define RSCS_SENS_LOC_OTHER_MASK (1)
+#define RSCS_SENS_LOC_TOP_OF_SHOE_MASK (1<<1)
+#define RSCS_SENS_LOC_IN_SHOE_MASK (1<<2)
+#define RSCS_SENS_LOC_HIP_MASK (1<<3)
+#define RSCS_SENS_LOC_FRONT_WHEEL_MASK (1<<4)
+#define RSCS_SENS_LOC_LEFT_CRANK_MASK (1<<5)
+#define RSCS_SENS_LOC_RIGHT_CRANK_MASK (1<<6)
+#define RSCS_SENS_LOC_LEFT_PEDAL_MASK (1<<7)
+#define RSCS_SENS_LOC_RIGHT_PEDAL_MASK (1<<8)
+#define RSCS_SENS_LOC_FRONT_HUB_MASK (1<<9)
+#define RSCS_SENS_LOC_REAR_DROPOUT_MASK (1<<10)
+#define RSCS_SENS_LOC_CHAINSTAY_MASK (1<<11)
+#define RSCS_SENS_LOC_REAR_WHEEL_MASK (1<<12)
+#define RSCS_SENS_LOC_REAR_HUB_MASK (1<<13)
+#define RSCS_SENS_LOC_CHEST_MASK (1<<14)
+#define RSCS_ALL_SENS_LOC_SUPPORTED (0x7FFF)
+/** @} */
+
+/** @defgroup RSCS_Control_Point_OpCodes RSC Control Point OpCodes
+ * @brief Control Point OpCodes
+ * @{
+ */
+#define RSCS_CP_OPCODE_RESERVED 0x00
+#define RSCS_CP_OPCODE_SET_CUMULATIVE 0x01
+#define RSCS_CP_OPCODE_START_CALIBRATION 0x02
+#define RSCS_CP_OPCODE_UPDATE_SENS_LOC 0x03
+#define RSCS_CP_OPCODE_REQ_SENS_LOC_LIST 0x04
+#define RSCS_CP_OPCODE_RSP_CODE 0x10
+/** @} */
+
+/** @defgroup RSCS_Control_Point_Response_Codes RSC Control Point Response Codes
+ * @brief Control Point Response Codes
+ * @{
+ */
+#define RSCS_CP_RSPCODE_RESERVED 0x00
+#define RSCS_CP_RSPCODE_SUCCESS 0x01
+#define RSCS_CP_RSPCODE_OPCODE_UNSUPPORT 0x02
+#define RSCS_CP_RSPCODE_INVALID_PARAMETER 0x03
+#define RSCS_CP_RSPCODE_OPERATION_FAILED 0x04
+/** @} */
+
+/** @defgroup RSCS_Error_Codes RSC Error Codes
+ * @brief Error codes defined in RSC spec
+ * @{
+ */
+#define RSCS_ERR_PROC_ALREADY_IN_PROG 0x80
+#define RSCS_ERR_CCCD_IMPROPERLY_CFG 0x81
+/** @} */
+
+/** @defgroup RSCS_Data_Length RSC Data Length
+ * @brief Max bytes of RSC Measurement data and RSC Control Point data
+ * @{
+ */
+#define RSCS_MAX_MEASUREMENT_VALUE 10
+#define RSCS_MAX_CTL_PNT_VALUE 18
+/** @} */
+
+
+/** @defgroup RSCS_Read_Info RSC Read Info
+ * @brief Parameter for reading characteristic value.
+ * @{
+ */
+#define RSCS_READ_RSCS_FEATURE 1
+#define RSCS_READ_SENSOR_LOCATION 2
+/** @} */
+
+/** @defgroup RSCS_Notify_Indicate_Info RSCS Notify Indicate Info
+ * @brief Parameter for enable or disable notification or indication.
+ * @{
+ */
+#define RSCS_NOTIFY_INDICATE_MEASUREMENT_ENABLE 1
+#define RSCS_NOTIFY_INDICATE_MEASUREMENT_DISABLE 2
+#define RSCS_NOTIFY_INDICATE_SC_CP_ENABLE 3
+#define RSCS_NOTIFY_INDICATE_SC_CP_DISABLE 4
+/** @} */
+
+/** End of RSCS_Exported_Macros
+* @}
+*/
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup RSCS_Exported_Types RSCS Exported Types
+ * @brief
+ * @{
+ */
+
+/**
+* @brief RSC service parameter type
+*/
+typedef enum
+{
+ RSCS_PARAM_CSCS_FEATURE = 0x01,
+ RSCS_PARAM_INC_FLAG,
+ RSCS_PARAM_SPEED,
+ RSCS_PARAM_CADENCE,
+ RSCS_PARAM_STRIDE_LENGTH,
+ RSCS_PARAM_TOTALDISTANCE,
+ RSCS_PARAM_CTL_PNT_PROG_CLR,
+ RSCS_PARAM_SENSOR_LOC,
+} T_RSCS_PARAM_TYPE;
+
+
+/** @defgroup RSCS_Sensor_Locations RSC Sensor Locations
+ * @brief All RSC sensor locations defined in spec
+ * @{
+ */
+typedef enum
+{
+ RSCS_SENSOR_LOC_OTHER = 0,
+ RSCS_SENSOR_LOC_TOP_OF_SHOE = 1,
+ RSCS_SENSOR_LOC_IN_SHOE = 2,
+ RSCS_SENSOR_LOC_HIP = 3,
+ RSCS_SENSOR_LOC_FRONT_WHEEL = 4,
+ RSCS_SENSOR_LOC_LEFT_CRANK = 5,
+ RSCS_SENSOR_LOC_RIGHT_CRANK = 6,
+ RSCS_SENSOR_LOC_LEFT_PEDAL = 7,
+ RSCS_SENSOR_LOC_RIGHT_PEDAL = 8,
+ RSCS_SENSOR_LOC_FRONT_HUB = 9,
+ RSCS_SENSOR_LOC_REAR_DROPOUT = 10,
+ RSCS_SENSOR_LOC_CHAINSTAY = 11,
+ RSCS_SENSOR_LOC_REAL_WHEEL = 12,
+ RSCS_SENSOR_LOC_REAL_HUB = 13,
+ RSCS_SENSOR_LOC_CHEST = 14,
+ RSCS_SENSOR_LOC_MAX
+} TRSCSensorLocation;
+/** @} */
+
+/** @defgroup RSCS_Measurement_Data RSC Measurement Data
+ * @brief RSC measurement data, variable length during connection, max can reach 10 bytes
+ * @{
+ */
+typedef struct
+{
+ uint8_t cur_length; /**< length of current RSC measurement data. */
+ uint8_t value[RSCS_MAX_MEASUREMENT_VALUE]; /**< value of current RSC measurement data. */
+} T_RSCS_MEASUREMENT;
+/** @} */
+
+/** @defgroup RSCS_Control_Point_Data RSC Control Point Data
+ * @brief RSC Control Point data, variable length during connection, max can reach 18 bytes
+ * @{
+ */
+typedef struct
+{
+ uint8_t cur_length; /**< length of current RSC Control Point data, . */
+ uint8_t value[RSCS_MAX_CTL_PNT_VALUE]; /**< value of current RSC Control Point data, . */
+} T_RSCS_CONTROL_POINT;
+/** @} */
+
+
+/** @defgroup RSCS_Callback_Data RSCS Callback Data
+ * @brief RSC data struct for notification data to application.
+ * @{
+ */
+typedef union
+{
+ uint8_t sensor_location_value;
+ uint32_t cumulative_value;
+} T_RSCS_CP_PARAMETER;
+
+typedef struct
+{
+ uint8_t opcode; //!< ref: @ref RSCS_Control_Point_OpCodes
+ T_RSCS_CP_PARAMETER cp_parameter;
+} T_RSCS_WRITE_MSG;
+
+typedef union
+{
+ uint8_t notification_indification_index; //!< ref: @ref RSCS_Notify_Indicate_Info
+ uint8_t read_value_index; //!< ref: @ref RSCS_Read_Info
+ T_RSCS_WRITE_MSG write;
+} T_RSCS_UPSTREAM_MSG_DATA;
+
+/** RSC service data to inform application */
+typedef struct
+{
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_RSCS_UPSTREAM_MSG_DATA msg_data;
+} T_RSCS_CALLBACK_DATA;
+/** @} */
+
+/** End of RSCS_Exported_Types
+* @}
+*/
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup RSCS_Exported_Functions RSCS Exported Functions
+ * @brief
+ * @{
+ */
+
+
+/**
+ * @brief Add Running Speed and Cadence Service.
+ *
+ * @param[in] p_func Callback when service attribute was read/write.
+ *
+ * @return service id @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ rscs_id = rscs_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID rscs_add_service(void *p_func);
+
+
+/**
+ * @brief Set a Running Speed and Cadence Service parameter.
+ *
+ * NOTE: You can call this function with a Running Speed and Cadence Service parameter type and it will set the
+ * Running Speed and Cadence Service parameter. Running Speed and Cadence Service parameters are defined
+ * in @ref T_RSCS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Running Speed and Cadence Service parameter type: @ref T_RSCS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint32_t total_distance = p_parse_value->dw_param[0];
+ bool op_result;
+
+ op_result = rscs_set_parameter(RSCS_PARAM_TOTALDISTANCE, 4, (uint8_t*)&total_distance);
+
+ if ( op_result )
+ {
+ rscs_get_parameter( RSCS_PARAM_TOTALDISTANCE, &total_distance );
+ data_uart_print("set total_distance = %d\r\n", total_distance);
+ }
+ else
+ {
+ data_uart_print("rscs_set_parameter total_distance failed\r\n");
+ }
+ }
+ * \endcode
+ */
+bool rscs_set_parameter(T_RSCS_PARAM_TYPE param_type, uint8_t len, void *p_value);
+
+/**
+ * @brief Get a Running Speed and Cadence Service parameter.
+ *
+ * NOTE: You can call this function with a Running Speed and Cadence Service parameter type and it will get the
+ * parameter. Running Speed and Cadence Service parameters are defined in @ref T_RSCS_PARAM_TYPE.
+ *
+ * @param[in] param_type Running Speed and Cadence Service parameter type: @ref T_RSCS_PARAM_TYPE
+ * @param[in] p_value Pointer to data to read.
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t bFlag;
+
+ rscs_get_parameter(RSCS_PARAM_INC_FLAG, &bFlag);
+ }
+ * \endcode
+ */
+bool rscs_get_parameter(T_RSCS_PARAM_TYPE param_type, void *p_value);
+
+/**
+ * @brief Send Running Speed and Cadence Service value notification data.
+ * Application shall call @ref rscs_set_parameter to set value first,
+ * and then call this api to send the notication value.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ *
+ * @return service id @ref T_SERVER_ID.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ bool op_result;
+ uint8_t flag = RSCS_INC_ALL_PRESENTS;
+
+ rscs_set_parameter(RSCS_PARAM_INC_FLAG, 1, &flag);
+
+ op_result = rscs_meas_value_notify(p_parse_value->dw_param[0], rscs_id);
+
+ if ( op_result )
+ {
+ data_uart_print("Notify RSC measurement value succeed\r\n");
+ }
+ else
+ {
+ data_uart_print("Notify RSC measurement value failed\r\n");
+ }
+
+ }
+ * \endcode
+ */
+bool rscs_meas_value_notify(uint8_t conn_id, T_SERVER_ID service_id);
+
+/**
+ * @brief Send Running Speed and Cadence Service value indication data,
+ * send indication of result of calibration to client.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] result calibration result.
+ *
+ * @return none;
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint8_t result = p_parse_value->dw_param[1];
+ rscs_calib_result_indicate(conn_id, rscs_id, result);
+ data_uart_print("cmd_rscs_calib_result_indicate result= %d\r\n", result);
+ }
+ * \endcode
+ */
+void rscs_calib_result_indicate(uint8_t conn_id, T_SERVER_ID service_id, bool result);
+
+
+/** @} End of RSCS_Exported_Functions */
+
+
+/** @} End of RSCS */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RSCS_DEF_H */
diff --git a/inc/bluetooth/profile/server/simple_ble_config.h b/inc/bluetooth/profile/server/simple_ble_config.h
new file mode 100644
index 0000000..04b7fb7
--- /dev/null
+++ b/inc/bluetooth/profile/server/simple_ble_config.h
@@ -0,0 +1,63 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file simple_ble_config.h
+ * @brief This file includes common constants or types for Simple BLE service/client.
+ * And some optional feature may be defined in this file.
+ * @details
+ * @author Ethan
+ * @date 2016-02-18
+ * @version v0.1
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion **/
+#ifndef _SIMPLE_BLE_CONFIG_H_
+#define _SIMPLE_BLE_CONFIG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @defgroup SIMP_Service Simple Ble Service
+ * @brief Simple BLE service
+ * @{
+ */
+
+/** @defgroup SIMP_Service_CONFIG SIMP Service Config
+ * @brief Simple BLE service configuration file
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup SIMP_Common_Exported_Macros SIMP Service Config Exported Constants
+ * @brief
+ * @{
+ */
+
+/** @defgroup SIMP_UUIDs SIMP UUIDs
+ * @brief Simple BLE Profile UUID definitions
+ * @{
+ */
+#define GATT_UUID_SIMPLE_PROFILE 0xA00A
+#define GATT_UUID_CHAR_SIMPLE_V1_READ 0xB001
+#define GATT_UUID_CHAR_SIMPLE_V2_WRITE 0xB002
+#define GATT_UUID_CHAR_SIMPLE_V3_NOTIFY 0xB003
+#define GATT_UUID_CHAR_SIMPLE_V4_INDICATE 0xB004
+/** @} End of SIMP_UUIDs */
+
+/** @} End of SIMP_Common_Exported_Macros */
+
+/** @} End of SIMP_Service_CONFIG */
+
+/** @} End of SIMP_Service */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/inc/bluetooth/profile/server/simple_ble_service.h b/inc/bluetooth/profile/server/simple_ble_service.h
new file mode 100644
index 0000000..93d69b8
--- /dev/null
+++ b/inc/bluetooth/profile/server/simple_ble_service.h
@@ -0,0 +1,205 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file simple_ble_service.h
+ * @brief Demonstration of how to implement a self-definition service.
+ * @details Demonstration of different kinds of service interfaces.
+ * @author
+ * @date
+ * @version
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _SIMPLE_BLE_SERVICE_H_
+#define _SIMPLE_BLE_SERVICE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include <profile_server.h>
+#include <simple_ble_config.h>
+
+
+/** @defgroup SIMP_Service Simple Ble Service
+ * @brief Simple BLE service
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup SIMP_Service_Exported_Macros SIMP Service Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @defgroup SIMP_Service_Application_Parameters SIMP Service Application Parameters
+ * @brief Type of parameters set/got from application.
+ * @{
+ */
+typedef enum
+{
+ SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL = 0x01,
+} T_SIMP_PARAM_TYPE;
+
+/** @} */
+
+
+
+/** @defgroup SIMP_Service_Upstream_Message SIMP Service Upstream Message
+ * @brief Upstream message used to inform application.
+ * @{
+ */
+
+/** @defgroup SIMP_Service_Read_Info SIMP Service Read Info
+ * @brief Parameter for reading characteristic value.
+ * @{
+ */
+#define SIMP_READ_V1 1
+/** @} */
+
+/** @defgroup SIMP_Service_Write_Info SIMP Service Write Info
+ * @brief Parameter for writing characteristic value.
+ * @{
+ */
+#define SIMP_WRITE_V2 1
+
+/** @} */
+
+/** @defgroup SIMP_Service_Notify_Indicate_Info SIMP Service Notify Indicate Info
+ * @brief Parameter for enable or disable notification or indication.
+ * @{
+ */
+#define SIMP_NOTIFY_INDICATE_V3_ENABLE 1
+#define SIMP_NOTIFY_INDICATE_V3_DISABLE 2
+#define SIMP_NOTIFY_INDICATE_V4_ENABLE 3
+#define SIMP_NOTIFY_INDICATE_V4_DISABLE 4
+
+
+/** @} */
+
+#define SIMP_READ_V1_MAX_LEN 300
+
+/** @} End of SIMP_Service_Upstream_Message */
+
+
+
+/** @} End of SIMP_Service_Exported_Macros */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup SIMP_Service_Exported_Types SIMP Service Exported Types
+ * @brief
+ * @{
+ */
+
+/** @defgroup TSIMP_WRITE_MSG TSIMP_WRITE_MSG
+ * @brief Simple BLE service written msg to application.
+ * @{
+ */
+typedef struct
+{
+ uint8_t opcode; //!< ref: @ref SIMP_Service_Write_Info
+ T_WRITE_TYPE write_type;
+ uint16_t len;
+ uint8_t *p_value;
+} TSIMP_WRITE_MSG;
+/** @} End of TSIMP_WRITE_MSG */
+
+
+/** @defgroup TSIMP_UPSTREAM_MSG_DATA TSIMP_UPSTREAM_MSG_DATA
+ * @brief Simple BLE service callback message content.
+ * @{
+ */
+typedef union
+{
+ uint8_t notification_indification_index; //!< ref: @ref SIMP_Service_Notify_Indicate_Info
+ uint8_t read_value_index; //!< ref: @ref SIMP_Service_Read_Info
+ TSIMP_WRITE_MSG write;
+} TSIMP_UPSTREAM_MSG_DATA;
+/** @} End of TSIMP_UPSTREAM_MSG_DATA */
+
+/** @defgroup TSIMP_CALLBACK_DATA TSIMP_CALLBACK_DATA
+ * @brief Simple BLE service data to inform application.
+ * @{
+ */
+typedef struct
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ TSIMP_UPSTREAM_MSG_DATA msg_data;
+} TSIMP_CALLBACK_DATA;
+/** @} End of TSIMP_CALLBACK_DATA */
+
+/** @} End of SIMP_Service_Exported_Types */
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup SIMP_Service_Exported_Functions SIMP Service Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add simple BLE service to the BLE stack database.
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ */
+T_SERVER_ID simp_ble_service_add_service(void *p_func);
+
+/**
+ * @brief Set service related data from application.
+ *
+ * @param[in] param_type parameter type to set.
+ * @param[in] len value length to be set.
+ * @param[in] p_value value to set.
+ * @return parameter set result.
+ * @retval 0 false
+ * @retval 1 true
+ */
+bool simp_ble_service_set_parameter(T_SIMP_PARAM_TYPE param_type, uint16_t len, void *p_value);
+
+/**
+ * @brief send notification of simple notify characteristic value.
+ *
+ * @param[in] conn_id connection id
+ * @param[in] service_id service ID of service.
+ * @param[in] p_value characteristic value to notify
+ * @param[in] length characteristic value length to notify
+ * @return notification action result
+ * @retval 1 true
+ * @retval 0 false
+ */
+bool simp_ble_service_send_v3_notify(uint8_t conn_id, T_SERVER_ID service_id,
+ void *p_value, uint16_t length);
+/**
+ * @brief send indication of simple indicate characteristic value.
+ *
+ * @param[in] conn_id connection id
+ * @param[in] service_id service ID of service.
+ * @param[in] p_value characteristic value to notify
+ * @param[in] length characteristic value length to notify
+ * @return notification action result
+ * @retval 1 true
+ * @retval 0 false
+ */
+bool simp_ble_service_send_v4_indicate(uint8_t conn_id, T_SERVER_ID service_id,
+ void *p_value, uint16_t length);
+
+/** @} End of SIMP_Service_Exported_Functions */
+
+/** @} End of SIMP_Service */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SIMPLE_BLE_SERVICE_H_ */
diff --git a/inc/bluetooth/profile/server/sps.h b/inc/bluetooth/profile/server/sps.h
new file mode 100644
index 0000000..a7ac4de
--- /dev/null
+++ b/inc/bluetooth/profile/server/sps.h
@@ -0,0 +1,219 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file sps.h
+ * @brief Head file for using scan parameters service.
+ * @details SPS data structs and external functions declaration.
+ * @author
+ * @date
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _SPS_H_
+#define _SPS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "profile_server.h"
+
+
+/** @defgroup SPS Scan Parameters Service
+ * @brief Scan parameters service
+ * @details
+
+ The Scan Parameters Service enables a GATT Server device to expose a characteristic for the GATT Client
+ to write its scan interval and scan window on the GATT Server device, and enables a GATT Server to
+ request a refresh of the GATT Client scan interval and scan window.Scan Parameter Service makes up the
+ services of HID Device, together with HID Service. Its role is to implement the interaction of data
+ information when needing to change Scan parameters.
+
+ Scan Parameter Service contains two Characteristics: one is scan interval and scan window, and it is used
+ to store Scan Parameters of the Client; the other is Scan Refresh, and it is used to notify the Client to
+ update the value of Scan parameter according to recent data by notification.
+
+ The specific configuration can be achieved by modifying @ref sps_config.h.
+
+ Application shall register scan parameter service when initialization through @ref sps_add_service function.
+
+ Application can set the scan refresh value through @ref sps_set_parameter function.
+
+ Application can notify refresh value to client through @ref sps_scan_interval_window_value_notify function.
+
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup SPS_Exported_Macros SPS Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @defgroup SPS_Write_Info SPS Write Info
+ * @brief Parameter for writing characteristic value.
+ * @{
+ */
+#define SPS_WRITE_SCAN_INTERVAL_WINDOW 1
+/** @} */
+
+/** @defgroup SPS_Notify_Indicate_Info SPS Notify Indicate Info
+ * @brief Parameter for enable or disable notification or indication.
+ * @{
+ */
+#define SPS_NOTIFY_INDICATE_SCAN_REFRESH_ENABLE 1
+#define SPS_NOTIFY_INDICATE_SCAN_REFRESH_DISABLE 2
+/** @} */
+
+/** @} End of SPS_Exported_Macros */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup SPS_Exported_Types SPS Exported Types
+ * @brief
+ * @{
+ */
+
+/** @defgroup SPS_PARAM_TYPE SPS Parameter Types
+* @brief
+* @{
+*/
+typedef enum
+{
+ SPS_PARAM_SCAN_REFRESH
+} T_SPS_PARAM_TYPE;
+
+/** @} */
+
+/** SPS scan interval window structure*/
+typedef struct
+{
+ uint16_t scan_interval;
+ uint16_t scan_window;
+} T_SPS_SCAN_INTERVAL_WINDOW;
+
+
+/** SPS write parameter*/
+typedef union
+{
+ T_SPS_SCAN_INTERVAL_WINDOW scan;
+} T_SPS_WRITE_PARAMETER;
+
+/** SPS write message*/
+typedef struct
+{
+ uint8_t write_type;
+ T_SPS_WRITE_PARAMETER write_parameter;
+} T_SPS_WRITE_MSG;
+
+/** SPS upstream message data*/
+typedef union
+{
+ uint8_t notification_indification_index;
+ T_SPS_WRITE_MSG write;
+} T_SPS_UPSTREAM_MSG_DATA;
+
+/** SPS callback data*/
+typedef struct
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_SPS_UPSTREAM_MSG_DATA msg_data;
+} T_SPS_CALLBACK_DATA;
+
+/** @} End of SPS_Exported_Types */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup SPS_Exported_Functions SPS Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Set a scan parameter service parameter.
+ *
+ * NOTE: You can call this function with a scan parameter service parameter type and it will set the
+ * scan parameter service parameter. Scan parameter service parameters are defined in @ref T_SPS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Scan parameter service parameter type: @ref T_SPS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t refresh_value = 10;
+ sps_set_parameter(SPS_PARAM_SCAN_REFRESH, 1, &refresh_value);
+ }
+ * \endcode
+ */
+bool sps_set_parameter(T_SPS_PARAM_TYPE param_type, uint8_t len, void *p_value);
+
+/**
+ * @brief Add scan parameters service to the BLE stack database.
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ sps_id = sps_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID sps_add_service(void *p_func);
+
+/**
+ * @brief send notification.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID of service.
+ * @param[in] sps_refresh_value characteristic value to notify
+ * @return notification action result
+ * @retval 1 TRUE
+ * @retval 0 FALSE
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t sps_refresh_value = 10;
+ sps_scan_interval_window_value_notify(conn_id, sps_id, sps_refresh_value);
+ }
+ * \endcode
+ */
+bool sps_scan_interval_window_value_notify(uint8_t conn_id, uint8_t service_id,
+ uint8_t sps_refresh_value);
+/** @} End of SPS_Exported_Functions */
+
+/** @} End of SPS */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _SPS_H_ */
+
diff --git a/inc/bluetooth/profile/server/sps_config.h b/inc/bluetooth/profile/server/sps_config.h
new file mode 100644
index 0000000..df477ba
--- /dev/null
+++ b/inc/bluetooth/profile/server/sps_config.h
@@ -0,0 +1,35 @@
+#ifndef _SPS_CONFIG_H_
+#define _SPS_CONFIG_H_
+
+
+/** @defgroup SPS Scan Parameters Service
+ * @brief Scan parameters service
+ * @{
+ */
+
+/** @defgroup SPS_CONFIG Scan Parameters Service Config
+ * @brief Scan parameters service config
+ * @{
+ */
+
+/** @defgroup SPS_Exported_Macros SPS Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @details
+ Set SPS_CHAR_SCAN_REFRESH_SUPPORT to 1 to support scan refresh characteristic,
+ otherwise set it to 0.
+*/
+#define SPS_CHAR_SCAN_REFRESH_SUPPORT 1
+
+
+/** @} End of SPS_Common_Exported_Macros */
+
+/** @} End of SPS_CONFIG */
+
+/** @} End of SPS */
+
+
+
+#endif
diff --git a/inc/bluetooth/profile/server/tps.h b/inc/bluetooth/profile/server/tps.h
new file mode 100644
index 0000000..48680c3
--- /dev/null
+++ b/inc/bluetooth/profile/server/tps.h
@@ -0,0 +1,158 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file tps.h
+ * @brief Head file for using TX power service.
+ * @details TPS data structs and external functions declaration.
+ * @author
+ * @date
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#ifndef _TPS_H_
+#define _TPS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdint.h>
+#include "profile_server.h"
+
+
+/** @defgroup TPS Tx Power Service
+ * @brief Tx power service
+ * @details
+
+ The Tx Power service uses the Tx Power Level characteristic to expose the current transmit power level
+ of a device when in a connection.The Tx Power service contains only a Tx Power Level characteristic.
+ The Tx Power Service generally makes up a profile with some other services, such as Proximity, and its
+ role is to indicate a device's transmit power level when in a connection.
+
+ Application shall register Tx Power service when initialization through @ref tps_add_service function.
+
+ Application can set the TX power value through @ref tps_set_parameter function.
+
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup TPS_Exported_Macros TPS Exported Macros
+ * @brief
+ * @{
+ */
+/** @defgroup TPS_Read_Info TPS Read Info
+ * @brief Read characteristic value.
+ * @{
+ */
+#define TPS_READ_TX_POWER_VALUE 1
+/** @} */
+/** @} End of TPS_Exported_Macros */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup TPS_Exported_Types TPS Exported Types
+ * @brief
+ * @{
+ */
+/* Add all public types here */
+/** @defgroup TPS_Application_Parameters TPS Application Parameters
+ * @brief Type of parameters set/got from application.
+ * @{
+ */
+typedef enum
+{
+ TPS_PARAM_TX_POWER
+} T_TPS_PARAM_TYPE;
+/** @} */
+
+/** @defgroup TPS_Upstream_Message TPS Upstream Message
+ * @brief TPS data struct for notification data to application.
+ * @{
+ */
+/** Message content: @ref TPS_Upstream_Message */
+typedef union
+{
+ uint8_t read_value_index;
+} T_TPS_UPSTREAM_MSG_DATA;
+
+/** TPS service data to inform application. */
+typedef struct
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_TPS_UPSTREAM_MSG_DATA msg_data;
+} T_TPS_CALLBACK_DATA;
+/** @} */
+
+/** @} End of TPS_Exported_Types */
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup TPS_Exported_Functions TPS Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Set a Tx power service parameter.
+ *
+ * NOTE: You can call this function with a tx power service parameter type and it will set the
+ * tx power service parameter. Tx power service parameters are defined in @ref T_TPS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Tx power service parameter type: @ref T_TPS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (example: data type of uint16 will be cast to
+ * uint16 pointer).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t tx_power = 0;
+ tps_set_parameter(TPS_PARAM_TX_POWER, 1, &tx_power);
+ }
+ * \endcode
+ */
+bool tps_set_parameter(T_TPS_PARAM_TYPE param_type, uint8_t len, void *p_value);
+
+
+/**
+ * @brief Add tx power service to the BLE stack database.
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ tps_id = tps_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID tps_add_service(void *p_func);
+
+/** @} End of TPS_Exported_Functions */
+
+/** @} End of TPS */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _TPS_H_ */
diff --git a/inc/bluetooth/profile/server/vendor_service.h b/inc/bluetooth/profile/server/vendor_service.h
new file mode 100644
index 0000000..2f76295
--- /dev/null
+++ b/inc/bluetooth/profile/server/vendor_service.h
@@ -0,0 +1,80 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file vendor_service.h
+ * @brief Head file for using Vendor Service Remote Controller.
+ * @details Vendor service data structs and external functions declaration.
+ * @author Chenjie Jin
+ * @date 2018-5-7
+ * @version v1.1
+ * *************************************************************************************
+ */
+
+#ifndef _VENDOR_SERVICE_H_
+#define _VENDOR_SERVICE_H_
+
+#include "profile_server.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/** @brief Demo Profile service related UUIDs. */
+
+#define GATT_UUID_CHAR_VENDOR_HANDSHAKE 0xA001
+#define GATT_UUID_CHAR_VENDOR_TEST_MODE 0xA002
+
+/** @brief Index of each characteristic in Demo Profile service database. */
+#define BLE_SERVICE_CHAR_VENDOR_HANDSHAKE_INDEX 0x02
+#define GATT_SVC_VENDOR_HANDSHAKE_CHAR_CCCD_INDEX 0x03
+#define BLE_SERVICE_CHAR_VENDOR_TEST_MODE_INDEX 0x05
+
+#define VENDOR_WRITE_HANDSHAKE 1
+#define VENDOR_WRITE_TEST_MODE 2
+
+#define VENDOR_NOTIFY_ENABLE 1
+#define VENDOR_NOTIFY_DISABLE 2
+
+/** Message content */
+typedef union
+{
+ struct
+ {
+ uint8_t len;
+ uint8_t *report;
+ } report_data;
+} T_VENDOR_WRITE_PARAMETER;
+
+/** @struct _TATVV_WRITE_MSG
+ * @brief write message
+ */
+typedef struct
+{
+ uint8_t write_type; /**< ref: @ref Vendor_Write_Info */
+ T_VENDOR_WRITE_PARAMETER write_parameter;
+} T_VENDOR_WRITE_MSG;
+
+typedef union _TVENDOR_UPSTREAM_MSG_DATA
+{
+ uint8_t notification_indification_index;
+ T_VENDOR_WRITE_MSG write_msg;
+} TVENDOR_UPSTREAM_MSG_DATA;
+
+/** Vendor service data to inform application */
+typedef struct _T_VENDOR_CALLBACK_DATA
+{
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ TVENDOR_UPSTREAM_MSG_DATA msg_data;
+} T_VENDOR_CALLBACK_DATA;
+
+extern uint8_t vendor_svc_handshake_values[16];
+
+uint8_t vendor_svc_add_service(void *pFunc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/inc/bluetooth/profile/server/voice_service.h b/inc/bluetooth/profile/server/voice_service.h
new file mode 100644
index 0000000..88249d2
--- /dev/null
+++ b/inc/bluetooth/profile/server/voice_service.h
@@ -0,0 +1,155 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hids_rmc.h
+ * @brief Head file for using Voice Service.
+ * @details Voice service data structs and external functions declaration.
+ * @author Chenjie Jin
+ * @date 2019-6-27
+ * @version v1.1
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _VOICE_SERVICE_H_
+#define _VOICE_SERVICE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Add Includes here */
+#include "profile_server.h"
+#include "board.h"
+#include "app_msg.h"
+
+/** @defgroup Voice_Service Voice Service
+ * @brief Voice Service based on GATT
+ * @{
+ */
+
+/** @defgroup Voice_Service_Exported_Constants Voice Service Exported Constants
+ * @brief macros that other .c files may use all defined here
+ * @{
+ */
+
+///@cond
+/** @brief Voice_Service related UUIDs. */
+#define GATT_UUID_VOICE_CHAR_CTL 0x3A40
+#define GATT_UUID_VOICE_CHAR_DATA 0x3A41
+#define GATT_UUID_VOICE_CHAR_CMD 0x3A42
+
+///@endcond
+
+/** @defgroup Voice_Service_Attribute_Index Voice Service Attribute Index
+ * @brief Index defines for Characteristic's value in Voice_Service
+ * @{
+ */
+#define GATT_SRV_VOICE_CHAR_CTL_VALUE_INDEX 2
+#define GATT_SRV_VOICE_CHAR_DATA_VALUE_INDEX 4
+#define GATT_SRV_VOICE_CHAR_DATA_CCCD_INDEX 5
+#define GATT_SRV_VOICE_CHAR_CMD_VALUE_INDEX 7
+#define GATT_SRV_VOICE_CHAR_CMD_CCCD_INDEX 8
+
+/** @} */
+
+/** @defgroup Voice_Service_Upstream_Message Voice Service Upstream Message
+ * @brief Upstream message used to inform application.
+ * @{
+ */
+
+/** @defgroup Voice_Service_Read_Info Voice Service Read Info
+ * @brief Parameter for read characteristic value.
+ * @{
+ */
+#define VOICE_SVC_READ_PARAM_VOICE_DATA 1
+#define VOICE_SVC_READ_PARAM_VOICE_CMD 2
+/** @} */
+
+/** @defgroup Voice_Service_Write_Info Voice Service Write Info
+ * @brief Parameter for write characteristic value.
+ * @{
+ */
+#define VOICE_SVC_WRITE_CHAR_CTL_INDEX 1
+/** @} */
+
+/** @defgroup Voice_Service_Notify_Indicate_Info Voice Service Notify Indicate Info
+ * @brief Parameter for enable or disable notification or indication.
+ * @{
+ */
+#define VOICE_NOTIFY_DATA_ENABLE 1
+#define VOICE_NOTIFY_DATA_DISABLE 2
+#define VOICE_NOTIFY_CMD_ENABLE 3
+#define VOICE_NOTIFY_CMD_DISABLE 4
+/** @} */
+
+/** @} End of Voice_Service_Upstream_Message */
+
+/** @} End of Voice_Service_Exported_Constants */
+
+/** @defgroup Voice_Service_Exported_Types Voice Service Exported Types
+ * @brief types that other.c files may use all defined here
+ * @{
+ */
+
+/** Message content */
+typedef union
+{
+ struct
+ {
+ uint8_t len;
+ uint8_t *report;
+ } report_data;
+} T_VOICE_WRITE_PARAMETER;
+
+/** @struct T_VOICE_WRITE_MSG
+ * @brief write message
+ */
+typedef struct
+{
+ uint8_t write_type;
+ T_VOICE_WRITE_PARAMETER write_parameter;
+} T_VOICE_WRITE_MSG;
+
+/** @struct T_VOICE_UPSTREAM_MSG_DATA
+ * @brief upstream message
+ */
+typedef struct
+{
+ uint8_t notification_indification_index;
+ uint8_t read_value_index;
+ T_VOICE_WRITE_MSG write;
+} T_VOICE_UPSTREAM_MSG_DATA;
+
+/** @struct T_VOICE_CALLBACK_DATA
+ * @brief callback data
+ */
+typedef struct
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_VOICE_UPSTREAM_MSG_DATA msg_data;
+} T_VOICE_CALLBACK_DATA;
+
+
+/** @} End of Voice_Service_Exported_Types */
+
+
+
+/** @defgroup Voice_Service_Exported_Functions Voice Service Exported Functions
+ * @brief functions that other .c files may use all defined here.
+ * @{
+ */
+uint8_t voice_service_add_service(void *pfn);
+/** @} End of Voice_Service_Exported_Functions */
+
+/** @} End of Voice_Service */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _VOICE_SERVICE_H_ */
diff --git a/inc/bluetooth/profile/server/wss.h b/inc/bluetooth/profile/server/wss.h
new file mode 100644
index 0000000..fa2f853
--- /dev/null
+++ b/inc/bluetooth/profile/server/wss.h
@@ -0,0 +1,303 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file wss.h
+ * @brief Head file for using weight scale service.
+ * @details Weight scale data types and external functions declaration.
+ * @author Vera
+ * @date
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _WSS_H_
+#define _WSS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Add Includes here */
+#include "stdint.h"
+#include "profile_server.h"
+
+
+
+/** @defgroup WSS Weight Scale Service
+ * @brief Weight Scale Service
+ * @details
+
+ The Weight Scale (WS) Service exposes weight and related data from a weight scale (Server) intended for
+ consumer healthcare as well as sports/fitness applications.
+
+ Weight Scale Feature and Weight Measurement are exposed in the Weight Scale Service.
+ Only one instance of each characteristic is permitted within this service.
+ The Weight Scale Feature characteristic shall be used to describe the supported features of the Server.
+ When read, the Weight Scale Feature characteristic return a value that is used by a Client to determine
+ the supported features of the Server.
+ The Weight Measurement characteristic is used to send weight-related data to the Client.
+ Included in the characteristic value are a Flags field (for showing the presence of optional fields and
+ measurement units), a Weight field, and depending upon the contents of the Flags field, may include one or more optional fields.
+
+ Application shall register weight scale service when initialization through @ref wss_add_service function.
+
+ Application can set the weight scale service parameters through @ref wss_set_parameter function.
+
+ Application can send the weight-related data of WSS to the client through @ref wss_measurement_indicate function.
+
+ * @{
+ */
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup WSS_Exported_Macros WSS Exported Macros
+ * @brief
+ * @{
+ */
+
+/**
+* @brief Weight scale service parameter type
+*/
+typedef enum
+{
+ WSS_PARAM_MEASUREMENT_WEIGHTPARAM_FLAG = 0x01,
+ WSS_PARAM_MEASUREMENT_WEIGHT_VALUE,
+ WSS_PARAM_MEASUREMENT_TIME_STAMP,
+ WSS_PARAM_MEASUREMENT_USERID,
+ WSS_PARAM_MEASUREMENT_BMI,
+ WSS_PARAM_MEASUREMENT_HEIGHT_VALUE,
+ WSS_PARAM_FEATURE_READ_CHAR_VAL,
+} T_WSS_PARAM_TYPE;
+
+
+/** @defgroup WSS_Measurement_Flag WSS Measurement Flag
+ * @{
+ */
+#define WSS_FLAG_MEASUREMENT_UINT_BIT BIT0
+#define WSS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT BIT1
+#define WSS_FLAG_MEASUREMENT_USERID_PRESENT_BIT BIT2
+#define WSS_FLAG_MEASUREMENT_BMI_PRESENT_BIT BIT3
+
+/** @} */
+
+
+
+/** @defgroup WSS_Service_Read_Info WSS Service Read Info
+ * @brief Parameter for reading characteristic value.
+ * @{
+ */
+#define WEIGHT_SCALE_READ_FEATURE 1
+/** @} End of WSS_Service_Read_Info*/
+
+
+
+/** @defgroup WSS_Service_Notify_Indicate_Info WSS Service Notify Indicate Info
+ * @brief Parameter for enable or disable notification or indication.
+ * @{
+ */
+#define WSS_INDICATE_WEIGHT_MEASUREMENT_ENABLE 1
+#define WSS_INDICATE_WEIGHT_MEASUREMENT_DISABLE 2
+/** @} */
+
+/** @} End of WSS_Exported_Macros */
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/** @defgroup WSS_Service_Exported_Types WSS Service Exported Types
+ * @brief
+ * @{
+ */
+
+/** @defgroup T_WSS_UPSTREAM_MSG_DATA TWS UPSTREAM MSG DATA
+ * @brief Weight scale service callback message content.
+ * @{
+ */
+typedef union
+{
+ uint8_t notification_indication_index; //!< ref: @ref WSS_Service_Notify_Indicate_Info
+ uint8_t read_value_index; //!< ref: @ref WSS_Service_Read_Info
+} T_WSS_UPSTREAM_MSG_DATA;
+/** @} End of T_WSS_UPSTREAM_MSG_DATA */
+
+/** @defgroup T_WSS_CALLBACK_DATA TWS CALLBACK DATA
+ * @brief Weight scale service data to inform application.
+ * @{
+ */
+typedef struct
+{
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_WSS_UPSTREAM_MSG_DATA msg_data;
+} T_WSS_CALLBACK_DATA;
+/** @} End of T_WSS_CALLBACK_DATA */
+
+
+/** @defgroup T_WEIGHT_SCALE_FEATURE_VALUE WEIGHT SCALE FEATURE VALUE
+ * @brief Weight Scale Feature Value.
+ * @{
+ */
+typedef struct
+{
+ uint32_t time_stamp_supported: 1;
+ uint32_t multiple_users_supported: 1;
+ uint32_t bmi_supported: 1;
+ uint32_t weight_measurement_resolution: 4;
+ uint32_t height_measurement_resolution: 3;
+ uint32_t rfu: 22;
+} T_WEIGHT_SCALE_FEATURE_VALUE;
+/** @} End of T_WEIGHT_SCALE_FEATURE_VALUE */
+
+/** @defgroup T_WEIGHT_MEASUREMENT_VALUE_FLAG WEIGHT MEASUREMENT VALUE FLAG
+ * @brief Weight Measurement Value Flag.
+ * @{
+ */
+typedef struct
+{
+ uint8_t measurement_units: 1;
+ uint8_t time_stamp_present: 1;
+ uint8_t user_id_present: 1;
+ uint8_t bmi_and_height_present: 1;
+ uint8_t rfu: 4;
+} T_WEIGHT_MEASUREMENT_VALUE_FLAG;
+/** @} End of T_WEIGHT_MEASUREMENT_VALUE_FLAG */
+
+/** @defgroup T_WSS_TIME_STAMP WSS TIME STAMP
+ * @brief Weight Scale Feature Time Stamp.
+ * @{
+ */
+typedef struct
+{
+ uint16_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t hours;
+ uint8_t minutes;
+ uint8_t seconds;
+} T_WSS_TIME_STAMP;
+/** @} End of T_WSS_TIME_STAMP */
+
+/** @defgroup T_WSS_MEASUREMENT WSS MEASUREMENT
+ * @brief Weight Measurement Value.
+ * @{
+ */
+typedef struct
+{
+ T_WEIGHT_MEASUREMENT_VALUE_FLAG flag;
+ uint16_t weight_si_value;
+ uint16_t weight_imperial_value;
+ T_WSS_TIME_STAMP time_stamp;
+ uint8_t user_id;
+ uint16_t bmi;
+ uint16_t height_si_value;
+ uint16_t height_imperial_value;
+} T_WSS_MEASUREMENT;
+/** @} End of T_WSS_MEASUREMENT */
+
+/** @} End of WSS_Service_Exported_Types */
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/** @defgroup WSS_Service_Exported_Functions WSS Service Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Add Weight scale service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ wss_id = wss_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID wss_add_service(void *p_func);
+
+/**
+ * @brief Set a weight scale service parameter.
+ *
+ * NOTE: You can call this function with a weight scale service parameter type and it will set the
+ * weight scale service parameter. Weight scale service parameters are defined in @ref T_WSS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Weight scale service parameter type: @ref T_WSS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint32_t weight_feature = 0x0000001f;
+ wss_set_parameter(WSS_PARAM_FEATURE_READ_CHAR_VAL, 4, &weight_feature);
+ }
+ * \endcode
+ */
+bool wss_set_parameter(T_WSS_PARAM_TYPE param_type, uint8_t len, void *p_value);
+
+
+/**
+ * @brief Send measurement indication data.
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t wm_flag = WSS_FLAG_MEASUREMENT_UINT_BIT
+ | WSS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT
+ | WSS_FLAG_MEASUREMENT_USERID_PRESENT_BIT
+ | WSS_FLAG_MEASUREMENT_BMI_PRESENT_BIT;
+
+ wss_set_parameter(WSS_PARAM_MEASUREMENT_WEIGHTPARAM_FLAG, sizeof(wm_flag), &wm_flag);
+ wss_set_parameter(WSS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(wss_measure_time_stamp),
+ &wss_measure_time_stamp);
+ wss_measurement_indicate(p_parse_value->dw_param[0], wss_id);
+ }
+ * \endcode
+ */
+bool wss_measurement_indicate(uint8_t conn_id, T_SERVER_ID service_id);
+/** @} End of WSS_Service_Exported_Functions */
+
+/** @} End of WSS */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WSS_H_ */
diff --git a/inc/os/os_mem.h b/inc/os/os_mem.h
new file mode 100644
index 0000000..763c8da
--- /dev/null
+++ b/inc/os/os_mem.h
@@ -0,0 +1,281 @@
+/**
+ * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved.
+ */
+
+#ifndef _OS_MEM_H_
+#define _OS_MEM_H_
+
+#include <stdint.h>
+#include <stddef.h>
+#include <mem_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup OS OSIF APIs
+ * \defgroup Memory Memory Management
+ *
+ * \brief Allocate, free, and peek memory functions.
+ * \details The Memory Management function group allows to allocate, free, and peek heap
+ * memory in the system.\n
+ *
+ * \ingroup OS
+ */
+
+
+void *os_mem_alloc_intern(RAM_TYPE ram_type, size_t size,
+ const char *p_func, uint32_t file_line);
+
+void *os_mem_zalloc_intern(RAM_TYPE ram_type, size_t size,
+ const char *p_func, uint32_t file_line);
+
+void *os_mem_aligned_alloc_intern(RAM_TYPE ram_type, size_t size, uint8_t alignment,
+ const char *p_func, uint32_t file_line);
+
+/**
+ * os_mem.h
+ *
+ * \brief Allocate a memory block with required size.
+ *
+ * \param[in] ram_type RAM type for allocation.
+ * \arg \c RAM_TYPE_DATA_ON Data ON RAM type.
+ * \arg \c RAM_TYPE_BUFFER_ON BUFFER ON RAM type.
+ *
+ * \param[in] size Required memory size.
+ *
+ * \return The address of the allocated memory block. If the address is NULL, the
+ * memory allocation failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * size_t mem_size = 0x1000;
+ * void *p_mem = NULL;
+ *
+ * p_mem = os_mem_alloc(RAM_TYPE_DATA_ON, mem_size);
+ * if (p_mem != NULL)
+ * {
+ * // Memory allocation succeeded, and free it.
+ * os_mem_free(p_mem);
+ * }
+ * else
+ * {
+ * // Memory allocation failed.
+ * return -1;
+ * }
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Memory
+ */
+#define os_mem_alloc(ram_type, size) \
+ os_mem_alloc_intern(ram_type, size, __func__, __LINE__)
+
+/**
+ * os_mem.h
+ *
+ * \brief Allocate and clear a memory block with required size.
+ *
+ * \param[in] ram_type RAM type for allocation.
+ * \arg \c RAM_TYPE_DATA_ON Data ON RAM type.
+ * \arg \c RAM_TYPE_BUFFER_ON BUFFER ON RAM type.
+ *
+ * \param[in] size Required memory size.
+ *
+ * \return The address of the allocated memory block. If the address is NULL, the
+ * memory allocation failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * size_t mem_size = 0x1000;
+ * void *p_mem = NULL;
+ *
+ * p_mem = os_mem_zalloc(RAM_TYPE_DATA_ON, mem_size);
+ * if (p_mem != NULL)
+ * {
+ * // Memory allocation succeeded, and free it.
+ * os_mem_free(p_mem);
+ * }
+ * else
+ * {
+ * // Memory allocation failed.
+ * return -1;
+ * }
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Memory
+ */
+#define os_mem_zalloc(ram_type, size) \
+ os_mem_zalloc_intern(ram_type, size, __func__, __LINE__)
+
+/**
+ * os_mem.h
+ *
+ * \brief Allocate an aligned memory block with required size.
+ *
+ * \param[in] ram_type RAM type for allocation.
+ * \arg \c RAM_TYPE_DATA_ON Data ON RAM type.
+ * \arg \c RAM_TYPE_BUFFER_ON BUFFER ON RAM type.
+ *
+ * \param[in] size Required memory size.
+ *
+ * \param[in] alignment memory alignment in 2^N bytes. If alignment is 0, use
+ * system default memory alignment. The aligned memory block
+ * must use os_mem_aligned_free() API function to free.
+ *
+ * \return The address of the allocated memory block. If the address is NULL, the
+ * memory allocation failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * size_t mem_size = 0x1000;
+ * uint8_t mem_alignment = 16;
+ * void *p_mem = NULL;
+ *
+ * p_mem = os_mem_aligned_alloc(RAM_TYPE_DATA_ON, mem_size, mem_alignment);
+ * if (p_mem != NULL)
+ * {
+ * // Aligned memory allocation succeeded, and free it.
+ * os_mem_aligned_free(p_mem);
+ * }
+ * else
+ * {
+ * // Aligned memory allocation failed.
+ * return -1;
+ * }
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Memory
+ */
+#define os_mem_aligned_alloc(ram_type, size, alignment) \
+ os_mem_aligned_alloc_intern(ram_type, size, alignment, __func__, __LINE__)
+
+/**
+ * os_mem.h
+ *
+ * \brief Free a memory block that had been allocated.
+ *
+ * \param[in] p_block The address of memory block being freed.
+ *
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * size_t mem_size = 0x1000;
+ * void *p_mem = NULL;
+ *
+ * p_mem = os_mem_alloc(RAM_TYPE_DATA_ON, mem_size);
+ * if (p_mem != NULL)
+ * {
+ * // Memory allocation succeeded, and free it.
+ * os_mem_free(p_mem);
+ * }
+ * else
+ * {
+ * // Memory allocation failed.
+ * return -1;
+ * }
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Memory
+ */
+void os_mem_free(void *p_block);
+
+/**
+ * os_mem.h
+ *
+ * \brief Free an aligned memory block that had been allocated.
+ *
+ * \param[in] p_block The address of memory block being freed.
+ *
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * size_t mem_size = 0x1000;
+ * uint8_t mem_alignment = 16;
+ * void *p_mem = NULL;
+ *
+ * p_mem = os_mem_aligned_alloc(RAM_TYPE_DATA_ON, mem_size, mem_alignment);
+ * if (p_mem != NULL)
+ * {
+ * // Aligned memory allocation succeeded, and free it.
+ * os_mem_aligned_free(p_mem);
+ * }
+ * else
+ * {
+ * // Aligned memory allocation failed.
+ * return -1;
+ * }
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Memory
+ */
+void os_mem_aligned_free(void *p_block);
+
+/**
+ * os_mem.h
+ *
+ * \brief Peek the unused memory size of the specified RAM type.
+ *
+ * \param[in] ram_type RAM type for allocation.
+ * \arg \c RAM_TYPE_DATA_ON Data ON RAM type.
+ * \arg \c RAM_TYPE_BUFFER_ON BUFFER ON RAM type.
+ *
+ * \return The unused memory size in btyes.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * size_t unused_data_on;
+ * size_t unused_data_off;
+ *
+ * // Peek unused DATA ON memory size.
+ * unused_size = os_mem_peek(RAM_TYPE_DATA_ON);
+ *
+ * // Peek unused buffer on memory size.
+ * unused_size = os_mem_peek(RAM_TYPE_BUFFER_ON);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Memory
+ */
+size_t os_mem_peek(RAM_TYPE ram_type);
+
+/* internal functions */
+void os_mem_check_heap_usage(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OS_MEM_H_ */
diff --git a/inc/os/os_msg.h b/inc/os/os_msg.h
new file mode 100644
index 0000000..5547014
--- /dev/null
+++ b/inc/os/os_msg.h
@@ -0,0 +1,432 @@
+/**
+ * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved.
+ */
+
+#ifndef _OS_MSG_H_
+#define _OS_MSG_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup OS OSIF APIs
+ * \defgroup Message Message Queue
+ *
+ * \brief Exchange messages between tasks in a FIFO-like operation.
+ * \details The Message Queue function group allows to control, send, receive, or wait for message.
+ * Message transmission is a basic communication model between tasks that one task sends
+ * data explicitly, while another task receives it. The operation is more like some
+ * kind of I/O rather than a direct access to information to be shared. The data to be
+ * passed can be any type.\n
+ *
+ * \image html OS-message-queue-overview.jpg "Message Queue Overview" width=617px height=321px
+ *
+ * \ingroup OS
+ */
+
+
+bool os_msg_queue_create_intern(void **pp_handle, uint32_t msg_num, uint32_t msg_size,
+ const char *p_func, uint32_t file_line);
+
+bool os_msg_queue_delete_intern(void *p_handle, const char *p_func, uint32_t file_line);
+
+bool os_msg_queue_peek_intern(void *p_handle, uint32_t *p_msg_num,
+ const char *p_func, uint32_t file_line);
+
+bool os_msg_send_intern(void *p_handle, void *p_msg, uint32_t wait_ms,
+ const char *p_func, uint32_t file_line);
+
+bool os_msg_recv_intern(void *p_handle, void *p_msg, uint32_t wait_ms,
+ const char *p_func, uint32_t file_line);
+
+bool os_msg_peek_intern(void *p_handle, void *p_msg, uint32_t wait_ms,
+ const char *p_func, uint32_t file_line);
+
+/**
+ * os_msg.h
+ *
+ * \brief Creates a message queue instance. This allocates the storage required by the
+ * new queue and passes back a handle for the queue.
+ *
+ * \param[out] pp_handle Used to pass back a handle by which the message queue
+ * can be referenced.
+ *
+ * \param[in] msg_num The maximum number of items that the queue can contain.
+ *
+ * \param[in] msg_size The number of bytes each item in the queue will require. Items
+ * are queued by copy, not by reference, so this is the number of
+ * bytes that will be copied for each posted item. Each item on the
+ * queue must be the same size.
+ *
+ * \return The status of the message queue creation.
+ * \retval true Message queue was created successfully.
+ * \retval false Message queue was failed to create.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * struct test_msg
+ * {
+ * uint8_t id;
+ * uint8_t data[16];
+ * }
+ *
+ * #define MSG_NUM 10
+ *
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ *
+ * // Create a queue capable of containing 10 items of structure test_msg.
+ * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true)
+ * {
+ * // Message queue created successfully.
+ * }
+ * else
+ * {
+ * // Message queue failed to create.
+ * return -1;
+ * }
+ *
+ * // Delete the message queue.
+ * os_msg_queue_delete(p_handle);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Message
+ */
+#define os_msg_queue_create(pp_handle, msg_num, msg_size) \
+ os_msg_queue_create_intern(pp_handle, msg_num, msg_size, __func__, __LINE__)
+
+/**
+ * os_msg.h
+ *
+ * \brief Delete the specified message queue, and free all the memory allocated for
+ * storing of items placed on the queue.
+ *
+ * \param[in] p_handle The handle to the message queue being deleted.
+ *
+ * \return The status of the message queue deletion.
+ * \retval true Message queue was deleted successfully.
+ * \retval false Message queue was failed to delete.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * struct test_msg
+ * {
+ * uint8_t id;
+ * uint8_t data[16];
+ * }
+ *
+ * #define MSG_NUM 10
+ *
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ *
+ * // Create a queue capable of containing 10 items of structure test_msg.
+ * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true)
+ * {
+ * // Message queue created successfully.
+ * }
+ * else
+ * {
+ * // Message queue failed to create.
+ * return -1;
+ * }
+ *
+ * // Delete the message queue.
+ * os_msg_queue_delete(p_handle);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Message
+ */
+#define os_msg_queue_delete(p_handle) \
+ os_msg_queue_delete_intern(p_handle, __func__, __LINE__)
+
+/**
+ * os_msg.h
+ *
+ * \brief Peek the number of items sent and resided on the message queue.
+ *
+ * \param[in] p_handle The handle to the message queue being peeked.
+ *
+ * \param[out] p_msg_num Used to pass back the number of items residing on the message queue.
+ *
+ * \return The status of the message queue peek.
+ * \retval true Message queue was peeked successfully.
+ * \retval false Message queue was failed to peek.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * struct test_msg
+ * {
+ * uint8_t id;
+ * uint8_t data[16];
+ * }
+ *
+ * #define MSG_NUM 10
+ *
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ * uint32_t msg_num;
+ *
+ * // Create a queue capable of containing 10 items of structure test_msg.
+ * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true)
+ * {
+ * // Message queue created successfully.
+ * }
+ * else
+ * {
+ * // Message queue failed to create.
+ * return -1;
+ * }
+ *
+ * // Peek the number of items sent on this message queue.
+ * os_msg_queue_peek(p_handle, &msg_num);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Message
+ */
+#define os_msg_queue_peek(p_handle, p_msg_num) \
+ os_msg_queue_peek_intern(p_handle, p_msg_num, __func__, __LINE__)
+
+/**
+ * os_msg.h
+ *
+ * \brief Send an item to the back of the specified message queue. The item is
+ * queued by copy, not by reference.
+ *
+ * \param[in] p_handle The handle to the message queue on which the item is to be sent.
+ *
+ * \param[in] p_msg Pointer to the item that is to be sent on the queue. The referenced
+ * item rather than pointer itself will be copied on the queue.
+ *
+ * \param[in] wait_ms The maximum amount of time in milliseconds that the task should
+ * block waiting for the item to sent on the queue.
+ * \arg \c 0 No blocking and return immediately.
+ * \arg \c 0xFFFFFFFF Block infinitely until the item sent.
+ * \arg \c others The timeout value in milliseconds.
+ *
+ * \return The status of the message item sent.
+ * \retval true Message item was sent successfully.
+ * \retval false Message item was failed to send.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * struct test_msg
+ * {
+ * uint8_t id;
+ * uint8_t data[16];
+ * }
+ *
+ * #define MSG_NUM 10
+ *
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ * struct test_msg msg;
+ *
+ * // Create a queue capable of containing 10 items of structure test_msg.
+ * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true)
+ * {
+ * // Message queue created successfully.
+ * }
+ * else
+ * {
+ * // Message queue failed to create.
+ * return -1;
+ * }
+ *
+ * // Send the item to this message queue.
+ * msg.id = 1;
+ * msg.data[0] = 0;
+ * os_msg_send(p_handle, &msg, 0);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Message
+ */
+#define os_msg_send(p_handle, p_msg, wait_ms) \
+ os_msg_send_intern(p_handle, p_msg, wait_ms, __func__, __LINE__)
+
+/**
+ * os_msg.h
+ *
+ * \brief Receive an item from the specified message queue. The item is received by
+ * copy rather than by reference, so a buffer of adequate size must be provided.
+ *
+ * \param[in] p_handle The handle to the message queue from which the item is to be received.
+ *
+ * \param[out] p_msg Pointer to the buffer into which the received item will be copied.
+ * item rather than pointer itself will be copied on the queue.
+ *
+ * \param[in] wait_ms The maximum amount of time in milliseconds that the task should
+ * block waiting for an item to be received from the queue.
+ * \arg \c 0 No blocking and return immediately.
+ * \arg \c 0xFFFFFFFF Block infinitely until the item received.
+ * \arg \c others The timeout value in milliseconds.
+ *
+ * \return The status of the message item received.
+ * \retval true Message item was received successfully.
+ * \retval false Message item was failed to receive.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * struct test_msg
+ * {
+ * uint8_t id;
+ * uint8_t data[16];
+ * }
+ *
+ * #define MSG_NUM 10
+ *
+ * void *p_handle = NULL;
+ *
+ * void send_msg(void)
+ * {
+ * struct test_msg msg;
+ *
+ * // Create a queue capable of containing 10 items of structure test_msg.
+ * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true)
+ * {
+ * // Message queue created successfully.
+ * }
+ * else
+ * {
+ * // Message queue failed to create.
+ * return -1;
+ * }
+ *
+ * // Send the item to this message queue.
+ * msg.id = 1;
+ * msg.data[0] = 0;
+ * os_msg_send(p_handle, &msg, 0);
+ *
+ * return 0;
+ * }
+ *
+ * void receive_msg(void)
+ * {
+ * struct test_msg msg;
+ *
+ * // Receive the message queue item.
+ * if (os_msg_recv(p_handle, &msg, 0) == true)
+ * {
+ * // Message item received successfully.
+ * }
+ * else
+ * {
+ * // Message item failed to receive.
+ * return -1;
+ * }
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Message
+ */
+#define os_msg_recv(p_handle, p_msg, wait_ms) \
+ os_msg_recv_intern(p_handle, p_msg, wait_ms, __func__, __LINE__)
+
+/**
+ * os_msg.h
+ *
+ * \brief Receive but not remove an item from the specified message queue. The item is
+ * received by copy rather than by reference, so a buffer of adequate size must
+ * be provided.
+ *
+ * \param[in] p_handle The handle to the message queue on which the item is to be peeked.
+ *
+ * \param[out] p_msg Pointer to the buffer into which the received item will be copied.
+ * item rather than pointer itself will be copied on the queue.
+ *
+ * \param[in] wait_ms The maximum amount of time in milliseconds that the task should
+ * block waiting for an item to be received from the queue.
+ * \arg \c 0 No blocking and return immediately.
+ * \arg \c 0xFFFFFFFF Block infinitely until the item received.
+ * \arg \c others The timeout value in milliseconds.
+ *
+ * \return The status of the message item received.
+ * \retval true Message item was received successfully.
+ * \retval false Message item was failed to receive.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * struct test_msg
+ * {
+ * uint8_t id;
+ * uint8_t data[16];
+ * }
+ *
+ * #define MSG_NUM 10
+ *
+ * void *p_handle = NULL;
+ *
+ * void send_msg(void)
+ * {
+ * struct test_msg msg;
+ *
+ * // Create a queue capable of containing 10 items of structure test_msg.
+ * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true)
+ * {
+ * // Message queue created successfully.
+ * }
+ * else
+ * {
+ * // Message queue failed to create.
+ * return -1;
+ * }
+ *
+ * // Send the item to this message queue.
+ * msg.id = 1;
+ * msg.data[0] = 0;
+ * os_msg_send(p_handle, &msg, 0);
+ *
+ * return 0;
+ * }
+ *
+ * void peek_msg(void)
+ * {
+ * struct test_msg msg;
+ *
+ * // Peek the message queue item.
+ * if (os_msg_peek(p_handle, &msg, 0) == true)
+ * {
+ * // Message item peeked successfully.
+ * }
+ * else
+ * {
+ * // Message item failed to peek.
+ * return -1;
+ * }
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Message
+ */
+#define os_msg_peek(p_handle, p_msg, wait_ms) \
+ os_msg_peek_intern(p_handle, p_msg, wait_ms, __func__, __LINE__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OS_MSG_H_ */
diff --git a/inc/os/os_pool.h b/inc/os/os_pool.h
new file mode 100644
index 0000000..fcb8424
--- /dev/null
+++ b/inc/os/os_pool.h
@@ -0,0 +1,362 @@
+/**
+ * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved.
+ */
+
+#ifndef _OS_POOL_H_
+#define _OS_POOL_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <mem_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup OS OSIF APIs
+ * \defgroup Pool Pool Management
+ *
+ * \brief Manage task-safe and fixed-size blocks of dynamic memory.
+ * \details Memory pools are fixed-size blocks of memory that are task-safe. They operate much
+ * faster than the dynamically allocated heap and do not suffer from fragmentation.
+ * Being task-safe, they can be accessed from tasks and ISRs alike.\n
+ * Shared memory is one of the basic models to exchange information between tasks.
+ * Using memory pools for exchanging data, you can share more complex objects between
+ * taks if compared to the Message Queue. Memory pool management functions are used to
+ * define and manage such fixed-sized memory pools.\n
+ *
+ * \image html OS-pool-overview.jpg "Memory Pool Overview" width=601px height=481px
+ *
+ * \ingroup OS
+ */
+
+
+/**
+ * os_pool.h
+ *
+ * \brief The invalid pool handle. Valid pool handles should be less than OS_POOL_INVALID_HANDLE.
+ *
+ * \ingroup Pool
+ */
+#define OS_POOL_INVALID_HANDLE 0xFF
+
+bool os_pool_create_intern(uint8_t *p_handle, RAM_TYPE ram_type, uint16_t buf_size,
+ uint16_t buf_count, const char *p_func, uint32_t file_line);
+
+bool os_pool_extend_intern(uint8_t handle, uint16_t buf_size, uint16_t buf_count,
+ const char *p_func, uint32_t file_line);
+
+bool os_pool_delete_intern(uint8_t handle, const char *p_func, uint32_t file_line);
+
+void *os_buffer_get_intern(uint8_t handle, uint16_t buf_size,
+ const char *p_func, uint32_t file_line);
+
+bool os_buffer_put_intern(void *p_buf, const char *p_func, uint32_t file_line);
+
+/**
+ * os_pool.h
+ *
+ * \brief Creates and initialize a memory pool.
+ *
+ * \param[out] p_handle Used to pass back a handle by which the memory pool
+ * can be referenced.
+ *
+ * \param[in] ram_type RAM type for the memory pool buffer.
+ * \arg \c RAM_TYPE_DATA_ON Data ON RAM type.
+ * \arg \c RAM_TYPE_DATA_OFF Data OFF RAM type.
+ * \arg \c RAM_TYPE_BUFFER_ON BUFFER ON RAM type.
+ * \arg \c RAM_TYPE_BUFFER_OFF BUFFER OFF RAM type.
+ *
+ * \param[in] buf_size The pool buffer size in bytes.
+ *
+ * \param[in] buf_count The number of pool buffers allocated.
+ *
+ * \return The status of the memory pool creation.
+ * \retval true Pool was created successfully.
+ * \retval false Pool was failed to create.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * #define BUF_SIZE 0x40
+ * #define BUF_NUM 16
+ *
+ * int test(void)
+ * {
+ * uint8_t handle;
+ *
+ * // Create a memory pool capable of containing 16 buffers.
+ * if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE, BUF_NUM) == true)
+ * {
+ * // Memory pool created successfully.
+ * }
+ * else
+ * {
+ * // Memory pool failed to create.
+ * return -1;
+ * }
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Pool
+ */
+#define os_pool_create(p_handle, ram_type, buf_size, buf_count) \
+ os_pool_create_intern(p_handle, ram_type, buf_size, buf_count, __func__, __LINE__)
+
+/**
+ * os_pool.h
+ *
+ * \brief Extend a set of buffers to the created memory pool. The extended pool
+ * buffers have the same RAM type with the created buffers.
+ *
+ * \param[in] handle The handle of the created memory pool.
+ *
+ * \param[in] buf_size The pool buffer size in bytes.
+ *
+ * \param[in] buf_count The number of pool buffers allocated.
+ *
+ * \return The status of the memory pool extension.
+ * \retval true Pool was extended successfully.
+ * \retval false Pool was failed to extend.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * #define BUF_SIZE1 0x40
+ * #define BUF_NUM1 16
+ * #define BUF_SIZE2 0x20
+ * #define BUF_NUM2 8
+ *
+ * int test(void)
+ * {
+ * uint8_t handle;
+ *
+ * // Create a memory pool capable of containing 16 buffers.
+ * if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE1, BUF_NUM1) == true)
+ * {
+ * // Memory pool created successfully.
+ * }
+ * else
+ * {
+ * // Memory pool failed to create.
+ * return -1;
+ * }
+ *
+ * // Extend the memory pool to have extra 8 buffers each in 0x20 bytes.
+ * os_pool_extend(handle, BUF_SIZE2, BUF_NUM2);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Pool
+ */
+#define os_pool_extend(handle, buf_size, buf_count) \
+ os_pool_extend_intern(handle, buf_size, buf_count, __func__, __LINE__)
+
+/**
+ * os_pool.h
+ *
+ * \brief Delete a memory pool.
+ *
+ * \param[in] handle The handle of the memory pool to be deleted.
+ *
+ * \return The status of the memory pool deletion.
+ * \retval true Pool was deleted successfully.
+ * \retval false Pool was failed to delete.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * #define BUF_SIZE 0x40
+ * #define BUF_NUM 16
+ *
+ * int test(void)
+ * {
+ * uint8_t handle;
+ *
+ * // Create a memory pool capable of containing 16 buffers.
+ * if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE, BUF_NUM) == true)
+ * {
+ * // Memory pool created successfully.
+ * }
+ * else
+ * {
+ * // Memory pool failed to create.
+ * return -1;
+ * }
+ *
+ * // Delete the memory pool.
+ * os_pool_delete(handle);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Pool
+ */
+#define os_pool_delete(handle) os_pool_delete_intern(handle, __func__, __LINE__)
+
+/**
+ * os_pool.h
+ *
+ * \brief Allocate a pool buffer from the specified memory pool. The allocated pool
+ * buffer size may be larger than the required size.
+ *
+ * \param[in] handle The handle of the created memory pool.
+ *
+ * \param[in] buf_size The pool buffer size in bytes.
+ *
+ * \return The address of the allocated pool buffer. If the address is NULL,
+ * the buffer allocation failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * #define BUF_SIZE1 0x40
+ * #define BUF_NUM1 16
+ * #define BUF_SIZE2 0x20
+ * #define BUF_NUM2 8
+ *
+ * int test(void)
+ * {
+ * uint8_t handle;
+ * void *p_buf;
+ *
+ * // Create a memory pool capable of containing 16 buffers.
+ * if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE1, BUF_NUM1) == true)
+ * {
+ * // Memory pool created successfully.
+ * }
+ * else
+ * {
+ * // Memory pool failed to create.
+ * return -1;
+ * }
+ *
+ * // Extend the memory pool to have extra 8 buffers each in 0x20 bytes.
+ * os_pool_extend(handle, BUF_SIZE2, BUF_NUM2);
+ *
+ * // Allocate a pool buffer in 0x30 bytes. While, the memory pool will
+ * // give a buffer in 0x40 bytes.
+ * p_buf = os_buffer_get(handle, 0x30);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Pool
+ */
+#define os_buffer_get(handle, buf_size) \
+ os_buffer_get_intern(handle, buf_size, __func__, __LINE__)
+
+/**
+ * os_pool.h
+ *
+ * \brief Free and return the pool buffer to the specified memory pool.
+ *
+ * \param[in] p_buf The address of the pool buffer allocated by os_buffer_get()
+ * API function.
+ *
+ * \return The status of the pool buffer freeing.
+ * \retval true Pool was freed successfully.
+ * \retval false Pool was failed to free.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * #define BUF_SIZE1 0x40
+ * #define BUF_NUM1 16
+ * #define BUF_SIZE2 0x20
+ * #define BUF_NUM2 8
+ *
+ * int test(void)
+ * {
+ * uint8_t handle;
+ * void *p_buf;
+ *
+ * // Create a memory pool capable of containing 16 buffers.
+ * if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE1, BUF_NUM1) == true)
+ * {
+ * // Memory pool created successfully.
+ * }
+ * else
+ * {
+ * // Memory pool failed to create.
+ * return -1;
+ * }
+ *
+ * // Extend the memory pool to have extra 8 buffers each in 0x20 bytes.
+ * os_pool_extend(handle, BUF_SIZE2, BUF_NUM2);
+ *
+ * // Allocate a pool buffer in 0x30 bytes. While, the memory pool will
+ * // give a buffer in 0x40 bytes.
+ * p_buf = os_buffer_get(handle, 0x30);
+ *
+ * // Free the pool buffer by the address.
+ * os_buffer_put(p_buf);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Pool
+ */
+#define os_buffer_put(p_buf) \
+ os_buffer_put_intern(p_buf, __func__, __LINE__)
+
+/**
+ * os_pool.h
+ *
+ * \brief Dump the pool buffers of the specified memory pool.
+ *
+ * \param[in] handle The handle of the memory pool buffer to be dumped. If the
+ * memory pool handle is invalid, all created memory pools
+ * will be dumped.
+ *
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * #define BUF_SIZE1 0x40
+ * #define BUF_NUM1 16
+ * #define BUF_SIZE2 0x20
+ * #define BUF_NUM2 8
+ *
+ * int test(void)
+ * {
+ * uint8_t handle;
+ * void *p_buf;
+ *
+ * // Create a memory pool capable of containing 16 buffers.
+ * if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE1, BUF_NUM1) == true)
+ * {
+ * // Memory pool created successfully.
+ * }
+ * else
+ * {
+ * // Memory pool failed to create.
+ * return -1;
+ * }
+ *
+ * // Extend the memory pool to have extra 8 buffers each in 0x20 bytes.
+ * os_pool_extend(handle, BUF_SIZE2, BUF_NUM2);
+ *
+ * // Allocate a pool buffer in 0x30 bytes. While, the memory pool will
+ * // give a buffer in 0x40 bytes.
+ * p_buf = os_buffer_get(handle, 0x30);
+ *
+ * // Dump the memory pool.
+ * os_pool_dump(handle);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Pool
+ */
+void os_pool_dump(uint8_t handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OS_POOL_H_ */
diff --git a/inc/os/os_queue.h b/inc/os/os_queue.h
new file mode 100644
index 0000000..f6547a1
--- /dev/null
+++ b/inc/os/os_queue.h
@@ -0,0 +1,311 @@
+/**
+ * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved.
+ */
+
+#ifndef _OS_QUEUE_H_
+#define _OS_QUEUE_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup OS OSIF APIs
+ * \defgroup Queue List Queue
+ *
+ * \brief Initialize and manage List Queue functions.
+ * \details List Queue is designed as a FIFO-like list, which can enqueue, dequeue and peek
+ * the list. While, List Queue also keeps these functionalities such as deleting
+ * and inserting the speicified list item.\n
+ *
+ * \image html OS-queue-overview.jpg "List Queue Overview" width=466px height=256px
+ *
+ * \ingroup OS
+ */
+
+
+/**
+ * os_queue.h
+ *
+ * \brief The element structure of List Queue.
+ *
+ * \ingroup Queue
+ */
+typedef struct t_os_queue_elem
+{
+ struct t_os_queue_elem *p_next; /**< Pointer to next list queue element. */
+} T_OS_QUEUE_ELEM;
+
+/**
+ * os_queue.h
+ *
+ * \brief The header structure of List Queue.
+ *
+ * \ingroup Queue
+ */
+typedef struct t_os_queue
+{
+ T_OS_QUEUE_ELEM *p_first; /**< Pointer to the first queue element. */
+ T_OS_QUEUE_ELEM *p_last; /**< Pointer to the last queue element. */
+ uint16_t count; /**< The queue element count. */
+ uint16_t flags; /**< The flags for customer usage. */
+} T_OS_QUEUE;
+
+/**
+ * os_queue.h
+ *
+ * \brief Initialize the list queue.
+ *
+ * \param[in] p_queue Pointer to the list queue header.
+ *
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * T_OS_QUEUE test_queue;
+ *
+ * int test(void)
+ * {
+ * // Initialize the queue before operating it.
+ * os_queue_init(&test_queue);
+ * }
+ * \endcode
+ *
+ * \ingroup Queue
+ */
+void os_queue_init(T_OS_QUEUE *p_queue);
+
+/**
+ * os_queue.h
+ *
+ * \brief Enqueue an element to the back of the list queue.
+ *
+ * \param[in] p_queue Pointer to the list queue header.
+ *
+ * \param[in] p_elem The list queue element being enqueued.
+ *
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * struct test_item
+ * {
+ * struct test_item *p_next; // Pointer to the next item, must be the first field.
+ * uint32_t id;
+ * uint8_t data[10];
+ * }
+ *
+ * T_OS_QUEUE test_queue;
+ *
+ * struct test_item a_item;
+ *
+ * int test(void)
+ * {
+ * // Initialize the queue before operating it.
+ * os_queue_init(&test_queue);
+ *
+ * // Enqueue the item.
+ * os_queue_in(&test_queue, &a_item);
+ * }
+ * \endcode
+ *
+ * \ingroup Queue
+ */
+void os_queue_in(T_OS_QUEUE *p_queue, void *p_elem);
+
+/**
+ * os_queue.h
+ *
+ * \brief Dequeue an element from the front of the list queue.
+ *
+ * \param[in] p_queue Pointer to the list queue header.
+ *
+ * \return The first element from the list queue. If the returned address is
+ * NULL, the list queue is empty.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * struct test_item
+ * {
+ * struct test_item *p_next; // Pointer to the next item, must be the first field.
+ * uint32_t id;
+ * uint8_t data[10];
+ * }
+ *
+ * T_OS_QUEUE test_queue;
+ *
+ * struct test_item a_item;
+ *
+ * int test(void)
+ * {
+ * struct test_item *p_item;
+ *
+ * // Initialize the queue before operating it.
+ * os_queue_init(&test_queue);
+ *
+ * // Enqueue the item.
+ * os_queue_in(&test_queue, &a_item);
+ *
+ * // Then dequeue the item from the list queue.
+ * p_item = os_queue_out(&test_queue);
+ * }
+ * \endcode
+ *
+ * \ingroup Queue
+ */
+void *os_queue_out(T_OS_QUEUE *p_queue);
+
+/**
+ * os_queue.h
+ *
+ * \brief Peek an element from the list queue.
+ *
+ * \param[in] p_queue Pointer to the list queue header.
+ *
+ * \return The first element from the list queue. If the returned address is
+ * NULL, the list queue is empty.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * struct test_item
+ * {
+ * struct test_item *p_next; // Pointer to the next item, must be the first field.
+ * uint32_t id;
+ * uint8_t data[10];
+ * }
+ *
+ * T_OS_QUEUE test_queue;
+ *
+ * struct test_item a_item;
+ *
+ * int test(void)
+ * {
+ * struct test_item *p_item;
+ *
+ * // Initialize the queue before operating it.
+ * os_queue_init(&test_queue);
+ *
+ * // Enqueue the item.
+ * os_queue_in(&test_queue, &a_item);
+ *
+ * // Peek but not remove the item from the list queue.
+ * p_item = os_queue_peek(&test_queue);
+ * }
+ * \endcode
+ *
+ * \ingroup Queue
+ */
+void *os_queue_peek(T_OS_QUEUE *p_queue);
+
+/**
+ * os_queue.h
+ *
+ * \brief Insert an element to the list queue.
+ *
+ * \param[in] p_queue Pointer to the list queue header.
+ *
+ * \param[in] p_elem The element which the new element to be inserted behind.
+ *
+ * \param[in] p_new_elem The inserted element.
+ *
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * struct test_item
+ * {
+ * struct test_item *p_next; // Pointer to the next item, must be the first field.
+ * uint32_t id;
+ * uint8_t data[10];
+ * }
+ *
+ * T_OS_QUEUE test_queue;
+ *
+ * struct test_item item1;
+ * struct test_item item2;
+ * struct test_item item3;
+ *
+ * int test(void)
+ * {
+ * struct test_item *p_item;
+ *
+ * // Initialize the queue before operating it.
+ * os_queue_init(&test_queue);
+ *
+ * // Enqueue the item 1.
+ * os_queue_in(&test_queue, &item1);
+ *
+ * // Enqueue the item 2.
+ * os_queue_in(&test_queue, &item2);
+ *
+ * // Insert the item 3 behind item 1 but before item 2.
+ * os_queue_insert(&test_queue, &item1, &item3);
+ * }
+ * \endcode
+ *
+ * \ingroup Queue
+ */
+void os_queue_insert(T_OS_QUEUE *p_queue, void *p_elem, void *p_new_elem);
+
+/**
+ * os_queue.h
+ *
+ * \brief Delete an element from the list queue.
+ *
+ * \param[in] p_queue Pointer to the list queue header.
+ *
+ * \param[in] p_elem The element to be deleted from the list queue.
+ *
+ * \return The status of queue element deletion.
+ * \retval true Queue element was deleted successfully.
+ * \retval false Queue element was failed to delete when the queue is empty
+ * or the being deleted queue element is not belonged to the queue.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * struct test_item
+ * {
+ * struct test_item *p_next; // Pointer to the next item, must be the first field.
+ * uint32_t id;
+ * uint8_t data[10];
+ * }
+ *
+ * T_OS_QUEUE test_queue;
+ *
+ * struct test_item item1;
+ * struct test_item item2;
+ * struct test_item item3;
+ *
+ * int test(void)
+ * {
+ * struct test_item *p_item;
+ *
+ * // Initialize the queue before operating it.
+ * os_queue_init(&test_queue);
+ *
+ * // Enqueue the item 1.
+ * os_queue_in(&test_queue, &item1);
+ *
+ * // Enqueue the item 2.
+ * os_queue_in(&test_queue, &item2);
+ *
+ * // Enqueue the item 3.
+ * os_queue_in(&test_queue, &item3);
+ *
+ * // Then delete the item 2.
+ * os_queue_delete(&test_queue, &item12);
+ * }
+ * \endcode
+ *
+ * \ingroup Queue
+ */
+bool os_queue_delete(T_OS_QUEUE *p_queue, void *p_elem);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OS_QUEUE_H_ */
diff --git a/inc/os/os_sched.h b/inc/os/os_sched.h
new file mode 100644
index 0000000..f5dd69a
--- /dev/null
+++ b/inc/os/os_sched.h
@@ -0,0 +1,314 @@
+/**
+ * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved.
+ */
+
+#ifndef _OS_SCHED_H_
+#define _OS_SCHED_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup OS OSIF APIs
+ * \defgroup Schedule Kernel Scheduler
+ *
+ * \brief Manage the kernel scheduler functions.
+ *
+ * \ingroup OS
+ */
+
+
+/**
+ * os_sched.h
+ *
+ * \brief Delay current task for a given period in milliseconds.
+ *
+ * \param[in] ms The amount of timer in milliseconds that the current task
+ * should block.
+ *
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Task routine implementation.
+ * void task_routine(void *p_param)
+ * {
+ * for (;;)
+ * {
+ * // Task code goes here.
+ * os_delay(100);
+ *
+ * // Do something here per 100ms.
+ * }
+ * }
+ * \endcode
+ *
+ * \ingroup Schedule
+ */
+void os_delay(uint32_t ms);
+
+/**
+ * os_sched.h
+ *
+ * \brief Get the time in milliseconds since os_sched_start() API function was called.
+ *
+ * \param None
+ *
+ * \return The time in milliseconds. Note the time represented by a 32-bit integer
+ * may be overflowed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Task routine implementation.
+ * void task_routine(void *p_param)
+ * {
+ * uint32_t last_time;
+ *
+ * // Get the last timestamp.
+ * last_time = os_sys_time_get();
+ *
+ * for (;;)
+ * {
+ * // Wait for the next cycle.
+ * os_delay(100);
+ *
+ * // Do something here per 100ms.
+ * }
+ * }
+ * \endcode
+ *
+ * \ingroup Schedule
+ */
+uint64_t os_sys_time_get(void);
+
+/**
+ * os_sched.h
+ *
+ * \brief Get the system tick since os_sched_start() API function was called.
+ *
+ * \param None
+ *
+ * \return The time in system tick. Note the tick represented by a 32-bit integer
+ * may be overflowed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+
+* #define portTICK_PERIOD_MS 10
+
+ * // Task routine implementation.
+ * void task_routine(void *p_param)
+ * {
+ * uint32_t beg_tick;
+ * uint32_t end_tick;
+ * uint32_t time;
+ *
+ * beg_tick = os_sys_tick_get();
+ *
+ * // Do something here
+ *
+ * end_tick = os_sys_tick_get();
+ *
+ * //get correct passed time in milliseconds
+ * time = (end_tick - beg_tick) * portTICK_PERIOD_MS;
+ * }
+ * \endcode
+ *
+ * \ingroup Schedule
+ */
+uint64_t os_sys_tick_get(void);
+
+/**
+ * os_sched.h
+ *
+ * \brief Start the RTOS kernel scheduler.
+ *
+ * \param None
+ *
+ * \return The status of starting kernel scheduler.
+ * \retval true Scheduler was started successfully.
+ * \retval false Scheduler was failed to start.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * // Create at least one task before starting kernel scheduler.
+ * if (os_task_create(&p_handle, "task", task_routine,
+ * NULL, STACK_SIZE, TASK_PRIORITY) == true)
+ * {
+ * // Task created successfully.
+ * }
+ * else
+ * {
+ * // Task failed to create.
+ * return -1;
+ * }
+ *
+ * // Start the kernel scheduler.
+ * os_sched_start();
+ *
+ * // Will not get here unless a task calls os_sched_stop().
+ * }
+ * \endcode
+ *
+ * \ingroup Schedule
+ */
+bool os_sched_start(void);
+
+/**
+ * os_sched.h
+ *
+ * \brief Stop the RTOS kernel scheduler. All created tasks will be automatically
+ * deleted and multitasking (either preemptive or cooperative) stops.
+ *
+ * \param None
+ *
+ * \return The status of stopping kernel scheduler.
+ * \retval true Scheduler was stopped successfully.
+ * \retval false Scheduler was failed to stop.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Task routine implementation.
+ * void task_routine(void *p_param)
+ * {
+ * for (;;)
+ * {
+ * // Task code goes here.
+ *
+ * // At some point we want to end the real time kernel processing.
+ * os_sched_stop();
+ * }
+ * }
+ *
+ * int test(void)
+ * {
+ * // Create at least one task before starting kernel scheduler.
+ * if (os_task_create(&p_handle, "task", task_routine,
+ * NULL, STACK_SIZE, TASK_PRIORITY) == true)
+ * {
+ * // Task created successfully.
+ * }
+ * else
+ * {
+ * // Task failed to create.
+ * return -1;
+ * }
+ *
+ * // Start the kernel scheduler.
+ * os_sched_start();
+ *
+ * // Will not get here unless a task calls os_sched_stop().
+ * }
+ * \endcode
+ *
+ * \ingroup Schedule
+ */
+bool os_sched_stop(void);
+
+/**
+ * os_sched.h
+ *
+ * \brief Suspends the kernel scheduler without disabling interrupts. Context
+ * switches will not occur while the scheduler is suspended. After calling
+ * os_sched_suspend(), the calling task will continue to execute without
+ * risk of being swapped out until a call to os_sched_resume() has been made.
+ *
+ * \param None
+ *
+ * \return The status of suspending kernel scheduler.
+ * \retval true Scheduler was suspended successfully.
+ * \retval false Scheduler was failed to suspend.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Task routine implementation.
+ * void task_routine(void *p_param)
+ * {
+ * for (;;)
+ * {
+ * // Task code goes here.
+ *
+ * // At some point the task wants to perform a long operation, and do not
+ * // want to get swapped out.
+ * os_sched_suspend();
+ *
+ * // The long operation.
+ *
+ * // The operation is completed, and resume the scheduler.
+ * os_sched_resume();
+ * }
+ * }
+ * \endcode
+ *
+ * \ingroup Schedule
+ */
+bool os_sched_suspend(void);
+
+/**
+ * os_sched.h
+ *
+ * \brief Resume the kernel scheduler after it was suspended by a call
+ * to os_sched_suspend().
+ *
+ * \param None
+ *
+ * \return The status of resuming kernel scheduler.
+ * \retval true Scheduler was resumed successfully.
+ * \retval false Scheduler was failed to resume.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Task routine implementation.
+ * void task_routine(void *p_param)
+ * {
+ * for (;;)
+ * {
+ * // Task code goes here.
+ *
+ * // At some point the task wants to perform a long operation, and do not
+ * // want to get swapped out.
+ * os_sched_suspend();
+ *
+ * // The long operation.
+ *
+ * // The operation is completed, and resume the scheduler.
+ * os_sched_resume();
+ * }
+ * }
+ * \endcode
+ *
+ * \ingroup Schedule
+ */
+bool os_sched_resume(void);
+
+/* internal function */
+bool os_sched_is_start(void);
+
+typedef enum
+{
+ SCHEDULER_SUSPENDED = 0,
+ SCHEDULER_NOT_STARTED = 1,
+ SCHEDULER_RUNNING = 2
+} SCHEDULER_STATE;
+
+SCHEDULER_STATE os_sched_state_get(void);
+
+void os_systick_handler(void);
+
+uint64_t os_sys_tick_increase(uint32_t tick_increment);
+
+void os_vector_table_update(void);
+
+void os_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OS_SCHED_H_ */
diff --git a/inc/os/os_sync.h b/inc/os/os_sync.h
new file mode 100644
index 0000000..2a6c414
--- /dev/null
+++ b/inc/os/os_sync.h
@@ -0,0 +1,475 @@
+/**
+ * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved.
+ */
+
+#ifndef _OS_SYNC_H_
+#define _OS_SYNC_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup OS OSIF APIs
+ * \defgroup Synchronization Inter-Task Communication
+ *
+ * \brief Manage Inter-task communication functions.
+ * \details Tasks need to communicate with each other or access shared resources together.
+ * There are many ways to exchange data between tasks, for example using shared
+ * data, polling loops and message passing.\n
+ * Many resources can be considered as serially-reusable. This means that they
+ * can be used repeatedly by different tasks, but only by one task at a time.\n
+ * The following mechanisms are available to the user:\n
+ * \arg <b>Lock</b>
+ * \arg <b>Semaphore</b>
+ * \arg <b>Mutex</b>
+ *
+ * \ingroup OS
+ */
+
+
+/**
+ * os_sync.h
+ *
+ * \brief Enter the critical region. Disable preemptive context switch and interrupts.
+ *
+ * \param None
+ *
+ * \return Interrupt mask flag.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * uint32_t s;
+ *
+ * // Enter the critical section.
+ * s = os_lock();
+ * // Allow only one task or ISR to operate the list.
+ * list_add(p_list, &item);
+ * // Exit the critical section and restore ISR mask flag.
+ * os_unlock(s);
+ * }
+ * \endcode
+ *
+ * \ingroup Synchronization
+ */
+uint32_t os_lock(void);
+
+/**
+ * os_sync.h
+ *
+ * \brief Exit the critical region. Enable preemptive context switch and interrupts.
+ *
+ * \param[in] s Interrupt mask flag to be restored.
+ *
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * uint32_t s;
+ *
+ * // Enter the critical section.
+ * s = os_lock();
+ * // Allow only one task or ISR to operate the list.
+ * list_add(p_list, &item);
+ * // Exit the critical section and restore ISR mask flag.
+ * os_unlock(s);
+ * }
+ * \endcode
+ *
+ * \ingroup Synchronization
+ */
+void os_unlock(uint32_t s);
+
+/**
+ * os_sync.h
+ *
+ * \brief Create a counting semaphore.
+ *
+ * \details Semaphores are used to manage and protect access to shared resources. A semaphore
+ * can be used to permit a fixed number of task to access a pool of shared resources.
+ * Using semaphores.\n
+ * A semaphore object should be initialized to the maximum number of available tokens.
+ * This number of available resources is specified as parameter of the os_sem_create()
+ * function. Each time a semaphore token is obtained with os_sem_take(), the semaphore
+ * count is decremented. When the semaphore count is 0, no semaphore token can be obtained.
+ * The task that tries to obtain the semaphore token needs to wait until the next token
+ * is free. Semaphores are released with os_sem_give() incrementing the semaphore count.
+ *
+ * \image html OS-semaphore-overview.jpg "Semaphore Overview" width=496px height=346px
+ *
+ * \param[out] pp_handle Used to pass back the created semaphore handle.
+ *
+ * \param[in] init_count The count value assigned to the semaphore when created.
+ *
+ * \param[in] max_count The maximum count value that can be reached. If the max_count is 1,
+ * a binary semaphore is being created.
+ *
+ * \return The status of the semaphore creation.
+ * \retval true Semaphore was created successfully.
+ * \retval false Semaphore was failed to create.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * void *p_handle;
+ *
+ * // Create a semaphore with initial value 0 and maximum value 10.
+ * if (os_sem_create(&p_handle, 0, 10) == true)
+ * {
+ * // Semaphore created successfully.
+ * }
+ * else
+ * {
+ * // Semaphore failed to create.
+ * return -1;
+ * }
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Synchronization
+ */
+bool os_sem_create(void **pp_handle, uint32_t init_count, uint32_t max_count);
+
+/**
+ * os_sync.h
+ *
+ * \brief Delete a semaphore.
+ *
+ * \param[in] p_handle The handle of the semaphore to be deleted.
+ *
+ * \return The status of the semaphore deletion.
+ * \retval true Semaphore was deleted successfully.
+ * \retval false Semaphore was failed to delete.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * void *p_handle;
+ *
+ * // Create a semaphore with initial value 0 and maximum value 10.
+ * if (os_sem_create(&p_handle, 0, 10) == true)
+ * {
+ * // Semaphore created successfully.
+ * }
+ * else
+ * {
+ * // Semaphore failed to create.
+ * return -1;
+ * }
+ *
+ * // Delete the created semaphore.
+ * os_sem_delete(p_handle);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Synchronization
+ */
+bool os_sem_delete(void *p_handle);
+
+/**
+ * os_sync.h
+ *
+ * \brief Take a semaphore.
+ *
+ * \param[in] p_handle The handle of the semaphore to be taken.
+ *
+ * \param[in] wait_ms The time in milliseconds to wait for the semaphore to become
+ * available.
+ * \arg \c 0 No blocking and return immediately.
+ * \arg \c 0xFFFFFFFF Block infinitely until the semaphore taken.
+ * \arg \c others The timeout value in milliseconds.
+ *
+ * \return The status of the semaphore taking.
+ * \retval true Semaphore was taken successfully.
+ * \retval false Semaphore was failed to take.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * void *p_handle = NULL;
+ *
+ * // One task creates a semaphore.
+ * void task1(void *p_param)
+ * {
+ * // Create a full binary semaphore.
+ * os_sem_create(&p_handle, 1, 1);
+ * }
+ *
+ * // Anohter task uses the semaphore.
+ * void task2(void *p_param)
+ * {
+ * // See if we can obtain the semaphore. If the semaphore is
+ * // not available, wait for 100ms.
+ * if (os_sem_take(p_handle, 100) == true)
+ * {
+ * // Access the share resource.
+ *
+ * // Finish accessing the share resource, then release the semaphore.
+ * os_sem_give(p_handle);
+ * }
+ * else
+ * {
+ * // Could not access the share resource.
+ * }
+ * }
+ * \endcode
+ *
+ * \ingroup Synchronization
+ */
+bool os_sem_take(void *p_handle, uint32_t wait_ms);
+
+/**
+ * os_sync.h
+ *
+ * \brief Give a semaphore.
+ *
+ * \param[in] p_handle The handle of the semaphore to be given.
+ *
+ * \return The status of the semaphore giving.
+ * \retval true Semaphore was given successfully.
+ * \retval false Semaphore was failed to give.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ *
+ * // Create an empty binary semaphore.
+ * os_sem_create(&p_handle, 0, 1);
+ *
+ * // Obtaining the empty semaphore immediately will be failed.
+ * if (os_sem_take(p_handle, 0) == false)
+ * {
+ * // Failed.
+ * }
+ *
+ * // Give the semaphore
+ * if (os_sem_give(p_hanel) == true)
+ * {
+ * // Now we can take the semaphore.
+ * os_sem_take(p_handle, 0);
+ *
+ * // Again taking the binary semaphore will be failed.
+ * os_sem_take(p_handle, 0);
+ * }
+ * }
+ * \endcode
+ *
+ * \ingroup Synchronization
+ */
+bool os_sem_give(void *p_handle);
+
+/**
+ * os_sync.h
+ *
+ * \brief Create a mutex.
+ *
+ * \details Mutex (Mutual Exclusion) is used to protect a shared resource that can be accessed
+ * only by one task at a time.\n
+ * A mutex is a special version of a binary empty semaphore. The advantage of a mutex
+ * is that it introduces task ownership. When a task acquires a mutex and becomes its
+ * owner, subsequent mutex acquires from that task will succeed immediately. Thus, mutex
+ * acquires/releases can be nested.\n
+ *
+ * \image html OS-mutex-overview.jpg "Mutex Overview" width=451px height=196px
+ *
+ * \param[out] pp_handle Used to pass back the created mutex handle.
+ *
+ * \return The status of the mutex creation.
+ * \retval true Mutex was created successfully.
+ * \retval false Mutex was failed to create.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ *
+ * // Create a mutex.
+ * if (os_mutex_create(&p_handle) == true)
+ * {
+ * // The mutex created successfully.
+ * // Now it can be used.
+ * }
+ * }
+ * \endcode
+ *
+ * \ingroup Synchronization
+ */
+bool os_mutex_create(void **pp_handle);
+
+/**
+ * os_sync.h
+ *
+ * \brief Delete a mutex.
+ *
+ * \param[in] p_handle The handle of the mutex to be deleted.
+ *
+ * \return The status of the Mutex deletion.
+ * \retval true Mutex was deleted successfully.
+ * \retval false Mutex was failed to delete.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * void *p_handle;
+ *
+ * // Create a mutex.
+ * if (os_mutex_create(&p_handle) == true)
+ * {
+ * // Mutex created successfully.
+ * }
+ * else
+ * {
+ * // Mutex failed to create.
+ * return -1;
+ * }
+ *
+ * // Delete the created mutex.
+ * os_mutex_delete(p_handle);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Synchronization
+ */
+bool os_mutex_delete(void *p_handle);
+
+/**
+ * os_sync.h
+ *
+ * \brief Take a mutex.
+ *
+ * \param[in] p_handle The handle of the mutex to be taken.
+ *
+ * \param[in] wait_ms The time in milliseconds to wait for the mutex to become
+ * available.
+ * \arg \c 0 No blocking and return immediately.
+ * \arg \c 0xFFFFFFFF Block infinitely until the mutex taken.
+ * \arg \c others The timeout value in milliseconds.
+ *
+ * \return The status of the mutex taking.
+ * \retval true Mutex was taken successfully.
+ * \retval false Mutex was failed to take.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * void *p_handle = NULL;
+ *
+ * // One task creates a mutex.
+ * void task1(void *p_param)
+ * {
+ * // Create a mutex.
+ * os_mutex_create(&p_handle);
+ * }
+ *
+ * // Anohter task uses the mutex.
+ * void task2(void *p_param)
+ * {
+ * // See if we can obtain the mutex. If the mutex is
+ * // not available, wait for 100ms.
+ * if (os_mutex_take(p_handle, 100) == true)
+ * {
+ * // Access the share resource.
+ *
+ * // In real code, recursive calls of mutex may occur.
+ * os_mutex_take(p_handle, 100);
+ * os_mutex_take(p_handle, 200);
+ *
+ * // The mutex has now been 'taken' three times, so will not be
+ * // available to another task until it has also been given back
+ * // three times.
+ * os_mutex_give(p_handle);
+ * os_mutex_give(p_handle);
+ * os_mutex_give(p_handle);
+ *
+ * // Finish accessing the share resource, then release the semaphore.
+ * // Now the mutex can be taken by other tasks.
+ * }
+ * else
+ * {
+ * // Could not access the share resource.
+ * }
+ * }
+ * \endcode
+ *
+ * \ingroup Synchronization
+ */
+bool os_mutex_take(void *p_handle, uint32_t wait_ms);
+
+/**
+ * os_sync.h
+ *
+ * \brief Give a mutex.
+ *
+ * \param[in] p_handle The handle of the mutex to be given.
+ *
+ * \return The status of the mutex giving.
+ * \retval true Mutex was given successfully.
+ * \retval false Mutex was failed to give.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * void *p_handle = NULL;
+ *
+ * // One task creates a mutex.
+ * void task1(void *p_param)
+ * {
+ * // Create a mutex.
+ * os_mutex_create(&p_handle);
+ * }
+ *
+ * // Anohter task uses the mutex.
+ * void task2(void *p_param)
+ * {
+ * // See if we can obtain the mutex. If the mutex is
+ * // not available, wait for 100ms.
+ * if (os_mutex_take(p_handle, 100) == true)
+ * {
+ * // Access the share resource.
+ *
+ * // In real code, recursive calls of mutex may occur.
+ * os_mutex_take(p_handle, 100);
+ * os_mutex_take(p_handle, 200);
+ *
+ * // The mutex has now been 'taken' three times, so will not be
+ * // available to another task until it has also been given back
+ * // three times.
+ * os_mutex_give(p_handle);
+ * os_mutex_give(p_handle);
+ * os_mutex_give(p_handle);
+ *
+ * // Finish accessing the share resource, then release the semaphore.
+ * // Now the mutex can be taken by other tasks.
+ * }
+ * else
+ * {
+ * // Could not access the share resource.
+ * }
+ * }
+ * \endcode
+ *
+ * \ingroup Synchronization
+ */
+bool os_mutex_give(void *p_handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OS_SYNC_H_ */
diff --git a/inc/os/os_task.h b/inc/os/os_task.h
new file mode 100644
index 0000000..6889b13
--- /dev/null
+++ b/inc/os/os_task.h
@@ -0,0 +1,566 @@
+/**
+ * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved.
+ */
+
+#ifndef _OS_TASK_H_
+#define _OS_TASK_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup OS OSIF APIs
+ * \defgroup Task Task Management
+ *
+ * \brief Define, create, and control task functions.
+ * \details The Task Management function group allows to create, delete, and control tasks
+ * in the system.\n
+ * Tasks can be in the following states:\n
+ * \arg <b>RUNNING:</b> The task that is currently running is in the <b>RUNNING</b> state.
+ * Only one task at a time can be in this state.
+ * \arg <b>READY:</b> Tasks which are ready to run are in the <b>READY</b> state. Once the
+ * <b>RUNNING</b> task has terminated or is <b>WAITING</b>, the next
+ * <b>READY</b> task with the highest priority becomes the <b>RUNNING</b> task.
+ * \arg <b>WAITING:</b> Tasks that are waiting for an event to occur are in the WAITING state.
+ * \arg <b>INACTIVE</b>: Tasks that are not created or terminated are in the <b>INACTIVE</b> state.
+ * These Tasks typically consume no system resources.
+ *
+ * \image html OS-task-state-transition.jpg "Task State Transition" width=526px height=526px
+ *
+ * \ingroup OS
+ */
+
+
+/**
+ * os_task.h
+ *
+ * \brief Create a new task and add it to the list of tasks that are ready to run.
+ *
+ * \param[out] pp_handle Used to pass back a handle by which the created task
+ * can be referenced.
+ *
+ * \param[in] p_name A descriptive name for the task.
+ *
+ * \param[in] p_routine Pointer to task routine function that must be implemented
+ * to never return.
+ *
+ * \param[in] p_param Pointer parameter passed to the task routine function.
+ *
+ * \param[in] stack_size The size of the task stack that is specified as the number
+ * of bytes.
+ *
+ * \param[in] priority The priority at which the task should run. Higher priority
+ * task has higher priority value.
+ *
+ * \return The status of the task creation.
+ * \retval true Task was created successfully and added to task ready list.
+ * \retval false Task was failed to create.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Task routine implementation.
+ * void task_routine(void *p_param)
+ * {
+ * for (;;)
+ * {
+ * // Task code goes here.
+ * }
+ * }
+ *
+ * // Task to be created.
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ * uint32_t task_param;
+ *
+ * if (os_task_create(&p_handle, "task", task_routine,
+ * &task_param, STACK_SIZE, TASK_PRIORITY) == true)
+ * {
+ * // Task created successfully.
+ * }
+ * else
+ * {
+ * // Task failed to create.
+ * return -1;
+ * }
+ *
+ * // Use the handle to delete the task.
+ * os_task_delete(p_handle);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Task
+ */
+bool os_task_create(void **pp_handle, const char *p_name, void (*p_routine)(void *),
+ void *p_param, uint16_t stack_size, uint16_t priority);
+
+/**
+ * os_task.h
+ *
+ * \brief Remove a task from RTOS's task management. The task being deleted will be removed
+ * from RUNNING, READY or WAITING state.
+ *
+ * \param[in] p_handle The handle of the task to be deleted.
+ *
+ * \return The status of the task deletion.
+ * \retval true Task was deleted successfully.
+ * \retval false Task was failed to delete.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Task routine implementation.
+ * void task_routine(void *p_param)
+ * {
+ * for (;;)
+ * {
+ * // Task code goes here.
+ * }
+ * }
+ *
+ * // Task to be created and deleted.
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ * uint32_t task_param;
+ *
+ * if (os_task_create(&p_handle, "task", task_routine,
+ * &task_param, STACK_SIZE, TASK_PRIORITY) == true)
+ * {
+ * // Task created successfully.
+ * }
+ * else
+ * {
+ * // Task failed to create.
+ * return -1;
+ * }
+ *
+ * // Use the handle to delete the task.
+ * os_task_delete(p_handle);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Task
+ */
+bool os_task_delete(void *p_handle);
+
+/**
+ * os_task.h
+ *
+ * \brief Suspend the task. The suspended task will not be scheduled and never get
+ * any microcontroller processing time.
+ *
+ * \param[in] p_handle The handle of the task to be suspended.
+ *
+ * \return The status of the task suspension.
+ * \retval true Task was suspended successfully.
+ * \retval false Task was failed to suspend.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Task routine implementation.
+ * void task_routine(void *p_param)
+ * {
+ * for (;;)
+ * {
+ * // Task code goes here.
+ * }
+ * }
+ *
+ * // Task to be created and suspended.
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ * uint32_t task_param;
+ *
+ * if (os_task_create(&p_handle, "task", task_routine,
+ * &task_param, STACK_SIZE, TASK_PRIORITY) == true)
+ * {
+ * // Task created successfully.
+ * }
+ * else
+ * {
+ * // Task failed to create.
+ * return -1;
+ * }
+ *
+ * // Use the handle to suspend the created task.
+ * os_task_suspend(p_handle);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Task
+ */
+bool os_task_suspend(void *p_handle);
+
+/**
+ * os_task.h
+ *
+ * \brief Resume the suspended task.
+ *
+ * \param[in] p_handle The handle of the task to be resumed.
+ *
+ * \return The status of the task resume.
+ * \retval true Task was resumed successfully.
+ * \retval false Task was failed to resume.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Task routine implementation.
+ * void task_routine(void *p_param)
+ * {
+ * for (;;)
+ * {
+ * // Task code goes here.
+ * }
+ * }
+ *
+ * // Task to be suspended and resumed.
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ * uint32_t task_param;
+ *
+ * if (os_task_create(&p_handle, "task", task_routine,
+ * &task_param, STACK_SIZE, TASK_PRIORITY) == true)
+ * {
+ * // Task created successfully.
+ * }
+ * else
+ * {
+ * // Task failed to create.
+ * return -1;
+ * }
+ *
+ * // Use the handle to suspend the created task.
+ * os_task_suspend(p_handle);
+ *
+ * // Resume the suspended task by ourselves.
+ * os_task_resume(p_handle);
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Task
+ */
+bool os_task_resume(void *p_handle);
+
+/**
+ * os_task.h
+ *
+ * \brief Force a context swith and pass control to the next task that is in
+ * READY state.
+ *
+ * \param None
+ *
+ * \return The status of the task resume.
+ * \retval true Task was yielded successfully.
+ * \retval false Task was failed to yield.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Task routine implementation.
+ * void task_routine(void *p_param)
+ * {
+ * for (;;)
+ * {
+ * // Force a context switch
+ * os_task_yield();
+ * }
+ * }
+ *
+ * // Task to be created.
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ * uint32_t task_param;
+ *
+ * if (os_task_create(&p_handle, "task", task_routine,
+ * &task_param, STACK_SIZE, TASK_PRIORITY) == true)
+ * {
+ * // Task created successfully.
+ * }
+ * else
+ * {
+ * // Task failed to create.
+ * return -1;
+ * }
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Task
+ */
+bool os_task_yield(void);
+
+/**
+ * os_task.h
+ *
+ * \brief Get the handle of the current running task.
+ *
+ * \param[out] pp_handle Used to pass back a handle by which the current task
+ * can be referenced.
+ *
+ * \return The status of getting the current task handle.
+ * \retval true Task handle was got successfully.
+ * \retval false Task handle was failed to get.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Get current task handle.
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ *
+ * os_task_handle_get(&p_handle);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Task
+ */
+bool os_task_handle_get(void **pp_handle);
+
+/**
+ * os_task.h
+ *
+ * \brief Get the priority of the specified task.
+ *
+ * \param[in] p_handle The handle of the task to be queried. Passing a NULL handle
+ * means querying the priority of the current task.
+ *
+ * \param[out] p_priority Used to pass back the priority of the task.
+ *
+ * \return The status of getting the task priority.
+ * \retval true Task priority was got successfully.
+ * \retval false Task priority was failed to get.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ * uint16_t priority;
+ *
+ * if (os_task_create(&p_handle, "task", task_routine,
+ * NULL, STACK_SIZE, TASK_PRIORITY) == true)
+ * {
+ * // Task created successfully.
+ * }
+ * else
+ * {
+ * // Task failed to create.
+ * return -1;
+ * }
+ *
+ * // Get the task priority.
+ * os_task_priority_get(p_handle, &priority);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Task
+ */
+bool os_task_priority_get(void *p_handle, uint16_t *p_priority);
+
+/**
+ * os_task.h
+ *
+ * \brief Set the priority of the specified task.
+ *
+ * \param[in] p_handle The handle of the task for which the priority is being set.
+ * Passing a NULL handle means setting the priority of the
+ * current task.
+ *
+ * \param[in] priority The priority to which the task will be set.
+ *
+ * \return The status of setting the task priority.
+ * \retval true Task priority was set successfully.
+ * \retval false Task priority was failed to set.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ * uint16_t priority;
+ *
+ * if (os_task_create(&p_handle, "task", task_routine,
+ * NULL, STACK_SIZE, TASK_PRIORITY) == true)
+ * {
+ * // Task created successfully.
+ * }
+ * else
+ * {
+ * // Task failed to create.
+ * return -1;
+ * }
+ *
+ * // Use the handle to raise the created task priority.
+ * os_task_priority_set(p_handle, TASK_PRIORITY + 1);
+ *
+ * // Use a NULL handle to raise the current task priority.
+ * os_task_priority_set(NULL, TASK_PRIORITY + 1);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Task
+ */
+bool os_task_priority_set(void *p_handle, uint16_t priority);
+
+/**
+ * os_task.h
+ *
+ * \brief Send a notification signal to the specified task.
+ *
+ * The notification signal sent to a task will remain pending until it is
+ * cleared by the task calling os_task_signal_recv(). If the task was already
+ * in the WAITING state to wait for the signal, then the task will be removed
+ * from WAITING state and the signal cleared.
+ *
+ * \param[in] p_handle The handle of the task to which the signal is sent.
+ *
+ * \param[in] signal The signal to be sent.
+ *
+ * \return The status of sending the signal.
+ * \retval true Task signal was sent successfully.
+ * \retval false Task signal was failed to send.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ * uint32_t signal;
+ *
+ * if (os_task_create(&p_handle, "task", task_routine,
+ * NULL, STACK_SIZE, TASK_PRIORITY) == true)
+ * {
+ * // Task created successfully.
+ * }
+ * else
+ * {
+ * // Task failed to create.
+ * return -1;
+ * }
+ *
+ * // Send signal to the created task.
+ * signal = 1;
+ * os_task_signal_send(p_handle, signal);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Task
+ */
+
+#if (BUILE_OS_COMMON == 0)
+
+bool os_task_signal_send(void *p_handle, uint32_t signal);
+
+/**
+ * os_task.h
+ *
+ * \brief Wait for a notification signal.
+ *
+ * \param[out] p_signal Used to pass back the received signal.
+ *
+ * \param[in] wait_ms The timeout in milliseconds to wait for the signal.
+ * \arg \c 0 No blocking and return immediately.
+ * \arg \c 0xFFFFFFFF Block infinitely until the signal received.
+ * \arg \c others The timeout value in milliseconds.
+ *
+ * \return The status of receiving the signal.
+ * \retval true Task signal was received successfully.
+ * \retval false Task signal was failed to receive.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * uint32_t signal;
+ *
+ * // Block to wait for the signal sent from other tasks.
+ * os_task_signal_recv(&signal, 0xFFFFFFFF);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Task
+ */
+bool os_task_signal_create(void *p_handle, uint32_t count);
+bool os_task_signal_recv(uint32_t *p_signal, uint32_t wait_ms);
+bool os_task_signal_take(uint32_t p_signal, uint32_t wait_ms);
+bool os_task_signal_give(void *p_handle);
+/**
+ * os_task.h
+ *
+ * \brief Clear the signal of the specified task.
+ *
+ * \param[in] p_handle The handle of the task to which the signal is clear.
+ *
+ * \return The status of clearing the signal.
+ * \retval true Task signal was cleared successfully.
+ * \retval false Task signal was failed to clear.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ * uint32_t signal;
+ *
+ * if (os_task_create(&p_handle, "task", task_routine,
+ * NULL, STACK_SIZE, TASK_PRIORITY) == true)
+ * {
+ * // Task created successfully.
+ * }
+ * else
+ * {
+ * // Task failed to create.
+ * return -1;
+ * }
+ *
+ * // Send signal to the created task.
+ * signal = 1;
+ * os_task_signal_send(p_handle, signal);
+ *
+ * // Clear signal of the created task.
+ * os_task_signal_clear(p_handle);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Task
+ */
+bool os_task_signal_clear(void *p_handle);
+
+#endif
+
+/* internal function */
+void os_task_status_dump(void);
+
+void os_task_dlps_return_idle_task(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OS_TASK_H_ */
diff --git a/inc/os/os_timer.h b/inc/os/os_timer.h
new file mode 100644
index 0000000..a4b67bd
--- /dev/null
+++ b/inc/os/os_timer.h
@@ -0,0 +1,517 @@
+/**
+ * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved.
+ */
+
+#ifndef _OS_TIMER_H_
+#define _OS_TIMER_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+//#include "timers.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup OS OSIF
+ * \defgroup Timer Timer Management
+ *
+ * \brief Create and control software timer and timer callback functions.
+ * \details The Timer Management function group allows to create, delete, and control software
+ * timers in the system. The software timers can be configured as one-short or periodic
+ * timers. When a timer expires, a callback function associated with the timer is
+ * executed.\n
+ * Timers can be in the following two states:\n
+ * \arg <b>Dormant</b> The timer first enters <b>Dormant</b> or <b>Inactive</b> state when created.
+ * If a one-short timer expires but not restarts yet, or is stopped the timer
+ * will be transformed from <b>Active</b> state into <b>Dormant</b> state.
+ * \arg <b>Active</b> The timer enters <b>Active</b> state If the timer starts or restarts. When
+ * expired, the callback function associcated with the timer will be executed.
+ *
+ * \image html OS-timer-state-transition.jpg "Software Timer State Transition" width=617px height=321px
+ *
+ * \ingroup OS
+ */
+
+
+/**
+ * os_timer.h
+ *
+ * \brief Get the ID assigned to the timer when created.
+ *
+ * \param[in] pp_handle Pointer to the created timer handle.
+ *
+ * \param[out] p_timer_id Used to pass back the ID assigned to the timer.
+ *
+ * \return The status of the timer id getting.
+ * \retval true Timer ID was got successfully.
+ * \retval false Timer ID was failed to get.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Timer callback function.
+ * void timer_callback(void *p_handle)
+ * {
+ * uint32_t timer_id;
+ *
+ * // Which timer expired?
+ * os_timer_id_get(&p_handle, &timer_id);
+ *
+ * if (timer_id == TIMER_ID)
+ * {
+ * // Delete the specified timer.
+ * os_timer_delete(&p_handle);
+ * }
+ * }
+ *
+ * #define TIMER_ID 1
+ *
+ * // Timer to be created.
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ *
+ * if (os_timer_create(&p_handle, "timer", TIMER_ID,
+ * INTERVAL_MS, false, timer_callback) == true)
+ * {
+ * // Timer created successfully, start the timer.
+ * os_timer_start(&p_handle);
+ * }
+ * else
+ * {
+ * // Timer failed to create.
+ * return -1;
+ * }
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Timer
+ */
+bool os_timer_id_get(void **pp_handle, uint32_t *p_timer_id);
+
+/**
+ * os_timer.h
+ *
+ * \brief Create a new software timer instance. This allocates the storage required by
+ * the new timer, initializes the new timers internal state, and return a handle
+ * by which the new timer can be referenced.
+ *
+ * \param[out] pp_handle Used to pass back a handle by which the created timer
+ * can be referenced.
+ *
+ * \param[in] p_timer_name A descriptive name for the timer.
+ *
+ * \param[in] timer_id An identifier that is assigned to the timer being created.
+ * Typically this would be used in the timer callback function to
+ * identify which timer expired when the same callback function is
+ * assigned to more than one timer.
+ *
+ * \param[in] interval_ms The timer period in milliseconds.
+ *
+ * \param[in] reload Used to set the timer as a periodic or one-shot timer.
+ * \arg \c true Create a periodic timer.
+ * \arg \c false Create a one-shot timer.
+ *
+ * \param[in] p_timer_callback The function to call when the timer expires. Callback functions
+ * must have the prototype defined as 'void callback(void *)'.
+ *
+ * \return The status of the timer creation.
+ * \retval true Timer was created successfully.
+ * \retval false Timer was failed to create.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Timer callback function.
+ * void timer_callback(void *p_handle)
+ * {
+ * uint32_t timer_id;
+ *
+ * // Which timer expired?
+ * os_timer_id_get(&p_handle, &timer_id);
+ *
+ * if (timer_id == TIMER_ID)
+ * {
+ * // Delete the specified timer.
+ * os_timer_delete(&p_handle);
+ * }
+ * }
+ *
+ * #define TIMER_ID 1
+ *
+ * // Timer to be created.
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ *
+ * if (os_timer_create(&p_handle, "timer", TIMER_ID,
+ * INTERVAL_MS, false, timer_callback) == true)
+ * {
+ * // Timer created successfully, start the timer.
+ * os_timer_start(&p_handle);
+ * }
+ * else
+ * {
+ * // Timer failed to create.
+ * return -1;
+ * }
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Timer
+ */
+bool os_timer_create(void **pp_handle, const char *p_timer_name, uint32_t timer_id,
+ uint32_t interval_ms, bool reload, void (*p_timer_callback)());
+
+/**
+ * os_timer.h
+ *
+ * \brief Start a timer that was previously created using the os_timer_create() API
+ * function. If the timer had already been started and was in the active state,
+ * then os_timer_create() has equivalent functionality to the os_timer_create()
+ * API function.
+ *
+ * \param[in] pp_handle Pointer to the created timer handle.
+ *
+ * \return The status of the timer starting.
+ * \retval true Timer was started successfully.
+ * \retval false Timer was failed to start.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Timer callback function.
+ * void timer_callback(void *p_handle)
+ * {
+ * uint32_t timer_id;
+ *
+ * // Which timer expired?
+ * os_timer_id_get(&p_handle, &timer_id);
+ *
+ * if (timer_id == TIMER_ID)
+ * {
+ * // Delete the specified timer.
+ * os_timer_delete(&p_handle);
+ * }
+ * }
+ *
+ * #define TIMER_ID 1
+ *
+ * // Timer to be created.
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ *
+ * if (os_timer_create(&p_handle, "timer", TIMER_ID,
+ * INTERVAL_MS, false, timer_callback) == true)
+ * {
+ * // Timer created successfully, start the timer.
+ * os_timer_start(&p_handle);
+ * }
+ * else
+ * {
+ * // Timer failed to create.
+ * return -1;
+ * }
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Timer
+ */
+bool os_timer_start(void **pp_handle);
+
+/**
+ * os_timer.h
+ *
+ * \brief Restart a timer that was previously created using the os_timer_create() API
+ * function. If the timer had already been started and was already in the active
+ * state, then os_timer_start() will cause the timer to re-evaluate its expiry
+ * time so that it is relative to when os_timer_start() was called. If the timer
+ * was in the dormant state then os_timer_start() has equivalent functionality to
+ * the os_timer_start() API function.
+ *
+ * \param[in] pp_handle Pointer to the created timer handle.
+ *
+ * \param[in] interval_ms The timer period in milliseconds.
+ *
+ * \return The status of the timer restarting.
+ * \retval true Timer was restarted successfully.
+ * \retval false Timer was failed to restart.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Timer callback function.
+ * void timer_callback(void *p_handle)
+ * {
+ * uint32_t timer_id;
+ *
+ * // Which timer expired?
+ * os_timer_id_get(&p_handle, &timer_id);
+ *
+ * if (timer_id == TIMER_ID)
+ * {
+ * // Restart the specified timer.
+ * os_timer_restart(&p_handle);
+ * }
+ * }
+ *
+ * #define TIMER_ID 1
+ *
+ * // Timer to be created.
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ *
+ * if (os_timer_create(&p_handle, "timer", TIMER_ID,
+ * INTERVAL_MS, false, timer_callback) == true)
+ * {
+ * // Timer created successfully, start the timer.
+ * os_timer_start(&p_handle);
+ * }
+ * else
+ * {
+ * // Timer failed to create.
+ * return -1;
+ * }
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Timer
+ */
+bool os_timer_restart(void **pp_handle, uint32_t interval_ms);
+
+/**
+ * os_timer.h
+ *
+ * \brief Stop a timer that was previously started using either of the os_timer_start(),
+ * os_timer_restart() API functions. Stopping a timer ensures the timer is not in
+ * the active state.
+ *
+ * \param[in] pp_handle Pointer to the handle of timer being stopped.
+ *
+ * \return The status of the timer stopping.
+ * \retval true Timer was stopped successfully.
+ * \retval false Timer was failed to stop.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Timer callback function.
+ * void timer_callback(void *p_handle)
+ * {
+ * uint32_t timer_id;
+ *
+ * // Which timer expired?
+ * os_timer_id_get(&p_handle, &timer_id);
+ *
+ * if (timer_id == TIMER_ID)
+ * {
+ * // Delete the specified timer.
+ * os_timer_delete(&p_handle);
+ * }
+ * }
+ *
+ * #define TIMER_ID 1
+ *
+ * // Timer to be created and stopped.
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ *
+ * if (os_timer_create(&p_handle, "timer", TIMER_ID,
+ * INTERVAL_MS, false, timer_callback) == true)
+ * {
+ * // Timer created successfully, start the timer.
+ * os_timer_start(&p_handle);
+ * }
+ * else
+ * {
+ * // Timer failed to create.
+ * return -1;
+ * }
+ *
+ * // Stop the timer before expiration.
+ * os_timer_stop(&p_handle);
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Timer
+ */
+bool os_timer_stop(void **pp_handle);
+
+/**
+ * os_timer.h
+ *
+ * \brief Delete a timer that was previously created using the os_timer_create()
+ * API function.
+ *
+ * \param[in] pp_handle Pointer to the handle of timer being deleted.
+ *
+ * \return The status of the timer deletion.
+ * \retval true Timer was deleted successfully.
+ * \retval false Timer was failed to delete.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Timer callback function.
+ * void timer_callback(void *p_handle)
+ * {
+ * uint32_t timer_id;
+ *
+ * // Which timer expired?
+ * os_timer_id_get(&p_handle, &timer_id);
+ *
+ * if (timer_id == TIMER_ID)
+ * {
+ * // Delete the specified timer.
+ * os_timer_delete(&p_handle);
+ * }
+ * }
+ *
+ * #define TIMER_ID 1
+ *
+ * // Timer to be created and deleted.
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ *
+ * if (os_timer_create(&p_handle, "timer", TIMER_ID,
+ * INTERVAL_MS, false, timer_callback) == true)
+ * {
+ * // Timer created successfully, start the timer.
+ * os_timer_start(&p_handle);
+ * }
+ * else
+ * {
+ * // Timer failed to create.
+ * return -1;
+ * }
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Timer
+ */
+bool os_timer_delete(void **pp_handle);
+
+/**
+ * os_timer.h
+ *
+ * \brief Dump all current used timers in system.
+ *
+ * \param None
+ *
+ * \return The status of the timer dump.
+ * \retval true Timer was dumped successfully.
+ * \retval false Timer was failed to dump.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // Timer callback function.
+ * void timer_callback(void *p_handle)
+ * {
+ * uint32_t timer_id;
+ *
+ * // Which timer expired?
+ * os_timer_id_get(&p_handle, &timer_id);
+ *
+ * if (timer_id == TIMER_ID)
+ * {
+ * // Delete the specified timer.
+ * os_timer_delete(&p_handle);
+ * }
+ * }
+ *
+ * #define TIMER_ID 1
+ *
+ * // Timer to be created and dumped.
+ * int test(void)
+ * {
+ * void *p_handle = NULL;
+ *
+ * if (os_timer_create(&p_handle, "timer", TIMER_ID,
+ * INTERVAL_MS, false, timer_callback) == true)
+ * {
+ * // Timer created successfully, start the timer.
+ * os_timer_start(&p_handle);
+ * }
+ * else
+ * {
+ * // Timer failed to create.
+ * return -1;
+ * }
+ *
+ * // Dump all used timers.
+ * os_timer_dump();
+ *
+ * return 0;
+ * }
+ * \endcode
+ *
+ * \ingroup Timer
+ */
+bool os_timer_dump(void);
+
+/**
+ * os_timer.h
+ *
+ * \brief get a timer state
+ *
+ * \param[in] pp_handle Pointer to the created timer handle.
+ * \param[out] p_timer_state Used to pass back the timer state.
+ * \arg \c 1 Timer is active.
+ * \arg \c 0 Timer is not active or timer is not created.
+ *
+ * \retval true Timer state was got successfully.
+ * \retval false Timer state was failed to get.
+ * \note A timer will be dormant if:
+ * 1) It has been created but not started, or
+ * 2) It is an expired one-shot timer that has not been restarted.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * // This function assumes the timer has already been created.
+ * void vAFunction( void *p_handle )
+ * {
+ * uint32_t timer_state;
+ * os_timer_state_get(&p_handle,&timer_state);
+ * if(timer_state)
+ * {
+ * // Timer is active, do something.
+ * }
+ * else
+ * {
+ * //Timer is not active, do something else.
+ * }
+ * }
+ * \endcode
+ *
+ * \ingroup Timer
+ */
+
+typedef void (*PendedFunctionOS_t)(void *para1, uint32_t para2);
+
+bool os_timer_state_get(void **pp_handle, uint32_t *p_timer_state);
+
+/* internal function */
+void os_timer_init(void);
+
+bool os_timer_number_get(void **pp_handle, uint32_t *p_timer_num);
+bool os_timer_pendcall(PendedFunctionOS_t xFunctionToPend, void *para1, uint32_t para2,
+ uint32_t xTicksToWait);
+uint32_t os_timer_next_timeout_value_get(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OS_TIMER_H_ */
diff --git a/inc/os/readme b/inc/os/readme
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/inc/os/readme
diff --git a/inc/os/system_trace/system_trace.h b/inc/os/system_trace/system_trace.h
new file mode 100644
index 0000000..b749bca
--- /dev/null
+++ b/inc/os/system_trace/system_trace.h
@@ -0,0 +1,41 @@
+/****************************************************************************************************//**
+ * @file system_trace.h
+ *
+ * @brief
+ *
+ * @version v0.1
+ * @date 2018-11-05
+ *
+ * @note
+ *******************************************************************************************************/
+#ifndef _SYSTEM_TRACE_H_
+#define _SYSTEM_TRACE_H_
+
+#include "app_section.h"
+#include "trace_heap.h"
+#include "trace_stack.h"
+#include "trace_timer.h"
+#include "trace_queue.h"
+#include "trace_dlps.h"
+#include "trace_task_hang.h"
+#include "trace_hardfault.h"
+#include "trace_wdg_timeout.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern HEAP_INFO heap_info[TRACE_HEAP_TYPE_NUM];
+extern STACK_INFO stack_info;
+extern TIMER_INFO timer_info;
+extern QUEUE_INFO queue_info[MAX_QUEUE_OBJECTS_NUM];
+
+extern void system_trace_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_SYSTEM_TRACE_H_*/
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/inc/os/system_trace/trace_common.h b/inc/os/system_trace/trace_common.h
new file mode 100644
index 0000000..6266575
--- /dev/null
+++ b/inc/os/system_trace/trace_common.h
@@ -0,0 +1,55 @@
+/****************************************************************************************************//**
+ * @file trace_common.h
+ *
+ * @brief
+ *
+ * @version v0.1
+ * @date 2018-11-05
+ *
+ * @note
+ *******************************************************************************************************/
+#ifndef _TRACE_COMMON_H_
+#define _TRACE_COMMON_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifndef NULL
+#define NULL (void *)0
+#endif
+
+#define portSTACK_TYPE uint32_t
+#define portBASE_TYPE long
+
+//typedef uint32_t size_t;
+typedef portSTACK_TYPE StackType_t;
+typedef unsigned long UBaseType_t;
+
+typedef struct tskTaskControlBlock
+{
+ uint32_t *pxTopOfStack;
+ uint32_t xGenericListItem[5];
+ uint32_t xEventListItem[5];
+ uint32_t uxPriority;
+ uint32_t *pxStack;
+ char pcTaskName[ 12 ];
+ uint32_t uxTCBNumber;
+ uint32_t uxTaskNumber;
+ uint32_t uxBasePriority;
+ uint32_t uxMutexesHeld;
+} TCB_t;
+
+typedef bool (*BOOL_PATCH_FUNC)();
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_TRACE_COMMON_H_*/
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/inc/os/system_trace/trace_config.h b/inc/os/system_trace/trace_config.h
new file mode 100644
index 0000000..342595c
--- /dev/null
+++ b/inc/os/system_trace/trace_config.h
@@ -0,0 +1,41 @@
+/****************************************************************************************************//**
+ * @file trace_config.h
+ *
+ * @brief
+ *
+ * @version v0.1
+ * @date 2018-11-05
+ *
+ * @note
+ *******************************************************************************************************/
+#ifndef _TRACE_CONFIG_H_
+#define _TRACE_CONFIG_H_
+
+#define TRACE_HEAP_EN 1
+#define TRACE_STACK_EN 1
+#define TRACE_TIMER_EN 1
+#define TRACE_QUEUE_EN 1
+#define DEBUG_TASK_HANG_EN 1
+#define DEBUG_DLPS_ERROR_EN 1
+#define TRACE_HARDFAULT 0
+#define TRACE_WDG_TIMEOUT 0
+#define TRACE_TASK_HANG_USE_WDG_ISR 0
+/******************* CONFIGURATION *******************/
+#define TRACE_PERIOD_TIME ( 10 * 1000 )
+
+/******************* QUEUE CONFIGURATION *******************/
+#define QUEUE_OBJECTS_NUM ( 3 )
+//#define TRACE_QUEUE_PERIOD_TIME ( 10 * 1000 )
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_TRACE_CONFIG_H_*/
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/inc/os/system_trace/trace_cpu_loading.h b/inc/os/system_trace/trace_cpu_loading.h
new file mode 100644
index 0000000..178a091
--- /dev/null
+++ b/inc/os/system_trace/trace_cpu_loading.h
@@ -0,0 +1,27 @@
+/****************************************************************************************************//**
+ * @file trace_cpu_loading.h
+ *
+ * @brief
+ *
+ * @version v0.1
+ * @date 2018-11-05
+ *
+ * @note
+ *******************************************************************************************************/
+#ifndef _TRACE_CPU_LOADING_H_
+#define _TRACE_CPU_LOADING_H_
+
+#include "trace_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_TRACE_CPU_LOADING_H_*/
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/inc/os/system_trace/trace_dlps.h b/inc/os/system_trace/trace_dlps.h
new file mode 100644
index 0000000..701e305
--- /dev/null
+++ b/inc/os/system_trace/trace_dlps.h
@@ -0,0 +1,32 @@
+/****************************************************************************************************//**
+ * @file trace_dlps.h
+ *
+ * @brief
+ *
+ * @version v0.1
+ * @date 2018-11-05
+ *
+ * @note
+ *******************************************************************************************************/
+#ifndef _TRACE_DLPS_H_
+#define _TRACE_DLPS_H_
+
+#include "trace_common.h"
+#include "trace_port_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef bool (*TRACE_DLPS_USER_CB)();
+
+bool trace_dlps_init(uint32_t trace_period_time_ms, uint32_t trace_total_time_ms,
+ TRACE_DLPS_USER_CB trace_dlps_user_cb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_TRACE_DLPS_H_*/
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/inc/os/system_trace/trace_hardfault.h b/inc/os/system_trace/trace_hardfault.h
new file mode 100644
index 0000000..94c9931
--- /dev/null
+++ b/inc/os/system_trace/trace_hardfault.h
@@ -0,0 +1,123 @@
+/****************************************************************************************************//**
+ * @file trace_hardfault.h
+ *
+ * @brief
+ *
+ * @version v0.1
+ * @date 2018-11-05
+ *
+ * @note
+ ****************************************************************************************************/
+
+#ifndef TRACE_HARDFAULT_H
+#define TRACE_HARDFAULT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "trace_common.h"
+#include "trace_port_config.h"
+
+typedef struct
+{
+ uint32_t stacked_r0;
+ uint32_t stacked_r1;
+ uint32_t stacked_r2;
+ uint32_t stacked_r3;
+ uint32_t stacked_r4;
+ uint32_t stacked_r5;
+ uint32_t stacked_r6;
+ uint32_t stacked_r7;
+ uint32_t stacked_r8;
+ uint32_t stacked_r9;
+ uint32_t stacked_r10;
+ uint32_t stacked_r11;
+ uint32_t stacked_r12;
+ uint32_t stacked_lr;
+ uint32_t stacked_pc;
+ uint32_t stacked_psr;
+ uint32_t old_sp;
+ uint32_t msp;
+ uint32_t cfsr;
+ uint32_t bus_fault_address;
+ uint32_t memmanage_fault_address;
+
+ uint32_t PRIMASK;
+ uint32_t BASEPRI;
+ uint32_t EXC_RETURN;
+
+ uint32_t HFSR;
+ uint32_t DFSR;
+ uint32_t AFSR;
+} T_HARDFAULT_RECORD;
+
+/******** magic pattern for hardfault record ********/
+#define HARDFAULT_PATTERN_BEG (0xbeefface)
+#define HARDFAULT_PATTERN_END (0xbabeface)
+#define HARDFAULT_PATTERN_MID (0xdcabface)
+
+extern bool patch_hardfault_save_to_flash_init(void);
+
+/************Dump info: *********
+*********Part0: beg pattern*******************
+4: PATTERN_BEG
+*********Part1: hardfault register record****
+sizeof(*record): hardfault reg info
+4: PATTERN_MID
+*********Part2: Current task stack****
+1024: current task stack
+4: PATTERN_MID
+16: bottom of current task stack
+4: PATTERN_MID
+*********Part3: specific task stack****
+task stack size0: task stack0
+4: PATTERN_MID
+16: bottom of task stack0
+4: PATTERN_MID
+task stack size1: task stack1
+4: PATTERN_MID
+16: bottom of task stack1
+4: PATTERN_MID
+.......
+task stack size n: task stack n
+4: PATTERN_MID
+16: bottom of task stack n
+4: PATTERN_MID
+**********Part4: end pattern*******************
+4: PATTERN_END
+*********************************/
+
+/**
+ * extern void *app_task_handle;
+ * TCB_t *pxTimerTCB =(TCB_t *)xTimerTaskHandle;
+ * TCB_t *pxLowerTCB =(TCB_t *)low_task_handle;
+ * TCB_t *pxUpperTCB =(TCB_t *)upperstack_handle;
+ * TCB_t *pxAppTCB =(TCB_t *)app_task_handle;
+*/
+/**
+ * @brief Initializes trace_hardfault save to flash including critical task stack
+ * @param dump_task_stack_num: number of task
+ * @return if it is successfully initialized , return true
+
+ * For example
+ hardfault_save_to_flash_init(2, &low_task_handle, 1024, &app_task_handle, 1024);
+ @param 2: dump two task stack
+ @param low_task_handle: lowstack task handler value
+ @param 1024: dump task stack size
+ @param app_task_handle: upperstack task handler value
+ @param 1024: dump task stack size
+ @note if need dump app task, must call this api after app task created!!!
+ Upperstack handler address is different when used different upperstack img!
+ */
+void hardfault_save_to_flash_init(uint32_t dump_task_stack_num, ...);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/inc/os/system_trace/trace_heap.h b/inc/os/system_trace/trace_heap.h
new file mode 100644
index 0000000..f53ca67
--- /dev/null
+++ b/inc/os/system_trace/trace_heap.h
@@ -0,0 +1,44 @@
+/****************************************************************************************************//**
+ * @file trace_heap.h
+ *
+ * @brief
+ *
+ * @version v0.1
+ * @date 2018-11-05
+ *
+ * @note
+ *******************************************************************************************************/
+#ifndef _TRACE_HEAP_H_
+#define _TRACE_HEAP_H_
+
+#include "trace_common.h"
+#include "trace_port_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _BLOCK_SIZE_LIST
+{
+ uint32_t number;
+ uint32_t size[TRACE_HEAP_MAX_NUMBER_IN_BLOCK_LIST];
+} BLOCK_SIZE_LIST;
+
+typedef struct _HEAP_INFO
+{
+ uint32_t total_size;
+ uint32_t curr_remain_size;
+ uint32_t minimum_ever_free_size;
+ //BLOCK_SIZE_LIST used_size_list;
+ BLOCK_SIZE_LIST free_size_list;
+} HEAP_INFO;
+
+extern void trace_heap(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_TRACE_HEAP_H_*/
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/inc/os/system_trace/trace_port_config.h b/inc/os/system_trace/trace_port_config.h
new file mode 100644
index 0000000..0aa813c
--- /dev/null
+++ b/inc/os/system_trace/trace_port_config.h
@@ -0,0 +1,66 @@
+/****************************************************************************************************//**
+ * @file trace_port_config.h
+ *
+ * @brief
+ *
+ * @version v0.1
+ * @date 2018-11-05
+ *
+ * @note
+ *******************************************************************************************************/
+#ifndef _TRACE_PORT_CONFIG_H_
+#define _TRACE_PORT_CONFIG_H_
+
+#include "mem_config.h"
+#include "otp.h"
+#include "rtl876x_ic_type.h"
+
+/******************* CPU CONFIGURATION *******************/
+#if (IC_TYPE == IC_TYPE_BEE3)
+#define PLATFORM_SUPPORT_CM4_INSTRUCTIONS 0
+#elif (IC_TYPE == IC_TYPE_SBEE2)
+#define PLATFORM_SUPPORT_CM4_INSTRUCTIONS 1
+#endif
+
+
+/******************* OS CONFIGURATION *******************/
+#define MAX_TASK_COUNT_FOR_DEBUG ( 12 )
+#define configMAX_TASK_NAME_LEN ( 10 )
+
+/******************* HEAP CONFIGURATION *******************/
+
+/* Bee2 has 2 types: data and buffer */
+#define TRACE_HEAP_TYPE_NUM ( 2 )
+#define TRACE_HEAP_MAX_NUMBER_IN_BLOCK_LIST ( 16 )
+
+/******************* STACK CONFIGURATION *******************/
+
+#define MAIN_STACK_START_ADDRESS ( DATA_RAM_START_ADDR + DATA_RAM_ROM_GLOBAL_SIZE ) //the bottom of stack
+
+/******************* TIMER CONFIGURATION *******************/
+
+#define MAX_TIMER_NUM ( otp.os_cfg.timerMaxNumber )
+
+
+/******************* QUEUE CONFIGURATION *******************/
+
+#define MAX_QUEUE_OBJECTS_NUM ( 8 )
+
+/******************* DLPS CONFIGURATION *******************/
+
+
+
+
+/******************* CONFIGURATION END*******************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_TRACE_PORT_CONFIG_H_*/
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/inc/os/system_trace/trace_queue.h b/inc/os/system_trace/trace_queue.h
new file mode 100644
index 0000000..035e889
--- /dev/null
+++ b/inc/os/system_trace/trace_queue.h
@@ -0,0 +1,38 @@
+/****************************************************************************************************//**
+ * @file trace_queue.h
+ *
+ * @brief
+ *
+ * @version v0.1
+ * @date 2018-11-05
+ *
+ * @note
+ *******************************************************************************************************/
+#ifndef _TRACE_QUEUE_H_
+#define _TRACE_QUEUE_H_
+
+#include "trace_common.h"
+#include "trace_port_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _QUEUE_INFO
+{
+ uint16_t capacity_num;
+ uint16_t curr_num_in_queue;
+ uint16_t maximum_ever_num_in_queue;
+ uint16_t reserved;
+} QUEUE_INFO;
+
+extern bool trace_queue_init(uint32_t queue_num, ...);
+extern void trace_queue(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_TRACE_QUEUE_H_*/
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/inc/os/system_trace/trace_stack.h b/inc/os/system_trace/trace_stack.h
new file mode 100644
index 0000000..ce9f113
--- /dev/null
+++ b/inc/os/system_trace/trace_stack.h
@@ -0,0 +1,44 @@
+/****************************************************************************************************//**
+ * @file trace_stack.h
+ *
+ * @brief
+ *
+ * @version v0.1
+ * @date 2018-11-05
+ *
+ * @note
+ *******************************************************************************************************/
+#ifndef _TRACE_STACK_H_
+#define _TRACE_STACK_H_
+
+#include "trace_common.h"
+#include "trace_port_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _TASK_STACK_INFO_BLOCK
+{
+ uint32_t task_id;
+ uint32_t minimum_ever_remain_size;
+ char task_name[configMAX_TASK_NAME_LEN];
+} TASK_STACK_INFO_BLOCK_t;
+
+
+typedef struct _STACK_INFO
+{
+ uint32_t task_number;
+ TASK_STACK_INFO_BLOCK_t task_stack_info[MAX_TASK_COUNT_FOR_DEBUG];
+ uint32_t main_stack_minimum_ever_remain_size;
+} STACK_INFO;
+
+extern void trace_task_stack(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_TRACE_STACK_H_*/
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/inc/os/system_trace/trace_task_hang.h b/inc/os/system_trace/trace_task_hang.h
new file mode 100644
index 0000000..ffe12f7
--- /dev/null
+++ b/inc/os/system_trace/trace_task_hang.h
@@ -0,0 +1,29 @@
+/****************************************************************************************************//**
+ * @file trace_task_hang.h
+ *
+ * @brief
+ *
+ * @version v0.1
+ * @date 2018-11-05
+ *
+ * @note
+ *******************************************************************************************************/
+#ifndef _TRACE_TASK_HANG_H_
+#define _TRACE_TASK_HANG_H_
+
+#include "trace_common.h"
+#include "trace_port_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern bool trace_task_hang_init(uint32_t queue_num, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_TRACE_TASK_HANG_H_*/
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/inc/os/system_trace/trace_task_schedule.h b/inc/os/system_trace/trace_task_schedule.h
new file mode 100644
index 0000000..7ee9f49
--- /dev/null
+++ b/inc/os/system_trace/trace_task_schedule.h
@@ -0,0 +1,27 @@
+/****************************************************************************************************//**
+ * @file trace_task_schedule.h
+ *
+ * @brief
+ *
+ * @version v0.1
+ * @date 2018-11-05
+ *
+ * @note
+ *******************************************************************************************************/
+#ifndef _TRACE_TASK_SCHEDULE_H_
+#define _TRACE_TASK_SCHEDULE_H_
+
+#include "trace_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_TRACE_TASK_SCHEDULE_H_*/
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/inc/os/system_trace/trace_timer.h b/inc/os/system_trace/trace_timer.h
new file mode 100644
index 0000000..8230b72
--- /dev/null
+++ b/inc/os/system_trace/trace_timer.h
@@ -0,0 +1,36 @@
+/****************************************************************************************************//**
+ * @file trace_timer.h
+ *
+ * @brief
+ *
+ * @version v0.1
+ * @date 2018-11-05
+ *
+ * @note
+ *******************************************************************************************************/
+#ifndef _TRACE_TIMER_H_
+#define _TRACE_TIMER_H_
+
+#include "trace_common.h"
+#include "trace_port_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _TIMER_INFO
+{
+ uint16_t curr_used_num;
+ uint16_t minimum_ever_remain_num;
+} TIMER_INFO;
+
+extern bool trace_timer_init(void);
+extern void trace_timer(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_TRACE_TIMER_H_*/
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/inc/os/system_trace/trace_wdg_timeout.h b/inc/os/system_trace/trace_wdg_timeout.h
new file mode 100644
index 0000000..42efcd1
--- /dev/null
+++ b/inc/os/system_trace/trace_wdg_timeout.h
@@ -0,0 +1,47 @@
+/****************************************************************************************************//**
+ * @file trace_wdg_timeout.h
+ *
+ * @brief
+ *
+ * @version v0.1
+ * @date 2018-11-05
+ *
+ * @note
+ ****************************************************************************************************/
+
+#ifndef TRACE_WDG_TIMEOUT_H
+#define TRACE_WDG_TIMEOUT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "trace_common.h"
+#include "trace_port_config.h"
+
+/******** magic pattern for wdg timeout reason record ********/
+#define WDG_TIMEOUT_PATTERN_BEG (0xfdcebaef)
+#define WDG_TIMEOUT_PATTERN_END (0xfcaebaef)
+
+/************Dump info: *********
+4: beg pattern(value=0xfdcebaef)
+4: reset reason(value=0x1)
+4: lr
+4: pc
+4: sp
+80: current TCB
+512 or less: task callstck
+4: end pattern(value=0xfcaebaef)
+*********************************/
+extern void patch_wdg_timeout_reason_save_to_flash_init(void);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/inc/peripheral/readme b/inc/peripheral/readme
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/inc/peripheral/readme
diff --git a/inc/peripheral/rtl876x_3wire_spi.h b/inc/peripheral/rtl876x_3wire_spi.h
new file mode 100644
index 0000000..a03be0f
--- /dev/null
+++ b/inc/peripheral/rtl876x_3wire_spi.h
@@ -0,0 +1,566 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_3wire_spi.h
+* \brief The header file of the peripheral 3-wire SPI driver.
+* \details This file provides all 3-wire SPI firmware functions.
+* \author elliot chen
+* \date 2016-12-13
+* \version v1.0
+* *********************************************************************************************************
+*/
+
+
+#ifndef _RTL876x_3WIRE_SPI_H_
+#define _RTL876x_3WIRE_SPI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup SPI3WIRE SPI 3WIRE
+ *
+ * \brief Manage the SPI 3WIRE peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup THREE_WIRE_SPI_Exported_Types Init Params Struct
+ *
+ * \ingroup SPI3WIRE
+ */
+
+/**
+ * \brief THREE_WIRE_SPI init structure definition.
+ * \ingroup THREE_WIRE_SPI_Exported_Types
+ */
+typedef struct
+{
+ uint32_t SPI3WIRE_SysClock; /**< Specifies system clock. */
+ uint32_t SPI3WIRE_Speed; /**< Specifies 3-wire SPI clock. */
+ uint32_t SPI3WIRE_Mode; /**< Specifies 3-wire SPI operation mode.
+ This parameter can be a value of \ref THREE_WIRE_SPI_Mode */
+ uint32_t SPI3WIRE_ReadDelay; /**< Specifies the delay time from the end of address phase to the start of read data phase.
+ This parameter can be a value of 0x0 to 0x1f, delay time = (SPI3WIRE_ReadDelay+1)/(2*SPI3WIRE_Speed) */
+ uint32_t SPI3WIRE_OutputDelay; /**< Specifies SPI output delay 1T or not.
+ This parameter can be a value of \ref THREE_WIRE_SPI_OE_Delay_Config */
+ uint32_t SPI3WIRE_ExtMode; /**< Specifies extended timing window for SPI output enable = 0. */
+} SPI3WIRE_InitTypeDef;
+
+/*============================================================================*
+ * Register Definitions
+ *============================================================================*/
+
+/* Peripheral: SPI3WIRE */
+/* Description: SPI3WIRE register defines */
+
+/* Register: CFGR ------------------------------------------------------------*/
+/* Description: SPI3WIRE configuration register. Offset: 0x30. Address: 0x40004030. */
+
+/* CFGR[31] :SPI3WIRE_SSI_EN. 0x1: enable SPI3WIRE mode. 0x0: disable SPI3WIRE mode. */
+#define SPI3WIRE_SSI_EN_Pos (31UL)
+#define SPI3WIRE_SSI_EN_Msk (0x1UL << SPI3WIRE_SSI_EN_Pos)
+#define SPI3WIRE_SSI_EN_CLR (~SPI3WIRE_SSI_EN_Msk)
+/* CFGR[30] :SPI3WIRE_SSI_CS_EN. 0x1: enable CS signal. 0x0: disable CS signal. */
+#define SPI3WIRE_SSI_CS_EN_Pos (30UL)
+#define SPI3WIRE_SSI_CS_EN_Msk (0x1UL << SPI3WIRE_SSI_CS_EN_Pos)
+#define SPI3WIRE_SSI_CS_EN_CLR (~SPI3WIRE_SSI_CS_EN_Msk)
+/* CFGR[29] :SPI3WIRE_SSI_END_EXT_EN. 0x1: extend mode. 0x0: normal mode. */
+/* Note: Using this control bit can extend the timing window for SPI output enable = 0, The extend time is 1/(2*SPI_CLK) */
+#define SPI3WIRE_SSI_END_EXT_EN_Pos (29UL)
+#define SPI3WIRE_SSI_END_EXT_EN_Msk (0x1UL << SPI3WIRE_SSI_END_EXT_EN_Pos)
+#define SPI3WIRE_SSI_END_EXT_EN_CLR (~SPI3WIRE_SSI_END_EXT_EN_Msk)
+/* CFGR[28] :SPI3WIRE_SSI_OE_DLY_EN. 0x1: enable. 0x0: disable. */
+/* Note: Extend 1T of ssi_OE(output-> input switch delay 4T->5T ) */
+#define SPI3WIRE_SSI_OE_DLY_EN_Pos (28UL)
+#define SPI3WIRE_SSI_OE_DLY_EN_Msk (0x1UL << SPI3WIRE_SSI_OE_DLY_EN_Pos)
+#define SPI3WIRE_SSI_OE_DLY_EN_CLR (~SPI3WIRE_SSI_OE_DLY_EN_Msk)
+/* CFGR[21] :SPI3WIRE_SSI_RESYNC_TIME. */
+/* output n*T low pulse, write 1 to 0x38 bit[31] to output;The T time is 1/(2*ssi_CLK) */
+#define SPI3WIRE_SSI_RESYNC_TIME_Pos (21UL)
+#define SPI3WIRE_SSI_RESYNC_TIME_Msk (0xfUL << SPI3WIRE_SSI_RESYNC_TIME_Pos)
+#define SPI3WIRE_SSI_RESYNC_TIME_CLR (~SPI3WIRE_SSI_RESYNC_TIME_Msk)
+/* CFGR[20] :SPI3WIRE_SSI_BURST_READ_EN. 0x1: enable burst read. 0x0: disable. */
+#define SPI3WIRE_SSI_BURST_READ_EN_Pos (20UL)
+#define SPI3WIRE_SSI_BURST_READ_EN_Msk (0x1UL << SPI3WIRE_SSI_BURST_READ_EN_Pos)
+#define SPI3WIRE_SSI_BURST_READ_EN_CLR (~SPI3WIRE_SSI_BURST_READ_EN_Msk)
+/* CFGR[16] :SPI3WIRE_SSI_BURST_READ_NUM. The total number of read data bytes in burst mode */
+#define SPI3WIRE_SSI_BURST_READ_NUM_Pos (16UL)
+#define SPI3WIRE_SSI_BURST_READ_NUM_Msk (0xfUL << SPI3WIRE_SSI_BURST_READ_NUM_Pos)
+#define SPI3WIRE_SSI_BURST_READ_NUM_CLR (~SPI3WIRE_SSI_BURST_READ_NUM_Msk)
+/* CFGR[8] :SPI3WIRE_SSI_DIV_NUM. The divider number to generate 2x SPI_CLK */
+#define SPI3WIRE_SSI_DIV_NUM_Pos (8UL)
+#define SPI3WIRE_SSI_DIV_NUM_Msk (0xffUL << SPI3WIRE_SSI_DIV_NUM_Pos)
+#define SPI3WIRE_SSI_DIV_NUM_CLR (~SPI3WIRE_SSI_DIV_NUM_Msk)
+/* CFGR[3] :SPI3WIRE_SSI_DLY_CYCLE. The delay time from the end of address phase to the start of read data phase. */
+#define SPI3WIRE_SSI_DLY_CYCLE_Pos (3UL)
+#define SPI3WIRE_SSI_DLY_CYCLE_Msk (0x1fUL << SPI3WIRE_SSI_DLY_CYCLE_Pos)
+#define SPI3WIRE_SSI_DLY_CYCLE_CLR (~SPI3WIRE_SSI_DLY_CYCLE_Msk)
+/* CFGR[1] :SPI3WIRE_SSI_INT_MASK. 0x1: mask. 0x0: no mask. */
+#define SPI3WIRE_SSI_INT_MASK_Pos (1UL)
+#define SPI3WIRE_SSI_INT_MASK_Msk (0x1UL << SPI3WIRE_SSI_INT_MASK_Pos)
+#define SPI3WIRE_SSI_INT_MASK_CLR (~SPI3WIRE_SSI_INT_MASK_Msk)
+/* CFGR[0] :SPI3WIRE_SSI_INT_EN. 0x1: enable. 0x0: disable. */
+#define SPI3WIRE_SSI_INT_EN_Pos (0UL)
+#define SPI3WIRE_SSI_INT_EN_Msk (0x1UL << SPI3WIRE_SSI_INT_EN_Pos)
+#define SPI3WIRE_SSI_INT_EN_CLR (~SPI3WIRE_SSI_INT_EN_Msk)
+
+/* Register: CR ------------------------------------------------------------*/
+/* Description: SPI3WIRE control register. Offset: 0x34. Address: 0x40004034. */
+
+/* CR[15] :SPI3WIRE_RW_MODE. 0x1: write mode. 0x0: read mode. */
+#define SPI3WIRE_RW_MODE_Pos (15UL)
+#define SPI3WIRE_RW_MODE_Msk (0x1UL << SPI3WIRE_RW_MODE_Pos)
+#define SPI3WIRE_RW_MODE_CLR (~SPI3WIRE_RW_MODE_Msk)
+/* CR[8] :SPI3WIRE_ADDRESS. */
+#define SPI3WIRE_ADDRESS_Pos (8UL)
+#define SPI3WIRE_ADDRESS_Msk (0x7fUL << SPI3WIRE_ADDRESS_Pos)
+#define SPI3WIRE_ADDRESS_CLR (~SPI3WIRE_ADDRESS_Msk)
+/* CR[0] :SPI3WIRE_DATA. write data ; in read mode, this data byte is useless */
+#define SPI3WIRE_DATA_Pos (0UL)
+#define SPI3WIRE_DATA_Msk (0xffUL << SPI3WIRE_ADDRESS_Pos)
+#define SPI3WIRE_DATA_CLR (~SPI3WIRE_ADDRESS_Msk)
+
+/* Register: INTCR ------------------------------------------------------------*/
+/* Description: SPI3WIRE interrupt clear register. Offset: 0x38. Address: 0x40004038. */
+
+/* INTCR[31] :SPI3WIRE_RESYNV_EN. 0x1: trriger resync signal. 0x0: disable resync signal. */
+#define SPI3WIRE_RESYNV_EN_Pos (30UL)
+#define SPI3WIRE_RESYNV_EN_Msk (0x1UL << SPI3WIRE_RESYNV_EN_Pos)
+#define SPI3WIRE_RESYNV_EN_CLR (~SPI3WIRE_RESYNV_EN_Msk)
+/* INTCR[2] :SPI3WIRE_RD_DATA_CLEAR. 0x1: write clear. */
+#define SPI3WIRE_RD_DATA_CLEAR_Pos (2UL)
+#define SPI3WIRE_RD_DATA_CLEAR_Msk (0x1UL << SPI3WIRE_RD_DATA_CLEAR_Pos)
+/* INTCR[1] :SPI3WIRE_RD_NUM_CLEAR. 0x1: write clear. */
+#define SPI3WIRE_RD_NUM_CLEAR_Pos (1UL)
+#define SPI3WIRE_RD_NUM_CLEAR_Msk (0x1UL << SPI3WIRE_RD_NUM_CLEAR_Pos)
+/* INTCR[0] :SPI3WIRE_INT_CLEAR. 0x1: write clear. */
+#define SPI3WIRE_INT_CLEAR_Pos (0UL)
+#define SPI3WIRE_INT_CLEAR_Msk (0x1UL << SPI3WIRE_INT_CLEAR_Pos)
+
+#define SPI3WIRE_FIFO_INT_ALL_CLR (SPI3WIRE_RD_DATA_CLEAR_Msk | \
+ SPI3WIRE_RD_NUM_CLEAR_Msk | \
+ SPI3WIRE_INT_CLEAR_Msk)
+
+/* Register: SR ------------------------------------------------------------*/
+/* Description: SPI3WIRE status register. Offset: 0x3C. Address: 0x4000403C. */
+
+/* SR[6] :SPI3WIRE_RESYNV_BUSY. 0x1: Resync busy. 0x0: Resync idle. */
+#define SPI3WIRE_RESYNV_BUSY_Pos (6UL)
+#define SPI3WIRE_RESYNV_BUSY_Msk (0x1UL << SPI3WIRE_RESYNV_BUSY_Pos)
+#define SPI3WIRE_RESYNV_BUSY_CLR (~SPI3WIRE_RESYNV_BUSY_Msk)
+/* SR[5] :SPI3WIRE_INT_STATUS. 0x1: Interrupt. 0x0: No interrupt. */
+#define SPI3WIRE_INT_STATUS_Pos (5UL)
+#define SPI3WIRE_INT_STATUS_Msk (0x1UL << SPI3WIRE_INT_STATUS_Pos)
+#define SPI3WIRE_INT_STATUS_CLR (~SPI3WIRE_INT_STATUS_Msk)
+/* SR[4] :SPI3WIRE_BUSY. 0x1: Busy. 0x0:Idle. */
+#define SPI3WIRE_BUSY_Pos (4UL)
+#define SPI3WIRE_BUSY_Msk (0x1UL << SPI3WIRE_BUSY_Pos)
+#define SPI3WIRE_BUSY_CLR (~SPI3WIRE_BUSY_Msk)
+/* SR[0] :SPI3WIRE_RDATA_NUM. The total number of data byte in each SPI read transaction */
+#define SPI3WIRE_RDATA_NUM_Pos (0UL)
+#define SPI3WIRE_RDATA_NUM_Msk (0xfUL << SPI3WIRE_RDATA_NUM_Pos)
+#define SPI3WIRE_RDATA_NUM_CLR (~SPI3WIRE_RDATA_NUM_Msk)
+
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup THREE_WIRE_SPI_Exported_Constants Macro Definitions
+ *
+ * \ingroup SPI3WIRE
+ */
+
+/**
+ * \defgroup THREE_WIRE_SPI_Mode 3WIRE SPI Mode
+ * \{
+ * \ingroup THREE_WIRE_SPI_Exported_Constants
+ */
+#define SPI3WIRE_2WIRE_MODE ((uint32_t)(0 << SPI3WIRE_SSI_CS_EN_Pos))
+#define SPI3WIRE_3WIRE_MODE ((uint32_t)(1 << SPI3WIRE_SSI_CS_EN_Pos))
+/** \} */
+#define IS_SPI3WIRE_MODE(MODE) ((MODE) == SPI3WIRE_2WIRE_MODE || (MODE) == SPI3WIRE_3WIRE_MODE)
+
+/**
+ * \defgroup THREE_WIRE_SPI_OE_Delay_Config 3WIRE SPI OE Delay Config
+ * \{
+ * \ingroup THREE_WIRE_SPI_Exported_Constants
+ */
+#define SPI3WIRE_OE_DELAY_NONE ((uint32_t)(0 << SPI3WIRE_SSI_OE_DLY_EN_Pos))
+#define SPI3WIRE_OE_DELAY_1T ((uint32_t)(1 << SPI3WIRE_SSI_OE_DLY_EN_Pos))
+/** \} */
+#define IS_SPI3WIRE_OE_DELAY_CFG(CFG) ((CFG) == SPI3WIRE_OE_DELAY_1T || (CFG) == SPI3WIRE_OE_DELAY_NONE)
+
+/**
+ * \defgroup THREE_WIRE_SPI_End_Extend_Mode 3WIRE SPI End Extend Mode
+ * \{
+ * \ingroup THREE_WIRE_SPI_Exported_Constants
+ */
+#define SPI3WIRE_NORMAL_MODE ((uint32_t)(0 << SPI3WIRE_SSI_END_EXT_EN_Pos))
+#define SPI3WIRE_EXTEND_MODE ((uint32_t)(1 << SPI3WIRE_SSI_END_EXT_EN_Pos))
+/** \} */
+#define IS_SPI3WIRE_END_EXTEND_MODE(MODE) ((MODE) == SPI3WIRE_EXTEND_MODE || (MODE) == SPI3WIRE_NORMAL_MODE)
+
+/**
+ * \brief THREE_WIRE_SPI_Read_Cycle_Delay
+ */
+#define IS_SPI3WIRE_READ_CYCLE_DELAY(DELAY) (DELAY <= 0x1f)
+
+/**
+ * \defgroup THREE_WIRE_SPI_FLAG 3WIRE SPI FLAG
+ * \{
+ * \ingroup THREE_WIRE_SPI_Exported_Constants
+ */
+#define SPI3WIRE_FLAG_BUSY ((uint32_t)SPI3WIRE_BUSY_Msk)
+#define SPI3WIRE_FLAG_INT_IND ((uint32_t)SPI3WIRE_INT_STATUS_Msk)
+#define SPI3WIRE_FLAG_RESYNC_BUSY ((uint32_t)SPI3WIRE_RESYNV_BUSY_Msk)
+/** \} */
+#define IS_SPI3WIRE_FLAG(FLAG) (((FLAG) == SPI3WIRE_FLAG_BUSY) || \
+ ((FLAG) == SPI3WIRE_FLAG_INT_IND) || \
+ ((FLAG) == SPI3WIRE_FLAG_RESYNC_BUSY))
+
+/**
+ * \defgroup THREE_WIRE_SPI_Interrupt_Definition 3WIRE SPI Interrupt Definition
+ * \{
+ * \ingroup THREE_WIRE_SPI_Exported_Constants
+ */
+#define SPI3WIRE_INT_BIT ((uint32_t)SPI3WIRE_SSI_INT_EN_Msk)
+/** \} */
+#define IS_SPI3WIRE_INT(INT) ((INT) == SPI3WIRE_INT_BIT)
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup THREE_WIRE_SPI_Exported_Functions Peripheral APIs
+ * \{
+ * \ingroup SPI3WIRE
+ */
+
+/**
+ * \brief Deinitializes the 3WIRE SPI peripheral registers to their default reset values.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_spi3wire_init(void)
+ * {
+ * SPI3WIRE_DeInit();
+ * }
+ * \endcode
+ */
+void SPI3WIRE_DeInit(void);
+
+/**
+ * \brief Initializes the 3-wire SPI peripheral according to the specified
+ * parameters in SPI3WIRE_InitStruct
+ * \param[in] SPI3WIRE_InitStruct: Pointer to a SPI3WIRE_InitTypeDef structure that
+ * contains the configuration information for the specified 3-wire SPI peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_spi3wire_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_SPI2W, APBPeriph_SPI2W_CLOCK, ENABLE);
+ * SPI3WIRE_InitTypeDef SPI3WIRE_InitStruct;
+ * SPI3WIRE_StructInit(&SPI3WIRE_InitStruct);
+ * SPI3WIRE_InitStruct.SPI3WIRE_Speed = 2000000;
+ * SPI3WIRE_InitStruct.SPI3WIRE_Mode = SPI3WIRE_3WIRE_MODE;
+ * SPI3WIRE_InitStruct.SPI3WIRE_ReadDelay = 0x1f;
+ * SPI3WIRE_InitStruct.SPI3WIRE_OutputDelay = SPI3WIRE_OE_DELAY_1T;
+ * SPI3WIRE_InitStruct.SPI3WIRE_ExtMode = SPI3WIRE_EXTEND_MODE;
+ * SPI3WIRE_Init(&SPI3WIRE_InitStruct);
+ * }
+ * \endcode
+ */
+void SPI3WIRE_Init(SPI3WIRE_InitTypeDef *SPI3WIRE_InitStruct);
+
+/**
+ * \brief Fills each SPI3WIRE_InitStruct member with its default value.
+ * \param[in] SPI3WIRE_InitStruct: Pointer to an SPI3WIRE_InitTypeDef structure which will be initialized.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_spi3wire_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_SPI2W, APBPeriph_SPI2W_CLOCK, ENABLE);
+ * SPI3WIRE_InitTypeDef SPI3WIRE_InitStruct;
+ * SPI3WIRE_StructInit(&SPI3WIRE_InitStruct);
+ * SPI3WIRE_InitStruct.SPI3WIRE_SysClock = 20000000;
+ * SPI3WIRE_InitStruct.SPI3WIRE_Speed = 800000;
+ * SPI3WIRE_InitStruct.SPI3WIRE_Mode = SPI3WIRE_2WIRE_MODE;
+ * SPI3WIRE_Init(SPI3WIRE);
+ * }
+ * \endcode
+ */
+void SPI3WIRE_StructInit(SPI3WIRE_InitTypeDef *SPI3WIRE_InitStruct);
+
+/**
+ * \brief Enables or disables the specified SPI3WIRE peripheral.
+ * \param[in] NewState: New state of the SPI3WIRE peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_spi3wire_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_SPI2W, APBPeriph_SPI2W_CLOCK, ENABLE);
+ * SPI3WIRE_InitTypeDef SPI3WIRE_InitStruct;
+ * SPI3WIRE_StructInit(&SPI3WIRE_InitStruct);
+ * SPI3WIRE_InitStruct.SPI3WIRE_SysClock = 20000000;
+ * SPI3WIRE_InitStruct.SPI3WIRE_Speed = 800000;
+ * SPI3WIRE_InitStruct.SPI3WIRE_Mode = SPI3WIRE_2WIRE_MODE;
+ * SPI3WIRE_Init(SPI3WIRE);
+ * SPI3WIRE_Cmd(ENABLE);
+ * }
+ * \endcode
+ */
+void SPI3WIRE_Cmd(FunctionalState NewState);
+
+/**
+ * \brief Enables or disables the specified SPI3WIRE interrupts.
+ * \param[in] SPI3WIRE_INT: Specifies the SPI3WIRE interrupts sources to be enabled or disabled.
+ * This parameter can be only be the following value:
+ * \arg SPI3WIRE_INT_BIT: Enable SPI3WIRE interrupt.
+ * \param[in] newState: New state of the specified SPI3WIRE interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_spi3wire_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_SPI2W, APBPeriph_SPI2W_CLOCK, ENABLE);
+ * SPI3WIRE_InitTypeDef SPI3WIRE_InitStruct;
+ * SPI3WIRE_StructInit(&SPI3WIRE_InitStruct);
+ * SPI3WIRE_InitStruct.SPI3WIRE_SysClock = 20000000;
+ * SPI3WIRE_InitStruct.SPI3WIRE_Speed = 800000;
+ * SPI3WIRE_InitStruct.SPI3WIRE_Mode = SPI3WIRE_2WIRE_MODE;
+ * SPI3WIRE_Init(SPI3WIRE);
+ * SPI3WIRE_INTConfig(SPI3WIRE_INT_BIT, ENABLE);
+ * }
+ * \endcode
+ */
+void SPI3WIRE_INTConfig(uint32_t SPI3WIRE_INT, FunctionalState newState);
+
+/**
+ * \brief Configure resync signal time value.
+ * \param[in] value: Resync signal time value whose uint is 1/(2*SPI3WIRE_Speed).
+ * This parameter can be only be the following value: 0x0 to 0xf.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi3wire_demo(void)
+ * {
+ * SPI3WIRE_SetResyncTime(10);
+ * }
+ * \endcode
+ */
+void SPI3WIRE_SetResyncTime(uint32_t value);
+
+/**
+ * \brief Send resync signal or not. Must send when SPI3WIRE is disable.
+ * \param[in] NewState: New state of the SPI3WIRE peripheral.
+ * This parameter can be only be the following value:
+ * \arg ENABLE: Trigger resync signal.
+ * \arg DISABLE: Disable resync signal.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi3wire_demo(void)
+ * {
+ * SPI3WIRE_ResyncSignalCmd(ENABLE);
+ * }
+ * \endcode
+ */
+void SPI3WIRE_ResyncSignalCmd(FunctionalState NewState);
+
+/**
+ * \brief Get total number of data byte in each SPI reading.
+ * \param[in] None.
+ * \return The total number of data byte in each SPI reading.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi3wire_demo(void)
+ * {
+ * uint8_t data_len = 0;
+ * data_len = SPI3WIRE_GetRxDataLen();
+ * }
+ * \endcode
+ */
+uint8_t SPI3WIRE_GetRxDataLen(void);
+
+/**
+ * \brief Clear read data number status.
+ * \param[in] None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi3wire_demo(void)
+ * {
+ * SPI3WIRE_ClearRxDataLen();
+ * }
+ * \endcode
+ */
+void SPI3WIRE_ClearRxDataLen(void);
+
+/**
+ * \brief Clear all read data registers.
+ * \param[in] None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi3wire_demo(void)
+ * {
+ * SPI3WIRE_ClearRxFIFO();
+ * }
+ * \endcode
+ */
+void SPI3WIRE_ClearRxFIFO(void);
+
+/**
+ * \brief Start to write data.
+ * \param[in] address: Write address.
+ * \param[in] data: Write data.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi3wire_demo(void)
+ * {
+ * uint8_t address = 0x10;
+ * uint8_t data = 0x10;
+ * SPI3WIRE_StartWrite(address, data);
+ * }
+ * \endcode
+ */
+void SPI3WIRE_StartWrite(uint8_t address, uint8_t data);
+
+/**
+ * \brief Start read.
+ * \param[in] address: Read address.
+ * \param[in] len: Number of data to read. This value can be 0x1 to 0xf.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi3wire_demo(void)
+ * {
+ * uint8_t address = 0x10;
+ * uint8_t len = 0x1;
+ * SPI3WIRE_StartRead(address, len);
+ * }
+ * \endcode
+ */
+void SPI3WIRE_StartRead(uint8_t address, uint32_t len);
+
+/**
+ * \brief Read data.
+ * \param[in] pBuf: Buffer to store read datas.
+ * \param[in] readNum: Read number.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi3wire_demo(void)
+ * {
+ * uint8_t data_buf[10] = {0};
+ * uint8_t data_len = 10;
+ * SPI3WIRE_ReadBuf(data_buf, data_len);
+ * }
+ * \endcode
+ */
+void SPI3WIRE_ReadBuf(uint8_t *pBuf, uint8_t readNum);
+
+/**
+ * \brief Check whether the specified 3-wire SPI flag is set.
+ * \param[in] SPI3WIRE_FLAG: Specify flags to check.
+ * This parameter can be one of the following values:
+ * \arg SPI3WIRE_FLAG_BUSY: 3-wire SPI is busy.
+ * \arg SPI3WIRE_FLAG_INT_IND: There is 3-wire SPI interrupt.
+ * \arg SPI3WIRE_FLAG_RESYNC_BUSY: Resync busy or not.
+ * \return The new state of the specified 3-wire SPI flag.
+ * \retval SET: The specified 3-wire SPI flag state is pending.
+ * \retval RESET: The specified 3-wire SPI flag state is not pending.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi3wire_demo(void)
+ * {
+ * FlagStatus flag_status = RESET;
+ * flag_status = SPI3WIRE_GetFlagStatus(SPI3WIRE_FLAG_BUSY);
+ * }
+ * \endcode
+ */
+FlagStatus SPI3WIRE_GetFlagStatus(uint32_t SPI3WIRE_FLAG);
+
+/**
+ * \brief Clear the 3-wire SPI interrupt pending bit.
+ * \param[in] SPI3WIRE_INT: Specify the 3-wire SPI interrupt source to enable or disable.
+ * This parameter can only be the following values:
+ * \arg SPI3WIRE_INT_BIT: Enable 3-wire SPI interrupt source.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi3wire_demo(void)
+ * {
+ * SPI3WIRE_ClearINTPendingBit(SPI3WIRE_INT_BIT);
+ * }
+ * \endcode
+ */
+
+void SPI3WIRE_ClearINTPendingBit(uint32_t SPI3WIRE_INT);
+
+/** \} */ /* End of group THREE_WIRE_SPI_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL8762_3WIRE_SPI_H_ */
+
+
+/******************* (C) COPYRIGHT 2016 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/inc/peripheral/rtl876x_adc.h b/inc/peripheral/rtl876x_adc.h
new file mode 100644
index 0000000..a4e5df6
--- /dev/null
+++ b/inc/peripheral/rtl876x_adc.h
@@ -0,0 +1,926 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_adc.h
+* \brief The header file of the peripheral ADC driver.
+* \details This file provides all ADC firmware functions.
+* \author yuan
+* \date 2020-05-28
+* \version v2.1.0
+* *********************************************************************************************************
+*/
+
+
+#ifndef _RTL876X_ADC_H_
+#define _RTL876X_ADC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup ADC ADC
+ *
+ * \brief Manage the ADC peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+#include "rtl876x_alias.h"
+#include "platform_utils.h"
+#include "adc_lib.h"
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup ADC_Exported_Types Init Params Struct
+ *
+ * \ingroup ADC
+ */
+
+/**
+ * \brief ADC init structure definition.
+ *
+ * \ingroup ADC_Exported_Types
+ */
+typedef struct
+{
+ uint32_t ADC_SampleTime; /**< Specifies the ADC sample clock, adc_sample_period = (n+1) cycles from 10MHz.
+ This parameter can be a value of 0 to 16383. */
+ uint32_t ADC_ConvertTime; /**< Specifies the ADC Sample convert time.
+ This parameter can be a value of \ref ADC_Convert_Time*/
+ uint32_t ADC_DataWriteToFifo; /**< Enable or disable writing ADC sampling data to FIFO in one shot mode.
+ This parameter can be a value of \ref ADC_Data_Write_To_Fifo*/
+ uint32_t ADC_FifoThdLevel; /**< Specifies the ADC FIFO threshold to trigger \ref ADC_INT_FIFO_THD interrupt.
+ This parameter can be a value of 0 to 31. */
+ uint32_t ADC_WaterLevel; /**< Specifies the ADC FIFO burst size to trigger GDMA.
+ This parameter can be a value of 0 to 31. */
+ uint32_t ADC_FifoOverWriteEn; /**< Specifies if over write FIFO when FIFO overflow.
+ This parameter can be a value of \ref ADC_Over_Write_Enable. */
+ uint32_t ADC_DataLatchEdge; /**< Specifies ADC data latch edge.
+ This parameter can be a value of \ref ADC_Latch_Data_Edge. */
+ uint16_t ADC_SchIndex[16]; /**< Specifies ADC mode and channel for schedule table.
+ This parameter can be a value of \ref ADC_Schedule_Table. */
+ uint16_t ADC_Bitmap; /**< Specifies the schedule table channel map.
+ This parameter can be a value of 16-bit map. */
+ uint32_t ADC_DataAlign; /**< ADC data MSB or LSB aligned. */
+ uint32_t ADC_DataMinusEn; /**< Enable or disable function that adc data latched minus the given offset before writes to reg/FIFO. */
+ uint32_t ADC_DataMinusOffset; /**< Offset to be minused from adc data latched. */
+ uint32_t ADC_DataAvgSel; /**< Number of data for calculate average.
+ This parameter can be a value of \ref ADC_Data_Avg_Num. */
+ uint32_t ADC_DataAvgEn; /**< Enable the calculation for average result of the one-shot data.
+ This parameter can be a value of \ref ADC_Data_Avg_En. */
+ uint32_t ADC_PowerOnMode; /**< Specifies ADC power on mode.
+ This parameter can be a value of \ref ADC_Power_On_Mode. */
+ uint32_t ADC_PowerAlwaysOnEn; /**< Specifies the power always on.
+ This parameter can be a value of \ref ADC_Power_Always_On_Cmd. */
+ uint32_t ADC_DataLatchDly; /**< Specifies delay of ck_ad to latch data.*/
+ uint32_t ADC_RG2X0Dly; /**< Specifies the power on delay time selection of RG2X_AUXADC[0].
+ This parameter can be a value of \ref ADC_RG2X_0_Delay_Time */
+ uint32_t ADC_RG0X1Dly; /**< Specifies the power on delay time selection of RG0X_AUXADC[1].
+ This parameter can be a value of \ref ADC_RG0X_1_Delay_Time */
+ uint32_t ADC_RG0X0Dly; /**< Specifies the power on delay time selection of RG0X_AUXADC[0].
+ This parameter can be a value of \ref ADC_RG0X_0_Delay_Time */
+} ADC_InitTypeDef;
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup ADC_Exported_Constants Macro Definitions
+ * \ingroup ADC
+ */
+
+#define MAX_ADC_SCH_NUM 8
+
+#define IS_ADC_PERIPH(PERIPH) ((PERIPH) == ADC)
+
+/** \defgroup ADC_Data_Write_To_Fifo Write DATA To FIFO
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+#define ADC_DATA_WRITE_TO_FIFO_DISABLE ((uint32_t)(0 << 27))
+#define ADC_DATA_WRITE_TO_FIFO_ENABLE ((uint32_t)(1 << 27))
+/** \} */
+
+#define IS_ADC_DATA_WRITE_TO_FIFO_CMD(CMD) (((CMD) == ADC_DATA_WRITE_TO_FIFO_DISABLE) || ((CMD) == ADC_DATA_WRITE_TO_FIFO_ENABLE))
+
+/**
+ * \def ADC_FIFO_Threshold ADC FIFO Threshold
+ */
+#define IS_ADC_FIFO_THRESHOLD(THD) ((THD) <= 0x3F)
+
+/**
+ * \def ADC_Burst_Size ADC Burst Size
+ */
+#define IS_ADC_WATER_LEVEL_CONFIG(CONFIG) ((CONFIG) <= 0x3F)
+
+/**
+ * \defgroup ADC_Over_Write_Enable ADC FIFO Over Write
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+#define ADC_FIFO_OVER_WRITE_DISABLE ((uint32_t)(0 << 13))
+#define ADC_FIFO_OVER_WRITE_ENABLE ((uint32_t)(1 << 13))
+/** \} */
+
+#define IS_ADC_OVERWRITE_MODE(MODE) (((MODE) == ADC_FIFO_OVER_WRITE_DISABLE) || ((MODE) == ADC_FIFO_OVER_WRITE_ENABLE))
+
+/**
+ * \defgroup ADC_Latch_Data_Edge ADC Latch Data Edge
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+#define ADC_LATCH_DATA_Positive ((uint32_t)(0 << 2))
+#define ADC_LATCH_DATA_Negative ((uint32_t)(1 << 2))
+/** \} */
+
+#define IS_ADC_LATCH_DATA_EDGE(EDGE) (((EDGE) == ADC_LATCH_DATA_Positive) || ((EDGE) == ADC_LATCH_DATA_Negative))
+
+/**
+ * \defgroup ADC_Operation_Mode ADC Operation Mode
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+
+#define ADC_CONTINUOUS_MODE ((uint32_t)(1 << 0))
+#define ADC_ONE_SHOT_MODE ((uint32_t)(1 << 1))
+/** \} */
+
+#define IS_ADC_SAMPLE_MODE(MODE) (((MODE) == ADC_CONTINUOUS_MODE) || ((MODE) == ADC_ONE_SHOT_MODE))
+
+/**
+ * \defgroup ADC_Interrupts_Definition ADC Interrupts Definition
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+
+#define ADC_INT_FIFO_RD_REQ ((uint32_t)(1 << 0))
+#define ADC_INT_FIFO_RD_ERR ((uint32_t)(1 << 1))
+#define ADC_INT_FIFO_THD ((uint32_t)(1 << 2))
+#define ADC_INT_FIFO_OVERFLOW ((uint32_t)(1 << 3))
+#define ADC_INT_ONE_SHOT_DONE ((uint32_t)(1 << 4))
+/** \} */
+
+//#define IS_ADC_INT(INT) ((((INT) & 0xFFFFFFE0) == 0x00) && ((INT) != 0x00))
+
+#define IS_ADC_INT(INT) (((INT) == ADC_INT_FIFO_RD_REQ) || ((INT) == ADC_INT_FIFO_RD_ERR)\
+ || ((INT) == ADC_INT_FIFO_THD) || ((INT) == ADC_INT_FIFO_OVERFLOW)\
+ || ((INT) == ADC_INT_ONE_SHOT_DONE))
+
+/**
+ * \defgroup ADC_Schedule_Table ADC Channel and Mode
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+#define EXT_SINGLE_ENDED(index) ((uint16_t)((0x00 << 3) | (index)))
+#define EXT_DIFFERENTIAL(index) ((uint16_t)((0x01 << 3) | (index)))
+#define INTERNAL_VBAT_MODE ((uint16_t)((0x02 << 3) | 0x00))
+#define EXT_CTC(index) ((uint16_t)((0x03 << 3) | (index)))
+/** \} */
+
+#define SCHEDULE_TABLE(index) (index)
+#define IS_ADC_SCHEDULE_INDEX_CONFIG(CONFIG) ((((CONFIG) & 0xFFE0) == 0) && ((((~(CONFIG)) & (0x18)) != 0)\
+ || ((CONFIG) == INTERNAL_VBAT_MODE)))
+
+/**
+ * \defgroup ADC_Data_Avg_Num ADC Data Averge Num
+ * \{
+ * \brief Number of raw data for calculate average.
+ * \ingroup ADC_Exported_Constants
+ */
+
+#define ADC_DATA_AVERAGE_OF_2 ((uint32_t)(0 << 25))
+#define ADC_DATA_AVERAGE_OF_4 ((uint32_t)(1 << 25))
+#define ADC_DATA_AVERAGE_OF_8 ((uint32_t)(2 << 25))
+#define ADC_DATA_AVERAGE_OF_16 ((uint32_t)(3 << 25))
+#define ADC_DATA_AVERAGE_OF_32 ((uint32_t)(4 << 25))
+#define ADC_DATA_AVERAGE_OF_64 ((uint32_t)(5 << 25))
+#define ADC_DATA_AVERAGE_OF_128 ((uint32_t)(6 << 25))
+#define ADC_DATA_AVERAGE_OF_256 ((uint32_t)(7 << 25))
+/** \} */
+
+#define IS_ADC_DATA_AVG_NUM(NUM) (((NUM) == ADC_DATA_AVERAGE_OF_2) ||\
+ ((NUM) == ADC_DATA_AVERAGE_OF_4) ||\
+ ((NUM) == ADC_DATA_AVERAGE_OF_8) ||\
+ ((NUM) == ADC_DATA_AVERAGE_OF_16) ||\
+ ((NUM) == ADC_DATA_AVERAGE_OF_32) ||\
+ ((NUM) == ADC_DATA_AVERAGE_OF_64) ||\
+ ((NUM) == ADC_DATA_AVERAGE_OF_128) ||\
+ ((NUM) == ADC_DATA_AVERAGE_OF_256))
+
+/**
+ * \defgroup ADC_Data_Avg_En ADC Data Average Enable
+ * \brief Enable the calculation for average result of the one-shot mode.
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+#define ADC_DATA_AVERAGE_DISABLE ((uint32_t)(0 << 24))
+#define ADC_DATA_AVERAGE_ENABLE ((uint32_t)(1 << 24))
+/** \} */
+
+#define IS_ADC_DATA_AVG_EN(CMD) (((CMD) == ADC_DATA_AVERAGE_DISABLE) || ((CMD) == ADC_DATA_AVERAGE_ENABLE))
+
+/**
+ * \defgroup ADC_Power_On_Mode ADC Power On Mode
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+
+#define ADC_POWER_ON_AUTO ((uint32_t)(0 << 19))
+#define ADC_POWER_ON_MANUAL ((uint32_t)(1 << 19))
+/** \} */
+
+#define IS_ADC_POWER_ON_MODE(MODE) (((MODE) == ADC_POWER_ON_AUTO) || ((MODE) == ADC_POWER_ON_MANUAL))
+
+/**
+ * \brief ADC set power on procedure.
+ */
+#define IS_ADC_POWER_ON_PROCEDURE(CONFIG) (((CONFIG) == ADC_POWERON_VBAT) || ((CONFIG) == ADC_POWERON_VA11)\
+ || ((CONFIG) == ADC_POWERON_RG1X_AUXADC_12) || ((CONFIG) == ADC_POWERON_RG2X_AUXADC_3))\
+|| ((CONFIG) == ADC_POWERON_ERC_VA11) || ((CONFIG) == ADC_POWERON_RG2X_AUXADC_0))\
+|| ((CONFIG) == ADC_POWERON_VA18) || ((CONFIG) == ADC_POWERON_RG0X_AUXADC_1))\
+|| ((CONFIG) == ADC_POWERON_RG0X_AUXADC_0)))
+
+/**
+ * \defgroup ADC_RG2X_0_Delay_Time ADC RG2X_0 Delay Time
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+#define ADC_RG2X_0_DELAY_10_US ((uint32_t)(0 << 4))
+#define ADC_RG2X_0_DELAY_20_US ((uint32_t)(1 << 4))
+#define ADC_RG2X_0_DELAY_40_US ((uint32_t)(2 << 4))
+#define ADC_RG2X_0_DELAY_80_US ((uint32_t)(3 << 4))
+/** \} */
+
+#define IS_ADC_RG2X_0_DELAY_TIME(TIME) (((TIME) == ADC_RG2X_0_DELAY_10_US) || ((TIME) == ADC_RG2X_0_DELAY_20_US)\
+ || ((TIME) == ADC_RG2X_0_DELAY_40_US) || ((TIME) == ADC_RG2X_0_DELAY_80_US))
+
+/**
+ * \defgroup ADC_RG0X_1_Delay_Time ADC RG0X_1 Delay Time
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+#define ADC_RG0X_1_DELAY_20_US ((uint32_t)(0 << 2))
+#define ADC_RG0X_1_DELAY_40_US ((uint32_t)(1 << 2))
+#define ADC_RG0X_1_DELAY_80_US ((uint32_t)(2 << 2))
+#define ADC_RG0X_1_DELAY_160_US ((uint32_t)(3 << 2))
+/** \} */
+
+#define IS_ADC_RG0X_1_DELAY_TIME(TIME) (((TIME) == ADC_RG0X_1_DELAY_20_US) || ((TIME) == ADC_RG0X_1_DELAY_40_US)\
+ || ((TIME) == ADC_RG0X_1_DELAY_80_US) || ((TIME) == ADC_RG0X_1_DELAY_160_US))
+
+/**
+ * \defgroup ADC_RG0X_0_Delay_Time ADC RG0X_0 Delay Time
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+#define ADC_RG0X_0_DELAY_30_US ((uint32_t)(0 << 0))
+#define ADC_RG0X_0_DELAY_60_US ((uint32_t)(1 << 0))
+#define ADC_RG0X_0_DELAY_120_US ((uint32_t)(2 << 0))
+#define ADC_RG0X_0_DELAY_240_US ((uint32_t)(3 << 0))
+/** \} */
+
+#define IS_ADC_RG0X_0_DELAY_TIME(TIME) (((TIME) == ADC_RG0X_0_DELAY_30_US) || ((TIME) == ADC_RG0X_0_DELAY_60_US)\
+ || ((TIME) == ADC_RG0X_0_DELAY_120_US) || ((TIME) == ADC_RG0X_0_DELAY_240_US))
+
+/**
+ * \defgroup ADC_Data_Minus_En ADC Data Minus Enable
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+#define ADC_DATA_MINUS_DISABLE (uint32_t)(0 << 31)
+#define ADC_DATA_MINUS_ENABLE (uint32_t)(1 << 31)
+/** \} */
+
+#define IS_ADC_DATA_MINUS_CMD(CMD) (((CMD) == ADC_DATA_MINUS_DISABLE) || ((CMD) == ADC_DATA_MINUS_ENABLE))
+
+/**
+ * \defgroup ADC_Data_Align ADC Data Align
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+#define ADC_DATA_ALIGN_LSB (uint32_t)(0 << 30)
+#define ADC_DATA_ALIGN_MSB (uint32_t)(1 << 30)
+/** \} */
+
+#define IS_ADC_DATA_ALIGN(DATA_ALIGN) (((DATA_ALIGN) == ADC_DATA_ALIGN_LSB) || ((DATA_ALIGN) == ADC_DATA_ALIGN_MSB))
+
+/**
+ * \defgroup ADC_Timer_Trigger_En ADC Timer Trigger En
+ * \brief ADC trigger one-shot mode with timer7.
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+#define ADC_TIMER_TRIGGER_DISABLE ((uint32_t)(0 << 29))
+#define ADC_TIMER_TRIGGER_ENABLE ((uint32_t)(1 << 29))
+/** \} */
+
+#define IS_ADC_TIMER_TRIGGER_CMD(CMD) (((CMD) == ADC_TIMER_TRIGGER_DISABLE) || ((CMD) == ADC_TIMER_TRIGGER_ENABLE))
+
+/**
+ * \defgroup ADC_Power_Always_On_Cmd ADC Power Always On Cmd
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+#define ADC_POWER_ALWAYS_ON_DISABLE ((uint32_t)(0 << 15))
+#define ADC_POWER_ALWAYS_ON_ENABLE ((uint32_t)(1 << 15))
+/** \} */
+
+#define IS_ADC_POWER_ALWAYS_ON(CMD) (((CMD) == ADC_POWER_ALWAYS_ON_DISABLE) || ((CMD) == ADC_POWER_ALWAYS_ON_ENABLE))
+
+/**
+ * \defgroup ADC_Convert_Time ADC Convert Time
+ * \{
+ * \ingroup ADC_Exported_Constants
+ */
+#define ADC_CONVERT_TIME_500NS ((uint32_t)(0 << 30))
+/** \} */
+
+#define IS_ADC_CONVERT_TIME(TIME) ((TIME) == ADC_CONVERT_TIME_500NS)
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * rtl876x_adc.h
+ *
+ * \brief Deinitializes the ADC peripheral registers to their
+ * default reset values(turn off ADC clock).
+ * \details
+ * \param[in] ADCx: Specify ADC peripheral, can only be ADC.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_adc_init(void)
+ * {
+ * //Turn off the clock.
+ * ADC_DeInit(ADC);
+ * }
+ * \endcode
+ */
+void ADC_DeInit(ADC_TypeDef *ADCx);
+
+/**
+ * rtl876x_adc.h
+ * \brief Initializes the ADC peripheral according to the specified
+ * parameters in the ADC_InitStruct
+ * \param[in] ADCx: selected ADC peripheral.
+ * \param[in] ADC_InitStruct: pointer to a ADC_InitTypeDef structure that
+ * contains the configuration information for the specified ADC peripheral
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_adc_init(void)
+ * {
+ * //Turn on the clock.
+ * RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+
+ * ADC_InitTypeDef ADC_InitStruct;
+ * ADC_StructInit(&ADC_InitStruct);
+ * ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0);
+ * ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(1);
+ * ADC_InitStruct.ADC_Bitmap = 0x03;
+ * //Add other initialization parameters that need to be configured here.
+ * ADC_Init(ADC, &ADC_InitStruct);
+ * }
+ * \endcode
+ */
+void ADC_Init(ADC_TypeDef *ADCx, ADC_InitTypeDef *ADC_InitStruct);
+
+/**
+ * rtl876x_adc.h
+ * \brief Fills each ADC_InitStruct member with its default value.
+ * \param[in] ADC_InitStruct: Pointer to an ADC_InitTypeDef structure which will be initialized.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_adc_init(void)
+ * {
+ * //Turn on the clock.
+ * RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+
+ * ADC_InitTypeDef ADC_InitStruct;
+ * ADC_StructInit(&ADC_InitStruct);
+ * ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0);
+ * ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(1);
+ * ADC_InitStruct.ADC_Bitmap = 0x03;
+ * //Add other initialization parameters that need to be configured here.
+ * ADC_Init(ADC, &ADC_InitStruct);
+ * }
+ * \endcode
+ * \callgraph
+ *
+ */
+void ADC_StructInit(ADC_InitTypeDef *ADC_InitStruct);
+
+/**
+ * rtl876x_adc.h
+ * \brief Enables or disables the ADC peripheral.
+ * \param[in] ADCx: Specify ADC peripheral.
+ * \param[in] adcMode: ADC operation mode selection.
+ This parameter can be one of the following values:
+ * \arg ADC_ONE_SHOT_MODE: One shot mode.
+ * \arg ADC_CONTINUOUS_MODE: Continuous sampling mode.
+ * \param[in] NewState: New state of the ADC peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_adc_init(void)
+ * {
+ * Pad_Config(P2_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ * PAD_OUT_LOW);
+ *
+ * Pad_Config(P2_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ * PAD_OUT_LOW);
+ * }
+ *
+ * void driver_adc_init(void)
+ * {
+ * //open clock
+ * RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+ *
+ * ADC_InitTypeDef ADC_InitStruct;
+ * ADC_StructInit(&ADC_InitStruct);
+ * ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0);
+ * ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(1);
+ * ADC_InitStruct.ADC_Bitmap = 0x03;
+ * //Add other initialization parameters here.
+ * ADC_Init(ADC, &ADC_InitStruct);
+ *
+ * ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE);
+ * }
+ *
+ * void adc_demo(void)
+ * {
+ * board_adc_init();
+ * driver_adc_init();
+ * ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE);
+ * }
+ * \endcode
+ */
+void ADC_Cmd(ADC_TypeDef *ADCx, uint8_t adcMode, FunctionalState NewState);
+
+/**
+ * rtl876x_adc.h
+ * \brief Enables or disables the specified ADC interrupts.
+ * \param[in] ADCx: Specify ADC peripheral.
+ * \param[in] ADC_IT: Specify the ADC interrupts sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * \arg ADC_INT_FIFO_RD_REQ : FIFO read request.
+ * \arg ADC_INT_FIFO_RD_ERR : FIFO read error.
+ * \arg ADC_INT_FIFO_THD : ADC FIFO size > thd.
+ * \arg ADC_INT_FIFO_OVERFLOW : ADC FIFO overflow.
+ * \arg ADC_INT_ONE_SHOT_DONE : ADC one shot mode done.
+ * \param[in] newState: New state of the specified ADC interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_adc_init(void)
+ * {
+ * //open clock
+ * RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+ *
+ * ADC_InitTypeDef ADC_InitStruct;
+ * ADC_StructInit(&ADC_InitStruct);
+ * ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0);
+ * ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(1);
+ * ADC_InitStruct.ADC_Bitmap = 0x03;
+ * //Add other initialization parameters here.
+ * ADC_Init(ADC, &ADC_InitStruct);
+ *
+ * ADC_INTConfig(ADC, ADC_INT_FIFO_RD_ERR, ENABLE);
+ * ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE);
+ * }
+ * \endcode
+ *
+ */
+void ADC_INTConfig(ADC_TypeDef *ADCx, uint32_t ADC_INT, FunctionalState NewState);
+
+/**
+ * rtl876x_adc.h
+ * \brief Read ADC data according to specific channel.
+ * \param[in] ADCx: Specify ADC peripheral.
+ * \param[in] index: Can be 0 to 15.
+ * \return The 12-bit converted ADC raw data.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_adc_init(void)
+ * {
+ * Pad_Config(P2_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ * PAD_OUT_LOW);
+ *
+ * Pad_Config(P2_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ * PAD_OUT_LOW);
+ * }
+ *
+ * void driver_adc_init(void)
+ * {
+ * //open clock
+ * RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+ *
+ * ADC_InitTypeDef ADC_InitStruct;
+ * ADC_StructInit(&ADC_InitStruct);
+ * ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0);
+ * ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(1);
+ * ADC_InitStruct.ADC_Bitmap = 0x03;
+ * //Add other initialization parameters here.
+ * ADC_Init(ADC, &ADC_InitStruct);
+ *
+ * ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE);
+ * }
+ *
+ * void adc_demo(void)
+ * {
+ * board_adc_init();
+ * driver_adc_init();
+ * ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE);
+ * while(ADC_GetINTStatus(ADC, ADC_INT_ONE_SHOT_DONE) == RESET);
+ * uint16_t raw_data_0 = ADC_ReadRawData(ADC, 0);
+ * uint16_t raw_data_1 = ADC_ReadRawData(ADC, 1);
+ * }
+ * \endcode
+ */
+uint16_t ADC_ReadRawData(ADC_TypeDef *ADCx, uint8_t index);
+
+/**
+ * rtl876x_adc.h
+ * \brief Get ADC average data from ADC schedule table0.
+ * \param[in] ADCx: Specify ADC peripheral.
+ * \param[out] OutBuf: Buffer to save data read from ADC FIFO.
+ * \return The 12-bit converted ADC raw data.
+ * \callgraph
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_adc_init(void)
+ * {
+ * Pad_Config(P2_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ * PAD_OUT_LOW);
+ * }
+ *
+ * void driver_adc_init(void)
+ * {
+ * //open clock
+ * RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+ *
+ * ADC_InitTypeDef ADC_InitStruct;
+ * ADC_StructInit(&ADC_InitStruct);
+ * ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0);
+ * ADC_InitStruct.ADC_Bitmap = 0x01;
+ * ADC_InitStruct.ADC_DataAvgEn = ADC_DATA_AVERAGE_ENABLE;
+ * ADC_InitStruct.ADC_DataAvgSel = ADC_DATA_AVERAGE_OF_2;
+ * //Add other initialization parameters here.
+ * ADC_Init(ADC, &ADC_InitStruct);
+ *
+ * ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE);
+ * }
+ *
+ * void adc_demo(void)
+ * {
+ * board_adc_init();
+ * driver_adc_init();
+ * ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE);
+ * while(ADC_GetINTStatus(ADC, ADC_INT_ONE_SHOT_DONE) == RESET);
+ * uint16_t raw_data = 0;
+ * raw_data = ADC_ReadAvgRawData(ADC);
+ * }
+ * \endcode
+ *
+ */
+uint16_t ADC_ReadAvgRawData(ADC_TypeDef *ADCx);
+
+/**
+ * rtl876x_adc.h
+ * \brief Read one byte data from ADC FIFO.
+ * \param[in] ADCx: selected ADC peripheral.
+ * \return adc FIFO data.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_adc_init(void)
+ * {
+ * Pad_Config(P2_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ * PAD_OUT_LOW);
+ * }
+ *
+ * void driver_adc_init(void)
+ * {
+ * //open clock
+ * RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+ *
+ * ADC_InitTypeDef ADC_InitStruct;
+ * ADC_StructInit(&ADC_InitStruct);
+ * ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0);
+ * ADC_InitStruct.ADC_Bitmap = 0x01;
+ * ADC_InitStruct.ADC_DataWriteToFifo = ADC_DATA_WRITE_TO_FIFO_DISABLE;
+ * ADC_Init(ADC, &ADC_InitStruct);
+ *
+ * ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE);
+ * }
+ *
+ * void adc_demo(void)
+ * {
+ * board_adc_init();
+ * driver_adc_init();
+ * ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE);
+ * while(ADC_GetINTStatus(ADC, ADC_INT_ONE_SHOT_DONE) == RESET);
+ * uint16_t raw_data = 0;
+ * raw_data = ADC_ReadFIFO(ADC);
+ * }
+ * \endcode
+ */
+uint16_t ADC_ReadFIFO(ADC_TypeDef *ADCx);
+
+/**
+ * rtl876x_adc.h
+ * \brief Get data from ADC FIFO.
+ * \param[in] ADCx: Specify ADC peripheral.
+ * \param[out] outBuf: Buffer to save data read from ADC FIFO.
+ * \param[in] num: Number of data to be read.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void adc_demo(void)
+ * {
+ * //ADC already start
+ * uint16_t raw_data[32] = {0};
+ * uint8_t data_len = ADC_GetFIFODataLen(ADC);
+ * ADC_ReadFIFOData(ADC,raw_data,data_len);
+ * }
+ * \endcode
+ *
+ */
+void ADC_ReadFIFOData(ADC_TypeDef *ADCx, uint16_t *outBuf, uint16_t num);
+
+/**
+ * rtl876x_adc.h
+ * \brief Get ADC fifo data number.
+ * \param[in] ADCx: selected ADC peripheral.
+ * \return Current data number in ADC FIFO.
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void adc_demo(void)
+ * {
+ * //ADC already start
+ * uint16_t raw_data[32] = {0};
+ * uint8_t data_len = ADC_GetFIFODataLen(ADC);
+ * ADC_ReadFIFOData(ADC,raw_data,data_len);
+ * }
+ * \endcode
+ *
+ */
+uint8_t ADC_GetFIFODataLen(ADC_TypeDef *ADCx);
+
+/**
+ * rtl876x_adc.h
+ * \brief Config ADC schedule table.
+ * \param[in] ADCx: Specify ADC peripheral.
+ * \param[in] adcMode: ADC operation mode.
+ * This parameter can be one of the following values:
+ * \arg EXT_SINGLE_ENDED(index)
+ * \arg EXT_DIFFERENTIAL(index)
+ * \arg INTERNAL_VBAT_MODE
+ * \param[in] Index: Schedule table index.
+ * \return None.
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void adc_demo(void)
+ * {
+ * ADC_SchIndexConfig(ADC,INTERNAL_VBAT_MODE,0);
+ * }
+ * \endcode
+ *
+ */
+void ADC_SchIndexConfig(ADC_TypeDef *ADCx, uint8_t adcMode, uint16_t Index);
+
+/**
+ * \brief Same as function ADC_SchIndexConfig, this function is version bee2.
+ */
+void ADC_SchTableConfig(ADC_TypeDef *ADCx, uint16_t Index, uint8_t adcMode);
+
+/**
+ * rtl876x_adc.h
+ * \brief Config adc schedule table.
+ * \param[in] ADCx: Specify ADC peripheral.
+ * \param[in] channelMap: ADC channel map.
+ * \param[in] NewState: New state of the ADC peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void adc_demo(void)
+ * {
+ * uint16_t bit_map = 0x03;
+ * ADC_BitMapConfig(ADC,bit_map,ENABLE);
+ * }
+ * \endcode
+ */
+void ADC_BitMapConfig(ADC_TypeDef *ADCx, uint16_t bitMap, FunctionalState NewState);
+
+/**
+ * rtl876x_adc.h
+ * \brief Power on ADC manually.
+ * \param[in] ADCx: Specify ADC peripheral.
+ * \param[in] NewState: New state of the ADC power on.
+ * This parameter can be: ENABLE or DISABLE. If enabled, ADC power will always be on until disabled.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void adc_demo(void)
+ * {
+ * ADC_ManualPowerOnCmd(ADC,ENABLE);
+ * }
+ * \endcode
+ */
+void ADC_ManualPowerOnCmd(ADC_TypeDef *ADCx, FunctionalState NewState);
+
+/**
+ * rtl876x_adc.h
+ * \brief Enable or disable stop FIFO from writing data.
+ * \param[in] ADCx: Specify ADC peripheral.
+ * \param[in] NewState: New state of the ADC FIFO write.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void adc_demo(void)
+ * {
+ * ADC_WriteFIFOCmd(ADC, ENABLE);
+ * }
+ * \endcode
+ */
+void ADC_WriteFIFOCmd(ADC_TypeDef *ADCx, FunctionalState NewState);
+
+/**
+ * rtl876x_adc.h
+ * \brief Config ADC bypass resistor.
+ * \param[in] channelNum: External channel number, can be 0~7.
+ * \param[in] NewState: Specifies whether the channel enables bypass mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ * \note The input voltage of channel pin using bypass mode cannot exceed 0.9V!
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void adc_demo(void)
+ * {
+ * ADC_BypassCmd(0,ENABLE);
+ * }
+ * \endcode
+ */
+void ADC_BypassCmd(uint8_t ChannelNum, FunctionalState NewState);
+
+/**
+ * rtl876x_adc.h
+ * \brief Check whether the specified ADC interrupt flag is set.
+ * \param[in] ADCx: selected ADC peripheral.
+ * \param[in] ADC_INT_FLAG: Specifies the interrupt flag to check.
+ * This parameter can be one of the following values:
+ * \arg ADC_INT_ONE_SHOT_DONE: ADC once convert end interrupt.
+ * \arg ADC_INT_FIFO_OVERFLOW: ADC FIFO overflow interrupt.
+ * \arg ADC_INT_FIFO_THD: FIFO larger than threshold interrupt.
+ * \arg ADC_INT_FIFO_RD_ERR: ADC read FIFO error interrupt.
+ * \arg ADC_INT_FIFO_RD_REQ: ADC read FIFO request interrupt.
+ *
+ * \return The new state of ADC_INT (SET or RESET).
+ * \retval SET.
+ * \retval RESET.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void adc_demo(void)
+ * {
+ * ITStatus int_status = RESET;
+ * int_status = ADC_GetINTStatus(ADC,ADC_INT_FIFO_OVERFLOW);
+ * }
+ * \endcode
+ */
+ITStatus ADC_GetINTStatus(ADC_TypeDef *ADCx, uint32_t ADC_INT);
+
+/**
+ * rtl876x_adc.h
+ * \brief Clear the ADC interrupt pending bit.
+ * \param[in] ADCx: Specify ADC peripheral.
+ * \param[in] ADC_INT: Specifies the interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * \arg ADC_INT_ONE_SHOT_DONE: ADC once convert end interrupt.
+ * \arg ADC_INT_FIFO_OVERFLOW: ADC FIFO overflow interrupt.
+ * \arg ADC_INT_FIFO_THD: FIFO larger than threshold interrupt.
+ * \arg ADC_INT_FIFO_RD_ERR: ADC read FIFO error interrupt.
+ * \arg ADC_INT_FIFO_RD_REQ: ADC read FIFO request interrupt.
+ *
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void adc_demo(void)
+ * {
+ * ADC_ClearINTPendingBit(ADC,ADC_INT_FIFO_OVERFLOW);
+ * }
+ * \endcode
+ */
+void ADC_ClearINTPendingBit(ADC_TypeDef *ADCx, uint32_t ADC_INT);
+
+/**
+ * rtl876x_adc.h
+ * \brief Clear ADC FIFO.
+ * \param[in] ADCx: Specify ADC peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void adc_demo(void)
+ * {
+ * ADC_ClearFIFO(ADC);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void ADC_ClearFIFO(ADC_TypeDef *ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+
+ ADCx->CR |= BIT26;
+}
+
+/**
+ * rtl876x_adc.h
+ * \brief Get all adc interrupt flag status.
+ * \param[in] ADCx: Specify ADC peripheral.
+ * \return All ADC interrupt status.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void adc_demo(void)
+ * {
+ * uint8_t all_flag_status = 0;
+ * all_flag_status = ADC_GetAllFlagStatus(ADC);
+ * }
+ * \endcode
+ *
+ */
+__STATIC_INLINE uint8_t ADC_GetAllFlagStatus(ADC_TypeDef *ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+
+ return ((uint8_t)(((ADCx->INTCR) & (0x1f << 16)) >> 16));
+}
+
+/** \} */ /* End of Group ADC_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_ADC_H_ */
+
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor *****END OF FILE****/
+
+
+
diff --git a/inc/peripheral/rtl876x_alias.h b/inc/peripheral/rtl876x_alias.h
new file mode 100644
index 0000000..18ab33b
--- /dev/null
+++ b/inc/peripheral/rtl876x_alias.h
@@ -0,0 +1,145 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_alias.h
+* \brief The header file of all peripherals internal alias.
+* \details To be compatible with the previous driver,create an alias file for the previous driver.
+* \author yuan
+* \date 2020-06-19
+* \version v2.1.0
+* *********************************************************************************************************
+*/
+
+
+#ifndef _RTL876X_ALIAS_H_
+#define _RTL876X_ALIAS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \cond private
+ * \brief To be compatible with the previous driver.
+ * \defgroup ADC_InitTypeDef_Alias ADC Init TypeDef Alias
+ * \{
+ */
+#define ADC_One_Shot_Mode ADC_ONE_SHOT_MODE
+#define schIndex ADC_SchIndex
+#define bitmap ADC_Bitmap
+#define adcSamplePeriod ADC_SampleTime
+#define PowerAlwaysOnEn ADC_PowerAlwaysOnEn
+#define dataWriteToFifo ADC_DataWriteToFifo
+#define timerTriggerEn ADC_TimerTriggerEn
+
+/**
+ * \}
+ * \endcond
+ */
+
+/**
+ * \cond private
+ * \brief To be compatible with the previous driver.
+ * \defgroup ADC_API_Alias ADC API Alias
+ * \{
+ */
+#define ADC_ReadByScheduleIndex ADC_ReadRawData
+#define ADC_ReadFifoData ADC_ReadFIFO
+#define ADC_GetFifoData ADC_ReadFIFOData
+#define ADC_GetFifoLen ADC_GetFIFODataLen
+#define ADC_SchTableSet ADC_BitMapConfig
+#define ADC_PowerAlwaysOnCmd ADC_ManualPowerOnCmd
+#define ADC_FifoWriteCmd ADC_WriteFIFOCmd
+#define ADC_AnalogCircuitConfig ADC_PowerSupplyConfig
+#define ADC_GetIntFlagStatus ADC_GetINTStatus
+#define ADC_ClearFifo ADC_ClearFIFO
+#define ADC_GetIntStatus ADC_GetAllFlagStatus
+
+/**
+ * \}
+ * \endcond
+ */
+
+/**
+ * \cond private
+ * \brief To be compatible with the previous driver.
+ * \defgroup RTC_API_Alias RTC API Alias
+ * \{
+ */
+#define RTC_SetComp RTC_SetCompValue
+#define RTC_RunCmd RTC_Cmd
+#define RTC_INT_CMP1 RTC_INT_COMP1
+
+/**
+ * \}
+ * \endcond
+ */
+
+/**
+ * \cond private
+ * \brief To be compatible with the previous driver.
+ * \defgroup UART_InitTypeDef_Alias UART Init TypeDef Alias
+ * \{
+ */
+#define ovsr_adj UART_OvsrAdj
+#define div UART_Div
+#define ovsr UART_Ovsr
+#define wordLen UART_WordLen
+#define parity UART_Parity
+#define stopBits UART_StopBits
+#define autoFlowCtrl UART_HardwareFlowControl
+#define txTriggerLevel UART_TxThdLevel
+#define rxTriggerLevel UART_RxThdLevel
+#define dmaEn UART_DmaEn
+#define idle_time UART_IdleTime
+#define TxWaterlevel UART_TxWaterLevel
+#define RxWaterlevel UART_RxWaterLevel
+#define TxDmaEn UART_TxDmaEn
+#define RxDmaEn UART_RxDmaEn
+
+#define UART_INT_LINE_STS UART_INT_RX_LINE_STS
+#define UART_INT_ID_RX_TMEOUT UART_INT_ID_RX_DATA_TIMEOUT
+#define UART_FLAG_THR_EMPTY UART_FLAG_TX_FIFO_EMPTY
+#define UART_FLAG_THR_TSR_EMPTY UART_FLAG_TX_EMPTY
+#define UART_FLAG_RX_DATA_RDY UART_FLAG_RX_DATA_AVA
+
+/**
+ * \}
+ * \endcond
+ */
+
+/**
+ * \cond private
+ * \brief To be compatible with the previous driver.
+ * \defgroup UART_API_Alias UART API Alias
+ * \{
+ */
+#define UART_GetFlagState UART_GetFlagStatus
+#define UART_ChangeBaudRate UART_SetBaudRate
+#define UART_ChangeParams UART_SetParams
+#define UART_ClearTxFifo UART_ClearTxFIFO
+#define UART_ClearRxFifo UART_ClearRxFIFO
+#define UART_GetTxFIFOLen UART_GetTxFIFODataLen
+#define UART_GetRxFIFOLen UART_GetRxFIFODataLen
+
+/**
+ * \}
+ * \endcond
+ */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_ALIAS_H_ */
+
+
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor *****END OF FILE****/
+
+
+
diff --git a/inc/peripheral/rtl876x_aon_wdg.h b/inc/peripheral/rtl876x_aon_wdg.h
new file mode 100644
index 0000000..e982f0d
--- /dev/null
+++ b/inc/peripheral/rtl876x_aon_wdg.h
@@ -0,0 +1,131 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file rtl876x_aon_wdg.h
+* @brief header file of aon watch dog driver.
+* @details
+* @author Serval Li
+* @date 2017-06-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _RTL876X_AON_WDG_H_
+#define _RTL876X_AON_WDG_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup IO Peripheral Drivers
+ *
+ * @defgroup AON_WATCH_DOG AON_WATCH_DOG
+ * @brief AON Watch Dog driver module
+ * \ingroup IO
+ * @{
+ */
+
+/** @defgroup AON_WATCH_DOG_Exported_Functions AON Watch Dog Exported Functions
+ * @{
+ */
+
+/**
+ * @brief AON Watchdog Config.
+ * @param reset_level: 0, Reset whole chip; 1, Reset whole chip except partial AON and RTC.
+ * @param comp: Set period in ms.
+ * @param cnt_ctl: 0, Stop count in low power mode; 1, Continue count in low power mode.
+ * @param cnt_reload: 0, Not reload counter when exit low power mode
+ 1, Reload counter when exit low power mode.
+ * @retval none.
+ */
+void AON_WDG_Config(uint8_t reset_level, uint32_t comp, uint8_t cnt_ctl, uint8_t cnt_reload);
+
+/**
+ * @brief Config Reset Level.
+ * @param reset_level: 0, Reset whole chip; 1, Reset whole chip except partial AON and RTC.
+ * @retval none.
+ */
+void AON_WDG_ConfigResetLevel(uint8_t reset_level);
+
+/**
+ * @brief Config Period.
+ * @param comp: Set period in ms.
+ * @retval none.
+ */
+void AON_WDG_ConfigComp(uint32_t comp);
+
+/**
+ * @brief Config whether continue count in low power mode or not.
+ * @param cnt_ctl: 0, Stop count in low power mode; 1, Continue count in low power mode.
+ * @retval none.
+ */
+void AON_WDG_ConfigCntCtl(uint8_t cnt_ctl);
+
+/**
+ * @brief Config whether reload counter when exit low power mode or not.
+ * @param cnt_reload: 0, Not reload counter when exit low power mode
+ 1, Reload counter when exit low power mode.
+ * @retval none.
+ */
+void AON_WDG_ConfigCntReload(uint8_t cnt_reload);
+
+/**
+ * @brief AON Watch Dog Timer Enable.
+ */
+void AON_WDG_Enable(void);
+
+/**
+ * @brief AON Watch Dog Timer Disable.
+ */
+void AON_WDG_Disable(void);
+
+/**
+ * @brief AON Watch Dog Timer Restart.
+ */
+void AON_WDG_Restart(void);
+
+/**
+ * @brief AON Watch Dog System Reset.
+ */
+void AON_WDG_SystemReset(void);
+
+/**
+ * @brief AON Watch Dog init.
+ * reset_level: 0, Reset whole chip; 1, Reset whole chip except partial AON and RTC.
+ * timeout_second: timeout period in seconds, max value is 65s
+ */
+static inline void aon_wdg_init(uint8_t reset_level, uint8_t timeout_second)
+{
+ uint32_t comp = (timeout_second * 1000 * 4) & 0x3FFFF; //only 18 bit
+ AON_WDG_Config(reset_level, comp, 1, 1);
+}
+
+/**
+ * @brief AON Watch Dog enable.
+ */
+static inline void aon_wdg_enable(void)
+{
+ AON_WDG_Enable();
+}
+
+/**
+ * @brief AON Watch Dog counter is clear and disable.
+ */
+static inline void aon_wdg_disable(void)
+{
+ AON_WDG_Restart();
+ AON_WDG_Disable();
+}
+
+
+/** @} */ /* End of group AON_WATCH_DOG_Exported_Functions */
+/** @} */ /* End of group AON_WATCH_DOG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_AON_WDG_H_ */
diff --git a/inc/peripheral/rtl876x_bitfields.h b/inc/peripheral/rtl876x_bitfields.h
new file mode 100644
index 0000000..9c4fd84
--- /dev/null
+++ b/inc/peripheral/rtl876x_bitfields.h
@@ -0,0 +1,523 @@
+/* Copyright (c) 2015 Realtek Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Realtek Semiconductor.
+ * Terms and conditions of usage are described in detail in Realtek
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+#ifndef __RTL876X_BITS_H
+#define __RTL876X_BITS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//#include <core_cm4.h>
+
+/* Peripheral: KEYSCAN */
+/* Description: Key Scan. */
+
+
+/* Register: RTL_KEYSCAN_CR0 */
+/* Description: Control register 0. */
+
+/* Bit 31 : Keyscan clock enable */
+#define KEYSCAN_CR0_CLKEN_Pos (31UL) /*!< Position of clock enable field. */
+#define KEYSCAN_CR0_CLKEN_Msk (0x1UL << KEYSCAN_CR0_CLKEN_Pos) /*!< Bit mask of clock enable field. */
+#define KEYSCAN_CR0_CLKEN_Disabled (0UL) /*!< Clock disabled. */
+#define KEYSCAN_CR0_CLKEN_Enabled (1UL) /*!< Clock enabled. */
+
+/* Bit 8 : Column selection */
+#define KEYSCAN_CR0_COLSEL_Pos (8UL) /*!< Position of column selection field. */
+#define KEYSCAN_CR0_COLSEL_Msk (0xFFFFFUL << KEYSCAN_CR0_COLSEL_Pos) /*!< Bit mask of column selection field. */
+
+/* Bit 5 : Row number */
+#define KEYSCAN_CR0_ROWNUM_Pos (5UL) /*!< Position of row number field. */
+#define KEYSCAN_CR0_ROWNUM_Msk (0x07UL << KEYSCAN_CR0_ROWNUM_Pos) /*!< Bit mask of row number field. */
+
+
+/* Bit 0 : Column number */
+#define KEYSCAN_CR0_COLNUM_Pos (0UL) /*!< Position of column number field. */
+#define KEYSCAN_CR0_COLNUM_Msk (0x1FUL << KEYSCAN_CR0_COLNUM_Pos) /*!< Bit mask of column number field. */
+
+/* Register: RTL_KEYSCAN_CR1 */
+/* Description: Control register 1. */
+
+/* Bit 27 : Post guard time for column*/
+#define KEYSCAN_CR1_POSTGUARD_Pos (27UL) /*!< Position of post guard time field. */
+#define KEYSCAN_CR1_POSTGUARD_Msk (0x07UL << KEYSCAN_CR1_POSTGUARD_Pos) /*!< Bit mask of post guard time field. */
+
+/* Bit 24 : Pre guard time for column */
+#define KEYSCAN_CR1_PREGUARD_Pos (24UL) /*!< Position pre guard time field. */
+#define KEYSCAN_CR1_PREGUARD_Msk (0x07UL << KEYSCAN_CR1_PREGUARD_Pos) /*!< Bit mask of pre guard time field. */
+
+/* Bit 16 : Row selection */
+#define KEYSCAN_CR1_ROWSEL_Pos (16UL) /*!< Position of row selection field. */
+#define KEYSCAN_CR1_ROWSEL_Msk (0xFFUL << KEYSCAN_CR1_ROWSEL_Pos) /*!< Bit mask of row selection field. */
+
+/* Bit 8 : Detection period */
+#define KEYSCAN_CR1_DETECTPERIOD_Pos (8UL) /*!< Position of detection period field. */
+#define KEYSCAN_CR1_DETECTPERIOD_Msk (0x07UL << KEYSCAN_CR1_DETECTPERIOD_Pos) /*!< Bit mask of detection period field. */
+#define KEYSCAN_CR1_DETECTPERIOD_Disabled (0UL) /*!< Detection disabled. */
+#define KEYSCAN_CR1_DETECTPERIOD_Enabled (1UL) /*!< Detection enabled. */
+
+/* Bit 7 : Debouncing enable */
+#define KEYSCAN_CR1_DEBOUNCEN_Pos (7UL) /*!< Position of debouncing enable field. */
+#define KEYSCAN_CR1_DEBOUNCEN_Msk (0x01UL << KEYSCAN_CR1_DEBOUNCEN_Pos) /*!< Bit mask of debouncing enable field. */
+#define KEYSCAN_CR1_DEBOUNCEN_Disabled (0UL) /*!< Debouncing disabled. */
+#define KEYSCAN_CR1_DEBOUNCEN_Enabled (1UL) /*!< Debouncing enabled. */
+
+/* Bit 2 : Timeout period */
+#define KEYSCAN_CR1_TOPERIOD_Pos (2UL) /*!< Position of timeout period field. */
+#define KEYSCAN_CR1_TOPERIOD_Msk (0x03UL << KEYSCAN_CR1_TOPERIOD_Pos) /*!< Bit mask of timeout period field. */
+
+/* Bit 0 : Wait period */
+#define KEYSCAN_CR1_WAITPERIOD_Pos (0UL) /*!< Position of wait period field. */
+#define KEYSCAN_CR1_WAITPERIOD_Msk (0x03UL << KEYSCAN_CR1_WAITPERIOD_Pos) /*!< Bit mask of wait period field. */
+
+
+/* Register: RTL_KEYSCAN_CR2 */
+/* Description: Control register 2. */
+
+/* Bit 27 : Program debouncing time enable */
+#define KEYSCAN_CR2_DEBEN_Pos (27UL) /*!< Position of program debouncing time enable field. */
+#define KEYSCAN_CR2_DEBEN_Msk (0x1UL << KEYSCAN_CR2_DEBEN_Pos) /*!< Bit mask of program debouncing time enable field. */
+#define KEYSCAN_CR2_DEBEN_Disabled (0UL) /*!< Clock disabled. */
+#define KEYSCAN_CR2_DEBEN_Enabled (1UL) /*!< Clock enabled. */
+
+/* Bit 16 : Debouncing time*/
+#define KEYSCAN_CR2_DEBTIME_Pos (16UL) /*!< Position of debouncing time field. */
+#define KEYSCAN_CR2_DEBTIME_Msk (0x3FFUL << KEYSCAN_CR2_DEBTIME_Pos) /*!< Bit mask of debouncing time field. */
+
+/* Bit 15 : FIFO clear */
+#define KEYSCAN_CR2_FIFOCLEAR_Pos (15UL) /*!< Position of FIFO clear field. */
+#define KEYSCAN_CR2_FIFOCLEAR_Msk (0x1UL << KEYSCAN_CR2_FIFOCLEAR_Pos) /*!< Bit mask of FIFO clear field. */
+
+/* Bit 14 : Force scan fsm idle */
+#define KEYSCAN_CR2_FSMIDLE_Pos (14UL) /*!< Position of force scan fsm idle field. */
+#define KEYSCAN_CR2_FSMIDLE_Msk (0x1UL << KEYSCAN_CR2_FSMIDLE_Pos) /*!< Bit mask of force scan fsm idle field. */
+
+/* Bit 13 : FIFO flag clear1 */
+#define KEYSCAN_CR2_FIFOFLAGCLR1_Pos (13UL) /*!< Position of FIFO flag clear1 field. */
+#define KEYSCAN_CR2_FIFOFLAGCLR1_Msk (0x1UL << KEYSCAN_CR2_FIFOFLAGCLR1_Pos) /*!< Bit mask of FIFO flag clear1 field. */
+
+/* Bit 12 : FIFO flag clear2 */
+#define KEYSCAN_CR2_FIFOFLAGCLR2_Pos (12UL) /*!< Position of FIFO flag clear2 field. */
+#define KEYSCAN_CR2_FIFOFLAGCLR2_Msk (0x1UL << KEYSCAN_CR2_FIFOFLAGCLR2_Pos) /*!< Bit mask of FIFO flag clear2 field. */
+
+/* Bit 7 : Key scan trigger type */
+#define KEYSCAN_CR2_TRIGTYPE_Pos (7UL) /*!< Position of ey scan trigger type field. */
+#define KEYSCAN_CR2_TRIGTYPE_Msk (0x1UL << KEYSCAN_CR2_TRIGTYPE_Pos) /*!< Bit mask of key scan trigger type field. */
+#define KEYSCAN_CR2_TRIGTYPE_EDGE (0UL) /*!< Edge trigger */
+#define KEYSCAN_CR2_TRIGTYPE_LEVEL (1UL) /*!< Level trigger */
+
+/* Bit 6 : FIFO overflow control */
+#define KEYSCAN_CR2_FIFOOVCTL_Pos (6UL) /*!< Position of FIFO overflow control field. */
+#define KEYSCAN_CR2_FIFOOVCTL_Msk (0x1UL << KEYSCAN_CR2_FIFOOVCTL_Pos) /*!< Bit mask of FIFO overflow control field. */
+#define KEYSCAN_CR2_FIFOOVCTL_DISCARDNEW (0UL) /*!< Discard all the new scan data when FIFO is full. */
+#define KEYSCAN_CR2_FIFOOVCTL_DISCARDOLD (1UL) /*!< Discard the last scan data when FIFO is full. */
+
+/* Bit 0 : Scan key limit */
+#define KEYSCAN_CR2_KEYLIMIT_Pos (0UL) /*!< Position of scan key limit field. */
+#define KEYSCAN_CR2_KEYLIMIT_Msk (0x1FUL << KEYSCAN_CR2_KEYLIMIT_Pos) /*!< Bit mask of scan key limit field. */
+
+
+/* Register: RTL_KEYSCAN_INTCR */
+/* Description: Interrupt Control Register */
+
+/* Bit 15 : Interrupt mask */
+#define KEYSCAN_INTCR_INTMSK_Pos (15UL) /*!< Position of interrupt mask field. */
+#define KEYSCAN_INTCR_INTMSK_Msk (0x1UL << KEYSCAN_INTCR_INTMSK_Pos) /*!< Bit mask of interrupt mask field. */
+
+/* Bit 14 : Int3 clear */
+#define KEYSCAN_INTCR_INT3CLR_Pos (14UL) /*!< Position of Int3 clear field. */
+#define KEYSCAN_INTCR_INT3CLR_Msk (0x1UL << KEYSCAN_INTCR_INT3CLR_Pos) /*!< Bit mask of Int3 clear field. */
+
+/* Bit 13 : Int2 clear */
+#define KEYSCAN_INTCR_INT2CLR_Pos (13UL) /*!< Position of Int2 clear field. */
+#define KEYSCAN_INTCR_INT2CLR_Msk (0x1UL << KEYSCAN_INTCR_INT2CLR_Pos) /*!< Bit mask of Int2 clear field. */
+
+/* Bit 12 : Int1 clear */
+#define KEYSCAN_INTCR_INT1CLR_Pos (12UL) /*!< Position of Int1 clear field. */
+#define KEYSCAN_INTCR_INT1CLR_Msk (0x1UL << KEYSCAN_INTCR_INT1CLR_Pos) /*!< Bit mask of Int1 clear field. */
+
+/* Bit 11 : Interrupt control mode */
+#define KEYSCAN_INTCR_INTCTLMODE_Pos (11UL) /*!< Position of interrupt control mode field. */
+#define KEYSCAN_INTCR_INTCTLMODE_Msk (0x1UL << KEYSCAN_INTCR_INTCTLMODE_Pos) /*!< Bit mask of interrupt control mode field. */
+#define KEYSCAN_INTCR_INTCTLMODE_HW (0UL) /*!< HW control interrupt mode */
+#define KEYSCAN_INTCR_INTCTLMODE_SW (1UL) /*!< SW control interrupt mode */
+
+/* Bit 10 : Enable/Disable interrupt in SW control mode */
+#define KEYSCAN_INTCR_SWINTEN_Pos (10UL) /*!< Position of Enable/Disable interrupt in SW control mode field. */
+#define KEYSCAN_INTCR_SWINTEN_Msk (0x1UL << KEYSCAN_INTCR_SWINTEN_Pos) /*!< Bit mask of Enable/Disable interrupt in SW control mode field. */
+
+/* Bit 8 : Interrupt timeout period */
+#define KEYSCAN_INTCR_INTTOPERIOD_Pos (8UL) /*!< Position of Interrupt timeout period field. */
+#define KEYSCAN_INTCR_INTTOPERIOD_Msk (0x3UL << KEYSCAN_INTCR_INTTOPERIOD_Pos) /*!< Bit mask of Interrupt timeout period field. */
+
+/* Bit 4 : Interrupt threshold */
+#define KEYSCAN_INTCR_INTTHRESHOLD_Pos (4UL) /*!< Position of ey Interrupt threshold field. */
+#define KEYSCAN_INTCR_INTTHRESHOLD_Msk (0x07UL << KEYSCAN_INTCR_INTTHRESHOLD_Pos) /*!< Bit mask of key Interrupt threshold field. */
+
+/* Bit 2 : Int3 enable */
+#define KEYSCAN_INTCR_INT3EN_Pos (2UL) /*!< Position of Int3 enable field. */
+#define KEYSCAN_INTCR_INT3EN_Msk (0x1UL << KEYSCAN_INTCR_INT3EN_Pos) /*!< Bit mask of Int3 enable field. */
+
+/* Bit 1 : Int2 enable */
+#define KEYSCAN_INTCR_INT2EN_Pos (1UL) /*!< Position of Int2 enable field. */
+#define KEYSCAN_INTCR_INT2EN_Msk (0x1UL << KEYSCAN_INTCR_INT2EN_Pos) /*!< Bit mask of Int2 enable field. */
+
+/* Bit 0 : Int1 enable */
+#define KEYSCAN_INTCR_INT1EN_Pos (0UL) /*!< Position of Int1 enable field. */
+#define KEYSCAN_INTCR_INT1EN_Msk (0x1UL << KEYSCAN_INTCR_INT1EN_Pos) /*!< Bit mask of Int1 enable field. */
+
+
+/* Register: RTL_KEYSCAN_FIFODATA */
+/* Description: . */
+
+/* Bit 5 : Row index */
+#define KEYSCAN_FIFODATA_ROWINDEX_Pos (5UL) /*!< Position of row index field. */
+#define KEYSCAN_FIFODATA_ROWINDEX_Msk (0x1FUL << KEYSCAN_FIFODATA_ROWINDEX_Pos) /*!< Bit mask of row index field. */
+
+/* Bit 0 : Column index */
+#define KEYSCAN_FIFODATA_COLINDEX_Pos (0UL) /*!< Position of column index field. */
+#define KEYSCAN_FIFODATA_COLINDEX_Msk (0x7UL << KEYSCAN_FIFODATA_COLINDEX_Pos) /*!< Bit mask of column index field. */
+
+
+/* Register: RTL_KEYSCAN_STATUS */
+/* Description: . */
+
+/* Bit 8 : FIFO offset */
+#define KEYSCAN_STATUS_FIFOOFFSET_Pos (8UL) /*!< Position of FIFO offset field. */
+#define KEYSCAN_STATUS_FIFOOFFSET_Msk (0x1FUL << KEYSCAN_STATUS_FIFOOFFSET_Pos) /*!< Bit mask of FIFO offset field. */
+
+/* Bit 7 : FIFO reject flag */
+#define KEYSCAN_STATUS_FIFOREJECT_Pos (7UL) /*!< Position of FIFO reject flag. */
+#define KEYSCAN_STATUS_FIFOREJECT_Msk (0x1UL << KEYSCAN_STATUS_FIFOREJECT_Pos) /*!< Bit mask of FIFO reject flag. */
+
+/* Bit 6 : FIFO overflow flag */
+#define KEYSCAN_STATUS_FIFOOVERFLOW_Pos (5UL) /*!< Position of FIFO overflow flag field. */
+#define KEYSCAN_STATUS_FIFOOVERFLOW_Msk (0x1UL << KEYSCAN_STATUS_FIFOOVERFLOW_Pos) /*!< Bit mask of FIFO overflow flag field. */
+
+/* Bit 5 : FIFO full flag */
+#define KEYSCAN_STATUS_FIFOFULL_Pos (5UL) /*!< Position of FIFO full flag field. */
+#define KEYSCAN_STATUS_FIFOFULL_Msk (0x1UL << KEYSCAN_STATUS_FIFOFULL_Pos) /*!< Bit mask of FIFO full flag field. */
+
+/* Bit 4 : FIFO empty flag */
+#define KEYSCAN_STATUS_FIFOEMPTY_Pos (4UL) /*!< Position of FIFO empty flag field. */
+#define KEYSCAN_STATUS_FIFOEMPTY_Msk (0x1UL << KEYSCAN_STATUS_FIFOEMPTY_Pos) /*!< Bit mask of FIFO empty flag field. */
+
+/* Bit 0 : Current state */
+#define KEYSCAN_STATUS_CURSTATE_Pos (0UL) /*!< Position of Current state field. */
+#define KEYSCAN_STATUS_CURSTATE_Msk (0x7UL << KEYSCAN_STATUS_CURSTATE_Pos) /*!< Bit mask of Current state field. */
+
+
+/****************************************************************************************************************/
+/* Peripheral: System Block Control */
+/* Description: System Block Control. */
+
+/* Register: REG_SYS_CLK_SEL */
+/* Description: REG_SYS_CLK_SEL. */
+
+/* Bit 31 : r_SYS_CKE_SPLL. Clock enable of 40MHz and divider */
+#define SYSBLK_SYSCLK_CLKEN_SPLL_Pos (31UL) /*!< Position of */
+#define SYSBLK_SYSCLK_CLKEN_SPLL_Msk (0x1UL << SYSBLK_SYSCLK_CLKEN_SPLL_Pos) /*!< Bit mask of */
+
+/* Bit 30 : r_SYS_40M_SEL. 0: from 40M RCOSC 1: from PLL */
+#define SYSBLK_SYSCLK_SRCSEL_Pos (30UL) /*!< Position of . */
+#define SYSBLK_SYSCLK_SRCSEL_Msk (0x1UL << SYSBLK_SYSCLK_SRCSEL_Pos) /*!< Bit mask of */
+
+/* Bit 0 : BIT_SYS_CKSL_CPU. CPU clock select 0: 40MHz 1: 20MHz 2: 10MHz 3: 5MHz 4: 53MHz 5: 26.5MHz Others: reserved */
+#define SYSBLK_SYSCLK_CPUCLK_Pos (0UL) /*!< Position of */
+#define SYSBLK_SYSCLK_CPUCLK_Msk (0x7UL << SYSBLK_SYSCLK_CPUCLK_Pos) /*!< Bit mask of */
+
+
+/* Register: REG_SOC_FUNC_EN */
+/* Description: REG_SOC_FUNC_EN. */
+
+/* Bit 16 : BIT_SOC_GTIMER_EN. 1: enable GTIMER IP and GTIMER register */
+#define SYSBLK_GTIMER_EN_Pos (16UL) /*!< Position of */
+#define SYSBLK_GTIMER_EN_Msk (0x1UL << SYSBLK_GTIMER_EN_Pos) /*!< Bit mask of */
+
+/* Bit 13 : BIT_SOC_GDMA0_EN. 1: Enable GDMA block */
+#define SYSBLK_GDMA0_EN_Pos (13UL) /*!< Position of . */
+#define SYSBLK_GDMA0_EN_Msk (0x1UL << SYSBLK_GDMA0_EN_Pos) /*!< Bit mask of */
+
+/* Bit 12 : BIT_SOC_LOG_UART_EN. 1: enable log UART; 0: disable log UART */
+#define SYSBLK_LOGUART_EN_Pos (12UL) /*!< Position of . */
+#define SYSBLK_LOGUART_EN_Msk (0x1UL << SYSBLK_LOGUART_EN_Pos) /*!< Bit mask of */
+
+/* Bit 5 : BIT_SOC_eFLASH_EN. 1. enable eflash controller */
+#define SYSBLK_EFLASH_EN_Pos (5UL) /*!< Position of . */
+#define SYSBLK_EFLASH_EN_Msk (0x1UL << SYSBLK_EFLASH_EN_Pos) /*!< Bit mask of */
+
+/* Bit 4 : BIT_SOC_FLASH_EN. 1: enaable flash controller */
+#define SYSBLK_EXTFLASH_EN_Pos (4UL) /*!< Position of . */
+#define SYSBLK_EXTFLASH_EN_Msk (0x1UL << SYSBLK_EXTFLASH_EN_Pos) /*!< Bit mask of */
+
+/* Bit 2 : BIT_SOC_BTBUS_EN. 1: enable BT function */
+#define SYSBLK_BTBUS_EN_Pos (2UL) /*!< Position of . */
+#define SYSBLK_BTBUS_EN_Msk (0x1UL << SYSBLK_BTBUS_EN_Pos) /*!< Bit mask of */
+
+
+/* Register: REG_SOC_PERI_FUNC0_EN */
+/* Description: REG_SOC_PERI_FUNC0_EN. */
+
+/* Bit 24 : BIT_PERI_SPI2W_EN. 1: enable 2-wire/3-wire SPI interface */
+#define SYSBLK_SPI2W_EN_Pos (24UL) /*!< Position of */
+#define SYSBLK_SPI2W_EN_Msk (0x1UL << SYSBLK_SPI2W_EN_Pos) /*!< Bit mask of */
+
+/* Bit 19 : BIT_PERI_KEYSCAN_EN. 1: enable KEYSCAN interface */
+#define SYSBLK_KEYSCAN_EN_Pos (19UL) /*!< Position of . */
+#define SYSBLK_KEYSCAN_EN_Msk (0x1UL << SYSBLK_KEYSCAN_EN_Pos) /*!< Bit mask of */
+
+/* Bit 18 : BIT_PERI_QDECODE_EN. 1: enable QDECODE interface */
+#define SYSBLK_QDECODE_EN_Pos (18UL) /*!< Position of . */
+#define SYSBLK_QDECODE_EN_Msk (0x1UL << SYSBLK_QDECODE_EN_Pos) /*!< Bit mask of */
+
+/* Bit 17 : BIT_PERI_I2C1_EN. 1: enable I2C1 interface */
+#define SYSBLK_I2C1_EN_Pos (17UL) /*!< Position of . */
+#define SYSBLK_I2C1_EN_Msk (0x1UL << SYSBLK_I2C1_EN_Pos) /*!< Bit mask of */
+
+/* Bit 16 : BIT_PERI_I2C0_EN. 1: enable I2C0 interface */
+#define SYSBLK_I2C0_EN_Pos (16UL) /*!< Position of . */
+#define SYSBLK_I2C0_EN_Msk (0x1UL << SYSBLK_I2C0_EN_Pos) /*!< Bit mask of */
+
+/* Bit 10 : BIT_PERI_IR_EN. 1: enable IR interface */
+#define SYSBLK_IR_EN_Pos (10UL) /*!< Position of . */
+#define SYSBLK_IR_EN_Msk (0x1UL << SYSBLK_IR_EN_Pos) /*!< Bit mask of */
+
+/* Bit 9 : BIT_PERI_SPI1_EN. 1: enable SPI1 interface */
+#define SYSBLK_SPI1_EN_Pos (9UL) /*!< Position of . */
+#define SYSBLK_SPI1_EN_Msk (0x1UL << SYSBLK_SPI1_EN_Pos) /*!< Bit mask of */
+
+/* Bit 8 : BIT_PERI_SPI0_EN. 1: enable SPI0 interface */
+#define SYSBLK_SPI0_EN_Pos (8UL) /*!< Position of . */
+#define SYSBLK_SPI0_EN_Msk (0x1UL << SYSBLK_SPI0_EN_Pos) /*!< Bit mask of */
+
+/* Bit 1 : BIT_PERI_UART1_EN. 1; enable UART1 interface ( DATA Uart1) */
+#define SYSBLK_UART1_EN_Pos (1UL) /*!< Position of . */
+#define SYSBLK_UART1_EN_Msk (0x1UL << SYSBLK_UART1_EN_Pos) /*!< Bit mask of */
+
+/* Bit 0 : BIT_PERI_UART0_EN. 1; enable UART0 interface ( DATA Uart) */
+#define SYSBLK_UART0_EN_Pos (0UL) /*!< Position of . */
+#define SYSBLK_UART0_EN_Msk (0x1UL << SYSBLK_UART0_EN_Pos) /*!< Bit mask of */
+
+
+/* Register: REG_SOC_PERI_FUNC1_EN */
+/* Description: REG_SOC_PERI_FUNC1_EN. */
+
+/* Bit 8 : BIT_PERI_GPIO_EN. 1: enable DW GPIO */
+#define SYSBLK_GPIO_EN_Pos (8UL) /*!< Position of */
+#define SYSBLK_GPIO_EN_Msk (0x1UL << SYSBLK_GPIO_EN_Pos) /*!< Bit mask of */
+
+/* Bit 0 : BIT_PERI_ADC_EN. 1: enable ADC */
+#define SYSBLK_ADC_EN_Pos (0UL) /*!< Position of . */
+#define SYSBLK_ADC_EN_Msk (0x1UL << SYSBLK_ADC_EN_Pos) /*!< Bit mask of */
+
+
+/* Register: REG_PESOC_CLK_CTRL */
+/* Description: REG_PESOC_CLK_CTRL. */
+
+/* Bit 25 : BIT_SOC_SLPCK_GPIO_EN */
+#define SYSBLK_SLPCK_GPIO_EN_Pos (25UL) /*!< Position of */
+#define SYSBLK_SLPCK_GPIO_EN_Msk (0x1UL << SYSBLK_SLPCK_GPIO_EN_Pos) /*!< Bit mask of */
+
+/* Bit 24 : BIT_SOC_ACTCK_GPIO_EN */
+#define SYSBLK_ACTCK_GPIO_EN_Pos (24UL) /*!< Position of */
+#define SYSBLK_ACTCK_GPIO_EN_Msk (0x1UL << SYSBLK_ACTCK_GPIO_EN_Pos) /*!< Bit mask of */
+
+/* Bit 17 : BIT_SOC_SLPCK_GDMA0_EN */
+#define SYSBLK_SLPCK_GDMA0_EN_Pos (17UL) /*!< Position of */
+#define SYSBLK_SLPCK_GDMA0_EN_Msk (0x1UL << SYSBLK_SLPCK_GDMA0_EN_Pos) /*!< Bit mask of */
+
+/* Bit 16 : BIT_SOC_ACTCK_GDMA0_EN */
+#define SYSBLK_ACTCK_GDMA0_EN_Pos (16UL) /*!< Position of */
+#define SYSBLK_ACTCK_GDMA0_EN_Msk (0x1UL << SYSBLK_ACTCK_GDMA0_EN_Pos) /*!< Bit mask of */
+
+/* Bit 15 : BIT_SOC_SLPCK_TIMER_EN */
+#define SYSBLK_SLPCK_TIMER_EN_Pos (15UL) /*!< Position of */
+#define SYSBLK_SLPCK_TIMER_EN_Msk (0x1UL << SYSBLK_SLPCK_TIMER_EN_Pos) /*!< Bit mask of */
+
+/* Bit 14 : BIT_SOC_ACTCK_TIMER_EN */
+#define SYSBLK_ACTCK_TIMER_EN_Pos (14UL) /*!< Position of */
+#define SYSBLK_ACTCK_TIMER_EN_Msk (0x1UL << SYSBLK_ACTCK_TIMER_EN_Pos) /*!< Bit mask of */
+
+/* Bit 13 : BIT_SOC_SLPCK_LOG_UART_EN */
+#define SYSBLK_SLPCK_LOGUART_EN_Pos (13UL) /*!< Position of */
+#define SYSBLK_SLPCK_LOGUART_EN_Msk (0x1UL << SYSBLK_SLPCK_LOGUART_EN_Pos) /*!< Bit mask of */
+
+/* Bit 12 : BIT_SOC_ACTCK_LOG_UART_EN */
+#define SYSBLK_ACTCK_LOGUART_EN_Pos (12UL) /*!< Position of */
+#define SYSBLK_ACTCK_LOGUART_EN_Msk (0x1UL << SYSBLK_ACTCK_LOGUART_EN_Pos) /*!< Bit mask of */
+
+/* Bit 11 : BIT_SOC_SLPCK_UART1_DATA_EN */
+#define SYSBLK_SLPCK_UART1DATA_EN_Pos (11UL) /*!< Position of */
+#define SYSBLK_SLPCK_UART1DATA_EN_Msk (0x1UL << SYSBLK_SLPCK_UART1DATA_EN_Pos) /*!< Bit mask of */
+
+/* Bit 10 : BIT_SOC_ACTCK_UART1_DATA_EN */
+#define SYSBLK_ACTCK_UART1DATA_EN_Pos (10UL) /*!< Position of */
+#define SYSBLK_ACTCK_UART1DATA_EN_Msk (0x1UL << SYSBLK_ACTCK_UART1DATA_EN_Pos) /*!< Bit mask of */
+
+/* Bit 9 : BIT_SOC_SLPCK_FLASH_EN */
+#define SYSBLK_SLPCK_FLASH_EN_Pos (9UL) /*!< Position of */
+#define SYSBLK_SLPCK_FLASH_EN_Msk (0x1UL << SYSBLK_SLPCK_FLASH_EN_Pos) /*!< Bit mask of */
+
+/* Bit 8 : BIT_SOC_ACTCK_FLASH_EN */
+#define SYSBLK_ACTCK_FLASH_EN_Pos (8UL) /*!< Position of */
+#define SYSBLK_ACTCK_FLASH_EN_Msk (0x1UL << SYSBLK_ACTCK_FLASH_EN_Pos) /*!< Bit mask of */
+
+/* Bit 7 : BIT_SOC_SLPCK_VENDOR_REG_EN */
+#define SYSBLK_SLPCK_VENDORREG_EN_Pos (7UL) /*!< Position of */
+#define SYSBLK_SLPCK_VENDORREG_EN_Msk (0x1UL << SYSBLK_SLPCK_VENDORREG_EN_Pos) /*!< Bit mask of */
+
+/* Bit 6 : BIT_SOC_ACTCK_VENDOR_REG_EN */
+#define SYSBLK_ACTCK_VENDORREG_EN_Pos (6UL) /*!< Position of */
+#define SYSBLK_ACTCK_VENDORREG_EN_Msk (0x1UL << SYSBLK_ACTCK_VENDORREG_EN_Pos) /*!< Bit mask of */
+
+/* Bit 3 : BIT_CKE_EFC. Embedded flash controller clock enable */
+#define SYSBLK_EFLASH_CLK_EN_Pos (3UL) /*!< Position of */
+#define SYSBLK_EFLASH_CLK_Msk (0x1UL << SYSBLK_EFLASH_CLK_EN_Pos) /*!< Bit mask of */
+
+/* Bit 1 : BIT_CKE_CORDIC. CORDIC clock enable */
+#define SYSBLK_CODEC_CLK_EN_Pos (1UL) /*!< Position of */
+#define SYSBLK_CODEC_CLK_EN_Msk (0x1UL << SYSBLK_CODEC_CLK_EN_Pos) /*!< Bit mask of */
+
+/* Bit 0 : BIT_CKE_HWSPI. HWSPI clock enable */
+#define SYSBLK_HWSPI_CLK_EN_Pos (0UL) /*!< Position of */
+#define SYSBLK_HWSPI_CLK_EN_Msk (0x1UL << SYSBLK_HWSPI_CLK_EN_Pos) /*!< Bit mask of */
+#define SYSBLK_ADC_EN_Msk (0x1UL << SYSBLK_ADC_EN_Pos) /*!< Bit mask of */
+
+
+/* Register: REG_PESOC_PERI_CLK_CTRL0 */
+/* Description: REG_PESOC_PERI_CLK_CTRL0. */
+
+/* Bit 21 : BIT_SOC_SLPCK_IR_EN. 1: IR clock enable when CPU sleep command */
+#define SYSBLK_SLPCK_IR_EN_Pos (21UL) /*!< Position of */
+#define SYSBLK_SLPCK_IR_EN_Msk (0x1UL << SYSBLK_SLPCK_IR_EN_Pos) /*!< Bit mask of */
+
+/* Bit 20 : BIT_SOC_ACTCK_IR_EN */
+#define SYSBLK_ACTCK_IR_EN_Pos (20UL) /*!< Position of */
+#define SYSBLK_ACTCK_IR_EN_Msk (0x1UL << SYSBLK_ACTCK_IR_EN_Pos) /*!< Bit mask of */
+
+/* Bit 19 : BIT_SOC_SLPCK_SPI1_EN */
+#define SYSBLK_SLPCK_SPI1_EN_Pos (19UL) /*!< Position of */
+#define SYSBLK_SLPCK_SPI1_EN_Msk (0x1UL << SYSBLK_SLPCK_SPI1_EN_Pos) /*!< Bit mask of */
+
+/* Bit 18 : BIT_SOC_ACTCK_SPI1_EN */
+#define SYSBLK_ACTCK_SPI1_EN_Pos (18UL) /*!< Position of */
+#define SYSBLK_ACTCK_SPI1_EN_Msk (0x1UL << SYSBLK_ACTCK_SPI1_EN_Pos) /*!< Bit mask of */
+
+/* Bit 17 : BIT_SOC_SLPCK_SPI0_EN */
+#define SYSBLK_SLPCK_SPI0_EN_Pos (17UL) /*!< Position of */
+#define SYSBLK_SLPCK_SPI0_EN_Msk (0x1UL << SYSBLK_SLPCK_SPI0_EN_Pos) /*!< Bit mask of */
+
+/* Bit 16 : BIT_SOC_ACTCK_SPI0_EN */
+#define SYSBLK_ACTCK_SPI0_EN_Pos (16UL) /*!< Position of */
+#define SYSBLK_ACTCK_SPI0_EN_Msk (0x1UL << SYSBLK_ACTCK_SPI0_EN_Pos) /*!< Bit mask of */
+
+/* Bit 3 : BIT_SOC_SLPCK_UART1_HCI_EN */
+#define SYSBLK_SLPCK_UART1HCI_EN_Pos (3UL) /*!< Position of */
+#define SYSBLK_SLPCK_UART1HCI_EN_Msk (0x1UL << SYSBLK_SLPCK_UART1HCI_EN_Pos) /*!< Bit mask of */
+
+/* Bit 2 : BIT_SOC_ACTCK_UART1_HCI_EN */
+#define SYSBLK_ACTCK_UART1HCI_EN_Pos (2UL) /*!< Position of */
+#define SYSBLK_ACTCK_UART1HCI_EN_Msk (0x1UL << SYSBLK_ACTCK_UART1HCI_EN_Pos) /*!< Bit mask of */
+
+/* Bit 1 : BIT_SOC_SLPCK_UART0_DATA_EN */
+#define SYSBLK_SLPCK_UART0DATA_EN_Pos (1UL) /*!< Position of */
+#define SYSBLK_SLPCK_UART0DATA_EN_Msk (0x1UL << SYSBLK_SLPCK_UART0DATA_EN_Pos) /*!< Bit mask of */
+
+/* Bit 0 : BIT_SOC_ACTCK_UART0_DATA_EN */
+#define SYSBLK_ACTCK_UART0DATA_EN_Pos (0UL) /*!< Position of */
+#define SYSBLK_ACTCK_UART0DATA_EN_Msk (0x1UL << SYSBLK_ACTCK_UART0DATA_EN_Pos) /*!< Bit mask of */
+
+
+/* Register: REG_PESOC_PERI_CLK_CTRL1 */
+/* Description: REG_PESOC_PERI_CLK_CTRL1. */
+
+/* Bit 31 : r_CODEC_CLK_10M_EN. Codec 10MHz clock source enable */
+#define SYSBLK_CODEC_CLK10M_EN_Pos (31UL) /*!< Position of */
+#define SYSBLK_CODEC_CLK10M_EN_Msk (0x1UL << SYSBLK_CODEC_CLK10M_EN_Pos) /*!< Bit mask of */
+
+/* Bit 30 : r_CODEC_CLK_40M_EN */
+#define SYSBLK_CODEC_CLK40M_EN_Pos (30UL) /*!< Position of */
+#define SYSBLK_CODEC_CLK40M_EN_Msk (0x1UL << SYSBLK_CODEC_CLK40M_EN_Pos) /*!< Bit mask of */
+
+/* Bit 25 : BIT_SOC_SLPCK_ADC_EN */
+#define SYSBLK_SLPCK_ADC_EN_Pos (25UL) /*!< Position of */
+#define SYSBLK_SLPCK_ADC_EN_Msk (0x1UL << SYSBLK_SLPCK_ADC_EN_Pos) /*!< Bit mask of */
+
+/* Bit 24 : BIT_SOC_ACTCK_ADC_EN */
+#define SYSBLK_ACTCK_ADC_EN_Pos (24UL) /*!< Position of */
+#define SYSBLK_ACTCK_ADC_EN_Msk (0x1UL << SYSBLK_ACTCK_ADC_EN_Pos) /*!< Bit mask of */
+
+/* Bit 17 : BIT_SOC_SLPCK_SPI_3WIRE_EN */
+#define SYSBLK_SLPCK_SPI2WIRE_EN_Pos (17UL) /*!< Position of */
+#define SYSBLK_SLPCK_SPI2WIRE_EN_Msk (0x1UL << SYSBLK_SLPCK_SPI2WIRE_EN_Pos) /*!< Bit mask of */
+
+/* Bit 16 : BIT_SOC_ACTCK_SPI_3WIRE_EN */
+#define SYSBLK_ACTCK_SPI2WIRE_EN_Pos (16UL) /*!< Position of */
+#define SYSBLK_ACTCK_SPI2WIRE_EN_Msk (0x1UL << SYSBLK_ACTCK_SPI2WIRE_EN_Pos) /*!< Bit mask of */
+
+/* Bit 7 : BIT_SOC_SLPCK_KEYSCAN_EN */
+#define SYSBLK_SLPCK_KEYSCAN_EN_Pos (7UL) /*!< Position of */
+#define SYSBLK_SLPCK_KEYSCAN_EN_Msk (0x1UL << SYSBLK_SLPCK_KEYSCAN_EN_Pos) /*!< Bit mask of */
+
+/* Bit 6 : BIT_SOC_ACTCK_KEYSCAN_EN */
+#define SYSBLK_ACTCK_KEYSCAN_EN_Pos (6UL) /*!< Position of */
+#define SYSBLK_ACTCK_KEYSCAN_EN_Msk (0x1UL << SYSBLK_ACTCK_KEYSCAN_EN_Pos) /*!< Bit mask of */
+
+/* Bit 5 : BIT_SOC_SLPCK_QDECODE_EN */
+#define SYSBLK_SLPCK_QDECODE_EN_Pos (5UL) /*!< Position of */
+#define SYSBLK_SLPCK_QDECODE_EN_Msk (0x1UL << SYSBLK_SLPCK_QDECODE_EN_Pos) /*!< Bit mask of */
+
+/* Bit 4 : BIT_SOC_ACTCK_QDECODE_EN */
+#define SYSBLK_ACTCK_QDECODE_EN_Pos (4UL) /*!< Position of */
+#define SYSBLK_ACTCK_QDECODE_EN_Msk (0x1UL << SYSBLK_ACTCK_QDECODE_EN_Pos) /*!< Bit mask of */
+
+/* Bit 3 : BIT_SOC_SLPCK_I2C1_EN */
+#define SYSBLK_SLPCK_I2C1_EN_Pos (3UL) /*!< Position of */
+#define SYSBLK_SLPCK_I2C1_EN_Msk (0x1UL << SYSBLK_SLPCK_I2C1_EN_Pos) /*!< Bit mask of */
+
+/* Bit 2 : BIT_SOC_ACTCK_I2C1_EN */
+#define SYSBLK_ACTCK_I2C1_EN_Pos (2UL) /*!< Position of */
+#define SYSBLK_ACTCK_I2C1_EN_Msk (0x1UL << SYSBLK_ACTCK_I2C1_EN_Pos) /*!< Bit mask of */
+
+/* Bit 1 : BIT_SOC_SLPCK_I2C0_EN */
+#define SYSBLK_SLPCK_I2C0_EN_Pos (1UL) /*!< Position of */
+#define SYSBLK_SLPCK_I2C0_EN_Msk (0x1UL << SYSBLK_SLPCK_I2C0_EN_Pos) /*!< Bit mask of */
+
+/* Bit 0 : BIT_SOC_ACTCK_I2C0_EN */
+#define SYSBLK_ACTCK_I2C0_EN_Pos (0UL) /*!< Position of */
+#define SYSBLK_ACTCK_I2C0_EN_Msk (0x1UL << SYSBLK_ACTCK_I2C0_EN_Pos) /*!< Bit mask of */
+
+
+/* Register: REG_PESOC_COM_CLK_CTRL1 */
+/* Description: REG_PESOC_COM_CLK_CTRL1. */
+
+/* Bit 1 : BIT_SOC_SLPCK_BTBUS_EN. 1: BTBUS clock enable when CPU sleep mode */
+#define SYSBLK_SLPCK_BTBUS_EN_Pos (1UL) /*!< Position of */
+#define SYSBLK_SLPCK_BTBUS_EN_Msk (0x1UL << SYSBLK_SLPCK_BTBUS_EN_Pos) /*!< Bit mask of */
+
+/* Bit 0 : BIT_SOC_ACTCK_BTBUS_EN. 1: BTBUS clock enable in CPU run mode */
+#define SYSBLK_ACTCK_BTBUS_EN_Pos (0UL) /*!< Position of */
+#define SYSBLK_ACTCK_BTBUS_EN_Msk (0x1UL << SYSBLK_ACTCK_BTBUS_EN_Pos) /*!< Bit mask of */
+
+
+/****************************************************************************************************************/
+/* Peripheral: Quad Decoder */
+/* Description: Quad Decoder */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/inc/peripheral/rtl876x_captouch.h b/inc/peripheral/rtl876x_captouch.h
new file mode 100644
index 0000000..494b281
--- /dev/null
+++ b/inc/peripheral/rtl876x_captouch.h
@@ -0,0 +1,895 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_captouch.h
+* \brief The header file of the peripheral CAP TOUCH driver.
+* \details This file provides all CAP TOUCH firmware functions.
+* \author Yuan
+* \date 2020-11-11
+* \version v1.0.0
+* *********************************************************************************************************
+*/
+
+#ifndef _RTL876X_CAPTOUCH_H_
+#define _RTL876X_CAPTOUCH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup CTC CAP TOUCH CONTROLLER
+ * \brief Manage the CAP TOUCH peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+
+/*============================================================================*
+ * Registers Definitions
+ *============================================================================*/
+
+/* Peripheral: CTC */
+/* Description: Cap touch register defines */
+
+/* Register: CR */
+/* Description: CTC Control Register 0. Offset: 0x00. Address: 0x40007000. */
+
+/* CR[8] :CTC_BASELINE_INI. Baseline initial function enable. 0x1: Enable. 0x0: Disable. */
+#define CTC_BASELINE_INI_Pos (8UL)
+#define CTC_BASELINE_INI_Msk (0x1UL << CTC_BASELINE_INI_Pos)
+#define CTC_BASELINE_INI_CLR (~(CTC_BASELINE_INI_Msk))
+
+/* CR[6:5] :CTC_DEBOUNCE_TIME. De-bounce time setting. 0x1: Enable. 0x0: Disable. */
+#define CTC_DEBOUNCE_TIME_Pos (5UL)
+#define CTC_DEBOUNCE_TIME_Msk (0x03UL << CTC_DEBOUNCE_TIME_Pos)
+#define CTC_DEBOUNCE_TIME_CLR (~(CTC_DEBOUNCE_TIME_Msk))
+
+/* CR[4] :CTC_DEBOUNCE_EN. De-bounce function control. 0x1: Enable. 0x0: Disable. */
+#define CTC_DEBOUNCE_EN_Pos (4UL)
+#define CTC_DEBOUNCE_EN_Msk (0x1UL << CTC_DEBOUNCE_EN_Pos)
+#define CTC_DEBOUNCE_EN_CLR (~(CTC_DEBOUNCE_EN_Msk))
+
+/* CR[0] :CTC_CT_EN. Cap touch function control. 0x1: Enable. 0x0: Disable. */
+#define CTC_CT_EN_Pos (0UL)
+#define CTC_CT_EN_Msk (0x1UL << CTC_CT_EN_Pos)
+#define CTC_CT_EN_Clr (~(CTC_CT_EN_Msk))
+
+/* Register: SCAN_PERIOD */
+/* Description: Scan period Register 0. Offset: 0x04. Address: 0x40007004. */
+
+/* SCAN_PERIOD[18:16] :CTC_SAMPLE_AVE. ADC Sampled number for average function. */
+#define CTC_SAMPLE_AVE_Pos (16UL)
+#define CTC_SAMPLE_AVE_Msk (0x7UL << CTC_SAMPLE_AVE_Pos)
+#define CTC_SAMPLE_AVE_Clr (~(CTC_SAMPLE_AVE_Msk))
+
+/* SCAN_PERIOD[11:0] :CTC_SCAN_INTERVAL. Scan interval setting. */
+#define CTC_SCAN_INTERVAL_Pos (0UL)
+#define CTC_SCAN_INTERVAL_Msk (0xFFFUL << CTC_SCAN_INTERVAL_Pos)
+#define CTC_SCAN_INTERVAL_Clr (~(CTC_SCAN_INTERVAL_Msk))
+
+/* Register: ETC_CR */
+/* Description: ETC Register 0. Offset: 0x08. Address: 0x40007008. */
+
+/* ETC_CR[15:12] :CTC_BASELINE_UPDATE_STEP. Baseline update step every time for all channel. Default: 0001. */
+#define CTC_BASELINE_UPDATE_STEP_Pos (12UL)
+#define CTC_BASELINE_UPDATE_STEP_Msk (0xFUL << CTC_BASELINE_UPDATE_STEP_Pos)
+#define CTC_BASELINE_UPDATE_STEP_Clr (~(CTC_BASELINE_UPDATE_STEP_Msk))
+
+/* ETC_CR[11:8] :CTC_BASELINE_UPD_WT_FACTOR. Baseline update weight factor for all channels. */
+#define CTC_BASELINE_UPD_WT_FACTOR_Pos (8UL)
+#define CTC_BASELINE_UPD_WT_FACTOR_Msk (0xFUL << CTC_BASELINE_UPD_WT_FACTOR_Pos)
+#define CTC_BASELINE_UPD_WT_FACTOR_Clr (~(CTC_BASELINE_UPD_WT_FACTOR_Msk))
+
+/* ETC_CR[7:1] :CTC_ETC_UPDATE_INTERVAL. ETC update interval between 2 scan period(sleep time )for all channel. */
+#define CTC_ETC_UPDATE_INTERVAL_Pos (1UL)
+#define CTC_ETC_UPDATE_INTERVAL_Msk (0x7FUL << CTC_ETC_UPDATE_INTERVAL_Pos)
+#define CTC_ETC_UPDATE_INTERVAL_Clr (~(CTC_ETC_UPDATE_INTERVAL_Msk))
+
+/* ETC_CR[0] :CTC_ETC_EN. Environmental cap tracking calibration function. 0x1: Enable. 0x0: Disable. */
+#define CTC_ETC_EN_Pos (0UL)
+#define CTC_ETC_EN_Msk (0x1UL << CTC_ETC_EN_Pos)
+#define CTC_ETC_EN_Clr (~(CTC_ETC_EN_Msk))
+
+/* Register: SNR_INF */
+/* Description: Scan period Register 0. Offset: 0x0C. Address: 0x4000700C. */
+
+/* SNR_INF[31] :CTC_SNR_UPDATE_MODE. SNR update mode. */
+#define CTC_SNR_UPDATE_MODE_Pos (31UL)
+#define CTC_SNR_UPDATE_MODE_Msk (0x1UL << CTC_SNR_UPDATE_MODE_Pos)
+#define CTC_SNR_UPDATE_MODE_Clr (~(CTC_SNR_UPDATE_MODE_Msk))
+
+/* Register: CTC_GUARD_CNT */
+/* Description: Guard counter Register. Offset: 0x1C. Address: 0x4000701C. */
+
+/* CTC_GUARD_CNT[20:16] :CTC_DLY_GUARD_INTERVAL. Delay guard interval,1 unit for 32k clock period (31.25us). */
+#define CTC_DLY_GUARD_INTERVAL_Pos (16UL)
+#define CTC_DLY_GUARD_INTERVAL_Msk (0x1FUL << CTC_DLY_GUARD_INTERVAL_Pos)
+#define CTC_DLY_GUARD_INTERVAL_Clr (~(CTC_DLY_GUARD_INTERVAL_Msk))
+
+/* CTC_GUARD_CNT[4:0] :CTC_ADV_GUARD_INTERVAL. Advanced guard interval,1 unit for 32k clock period (31.25us). */
+#define CTC_ADV_GUARD_INTERVAL_Pos (0UL)
+#define CTC_ADV_GUARD_INTERVAL_Msk (0x1FUL << CTC_ADV_GUARD_INTERVAL_Pos)
+#define CTC_ADV_GUARD_INTERVAL_Clr (~(CTC_ADV_GUARD_INTERVAL_Msk))
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/**
+ * \defgroup CTC_Exported_Constants Macro Definitions
+ * \ingroup CTC
+ */
+
+#define IS_CTC_PERIPH(PERIPH) ((PERIPH) == CTC)
+#define IS_CTC_CHANNEL(CH) (((CH) == CTC_Channel0)\
+ ||((CH) == CTC_Channel1))
+
+/* CTC private defines */
+#define CTC_ANA_ADC_REG0X_LPAD *((volatile uint32_t *)0x40007400UL)
+#define CTC_ANA_ADC_REG1X_LPAD *((volatile uint32_t *)0x40007404UL)
+#define CTC_ANA_ADC_REG0X_LPSD *((volatile uint32_t *)0x40007408UL)
+#define CTC_ANA_ADC_TIME_SET *((volatile uint32_t *)0x4000740CUL)
+#define CTC_ANA_ADC_POWER_SEQ *((volatile uint32_t *)0x40007410UL)
+
+#define CTC_CLOCK_SOURCE_1M 1000000
+#define CTC_CLOCK_SOURCE_40M 40000000
+
+typedef enum
+{
+ CTC_SLOW_MODE = 0,
+ CTC_FAST_MODE = 1
+} E_CTC_MODE;
+
+#define IS_CTC_MODE(mode) (((mode) == CTC_SLOW_MODE) || ((mode) == CTC_FAST_MODE))
+
+typedef enum
+{
+ CTC_TOUCH_JUDGEMENT_DIFFEENCE = 0,
+ CTC_TOUCH_JUDGEMENT_ABSOLUTE = 1,
+} E_CTC_TOUCH_JUDGEMENT_MODE;
+
+#define IS_CTC_TOUCH_JUDGEMENT_MODE(mode) (((mode) == CTC_TOUCH_JUDGEMENT_DIFFEENCE) || ((mode) == CTC_TOUCH_JUDGEMENT_ABSOLUTE))
+
+/**
+ * \defgroup CTC_BaselineIni_Enable CTC BaselineIni Enable
+ * \{
+ * \ingroup CTC_Exported_Constants
+ */
+#define CTC_BASELINEINI_DISABLE 0x00
+#define CTC_BASELINEINI_ENABLE 0x01
+/** \} */
+
+/**
+ * \defgroup CTC_Debounce_Times CTC Debounce Times
+ * \{
+ * \ingroup CTC_Exported_Constants
+ */
+#define CTC_DEBOUNCE_TIMES_2 0x00
+#define CTC_DEBOUNCE_TIMES_3 0x01
+#define CTC_DEBOUNCE_TIMES_4 0x02
+#define CTC_DEBOUNCE_TIMES_5 0x03
+/** \} */
+
+/**
+ * \defgroup CTC_Interrupts_Definition CTC Interrupts Definition
+ * \{
+ * \ingroup CTC_Exported_Constants
+ */
+#define CTC_DEBOUNCE_DISABLE 0x00
+#define CTC_DEBOUNCE_ENABLE 0x01
+/** \} */
+
+/**
+ * \defgroup CTC_Enable CTC Enable
+ * \{
+ * \ingroup CTC_Exported_Constants
+ */
+#define CTC_DISABLE 0x00
+#define CTC_ENABLE 0x01
+/** \} */
+
+/**
+ * \defgroup CTC_Sample_Time CTC Sample Time
+ * \{
+ * \ingroup CTC_Exported_Constants
+ */
+#define CTC_SAMPLE_TIME_AVE_4 0x00
+#define CTC_SAMPLE_TIME_AVE_8 0x01
+#define CTC_SAMPLE_TIME_AVE_16 0x02
+#define CTC_SAMPLE_TIME_AVE_32 0x03
+#define CTC_SAMPLE_TIME_AVE_64 0x04
+#define CTC_SAMPLE_TIME_AVE_128 0x05
+#define CTC_SAMPLE_TIME_AVE_256 0x06
+#define CTC_SAMPLE_TIME_AVE_512 0x07
+/** \} */
+
+/**
+ * \defgroup CTC_Scan_Interval CTC Scan Interval
+ * \{
+ * \ingroup CTC_Exported_Constants
+ */
+#define CTC_SCAN_INTERVAL_60ms 0x3C
+#define CTC_SCAN_INTERVAL_100ms 0x64
+#define CTC_SCAN_INTERVAL_140ms 0x8C
+#define CTC_SCAN_INTERVAL_180ms 0xB4
+#define CTC_SCAN_INTERVAL_220ms 0xDC
+#define CTC_SCAN_INTERVAL_260ms 0x104
+#define CTC_SCAN_INTERVAL_300ms 0x12C
+#define CTC_SCAN_INTERVAL_480ms 0x1E0
+/** \} */
+
+/**
+ * \defgroup CTC_Interrupts_Definition CTC Interrupts Definition
+ * \{
+ * \ingroup CTC_Exported_Constants
+ */
+#define CTC_INT_FALSE_TOUCH_CH1 BIT20
+#define CTC_INT_FALSE_TOUCH_CH0 BIT19
+#define CTC_INT_N_NOISE_THD BIT18
+#define CTC_INT_FIFO_OVERFLOW BIT17
+#define CTC_INT_P_NOISE_THD BIT16
+#define CTC_INT_TOUCH_RELEASE_CH1 BIT9
+#define CTC_INT_TOUCH_RELEASE_CH0 BIT8
+#define CTC_INT_TOUCH_PRESS_CH1 BIT1
+#define CTC_INT_TOUCH_PRESS_CH0 BIT0
+/** \} */
+
+#define IS_CTC_INT(INT) (((INT) == CTC_INT_FALSE_TOUCH_CH1) || \
+ ((INT) == CTC_INT_FALSE_TOUCH_CH0) || \
+ ((INT) == CTC_INT_N_NOISE_THD) || \
+ ((INT) == CTC_INT_FIFO_OVERFLOW) || \
+ ((INT) == CTC_INT_P_NOISE_THD) || \
+ ((INT) == CTC_INT_TOUCH_RELEASE_CH1) || \
+ ((INT) == CTC_INT_TOUCH_RELEASE_CH0) || \
+ ((INT) == CTC_INT_TOUCH_PRESS_CH1) || \
+ ((INT) == CTC_INT_TOUCH_PRESS_CH0))
+
+/**
+ * \defgroup CTC_MBIAS_Current CTC MBIAS Current
+ * \{
+ * \ingroup CTC_Exported_Constants
+ */
+#define CTC_MBIAS_0p25uA (1UL << 0)
+#define CTC_MBIAS_0p5uA (1UL << 1)
+#define CTC_MBIAS_1uA (1UL << 2)
+#define CTC_MBIAS_2uA (1UL << 3)
+#define CTC_MBIAS_4uA (1UL << 4)
+#define CTC_MBIAS_8uA (1UL << 5)
+/** \} */
+
+#define IS_CTC_MBIAS(mbias) (((mbias) == CTC_MBIAS_0p25uA) ||\
+ ((mbias) == CTC_MBIAS_0p5uA) ||\
+ ((mbias) == CTC_MBIAS_1uA ) ||\
+ ((mbias) == CTC_MBIAS_2uA ) ||\
+ ((mbias) == CTC_MBIAS_4uA ) ||\
+ ((mbias) == CTC_MBIAS_8uA ))
+
+/**
+ * \defgroup CTC_FS_Match_Count CTC FS Match Count
+ * \{
+ * \ingroup CTC_Exported_Constants
+ */
+typedef enum
+{
+ CTC_FS_Match_Cnt_No_Switch = 0x0,
+ CTC_FS_Match_Cnt_1DB = 0x01,
+ CTC_FS_Match_Cnt_2DB = 0x02,
+ CTC_FS_Match_Cnt_3DB = 0x03,
+ CTC_FS_Match_Cnt_4DB = 0x04
+} E_CTC_MODE_SWITCH;
+/** \} */
+
+#define IS_CTC_FS_Match(cnt) (((cnt) == CTC_FS_Match_Cnt_No_Switch) ||\
+ ((cnt) == CTC_FS_Match_Cnt_1DB) ||\
+ ((cnt) == CTC_FS_Match_Cnt_2DB ) ||\
+ ((cnt) == CTC_FS_Match_Cnt_3DB ) ||\
+ ((cnt) == CTC_FS_Match_Cnt_4DB ))
+
+#define CTC_CH_MAX 2
+
+/**
+ * \defgroup CTC_Channel CTC Channel
+ * \{
+ * \ingroup CTC_Exported_Constants
+ */
+typedef enum
+{
+ CTC_CH0 = 0,
+ CTC_CH1 = 1,
+} E_CTC_CH;
+/** \} */
+
+/**
+ * \cond private
+ * \defgroup CTC_FS_TOUCH_CNT_TYPE CTC FS Touch Count
+ * \{
+ */
+typedef union _FS_TOUCH_CNT01_TYPE
+{
+ uint32_t d32;
+ struct
+ {
+ uint32_t TOUCH_ACTIVE_CNT0: 10;
+ uint32_t RSVD: 6;
+ uint32_t TOUCH_ACTIVE_CNT1: 10;
+ uint32_t RSVD2: 6;
+ };
+} FS_TOUCH_CNT01_TYPE;
+
+typedef union _FS_TOUCH_CNT23_TYPE
+{
+ uint32_t d32;
+ struct
+ {
+ uint32_t TOUCH_ACTIVE_CNT2: 10;
+ uint32_t RSVD: 6;
+ uint32_t TOUCH_ACTIVE_CNT3: 10;
+ uint32_t RSVD2: 6;
+ };
+} FS_TOUCH_CNT23_TYPE;
+
+/* combine 0x158 & 0x15C for API usage */
+typedef union _FS_TOUCH_CNT_TYPE
+{
+ uint16_t d16[4];
+ struct
+ {
+ FS_TOUCH_CNT01_TYPE fs_touch_cnt_01;
+ FS_TOUCH_CNT23_TYPE fs_touch_cnt_23;
+ };
+} FS_TOUCH_CNT_TYPE;
+/**
+ * \}
+ * \endcond
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup CTC_Exported_Types Init Params Struct
+ *
+ * \ingroup CTC
+ */
+
+/**
+ * \brief CTC init structure definition.
+ *
+ * \ingroup CTC_Exported_Types
+ */
+typedef struct
+{
+ uint16_t CTC_BaselineIniEn; /**< Baseline initial function enable, HW will clear this bit to "0" after baseline initial. */
+ uint8_t CTC_DebounceTime; /**< Debounce time setting.*/
+ uint8_t CTC_DebounceEn; /**< Debounce function control: "0":disable; "1": enable.*/
+ uint32_t CTC_SampleTime; /**< ADC sample time, active time. sample_time = 2^(CTC_SampleTime+2)*131072;unit is 131.072KHz;
+ sample number=4~512.Default: 110, sample number=256. */
+ uint16_t CTC_ScanInterval; /**< Scan interval :Sleep time between 2 scan burst for all channels, range: 0~4095ms; code: 0~4095(0~0xFFF), unit is 1.024KHz cycle. (1/32 32.768KHz).
+ When this register set to 0 or 1, HW will scan continuously and has no sleep time; Recommend value: 60~480ms; Default: 0X3c(60ms).*/
+ uint16_t CTC_BaselineUpdateStep; /**< Baseline update step every time for all channel.
+ This parameter can be a value of \ref ENHTIM_Clock_Divider*/
+ uint16_t CTC_BaselineWeightFactor; /**< Baseline update weight factor for all channels; Factor=2 ^ (BASELINE_WT_FACTOR); Default: 0010.
+ This parameter can be a value of DISABLE or ENABLE */
+ uint8_t CTC_ETCScanInterval; /**< ETC update interval between 2 scan period(sleep time )for all channel:
+ Interval=(ETC_SCAN_INTERVAL+1)*Scan period; (1~128). Default: 0x2; (Update every scan period). */
+ uint8_t CTC_ETCEn; /**< Environmental cap tracking calibration function: "0":disable; "1": enable.
+ This parameter can be a value of DISABLE or ENABLE */
+ uint32_t CTC_SNRUpdateMode; /**< Specifies SNR update mode.
+ This parameter default to 0x0, which is update SNR_noise data or touch data based on touch status*/
+ uint8_t CTC_ScanChannel; /**< Specifies scan channel control.
+ This parameter default to 0x0000. */
+ uint8_t CTC_ScanChannelSwitchMode; /**< Specifies the scan channel switch control.
+ This parameter default to 1, which is auto switch to next channel.*/
+ uint32_t CTC_DelayGuardInterval; /**< Delay guard interval 1 unit for 32k clock period (31.25us).*/
+ uint32_t CTC_AdvancedGuardInterval; /**< Delay guard interval 1 unit for 32k clock period (31.25us).*/
+ uint32_t CTC_FastMatchCnt; /**< Enter Fast mode when the Debounce time matches FS_MATCH_CNT.
+ This parameter can be a value of \ref CTC_FS_Match_Coun. */
+ uint32_t CTC_FastScanInerval; /**< Specifies the scan Interval under Fast mode,range: 0~4095ms;
+ This parameter can be a range of 0~0xFFF;*/
+ uint32_t CTC_FalseTouchCnt; /**< Specifies the false touch detection after enter Fast mode (1 unit for 1scan).
+ This parameter can be a a range of 0~0x3FF. */
+ uint32_t CTC_FalseAlarmCnt; /**< Specifies the false alarm detection after enter Fast mode (1 unit for 1scan).
+ This parameter can be a a range of 0~0xF.*/
+ uint32_t CTC_ReleaseActiveCnt; /**< Specifies the determine counter value when leave Fast mode after touch release.
+ This parameter can be a a range of 0~0x3FF.*/
+} CTC_InitTypeDef;
+
+/**
+ * \brief CTC channel init structure definition.
+ *
+ * \ingroup CTC_Exported_Types
+ */
+typedef struct
+{
+ uint8_t CTC_ChannelEn; /**< Cap Sensor activity control of channelx.
+ This parameter can be a value of ENABLE or DISABLE. */
+ uint16_t CTC_BaselineData; /**< Specifies digital baseline data of channelx.
+ This parameter can be 0x0 ~ 0xFFF. */
+ uint16_t CTC_DifferenceTouchThd;/**< Difference threshold data of touch judgement for channelx.
+ This parameter can be 0x0 ~ 0xFFF. */
+ uint16_t CTC_AbsoluteTouchThd; /**< Specifies absolute threshold data of touch judgement for channelx.
+ This parameter can be 0x0 ~ 0xFFF. */
+ uint32_t CTC_PNoiseThd; /**< The environmental pasitive noise threshold: the positive maximum capacitance change of raw data that is still considered an environmental change.
+ This parameter can be 0x0 ~ 0xFF. */
+ uint32_t CTC_NNoiseThd; /**< The environmental negative noise threshold: the negative maximum capacitance change of raw data that is still considered an environmental change.
+ This parameter can be 0x0 ~ 0xFF. */
+ uint8_t CTC_MBias; /**< Specifies Channelx mbias current tuning(sensitivity tuning) Touch bias current [5:0]: 8uA/4Ua/2uA/1uA/0.5uA/0.25uA.
+ This parameter can be a value of \ref CTC_MBIAS_Current. */
+} CTC_ChannelInitTypeDef;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup CTC_Exported_Functions Peripheral APIs
+ * \{
+ * \ingroup CTC
+ */
+
+/**
+ * \brief Deinitialize the Cap Touch peripheral registers to their default reset values.
+ * \return None.
+ */
+void CTC_DeInit(void);
+
+/**
+ * \brief Enable the CTC peripheral IP clock and function.
+ * \param clock_source: CTC peripheral clock source.
+ * This parameter can be one of the following values.
+ * \arg CTC_CLOCK_SOURCE_1M: 1M clock source
+ * \arg CTC_CLOCK_SOURCE_40M: 40M clock source
+ * \return None.
+ */
+void CTC_RCCConfig(uint32_t clock_source);
+
+/**
+ * \brief Initializes the CTC peripheral according to
+ * the specified parameters in the CTC_InitStruct.
+ * \param[in] CTCx: CTC peripheral.
+ * \param[in] CTC_InitStruct: Pointer to a CTC_InitTypeDef structure that contains
+ * the configuration information for the specified CTC peripheral.
+ * \return None.
+ */
+void CTC_Init(CTC_TypeDef *CTCx, CTC_InitTypeDef *CTC_InitStruct);
+
+/**
+ * \brief Initializes the specified channel.
+ * \param CTC_Channelx: specified channel
+ * \param CTC_ChannelInitStruct: pointer to a CTC_ChannelInitTypeDef structure that
+ * contains the configuration information for the specified CTC channel.
+ * \return None
+ */
+void CTC_ChannelInit(CTC_ChannelTypeDef *CTC_Channelx,
+ CTC_ChannelInitTypeDef *CTC_ChannelInitStruct);
+
+/**
+ * \brief Fills each CTC_InitStruct member with its default value.
+ * \param CTC_InitStruct: Pointer to a CTC_InitStruct structure which will be initialized.
+ * \return None.
+ */
+void CTC_StructInit(CTC_InitTypeDef *CTC_InitStruct);
+
+/**
+ * \brief Fills each CTC_InitStruct member with its default value.
+ * \param CTC_InitStruct: Pointer to a CTC_InitStruct structure which will be initialized.
+ * \return None.
+ */
+void CTC_ChannelStructInit(CTC_ChannelInitTypeDef *CTC_ChannelInitStruct);
+
+/**
+ * \brief Enable or disable the specified Cap Touch interrupt.
+ * \param[in] CTCx: The Cap Touch peripheral.
+ * \param[in] CTC_INT: Specifies the Cap Touch interrupt source which to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * \arg CTC_INT_FALSE_TOUCH_CH1: Channel 1 Touch cnt reach false touch cnt interrupt.
+ * \arg CTC_INT_FALSE_TOUCH_CH0: Channel 0 Touch cnt reach false touch cnt interrupt.
+ * \arg CTC_INT_N_NOISE_THD: Negative noise threshold overflow interrupt.
+ * \arg CTC_INT_FIFO_OVERFLOW: Raw code FIFO over flow interrupt
+ * \arg CTC_INT_P_NOISE_THD: Positive noise threshold overflow interrupt.
+ * \arg CTC_INT_TOUCH_RELEASE_CH1: Channel x release interrupt.
+ * \arg CTC_INT_TOUCH_RELEASE_CH0: Channel x release interrupt.
+ * \arg CTC_INT_TOUCH_PRESS_CH1: Channel x press interrupt.
+ * \arg CTC_INT_TOUCH_PRESS_CH0: Channel x press interrupt.
+ * \param NewState: New state of the Cap Touch interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None
+ */
+void CTC_INTConfig(uint32_t CTC_INT, FunctionalState NewState);
+
+/**
+ * \brief Enables or disables the specified Cap Touch peripheral.
+ * \param ENHTIMx: Cap Touch peripheral.
+ * \param NewState: New state of the Cap Touch peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * \retutn None.
+ */
+void CTC_Cmd(CTC_TypeDef *CTCx, FunctionalState NewState);
+
+/**
+ * \brief Enable or disable system wake up of CTC.
+ * \param NewState: new state of the wake up function.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None
+ */
+void CTC_SystemWakeupConfig(E_CTC_CH channel, FunctionalState NewState);
+
+/**
+ * \brief Set CTC Scan interval for slow mode or fast mode.
+ * \param scan_interval: scan interval in units of 1s/1.024KHz (= 0.9765625 ms)
+ * Configurable range: 0x0~0xFFF (0~4095)
+ * Note that slow mode interval should not be lower then fast mode interval,
+ * Fast mode interval should be greater than total guard time for auxADC
+ * \param CTCMode: CTC_SLOW_MODE or CTC_FAST_MODE.
+ * \return true: success, false: interval is out of range.
+ */
+bool CTC_SetScanInterval(uint16_t scan_interval, E_CTC_MODE CTCMode);
+
+/**
+ * \brief Get touch active count from specified channel under fast mode.
+ * \param channel: specified channel
+ * \return touch active count
+ */
+uint16_t CTC_GetChannelTouchCount(E_CTC_CH channel);
+
+/**
+ * \brief Get Cap Touch baseline init status.
+ * \return Cap Touch enable status. 1: Baseline initial, 0: Baseline initial done.
+ */
+__STATIC_INLINE FlagStatus CTC_GetBaselineInistatus(void)
+{
+ return (FlagStatus)((CTC->CR & BIT8) >> 8);
+}
+
+/**
+ * \brief Get Cap Touch enable status.
+ * \return Cap Touch enable status. 1: Running, 0: Non-runnung.
+ */
+__STATIC_INLINE bool CTC_IsRunning(void)
+{
+ return (CTC->CR & BIT0);
+}
+
+/**
+ * \brief Read Cap Touch mode.
+ * \retval Cap Touch mode. 1: Fast mode, 0: Slow mode
+ */
+__STATIC_INLINE bool CTC_IsFastMode(void)
+{
+ return (CTC_FAST->TOUCH_SR & BIT8) >> 8;
+}
+
+/**
+ * \brief Check legality of specified channel.
+ * \param channel: specified channel.
+ * \return 1: Allowed, 0: Not allowed.
+ */
+__STATIC_INLINE bool CTC_IsChannelAllowed(E_CTC_CH channel)
+{
+ return (channel <= CTC_CH_MAX);
+}
+
+/**
+ * \brief Set relative touch threshold for related channel.
+ * \param channel: specified channel
+ * \param threshold: related threshold value.
+ * \return None
+ */
+__STATIC_INLINE void CTC_SetCHDifferenceThd(CTC_ChannelTypeDef *CTC_Channelx, uint16_t threshold)
+{
+ /* Check the parameters */
+// configASSERT(CTC_IsChAllowed(channel));
+// configASSERT(threshold <= 4095);
+// configASSERT(!CTC_IsRunning());
+
+ CTC_Channelx->CR |= (uint32_t)threshold << 16;
+}
+
+/**
+ * \brief Get absolute threshold of touch judgement for specified channel.
+ * \param channel: specified channel
+ * \param threshold: Threshold value
+ * \return None
+ */
+__STATIC_INLINE void CTC_SetCHAbsoluteThd(CTC_ChannelTypeDef *CTC_Channelx, uint16_t threshold)
+{
+ /* Check the parameters */
+// configASSERT(CTC_IsChAllowed(channel));
+// configASSERT(threshold <= 4095);
+// configASSERT(!CTC_IsRunning());
+
+ CTC_Channelx->TOUCH_TH |= threshold & 0xFFF;
+}
+
+/**
+ * \brief Set P noise threshold for related channel.
+ * \param channel: specified channel
+ * \param p_noise_threshold: Pnoise Threshold value.
+ * \retval None
+ */
+__STATIC_INLINE void CTC_SetCHPNoiseThd(CTC_ChannelTypeDef *CTC_Channelx, uint8_t p_noise_threshold)
+{
+ /* Check the parameters */
+// configASSERT(CTC_IsChAllowed(channel));
+// configASSERT(p_noise_threshold <= 255);
+// configASSERT(!CTC_IsRunning());
+
+ CTC_Channelx->TOUCH_TH |= (uint32_t)p_noise_threshold << 16;
+}
+
+/**
+ * \brief Set N noise threshold for related channel.
+ * \param channel: specified channel
+ * \param n_noise_threshold: Nnoise Threshold value.
+ * \return None
+ */
+__STATIC_INLINE void CTC_SetCHNNoiseThd(CTC_ChannelTypeDef *CTC_Channelx, uint8_t n_noise_threshold)
+{
+ /* Check the parameters */
+// configASSERT(CTC_IsChAllowed(channel));
+// configASSERT(n_noise_threshold <= 255);
+// configASSERT(!CTC_IsRunning());
+
+ CTC_Channelx->TOUCH_TH |= (uint32_t)n_noise_threshold << 24;
+}
+
+/**
+ * \brief Set mbias current for specified channel.
+ * \param channel: specified channel
+ * \param mbias: mbias value, relate current = 0.25*mbias.
+ * \return None.
+ */
+__STATIC_INLINE void CTC_SetChannelMbias(CTC_ChannelTypeDef *CTC_Channelx, uint8_t mbias)
+{
+// /* Check the parameters */
+// configASSERT(CTC_IsChAllowed(channel));
+// configASSERT(mbias < 64);
+// configASSERT(!CTC_IsRunning());
+
+ CTC_Channelx->MBIAS |= mbias & 0x3F;
+}
+
+/**
+ * \brief Get status for specified channel.
+ * \param channel: specified channel
+ * \return channel enable status.
+ */
+__STATIC_INLINE FlagStatus CTC_GetChannelStatus(CTC_ChannelTypeDef *CTC_Channelx)
+{
+ return (FlagStatus)(CTC_Channelx->CR & 0x1);
+}
+
+/**
+ * \brief Get Baseline data from specified channel.
+ * \param channel: Specified channel.
+ * \return Baseline data.
+ */
+__STATIC_INLINE uint16_t CTC_GetChannelBaseline(CTC_ChannelTypeDef *CTC_Channelx)
+{
+ return ((CTC_Channelx->CR & 0xFFF0) >> 4);
+}
+
+/**
+ * \brief Get relative threshold of touch judgement for specified channel.
+ * \param channel: specified channel
+ * \return Difference threshold of specified channel.
+ */
+__STATIC_INLINE uint16_t CTC_GetCHDifferenceThd(CTC_ChannelTypeDef *CTC_Channelx)
+{
+ return ((CTC_Channelx->CR >> 16) & 0xFFF);
+}
+
+/**
+ * \brief Get Absolute threshold of touch judgement for specified channel.
+ * \param channel: specified channel
+ * \return Difference threshold of specified channel.
+ */
+__STATIC_INLINE uint16_t CTC_GetCHAbsoluteThd(CTC_ChannelTypeDef *CTC_Channelx)
+{
+ return (CTC_Channelx->TOUCH_TH & 0xFFF);
+}
+
+/**
+ * \brief Get positive noise threshold for specified channel.
+ * \param CTC_Channelx: specified channel
+ * \return Noise threshold of specified channel.
+ */
+__STATIC_INLINE uint8_t CTC_GetCHPNoiseThd(CTC_ChannelTypeDef *CTC_Channelx)
+{
+ return ((CTC_Channelx->TOUCH_TH >> 16) & 0xFF);
+}
+
+/**
+ * \brief Get negative noise threshold for specified channel.
+ * \param CTC_Channelx: specified channel
+ * \return Noise threshold of specified channel.
+ */
+__STATIC_INLINE uint8_t CTC_GetCHNNoiseThd(CTC_ChannelTypeDef *CTC_Channelx)
+{
+ return ((CTC_Channelx->TOUCH_TH >> 24) & 0xFF);
+}
+
+/**
+ * \brief Get ave data from specified channel.
+ * \param channel: specified channel
+ * \retval Average data
+ */
+__STATIC_INLINE uint16_t CTC_GetChannelAveData(CTC_ChannelTypeDef *CTC_Channelx)
+{
+ return (CTC_Channelx->DATA & 0xFFF);
+}
+
+/**
+ * \brief Get Cap Touch status under fast mode.
+ * \param[in] channel: Specifies the Cap Touch channel.
+ * This parameter can be one of the following values:
+ * \arg CTC_CH3: Channel 3.
+ * \arg CTC_CH2: Channel 2.
+ * \arg CTC_CH1: Channel 1.
+ * \arg CTC_CH0: Channel 0.
+ * \return The new state of the Cap Touch channel(SET or RESET). bit4~bit0 each bit represent one channel.
+ * \retval SET: tounch.
+ * \retval RESET: un-tounch.
+ */
+__STATIC_INLINE FlagStatus CTC_GetChannelTouchStatus(E_CTC_CH channel)
+{
+ if (CTC_IsFastMode())
+ {
+ return (FlagStatus)((CTC_FAST->TOUCH_SR & 0xF) >> (uint8_t)channel);
+ }
+ else
+ {
+ return RESET;
+ }
+}
+
+/**
+ * \brief Check whether the Cap Touch interrupt has occurred or not.
+ * \param[in] CTCx: The Cap Touch peripheral.
+ * \param[in] CTC_INT: Specifies the Cap Touch interrupt has occurred or not.
+ * This parameter can be any combination of the following values:
+ * \arg CTC_INT_FALSE_TOUCH_CH1: Channel 1 Touch cnt reach false touch cnt interrupt.
+ * \arg CTC_INT_FALSE_TOUCH_CH0: Channel 0 Touch cnt reach false touch cnt interrupt.
+ * \arg CTC_INT_N_NOISE_THD: Negative noise threshold overflow interrupt.
+ * \arg CTC_INT_FIFO_OVERFLOW: Raw code FIFO over flow interrupt
+ * \arg CTC_INT_P_NOISE_THD: Positive noise threshold overflow interrupt.
+ * \arg CTC_INT_TOUCH_RELEASE_CH1: Channel 1 release interrupt.
+ * \arg CTC_INT_TOUCH_RELEASE_CH0: Channel 0 release interrupt.
+ * \arg CTC_INT_TOUCH_PRESS_CH1: Channel 1 press interrupt.
+ * \arg CTC_INT_TOUCH_PRESS_CH0: Channel 0 press interrupt.
+ * \return The new state of the CTC_INT(SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void cap_touch_demo(void)
+ * {
+ * ITStatus int_status = CTC_GetINTStatus(CTC, CTC_INT_TOUCH_PRESS_CH1);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE ITStatus CTC_GetINTStatus(CTC_TypeDef *CTCx, uint32_t CTC_INT)
+{
+ /* Check the parameters */
+ assert_param(IS_CTC_ALL_PERIPH(CTCx));
+
+ ITStatus itstatus = RESET;
+
+ if (CTCx->INT_SR & (CTC_INT))
+ {
+ itstatus = SET;
+ }
+
+ return itstatus;
+}
+
+/**
+ * \brief Get CTC Raw Interrupt (without hardware mask) Status.
+ * \param[in] CTCx: The Cap Touch peripheral.
+ * \param[in] CTC_INT: Specifies the Cap Touch interrupt has occurred or not.
+ * This parameter can be any combination of the following values:
+ * \arg CTC_INT_FALSE_TOUCH_CH1: Channel 1 Touch cnt reach false touch cnt interrupt.
+ * \arg CTC_INT_FALSE_TOUCH_CH0: Channel 0 Touch cnt reach false touch cnt interrupt.
+ * \arg CTC_INT_N_NOISE_THD: Negative noise threshold overflow interrupt.
+ * \arg CTC_INT_FIFO_OVERFLOW: Raw code FIFO over flow interrupt
+ * \arg CTC_INT_P_NOISE_THD: Positive noise threshold overflow interrupt.
+ * \arg CTC_INT_TOUCH_RELEASE_CH1: Channel 1 release interrupt.
+ * \arg CTC_INT_TOUCH_RELEASE_CH0: Channel 0 release interrupt.
+ * \arg CTC_INT_TOUCH_PRESS_CH1: Channel 1 press interrupt.
+ * \arg CTC_INT_TOUCH_PRESS_CH0: Channel 0 press interrupt.
+ * \return Raw interrupt status of the CTC_INT(SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void cap_touch_demo(void)
+ * {
+ * ITStatus int_status = CTC_GetRawINTStatus(CTC, CTC_INT_TOUCH_PRESS_CH1);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE ITStatus CTC_GetRawINTStatus(CTC_TypeDef *CTCx, uint32_t CTC_INT)
+{
+ /* Check the parameters */
+ assert_param(IS_CTC_ALL_PERIPH(CTCx));
+
+ ITStatus itstatus = RESET;
+
+ if (CTCx->RAW_INT_SR & (CTC_INT))
+ {
+ itstatus = SET;
+ }
+
+ return itstatus;
+}
+
+/**
+ * \brief Clear CTC interrupt.
+ * \param[in] CTCx: The Cap Touch peripheral.
+ * \param[in] CTC_INT: Specifies the Cap Touch interrupt source which to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * \arg CTC_INT_FALSE_TOUCH_CH1: Channel 1 Touch cnt reach false touch cnt interrupt.
+ * \arg CTC_INT_FALSE_TOUCH_CH0: Channel 0 Touch cnt reach false touch cnt interrupt.
+ * \arg CTC_INT_N_NOISE_THD: Negative noise threshold overflow interrupt.
+ * \arg CTC_INT_FIFO_OVERFLOW: Raw code FIFO over flow interrupt
+ * \arg CTC_INT_P_NOISE_THD: Positive noise threshold overflow interrupt.
+ * \arg CTC_INT_TOUCH_RELEASE_CH1: Channel x release interrupt.
+ * \arg CTC_INT_TOUCH_RELEASE_CH0: Channel x release interrupt.
+ * \arg CTC_INT_TOUCH_PRESS_CH1: Channel x press interrupt.
+ * \arg CTC_INT_TOUCH_PRESS_CH0: Channel x press interrupt.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void cap_touch_demo(void)
+ * {
+ * CTC_ClearINTPendingBit(CTC, CTC_INT_TOUCH_PRESS_CH0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void CTC_ClearINTPendingBit(CTC_TypeDef *CTCx, uint32_t CTC_INT)
+{
+ /* Check the parameters */
+ assert_param(IS_CTC_ALL_PERIPH(CTCx));
+
+ /* Clear the IT */
+ CTCx->INT_SCLR |= CTC_INT;
+}
+
+/**
+ * \brief Clear ALL CTC interrupt.
+ * \param None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void cap_touch_demo(void)
+ * {
+ * CTC_ClearAllINT();
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void CTC_ClearAllINT(void)
+{
+ /* Clear the IT */
+ CTC->INT_CLR |= BIT0;
+}
+/** \} */ /* End of group CODEC_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_CAPTOUCH_H_ */
+
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/inc/peripheral/rtl876x_codec.h b/inc/peripheral/rtl876x_codec.h
new file mode 100644
index 0000000..6fdc37b
--- /dev/null
+++ b/inc/peripheral/rtl876x_codec.h
@@ -0,0 +1,713 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_codec.h
+* \brief The header file of the peripheral CODEC driver.
+* \details This file provides all CODEC firmware functions.
+* \author Yuan
+* \date 2020-11-16
+* \version v2.1.1
+* *********************************************************************************************************
+*/
+
+#ifndef _RTL876X_CODEC_H_
+#define _RTL876X_CODEC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup CODEC CODEC
+ *
+ * \brief Manage the CODEC peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup CODEC_Exported_Types Init Params Struct
+ *
+ * \ingroup CODEC
+ */
+
+/**
+ * \brief CODEC init structure definition.
+ *
+ * \ingroup CODEC_Exported_Types
+ */
+typedef struct
+{
+ /* Basic parameters section */
+ uint32_t CODEC_SampleRate; /*!< Specifies the sample rate. */
+ uint32_t CODEC_DmicClock; /*!< Specifies the dmic clock. */
+ uint32_t CODEC_I2SFormat; /*!< Specifies the I2S Tx/Rx format of codec port. */
+ uint32_t CODEC_I2SDataWidth; /*!< Specifies the I2S Tx/Rx data width of codec port. */
+ uint32_t CODEC_I2SChSequence; /*!< Specifies the I2S Tx/Rx channel sequence. */
+ uint32_t CODEC_MicBIAS; /*!< Specifies the MICBIAS voltage. */
+ uint32_t CODEC_MicBstGain; /*!< Specifies the MICBST gain. */
+ uint32_t CODEC_MicBstMode; /*!< Specifies the MICBST mode. */
+
+ /* MIC channel 0 initialization parameters section */
+ uint32_t CODEC_Ch0Mute; /*!< Specifies the channel 0 dmic mute status. */
+ uint32_t CODEC_Ch0MicType; /*!< Specifies the channel 0 mic type, which can be dmic or amic. */
+ uint32_t CODEC_Ch0DmicDataLatch; /*!< Specifies the channel 0 dmic data latch type. */
+ uint32_t CODEC_Ch0AdGain; /*!< Specifies the channel 0 ADC digital volume. */
+ uint32_t CODEC_Ch0BoostGain; /*!< Specifies the channel 0 boost gain. */
+ uint32_t CODEC_Ch0ZeroDetTimeout; /*!< Specifies the channel 0 zero detection timeout mode control. */
+
+} CODEC_InitTypeDef;
+
+/*============================================================================*
+ * Register Defines
+ *============================================================================*/
+
+/* Peripheral: CODEC */
+/* Description: CODEC register defines */
+
+/* Register: ANA_CR0 ----------------------------------------------------------*/
+/* Description: Control register 0. Offset: 0x00. Address: 0x40022000UL. */
+
+/* ANA_CR0[10]: ADC_ANA_POW. 0x1: Powen on. 0x0: Power down. */
+#define CODEC_ADC_ANA_POW_POS (10)
+#define CODEC_ADC_ANA_POW_MSK (0x1 << CODEC_ADC_ANA_POW_POS)
+#define CODEC_ADC_ANA_POW_CLR (~CODEC_ADC_ANA_POW_MSK)
+/* ANA_CR0[9]: DTSDM_CLK_EN. 0x1: Powen on. 0x0: Power down. */
+#define CODEC_DTSDM_CLK_EN_POS (9)
+#define CODEC_DTSDM_CLK_EN_MSK (0x1 << CODEC_DTSDM_CLK_EN_POS)
+#define CODEC_DTSDM_CLK_EN_CLR (~CODEC_DTSDM_CLK_EN_MSK)
+/* ANA_CR0[0]: DAC_ADDACK_POW. 0x1: Powen on. 0x0: Power down. */
+#define CODEC_DAC_ADDACK_POW_POS (0)
+#define CODEC_DAC_ADDACK_POW_MSK (0x1 << CODEC_DAC_ADDACK_POW_POS)
+#define CODEC_DAC_ADDACK_POW_CLR (~CODEC_DAC_ADDACK_POW_MSK)
+
+/* Register: ANA_CR1 ----------------------------------------------------------*/
+/* Description: Control register 1. Offset: 0x04. Address: 0x40022004UL. */
+
+/* ANA_CR1[27:26]: VREF_SEL. */
+#define CODEC_VREF_SEL_POS (26)
+#define CODEC_VREF_SEL_MSK (0x3 << CODEC_VREF_SEL_POS)
+#define CODEC_VREF_SEL_CLR (~CODEC_VREF_SEL_MSK)
+#define CODEC_VREF_SEL_DEFAULT_MSK (0x2 << CODEC_VREF_SEL_POS)
+/* ANA_CR1[25]: MICBST_POW. */
+#define CODEC_MICBST_POW_POS (25)
+#define CODEC_MICBST_POW_MSK (0x1 << CODEC_MICBST_POW_POS)
+#define CODEC_MICBST_POW_CLR (~CODEC_MICBST_POW_MSK)
+/* ANA_CR1[21:20]: MICBST_MUTE. */
+#define CODEC_MICBST_MUTE_POS (20)
+#define CODEC_MICBST_MUTE_MSK (0x3 << CODEC_MICBST_MUTE_POS)
+#define CODEC_MICBST_MUTE_CLR (~CODEC_MICBST_MUTE_MSK)
+#define CODEC_MICBST_MUTE_MIC_MSK (0x2 << CODEC_MICBST_MUTE_POS)
+/* ANA_CR1[17:16]: MICBST_GAIN. */
+#define CODEC_MICBST_GAIN_POS (16)
+#define CODEC_MICBST_GAIN_MSK (0x3 << CODEC_MICBST_GAIN_POS)
+#define CODEC_MICBST_GAIN_CLR (~CODEC_MICBST_GAIN_MSK)
+/* ANA_CR1[15]: MICBST_VREF_POW. */
+#define CODEC_MICBST_VREF_POW_POS (15)
+#define CODEC_MICBST_VREF_POW_MSK (0x1 << CODEC_MICBST_VREF_POW_POS)
+#define CODEC_MICBST_VREF_POW_CLR (~CODEC_MICBST_VREF_POW_MSK)
+/* ANA_CR1[14]: MICBST_ENDFL. */
+#define CODEC_MICBST_ENDFL_POS (14)
+#define CODEC_MICBST_ENDFL_MSK (0x1 << CODEC_MICBST_ENDFL_POS)
+#define CODEC_MICBST_ENDFL_CLR (~CODEC_MICBST_ENDFL_MSK)
+/* ANA_CR1[13:11]: MICBIAS_VSET. */
+#define CODEC_MICBIAS_VSET_POS (11)
+#define CODEC_MICBIAS_VSET_MSK (0x7 << CODEC_MICBIAS_VSET_POS)
+#define CODEC_MICBIAS_VSET_CLR (~CODEC_MICBIAS_VSET_MSK)
+/* ANA_CR1[10]: MICBIAS_POW. 0x1: Powen on. 0x0: Power down. */
+#define CODEC_MICBIAS_POW_POS (10)
+#define CODEC_MICBIAS_POW_MSK (0x1 << CODEC_MICBIAS_POW_POS)
+#define CODEC_MICBIAS_POW_CLR (~CODEC_MICBIAS_POW_MSK)
+/* ANA_CR1[9]: MICBIAS_ENCHX. */
+#define CODEC_MICBIAS_ENCHX_POS (9)
+#define CODEC_MICBIAS_ENCHX_MSK (0x1 << CODEC_MICBIAS_ENCHX_POS)
+#define CODEC_MICBIAS_ENCHX_CLR (~CODEC_MICBIAS_ENCHX_MSK)
+
+/* Register: ANA_CR2 ----------------------------------------------------------*/
+/* Description: Control register 2. Offset: 0x08. Address: 0x40022008UL. */
+
+/* ANA_CR2[15]: MICBIAS_LIMIT. */
+#define CODEC_MICBIAS_LIMIT_POS (15)
+#define CODEC_MICBIAS_LIMIT_MSK (0x1 << CODEC_MICBIAS_LIMIT_POS)
+#define CODEC_MICBIAS_LIMIT_CLR (~CODEC_MICBIAS_LIMIT_MSK)
+#define CODEC_MICBIAS_LIMIT_DEFAULT_MSK (0)
+
+/* ANA_CR2[14]: MICBIAS_POWSHDT. */
+#define CODEC_MICBIAS_POWSHDT_POS (14)
+#define CODEC_MICBIAS_POWSHDT_MSK (0x1 << CODEC_MICBIAS_POWSHDT_POS)
+#define CODEC_MICBIAS_POWSHDT_CLR (~CODEC_MICBIAS_POWSHDT_MSK)
+#define CODEC_MICBIAS_POWSHDT_DEFAULT_MSK (0)
+
+/* ANA_CR2[13:12]: MICBIAS_OCSEL. */
+#define CODEC_MICBIAS_OCSEL_POS (12)
+#define CODEC_MICBIAS_OCSEL_MSK (0x3 << CODEC_MICBIAS_OCSEL_POS)
+#define CODEC_MICBIAS_OCSEL_CLR (~CODEC_MICBIAS_OCSEL_MSK)
+#define CODEC_MICBIAS_OCSEL_DEFAULT_MSK (0x1 << CODEC_MICBIAS_OCSEL_POS)
+
+/* ANA_CR2[11:8]: MICBIAS_COUNT. */
+#define CODEC_MICBIAS_COUNT_POS (8)
+#define CODEC_MICBIAS_COUNT_MSK (0xF << CODEC_MICBIAS_COUNT_POS)
+#define CODEC_MICBIAS_COUNT_CLR (~CODEC_MICBIAS_COUNT_MSK)
+#define CODEC_MICBIAS_COUNT_DEFAULT_MSK (0x1 << CODEC_MICBIAS_COUNT_POS)
+
+/* Register: CR0 --------------------------------------------------------------*/
+/* Description: audio Control register. Offset: 0x100. Address: 0x4002_2100UL. */
+
+/* CR0[0]: AUDIO_IP_EN. */
+#define CODEC_AUDIO_IP_EN_POS (0)
+#define CODEC_AUDIO_IP_EN_MSK (0x1 << CODEC_AUDIO_IP_EN_POS)
+#define CODEC_AUDIO_IP_EN_CLR (~CODEC_AUDIO_IP_EN_MSK)
+
+/* Register: ANA_CR1 -----------------------------------------------------------*/
+/* Description: analog Control register. Offset: 0x104. Address: 0x4002_2104UL. */
+
+/* ANA_CR1[3]: CKX_MICBIAS_EN. */
+#define CODEC_CKX_MICBIAS_EN_POS (3)
+#define CODEC_CKX_MICBIAS_EN_MSK (0x1 << CODEC_CKX_MICBIAS_EN_POS)
+#define CODEC_CKX_MICBIAS_EN_CLR (~CODEC_CKX_MICBIAS_EN_MSK)
+
+/* Register: CLK_CR1 ----------------------------------------------------------*/
+/* Description: clock Control register. Offset: 0x108. Address: 0x4002_2108UL. */
+
+/* CLK_CR1[12]: AD_FILTER_CH0_CLK. 0x1: Enable clock. 0x0: Disable clock. */
+#define CODEC_AD_FILTER_CH0_CLK_POS (12)
+#define CODEC_AD_FILTER_CH0_CLK_MSK (0x1 << CODEC_AD_FILTER_CH0_CLK_POS)
+#define CODEC_AD_FILTER_CH0_CLK_CLR (~CODEC_AD_FILTER_CH0_CLK_MSK)
+/* CLK_CR1[11]: AD_ANA_CLK_EN. 0x1: Enable ADC analog clock. 0x0: Disable ADC analog clock. */
+#define CODEC_AD_ANA_CLK_EN_POS (11)
+#define CODEC_AD_ANA_CLK_EN_MSK (0x1 << CODEC_AD_ANA_CLK_EN_POS)
+#define CODEC_AD_ANA_CLK_EN_CLR (~CODEC_AD_ANA_CLK_EN_MSK)
+/* CLK_CR1[10]: AD_FIFO_CLK_EN. 0x1: Enable ADC FIFO clock. 0x0: Disable ADC FIFO clock. */
+#define CODEC_AD_FIFO_CLK_EN_POS (10)
+#define CODEC_AD_FIFO_CLK_EN_MSK (0x1 << CODEC_AD_FIFO_CLK_EN_POS)
+#define CODEC_AD_FIFO_CLK_EN_CLR (~CODEC_AD_FIFO_CLK_EN_MSK)
+/* CLK_CR1[6]: AD_CH0_CLK. 0x1: Enable clock. 0x0: Disable clock. */
+#define CODEC_AD_CH0_CLK_POS (6)
+#define CODEC_AD_CH0_CLK_MSK (0x1 << CODEC_AD_CH0_CLK_POS)
+#define CODEC_AD_CH0_CLK_CLR (~CODEC_AD_CH0_CLK_MSK)
+
+/* Register: CLK_CR2 ----------------------------------------------------------*/
+/* Description: clock Control register. Offset: 0x10C. Address: 0x4002_210CUL. */
+
+/* CLK_CR2[4]: DMIC1_CLK_SRC. 0x1: 8M. 0x0: 10M. */
+#define CODEC_DMIC1_CLK_SRC_POS (4)
+#define CODEC_DMIC1_CLK_SRC_MSK (0x1 << CODEC_DMIC1_CLK_SRC_POS)
+#define CODEC_DMIC1_CLK_SRC_CLR (~CODEC_DMIC1_CLK_SRC_MSK)
+/* CLK_CR2[3]: DMIC1_CLK_EN. 0x1: Enable clock. 0x0: Disable clock. */
+#define CODEC_DMIC1_CLK_EN_POS (3)
+#define CODEC_DMIC1_CLK_EN_MSK (0x1 << CODEC_DMIC1_CLK_EN_POS)
+#define CODEC_DMIC1_CLK_EN_CLR (~CODEC_DMIC1_CLK_EN_MSK)
+/* CLK_CR2[2:0]: DMIC1_CLK_SEL. */
+#define CODEC_DMIC1_CLK_SEL_POS (0)
+#define CODEC_DMIC1_CLK_SEL_MSK (0x7 << CODEC_DMIC1_CLK_SEL_POS)
+#define CODEC_DMIC1_CLK_SEL_CLR (~CODEC_DMIC1_CLK_SEL_MSK)
+
+/* Register: CLK_CR3 ----------------------------------------------------------*/
+/* Description: clock Control register. Offset: 0x110. Address: 0x4002_2110UL. */
+
+/* CLK_CR3[13:12]: AD_LPF_CLK_SEL. */
+#define CODEC_AD_LPF_CLK_SEL_POS (12)
+#define CODEC_AD_LPF_CLK_SEL_MSK (0x3 << CODEC_AD_LPF_CLK_SEL_POS)
+#define CODEC_AD_LPF_CLK_SEL_CLR (~CODEC_AD_LPF_CLK_SEL_MSK)
+//#define CODEC_AD_LPF_CLK_SEL_DEFAULT (~CODEC_AD_LPF_CLK_SEL_MSK)
+
+/* CLK_CR3[10]: ADC_LATCH_PHASE. */
+#define CODEC_ADC_LATCH_PHASE_POS (10)
+#define CODEC_ADC_LATCH_PHASE_MSK (0x1 << CODEC_ADC_LATCH_PHASE_POS)
+#define CODEC_ADC_LATCH_PHASE_CLR (~CODEC_ADC_LATCH_PHASE_MSK)
+
+/* CLK_CR3[9]: AD_ANA_CLK_SEL. */
+#define CODEC_AD_ANA_CLK_SEL_POS (9)
+#define CODEC_AD_ANA_CLK_SEL_MSK (0x1 << CODEC_AD_ANA_CLK_SEL_POS)
+#define CODEC_AD_ANA_CLK_SEL_CLR (~CODEC_AD_ANA_CLK_SEL_MSK)
+
+/* CLK_CR3[8]: ANA_CLK_RATE. */
+#define CODEC_ANA_CLK_RATE_POS (8)
+#define CODEC_ANA_CLK_RATE_MSK (0x1 << CODEC_ANA_CLK_RATE_POS)
+#define CODEC_ANA_CLK_RATE_CLR (~CODEC_ANA_CLK_RATE_MSK)
+
+/* CLK_CR3[3:0]: SAMPLE_RATE. */
+#define CODEC_SAMPLE_RATE_POS (0)
+#define CODEC_SAMPLE_RATE_MSK (0xF << CODEC_SAMPLE_RATE_POS)
+#define CODEC_SAMPLE_RATE_CLR (~CODEC_SAMPLE_RATE_MSK)
+
+/* Register: I2S_CTRL -------------------------------------------------------*/
+/* Description: I2S Control register. Offset: 0x11C. Address: 0x4002_211CUL. */
+
+/* I2S_CTRL[19:18]: I2S_RX_CH. */
+#define CODEC_I2S_RX_CH_POS (18)
+#define CODEC_I2S_RX_CH_MSK (0x3 << CODEC_I2S_RX_CH_POS)
+#define CODEC_I2S_RX_CH_CLR (~CODEC_I2S_RX_CH_MSK)
+/* I2S_CTRL[15:14]: I2S_RX_DATA_LEN. */
+#define CODEC_I2S_RX_DATA_LEN_POS (14)
+#define CODEC_I2S_RX_DATA_LEN_MSK (0x3 << CODEC_I2S_RX_DATA_LEN_POS)
+#define CODEC_I2S_RX_DATA_LEN_CLR (~CODEC_I2S_RX_DATA_LEN_MSK)
+/* I2S_CTRL[11:10]: I2S_RX_DATA_FORMAT. */
+#define CODEC_I2S_RX_DATA_FORMAT_POS (10)
+#define CODEC_I2S_RX_DATA_FORMAT_MSK (0x3 << CODEC_I2S_RX_DATA_FORMAT_POS)
+#define CODEC_I2S_RX_DATA_FORMAT_CLR (~CODEC_I2S_RX_DATA_FORMAT_MSK)
+/* I2S_CTRL[2]: I2S_SELF_LPBK. */
+#define CODEC_I2S_SELF_LPBK_POS (2)
+#define CODEC_I2S_SELF_LPBK_MSK (0x1 << CODEC_I2S_SELF_LPBK_POS)
+#define CODEC_I2S_SELF_LPBK_CLR (~CODEC_I2S_SELF_LPBK_MSK)
+/* I2S_CTRL[1]: I2S_INV_SCLK. */
+#define CODEC_I2S_INV_SCLK_POS (1)
+#define CODEC_I2S_INV_SCLK_MSK (0x1 << CODEC_I2S_INV_SCLK_POS)
+#define CODEC_I2S_INV_SCLK_CLR (~CODEC_I2S_INV_SCLK_MSK)
+/* I2S_CTRL[0]: AUDIO_RST_N. 0x1: Powen on. 0x0: Power down. */
+#define CODEC_AUDIO_RST_N_POS (0)
+#define CODEC_AUDIO_RST_N_MSK (0x1 << CODEC_AUDIO_RST_N_POS)
+#define CODEC_AUDIO_RST_N_CLR (~CODEC_AUDIO_RST_N_MSK)
+
+/* Register: ADC0_CTRL0 -------------------------------------------------------*/
+/* Description: ADC0 Control register. Offset: 0x120. Address: 0x4002_2120UL. */
+
+/* ADC0_CTRL0[19:17]: ADC0_DCHPF_FC_SEL. */
+#define CODEC_ADC0_DCHPF_FC_SEL_POS (17)
+#define CODEC_ADC0_DCHPF_FC_SEL_MSK (0x7 << CODEC_ADC0_DCHPF_FC_SEL_POS)
+#define CODEC_ADC0_DCHPF_FC_SEL_CLR (~CODEC_ADC0_DCHPF_FC_SEL_MSK)
+
+/* ADC0_CTRL0[16]: ADC0_DCHPF_EN. 0x1: enable. 0x0: disable. */
+#define CODEC_ADC0_DCHPF_EN_POS (16)
+#define CODEC_ADC0_DCHPF_EN_MSK (0x1 << CODEC_ADC0_DCHPF_EN_POS)
+#define CODEC_ADC0_DCHPF_EN_CLR (~CODEC_ADC0_DCHPF_EN_MSK)
+
+/* ADC0_CTRL0[15]: AMIC_DMIC_CH0_SEL. 0x1: ADC path. 0x0: DMIC path. */
+#define CODEC_AMIC_DMIC_CH0_SEL_POS (15)
+#define CODEC_AMIC_DMIC_CH0_SEL_MSK (0x1 << CODEC_AMIC_DMIC_CH0_SEL_POS)
+#define CODEC_AMIC_DMIC_CH0_SEL_CLR (~CODEC_AMIC_DMIC_CH0_SEL_MSK)
+
+/* ADC0_CTRL0[14:13]: ADC_CH0_BOOST_GAIN. */
+#define CODEC_ADC_CH0_BOOST_GAIN_POS (13)
+#define CODEC_ADC_CH0_BOOST_GAIN_MSK (0x3 << CODEC_ADC_CH0_BOOST_GAIN_POS)
+#define CODEC_ADC_CH0_BOOST_GAIN_CLR (~CODEC_ADC_CH0_BOOST_GAIN_MSK)
+
+/* ADC0_CTRL0[12]: ADC_CH0_AD_MUTE. */
+#define CODEC_ADC_CH0_AD_MUTE_POS (12)
+#define CODEC_ADC_CH0_AD_MUTE_MSK (0x1 << CODEC_ADC_CH0_AD_MUTE_POS)
+#define CODEC_ADC_CH0_AD_MUTE_CLR (~CODEC_ADC_CH0_AD_MUTE_MSK)
+
+/* ADC0_CTRL0[11:10]: ADC_CH0_ZDET_TOUT. */
+#define CODEC_ADC_CH0_ZDET_TOUT_POS (10)
+#define CODEC_ADC_CH0_ZDET_TOUT_MSK (0x3 << CODEC_ADC_CH0_ZDET_TOUT_POS)
+#define CODEC_ADC_CH0_ZDET_TOUT_CLR (~CODEC_ADC_CH0_ZDET_TOUT_MSK)
+
+/* ADC0_CTRL0[9:8]: ADC_CH0_ZDET_FUN. 0x1: ADC path. 0x0: DMIC path. */
+#define CODEC_ADC_CH0_ZDET_FUN_POS (8)
+#define CODEC_ADC_CH0_ZDET_FUN_MSK (0x3 << CODEC_ADC_CH0_ZDET_FUN_POS)
+#define CODEC_ADC_CH0_ZDET_FUN_CLR (~CODEC_ADC_CH0_ZDET_FUN_MSK)
+#define CODEC_ADC_CH0_ZDET_FUN_DEFAULT_MSK (0x1 << CODEC_ADC_CH0_ZDET_FUN_POS)
+
+/* ADC0_CTRL0[7:6]: ADC0_AD_LPF1ST_FC_SEL. */
+#define CODEC_ADC0_AD_LPF1ST_FC_SEL_POS (6)
+#define CODEC_ADC0_AD_LPF1ST_FC_SEL_MSK (0x3 << CODEC_ADC0_AD_LPF1ST_FC_SEL_POS)
+#define CODEC_ADC0_AD_LPF1ST_FC_SEL_CLR (~CODEC_ADC0_AD_LPF1ST_FC_SEL_MSK)
+
+/* ADC0_CTRL0[5]: ADC0_AD_LPF1ST_EN. 0x1: enable. 0x0: disable. */
+#define CODEC_ADC0_AD_LPF1ST_EN_POS (5)
+#define CODEC_ADC0_AD_LPF1ST_EN_MSK (0x1 << CODEC_ADC0_AD_LPF1ST_EN_POS)
+#define CODEC_ADC0_AD_LPF1ST_EN_CLR (~CODEC_ADC0_AD_LPF1ST_EN_MSK)
+
+/* ADC0_CTRL0[4]: ADC0_AD_LPF2ND_EN. 0x1: enable. 0x0: disable. */
+#define CODEC_ADC0_AD_LPF2ND_EN_POS (4)
+#define CODEC_ADC0_AD_LPF2ND_EN_MSK (0x1 << CODEC_ADC0_AD_LPF2ND_EN_POS)
+#define CODEC_ADC0_AD_LPF2ND_EN_CLR (~CODEC_ADC0_AD_LPF2ND_EN_MSK)
+
+/* ADC0_CTRL0[1:0]: ADC0_DMIC_SRC_SEL. */
+#define CODEC_ADC0_DMIC_SRC_SEL_POS (0)
+#define CODEC_ADC0_DMIC_SRC_SEL_MSK (0x3 << CODEC_ADC0_DMIC_SRC_SEL_POS)
+#define CODEC_ADC0_DMIC_SRC_SEL_CLR (~CODEC_ADC0_DMIC_SRC_SEL_MSK)
+
+#define CODEC_ADC0_CTRL0_REG_DEFAULT_MSK ((0x2 << 17) | (0x01 << 16) | (0x01 << 10) | (0x02 << 8) | (0x03 <<4))
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup CODEC_Exported_Constants Macro Definitions
+ *
+ * \ingroup CODEC
+ */
+
+#define IS_CODEC_PERIPH(PERIPH) ((PERIPH) == CODEC)
+
+/**
+ * \defgroup MICBST_Gain MICBST Gain
+ * \{
+ * \ingroup CODEC_Exported_Constants
+ */
+#define MICBST_Gain_0dB ((uint32_t)(0x0))
+#define MICBST_Gain_20dB ((uint32_t)(0x1 << CODEC_MICBST_GAIN_POS))
+#define MICBST_Gain_30dB ((uint32_t)(0x2 << CODEC_MICBST_GAIN_POS))
+#define MICBST_Gain_40dB ((uint32_t)(0x3 << CODEC_MICBST_GAIN_POS))
+/** \} */
+#define IS_MICBST_GAIN(GAIN) (((GAIN) == MICBST_Gain_0dB) || \
+ ((GAIN) == MICBST_Gain_20dB) || \
+ ((GAIN) == MICBST_Gain_30dB) || \
+ ((GAIN) == MICBST_Gain_40dB))
+
+/**
+ * \defgroup MICBST_Mode MICBST Mode
+ * \{
+ * \ingroup CODEC_Exported_Constants
+ */
+#define MICBST_Mode_Single ((uint32_t)(0x0))
+#define MICBST_Mode_Differential ((uint32_t)CODEC_MICBST_ENDFL_MSK)
+/** \} */
+#define IS_MICBST_MODE(MODE) (((MODE) == MICBST_Mode_Single) || \
+ ((MODE) == MICBST_Mode_Differential))
+
+/**
+ * \defgroup CODEC_MIC_BIAS_Config CODEC MIC BIAS Config
+ * \{
+ * \ingroup CODEC_Exported_Constants
+ */
+
+#define MICBIAS_VOLTAGE_1_507 ((uint32_t)(0x00))
+#define MICBIAS_VOLTAGE_1_62 ((uint32_t)(0x01 << CODEC_MICBIAS_VSET_POS))
+#define MICBIAS_VOLTAGE_1_705 ((uint32_t)(0x02 << CODEC_MICBIAS_VSET_POS))
+#define MICBIAS_VOLTAGE_1_8 ((uint32_t)(0x03 << CODEC_MICBIAS_VSET_POS))
+#define MICBIAS_VOLTAGE_1_906 ((uint32_t)(0x04 << CODEC_MICBIAS_VSET_POS))
+#define MICBIAS_VOLTAGE_2_025 ((uint32_t)(0x05 << CODEC_MICBIAS_VSET_POS))
+#define MICBIAS_VOLTAGE_2_16 ((uint32_t)(0x06 << CODEC_MICBIAS_VSET_POS))
+#define MICBIAS_VOLTAGE_2_314 ((uint32_t)(0x07 << CODEC_MICBIAS_VSET_POS))
+/** \} */
+
+#define IS_MICBIAS_CONFIG(CONFIG) (((CONFIG) == MICBIAS_VOLTAGE_1_507) || ((CONFIG) == MICBIAS_VOLTAGE_1_62) || \
+ ((CONFIG) == MICBIAS_VOLTAGE_1_705) || ((CONFIG) == MICBIAS_VOLTAGE_1_8) || \
+ ((CONFIG) == MICBIAS_VOLTAGE_1_906) || ((CONFIG) == MICBIAS_VOLTAGE_2_025) || \
+ ((CONFIG) == MICBIAS_VOLTAGE_2_16) || ((CONFIG) == MICBIAS_VOLTAGE_2_314))
+
+/**
+ * \defgroup Sample_Rate_Definition Sample Rate Definition
+ * \{
+ * \ingroup CODEC_Exported_Constants
+ */
+#define SAMPLE_RATE_48KHz ((uint32_t)(0x00 << CODEC_SAMPLE_RATE_POS))
+#define SAMPLE_RATE_16KHz ((uint32_t)(0x05 << CODEC_SAMPLE_RATE_POS))
+#define SAMPLE_RATE_8KHz ((uint32_t)(0x07 << CODEC_SAMPLE_RATE_POS))
+/** \} */
+
+#define IS_SAMPLE_RATE(RATE) (((RATE) == SAMPLE_RATE_16KHz) || ((RATE) == SAMPLE_RATE_8KHz)))
+
+/**
+ * \defgroup CODEC_I2S_CH CODEC I2S CH
+ * \{
+ * \ingroup CODEC_Exported_Constants
+ */
+#define CODEC_I2S_CH_L_R ((uint32_t)(0x00))
+#define CODEC_I2S_CH_R_L ((uint32_t)(0x01 << CODEC_I2S_RX_CH_POS))
+#define CODEC_I2S_CH_L_L ((uint32_t)(0x02 << CODEC_I2S_RX_CH_POS))
+#define CODEC_I2S_CH_R_R ((uint32_t)(0x03 << CODEC_I2S_RX_CH_POS))
+/** \} */
+
+#define IS_CODEC_I2S_CH(CH) (((CH) == CODEC_I2S_CH_L_R) || \
+ ((CH) == CODEC_I2S_CH_R_L) || \
+ ((CH) == CODEC_I2S_CH_L_L) || \
+ ((CH) == CODEC_I2S_CH_R_R))
+
+/**
+ * \defgroup I2S_Data_Width I2S Data Width
+ * \{
+ * \ingroup CODEC_Exported_Constants
+ */
+#define CODEC_I2S_DataWidth_16Bits ((uint32_t)(0x00))
+#define CODEC_I2S_DataWidth_24Bits ((uint32_t)(0x02 << CODEC_I2S_RX_DATA_LEN_POS)
+#define CODEC_I2S_DataWidth_8Bits ((uint32_t)(0x03 << CODEC_I2S_RX_DATA_LEN_POS)
+/** \} */
+#define IS_CODEC_I2S_DATA_WIDTH(WIDTH) (((WIDTH) == CODEC_I2S_DataWidth_16Bits) || \
+ ((WIDTH) == CODEC_I2S_DataWidth_24Bits) || \
+ ((WIDTH) == CODEC_I2S_DataWidth_8Bits))
+
+/**
+ * \defgroup I2S_Data_Format I2S Data Format
+ * \{
+ * \ingroup CODEC_Exported_Constants
+ */
+#define CODEC_I2S_DataFormat_I2S ((uint32_t)(0x00))
+#define CODEC_I2S_DataFormat_LeftJustified ((uint32_t)(0x01 << CODEC_I2S_RX_DATA_FORMAT_POS)
+#define CODEC_I2S_DataFormat_PCM_A ((uint32_t)(0x02 << CODEC_I2S_RX_DATA_FORMAT_POS)
+#define CODEC_I2S_DataFormat_PCM_B ((uint32_t)(0x03 << CODEC_I2S_RX_DATA_FORMAT_POS)
+/** \} */
+
+#define IS_CODEC_I2S_DATA_FORMAT(FORMAT) (((FORMAT) == CODEC_I2S_DataFormat_I2S) || \
+ ((FORMAT) == CODEC_I2S_DataFormat_LeftJustified) || \
+ ((FORMAT) == CODEC_I2S_DataFormat_PCM_A) || \
+ ((FORMAT) == CODEC_I2S_DataFormat_PCM_B))
+
+/**
+ * \defgroup DMIC_Clock_Type_Definition DMIC Clock Type Definition
+ * \{
+ * \ingroup CODEC_Exported_Constants
+ */
+#define DMIC_Clock_5MHz ((uint32_t)(0x0))
+#define DMIC_Clock_2500KHz ((uint32_t)(0x01 << CODEC_DMIC1_CLK_SEL_POS))
+#define DMIC_Clock_1250KHz ((uint32_t)(0x02 << CODEC_DMIC1_CLK_SEL_POS))
+#define DMIC_Clock_625KHz ((uint32_t)(0x03 << CODEC_DMIC1_CLK_SEL_POS))
+#define DMIC_Clock_312500Hz ((uint32_t)(0x04 << CODEC_DMIC1_CLK_SEL_POS))
+/** \} */
+
+#define IS_CODEC_DMIC_CLOCK(CLOCK) (((CLOCK) == DMIC_Clock_5MHz) || ((CLOCK) == DMIC_Clock_2500KHz) || \
+ ((CLOCK) == DMIC_Clock_1250KHz) || ((CLOCK) == DMIC_Clock_625KHz) || \
+ ((CLOCK) == DMIC_Clock_312500Hz))
+
+/**
+ * \defgroup CODEC_Ch0_Mic_Type CODEC Ch0 Mic Type
+ * \{
+ * \ingroup CODEC_Exported_Constants
+ */
+#define CODEC_CH0_AMIC (CODEC_AMIC_DMIC_CH0_SEL_MSK)
+#define CODEC_CH0_DMIC (0)
+/** \} */
+
+#define IS_CODEC_CH0_MIC_TYPE(TYPE) (((TYPE) == CODEC_CH0_AMIC) || ((TYPE) == CODEC_CH0_DMIC))
+
+/**
+ * \defgroup Ch0_Boost_Gain Ch0 Boost Gain
+ * \{
+ * \ingroup CODEC_Exported_Constants
+ */
+#define Ch0_Boost_Gain_0dB ((uint32_t)(0x0))
+#define Ch0_Boost_Gain_12dB ((uint32_t)(0x1 << CODEC_ADC_CH0_BOOST_GAIN_POS))
+#define Ch0_Boost_Gain_24dB ((uint32_t)(0x2 << CODEC_ADC_CH0_BOOST_GAIN_POS))
+#define Ch0_Boost_Gain_36dB ((uint32_t)(0x3 << CODEC_ADC_CH0_BOOST_GAIN_POS))
+/** \} */
+
+#define IS_CH0_BOOST_GAIN(GAIN) (((GAIN) == Ch0_Boost_Gain_0dB) || \
+ ((GAIN) == Ch0_Boost_Gain_12dB) || \
+ ((GAIN) == Ch0_Boost_Gain_24dB) || \
+ ((GAIN) == Ch0_Boost_Gain_36dB))
+
+/**
+ * \defgroup CODEC_Ch0_Mute CODEC Ch0 Mute
+ * \{
+ * \ingroup CODEC_Exported_Constants
+ */
+#define CODEC_CH0_MUTE (CODEC_ADC_CH0_AD_MUTE_MSK)
+#define CODEC_CH0_UNMUTE (0)
+/** \} */
+
+#define IS_CODEC_CH0_MIC_MUTE(MUTE) (((MUTE) == CODEC_CH0_MUTE) || ((MUTE) == CODEC_CH0_UNMUTE))
+
+/**
+ * \defgroup Ch0_ADC_Zero_Detection_Timeout Ch0 ADC Zero Detection Timeout
+ * \{
+ * \ingroup CODEC_Exported_Constants
+ */
+#define Ch0_ADC_Zero_DetTimeout_1024_16_Sample ((uint32_t)(0x00))
+#define Ch0_ADC_Zero_DetTimeout_1024_32_Sample ((uint32_t)(0x01 << CODEC_ADC_CH0_ZDET_TOUT_POS))
+#define Ch0_ADC_Zero_DetTimeout_1024_64_Sample ((uint32_t)(0x02 << CODEC_ADC_CH0_ZDET_TOUT_POS))
+#define Ch0_ADC_Zero_DetTimeout_64_Sample ((uint32_t)(0x03 << CODEC_ADC_CH0_ZDET_TOUT_POS))
+/** \} */
+
+#define IS_CH0_ADC_ZERO_DET_TIMEOUT(TIMEOUT) (((TIMEOUT) == Ch0_ADC_Zero_DetTimeout_1024_16_Sample) || \
+ ((TIMEOUT) == Ch0_ADC_Zero_DetTimeout_1024_32_Sample) || \
+ ((TIMEOUT) == Ch0_ADC_Zero_DetTimeout_1024_64_Sample) || \
+ ((TIMEOUT) == Ch0_ADC_Zero_DetTimeout_64_Sample))
+
+/**
+ * \defgroup DMIC_Data_Latch_Edge DMIC Data Latch Edge
+ * \{
+ * \ingroup CODEC_Exported_Constants
+ */
+#define DMIC_Ch0_Falling_Latch ((uint32_t)(0x01 << CODEC_ADC0_DMIC_SRC_SEL_MSK))
+#define DMIC_Ch0_Rising_Latch ((uint32_t)(0x00))
+/** \} */
+
+#define IS_DMIC_CH0_LATCH_EDGE(EDGE) (((EDGE) == DMIC_Ch0_Rising_Latch) || ((EDGE) == DMIC_Ch0_Falling_Latch))
+
+/**
+ * \def CODEC_Ad_Gain Codec Ad Gain
+ */
+
+#define IS_AD_GAIN(GAIN) (((GAIN)<= 0x7F))
+
+/**
+ * \def CODEC_Da_Gain Codec Da Gain
+ */
+#define IS_DA_GAIN(GAIN) (((GAIN)<= 0xFF))
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup CODEC_Exported_Functions Peripheral APIs
+ * \{
+ * \ingroup CODEC
+ */
+
+void CODEC_AnalogCircuitInit(void);
+
+/**
+ * \brief Deinitializes the CODEC peripheral registers to their default reset values(turn off CODEC clock).
+ * \param[in] CODECx: CODEC peripheral selected .
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_codec_init(void)
+ * {
+ * CODEC_DeInit(CODEC);
+ * }
+ * \endcode
+ */
+void CODEC_DeInit(CODEC_TypeDef *CODECx);
+
+/**
+ * \brief Initializes the CODEC peripheral according to the specified
+ * parameters in the CODEC_InitStruct.
+ * \param[in] CODECx: CODEC peripheral selected.
+ * \param[in] CODEC_InitStruct: Pointer to a CODEC_InitTypeDef structure that
+ * contains the configuration information for the specified CODEC peripheral
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_codec_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_CODEC, APBPeriph_CODEC_CLOCK, ENABLE);
+ *
+ * CODEC_InitTypeDef CODEC_InitStruct;
+
+ * CODEC_StructInit(&CODEC_InitStruct);
+ * CODEC_InitStruct.CODEC_Ch0MicType = CODEC_CH0_AMIC;
+ * CODEC_InitStruct.CODEC_MicBstMode = MICBST_Mode_Differential;
+ * CODEC_InitStruct.CODEC_SampleRate = SAMPLE_RATE_16KHz;
+ * CODEC_InitStruct.CODEC_I2SFormat = CODEC_I2S_DataFormat_I2S;
+ * CODEC_InitStruct.CODEC_I2SDataWidth = CODEC_I2S_DataWidth_16Bits;
+ * CODEC_Init(CODEC, &CODEC_InitStruct);
+ * }
+ * \endcode
+ */
+void CODEC_Init(CODEC_TypeDef *CODECx, CODEC_InitTypeDef *CODEC_InitStruct);
+
+/**
+ * \brief Fills each CODEC_InitStruct member with its default value.
+ * \param[in] CODEC_InitStruct: Pointer to a CODEC_InitTypeDef structure which will be initialized.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_codec_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_CODEC, APBPeriph_CODEC_CLOCK, ENABLE);
+ *
+ * CODEC_InitTypeDef CODEC_InitStruct;
+
+ * CODEC_StructInit(&CODEC_InitStruct);
+ * CODEC_InitStruct.CODEC_Ch0MicType = CODEC_CH0_AMIC;
+ * CODEC_InitStruct.CODEC_MicBstMode = MICBST_Mode_Differential;
+ * CODEC_InitStruct.CODEC_SampleRate = SAMPLE_RATE_16KHz;
+ * CODEC_InitStruct.CODEC_I2SFormat = CODEC_I2S_DataFormat_I2S;
+ * CODEC_InitStruct.CODEC_I2SDataWidth = CODEC_I2S_DataWidth_16Bits;
+ * CODEC_Init(CODEC, &CODEC_InitStruct);
+ * }
+ * \endcode
+ */
+void CODEC_StructInit(CODEC_InitTypeDef *CODEC_InitStruct);
+
+/**
+ * \brief Enable or disable mic_bias output.
+ * \param[in] CODECx: CODEC peripheral selected.
+ * \param[in] NewState: New state of MICBIAS.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return none.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void codec_demo(void)
+ * {
+ * CODEC_MICBIASCmd(CODEC, ENABLE);
+ * }
+ * \endcode
+ */
+void CODEC_MICBIASCmd(CODEC_TypeDef *CODECx, FunctionalState NewState);
+
+/**
+ * \brief Reset CODEC.
+ * \param[in] CODECx: CODEC peripheral selected.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void codec_demo(void)
+ * {
+ * CODEC_Reset(CODEC);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void CODEC_Reset(CODEC_TypeDef *CODECx)
+{
+ /* Check the parameters */
+ assert_param(IS_CODEC_PERIPH(CODECx));
+
+ /* CODEC IP reset */
+ CODECx->CR0 &= CODEC_AUDIO_IP_EN_CLR;;
+ CODECx->CR0 = CODEC_AUDIO_IP_EN_MSK;;
+}
+
+/**
+ * \brief Config MIC BIAS Vref voltage.
+ * \param[in] CODECx: CODEC peripheral selected.
+ * \param[in] data: New value of MIC BIAS.
+ * This parameter can be one of the following values:
+ * \arg MICBIAS_VOLTAGE_1_507: Vref voltage is 1.507V.
+ * \arg MICBIAS_VOLTAGE_1_62: Vref voltage is 1.62V.
+ * \arg MICBIAS_VOLTAGE_1_705: Vref voltage is 1.705V.
+ * \arg MICBIAS_VOLTAGE_1_8: Vref voltage is 1.8V.
+ * \arg MICBIAS_VOLTAGE_1_906: Vref voltage is 1.906V.
+ * \arg MICBIAS_VOLTAGE_2_025: Vref voltage is 2.025V.
+ * \arg MICBIAS_VOLTAGE_2_16: Vref voltage is 2.16V.
+ * \arg MICBIAS_VOLTAGE_2_314: Vref voltage is 2.314V.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void codec_demo(void)
+ * {
+ * CODEC_SetMICBIAS(CODEC, MICBIAS_VOLTAGE_1_507);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void CODEC_SetMICBIAS(CODEC_TypeDef *CODECx, uint16_t data)
+
+{
+ /* Check the parameters */
+ assert_param(IS_CODEC_PERIPH(CODECx));
+ assert_param(IS_MICBIAS_CONFIG(data));
+
+ CODEC_ANA->ANA_CR1 &= CODEC_MICBIAS_POW_CLR;
+ CODEC_ANA->ANA_CR1 &= CODEC_MICBIAS_VSET_CLR;
+ CODEC_ANA->ANA_CR1 |= data;
+}
+
+/** \} */ /* End of group CODEC_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_CODEC_H_ */
+
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor *****END OF FILE****/
+
diff --git a/inc/peripheral/rtl876x_enh_tim.h b/inc/peripheral/rtl876x_enh_tim.h
new file mode 100644
index 0000000..dfa1c7c
--- /dev/null
+++ b/inc/peripheral/rtl876x_enh_tim.h
@@ -0,0 +1,883 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_enh_tim.h
+* \brief The header file of the peripheral Enhance ENHTIMER driver.
+* \details This file provides all Enhance ENHTIMER firmware functions.
+* \author Yuan
+* \date 2020-10-19
+* \version v1.0.0
+* *********************************************************************************************************
+*/
+
+#ifndef _RTL876X_ENH_TIM_H_
+#define _RTL876X_ENH_TIM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup ENHTIM ENHTIM
+ * \brief Manage the ENHTIM peripheral functions.
+ * \ingroup IO
+ */
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/* ENHTIM private defines */
+#define ENHTIM_PWM_DEADZONE_CR *((volatile uint32_t *)0x40000368UL)
+#define ENHTIM_LATCH_COUNT_CR *((volatile uint32_t *)0x40006028UL)
+
+/**
+ * \defgroup ENHTIM_Exported_Constants Macro Definitions
+ * \ingroup ENHTIM
+ */
+#define IS_ENHTIM_ALL_PERIPH(PERIPH) (((PERIPH) == ENH_ENHTIM0) || \
+ ((PERIPH) == ENH_ENHTIM1))
+
+/**
+ * \defgroup ENHTIM_Clock_Source ENHTIM Clock Source
+ * \{
+ * \ingroup ENHTIM_Exported_Constants
+ */
+#define ENHTIM_TIMER_TOGGLE_OUTPUT ((uint16_t)0x1)
+#define ENHTIM_DIVIDER_CLOCK ((uint16_t)0x0)
+/** \} */
+#define IS_ENHTIM_CLOCK_SOURCE(src) (((src) == ENHTIM_TIMER_TOGGLE_OUTPUT) || \
+ ((src) == ENHTIM_DIVIDER_CLOCK))
+
+/**
+ * \defgroup ENHTIM_Latch_Count_En ENHTIM Latch Count Enable
+ * \{
+ * \ingroup ENHTIM_Exported_Constants
+ */
+#define ENHTIM_LATCH_COUNT_ENABLE ((uint16_t)0x1)
+#define ENHTIM_LATCH_COUNT_DISABLE ((uint16_t)0x0)
+/** \} */
+#define IS_ENHTIM_LATCH_COUNT_En(mode) (((mode) == ENHTIM_LATCH_COUNT_ENABLE) || \
+ ((mode) == ENHTIM_LATCH_COUNT_DISABLE))
+
+/**
+ * \defgroup ENHTIM_LATCH_TRIGGER_Mode Latch Count Trigger Mode
+ * \{
+ * \ingroup ENHTIM_Exported_Constants
+ */
+#define ENHTIM_LATCH_TRIGGER_BOTH_EDGE ((uint16_t)0x02)
+#define ENHTIM_LATCH_TRIGGER_FALLING_EDGE ((uint16_t)0x01)
+#define ENHTIM_LATCH_TRIGGER_RISING_EDGE ((uint16_t)0x00)
+/** \} */
+#define IS_ENHTIM_LATCH_TRIGGER_Mode(mode) (((mode) == ENHTIM_LATCH_TRIGGER_BOTH_EDGE) || \
+ ((mode) == ENHTIM_LATCH_TRIGGER_FALLING_EDGE) || \
+ ((mode) == ENHTIM_LATCH_TRIGGER_RISING_EDGE))
+
+/**
+ * \defgroup ENHTIM_PWM_En ENHTIM PWM Output Enable
+ * \{
+ * \ingroup ENHTIM_Exported_Constants
+ */
+#define ENHTIM_PWM_ENABLE ((uint16_t)0x08)
+#define ENHTIM_PWM_DISABLE ((uint16_t)0x00)
+/** \} */
+#define IS_ENHTIM_PWM_En(mode) (((mode) == ENHTIM_PWM_ENABLE) || \
+ ((mode) == ENHTIM_PWM_DISABLE))
+
+/**
+ * \defgroup ENHTIM_PWM_Polarity ENHTIM PWM Polarity
+ * \{
+ * \ingroup ENHTIM_Exported_Constants
+ */
+#define ENHTIM_PWM_START_WITH_HIGH ((uint16_t)0x04)
+#define ENHTIM_PWM_START_WITH_LOW ((uint16_t)0x00)
+/** \} */
+#define IS_ENHTIM_PWM_POLARITY(pola) (((pola) == ENHTIM_PWM_START_WITH_HIGH) || \
+ ((pola) == ENHTIM_PWM_START_WITH_LOW))
+
+/**
+ * \defgroup ENHTIM_Mode ENHTIM Mode
+ * \{
+ * \ingroup ENHTIM_Exported_Constants
+ */
+#define ENHTIM_MODE_PWM_MANUAL ((uint16_t)0x02) /*!< User define pwm manual mode. */
+#define ENHTIM_MODE_PWM_AUTO ((uint16_t)0x01) /*!< User define pwm auto mode. */
+#define ENHTIM_MODE_FreeRun ((uint16_t)0x00) /*!< User define freerun mode. */
+/** \} */
+#define IS_ENHTIM_MODE(mode) (((mode) == ENHTIM_MODE_PWM_MANUAL) || \
+ ((mode) == ENHTIM_MODE_PWM_AUTO) || \
+ ((mode) == ENHTIM_MODE_UserDefine))
+
+/**
+ * \defgroup ENHTIM_Interrupts_Definition ENHTIM Interrupts Definition
+ * \{
+ * \ingroup ENHTIM_Exported_Constants
+ */
+#define ENHTIM_INT_TIM (0x00)
+#define ENHTIM_INT_LATCH_CNT2_FIFO_FULL (0x40)
+#define ENHTIM_INT_LATCH_CNT2_FIFO_THD (0x42)
+/** \} */
+
+#define IS_ENHTIM_INT(INT) (((INT) == ENHTIM_INT_TIM) || \
+ ((INT) == ENHTIM_INT_LATCH_CNT2_FIFO_FULL) || \
+ ((INT) == ENHTIM_INT_LATCH_CNT2_FIFO_THD))
+
+/**
+ * \defgroup ENHTIM_FIFO_Flag ENHTIM FIFO Flag
+ * \{
+ * \ingroup ENHTIM_Exported_Constants
+ */
+#define ENHTIM_FLAG_TIM1_LC_FIFO_EMPTY BIT(19)
+#define ENHTIM_FLAG_TIM0_LC_FIFO_EMPTY BIT(17)
+#define ENHTIM_FLAG_TIM1_CCR_FIFO_EMPTY BIT(3)
+#define ENHTIM_FLAG_TIM1_CCR_FIFO_FULL BIT(2)
+#define ENHTIM_FLAG_TIM0_CCR_FIFO_EMPTY BIT(1)
+#define ENHTIM_FLAG_TIM0_CCR_FIFO_FULL BIT(0)
+/** \} */
+#define IS_ENHTIM_CCR_FIFO_FLAG(flag) (((flag) == ENHTIM_FLAG_TIM1_LC_FIFO_EMPTY) || \
+ ((flag) == ENHTIM_FLAG_TIM0_LC_FIFO_EMPTY) || \
+ ((flag) == ENHTIM_FLAG_TIM1_CCR_FIFO_EMPTY) || \
+ ((flag) == ENHTIM_FLAG_TIM1_CCR_FIFO_FULL) || \
+ ((flag) == ENHTIM_FLAG_TIM0_CCR_FIFO_EMPTY) || \
+ ((flag) == ENHTIM_FLAG_TIM0_CCR_FIFO_FULL) ))
+
+/**
+ * \defgroup PWM_DeadZone_En PWM DeadZone enable
+ * \{
+ * \ingroup ENHTIM_Exported_Constants
+ */
+#define ENHTIM_PWM_DEADZONE_ENABLE ((uint16_t)0x1)
+#define ENHTIM_PWM_DEADZONE_DISABLE ((uint16_t)0x0)
+/** \} */
+#define IS_ENHTIM_PWM_DEADZONE_EN(mode) (((mode) == ENHTIM_PWM_DEADZONE_ENABLE) || \
+ ((mode) == ENHTIM_PWM_DEADZONE_DISABLE))
+
+/**
+ * \defgroup PWM_DeadZone_En PWM DeadZone enable
+ * \{
+ * \ingroup ENHTIM_Exported_Constants
+ */
+#define ENHTIM_PWM_DZCLKSRCE_ENHTIM ((uint32_t)0x80000)
+#define ENHTIM_PWM_DZCLKSRCE_5M ((uint32_t)0x10000)
+#define ENHTIM_PWM_DZCLKSRCE_32K ((uint32_t)0x0)
+/** \} */
+#define IS_ENHTIM_PWM_DEADZONE_EN(mode) (((mode) == ENHTIM_PWM_DEADZONE_ENABLE) || \
+ ((mode) == ENHTIM_PWM_DEADZONE_DISABLE))
+
+/**
+ * \defgroup ENHTIM_PWM_DeadZone_Stop_State ENHTIM PWM DeadZone Stop State
+ * \{
+ * \ingroup ENHTIM_Exported_Constants
+ */
+#define ENHTIM_PWM_STOP_AT_HIGH ((uint16_t)0x1)
+#define ENHTIM_PWM_STOP_AT_LOW ((uint16_t)0x0)
+/** \} */
+
+/**
+ * \defgroup ENHTIM_FIFO_Clear_Flag ENHTIM FIFO Clear Flag
+ * \{
+ * \ingroup ENHTIM_Exported_Constants
+ */
+#define ENHTIM_FIFO_CLR_CCR (0)
+#define ENHTIM_FIFO_CLR_CNT2 (24)
+/** \} */
+
+/**
+ * \defgroup ENHTIM_Clock_Divider ENHTIM Clock Divider
+ * \{
+ * \ingroup ENHTIM_Exported_Constants
+ */
+typedef enum
+{
+ ENHTIM_CLOCK_DIVIDER_1 = 0x00,
+ ENHTIM_CLOCK_DIVIDER_125 = 0x03,
+ ENHTIM_CLOCK_DIVIDER_2 = 0x04,
+ ENHTIM_CLOCK_DIVIDER_4 = 0x05,
+ ENHTIM_CLOCK_DIVIDER_8 = 0x06,
+ ENHTIM_CLOCK_DIVIDER_40 = 0x07,
+} E_ENHTIM_CLKDIV;
+/** \} */
+
+/**
+ * \defgroup ENHTIM_Latch_Channel_Count ENHTIM Latch Channel Order Number
+ * \{
+ * \ingroup ENHTIM_Exported_Constants
+ */
+typedef enum
+{
+ LATCH_CNT_0 = 0,
+ LATCH_CNT_1 = 1,
+ LATCH_CNT_2 = 2,
+} E_ENHTIM_LATCHCNT;
+/** \} */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup ENHTIM_Exported_Types Init Params Struct
+ *
+ * \ingroup ENHTIM
+ */
+
+/**
+ * \brief ENHTIM init structure definition.
+ *
+ * \ingroup ENHTIM_Exported_Types
+ */
+typedef struct
+{
+ uint16_t ENHTIM_ClockSource; /*!< Specifies the ENHTIM clock source.*/
+ E_ENHTIM_CLKDIV ENHTIM_ClockDiv; /*!< Specifies the clock source div.
+ This parameter can be a value of \ref ENHTIM_Clock_Divider*/
+ uint16_t ENHTIM_Mode; /*!< Specifies the counter mode.
+ This parameter can be a value of \ref ENHTIM_Mode. */
+ uint16_t ENHTIM_PWMOutputEn; /*!< Enable EnhtimerN PWM oupput.
+ This parameter can be a value of DISABLE or ENABLE */
+ uint16_t ENHTIM_PWMStartPolarity; /*!< EnhtimerN toggle output polarity for user-define PWM mode.
+ This parameter can be a value of \ref ENHTIM_PWMStartPolarity. */
+ uint16_t ENHTIM_LatchCountEn[3]; /*!< Specifies enable EnhtimerN Latch_cnt.
+ This parameter can be a value of DISABLE or ENABLE */
+ uint16_t ENHTIM_LatchCountTrigger[3]; /*!< Specifies EnhtimerN counter latch trigger mode.
+ This parameter can be a value of \ref ENHTIM_LatchCountTrigger. */
+ uint16_t ENHTIM_LatchCount2Thd; /*!< Specifies EnhtimerN latched counter fifo threshold.
+ This parameter ranges from 1 to 4. */
+ uint16_t ENHTIM_LatchTriggerPad; /*!< User-defined GPIO trigger latch pin.*/
+ uint16_t ENHTIM_TimerGPIOTriggerEn; /*!< Timer GPIO trigger enable.
+ This parameter can be a value of DISABLE or ENABLE */
+ uint16_t ENHTIM_BTGPIOTriggerEn; /*!< Bluetooth GPIO trigger enable.
+ This parameter can be a value of DISABLE or ENABLE */
+ uint32_t ENHTIM_MaxCount; /*!< Specifies the Enhtimer max counter value for user-define PWM mode.
+ This parameter leagel value range is from 0 ~ 2^32-2. */
+ uint32_t ENHTIM_CCValue; /*!< Specifies the Enhtimer capture/compare value for user-define PWM mode.*/
+ uint16_t ENHTIM_PWMDeadZoneEn; /*!< PWM Deadzone enable, pwm0_pn: timer2, pwm1_pn:timer3
+ This parameter can be a value of ENABLE or DISABLE. */
+ uint32_t ENHTIM_PWMDeadZoneClockSource; /*!< Specifies ENHTIM Source depend.timer3 depend timer2 ,timer5 depend timer4, timer7 depend timer6.
+ This parameter can be a value of ENABLE or DISABLE */
+ uint16_t ENHTIM_PWMStopStateP; /*!< Specifies the PWM P stop state.
+ This parameter can be a value of \ref PWMDeadZone_Stop_state. */
+ uint16_t ENHTIM_PWMStopStateN; /*!< Specifies the PWM N stop state.
+ This parameter can be a value of \ref PWMDeadZone_Stop_state. */
+ uint32_t ENHTIM_DeadZoneSize; /*!< Size of deadzone time, DeadzoneTime=deadzonesize/32000 or 32768.
+ This parameter must range from 1 to 0xff. */
+} ENHTIM_InitTypeDef;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup ENHTIM_Exported_Functions Peripheral APIs
+ * \{
+ * \ingroup ENHTIM
+ */
+
+/**
+ * \brief Initialize the ENHTIMx unit peripheral according to
+ * the specified parameters in ENHTIM_InitStruct.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIM peripheral.
+ * \param[in] ENHTIM_InitStruct: pointer to a ENHTIM_InitTypeDef structure
+ * that contains the configuration information for the specified ENHTIM peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_enhance_timer_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+ *
+ * ENHTIM_InitTypeDef ENHTIM_InitStruct;
+ * ENHTIM_StructInit(&ENHTIM_InitStruct);
+ *
+ * ENHTIM_InitStruct.ENHTIM_PWM_En = PWM_DISABLE;
+ * ENHTIM_InitStruct.ENHTIM_Period = 1000000 - 1 ;
+ * ENHTIM_InitStruct.ENHTIM_Mode = ENHTIM_Mode_UserDefine;
+ * ENHTIM_Init(ENHTIMER_NUM, &ENHTIM_InitStruct);
+ * }
+ * \endcode
+ */
+void ENHTIM_Init(ENHTIM_TypeDef *ENHTIMx, ENHTIM_InitTypeDef *ENHTIM_TimeBaseInitStruct);
+
+/**
+ * \brief Fills each ENHTIM_InitStruct member with its default value.
+ * \param[in] ENHTIM_TimeBaseInitStruct: Pointer to a ENHTIM_TimeBaseInitTypeDef structure which will be initialized.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_enhance_timer_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_ENHTIMER, APBPeriph_ENHTIMER_CLOCK, ENABLE);
+ *
+ * ENHTIM_TimeBaseInitTypeDef ENHTIM_InitStruct;
+ * ENHTIM_StructInit(&ENHTIM_InitStruct);
+ *
+ * ENHTIM_InitStruct.ENHTIM_PWM_En = PWM_DISABLE;
+ * ENHTIM_InitStruct.ENHTIM_Period = 1000000 - 1;
+ * ENHTIM_InitStruct.ENHTIM_Mode = ENHTIM_Mode_UserDefine;
+ * ENHTIM_TimeBaseInit(ENH_TIM0, &ENHTIM_InitStruct);
+ * }
+ * \endcode
+ */
+void ENHTIM_StructInit(ENHTIM_InitTypeDef *ENHTIM_InitStruct);
+
+/**
+ * \brief Enables or disables the specified ENHTIM peripheral.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] NewState: New state of the ENHTIMx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_enhance_timer_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_ENHTIMER, APBPeriph_ENHTIMER_CLOCK, ENABLE);
+ *
+ * ENHTIM_InitTypeDef ENHTIM_InitStruct;
+ * ENHTIM_StructInit(&ENHTIM_InitStruct);
+ *
+ * ENHTIM_InitStruct.ENHTIM_PWM_En = PWM_DISABLE;
+ * ENHTIM_InitStruct.ENHTIM_Period = 1000000 - 1;
+ * ENHTIM_InitStruct.ENHTIM_Mode = ENHTIM_Mode_UserDefine;
+ * ENHTIM_Init(ENH_TIM0, &ENHTIM_InitStruct);
+ * ENHTIM_Cmd(ENH_TIM0, ENABLE);
+ * }
+ * \endcode
+ */
+void ENHTIM_Cmd(ENHTIM_TypeDef *ENHTIMx, FunctionalState NewState);
+
+/**
+ * \brief Mask or unmask the latch count2 fifo interrupt.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] NewState: New state of the specified ENHTIMx peripheral latch count2 fifo interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ */
+void ENHTIM_LCFIFOMaskConfig(ENHTIM_TypeDef *ENHTIMx, FunctionalState NewState);
+
+/**
+ * \brief Enables or disables ENHTIMx interrupt.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] ENHTIM_INT: Specifies the ENHTIMx interrupt source which to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * \arg ENHTIM_INT_TIM: Enhance Timer interrupt source.
+ * \arg ENHTIM_INT_LATCH_CNT2_FIFO_FULL: Enhance Timer latch count2 fifo full interrupt source.
+ * \arg ENHTIM_INT_LATCH_CNT2_FIFO_EMPTY: Enhance Timer latch count2 fifo empty interrupt source.
+ * \arg ENHTIM_INT_LATCH_CNT2_FIFO_THD: Enhance Timer latch count2 fifo threshold interrupt source.
+ * \param[in] NewState: New state of the ENHTIMx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_enhance_timer_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+ *
+ * ENHTIM_InitTypeDef ENHTIM_InitStruct;
+ * ENHTIM_StructInit(&ENHTIM_InitStruct);
+ *
+ * ENHTIM_InitStruct.ENHTIM_PWM_En = PWM_DISABLE;
+ * ENHTIM_InitStruct.ENHTIM_Period = 1000000 - 1;
+ * ENHTIM_InitStruct.ENHTIM_Mode = ENHTIM_Mode_UserDefine;
+ * ENHTIM_Init(ENH_TIM0, &ENHTIM_InitStruct);
+ * ENHTIM_ClearINT(ENH_TIM0);
+ * ENHTIM_INTConfig(ENH_TIM0, ENABLE);
+ */
+void ENHTIM_INTConfig(ENHTIM_TypeDef *ENHTIMx, uint8_t ENHTIM_INT, FunctionalState NewState);
+
+/**
+ * \brief Read ENHTIMx latch counter2 fifo data.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] length: Latch count2 fifo length, max 4.
+ * \pBuf[out] pBuf: FIFO data out buffer.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * uint8_t length = ENHTIM_GetLatchCount2FIFOLength(ENH_TIM0);
+ * }
+ * \endcode
+ */
+void ENHTIM_ReadLatchCount2FIFO(ENHTIM_TypeDef *ENHTIMx, uint32_t *pBuf, uint8_t length);
+
+/**
+ * \brief Check whether the ENHTIM interrupt has occurred or not.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \return The new state of the specified ENHTIMx peripheral
+ * latch count2 fifo interrupt(SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * ITStatus int_status = ENHTIM_GetLCMaskINTStatus(ENH_TIM0);
+ * }
+ * \endcode
+ */
+ITStatus ENHTIM_GetLCFIFOMaskStatus(ENHTIM_TypeDef *ENHTIMx);
+
+/**
+ * \brief Check whether the ENHTIM interrupt has occurred or not.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] ENHTIM_INT: Specifies the ENHTIMx interrupt source which to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * \arg ENHTIM_INT_TIM: Enhance Timer interrupt source.
+ * \arg ENHTIM_INT_LATCH_CNT2_FIFO_FULL: Enhance Timer latch count2 fifo full interrupt source.
+ * \arg ENHTIM_INT_LATCH_CNT2_FIFO_EMPTY: Enhance Timer latch count2 fifo empty interrupt source.
+ * \arg ENHTIM_INT_LATCH_CNT2_FIFO_THD: Enhance Timer latch count2 fifo threshold interrupt source.
+ * \return The new state of the ENHTIM_INT(SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * ENHTIM_GetINTStatus(ENH_TIM0, ENHTIM_INT_TIM);
+ * }
+ * \endcode
+ */
+ITStatus ENHTIM_GetINTStatus(ENHTIM_TypeDef *ENHTIMx, uint8_t ENHTIM_INT);
+
+/**
+ * \brief Clear ENHTIMx interrupt.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] ENHTIM_INT: Specifies the ENHTIMx interrupt source which to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * \arg ENHTIM_INT_TIM: Enhance Timer interrupt source.
+ * \arg ENHTIM_INT_LATCH_CNT2_FIFO_FULL: Enhance Timer latch count2 fifo full interrupt source.
+ * \arg ENHTIM_INT_LATCH_CNT2_FIFO_THD: Enhance Timer latch count2 fifo threshold interrupt source.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * ENHTIM_ClearINTPendingBit(ENH_TIM0, ENHTIM_INT_TIM);
+ * }
+ * \endcode
+ */
+void ENHTIM_ClearINTPendingBit(ENHTIM_TypeDef *ENHTIMx, uint8_t ENHTIM_INT);
+
+/**
+ * \brief Get ENHTIMx current value when timer is running.
+ * \param[in] ENHTIMx: where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \return The counter value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * uint32_t cur_value = ENHTIM_GetCurrentValue(ENH_TIM0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t ENHTIM_GetCurrentCount(ENHTIM_TypeDef *ENHTIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+
+ return ENHTIMx->CUR_CNT;
+}
+
+/**
+ * \brief Set Max Count value.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] count: EnhtimerN max counter value for user-define PWM mode (leagel value range is from 0 ~
+2^32-2).
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * ENHTIM_SetMaxCount(ENH_TIM0, 0x10000);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void ENHTIM_SetMaxCount(ENHTIM_TypeDef *ENHTIMx, uint32_t count)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+
+ ENHTIMx->MAX_CNT = count & 0xFFFFFFFE;
+}
+
+/**
+ * \brief Set ENHTIMx capture/compare value for user-define PWM manual mode.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] value: .
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * ENHTIM_SetCCValue(ENH_TIM0, 0x1000);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void ENHTIM_SetCCValue(ENHTIM_TypeDef *ENHTIMx, uint32_t value)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+
+ ENHTIMx->CCR = value;
+}
+
+/**
+ * \brief Set ENHTIMx capture/compare value for user-define PWM auto mode.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] value: .
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * ENHTIM_WriteCCFIFO(ENH_TIM0,0x10000);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void ENHTIM_WriteCCFIFO(ENHTIM_TypeDef *ENHTIMx, uint32_t value)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+
+ ENHTIMx->CCR_FIFO = value;
+}
+
+///**
+// * \brief Check whether the specified ENHTIM CCR FIFO flag is set.
+// * \param[in] ENHTIM_FLAG: Specifies the flag to check.
+// * This parameter can be one of the following values:
+// * \arg ENHTIM_FLAG_TIM1_LC_FIFO_EMPTY: FIFO empty or not. If SET, CCR FIFO is empty.
+// * \arg ENHTIM_FLAG_TIM0_LC_FIFO_EMPTY: FIFO full or not. If SET, CCR FIFO is full.
+// * \return The new state of ENHTIM_FLAG (SET or RESET).
+// *
+// * <b>Example usage</b>
+// * \code{.c}
+// *
+// * void enhance_timer_demo(void)
+// * {
+// * FlagStatus flag_status = ENHTIM_GetCCRFIFOFlagStatus(ENHTIM_FLAG_FIFO_EMPTY);
+// * }
+// * \endcode
+// */
+//__STATIC_INLINE FlagStatus ENHTIM_GetLCFIFOFlagStatus(uint32_t ENHTIM_FLAG)
+//{
+// /* Check the parameters */
+// assert_param(IS_ENHTIM_LC_FIFO_FLAG(ENHTIM_FLAG));
+
+// FlagStatus bitstatus = RESET;
+
+// if (ENH_TIM_SHARE->FIFO_SR2 & ENHTIM_FLAG)
+// {
+// bitstatus = SET;
+// }
+
+// return bitstatus;
+//}
+
+///**
+// * \brief Check whether the specified ENHTIM CCR FIFO flag is set.
+// * \param[in] ENHTIM_FLAG: Specifies the flag to check.
+// * This parameter can be one of the following values:
+// * \arg ENHTIM_FLAG_TIM1_CCR_FIFO_EMPTY: FIFO empty or not. If SET, CCR FIFO is empty.
+// * \arg ENHTIM_FLAG_TIM1_CCR_FIFO_FULL: FIFO full or not. If SET, CCR FIFO is full.
+// * \arg ENHTIM_FLAG_TIM0_CCR_FIFO_EMPTY: FIFO empty or not. If SET, CCR FIFO is empty.
+// * \arg ENHTIM_FLAG_TIM0_CCR_FIFO_FULL: FIFO full or not. If SET, CCR FIFO is full.
+// * \return The new state of ENHTIM_FLAG (SET or RESET).
+// *
+// * <b>Example usage</b>
+// * \code{.c}
+// *
+// * void enhance_timer_demo(void)
+// * {
+// * FlagStatus flag_status = ENHTIM_GetCCRFIFOFlagStatus(ENHTIM_FLAG_FIFO_EMPTY);
+// * }
+// * \endcode
+// */
+//__STATIC_INLINE FlagStatus ENHTIM_GetCCRFIFOFlagStatus(uint32_t ENHTIM_FLAG)
+//{
+// /* Check the parameters */
+// assert_param(IS_ENHTIM_CCR_FIFO_FLAG(ENHTIM_FLAG));
+
+// FlagStatus bitstatus = RESET;
+
+// if (ENH_TIM_SHARE->FIFO_SR2 & ENHTIM_FLAG)
+// {
+// bitstatus = SET;
+// }
+
+// return bitstatus;
+//}
+
+/**
+ * \brief Check whether the specified ENHTIM CCR FIFO flag is set.
+ * \param[in] ENHTIM_FLAG: Specifies the flag to check.
+ * This parameter can be one of the following values:
+ * \arg ENHTIM_FLAG_TIM1_LC_FIFO_EMPTY: FIFO empty or not. If SET, CCR FIFO is empty.
+ * \arg ENHTIM_FLAG_TIM0_LC_FIFO_EMPTY: FIFO full or not. If SET, CCR FIFO is full.
+ * \arg ENHTIM_FLAG_TIM1_CCR_FIFO_EMPTY: FIFO empty or not. If SET, CCR FIFO is empty.
+ * \arg ENHTIM_FLAG_TIM1_CCR_FIFO_FULL: FIFO full or not. If SET, CCR FIFO is full.
+ * \arg ENHTIM_FLAG_TIM0_CCR_FIFO_EMPTY: FIFO empty or not. If SET, CCR FIFO is empty.
+ * \arg ENHTIM_FLAG_TIM0_CCR_FIFO_FULL: FIFO full or not. If SET, CCR FIFO is full.
+ * \return The new state of ENHTIM_FLAG (SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * FlagStatus flag_status = ENHTIM_GetCCRFIFOFlagStatus(ENHTIM_FLAG_FIFO_EMPTY);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE FlagStatus ENHTIM_GetFIFOFlagStatus(uint32_t ENHTIM_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_FIFO_FLAG(ENHTIM_FLAG));
+
+ FlagStatus bitstatus = RESET;
+
+ if (ENH_TIM_SHARE->FIFO_SR2 & ENHTIM_FLAG)
+ {
+ bitstatus = SET;
+ }
+
+ return bitstatus;
+}
+
+/**
+ * \brief Enable ENHTIMx latch counter.
+ * \param[in] ENHTIMx: where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] LatchCntIdx: E_ENHTIM_LATCHCNT enum value.
+ * This parameter can be one of follow.
+ * \arg LATCH_COUNT_0: Enhance timer latch count 0.
+ * \arg LATCH_COUNT_1: Enhance timer latch count 1.
+ * \arg LATCH_COUNT_2: Enhance timer latch count 2.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * uint32_t cur_value = ENHTIM_LatchCountEnable(ENH_TIM0, LATCH_COUNT_2);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void ENHTIM_LatchCountEnable(ENHTIM_TypeDef *ENHTIMx, E_ENHTIM_LATCHCNT LatchCntIdx)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+
+ ENHTIMx->CR |= BIT(LatchCntIdx + 10);
+}
+
+/**
+ * \brief Disable ENHTIMx latch counter.
+ * \param[in] ENHTIMx: where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] LatchCntIdx: E_ENHTIM_LATCHCNT enum value.
+ * This parameter can be one of follow.
+ * \arg LATCH_COUNT_0: Enhance timer latch count 0.
+ * \arg LATCH_COUNT_1: Enhance timer latch count 1.
+ * \arg LATCH_COUNT_2: Enhance timer latch count 2.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * uint32_t cur_value = ENHTIM_LatchCountDisable(ENH_TIM0, LATCH_COUNT_2);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void ENHTIM_LatchCountDisable(ENHTIM_TypeDef *ENHTIMx,
+ E_ENHTIM_LATCHCNT LatchCntIdx)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+
+ ENHTIMx->CR &= ~BIT(LatchCntIdx + 10);
+}
+
+/**
+ * \brief Get ENHTIMx latch count value.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] LatchCntIdx: E_ENHTIM_LATCHCNT enum value.
+ * This parameter can be one of follow.
+ * \arg LATCH_COUNT_0: Enhance timer latch count 0.
+ * \arg LATCH_COUNT_1: Enhance timer latch count 1.
+ * \arg LATCH_COUNT_2: Enhance timer latch count 2.
+ * \return The latch counter value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * uint32_t count_value = ENHTIM_GetLatchCountValue(ENH_TIM0, LATCH_COUNT_0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t ENHTIM_GetLatchCount(ENHTIM_TypeDef *ENHTIMx,
+ E_ENHTIM_LATCHCNT LatchCntIdx)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+
+ uint32_t count = 0;
+ count = *(volatile uint32_t *)(&(ENHTIMx->LATCH_CNT0) + LatchCntIdx);
+ return count;
+}
+
+/**
+ * \brief Get ENHTIMx latch counter2 fifo length.
+ * \param[in] ENHTIMx: where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \return FIFO data length.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * uint8_t length = ENHTIM_GetLatchCount2FIFOLength(ENH_TIM0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint8_t ENHTIM_GetLatchCount2FIFOLength(ENHTIM_TypeDef *ENHTIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+
+ uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24;
+
+ return (uint8_t)(((*((volatile uint32_t *)(&(ENH_TIM_SHARE->LC_FIFO_LEVEL0) + enhtim_id))) >> 16) &
+ 0x1F);
+}
+
+/**
+ * \brief Clear capture/compare or latch count2 fifo.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] FIFO_CLR: Specifies the FIFO type which to be clear.
+ * This parameter can be one of the following values:
+ * \arg ENHTIM_FIFO_CLR_CCR: Enhance Timer CCR FIFO clear flag.
+ * \arg ENHTIM_FIFO_CLR_CNT2: Enhance Timer latch count2 FIFO clear flag.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * ENHTIM_ClearFIFO(ENH_TIM0, ENHTIM_FIFO_CLR_CCR);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void ENHTIM_ClearFIFO(ENHTIM_TypeDef *ENHTIMx, uint8_t FIFO_CLR)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+
+ uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24;
+
+ ENH_TIM_SHARE->FIFO_CLR |= (BIT(FIFO_CLR + enhtim_id));
+}
+
+/**
+ * \brief ENHTIM PWM complementary output emergency stop.
+ * \param None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * ENHTIM_PWMDeadZoneEMStop();
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void ENHTIM_PWMDeadZoneEMStop(void)
+{
+ ENHTIM_PWM_DEADZONE_CR |= BIT(8);
+}
+
+/**
+ * \brief Get ENHTIM PWM output status.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \return ENHTIM PWM output status(SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * FlagStatus status = ENHTIM_GetPWMOutputState(ENH_TIM0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE FlagStatus ENHTIM_GetPWMOutputState(ENHTIM_TypeDef *ENHTIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+
+ uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24;
+ uint32_t status = ENHTIM_LATCH_COUNT_CR & (0x1 << (enhtim_id + 6));
+ return (FlagStatus)(status >> (enhtim_id + 6));
+}
+
+///**
+// * \brief Check whether the ENHTIM interrupt has occurred or not.
+// * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+// * \return The new state of the ENHTIM_IT(SET or RESET).
+// *
+// * <b>Example usage</b>
+// * \code{.c}
+// *
+// * void enhance_timer_demo(void)
+// * {
+// * ITStatus int_status = ENHTIM_GetINTStatus(ENH_TIM0);
+// * }
+// * \endcode
+// */
+//__STATIC_INLINE uint32_t ENHTIM_GetAllINTStatus(void)
+//{
+// return ENH_TIM_SHARE->MASK_INT_SR;
+//}
+
+/** \} */ /* End of group ENHTIM_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_RTL876X_ENH_TIM_H_*/
+
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/inc/peripheral/rtl876x_gdma.h b/inc/peripheral/rtl876x_gdma.h
new file mode 100644
index 0000000..5924eb4
--- /dev/null
+++ b/inc/peripheral/rtl876x_gdma.h
@@ -0,0 +1,970 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_gdma.h
+* \brief The header file of the peripheral GDMA driver.
+* \details This file provides all GDMA firmware functions.
+* \author yuan
+* \date 2019-11-14
+* \version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef _RTL876X_GDMA_H_
+#define _RTL876X_GDMA_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup GDMA GDMA
+ *
+ * \brief Manage the GDMA peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup GDMA_Exported_Types Init Params Struct
+ *
+ * \ingroup GDMA
+ */
+
+/**
+ * \brief GDMA init structure definition.
+ *
+ * \ingroup GDMA_Exported_Types
+ */
+typedef struct
+{
+ uint8_t GDMA_ChannelNum; /*!< Specifies channel number for GDMA. */
+ uint8_t GDMA_DIR; /*!< Specifies if the peripheral is the source or destination.
+ This parameter can be a value of \ref GDMA_Data_Transfer_Direction. */
+ uint32_t GDMA_BufferSize; /*!< Specifies the buffer size(<=4095), in data unit, of the specified Channel.
+ The data unit is equal to the configuration set in DMA_PeripheralDataSize
+ or DMA_MemoryDataSize members depending in the transfer direction. */
+ uint8_t GDMA_SourceInc; /*!< Specifies whether the source address register is incremented or not.
+ This parameter can be a value of \ref GDMA_Source_Incremented_Mode */
+ uint8_t GDMA_DestinationInc; /*!< Specifies whether the destination address register is incremented or not.
+ This parameter can be a value of \ref GDMA_Destination_Incremented_Mode. */
+ uint32_t GDMA_SourceDataSize; /*!< Specifies the source data width.
+ This parameter can be a value of \ref GDMA_Data_Size */
+ uint32_t GDMA_DestinationDataSize; /*!< Specifies the Memory data width.
+ This parameter can be a value of \ref GDMA_Data_Size */
+ uint32_t GDMA_SourceMsize; /*!< Specifies the number of data items to be transferred.
+ This parameter can be a value of \ref GDMA_Msize */
+ uint32_t GDMA_DestinationMsize; /*!< Specifies the number of data items to be transferred.
+ This parameter can be a value of \ref GDMA_Msize */
+ uint32_t GDMA_SourceAddr; /*!< Specifies the source base address for GDMA Channelx. */
+ uint32_t GDMA_DestinationAddr; /*!< Specifies the destination base address for GDMA Channelx. */
+ uint32_t GDMA_ChannelPriority; /*!< Specifies the software priority for the GDMA Channelx. */
+ uint32_t GDMA_Multi_Block_Mode; /*!< Specifies the multi block transfer mode.
+ This parameter can be a value of \ref GDMA_Multiblock_Mode. */
+ uint32_t GDMA_Multi_Block_Struct; /*!< Pointer to the first struct of LLI. */
+ uint8_t GDMA_Multi_Block_En; /*!< Enable or disable multi-block function. */
+ uint8_t GDMA_SourceHandshake; /*!< Specifies the handshake index in source.
+ This parameter can be a value of \ref GDMA_Handshake_Type. */
+ uint8_t GDMA_DestHandshake; /*!< Specifies the handshake index in Destination.
+ This parameter can be a value of \ref GDMA_Handshake_Type. */
+} GDMA_InitTypeDef;
+
+/**
+ * \brief GDMA link list item structure definition.
+ *
+ * \ingroup GDMA_Exported_Types
+ */
+typedef struct
+{
+ __IO uint32_t SAR;
+ __IO uint32_t DAR;
+ __IO uint32_t LLP;
+ __IO uint32_t CTL_LOW;
+ __IO uint32_t CTL_HIGH;
+} GDMA_LLIDef;
+
+
+
+#define DMA_CH_BASE(ChNum) ((GDMA_ChannelTypeDef *) (GDMA_CHANNEL_REG_BASE + ChNum * 0x0058))
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup GDMA_Exported_Constants Macro Definitions
+ *
+ * \ingroup GDMA
+ */
+
+#define IS_GDMA_ALL_PERIPH(PERIPH) (((PERIPH) == GDMA_Channel0) || \
+ ((PERIPH) == GDMA_Channel1) || \
+ ((PERIPH) == GDMA_Channel2) || \
+ ((PERIPH) == GDMA_Channel3))
+
+#define IS_GDMA_ChannelNum(NUM) ((NUM) < 4)
+
+/**
+ * \defgroup GDMA_Handshake_Type GDMA Handshake Type
+ * \{
+ * \ingroup GDMA_Exported_Constants
+ */
+#define GDMA_Handshake_UART0_TX (0)
+#define GDMA_Handshake_UART0_RX (1)
+#define GDMA_Handshake_ENH_TIM0 (2)
+#define GDMA_Handshake_ENH_TIM1 (3)
+#define GDMA_Handshake_SPI0_TX (4)
+#define GDMA_Handshake_SPI0_RX (5)
+#define GDMA_Handshake_SPI1_TX (6)
+#define GDMA_Handshake_SPI1_RX (7)
+#define GDMA_Handshake_I2C0_TX (8)
+#define GDMA_Handshake_I2C0_RX (9)
+#define GDMA_Handshake_I2C1_TX (10)
+#define GDMA_Handshake_I2C1_RX (11)
+#define GDMA_Handshake_ADC (12)
+#define GDMA_Handshake_AES_TX (13)
+#define GDMA_Handshake_AES_RX (14)
+#define GDMA_Handshake_UART1_TX (15)
+#define GDMA_Handshake_I2S0_TX (16)
+#define GDMA_Handshake_I2S0_RX (17)
+#define GDMA_Handshake_SPIC0_TX (20)
+#define GDMA_Handshake_SPIC0_RX (21)
+#define GDMA_Handshake_UART1_RX (23)
+#define GDMA_Handshake_TIM0 (24)
+#define GDMA_Handshake_TIM1 (25)
+#define GDMA_Handshake_TIM2 (26)
+#define GDMA_Handshake_IR_TX (27)
+#define GDMA_Handshake_IR_RX (28)
+#define GDMA_Handshake_TIM3 (29)
+#define GDMA_Handshake_TIM4 (30)
+#define GDMA_Handshake_TIM5 (31)
+/** \} */
+
+#define IS_GDMA_TransferType(Type) (((Type) == GDMA_Handshake_UART0_TX) || \
+ ((Type) == GDMA_Handshake_UART0_RX) || \
+ ((Type) == GDMA_Handshake_ENH_TIM0) || \
+ ((Type) == GDMA_Handshake_ENH_TIM1) || \
+ ((Type) == GDMA_Handshake_SPI0_TX) || \
+ ((Type) == GDMA_Handshake_SPI0_RX) || \
+ ((Type) == GDMA_Handshake_SPI1_TX) || \
+ ((Type) == GDMA_Handshake_SPI1_RX) || \
+ ((Type) == GDMA_Handshake_I2C0_TX) || \
+ ((Type) == GDMA_Handshake_I2C0_RX) || \
+ ((Type) == GDMA_Handshake_I2C1_TX) || \
+ ((Type) == GDMA_Handshake_I2C1_RX) || \
+ ((Type) == GDMA_Handshake_ADC) || \
+ ((Type) == GDMA_Handshake_AES_TX) || \
+ ((Type) == GDMA_Handshake_AES_RX) || \
+ ((Type) == GDMA_Handshake_UART1_TX) || \
+ ((Type) == GDMA_Handshake_I2S0_TX) || \
+ ((Type) == GDMA_Handshake_I2S0_RX) || \
+ ((Type) == GDMA_Handshake_SPIC0_TX) || \
+ ((Type) == GDMA_Handshake_SPIC0_RX) ||\
+ ((Type) == GDMA_Handshake_UART1_RX) || \
+ ((Type) == GDMA_Handshake_IR_TX) ||\
+ ((Type) == GDMA_Handshake_IR_RX) ||\
+ ((Type) == GDMA_Handshake_TIM0) ||\
+ ((Type) == GDMA_Handshake_TIM1) ||\
+ ((Type) == GDMA_Handshake_TIM2) ||\
+ ((Type) == GDMA_Handshake_TIM3) ||\
+ ((Type) == GDMA_Handshake_TIM4) ||\
+ ((Type) == GDMA_Handshake_TIM5))
+
+/**
+ * \defgroup GDMA_Data_Size GDMA Data Size
+ * \{
+ * \ingroup GDMA_Exported_Constants
+ */
+#define GDMA_DataSize_Byte ((uint32_t)0x00000000)
+#define GDMA_DataSize_HalfWord ((uint32_t)0x00000001)
+#define GDMA_DataSize_Word ((uint32_t)0x00000002)
+/** \} */
+
+#define IS_GDMA_DATA_SIZE(SIZE) (((SIZE) == GDMA_DataSize_Byte) || \
+ ((SIZE) == GDMA_DataSize_HalfWord) || \
+ ((SIZE) == GDMA_DataSize_Word))
+
+/**
+ * \defgroup GDMA_Msize GDMA Msize
+ * \{
+ * \ingroup GDMA_Exported_Constants
+ */
+#define GDMA_Msize_1 ((uint32_t)0x00000000)
+#define GDMA_Msize_4 ((uint32_t)0x00000001)
+#define GDMA_Msize_8 ((uint32_t)0x00000002)
+#define GDMA_Msize_16 ((uint32_t)0x00000003)
+#define GDMA_Msize_32 ((uint32_t)0x00000004)
+#define GDMA_Msize_64 ((uint32_t)0x00000005)
+#define GDMA_Msize_128 ((uint32_t)0x00000006)
+#define GDMA_Msize_256 ((uint32_t)0x00000007)
+/** \} */
+#define IS_GDMA_MSIZE(SIZE) (((SIZE) == GDMA_Msize_1) || \
+ ((SIZE) == GDMA_Msize_4) || \
+ ((SIZE) == GDMA_Msize_8) || \
+ ((SIZE) == GDMA_Msize_16) || \
+ ((SIZE) == GDMA_Msize_32) || \
+ ((SIZE) == GDMA_Msize_64) || \
+ ((SIZE) == GDMA_Msize_128) || \
+ ((SIZE) == GDMA_Msize_256))
+
+/**
+ * \defgroup GDMA_Data_Transfer_Direction GDMA Data Transfer Direction
+ * \{
+ * \ingroup GDMA_Exported_Constants
+ */
+#define GDMA_DIR_MemoryToMemory ((uint32_t)0x00000000)
+#define GDMA_DIR_MemoryToPeripheral ((uint32_t)0x00000001)
+#define GDMA_DIR_PeripheralToMemory ((uint32_t)0x00000002)
+#define GDMA_DIR_PeripheralToPeripheral ((uint32_t)0x00000003)
+/** \} */
+
+#define IS_GDMA_DIR(DIR) (((DIR) == GDMA_DIR_MemoryToMemory) || \
+ ((DIR) == GDMA_DIR_MemoryToPeripheral) || \
+ ((DIR) == GDMA_DIR_PeripheralToMemory) ||\
+ ((DIR) == GDMA_DIR_PeripheralToPeripheral))
+
+/**
+ * \defgroup GDMA_Source_Incremented_Mode GDMA Source Incremented Mode
+ * \{
+ * \ingroup GDMA_Exported_Constants
+ */
+#define DMA_SourceInc_Inc ((uint32_t)0x00000000)
+#define DMA_SourceInc_Dec ((uint32_t)0x00000001)
+#define DMA_SourceInc_Fix ((uint32_t)0x00000002)
+/** \} */
+
+#define IS_GDMA_SourceInc(STATE) (((STATE) == DMA_SourceInc_Inc) || \
+ ((STATE) == DMA_SourceInc_Dec) || \
+ ((STATE) == DMA_SourceInc_Fix))
+
+/**
+ * \defgroup GDMA_Destination_Incremented_Mode GDMA Destination Incremented Mode
+ * \{
+ * \ingroup GDMA_Exported_Constants
+ */
+#define DMA_DestinationInc_Inc ((uint32_t)0x00000000)
+#define DMA_DestinationInc_Dec ((uint32_t)0x00000001)
+#define DMA_DestinationInc_Fix ((uint32_t)0x00000002)
+/** \} */
+
+#define IS_GDMA_DestinationInc(STATE) (((STATE) == DMA_DestinationInc_Inc) || \
+ ((STATE) == DMA_DestinationInc_Dec) || \
+ ((STATE) == DMA_DestinationInc_Fix))
+
+/**
+ * \defgroup DMA_Interrupts_Definition DMA Interrupts Definition
+ * \{
+ * \ingroup GDMA_Exported_Constants
+ */
+#define GDMA_INT_Transfer ((uint32_t)0x00000001)
+#define GDMA_INT_Block ((uint32_t)0x00000002)
+#define GDMA_INT_SrcTransfer ((uint32_t)0x00000004)
+#define GDMA_INT_DstTransfer ((uint32_t)0x00000008)
+#define GDMA_INT_Error ((uint32_t)0x00000010)
+/** \} */
+
+#define IS_GDMA_CONFIG_IT(IT) ((((IT) & 0xFFFFFE00) == 0x00) && ((IT) != 0x00))
+
+/**
+ * \defgroup GDMA_Multiblock_Mode GDMA Multi-block Mode
+ * \{
+ * \ingroup GDMA_Exported_Constants
+ */
+#define AUTO_RELOAD_WITH_CONTIGUOUS_SAR (BIT30)
+#define AUTO_RELOAD_WITH_CONTIGUOUS_DAR (BIT31)
+#define AUTO_RELOAD_TRANSFER (BIT30 | BIT31)
+#define LLI_WITH_CONTIGUOUS_SAR (BIT27)
+#define LLI_WITH_AUTO_RELOAD_SAR (BIT27 | BIT30)
+#define LLI_WITH_CONTIGUOUS_DAR (BIT28)
+#define LLI_WITH_AUTO_RELOAD_DAR (BIT28 | BIT31)
+#define LLI_TRANSFER (BIT27 | BIT28)
+/** \} */
+
+#define IS_GDMA_MULTIBLOCKMODE(MODE) (((MODE) == AUTO_RELOAD_WITH_CONTIGUOUS_SAR) || ((MODE) == AUTO_RELOAD_WITH_CONTIGUOUS_DAR)\
+ ||((MODE) == AUTO_RELOAD_TRANSFER) || ((MODE) == LLI_WITH_CONTIGUOUS_SAR)\
+ ||((MODE) == LLI_WITH_AUTO_RELOAD_SAR) || ((MODE) == LLI_WITH_CONTIGUOUS_DAR)\
+ ||((MODE) == LLI_WITH_AUTO_RELOAD_DAR) || ((MODE) == LLI_TRANSFER))
+
+/**
+ * \def GDMA_Multiblock_Select_Bit Multi-Block Select Bit
+ *
+ */
+#define AUTO_RELOAD_SELECTED_BIT (uint32_t)(0xC0000000)
+#define LLP_SELECTED_BIT (uint32_t)(0x18000000)
+
+/**
+ * \def DMA_Suspend_Flag_Definition DMA Suspend Flag Definition
+ */
+#define GDMA_FIFO_STATUS (BIT(9))
+#define GDMA_SUSPEND_TRANSMISSSION (BIT(8))
+#define GDMA_SUSPEND_CMD_STATUS (BIT(2) | BIT(1))
+#define GDMA_SUSPEND_CHANNEL_STATUS (BIT(0))
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup GDMA_Exported_Functions Peripheral APIs
+ * \{
+ * \ingroup GDMA
+ */
+
+/**
+ * \brief Deinitializes the GDMA registers to their default reset
+ * values.
+ * \param None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_gdma_init(void)
+ * {
+ * GDMA_DeInit();
+ * }
+ * \endcode
+ */
+void GDMA_DeInit(void);
+
+/**
+ * \brief Initializes the GDMA Channelx according to the specified
+ * parameters in the GDMA_InitStruct.
+ * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the DMA Channel.
+ * \param[in] GDMA_InitStruct: Pointer to a GDMA_InitTypeDef structure that
+ * contains the configuration information for the specified DMA Channel.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_gdma_init(void)
+ * {
+ *
+ * for (uint32_t i = 0; i < UART_TX_GDMA_BUFFER_SIZE; i++)
+ * {
+ * GDMA_SendData_Buffer[i] = 0x10 + i;
+ * }
+
+ * GDMA_InitTypeDef GDMA_InitStruct;
+ * GDMA_StructInit(&GDMA_InitStruct);
+ * GDMA_InitStruct.GDMA_ChannelNum = 1;
+ * GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral;
+ * GDMA_InitStruct.GDMA_BufferSize = UART_TX_GDMA_BUFFER_SIZE;//determine total transfer size
+ * GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc;
+ * GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ * GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ * GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ * GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ * GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+ * GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_SendData_Buffer;
+ * GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(UART0->RB_THR));
+ * GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_UART0_TX;
+ * GDMA_InitStruct.GDMA_ChannelPriority = 2;//channel prority between 0 to 5
+ * GDMA_Init(UART_TX_GDMA_CHANNEL, &GDMA_InitStruct);
+
+ * GDMA_INTConfig(UART_TX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+
+ * NVIC_InitTypeDef NVIC_InitStruct;
+ * NVIC_InitStruct.NVIC_IRQChannel = UART_TX_GDMA_CHANNEL_IRQN;
+ * NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ * NVIC_Init(&NVIC_InitStruct);
+
+ * GDMA_Cmd(UART_TX_GDMA_CHANNEL_NUM, ENABLE);
+ * }
+ * \endcode
+ */
+void GDMA_Init(GDMA_ChannelTypeDef *GDMA_Channelx, GDMA_InitTypeDef *GDMA_InitStruct);
+
+/**
+ * \brief Fills each GDMA_InitStruct member with its default value.
+ * \param[in] GDMA_InitStruct : pointer to a GDMA_InitTypeDef structure which will
+ * be initialized.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_gdma_init(void)
+ * {
+ *
+ * for (uint32_t i = 0; i < UART_TX_GDMA_BUFFER_SIZE; i++)
+ * {
+ * GDMA_SendData_Buffer[i] = 0x10 + i;
+ * }
+
+ * GDMA_InitTypeDef GDMA_InitStruct;
+ * GDMA_StructInit(&GDMA_InitStruct);
+ * GDMA_InitStruct.GDMA_ChannelNum = 1;
+ * GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral;
+ * GDMA_InitStruct.GDMA_BufferSize = UART_TX_GDMA_BUFFER_SIZE;//determine total transfer size
+ * GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc;
+ * GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ * GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ * GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ * GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ * GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+ * GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_SendData_Buffer;
+ * GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(UART0->RB_THR));
+ * GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_UART0_TX;
+ * GDMA_InitStruct.GDMA_ChannelPriority = 2;//channel prority between 0 to 5
+ * GDMA_Init(UART_TX_GDMA_CHANNEL, &GDMA_InitStruct);
+ *
+ * }
+ * \endcode
+ */
+void GDMA_StructInit(GDMA_InitTypeDef *GDMA_InitStruct);
+
+/**
+ * \brief Enables or disables the selected GDMA channel.
+ * \param[in] GDMA_Channel_Num: GDMA channel number, can be 0~3.
+ * \param[in] NewState: New state of the selected DMA channel.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_gdma_init(void)
+ * {
+ *
+ * for (uint32_t i = 0; i < UART_TX_GDMA_BUFFER_SIZE; i++)
+ * {
+ * GDMA_SendData_Buffer[i] = 0x10 + i;
+ * }
+
+ * GDMA_InitTypeDef GDMA_InitStruct;
+ * GDMA_StructInit(&GDMA_InitStruct);
+ * GDMA_InitStruct.GDMA_ChannelNum = 1;
+ * GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral;
+ * GDMA_InitStruct.GDMA_BufferSize = UART_TX_GDMA_BUFFER_SIZE;//determine total transfer size
+ * GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc;
+ * GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ * GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ * GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ * GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ * GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+ * GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_SendData_Buffer;
+ * GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(UART0->RB_THR));
+ * GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_UART0_TX;
+ * GDMA_InitStruct.GDMA_ChannelPriority = 2;//channel prority between 0 to 5
+ * GDMA_Init(UART_TX_GDMA_CHANNEL, &GDMA_InitStruct);
+
+ * GDMA_INTConfig(UART_TX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+
+ * NVIC_InitTypeDef NVIC_InitStruct;
+ * NVIC_InitStruct.NVIC_IRQChannel = UART_TX_GDMA_CHANNEL_IRQN;
+ * NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ * NVIC_Init(&NVIC_InitStruct);
+
+ * GDMA_Cmd(UART_TX_GDMA_CHANNEL_NUM, ENABLE);
+ * }
+ * \endcode
+ */
+void GDMA_Cmd(uint8_t GDMA_Channel_Num, FunctionalState NewState);
+
+/**
+ * \brief Enables or disables the specified DMA channelx interrupt source.
+ * \param[in] GDMA_Channel_Num: GDMA channel number, can be 0~3.
+ * \param[in] GDMA_IT: Specifies the GDMA interrupt source to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * \arg GDMA_INT_Transfer: Transfer complete interrupt source.
+ * \arg GDMA_INT_Block: Block transfer interrupt source.
+ * \arg GDMA_INT_SrcTransfer: SourceTransfer interrupt source.
+ * \arg GDMA_INT_DstTransfer: Destination Transfer interruptsource.
+ * \arg GDMA_INT_Error: Transfer error interrupt source.
+ * \param[in] NewState: New state of the specified DMA interrupt source.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_gdma_init(void)
+ * {
+ *
+ * for (uint32_t i = 0; i < UART_TX_GDMA_BUFFER_SIZE; i++)
+ * {
+ * GDMA_SendData_Buffer[i] = 0x10 + i;
+ * }
+
+ * GDMA_InitTypeDef GDMA_InitStruct;
+ * GDMA_StructInit(&GDMA_InitStruct);
+ * GDMA_InitStruct.GDMA_ChannelNum = 1;
+ * GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral;
+ * GDMA_InitStruct.GDMA_BufferSize = UART_TX_GDMA_BUFFER_SIZE;//determine total transfer size
+ * GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc;
+ * GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ * GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ * GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ * GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ * GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+ * GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_SendData_Buffer;
+ * GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(UART0->RB_THR));
+ * GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_UART0_TX;
+ * GDMA_InitStruct.GDMA_ChannelPriority = 2;//channel prority between 0 to 5
+ * GDMA_Init(UART_TX_GDMA_CHANNEL, &GDMA_InitStruct);
+
+ * GDMA_INTConfig(UART_TX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+
+ * NVIC_InitTypeDef NVIC_InitStruct;
+ * NVIC_InitStruct.NVIC_IRQChannel = UART_TX_GDMA_CHANNEL_IRQN;
+ * NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ * NVIC_Init(&NVIC_InitStruct);
+
+ * GDMA_Cmd(UART_TX_GDMA_CHANNEL_NUM, ENABLE);
+ * }
+ * \endcode
+ */
+void GDMA_INTConfig(uint8_t GDMA_Channel_Num, uint32_t GDMA_IT, FunctionalState NewState);
+
+/**
+ * \brief Clear the specified DMA channelx interrupt pending bit.
+ * \param[in] GDMA_Channel_Num: GDMA channel number, can be 0~3.
+ * \param[in] GDMA_IT: Specifies the GDMA interrupts sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * \arg GDMA_INT_Transfer: Transfer complete interrupt source.
+ * \arg GDMA_INT_Block: Block transfer interrupt source.
+ * \arg GDMA_INT_SrcTransfer: SourceTransfer interrupt source.
+ * \arg GDMA_INT_DstTransfer: Destination Transfer interruptsource.
+ * \arg GDMA_INT_Error: Transfer error interrupt source.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gdma_demo(void)
+ * {
+ * driver_gdma_init();
+ * }
+ *
+ * void UART_TX_GDMA_Handler(void)
+ * {
+ * GDMA_ClearINTPendingBit(1, GDMA_INT_Transfer);
+ * //Add user code here.
+ * }
+ * \endcode
+ */
+void GDMA_ClearINTPendingBit(uint8_t GDMA_Channel_Num, uint32_t GDMA_IT);
+
+/**
+ * \brief Get selected GDMA channel status.
+ * \param[in] GDMA_Channel_Num: GDMA channel number, can be 0~3.
+ * \return GDMA channel status.
+ * \retval SET: Channel is be used
+ * \retval RESET: Channel is free.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gdma_demo(void)
+ * {
+ * FlagStatus flag_status = GDMA_GetChannelStatus(0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE FlagStatus GDMA_GetChannelStatus(uint8_t GDMA_Channel_Num)
+{
+ FlagStatus bit_status = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_GDMA_ChannelNum(GDMA_Channel_Num));
+
+ if ((GDMA_BASE->ChEnReg & BIT(GDMA_Channel_Num)) != (uint32_t)RESET)
+ {
+
+ bit_status = SET;
+ }
+
+ /* Return the selected channel status */
+ return bit_status;
+}
+
+/**
+ * \brief Check whether GDMA Channel transfer interrupt is set.
+ * \param[in] GDMA_Channel_Num: GDMA channel number, can be 0~3.
+ * \return Transfer interrupt status, SET or RESET.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gdma_demo(void)
+ * {
+ * ITStatus int_status = GDMA_GetTransferINTStatus(0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE ITStatus GDMA_GetTransferINTStatus(uint8_t GDMA_Channel_Num)
+{
+ ITStatus bit_status = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_GDMA_ChannelNum(GDMA_Channel_Num));
+
+ if ((GDMA_BASE->STATUS_TFR & BIT(GDMA_Channel_Num)) != (uint32_t)RESET)
+ {
+
+ bit_status = SET;
+ }
+
+ /* Return the transfer interrupt status */
+ return bit_status;
+}
+
+/**
+ * \brief Clear GDMA Channelx all interrupt.
+ * \param[in] GDMA_Channel_Num: GDMA channel number, can be 0~3.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gdma_demo(void)
+ * {
+ * GDMA_ClearAllTypeINT(0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void GDMA_ClearAllTypeINT(uint8_t GDMA_Channel_Num)
+{
+ /* Check the parameters */
+ assert_param(IS_GDMA_ChannelNum(GDMA_Channel_Num));
+
+ GDMA_BASE->CLEAR_TFR = BIT(GDMA_Channel_Num);
+ GDMA_BASE->CLEAR_BLOCK = BIT(GDMA_Channel_Num);
+ GDMA_BASE->CLEAR_DST_TRAN = BIT(GDMA_Channel_Num);
+ GDMA_BASE->CLEAR_SRC_TRAN = BIT(GDMA_Channel_Num);
+ GDMA_BASE->CLEAR_ERR = BIT(GDMA_Channel_Num);
+}
+
+/**
+ * \brief Set GDMA transmission source address.
+ * \param[in] GDMA_Channelx: where x can be 0 to 3 to select the DMA Channel.
+ * \param[in] Address: Source address.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gdma_demo(void)
+ * {
+ * uint32_t data_buf[10] = {0};
+ * GDMA_SetSourceAddress(GDMA_Channel0,(uint32_t)data_buf);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void GDMA_SetSourceAddress(GDMA_ChannelTypeDef *GDMA_Channelx, uint32_t Address)
+{
+ /* Check the parameters */
+ assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx));
+
+ GDMA_Channelx->SAR = Address;
+}
+
+/**
+ * \brief Set GDMA transmission destination address.
+ * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the GDMA Channel.
+ * \param[in] Address: Destination address.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gdma_demo(void)
+ * {
+ * uint32_t data_buf[10] = {0};
+ * GDMA_SetDestinationAddress(GDMA_Channel0,(uint32_t)data_buf);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void GDMA_SetDestinationAddress(GDMA_ChannelTypeDef *GDMA_Channelx,
+ uint32_t Address)
+{
+ /* Check the parameters */
+ assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx));
+
+ GDMA_Channelx->DAR = Address;
+}
+
+/**
+ * \brief Set GDMA buffer size.
+ * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the GDMA Channel.
+ * \param[in] buffer_size: Set GDMA_BufferSize.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gdma_demo(void)
+ * {
+ * uint32_t data_buf_size = 4095;//max
+ * GDMA_SetBufferSize(GDMA_Channel0,data_buf_size);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void GDMA_SetBufferSize(GDMA_ChannelTypeDef *GDMA_Channelx, uint32_t buffer_size)
+{
+ /* Check the parameters */
+ assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx));
+
+ /* configure high 32 bit of CTL register */
+ GDMA_Channelx->CTL_HIGH = buffer_size;
+}
+
+/**
+ * \brief Suspend GDMA transmission from the source.
+ * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the GDMA Channel.
+ * \param[in] NewState: New state of the DMA Channelx.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ * \note To prevent data loss, it is necessary to check whether FIFO data transmission is completed
+ * after suspend, and judge by checking whether GDMA FIFO is empty.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gdma_demo(void)
+ * {
+ * GDMA_SuspendCmd(GDMA_Channel0,ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void GDMA_SuspendCmd(GDMA_ChannelTypeDef *GDMA_Channelx,
+ FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState == DISABLE)
+ {
+ /* Not suspend transmission*/
+ GDMA_Channelx->CFG_LOW &= ~(GDMA_SUSPEND_TRANSMISSSION);
+ }
+ else
+ {
+ /* Suspend transmission */
+ GDMA_Channelx->CFG_LOW |= GDMA_SUSPEND_TRANSMISSSION;
+ }
+}
+
+/**
+ * \brief Get GDMA transfer data length.
+ * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the GDMA Channel.
+ * \return GDMA transfer data length.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gdma_demo(void)
+ * {
+ * uint16_t data_len = GDMA_GetTransferLen(GDMA_Channel0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint16_t GDMA_GetTransferLen(GDMA_ChannelTypeDef *GDMA_Channelx)
+{
+ /* Check the parameters */
+ assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx));
+
+ return (uint16_t)(GDMA_Channelx->CTL_HIGH & 0xffff);
+}
+
+/**
+ * \brief Set GDMA LLP structure address.
+ * \param[in] GDMA_Channelx: Only for GDMA_Channel0~3.
+ * \param[in] Address: LLP structure address.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gdma_demo(void)
+ * {
+ * GDMA_LLIDef GDMA_LLIStruct[4000];
+ * GDMA_SetLLPAddress(GDMA_Channel0,(uint32_t)GDMA_LLIStruct);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void GDMA_SetLLPAddress(GDMA_ChannelTypeDef *GDMA_Channelx, uint32_t Address)
+{
+ /* Check the parameters */
+ assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx));
+
+ if ((GDMA_Channelx == GDMA_Channel0) | (GDMA_Channelx == GDMA_Channel1) | \
+ (GDMA_Channelx == GDMA_Channel2) | (GDMA_Channelx == GDMA_Channel3))
+ {
+ GDMA_Channelx->LLP = Address;
+ }
+}
+
+/**
+ * \brief Check GDMA suspend channel status.
+ * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the GDMA Channel.
+ * \return GDMA suspend channel status.
+ * \retval SET: Inactive.
+ * \retval RESET: Active.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gdma_demo(void)
+ * {
+ * FlagStatus flag_status = GDMA_GetSuspendChannelStatus(GDMA_Channel0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE FlagStatus GDMA_GetSuspendChannelStatus(GDMA_ChannelTypeDef *GDMA_Channelx)
+{
+ FlagStatus bit_status = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx));
+
+ if ((GDMA_Channelx->CFG_LOW & GDMA_SUSPEND_CHANNEL_STATUS) == GDMA_SUSPEND_CHANNEL_STATUS)
+ {
+ bit_status = SET;
+ }
+
+ /* Return the selected channel suspend status */
+ return bit_status;
+}
+
+/**
+ * \brief Check GDMA suspend command status.
+ * \param GDMA_Channelx: Where x can be 0 to 3 to select the GDMA Channel.
+ * \return GDMA suspend command status.
+ * \retval SET: Suspend.
+ * \retval RESET: Not suspend.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gdma_demo(void)
+ * {
+ * FlagStatus flag_status = GDMA_GetSuspendCmdStatus(GDMA_Channel0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE FlagStatus GDMA_GetSuspendCmdStatus(GDMA_ChannelTypeDef *GDMA_Channelx)
+{
+ FlagStatus bit_status = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx));
+
+ if ((GDMA_Channelx->CFG_LOW & GDMA_SUSPEND_CMD_STATUS) == GDMA_SUSPEND_CMD_STATUS)
+ {
+ bit_status = SET;
+ }
+
+ /* Return the selected channel suspend status */
+ return bit_status;
+}
+
+/**
+ * \brief Check GDMA FIFO status.
+ * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the GDMA Channel.
+ * \return GDMA FIFO status.
+ * \retval SET: FIFO empty.
+ * \retval RESET: FIFO not empty.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gdma_demo(void)
+ * {
+ * FlagStatus flag_status = GDMA_GetFIFOStatus(GDMA_Channel0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE FlagStatus GDMA_GetFIFOStatus(GDMA_ChannelTypeDef *GDMA_Channelx)
+{
+ FlagStatus bit_status = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx));
+
+ if ((GDMA_Channelx->CFG_LOW & GDMA_FIFO_STATUS) != (uint32_t)RESET)
+ {
+
+ bit_status = SET;
+ }
+
+ /* Return the selected channel status */
+ return bit_status;
+}
+
+/**
+ * \brief Get GDMA source address.
+ * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the DMA Channel.
+ * \return Source address.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gdma_demo(void)
+ * {
+ * uint32_t address = GDMA_GetSrcTransferAddress(GDMA_Channel0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t GDMA_GetSrcTransferAddress(GDMA_ChannelTypeDef *GDMA_Channelx)
+{
+ /* Check the parameters */
+ assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx));
+
+ uint32_t address = 0;
+ address = GDMA_Channelx->SAR;
+ return address;
+}
+
+/**
+ * \brief Get GDMA destination address.
+ * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the DMA Channel.
+ * \return Destination address.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gdma_demo(void)
+ * {
+ * uint32_t address = GDMA_GetDstTransferAddress(GDMA_Channel0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t GDMA_GetDstTransferAddress(GDMA_ChannelTypeDef *GDMA_Channelx)
+{
+ /* Check the parameters */
+ assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx));
+
+ uint32_t address = 0;
+ address = GDMA_Channelx->DAR;
+ return address;
+}
+
+/** \} */ /* End of group GDMA_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_RTL8762X_GDMA_H_*/
+
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/inc/peripheral/rtl876x_gpio.h b/inc/peripheral/rtl876x_gpio.h
new file mode 100644
index 0000000..aa66709
--- /dev/null
+++ b/inc/peripheral/rtl876x_gpio.h
@@ -0,0 +1,805 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_gpio.h
+* \brief The header file of the peripheral GPIO driver.
+* \details This file provides all GPIO firmware functions.
+* \author elliot chen
+* \date 2015-05-20
+* \version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef _RTL876X_GPIO_H_
+#define _RTL876X_GPIO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup GPIO GPIO
+ *
+ * \brief Manage the GPIO peripheral functions.
+ *
+ * \ingroup IO
+ */
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+
+/**
+ * \cond private
+ * \defgroup GPIO_Debounce_Register GPIO Debounce Register
+ * \{
+ */
+
+/**
+ * \brief GPIO Private Defines
+ */
+#define GPIO_DBCLK_DIV *((volatile uint32_t *)0x40000344UL)
+
+/**
+ * \}
+ * \endcond
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup GPIO_Exported_Constants Macro Definitions
+ *
+ * \ingroup GPIO
+ */
+
+/**
+ * \defgroup GPIO_Number GPIO Number
+ * \{
+ * \ingroup GPIO_Exported_Constants
+ */
+#define GPIO0 0
+#define GPIO1 1
+#define GPIO2 2
+#define GPIO3 3
+#define GPIO4 4
+#define GPIO5 5
+#define GPIO6 6
+#define GPIO7 7
+#define GPIO8 8
+#define GPIO9 9
+#define GPIO10 10
+#define GPIO11 11
+#define GPIO12 12
+#define GPIO13 13
+#define GPIO14 14
+#define GPIO15 15
+#define GPIO16 16
+#define GPIO17 17
+#define GPIO18 18
+#define GPIO19 19
+#define GPIO20 20
+#define GPIO21 21
+#define GPIO22 22
+#define GPIO23 23
+#define GPIO24 24
+#define GPIO25 25
+#define GPIO26 26
+#define GPIO27 27
+#define GPIO28 28
+#define GPIO29 29
+#define GPIO30 30
+#define GPIO31 31
+/** \} */
+
+/**
+ * \defgroup GPIO_Pins_Define GPIO Pins Define
+ * \{
+ * \ingroup GPIO_Exported_Constants
+ */
+#define GPIO_Pin_0 ((uint32_t)0x00000001) /*!< Pin 0 selected */
+#define GPIO_Pin_1 ((uint32_t)0x00000002) /*!< Pin 1 selected */
+#define GPIO_Pin_2 ((uint32_t)0x00000004) /*!< Pin 2 selected */
+#define GPIO_Pin_3 ((uint32_t)0x00000008) /*!< Pin 3 selected */
+#define GPIO_Pin_4 ((uint32_t)0x00000010) /*!< Pin 4 selected */
+#define GPIO_Pin_5 ((uint32_t)0x00000020) /*!< Pin 5 selected */
+#define GPIO_Pin_6 ((uint32_t)0x00000040) /*!< Pin 6 selected */
+#define GPIO_Pin_7 ((uint32_t)0x00000080) /*!< Pin 7 selected */
+#define GPIO_Pin_8 ((uint32_t)0x00000100) /*!< Pin 8 selected */
+#define GPIO_Pin_9 ((uint32_t)0x00000200) /*!< Pin 9 selected */
+#define GPIO_Pin_10 ((uint32_t)0x00000400) /*!< Pin 10 selected */
+#define GPIO_Pin_11 ((uint32_t)0x00000800) /*!< Pin 11 selected */
+#define GPIO_Pin_12 ((uint32_t)0x00001000) /*!< Pin 12 selected */
+#define GPIO_Pin_13 ((uint32_t)0x00002000) /*!< Pin 13 selected */
+#define GPIO_Pin_14 ((uint32_t)0x00004000) /*!< Pin 14 selected */
+#define GPIO_Pin_15 ((uint32_t)0x00008000) /*!< Pin 15 selected */
+#define GPIO_Pin_16 ((uint32_t)0x00010000) /*!< Pin 16 selected */
+#define GPIO_Pin_17 ((uint32_t)0x00020000) /*!< Pin 17 selected */
+#define GPIO_Pin_18 ((uint32_t)0x00040000) /*!< Pin 18 selected */
+#define GPIO_Pin_19 ((uint32_t)0x00080000) /*!< Pin 19 selected */
+#define GPIO_Pin_20 ((uint32_t)0x00100000) /*!< Pin 20 selected */
+#define GPIO_Pin_21 ((uint32_t)0x00200000) /*!< Pin 21 selected */
+#define GPIO_Pin_22 ((uint32_t)0x00400000) /*!< Pin 22 selected */
+#define GPIO_Pin_23 ((uint32_t)0x00800000) /*!< Pin 23 selected */
+#define GPIO_Pin_24 ((uint32_t)0x01000000) /*!< Pin 24 selected */
+#define GPIO_Pin_25 ((uint32_t)0x02000000) /*!< Pin 25 selected */
+#define GPIO_Pin_26 ((uint32_t)0x04000000) /*!< Pin 26 selected */
+#define GPIO_Pin_27 ((uint32_t)0x08000000) /*!< Pin 27 selected */
+#define GPIO_Pin_28 ((uint32_t)0x10000000) /*!< Pin 28 selected */
+#define GPIO_Pin_29 ((uint32_t)0x20000000) /*!< Pin 29 selected */
+#define GPIO_Pin_30 ((uint32_t)0x40000000) /*!< Pin 30 selected */
+#define GPIO_Pin_31 ((uint32_t)0x80000000) /*!< Pin 31 selected */
+#define GPIO_Pin_All ((uint32_t)0xFFFFFFFF) /*!< All pins selected */
+/** \} */
+
+#define IS_PIN_NUM(NUM) ((NUM) <= (uint8_t)P4_1)
+
+#define IS_GPIO_PIN(PIN) ((PIN) != (uint32_t)0x00)
+
+#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \
+ ((PIN) == GPIO_Pin_1) || \
+ ((PIN) == GPIO_Pin_2) || \
+ ((PIN) == GPIO_Pin_3) || \
+ ((PIN) == GPIO_Pin_4) || \
+ ((PIN) == GPIO_Pin_5) || \
+ ((PIN) == GPIO_Pin_6) || \
+ ((PIN) == GPIO_Pin_7) || \
+ ((PIN) == GPIO_Pin_8) || \
+ ((PIN) == GPIO_Pin_9) || \
+ ((PIN) == GPIO_Pin_10) || \
+ ((PIN) == GPIO_Pin_11) || \
+ ((PIN) == GPIO_Pin_12) || \
+ ((PIN) == GPIO_Pin_13) || \
+ ((PIN) == GPIO_Pin_14) || \
+ ((PIN) == GPIO_Pin_15) || \
+ ((PIN) == GPIO_Pin_16) || \
+ ((PIN) == GPIO_Pin_17) || \
+ ((PIN) == GPIO_Pin_18) || \
+ ((PIN) == GPIO_Pin_19) || \
+ ((PIN) == GPIO_Pin_20) || \
+ ((PIN) == GPIO_Pin_21) || \
+ ((PIN) == GPIO_Pin_22) || \
+ ((PIN) == GPIO_Pin_23) || \
+ ((PIN) == GPIO_Pin_24) || \
+ ((PIN) == GPIO_Pin_25) || \
+ ((PIN) == GPIO_Pin_26) || \
+ ((PIN) == GPIO_Pin_27) || \
+ ((PIN) == GPIO_Pin_28) || \
+ ((PIN) == GPIO_Pin_29) || \
+ ((PIN) == GPIO_Pin_30) || \
+ ((PIN) == GPIO_Pin_31))
+/**
+ * \brief Bit_SET and Bit_RESET enumeration
+ */
+typedef enum
+{
+ Bit_RESET = 0,
+ Bit_SET
+} BitAction;
+
+#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET))
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup GPIO_Exported_Types GPIO Exported Types
+ *
+ * \ingroup GPIO
+ */
+
+/**
+ * \brief GPIO mode enumeration.
+ *
+ * \ingroup GPIO_Exported_Types
+ */
+typedef enum
+{
+ GPIO_Mode_IN = 0x00, /**< GPIO Input Mode */
+ GPIO_Mode_OUT = 0x01, /**< GPIO Output Mode */
+} GPIOMode_TypeDef;
+
+#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN)|| ((MODE) == GPIO_Mode_OUT))
+
+/**
+ * \brief Setting interrupt trigger type.
+ *
+ * \ingroup GPIO_Exported_Types
+ */
+typedef enum
+{
+ GPIO_INT_Trigger_LEVEL = 0x0, /**< This interrupt is level trigger. */
+ GPIO_INT_Trigger_EDGE = 0x1, /**< This interrupt is edge trigger. */
+ GPIO_INT_BOTH_EDGE = 0x2, /**< This interrupt is both edge trigger. */
+} GPIOIT_LevelType;
+
+#define IS_GPIOIT_LEVEL_TYPE(TYPE) (((TYPE) == GPIO_INT_Trigger_LEVEL)\
+ || ((TYPE) == GPIO_INT_Trigger_EDGE)\
+ || ((TYPE) == GPIO_INT_BOTH_EDGE))
+
+/**
+ * \brief Setting interrupt active mode.
+ *
+ * \ingroup GPIO_Exported_Types
+ */
+typedef enum
+{
+ GPIO_INT_POLARITY_ACTIVE_LOW = 0x0, /**< Setting interrupt to low active. */
+ GPIO_INT_POLARITY_ACTIVE_HIGH = 0x1, /**< Setting interrupt to high active. */
+} GPIOIT_PolarityType;
+
+#define IS_GPIOIT_POLARITY_TYPE(TYPE) (((TYPE) == GPIO_INT_POLARITY_ACTIVE_LOW)\
+ || ((TYPE) == GPIO_INT_POLARITY_ACTIVE_HIGH))
+
+/**
+ * \brief Enable/Disable interrupt debounce.
+ *
+ * \ingroup GPIO_Exported_Types
+ */
+typedef enum
+{
+ GPIO_INT_DEBOUNCE_DISABLE = 0x0, /**< Disable interrupt debounce. */
+ GPIO_INT_DEBOUNCE_ENABLE = 0x1, /**< Enable interrupt debounce. */
+} GPIOIT_DebounceType;
+
+#define IS_GPIOIT_DEBOUNCE_TYPE(TYPE) (((TYPE) == GPIO_INT_DEBOUNCE_DISABLE)\
+ || ((TYPE) == GPIO_INT_DEBOUNCE_ENABLE))
+
+/**
+ * \brief Hardware/Software mode select.
+ *
+ * \ingroup GPIO_Exported_Types
+ */
+typedef enum
+{
+ GPIO_SOFTWARE_MODE = 0x0, /**< GPIO software mode(default). */
+ GPIO_HARDWARE_MODE = 0x1, /**< GPIO hardware control mode. */
+} GPIOControlMode_Typedef;
+
+#define IS_GPIOIT_MODDE(TYPE) (((TYPE) == GPIO_SOFTWARE_MODE)\
+ || ((TYPE) == GPIO_HARDWARE_MODE))
+
+/**
+ * \brief GPIO init structure definition.
+ *
+ * \ingroup GPIO_Exported_Types
+ */
+typedef struct
+{
+ uint32_t GPIO_Pin; /**< Specifies the GPIO pins to be configured.
+ This parameter can be any value of \ref GPIO_Pins_Define */
+ GPIOMode_TypeDef
+ GPIO_Mode; /**< Specifies the operating mode for the selected pins. */
+ FunctionalState GPIO_ITCmd; /**< Enable or disable GPIO interrupt.
+ This parameter can be a value of DISABLE or ENABLE. */
+ GPIOIT_LevelType GPIO_ITTrigger; /**< Interrupt mode is level or edge trigger. */
+ GPIOIT_PolarityType GPIO_ITPolarity; /**< Interrupt mode is high or low active trigger. */
+ GPIOIT_DebounceType GPIO_ITDebounce; /**< Enable or disable de-bounce for interrupt. */
+ GPIOControlMode_Typedef GPIO_ControlMode; /**< Specifies the gpio control mode. */
+ uint32_t GPIO_DebounceTime; /**< Specifies the gpio debounce time(ms). */
+} GPIO_InitTypeDef;
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+
+/**
+ * \defgroup GPIO_Exported_Functions Peripheral APIs
+ * \{
+ * \ingroup GPIO
+ */
+
+/**
+ * \brief Deinitializes the GPIO peripheral registers to their default reset values.
+ * \param None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_gpio_init(void)
+ * {
+ * GPIO_DeInit();
+ * }
+ * \endcode
+ */
+void GPIO_DeInit(void);
+
+/**
+ * \brief Initializes the GPIO peripheral according to the specified
+ * parameters in the GPIO_InitStruct.
+ * \param[in] GPIO_InitStruct: Pointer to a GPIO_InitTypeDef structure that
+ * contains the configuration information for the specified GPIO peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_gpio_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+ *
+ * GPIO_InitTypeDef GPIO_InitStruct;
+ * GPIO_StructInit(&GPIO_InitStruct);
+ * GPIO_InitStruct.GPIO_Pin = GPIO_GetPin(P4_0);
+ * GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
+ * GPIO_InitStruct.GPIO_ITCmd = ENABLE;
+ * GPIO_InitStruct.GPIO_ITTrigger = GPIO_INT_Trigger_EDGE;
+ * GPIO_InitStruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW;
+ * GPIO_InitStruct.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_ENABLE;
+ * GPIO_InitStruct.GPIO_DebounceTime = 10;
+ * GPIO_Init(&GPIO_InitStruct);
+ *
+ * NVIC_InitTypeDef NVIC_InitStruct;
+ * NVIC_InitStruct.NVIC_IRQChannel = GPIO28_IRQn;
+ * NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ * NVIC_Init(&NVIC_InitStruct);
+
+ * GPIO_MaskINTConfig(GPIO_PIN_INPUT, DISABLE);
+ * GPIO_INTConfig(GPIO_PIN_INPUT, ENABLE);
+ * }
+ * \endcode
+ */
+void GPIO_Init(GPIO_InitTypeDef *GPIO_InitStruct);
+
+/**
+ * \brief Fills each GPIO_InitStruct member with its default value.
+ * \param[in] GPIO_InitStruct: Pointer to a GPIO_InitTypeDef structure which will
+ * be initialized.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_gpio_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+ *
+ * GPIO_InitTypeDef GPIO_InitStruct;
+ * GPIO_StructInit(&GPIO_InitStruct);
+ * GPIO_InitStruct.GPIO_Pin = GPIO_GetPin(P4_0);
+ * GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
+ * GPIO_InitStruct.GPIO_ITCmd = ENABLE;
+ * GPIO_InitStruct.GPIO_ITTrigger = GPIO_INT_Trigger_EDGE;
+ * GPIO_InitStruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW;
+ * GPIO_InitStruct.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_ENABLE;
+ * GPIO_InitStruct.GPIO_DebounceTime = 10;
+ * GPIO_Init(&GPIO_InitStruct);
+ * }
+ * \endcode
+ */
+void GPIO_StructInit(GPIO_InitTypeDef *GPIO_InitStruct);
+
+/**
+ * \brief Enable the specified GPIO pin interrupt.
+ * \param[in] GPIO_Pin: Where x can be 0 or 31.
+ * \param[in] NewState: Enable or disable interrupt
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_gpio_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+ *
+ * GPIO_InitTypeDef GPIO_InitStruct;
+ * GPIO_StructInit(&GPIO_InitStruct);
+ * GPIO_InitStruct.GPIO_Pin = GPIO_GetPin(P4_0);
+ * GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
+ * GPIO_InitStruct.GPIO_ITCmd = ENABLE;
+ * GPIO_InitStruct.GPIO_ITTrigger = GPIO_INT_Trigger_EDGE;
+ * GPIO_InitStruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW;
+ * GPIO_InitStruct.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_ENABLE;
+ * GPIO_InitStruct.GPIO_DebounceTime = 10;
+ * GPIO_Init(&GPIO_InitStruct);
+ *
+ * NVIC_InitTypeDef NVIC_InitStruct;
+ * NVIC_InitStruct.NVIC_IRQChannel = GPIO28_IRQn;
+ * NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ * NVIC_Init(&NVIC_InitStruct);
+
+ * GPIO_MaskINTConfig(GPIO_PIN_INPUT, DISABLE);
+ * GPIO_INTConfig(GPIO_PIN_INPUT, ENABLE);
+ * }
+ * \endcode
+ */
+void GPIO_INTConfig(uint32_t GPIO_Pin, FunctionalState NewState);
+
+/**
+ * \brief Clear the specified GPIO pin interrupt pending bit.
+ * \param[in] GPIO_Pin: Where x can be 0 or 31.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gpio_demo(void)
+ * {
+ * driver_gpio_init();
+ * }
+ *
+ * void GPIO28_Handler(void)
+ * {
+ * GPIO_INTConfig(GPIO_PIN_INPUT, DISABLE);
+ * GPIO_MaskINTConfig(GPIO_PIN_INPUT, ENABLE);
+ * //Add user code here.
+ * GPIO_ClearINTPendingBit(GPIO_PIN_INPUT);
+ * GPIO_MaskINTConfig(GPIO_PIN_INPUT, DISABLE);
+ * GPIO_INTConfig(GPIO_PIN_INPUT, ENABLE);
+}
+ * \endcode
+ */
+void GPIO_ClearINTPendingBit(uint32_t GPIO_Pin);
+
+/**
+ * \brief Mask the specified GPIO pin interrupt.
+ * \param[in] GPIO_Pin: Where x can be 0 or 31.
+ * \param[in] NewState: Disable or enable interrupt.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ *
+ * void gpio_demo(void)
+ * {
+ * driver_gpio_init();
+ * }
+ *
+ * void GPIO28_Handler(void)
+ * {
+ * GPIO_INTConfig(GPIO_PIN_INPUT, DISABLE);
+ * GPIO_MaskINTConfig(GPIO_PIN_INPUT, ENABLE);
+ *
+ * //Add user code here.
+ *
+ * GPIO_ClearINTPendingBit(GPIO_PIN_INPUT);
+ * GPIO_MaskINTConfig(GPIO_PIN_INPUT, DISABLE);
+ * GPIO_INTConfig(GPIO_PIN_INPUT, ENABLE);
+ * }
+ * \endcode
+ */
+void GPIO_MaskINTConfig(uint32_t GPIO_Pin, FunctionalState NewState);
+
+/**
+ * \brief Get the GPIO_Pin through the given PAD num.
+ * \param[in] Pin_num: Pad num which can be from P0_0 to H_2, please refer to rtl876x.h "Pin_Number" part.
+ * \retval GPIO_Pin for GPIO initialization.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_gpio_init(void)
+ * {
+ * uint32_t gpio_pin = GPIO_GetPin(P4_0);
+ * //result: gpio_pin = GPIO_Pin_28
+ * }
+ * \endcode
+ */
+uint32_t GPIO_GetPin(uint8_t Pin_num);
+
+/**
+ * \brief Get GPIOx(x is 0~31) value through the given pad.
+ * \param[in] Pin_num: Pad num which can be from P0_0 to H_2, please refer to rtl876x.h "Pin_Number" part.
+ * \return GPIOx(x is 0~31) value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gpio_demo(void)
+ * {
+ * uint8_t gpio_num = GPIO_GetNum(P4_0);
+ * //result: gpio_num = 28
+ * }
+ * \endcode
+ */
+uint8_t GPIO_GetNum(uint8_t Pin_num);
+
+/**
+ * \brief Enable GPIO debounce clock.
+ * \param[in] NewState: Disable or enable debounce clock.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gpio_demo(void)
+ * {
+ * GPIO_DBClkCmd(ENABLE);
+ * }
+ * \endcode
+ */
+void GPIO_DBClkCmd(FunctionalState NewState);
+
+/**
+ * \brief Read the specified input port pin.
+ * \param[in] GPIO_Pin: Specifies the port bit to read.
+ * This parameter can be GPIO_Pin_x where x can be 0~31.
+ * \return The input port pin value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gpio_demo(void)
+ * {
+ * uint8_t input_bit = GPIO_ReadInputDataBit(GPIO_GetPin(P4_0));
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint8_t GPIO_ReadInputDataBit(uint32_t GPIO_Pin)
+{
+ uint8_t bitstatus = RESET;
+ uint32_t data_in = GPIO->DATAIN;
+
+ /* Check the parameters */
+ assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
+
+ if (GPIO->DATAIN & GPIO_Pin)
+ {
+ bitstatus = (uint8_t)SET;
+ }
+
+ return bitstatus;
+}
+
+/**
+ * \brief Read value of all GPIO input data port.
+ * \param None.
+ * \return GPIO input data port value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gpio_demo(void)
+ * {
+ * uint32_t input_data = GPIO_ReadInputData();
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t GPIO_ReadInputData(void)
+{
+ return GPIO->DATAIN;
+}
+
+/**
+ * \brief Read the specified output port pin.
+ * \param[in] GPIO_Pin: Specifies the port bit to read.
+ * This parameter can be GPIO_Pin_x where x can be 0~31.
+ * \retval The output port pin value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gpio_demo(void)
+ * {
+ * uint8_t output_bit = GPIO_ReadOutputDataBit(GPIO_GetPin(P4_0));
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint8_t GPIO_ReadOutputDataBit(uint32_t GPIO_Pin)
+{
+ uint8_t bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
+
+ if (GPIO->DATAOUT & GPIO_Pin)
+ {
+ bitstatus = (uint8_t)SET;
+ }
+
+ return bitstatus;
+}
+
+/**
+ * \brief Read value of all GPIO output data port.
+ * \param None.
+ * \return GPIO output data port value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gpio_demo(void)
+ * {
+ * uint32_t output_data = GPIO_ReadOutputData();
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t GPIO_ReadOutputData(void)
+{
+ return ((uint32_t)GPIO->DATAOUT);
+}
+
+/**
+ * \brief Sets the selected data port bit.
+ * \param[in] GPIO_Pin: Specifies the port bit to be written.
+ * This parameter can be GPIO_Pin_x where x can be 0~31 or GPIO_Pin_All.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gpio_demo(void)
+ * {
+ * GPIO_SetBits(GPIO_GetPin(P4_0));
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void GPIO_SetBits(uint32_t GPIO_Pin)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ GPIO->DATAOUT |= GPIO_Pin;
+}
+
+/**
+ * \brief Reset the selected data port bit.
+ * \param[in] GPIO_Pin: Specifies the port bits to be written.
+ * This parameter can be GPIO_Pin_0 to GPIO_Pin_31 or GPIO_Pin_All.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gpio_demo(void)
+ * {
+ * GPIO_ResetBits(GPIO_GetPin(P4_0));
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void GPIO_ResetBits(uint32_t GPIO_Pin)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ GPIO->DATAOUT &= ~(GPIO_Pin);
+}
+
+/**
+ * \brief Set or clear the selected data port bit.
+ * \param[in] GPIO_Pin: Specifies the port bit to be written.
+ * This parameter can be one of GPIO_Pin_x where x can be 0~31.
+ * \param[in] BitVal: specifies the value to be written to the selected bit.
+ * This parameter can be one of the BitAction enum values:
+ * \arg Bit_RESET: To clear the port pin.
+ * \arg Bit_SET: To set the port pin.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gpio_demo(void)
+ * {
+ * GPIO_WriteBit(GPIO_GetPin(P4_0), Bit_SET);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void GPIO_WriteBit(uint32_t GPIO_Pin, BitAction BitVal)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+ assert_param(IS_GPIO_BIT_ACTION(BitVal));
+
+ if (BitVal != Bit_RESET)
+ {
+ GPIO->DATAOUT |= GPIO_Pin;
+ }
+ else
+ {
+ GPIO->DATAOUT &= ~(GPIO_Pin);
+ }
+}
+
+/**
+ * \brief Set or clear data port.
+ * \param[in] PortVal: Specifies the value to be written to the selected bit.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gpio_demo(void)
+ * {
+ * GPIO_Write(0xFFFFFFFF);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void GPIO_Write(uint32_t PortVal)
+{
+ GPIO->DATAOUT = PortVal;
+}
+
+/**
+ * \brief Get GPIO interrupt status.
+ * \param[in] GPIO_Pin: Specifies the port bit to be written.
+ * This parameter can be one of GPIO_Pin_x where x can be 0~31.
+ * \retturn The new state of GPIO_IT (SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gpio_demo(void)
+ * {
+ * ITStatus int_status = GPIO_GetINTStatus(GPIO_GetPin(P4_0));
+ * }
+ * \endcode
+ */
+__STATIC_INLINE ITStatus GPIO_GetINTStatus(uint32_t GPIO_Pin)
+{
+ /* Check the parameters */
+ assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
+
+ if ((GPIO->INTSTATUS & GPIO_Pin) == GPIO_Pin)
+ {
+ return SET;
+ }
+ else
+ {
+ return RESET;
+ }
+}
+
+/**
+ * \brief Set debounce time.
+ * \param[in] DebounceTime: Specifies interrupt debounce time.
+ * This parameter can be 1ms ~ 64ms.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void gpio_demo(void)
+ * {
+ * GPIO_Debounce_Time(10);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void GPIO_Debounce_Time(uint32_t DebounceTime)
+{
+ uint8_t count = 0;
+
+ if (DebounceTime < 1)
+ {
+ DebounceTime = 1;
+ }
+ if (DebounceTime > 64)
+ {
+ DebounceTime = 64;
+ }
+#ifdef _IS_ASIC_
+ //div = 14;//0xd 0b1101<<8
+ GPIO_DBCLK_DIV = ((0xd << 8) | (1 << 12));
+#else
+ //div = 13;//0xc 0b1100<<8
+ GPIO_DBCLK_DIV |= ((1 << 11) | (1 << 10) | (1 << 12));
+ GPIO_DBCLK_DIV &= (~((1 << 9) | (1 << 8)));
+#endif
+ count = (244 * DebounceTime) / 100 - 1;
+ GPIO_DBCLK_DIV &= (~((0xff << 0)));
+ GPIO_DBCLK_DIV = GPIO_DBCLK_DIV + count;
+}
+
+/** \} */ /* End of group GPIO_Exported_Functions */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_GPIO_H_ */
+
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/inc/peripheral/rtl876x_hw_aes.h b/inc/peripheral/rtl876x_hw_aes.h
new file mode 100644
index 0000000..440c2c0
--- /dev/null
+++ b/inc/peripheral/rtl876x_hw_aes.h
@@ -0,0 +1,181 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file rtl876x_hw_aes.h
+* @brief
+* @details
+* @author eason li
+* @date 2016-01-04
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef __RTL876X_HW_AES_H
+#define __RTL876X_HW_AES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* Includes ------------------------------------------------------------------*/
+#include <stdbool.h>
+#include "rtl876x.h"
+#include "hw_aes.h"
+
+/**
+ * @brief referenc to hw aes register table
+ */
+typedef struct
+{
+ union
+ {
+ __IO uint32_t CTL;
+ struct
+ {
+ __IO uint32_t enc_en: 1; /* aes encryption enable */
+ __IO uint32_t dec_en: 1; /* aes decryption enable */
+ __IO uint32_t ase256_en: 1; /* aes 256-bit mode enable */
+ __IO uint32_t aes_mode_sel: 3; /* aes mode select, see HW_AES_MODE below */
+ __IO uint32_t access_mode: 1; /* 0: CPU mode, 1: DMA mode */
+ __IO uint32_t scram_en: 1; /* scramble function, 0:disable, 1:enable */
+ __IO uint32_t use_hidden_key: 1; /* secure related */
+ __IO uint32_t copy_hidden_key: 1; /* secure related */
+ __IO uint32_t hidden_256: 1; /* secure related */
+ __IO uint32_t poly_en: 1; /* XOR polynomial, 0:disable, 1:enable */
+ __IO uint32_t rsvd: 19;
+ __IO uint32_t dout_rdy: 1; /* aes data output ready signal used in CPU mode.
+ when data output is ready, dout_rdy = 1.
+ if dout_rdy == 1, "CPU reads enc_dout or dec_dout
+ for 4 times (128 bits)" will clear dout_rdy to 0.
+ */
+ } CTL_BITS;
+ };
+ __IO uint32_t data_in;
+ __I uint32_t enc_dout;
+ __I uint32_t dec_dout;
+ __IO uint32_t IRK[8];
+ __IO uint32_t iv[4];
+ union
+ {
+ __O uint32_t secure_reg[13];
+ struct
+ {
+ __O uint32_t RPZ0_CMP_ADDR_TOP_H; /* 0x40 */
+ __O uint32_t RPZ0_CMP_ADDR_TOP_L; /* 0x44 */
+ __O uint32_t RPZ0_CMP_ADDR_BUTTOM_H; /* 0x48 */
+ __O uint32_t RPZ0_CMP_ADDR_BUTTOM_L; /* 0x4C */
+ __O uint32_t RPZ1_CMP_ADDR_TOP_H; /* 0x50 */
+ __O uint32_t RPZ1_CMP_ADDR_TOP_L; /* 0x54 */
+ __O uint32_t RPZ1_CMP_ADDR_BUTTOM_H; /* 0x58 */
+ __O uint32_t RPZ1_CMP_ADDR_BUTTOM_L; /* 0x5C */
+ __O uint32_t RPZ_SWD_CTRL; /* 0x60 */
+ __O uint32_t DSP_MEM_CTRL_H; /* 0x64 */
+ __O uint32_t DSP_MEM_CTRL_L; /* 0x68 */
+ __O uint32_t rsvd; /* 0x6C */
+ __O uint32_t reg_buf_cache_sram_en; /* 0x70 */
+ };
+ };
+ union
+ {
+ __IO uint32_t secure_status;
+ struct
+ {
+ __IO uint32_t cnt: 4;
+ __IO uint32_t S: 1;
+ __IO uint32_t irk_cnt: 3;
+ __IO uint32_t rsvd: 8;
+ __IO uint32_t hash_: 16;
+ } SEC_STS;
+ };
+ __O uint32_t authentication;
+} HW_AES_TypeDef;
+
+#define HWAES_CTL 0x0
+#define HWAES_DATAIN 0x4
+#define HWAES_ENC_DOUT 0x8
+#define HWAES_DEC_DOUT 0xC
+#define HWAES_IRK 0x10
+#define HWAES_IV 0x30
+#define HWAES_SEC_REG 0x40
+#define HWAES_SEC_STS 0x74
+#define HWAES_AUTHEN 0x78
+
+
+typedef enum
+{
+ CPU_MODE,
+ DMA_MODE
+} HW_AES_ACCESS_MODE;
+
+#define DMA_CH_BASE(ChNum) (GDMA_CHANNEL_REG_BASE + ChNum * 0x0058)
+#define DMA_CH_IRQ(ChNum) ((GDMA0_Channel0_IRQn + ChNum))
+#define HW_AES_RX_DMA_IO_NUM 14
+#define HW_AES_TX_DMA_IO_NUM 13
+
+#define HW_AES_SET_ENC_EN(isEnable) (HWAES->CTL_BITS.enc_en = isEnable)
+#define HW_AES_SET_DEC_EN(isEnable) (HWAES->CTL_BITS.dec_en = isEnable)
+#define HW_AES_SET_256_EN(isEnable) (HWAES->CTL_BITS.ase256_en = isEnable)
+#define HW_AES_GET_256_EN (HWAES->CTL_BITS.ase256_en)
+#define HW_AES_SET_AES_MODE(mode) (HWAES->CTL_BITS.aes_mode_sel = (mode & 0x7))
+#define HW_AES_SET_WORK_MODE(mode) (HWAES->CTL_BITS.access_mode = (mode & BIT0))
+#define HW_AES_IS_DATA_OUT_READY (HWAES->CTL_BITS.dout_rdy)
+#define HW_AES_SET_INPUT_DATA(data) (HWAES->data_in = (uint32_t)data)
+#define HW_AES_READ_ENC_OUTPUT(Out) (Out = HWAES->enc_dout)
+#define HW_AES_READ_DEC_OUTPUT(Out) (Out = HWAES->dec_dout)
+#define HW_AES_SET_IRK(pIRK, cnt) for (uint8_t i = 0;i < cnt;i ++) {HWAES->IRK[(cnt - 1) - i] = pIRK[i];}
+#define HW_AES_GET_IRK(pIRK, cnt) for (uint8_t i = 0;i < cnt;i ++) {pIRK[i] = HWAES->IRK[(cnt - 1) - i];}
+#define HW_AES_SET_IV(pIV) for (uint8_t i = 0;i < 4;i ++) {HWAES->iv[3 - i] = pIV[i];}
+#define HW_AES_GET_IV(pIV) for (uint8_t i = 0;i < 4;i ++) {pIV[i] = HWAES->iv[3 - i];}
+#define HW_AES_SET_SCRAMBLE_EN(isEnable) (HWAES->CTL_BITS.scram_en = isEnable)
+#define HW_AES_USE_HIDDEN_KEY(isEnable) (HWAES->CTL_BITS.use_hidden_key = isEnable)
+#define HW_AES_COPY_HIDDEN_KEY(isEnable) (HWAES->CTL_BITS.copy_hidden_key = isEnable)
+#define HW_AES_SET_HIDDEN_256(isEnable) (HWAES->CTL_BITS.hidden_256 = isEnable)
+
+#define HWAES_DMA_RX_CH_NUM 2
+#define HWAES_DMA_TX_CH_NUM 1
+#define HWAES_DMA_RX_CH GDMA_Channel2
+#define HWAES_DMA_TX_CH GDMA_Channel1
+#define HWAES_DMA_RX_HANDLER GDMA0_Channel2_Handler
+#define HWAES_DMA_TX_HANDLER GDMA0_Channel1_Handler
+#define MAX_DMA_BUF_SZ 0xFF0
+
+#if 1
+#define AES_INFO(...) DBG_DIRECT(__VA_ARGS__);
+#else
+#define AES_INFO(...)
+#endif
+__STATIC_INLINE void hw_aes_clear(void)
+{
+ HWAES->CTL = 0;
+}
+__STATIC_INLINE void hw_aes_set_clk(bool is_enable)
+{
+ /* turn on hw aes clock */
+ SYSBLKCTRL->u_238.BITS_238.r_PON_ACTCKE_AES = is_enable;
+
+ /* enable hw aes */
+ SYSBLKCTRL->u_218.BITS_218.r_PON_FEN_AES = is_enable;
+}
+
+bool hw_aes_init(const uint32_t *aesKey, uint32_t *iv, T_HW_AES_MODE work_mode, bool isAes256);
+bool hw_aes_cpu_operate(uint32_t *in, uint32_t *out, uint32_t word_len, bool isEncrypt);
+bool hw_aes_dma_operate(uint32_t *in, uint32_t *out, uint32_t word_len, bool isEncrypt,
+ uint8_t dma_rx_ch_num, uint8_t dma_tx_ch_num, bool isMac);
+void hw_aes_set_dma_rx_done(bool isDone);
+bool hw_aes_is_dma_rx_done(void);
+void hw_aes_set_dma_tx_done(bool isDone);
+bool hw_aes_is_dma_tx_done(void);
+bool hw_aes_dma_done(void);
+void hw_aes_dma_interrupt_disable(void);
+void hw_aes_set_dma_move_src(uint32_t src);
+void hw_aes_set_dma_move_dst(uint32_t dst);
+void hw_aes_set_dma_carry_size(uint32_t size);
+bool aes_cmac_inverse(uint8_t *key, uint8_t *input, uint32_t length, uint8_t *mac, int mode);
+uint32_t get_secure_reg_cfg_val(uint32_t in_val);
+
+void share_dsp_and_cache_ram_rom(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__RTL8762X_GDMA_H*/
diff --git a/inc/peripheral/rtl876x_i2c.h b/inc/peripheral/rtl876x_i2c.h
new file mode 100644
index 0000000..6452f63
--- /dev/null
+++ b/inc/peripheral/rtl876x_i2c.h
@@ -0,0 +1,876 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_i2c.h
+* \brief The header file of the peripheral I2C driver.
+* \details This file provides all I2C firmware functions.
+* \author elliot chen
+* \date 2015-4-20
+* \version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef _RTL876X_I2C_H_
+#define _RTL876X_I2C_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup I2C I2C
+ *
+ * \brief Manage the I2C peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup I2C_Exported_Types Init Params Struct
+ *
+ * \ingroup I2C
+ */
+
+/**
+ * \brief I2C init structure definition.
+ *
+ * \ingroup I2C_Exported_Types
+ */
+
+typedef struct
+{
+ uint32_t I2C_Clock; /*!< Specifies the clock frequency,default 40000000.
+ This parameter must be set with I2C clock div. */
+ uint32_t I2C_ClockSpeed; /*!< Specifies the clock frequency.
+ This parameter must be set to a value lower than 400kHz. */
+ uint16_t I2C_DeviveMode; /*!< Specifies the I2C devie mode.
+ This parameter can be a value of \ref I2C_Device_Mode. */
+ uint16_t I2C_AddressMode; /*!< Specifies the I2C address mode.
+ This parameter can be a value of \ref I2C_Address_Mode. */
+ uint16_t I2C_SlaveAddress; /*!< Specifies the first device own address.
+ This parameter can be a 7-bit or 10-bit address. */
+ uint16_t I2C_Ack; /*!< Enables or disables the acknowledgement only in slave mode.
+ This parameter can be a value of \ref I2C_Acknowledgement. */
+ uint32_t I2C_TxThresholdLevel; /* !< Specifies the transmit FIFO Threshold to trigger interrupt I2C_INT_TX_EMPTY.
+ This parameter can be a value less than 24*/
+ uint32_t I2C_RxThresholdLevel; /* !<Specifies the receive FIFO Threshold to trigger interrupt I2C_INT_RX_FULL.
+ This parameter can be a value less than 16*/
+ uint16_t I2C_TxDmaEn; /*!< Specifies the Tx dma mode.
+ This parameter can be a value of ENABLE or DISABLE. */
+ uint16_t I2C_RxDmaEn; /*!< Specifies the Rx dma mode.
+ This parameter can be a value of ENABLE or DISABLE. */
+ uint8_t I2C_TxWaterlevel; /*!< Specifies the DMA tx water level.
+ This parameter should be I2C Tx fifo depth minus GDMA MSize. */
+ uint8_t I2C_RxWaterlevel; /*!< Specifies the DMA rx water level.
+ This parameter should be I2C Rx GDMA MSize - 1. */
+} I2C_InitTypeDef;
+
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup I2C_Exported_Constants Marco Definitions
+ *
+ * \ingroup I2C
+ */
+
+#define IS_I2C_ALL_PERIPH(PERIPH) (((PERIPH) == I2C0) || \
+ ((PERIPH) == I2C1))
+
+/**
+ * \def I2C_clock_speed I2C Clock Speed
+ */
+#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) >= 0x01) && ((SPEED) <= 400000))
+
+/**
+ * \defgroup I2C_Device_Mode I2C Device Mode
+ * \{
+ * \ingroup I2C_Exported_Constants
+ */
+#define I2C_DeviveMode_Master ((uint16_t)0x0041)
+#define I2C_DeviveMode_Slave ((uint16_t)0x0000)
+/** \} */
+
+/**
+ * \defgroup I2C_Address_Mode I2C Address Mode
+ * \{
+ * \ingroup I2C_Exported_Constants
+ */
+#define I2C_AddressMode_7BIT ((uint16_t)0x0000)
+#define I2C_AddressMode_10BIT ((uint16_t)0x0001)
+/** \} */
+
+/**
+ * \defgroup I2C_Acknowledgement I2C Acknowledgement
+ * \{
+ * \ingroup I2C_Exported_Constants
+ */
+#define I2C_Ack_Enable ((uint16_t)0x0001)
+#define I2C_Ack_Disable ((uint16_t)0x0000)
+/** \} */
+
+/**
+ * \defgroup I2C_Flags_Definition I2C Flags Definition
+ * \{
+ * \ingroup I2C_Exported_Constants
+ */
+#define I2C_FLAG_SLV_ACTIVITY ((uint32_t)0x00000040)
+#define I2C_FLAG_MST_ACTIVITY ((uint32_t)0x00000020)
+#define I2C_FLAG_RFF ((uint32_t)0x00000010)
+#define I2C_FLAG_RFNE ((uint32_t)0x00000008)
+#define I2C_FLAG_TFE ((uint32_t)0x00000004)
+#define I2C_FLAG_TFNF ((uint32_t)0x00000002)
+#define I2C_FLAG_ACTIVITY ((uint32_t)0x00000001)
+/** \} */
+
+#define IS_I2C_GET_FLAG(FLAG) (((FLAG) == I2C_FLAG_SLV_ACTIVITY) || ((FLAG) == I2C_FLAG_MST_ACTIVITY) || \
+ ((FLAG) == I2C_FLAG_RFF) || ((FLAG) == I2C_FLAG_RFNE) || \
+ ((FLAG) == I2C_FLAG_TFE) || ((FLAG) == I2C_FLAG_TFNF) || \
+ ((FLAG) == I2C_FLAG_ACTIVITY))
+/**
+ * \defgroup I2C_Transmit_Abort_Source I2C Transmit Abort Source
+ * \{
+ * \ingroup I2C_Exported_Constants
+ */
+#define ABRT_SLVRD_INTX ((uint32_t)BIT(15))
+#define ABRT_SLV_ARBLOST ((uint32_t)BIT(14))
+#define ABRT_SLVFLUSH_TXFIFO ((uint32_t)BIT(13))
+#define ARB_LOST ((uint32_t)BIT(12))
+#define ABRT_MASTER_DIS ((uint32_t)BIT(11))
+#define ABRT_10B_RD_NORSTRT ((uint32_t)BIT(10))
+#define ABRT_SBYTE_NORSTRT ((uint32_t)BIT(9))
+#define ABRT_HS_NORSTRT ((uint32_t)BIT(8))
+#define ABRT_SBYTE_ACKDET ((uint32_t)BIT(7))
+#define ABRT_HS_ACKDET ((uint32_t)BIT(6))
+#define ABRT_GCALL_READ ((uint32_t)BIT(5))
+#define ABRT_GCALL_NOACK ((uint32_t)BIT(4))
+#define ABRT_TXDATA_NOACK ((uint32_t)BIT(3))
+#define ABRT_10ADDR2_NOACK ((uint32_t)BIT(2))
+#define ABRT_10ADDR1_NOACK ((uint32_t)BIT(1))
+#define ABRT_7B_ADDR_NOACK ((uint32_t)BIT(0))
+/** \} */
+
+#define MS_ALL_ABORT (ARB_LOST | ABRT_MASTER_DIS | ABRT_TXDATA_NOACK |\
+ ABRT_10ADDR2_NOACK | ABRT_10ADDR1_NOACK | ABRT_7B_ADDR_NOACK)
+
+#define IS_I2C_EVENT(EVENT) (((EVENT) == ABRT_SLVRD_INTX) || \
+ ((EVENT) == ABRT_SLV_ARBLOST) || \
+ ((EVENT) == ABRT_SLVFLUSH_TXFIFO) || \
+ ((EVENT) == ARB_LOST) || \
+ ((EVENT) == ABRT_MASTER_DIS) || \
+ ((EVENT) == ABRT_10B_RD_NORSTRT) || \
+ ((EVENT) == ABRT_SBYTE_NORSTRT) || \
+ ((EVENT) == ABRT_HS_NORSTRT) || \
+ ((EVENT) == ABRT_SBYTE_ACKDET) || \
+ ((EVENT) == ABRT_HS_ACKDET) || \
+ ((EVENT) == ABRT_GCALL_READ) || \
+ ((EVENT) == ABRT_GCALL_NOACK) || \
+ ((EVENT) == ABRT_TXDATA_NOACK) || \
+ ((EVENT) == ABRT_10ADDR2_NOACK) || \
+ ((EVENT) == ABRT_10ADDR1_NOACK) || \
+ ((EVENT) == ABRT_7B_ADDR_NOACK))
+
+/**
+ * \defgroup I2C_Interrupts_Definition I2C Interrupts Definition
+ * \{
+ * \ingroup I2C_Exported_Constants
+ */
+#define I2C_INT_GEN_CALL ((uint32_t)BIT(11))
+#define I2C_INT_START_DET ((uint32_t)BIT(10))
+#define I2C_INT_STOP_DET ((uint32_t)BIT(9))
+#define I2C_INT_ACTIVITY ((uint32_t)BIT(8))
+#define I2C_INT_RX_DONE ((uint32_t)BIT(7))
+#define I2C_INT_TX_ABRT ((uint32_t)BIT(6))
+#define I2C_INT_RD_REQ ((uint32_t)BIT(5))
+#define I2C_INT_TX_EMPTY ((uint32_t)BIT(4))
+#define I2C_INT_TX_OVER ((uint32_t)BIT(3))
+#define I2C_INT_RX_FULL ((uint32_t)BIT(2))
+#define I2C_INT_RX_OVER ((uint32_t)BIT(1))
+#define I2C_INT_RX_UNDER ((uint32_t)BIT(0))
+/** \} */
+
+#define I2C_GET_INT(INT) (((INT) == I2C_INT_GEN_CALL) || ((INT) == I2C_INT_START_DET) || \
+ ((INT) == I2C_INT_STOP_DET) || ((INT) == I2C_INT_ACTIVITY) || \
+ ((INT) == I2C_INT_RX_DONE) || ((INT) == I2C_INT_TX_ABRT) || \
+ ((INT) == I2C_INT_RD_REQ) || ((INT) == I2C_INT_TX_EMPTY) || \
+ ((INT) == I2C_INT_TX_OVER) || ((INT) == I2C_INT_RX_FULL) || \
+ ((INT) == I2C_INT_RX_OVER) || ((INT) == I2C_INT_RX_UNDER))
+
+/**
+ * \defgroup I2C_GDMA_Transfer_Requests I2C GDMA transfer requests
+ * \{
+ * \ingroup I2C_Exported_Constants
+ */
+#define I2C_GDMAReq_Tx ((uint16_t)0x0002)
+#define I2C_GDMAReq_Rx ((uint16_t)0x0001)
+/** \} */
+#define IS_I2C_GDMAREQ(GDMAREQ) ((((GDMAREQ) & (uint16_t)0xFFFC) == 0x00) && ((GDMAREQ) != 0x00))
+
+/**
+ * \defgroup I2C_Send_Command I2C Send Command
+ * \{
+ * \ingroup I2C_Exported_Constants
+ */
+#define I2C_WRITE_CMD 0
+#define I2C_READ_CMD BIT(8)
+/** \} */
+#define IS_I2C_CMD(CMD) (((CMD) == I2C_WRITE_CMD) || ((CMD) == I2C_READ_CMD))
+
+/**
+ * \defgroup I2C_Send_Stop I2C Send Stop
+ * \{
+ * \ingroup I2C_Exported_Constants
+ */
+
+#define I2C_STOP_ENABLE BIT(9)
+#define I2C_STOP_DISABLE 0
+/** \} */
+
+#define IS_I2C_STOP(CMD) (((CMD) == I2C_STOP_ENABLE) || ((CMD) == I2C_STOP_DISABLE))
+
+/**
+ * \brief I2C status.
+ *
+ * \ingroup I2C_Exported_Constants
+ */
+typedef enum
+{
+ I2C_Success,
+ I2C_ARB_LOST,
+ I2C_ABRT_MASTER_DIS,
+ I2C_ABRT_TXDATA_NOACK,
+ I2C_ABRT_10ADDR2_NOACK,
+ I2C_ABRT_10ADDR1_NOACK,
+ I2C_ABRT_7B_ADDR_NOACK,
+ I2C_ERR_TIMEOUT
+} I2C_Status;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup I2C_Exported_functions Peripheral APIs
+ * \{
+ * \ingroup I2C
+ */
+
+/**
+ * \brief Deinitializes the I2Cx peripheral registers to their default reset values.
+ * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_i2c0_init(void)
+ * {
+ * I2C_DeInit(I2C0);
+ * }
+ * \endcode
+ */
+void I2C_DeInit(I2C_TypeDef *I2Cx);
+
+/**
+ * \brief Initializes the I2Cx peripheral according to the specified
+ * parameters in the I2C_InitStruct.
+ * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral.
+ * \param[in] I2C_InitStruct: Pointer to a I2C_InitTypeDef structure that
+ * contains the configuration information for the specified I2C peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_i2c0_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, ENABLE);
+ *
+ * I2C_InitTypeDef I2C_InitStruct;
+ * I2C_StructInit(&I2C_InitStruct);
+ *
+ * I2C_InitStruct.I2C_ClockSpeed = 100000;
+ * I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Master;
+ * I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT;
+ * I2C_InitStruct.I2C_SlaveAddress = STK8321_ADDRESS;
+ * I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
+ *
+ * I2C_Init(I2C0, &I2C_InitStruct);
+ * I2C_Cmd(I2C0, ENABLE);
+ * }
+ * \endcode
+ */
+void I2C_Init(I2C_TypeDef *I2Cx, I2C_InitTypeDef *I2C_InitStruct);
+
+/**
+ * \brief Enable or disable the specified I2C peripheral.
+ * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral.
+ * \param[in] NewState: New state of the I2Cx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_i2c0_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, ENABLE);
+ *
+ * I2C_InitTypeDef I2C_InitStruct;
+ * I2C_StructInit(&I2C_InitStruct);
+ *
+ * I2C_InitStruct.I2C_ClockSpeed = 100000;
+ * I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Master;
+ * I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT;
+ * I2C_InitStruct.I2C_SlaveAddress = STK8321_ADDRESS;
+ * I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
+ *
+ * I2C_Init(I2C0, &I2C_InitStruct);
+ * I2C_Cmd(I2C0, ENABLE);
+ * }
+ * \endcode
+ */
+void I2C_Cmd(I2C_TypeDef *I2Cx, FunctionalState NewState);
+
+/**
+ * \brief Fills each I2C_InitStruct member with its default value.
+ * \param[in] I2C_InitStruct: Pointer to a I2C_InitTypeDef structure which will be initialized.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_i2c0_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, ENABLE);
+ *
+ * I2C_InitTypeDef I2C_InitStruct;
+ * I2C_StructInit(&I2C_InitStruct);
+ *
+ * I2C_InitStruct.I2C_ClockSpeed = 100000;
+ * I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Master;
+ * I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT;
+ * I2C_InitStruct.I2C_SlaveAddress = STK8321_ADDRESS;
+ * I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
+ *
+ * I2C_Init(I2C0, &I2C_InitStruct);
+ * I2C_Cmd(I2C0, ENABLE);
+ * }
+ * \endcode
+ */
+void I2C_StructInit(I2C_InitTypeDef *I2C_InitStruct);
+
+/**
+ * \brief Send data in master mode through the I2Cx peripheral.
+ * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral.
+ * \param[in] pBuf: Byte to be transmitted.
+ * \param[in] len: Data length to send.
+ * \return I2C status \ref I2C_Status.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2c0_demo(void)
+ * {
+ * uint8_t data[10] = {0x01,x0x02,0x03,0x04};
+ * I2C_MasterWrite(I2C0, data, 4);
+ * }
+ * \endcode
+ */
+I2C_Status I2C_MasterWrite(I2C_TypeDef *I2Cx, uint8_t *pBuf, uint16_t len);
+
+/**
+ * \brief Read data in master mode through the I2Cx peripheral.
+ * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral.
+ * \param[in] pBuf: Data buffer to receive data.
+ * \param[in] len: Read data length.
+ * \return I2C status \ref I2C_Status.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2c0_demo(void)
+ * {
+ * uint8_t data[10] = {0};
+ * I2C_MasterRead(I2C0, data, 10);
+ * }
+ * \endcode
+ */
+I2C_Status I2C_MasterRead(I2C_TypeDef *I2Cx, uint8_t *pBuf, uint16_t len);
+
+/**
+ * \brief Sends data and read data in master mode through the I2Cx peripheral.
+ * Attention:Read data with time out mechanism.
+ * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral.
+ * \param[in] pWriteBuf: Data buffer to send before read.
+ * \param[in] Writelen: Send data length.
+ * \param[in] pReadBuf: Data buffer to receive.
+ * \param[in] Readlen: Receive data length.
+ * \return I2C status \ref I2C_Status.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2c0_demo(void)
+ * {
+ * uint8_t tx_data[10] = {0x01,x0x02,0x03,0x04};
+ * uint8_t rx_data[10] = {0};
+ * I2C_RepeatRead(I2C0, tx_data, 4, rx_data, 10);
+ * }
+ * \endcode
+ */
+I2C_Status I2C_RepeatRead(I2C_TypeDef *I2Cx, uint8_t *pWriteBuf, uint16_t Writelen,
+ uint8_t *pReadBuf, uint16_t Readlen);
+
+/**
+ * \brief mask the specified I2C interrupt.
+ * \param[in] I2Cx: Where x can be 0 or 1.
+ * \param[in] I2C_IT
+ * This parameter can be one of the following values:
+ * \arg I2C_INT_GEN_CALL: Set only when a General Call address is received and it is acknowledged.
+ * \arg I2C_INT_START_DET: Indicates whether a START or RESTART condition has occurred on the I2C
+ interface regardless of whether I2C is operating in slave or master mode.
+ * \arg I2C_INT_STOP_DET: Indicates whether a STOP condition has occurred on the I2C interface regardless
+ of whether I2C is operating in slave or master mode
+ * \arg I2C_INT_ACTIVITY: This bit captures I2C activity and stays set until it is cleared.
+ * \arg I2C_INT_RX_DONE: When the I2C is acting as a slave-transmitter, this bit is set to 1 if the
+ master does not acknowledge a transmitted byte. This occurs on the last byte of
+ the transmission, indicating that the transmission is done.
+ * \arg I2C_INT_TX_ABRT: This bit indicates if I2C as an I2C transmitter, is unable to complete the
+ intended actions on the contents of the transmit FIFO.
+ * \arg I2C_INT_RD_REQ: This bit is set to 1 when acting as a slave and another I2C master
+ is attempting to read data.
+ * \arg I2C_INT_TX_EMPTY: This bit is set to 1 when the transmit buffer is at or below the threshold value set
+ in the IC_TX_TL register.
+ * \arg I2C_INT_TX_OVER: Set during transmit if the transmit buffer is filled to IC_TX_BUFFER_DEPTH and
+ the processor attempts to issue another I2C command.
+ * \arg I2C_INT_RX_FULL: Set when the receive buffer reaches or goes above the RX_TL threshold in the
+ IC_RX_TL register
+ * \arg I2C_INT_RX_OVER: Set if the receive buffer is completely filled to IC_RX_BUFFER_DEPTH and an
+ additional byte is received from an external I2C device.
+ * \arg I2C_INT_RX_UNDER: Set if the processor attempts to read the receive buffer when it is empty by reading.
+ * \param[in] NewState: Disable or enable I2C interrupt.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2c0_demo(void)
+ * {
+ * I2C_ClearINTPendingBit(I2C0, I2C_INT_STOP_DET);
+ * I2C_INTConfig(I2C0, I2C_INT_STOP_DET, ENABLE);
+ *
+ * NVIC_InitTypeDef NVIC_InitStruct;
+ * NVIC_InitStruct.NVIC_IRQChannel = I2C0_IRQn;
+ * NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ * NVIC_Init(&NVIC_InitStruct);
+ * }
+ * \endcode
+ */
+void I2C_INTConfig(I2C_TypeDef *I2Cx, uint16_t I2C_IT, FunctionalState NewState);
+
+/**
+ * \brief Clear the specified I2C interrupt pending bit.
+ * \param[in] I2Cx: Where x can be 0 or 1.
+ * \param[in] I2C_IT
+ * This parameter can be one of the following values:
+ * \arg I2C_INT_GEN_CALL: Set only when a General Call address is received and it is acknowledged.
+ * \arg I2C_INT_START_DET: Indicates whether a START or RESTART condition has occurred on the I2C
+ interface regardless of whether I2C is operating in slave or master mode.
+ * \arg I2C_INT_STOP_DET: Indicates whether a STOP condition has occurred on the I2C interface regardless
+ of whether I2C is operating in slave or master mode
+ * \arg I2C_INT_ACTIVITY: This bit captures I2C activity and stays set until it is cleared.
+ * \arg I2C_INT_RX_DONE: When the I2C is acting as a slave-transmitter, this bit is set to 1 if the
+ master does not acknowledge a transmitted byte. This occurs on the last byte of
+ the transmission, indicating that the transmission is done.
+ * \arg I2C_INT_TX_ABRT: This bit indicates if I2C as an I2C transmitter, is unable to complete the
+ intended actions on the contents of the transmit FIFO.
+ * \arg I2C_INT_RD_REQ: This bit is set to 1 when acting as a slave and another I2C master
+ is attempting to read data.
+ * \arg I2C_INT_TX_EMPTY: This bit is set to 1 when the transmit buffer is at or below the threshold value set
+ in the IC_TX_TL register.
+ * \arg I2C_INT_TX_OVER: Set during transmit if the transmit buffer is filled to IC_TX_BUFFER_DEPTH and
+ the processor attempts to issue another I2C command.
+ * \arg I2C_INT_RX_FULL: Set when the receive buffer reaches or goes above the RX_TL threshold in the
+ IC_RX_TL register
+ * \arg I2C_INT_RX_OVER: Set if the receive buffer is completely filled to IC_RX_BUFFER_DEPTH and an
+ additional byte is received from an external I2C device.
+ * \arg I2C_INT_RX_UNDER: Set if the processor attempts to read the receive buffer when it is empty by reading.
+
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void I2C0_Handler(void)
+ * {
+ * if (I2C_GetINTStatus(I2C0, I2C_INT_STOP_DET) == SET)
+ * {
+ * //Add user code here.
+ * I2C_ClearINTPendingBit(I2C0, I2C_INT_STOP_DET);
+ * }
+ * }
+ * \endcode
+ */
+void I2C_ClearINTPendingBit(I2C_TypeDef *I2Cx, uint16_t I2C_IT);
+
+/**
+ * \brief Set slave device address.
+ * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral.
+ * \param[in] Address: Specifies the slave address which will be transmitte.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2c0_demo(void)
+ * {
+ * I2C_SetSlaveAddress(I2C0, 0x55);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void I2C_SetSlaveAddress(I2C_TypeDef *I2Cx, uint16_t Address)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Mask target address */
+ I2Cx->IC_TAR &= ~((uint16_t)0x3ff);
+ /* Configure new target address */
+ I2Cx->IC_TAR |= Address & 0x3ff;
+}
+
+/**
+ * \brief Write command through the I2Cx peripheral.
+ * \param[in] I2Cx: where x can be 0 or 1 to select the I2C peripheral.
+ * \param[in] command: command of write or read.
+ * \arg I2C_READ_CMD: Read command. Data which want to transmit can be 0 in this situation.
+ * \arg I2C_WRITE_CMD: Write command.
+ * \param[in] data: Data which to be transmitted.
+ * \param[in] StopState: Command of write or read.
+ * \arg I2C_STOP_ENABLE: Send stop signal.
+ * \arg I2C_STOP_DISABLE: Do not send stop signal.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2c0_demo(void)
+ * {
+ * I2C_SendCmd(I2C0, 0x01, 0xAA, I2C_STOP_ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void I2C_SendCmd(I2C_TypeDef *I2Cx, uint16_t command, uint8_t data,
+ uint16_t StopState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_CMD(command));
+ assert_param(IS_I2C_STOP(StopState));
+
+ I2Cx->IC_DATA_CMD = data | command | StopState;
+}
+
+/**
+ * \brief Received data by the I2Cx peripheral.
+ * \param[in] I2Cx: Where x can be 1 or 2 to select the I2C peripheral.
+ * \retval Return the most recent received data.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2c0_demo(void)
+ * {
+ * uint8_t data = I2C_ReceiveData(I2C0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint8_t I2C_ReceiveData(I2C_TypeDef *I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Return the data in the DR register */
+ return (uint8_t)I2Cx->IC_DATA_CMD;
+}
+
+/**
+ * \brief Get data length in Rx FIFO of the I2Cx peripheral.
+ * \param[in] I2Cx: Where x can be 0 or 1.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2c0_demo(void)
+ * {
+ * uint8_t data_len = I2C_GetRxFIFOLen(I2C0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint8_t I2C_GetRxFIFOLen(I2C_TypeDef *I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ return (uint8_t)I2Cx->IC_RXFLR;
+}
+
+/**
+ * \brief Get data length in Tx FIFO of the I2Cx peripheral.
+ * \param[in] I2Cx: Where x can be 0 or 1.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2c0_demo(void)
+ * {
+ * uint8_t data_len = I2C_GetTxFIFOLen(I2C0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint8_t I2C_GetTxFIFOLen(I2C_TypeDef *I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ return (uint8_t)I2Cx->IC_TXFLR;
+}
+
+/**
+ * \brief Clear all I2C interrupt.
+ * \param[in] I2Cx: Where x can be 0 or 1.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2c0_demo(void)
+ * {
+ * I2C_ClearAllINT(I2C0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void I2C_ClearAllINT(I2C_TypeDef *I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ I2Cx->IC_CLR_INTR;
+}
+
+/**
+ * \brief Check whether the specified I2C flag is set.
+ * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral.
+ * \param[in] I2C_FLAG: Specifies the flag to check.
+ * This parameter can be one of the following values:
+ * \arg I2C_FLAG_SLV_ACTIVITY: Slave FSM activity status.
+ * \arg I2C_FLAG_MST_ACTIVITY: Master FSM activity status.
+ * \arg I2C_FLAG_RFF: Receive FIFO completely full.
+ * \arg I2C_FLAG_RFNE: Receive FIFO not empty.
+ * \arg I2C_FLAG_TFE: Transmit FIFO completely empty.
+ * \arg I2C_FLAG_TFNF: Transmit FIFO not full.
+ * \arg I2C_FLAG_ACTIVITY: I2C activity status.
+ * \retval The new state of I2C_FLAG (SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2c0_demo(void)
+ * {
+ * FlagStatus flag_status = I2C_GetFlagState(I2C0, I2C_FLAG_RFF);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE FlagStatus I2C_GetFlagState(I2C_TypeDef *I2Cx, uint32_t I2C_FLAG)
+{
+ FlagStatus bit_status = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_GET_FLAG(I2C_FLAG));
+
+ if ((I2Cx->IC_STATUS & I2C_FLAG) != (uint32_t)RESET)
+ {
+ /* I2C_FLAG is set */
+ bit_status = SET;
+ }
+
+ /* Return the I2C_FLAG status */
+ return bit_status;
+}
+
+/**
+ * \brief Check whether the last I2Cx event is equal to the one passed as parameter.
+ * \param[in] I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * \param[in] I2C_EVENT: specifies the event to be checked about I2C Transmit Abort Status Register.
+ * This parameter can be one of the following values:
+ * \arg ABRT_SLVRD_INTX: When the processor side responds to a slave mode request for data to be transmitted to a remote master and user send read command.
+ * \arg ABRT_SLV_ARBLOST: Slave lost the bus while transmitting data to a remote master.
+ * \arg ABRT_SLVFLUSH_TXFIFO: Slave has received a read command and some data exists in the TX FIFO so the slave issues a TX_ABRT interrupt to flush old data in TX FIFO.
+ * \arg ARB_LOST: Master has lost arbitration or the slave transmitter has lost arbitration.
+ * \arg ABRT_MASTER_DIS: User tries to initiate a Master operation with the Master mode disabled
+ * \arg ABRT_10B_RD_NORSTRT: The restart is disabled and the master sends a read command in 10-bit addressing mode.
+ * \arg ABRT_SBYTE_NORSTRT: The restart is disabled and the user is trying to send a START Byte.
+ * \arg ABRT_HS_NORSTRT: The restart is disabled and the user is trying to use the master to transfer data in High Speed mode.
+ * \arg ABRT_SBYTE_ACKDET: Master has sent a START Byte and the START Byte was acknowledged (wrong behavior).
+ * \arg ABRT_HS_ACKDET: Master is in High Speed mode and the High Speed Master code was acknowledged (wrong behavior).
+ * \arg ABRT_GCALL_READ: Sent a General Call but the user programmed the byte following the General Call to be a read from the bus.
+ * \arg ABRT_GCALL_NOACK: Sent a General Call and no slave on the bus acknowledged the General Call.
+ * \arg ABRT_TXDATA_NOACK: Master sent data byte(s) following the address, it did not receive an acknowledge from the remote slave.
+ * \arg ABRT_10ADDR2_NOACK: Master is in 10-bit address mode and the second address byte of the 10-bit address was not acknowledged by any slave.
+ * \arg ABRT_10ADDR1_NOACK: Master is in 10-bit address mode and the first 10-bit address byte was not acknowledged by any slave.
+ * \arg ABRT_7B_ADDR_NOACK: Master is in 7-bit addressing mode and th address sent was not acknowledged by any slave.
+ * \return An ErrorStatus enumeration value.
+ * \retval SUCCESS: Last event is equal to the I2C_EVENT.
+ * \retval ERROR: Last event is different from the I2C_EVENT.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2c0_demo(void)
+ * {
+ * FlagStatus flag_status = I2C_CheckEvent(I2C0, ABRT_SLVRD_INTX);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE FlagStatus I2C_CheckEvent(I2C_TypeDef *I2Cx, uint32_t I2C_EVENT)
+{
+ FlagStatus bit_status = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_EVENT(I2C_EVENT));
+
+ if ((I2Cx->IC_TX_ABRT_SOURCE & I2C_EVENT) != (uint32_t)RESET)
+ {
+
+ bit_status = SET;
+ }
+
+ /* Return the I2C event status */
+ return bit_status;
+}
+
+/**
+ * \brief Get the specified I2C interrupt status.
+ * \param[in] I2Cx: where x can be 0 or 1.
+ * \param[in] I2C_IT
+ * This parameter can be one of the following values:
+ * \arg I2C_INT_GEN_CALL: Set only when a General Call address is received and it is acknowledged.
+ * \arg I2C_INT_START_DET: Indicates whether a START or RESTART condition has occurred on the I2C
+ interface regardless of whether DW_apb_i2c is operating in slave or master mode.
+ * \arg I2C_INT_STOP_DET: Indicates whether a STOP condition has occurred on the I2C interface regardless
+ of whether DW_apb_i2c is operating in slave or master mode
+ * \arg I2C_INT_ACTIVITY: This bit captures DW_apb_i2c activity and stays set until it is cleared.
+ * \arg I2C_INT_RX_DONE: When the DW_apb_i2c is acting as a slave-transmitter, this bit is set to 1 if the
+ master does not acknowledge a transmitted byte. This occurs on the last byte of
+ the transmission, indicating that the transmission is done.
+ * \arg I2C_INT_TX_ABRT: This bit indicates if DW_apb_i2c, as an I2C transmitter, is unable to complete the
+ intended actions on the contents of the transmit FIFO.
+ * \arg I2C_INT_RD_REQ: This bit is set to 1 when acting as a slave and another I2C master
+ is attempting to read data.
+ * \arg I2C_INT_TX_EMPTY: This bit is set to 1 when the transmit buffer is at or below the threshold value set
+ in the IC_TX_TL register.
+ * \arg I2C_INT_TX_OVER: Set during transmit if the transmit buffer is filled to IC_TX_BUFFER_DEPTH and
+ the processor attempts to issue another I2C command.
+ * \arg I2C_INT_RX_FULL: Set when the receive buffer reaches or goes above the RX_TL threshold in the
+ IC_RX_TL register
+ * \arg I2C_INT_RX_OVER: Set if the receive buffer is completely filled to IC_RX_BUFFER_DEPTH and an
+ additional byte is received from an external I2C device.
+ * \arg I2C_INT_RX_UNDER: Set if the processor attempts to read the receive buffer when it is empty by reading.
+ * \return The new state of I2C_IT (SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2c0_demo(void)
+ * {
+ * ITStatus int_status = I2C_GetINTStatus(I2C0, I2C_INT_RD_REQ);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE ITStatus I2C_GetINTStatus(I2C_TypeDef *I2Cx, uint32_t I2C_IT)
+{
+ ITStatus bit_status = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(I2C_GET_INT(I2C_IT));
+
+ if ((I2Cx->IC_INTR_STAT & I2C_IT) != (uint32_t)RESET)
+ {
+ bit_status = SET;
+ }
+
+ /* Return the I2C_IT status */
+ return bit_status;
+}
+
+/**
+ * \brief Enable or disable the I2Cx GDMA interface.
+ * \param[in] I2Cx: Where x can be 0 or 1
+ * \param[in] I2C_GDMAReq: Specifies the I2C GDMA transfer request to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * \arg I2C_GDMAReq_Tx: Tx buffer GDMA transfer request.
+ * \arg I2C_GDMAReq_Rx: Rx buffer GDMA transfer request.
+ * \param[in] NewState: New state of the selected I2C GDMA transfer request.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2c0_demo(void)
+ * {
+ * I2C_GDMACmd(I2C0, I2C_GDMAReq_Tx, ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void I2C_GDMACmd(I2C_TypeDef *I2Cx, uint16_t I2C_GDMAReq, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_I2C_GDMAREQ(I2C_GDMAReq));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C GDMA request */
+ I2Cx->IC_DMA_CR |= I2C_GDMAReq;
+ }
+ else
+ {
+ /* Disable the selected I2C GDMA request */
+ I2Cx->IC_DMA_CR &= (uint16_t)~(I2C_GDMAReq);
+ }
+}
+
+/** \} */ /* End of group I2C_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_RTL8762X_I2C_H_*/
+
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/inc/peripheral/rtl876x_i2s.h b/inc/peripheral/rtl876x_i2s.h
new file mode 100644
index 0000000..f338971
--- /dev/null
+++ b/inc/peripheral/rtl876x_i2s.h
@@ -0,0 +1,1112 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_i2s.h
+* \brief The header file of the peripheral I2S driver.
+* \details This file provides all I2S firmware functions.
+* \author elliot chen
+* \date 2017-12-06
+* \version v1.0
+* *********************************************************************************************************
+*/
+
+
+#ifndef _RTL876x_I2S_H
+#define _RTL876x_I2S_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup I2S I2S
+ *
+ * \brief Manage the I2S peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup I2S_Exported_Types Inti Params Struct
+ *
+ * \ingroup I2S
+ */
+
+/**
+ * \brief I2S init structure definition.
+ *
+ * \ingroup I2S_Exported_Types
+ */
+typedef struct
+{
+ uint32_t I2S_ClockSource; /*!< Specifies the I2S clock source.
+ This parameter can be a value of \ref I2S_Clock_Source*/
+ uint32_t I2S_BClockMi; /*!< Specifies the BLCK clock speed. BCLK = 40MHz*(I2S_BClockNi/I2S_BClockMi).
+ This parameter must range from 1 to 0xffff */
+ uint32_t I2S_BClockNi; /*!< Specifies the BLCK clock speed.
+ This parameter must range from 1 to 0x7FFF */
+ uint32_t I2S_DeviceMode; /*!< Specifies the I2S device mode.
+ This parameter can be a value of \ref I2S_device_mode*/
+ uint32_t I2S_ChannelType; /*!< Specifies the channel type used for the I2S communication.
+ This parameter can be a value of \ref I2S_Channel_Type */
+ uint32_t I2S_TxChSequence; /*!< Specifies the transmission channel seqence used for the I2S communication.
+ This parameter can be a value of \ref I2S_Tx_Ch_Sequence*/
+ uint32_t I2S_RxChSequence; /*!< Specifies the receiving channel seqence used for the I2S communication.
+ This parameter can be a value of \ref I2S_Rx_Ch_Sequence*/
+ uint32_t I2S_DataFormat; /*!< Specifies the I2S Data format mode.
+ This parameter can be a value of \ref I2S_Format_Mode*/
+ uint32_t I2S_TxBitSequence; /*!< Specifies the I2S Data bits sequences.
+ This parameter can be a value of \ref I2S_Tx_Bit_Sequence*/
+ uint32_t I2S_RxBitSequence; /*!< Specifies the I2S Data bits sequences.
+ This parameter can be a value of \ref I2S_Rx_Bit_Sequence*/
+ uint32_t I2S_DataWidth; /*!< Specifies the I2S Data width.
+ This parameter can be a value of \ref I2S_Data_Width */
+ uint32_t I2S_MCLKOutput; /*!< Specifies the I2S MCLK output freqency.
+ This parameter can be a value of \ref I2S_MCLK_Output */
+ uint32_t I2S_DMACmd; /*!< Specifies the I2S DMA control.
+ This parameter can be a value of \ref FunctionalState */
+ uint32_t I2S_TxWaterlevel; /*!< Specifies the dma watermark level in transmit mode.
+ This parameter must range from 1 to 63 */
+ uint32_t I2S_RxWaterlevel; /*!< Specifies the dma watermark level in receive mode.
+ This parameter must range from 1 to 63 */
+} I2S_InitTypeDef;
+
+
+/*============================================================================*
+ * Register Defines
+ *============================================================================*/
+
+/* Peripheral: I2S */
+/* Description: I2S register defines */
+
+/* Register: CTRL0 -------------------------------------------------------*/
+/* Description: Control register 0. Offset: 0x04. */
+
+/* CTRL0[30]: I2S_MCLK_SEL. */
+#define I2S_MCLK_SEL_POS (30)
+#define I2S_MCLK_SEL_MSK (0x1 << I2S_MCLK_SEL_POS)
+#define I2S_MCLK_SEL_CLR (~I2S_MCLK_SEL_MSK)
+/* CTRL0[29:28]: I2S_RX_CH_SEQ. */
+#define I2S_RX_CH_SEQ_POS (28)
+#define I2S_RX_CH_SEQ_MSK (0x1 << I2S_RX_CH_SEQ_POS)
+#define I2S_RX_CH_SEQ_CLR (~I2S_RX_CH_SEQ_MSK)
+/* CTRL0[25]: I2S_START_RX. */
+#define I2S_START_RX_POS (25)
+#define I2S_START_RX_MSK (0x1 << I2S_START_RX_POS)
+#define I2S_START_RX_CLR (~I2S_START_RX_MSK)
+/* CTRL0[24]: I2S_RX_DISABLE. */
+#define I2S_RX_DISABLE_POS (24)
+#define I2S_RX_DISABLE_MSK (0x1 << I2S_RX_DISABLE_POS)
+#define I2S_RX_DISABLE_CLR (~I2S_RX_DISABLE_MSK)
+/* CTRL0[23]: I2S_RX_LSB_FIRST. */
+#define I2S_RX_LSB_FIRST_POS (23)
+#define I2S_RX_LSB_FIRST_MSK (0x1 << I2S_RX_LSB_FIRST_POS)
+#define I2S_RX_LSB_FIRST_CLR (~I2S_RX_LSB_FIRST_MSK)
+/* CTRL0[22]: I2S_TX_LSB_FIRST. */
+#define I2S_TX_LSB_FIRST_POS (22)
+#define I2S_TX_LSB_FIRST_MSK (0x1 << I2S_TX_LSB_FIRST_POS)
+#define I2S_TX_LSB_FIRST_CLR (~I2S_TX_LSB_FIRST_MSK)
+/* CTRL0[21:20]: I2S_TX_CH_SEQ. */
+#define I2S_TX_CH_SEQ_POS (20)
+#define I2S_TX_CH_SEQ_MSK (0x1 << I2S_TX_CH_SEQ_POS)
+#define I2S_TX_CH_SEQ_CLR (~I2S_TX_CH_SEQ_MSK)
+/* CTRL0[17]: I2S_START_TX. */
+#define I2S_START_TX_POS (17)
+#define I2S_START_TX_MSK (0x1 << I2S_START_TX_POS)
+#define I2S_START_TX_CLR (~I2S_START_TX_MSK)
+/* CTRL0[16]: I2S_TX_DISABLE. */
+#define I2S_TX_DISABLE_POS (16)
+#define I2S_TX_DISABLE_MSK (0x1 << I2S_TX_DISABLE_POS)
+#define I2S_TX_DISABLE_CLR (~I2S_TX_DISABLE_MSK)
+/* CTRL0[13:12]: I2S_DATA_WIDTH. */
+#define I2S_DATA_WIDTH_POS (12)
+#define I2S_DATA_WIDTH_MSK (0x3 << I2S_DATA_WIDTH_POS)
+#define I2S_DATA_WIDTH_CLR (~I2S_DATA_WIDTH_MSK)
+/* CTRL0[11]: I2S_CHANNEL_TYPE. */
+#define I2S_CHANNEL_TYPE_POS (11)
+#define I2S_CHANNEL_TYPE_MSK (0x1 << I2S_CHANNEL_TYPE_POS)
+#define I2S_CHANNEL_TYPE_CLR (~I2S_CHANNEL_TYPE_MSK)
+/* CTRL0[9:8]: I2S_DATA_FORMAT. */
+#define I2S_DATA_FORMAT_POS (8)
+#define I2S_DATA_FORMAT_MSK (0x3 << I2S_DATA_FORMAT_POS)
+#define I2S_DATA_FORMAT_CLR (~I2S_DATA_FORMAT_MSK)
+/* CTRL0[7]: I2S_CTRL_MODE. */
+#define I2S_CTRL_MODE_POS (7)
+#define I2S_CTRL_MODE_MSK (0x1 << I2S_CTRL_MODE_POS)
+#define I2S_CTRL_MODE_CLR (~I2S_CTRL_MODE_MSK)
+/* CTRL0[4]: I2S_SLAVE_DATA_SEL. */
+#define I2S_SLAVE_DATA_SEL_POS (4)
+#define I2S_SLAVE_DATA_SEL_MSK (0x1 << I2S_SLAVE_DATA_SEL_POS)
+#define I2S_SLAVE_DATA_SEL_CLR (~I2S_SLAVE_DATA_SEL_MSK)
+/* CTRL0[3]: I2S_SLAVE_CLK_SEL. */
+#define I2S_SLAVE_CLK_SEL_POS (3)
+#define I2S_SLAVE_CLK_SEL_MSK (0x1 << I2S_SLAVE_CLK_SEL_POS)
+#define I2S_SLAVE_CLK_SEL_CLR (~I2S_SLAVE_CLK_SEL_MSK)
+/* CTRL0[0]: I2S_RESET. */
+#define I2S_RESET_POS (0)
+#define I2S_RESET_MSK (0x1 << I2S_RESET_POS)
+#define I2S_RESET_CLR (~I2S_RESET_MSK)
+
+/* Register: CTRL1 -------------------------------------------------------*/
+/* Description: Control register 1. Offset: 0x08. */
+
+/* CTRL1[30]: I2S_TX_IDLE. */
+#define I2S_TX_IDLE_POS (30)
+#define I2S_TX_IDLE_MSK (0x1 << I2S_TX_IDLE_POS)
+#define I2S_TX_IDLE_CLR (~I2S_TX_IDLE_MSK)
+/* CTRL1[29]: I2S_RF_EMPTY. */
+#define I2S_RF_EMPTY_POS (29)
+#define I2S_RF_EMPTY_MSK (0x1 << I2S_RF_EMPTY_POS)
+#define I2S_RF_EMPTY_CLR (~I2S_RF_EMPTY_MSK)
+/* CTRL1[28]: I2S_TF_EMPTY. */
+#define I2S_TF_EMPTY_POS (28)
+#define I2S_TF_EMPTY_MSK (0x1 << I2S_TF_EMPTY_POS)
+#define I2S_TF_EMPTY_CLR (~I2S_TF_EMPTY_MSK)
+/* CTRL1[27]: I2S_RX_FULL. */
+#define I2S_RX_FULL_POS (27)
+#define I2S_RX_FULL_MSK (0x1 << I2S_RX_FULL_POS)
+#define I2S_RX_FULL_CLR (~I2S_RX_FULL_MSK)
+/* CTRL1[26]: I2S_TX_FULL. */
+#define I2S_TX_FULL_POS (26)
+#define I2S_TX_FULL_MSK (0x1 << I2S_TX_FULL_POS)
+#define I2S_TX_FULL_CLR (~I2S_TX_FULL_MSK)
+/* CTRL1[25]: I2S_READY_TO_RX. */
+#define I2S_READY_TO_RX_POS (25)
+#define I2S_READY_TO_RX_MSK (0x1 << I2S_READY_TO_RX_POS)
+#define I2S_READY_TO_RX_CLR (~I2S_READY_TO_RX_MSK)
+/* CTRL1[24]: I2S_READY_TO_TX. */
+#define I2S_READY_TO_TX_POS (24)
+#define I2S_READY_TO_TX_MSK (0x1 << I2S_READY_TO_TX_POS)
+#define I2S_READY_TO_TX_CLR (~I2S_READY_TO_TX_MSK)
+
+/* CTRL1[23]: I2S_RX_SNK_LR_SWAP. */
+#define I2S_RX_SNK_LR_SWAP_POS (23)
+#define I2S_RX_SNK_LR_SWAP_MSK (0x1 << I2S_RX_SNK_LR_SWAP_POS)
+#define I2S_RX_SNK_LR_SWAP_CLR (~I2S_RX_SNK_LR_SWAP_MSK)
+/* CTRL1[22]: I2S_RX_SNK_BYTE_SWAP. */
+#define I2S_RX_SNK_BYTE_SWAP_POS (22)
+#define I2S_RX_SNK_BYTE_SWAP_MSK (0x1 << I2S_RX_SNK_BYTE_SWAP_POS)
+#define I2S_RX_SNK_BYTE_SWAP_CLR (~I2S_RX_SNK_BYTE_SWAP_MSK)
+/* CTRL1[21]: I2S_TX_SRC_LR_SWAP. */
+#define I2S_TX_SRC_LR_SWAP_POS (21)
+#define I2S_TX_SRC_LR_SWAP_MSK (0x1 << I2S_TX_SRC_LR_SWAP_POS)
+#define I2S_TX_SRC_LR_SWAP_CLR (~I2S_TX_SRC_LR_SWAP_MSK)
+/* CTRL1[20]: I2S_TX_SRC_BYTE_SWAP. */
+#define I2S_TX_SRC_BYTE_SWAP_POS (20)
+#define I2S_TX_SRC_BYTE_SWAP_MSK (0x1 << I2S_TX_SRC_BYTE_SWAP_POS)
+#define I2S_TX_SRC_BYTE_SWAP_CLR (~I2S_TX_SRC_BYTE_SWAP_MSK)
+/* CTRL1[17]: I2S_CLK_128FS. */
+#define I2S_CLK_128FS_POS (17)
+#define I2S_CLK_128FS_MSK (0x1 << I2S_CLK_128FS_POS)
+#define I2S_CLK_128FS_CLR (~I2S_CLK_128FS_MSK)
+/* CTRL1[16]: I2S_CLK_40M. */
+#define I2S_CLK_128_FS_POS (16)
+#define I2S_CLK_128_FS_MSK (0x1 << I2S_CLK_128_FS_POS)
+#define I2S_CLK_128_FS_CLR (~I2S_CLK_128_FS_MSK)
+/* CTRL1[13]: I2S_CLR_RX_ERR_CNT. */
+#define I2S_CLR_RX_ERR_CNT_POS (13)
+#define I2S_CLR_RX_ERR_CNT_MSK (0x1 << I2S_CLR_RX_ERR_CNT_POS)
+#define I2S_CLR_RX_ERR_CNT_CLR (~I2S_CLR_RX_ERR_CNT_MSK)
+/* CTRL1[12]: I2S_CLR_TX_ERR_CNT. */
+#define I2S_CLR_TX_ERR_CNT_POS (12)
+#define I2S_CLR_TX_ERR_CNT_MSK (0x1 << I2S_CLR_TX_ERR_CNT_POS)
+#define I2S_CLR_TX_ERR_CNT_CLR (~I2S_CLR_TX_ERR_CNT_MSK)
+/* CTRL1[7:0]: I2S_FRAME_SYNC_OFFSET. */
+#define I2S_FRAME_SYNC_OFFSET_POS (0)
+#define I2S_FRAME_SYNC_OFFSET_MSK (0xFF << I2S_FRAME_SYNC_OFFSET_POS)
+#define I2S_FRAME_SYNC_OFFSET_CLR (~I2S_FRAME_SYNC_OFFSET_MSK)
+#define I2S_FRAME_SYNC_OFFSET_DEFAULT (0x81 << I2S_FRAME_SYNC_OFFSET_POS)
+
+/* Register: DSP_INT_CR -------------------------------------------------------*/
+/* Description:Interrupt clearregister. Offset: 0x0C. */
+
+/* DSP_INT_CR[1]: I2S_RX_CLEAR_INT. */
+#define I2S_RX_CLEAR_INT_POS (1)
+#define I2S_RX_CLEAR_INT_MSK (0x1 << I2S_RX_CLEAR_INT_POS)
+#define I2S_RX_CLEAR_INT_CLR (~I2S_RX_CLEAR_INT_MSK)
+/* DSP_INT_CR[0]: I2S_TX_CLEAR_INT. */
+#define I2S_TX_CLEAR_INT_POS (0)
+#define I2S_TX_CLEAR_INT_MSK (0x1 << I2S_TX_CLEAR_INT_POS)
+#define I2S_TX_CLEAR_INT_CLR (~I2S_TX_CLEAR_INT_MSK)
+
+/* Register: FIFO_SR -------------------------------------------------------*/
+/* Description: FIFO status register. Offset: 0x14. */
+
+/* FIFO_SR[13:8]: I2S_RX_FIFO_DEPTH_CNT. */
+#define I2S_RX_FIFO_DEPTH_CNT_POS (8)
+#define I2S_RX_FIFO_DEPTH_CNT_MSK (0x3F << I2S_RX_FIFO_DEPTH_CNT_POS)
+#define I2S_RX_FIFO_DEPTH_CNT_CLR (~I2S_RX_FIFO_DEPTH_CNT_MSK)
+/* FIFO_SR[5:0]: I2S_TX_FIFO_DEPTH_CNT. */
+#define I2S_TX_FIFO_DEPTH_CNT_POS (0)
+#define I2S_TX_FIFO_DEPTH_CNT_MSK (0x3F << I2S_TX_FIFO_DEPTH_CNT_POS)
+#define I2S_TX_FIFO_DEPTH_CNT_CLR (~I2S_TX_FIFO_DEPTH_CNT_MSK)
+
+/* Register: ERROR_CNT_SR -------------------------------------------------------*/
+/* Description: Error counter status register. Offset: 0x18. */
+
+/* ERROR_CNT_SR[15:8]: I2S_RX_ERR_CNT. */
+#define I2S_RX_ERR_CNT_POS (8)
+#define I2S_RX_ERR_CNT_MSK (0xFF << I2S_RX_ERR_CNT_POS)
+#define I2S_RX_ERR_CNT_CLR (~I2S_RX_ERR_CNT_MSK)
+/* ERROR_CNT_SR[7:0]: I2S_TX_ERR_CNT. */
+#define I2S_TX_ERR_CNT_POS (0)
+#define I2S_TX_ERR_CNT_MSK (0xFF << I2S_TX_ERR_CNT_POS)
+#define I2S_TX_ERR_CNT_CLR (~I2S_TX_ERR_CNT_MSK)
+
+/* Register: BCLK_DIV -------------------------------------------------------*/
+/* Description: BCLK divider register. Offset: 0x1C. */
+
+/* BCLK_DIV[31]: I2S_MI_NI_UPDATE. */
+#define I2S_MI_NI_UPDATE_POS (31)
+#define I2S_MI_NI_UPDATE_MSK ((uint32_t)0x1 << I2S_MI_NI_UPDATE_POS)
+#define I2S_MI_NI_UPDATE_CLR (~I2S_MI_NI_UPDATE_MSK)
+/* BCLK_DIV[30:16]: I2S_BCLK_NI. */
+#define I2S_BCLK_NI_POS (16)
+#define I2S_BCLK_NI_MSK (0x7FFF << I2S_BCLK_NI_POS)
+#define I2S_BCLK_NI_CLR (~I2S_BCLK_NI_MSK)
+/* BCLK_DIV[15:0]: I2S_BCLK_MI. */
+#define I2S_BCLK_MI_POS (0)
+#define I2S_BCLK_MI_MSK (0xFFFF << I2S_BCLK_MI_POS)
+#define I2S_BCLK_MI_CLR (~I2S_BCLK_MI_MSK)
+
+/* Register: DMA_TRDLR -------------------------------------------------------*/
+/* Description: DMA transmit receive data level register. Offset: 0x20. */
+
+/* DMA_TRDLR[5:0]: I2S_TX_DMA_BURST_SIZE. */
+#define I2S_TX_DMA_BURST_SIZE_POS (0)
+#define I2S_TX_DMA_BURST_SIZE_MSK (0x3F << I2S_TX_DMA_BURST_SIZE_POS)
+#define I2S_TX_DMA_BURST_SIZE_CLR (~I2S_TX_DMA_BURST_SIZE_MSK)
+/* DMA_TRDLR[13:8]: I2S_RX_DMA_BURST_SIZE. */
+#define I2S_RX_DMA_BURST_SIZE_POS (8)
+#define I2S_RX_DMA_BURST_SIZE_MSK (0x3F << I2S_RX_DMA_BURST_SIZE_POS)
+#define I2S_RX_DMA_BURST_SIZE_CLR (~I2S_RX_DMA_BURST_SIZE_MSK)
+
+/* Register: PERIPH_AUDIO_CLK_224 -------------------------------------------------------*/
+/* Description: peri on register. address: 0x40000224. */
+#define PERIPH_AUDIO_CLK_224 0x40000224
+/* PERIPH_AUDIO_CLK_224[3]: I2S0_EXT_CODEC. */
+#define I2S0_EXT_CODEC_POS (3)
+#define I2S0_EXT_CODEC_MSK (0x1 << I2S0_EXT_CODEC_POS)
+#define I2S0_EXT_CODEC_CLR (~I2S0_EXT_CODEC_MSK)
+
+/* Register: PERIPH_AUDIO_CLK_228 -------------------------------------------------------*/
+/* Description: peri on register. address: 0x40000228. */
+#define PERIPH_AUDIO_CLK_228 0x40000228
+/* PERIPH_AUDIO_CLK_228[4]: I2S_MCLK_OUTPUT. */
+#define I2S_MCLK_OUTPUT_POS (4)
+#define I2S_MCLK_OUTPUT_MSK (0x1 << I2S_MCLK_OUTPUT_POS)
+#define I2S_MCLK_OUTPUT_CLR (~I2S_MCLK_OUTPUT_MSK)
+
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup I2S_Exported_Constants Macro Defines
+ *
+ * \ingroup I2S
+ */
+
+#define IS_I2S_ALL_PERIPH(PERIPH) ((PERIPH) == I2S0)
+
+/**
+ * \defgroup I2S_Clock_Source I2S Clock Source
+ * \{
+ * \ingroup I2S_Exported_Constants
+ */
+#define I2S_CLK_40M (I2S_CLK_128_FS_MSK)
+#define I2S_CLK_128fs (I2S_CLK_128FS_MSK)
+#define I2S_CLK_256fs ((uint32_t)(0x00))
+/** \} */
+
+#define IS_I2S_CLK_SOURCE(CLK) (((CLK) == I2S_CLK_40M) || \
+ ((CLK) == I2S_CLK_128fs) || \
+ ((CLK) == I2S_CLK_256fs))
+
+/**
+ * \defgroup I2S_Device_Mode I2S Device Mode
+ * \{
+ * \ingroup I2S_Exported_Constants
+ */
+
+#define I2S_DeviceMode_Master ((uint32_t)0x00)
+#define I2S_DeviceMode_Slave (I2S_SLAVE_DATA_SEL_MSK )//| I2S_SLAVE_CLK_SEL_MSK)
+/** \} */
+
+#define IS_I2S_DEVICE_MODE(DEVICE) (((DEVICE) == I2S_DeviceMode_Master) || ((DEVICE) == I2S_DeviceMode_Slave))
+
+/**
+ * \defgroup I2S_Mode I2S Mode
+ * \{
+ * \ingroup I2S_Exported_Constants
+ */
+#define I2S_MODE_TX (I2S_START_TX_MSK)
+#define I2S_MODE_RX (I2S_START_RX_MSK)
+/** \} */
+
+#define IS_I2S_MODE(MODE) (((MODE) == I2S_MODE_TX) || ((MODE) == I2S_MODE_RX))
+
+/**
+ * \defgroup I2S_Channel_Type I2S Channel Type
+ * \{
+ * \ingroup I2S_Exported_Constants
+ */
+#define I2S_Channel_Mono (I2S_CHANNEL_TYPE_MSK)
+#define I2S_Channel_stereo ((uint32_t)(0x0))
+/** \} */
+
+#define IS_I2S_CHANNEL_TYPE(TYPE) (((TYPE) == I2S_Channel_Mono) || ((TYPE) == I2S_Channel_stereo))
+
+/**
+ * \defgroup I2S_Tx_Ch_Sequence I2S Transmission Channel Sequence
+ * \{
+ * \ingroup I2S_Exported_Constants
+ */
+#define I2S_TX_CH_L_R (0)
+#define I2S_TX_CH_R_L ((uint32_t)0x01 << I2S_TX_CH_SEQ_POS)
+#define I2S_TX_CH_L_L ((uint32_t)0x02 << I2S_TX_CH_SEQ_POS)
+#define I2S_TX_CH_R_R ((uint32_t)0x03 << I2S_TX_CH_SEQ_POS)
+/** \} */
+
+#define IS_I2S_TX_CH_SEQ(SEQ) (((SEQ) == I2S_TX_CH_L_R) || ((SEQ) == I2S_TX_CH_R_L) || \
+ ((SEQ) == I2S_TX_CH_L_L) || ((SEQ) == I2S_TX_CH_R_R))
+
+/**
+ * \defgroup I2S_Rx_Ch_Sequence I2S Receiving Channel Sequence
+ * \{
+ * \ingroup I2S_Exported_Constants
+ */
+#define I2S_RX_CH_L_R (0)
+#define I2S_RX_CH_R_L ((uint32_t)0x01 << I2S_RX_CH_SEQ_POS)
+#define I2S_RX_CH_L_L ((uint32_t)0x02 << I2S_RX_CH_SEQ_POS)
+#define I2S_RX_CH_R_R ((uint32_t)0x03 << I2S_RX_CH_SEQ_POS)
+/** \} */
+
+#define IS_I2S_RX_CH_SEQ(SEQ) (((SEQ) == I2S_RX_CH_L_R) || ((SEQ) == I2S_RX_CH_R_L) || \
+ ((SEQ) == I2S_RX_CH_L_L) || ((SEQ) == I2S_RX_CH_R_R))
+
+/**
+ * \defgroup I2S_Format_Mode I2S Format Mode
+ * \{
+ * \ingroup I2S_Exported_Constants
+ */
+#define I2S_Mode ((uint32_t)(0x00 << I2S_DATA_FORMAT_POS))
+#define Left_Justified_Mode ((uint32_t)(0x01 << I2S_DATA_FORMAT_POS))
+#define PCM_Mode_A ((uint32_t)(0x02 << I2S_DATA_FORMAT_POS))
+#define PCM_Mode_B ((uint32_t)(0x03 << I2S_DATA_FORMAT_POS))
+/** \} */
+
+#define IS_I2S_DATA_FORMAT(FORMAT) (((FORMAT) == I2S_Mode) || ((FORMAT) == Left_Justified_Mode) || \
+ ((FORMAT) == PCM_Mode_A) || ((FORMAT) == PCM_Mode_B))
+
+/**
+ * \defgroup I2S_Tx_Bit_Sequence I2S Tx Bit Sequence
+ * \{
+ * \ingroup I2S_Exported_Constants
+ */
+#define I2S_TX_MSB_First ((uint32_t)0x0)
+#define I2S_TX_LSB_First (I2S_TX_LSB_FIRST_MSK)
+/** \} */
+
+#define IS_I2S_TX_BIT_SEQ(SEQ) (((SEQ) == I2S_TX_MSB_First) || ((SEQ) == I2S_TX_LSB_First))
+
+/**
+ * \defgroup I2S_Rx_Bit_Sequence I2S Rx Bit Sequence
+ * \{
+ * \ingroup I2S_Exported_Constants
+ */
+#define I2S_RX_MSB_First ((uint32_t)0x0)
+#define I2S_RX_LSB_First (I2S_RX_LSB_FIRST_MSK)
+/** \} */
+
+#define IS_I2S_RX_BIT_SEQ(SEQ) (((SEQ) == I2S_RX_MSB_First) || ((SEQ) == I2S_RX_LSB_First))
+
+/**
+ * \defgroup I2S_Data_Width I2S Data Width
+ * \{
+ * \ingroup I2S_Exported_Constants
+ */
+
+#define I2S_Width_16Bits ((uint32_t)(0x00 << I2S_DATA_WIDTH_POS))
+#define I2S_Width_24Bits ((uint32_t)(0x02 << I2S_DATA_WIDTH_POS))
+#define I2S_Width_8Bits ((uint32_t)(0x03 << I2S_DATA_WIDTH_POS))
+/** \} */
+
+#define IS_I2S_DATA_WIDTH(WIDTH) (((WIDTH) == I2S_Width_16Bits) || \
+ ((WIDTH) == I2S_Width_24Bits) || \
+ ((WIDTH) == I2S_Width_8Bits))
+
+/**
+ * \defgroup I2S_MCLK_Output I2S MCLK Output
+ * \{
+ * \ingroup I2S_Exported_Constants
+ */
+#define I2S_MCLK_128fs ((uint32_t)0x0)
+#define I2S_MCLK_256fs (I2S_MCLK_SEL_MSK)
+/** \} */
+
+#define IS_I2S_MCLK_OUTPUT_TYPE(TYPE) (((TYPE) == I2S_MCLK_128fs) || ((TYPE) == I2S_MCLK_256fs))
+
+/**
+ * \defgroup I2S_DMA_Cmd I2S DMA Cmd
+ * \{
+ * \ingroup I2S_Exported_Constants
+ */
+#define I2S_DMA_ENABLE ((uint32_t)0x0)
+#define I2S_DMA_DISABLE (I2S_CTRL_MODE_MSK)
+/** \} */
+
+#define IS_I2S_DMA_CMD(CMD) (((CMD) == I2S_DMA_ENABLE) || ((CMD) == I2S_DMA_DISABLE))
+
+/**
+ * \defgroup I2S_Interrupt_Definition I2S Interrupt Definition
+ * \{
+ * \ingroup I2S_Exported_Constants
+ */
+#define I2S_INT_TX_IDLE (I2S_TX_IDLE_MSK)
+#define I2S_INT_RF_EMPTY (I2S_RF_EMPTY_MSK)
+#define I2S_INT_TF_EMPTY (I2S_TF_EMPTY_MSK)
+#define I2S_INT_RF_FULL (I2S_RX_FULL_MSK)
+#define I2S_INT_TF_FULL (I2S_TX_FULL_MSK)
+#define I2S_INT_RX_READY (I2S_READY_TO_RX_MSK)
+#define I2S_INT_TX_READY (I2S_READY_TO_TX_MSK)
+/** \} */
+
+#define IS_I2S_INT_CONFIG(INT) (((INT) == I2S_INT_TX_IDLE) || ((INT) == I2S_INT_RF_EMPTY) || \
+ ((INT) == I2S_INT_TF_EMPTY) || ((INT) == I2S_INT_RF_FULL) || \
+ ((INT) == I2S_INT_TF_FULL) || ((INT) == I2S_INT_RX_READY) || \
+ ((INT) == I2S_INT_TX_READY) )
+
+/**
+ * \defgroup I2S_Clear_Interrupt_Definition I2S Clear Interrupt Definition
+ * \{
+ * \ingroup I2S_Exported_Constants
+ */
+#define I2S_CLEAR_INT_RX_READY (I2S_RX_CLEAR_INT_MSK)
+#define I2S_CLEAR_INT_TX_READY (I2S_TX_CLEAR_INT_MSK)
+/** \} */
+
+#define IS_I2S_CLEAR_INT(CLEAR) (((CLEAR) == I2S_CLEAR_INT_RX_READY) || \
+ ((CLEAR) == I2S_CLEAR_INT_TX_READY) )
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup I2S_Exported_Functions Peripheral APIs
+ * \{
+ * \ingroup I2S
+ */
+
+/**
+ * \brief Deinitializes the I2S peripheral registers to their default values.
+ * \param None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_i2s_init(void)
+ * {
+ * I2S_DeInit(I2S0);
+ * }
+ * \endcode
+ */
+void I2S_DeInit(I2S_TypeDef *I2Sx);
+
+/**
+ * \brief Initializes the I2S peripheral according to the specified
+ * parameters in the I2S_InitStruct
+ * \param[in] I2Sx: Selected I2S peripheral.
+ * \param[in] I2S_InitStruct: Pointer to a I2S_InitTypeDef structure that
+ * contains the configuration information for the specified I2S peripheral
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_i2s_init(void)
+ * {
+ * RCC_PeriphClockCmd(APB_I2S, APB_I2S_CLOCK, ENABLE);
+ *
+ * I2S_InitTypeDef I2S_InitStruct;
+ *
+ * I2S_StructInit(&I2S_InitStruct);
+ * I2S_InitStruct.I2S_ClockSource = I2S_CLK_40M;
+ * I2S_InitStruct.I2S_BClockMi = 0x271;
+ * I2S_InitStruct.I2S_BClockNi = 0x10;
+ * I2S_InitStruct.I2S_DeviceMode = I2S_DeviceMode_Master;
+ * I2S_InitStruct.I2S_ChannelType = I2S_Channel_stereo;
+ * I2S_InitStruct.I2S_DataWidth = I2S_Width_16Bits;
+ * I2S_InitStruct.I2S_DataFormat = I2S_Mode;
+ * I2S_InitStruct.I2S_DMACmd = I2S_DMA_DISABLE;
+ * I2S_Init(I2S0, &I2S_InitStruct);
+ * I2S_Cmd(I2S0, I2S_MODE_TX, ENABLE);
+ * }
+ * \endcode
+ */
+void I2S_Init(I2S_TypeDef *I2Sx, I2S_InitTypeDef *I2S_InitStruct);
+
+/**
+ * \brief Fills each I2S_InitStruct member with its default value.
+ * \param[in] I2S_InitStruct: Pointer to an I2S_InitTypeDef structure which will be initialized.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_i2s_init(void)
+ * {
+ * RCC_PeriphClockCmd(APB_I2S, APB_I2S_CLOCK, ENABLE);
+ *
+ * I2S_InitTypeDef I2S_InitStruct;
+ *
+ * I2S_StructInit(&I2S_InitStruct);
+ * I2S_InitStruct.I2S_ClockSource = I2S_CLK_40M;
+ * I2S_InitStruct.I2S_BClockMi = 0x271;
+ * I2S_InitStruct.I2S_BClockNi = 0x10;
+ * I2S_InitStruct.I2S_DeviceMode = I2S_DeviceMode_Master;
+ * I2S_InitStruct.I2S_ChannelType = I2S_Channel_stereo;
+ * I2S_InitStruct.I2S_DataWidth = I2S_Width_16Bits;
+ * I2S_InitStruct.I2S_DataFormat = I2S_Mode;
+ * I2S_InitStruct.I2S_DMACmd = I2S_DMA_DISABLE;
+ * I2S_Init(I2S0, &I2S_InitStruct);
+ * I2S_Cmd(I2S0, I2S_MODE_TX, ENABLE);
+ * }
+ * \endcode
+ */
+void I2S_StructInit(I2S_InitTypeDef *I2S_InitStruct);
+
+/**
+ * \brief Enable or disable the selected I2S mode.
+ * \param[in] I2Sx: Selected I2S peripheral.
+ * \param[in] mode: Selected I2S operation mode.
+ * This parameter can be the following values:
+ * \arg I2S_MODE_TX: Transmission mode.
+ * \arg I2S_MODE_RX: Receiving mode.
+ * \param[in] NewState: New state of the operation mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_i2s_init(void)
+ * {
+ * RCC_PeriphClockCmd(APB_I2S, APB_I2S_CLOCK, ENABLE);
+ *
+ * I2S_InitTypeDef I2S_InitStruct;
+ *
+ * I2S_StructInit(&I2S_InitStruct);
+ * I2S_InitStruct.I2S_ClockSource = I2S_CLK_40M;
+ * I2S_InitStruct.I2S_BClockMi = 0x271;
+ * I2S_InitStruct.I2S_BClockNi = 0x10;
+ * I2S_InitStruct.I2S_DeviceMode = I2S_DeviceMode_Master;
+ * I2S_InitStruct.I2S_ChannelType = I2S_Channel_stereo;
+ * I2S_InitStruct.I2S_DataWidth = I2S_Width_16Bits;
+ * I2S_InitStruct.I2S_DataFormat = I2S_Mode;
+ * I2S_InitStruct.I2S_DMACmd = I2S_DMA_DISABLE;
+ * I2S_Init(I2S_NUM, &I2S_InitStruct);
+ * I2S_Cmd(I2S_NUM, I2S_MODE_TX, ENABLE);
+ * }
+ * \endcode
+ */
+void I2S_Cmd(I2S_TypeDef *I2Sx, uint32_t mode, FunctionalState NewState);
+
+/**
+ * \brief Enable or disable the specified I2S interrupt source.
+ * \param[in] I2S_INT: Specifies the I2S interrupt source to be enable or disable.
+ * This parameter can be the following values:
+ * \arg I2S_INT_TX_IDLE: Transmit idle interrupt source.
+ * \arg I2S_INT_RF_EMPTY: Receive FIFO empty interrupt source.
+ * \arg I2S_INT_TF_EMPTY: Transmit FIFO empty interrupt source.
+ * \arg I2S_INT_RF_FULL: Receive FIFO full interrupt source.
+ * \arg I2S_INT_TF_FULL: Transmit FIFO full interrupt source.
+ * \arg I2S_INT_RX_READY: Ready to receive interrupt source.
+ * \arg I2S_INT_TX_READY: Ready to transmit interrupt source.
+ * \param[in] NewState: New state of the specified I2S interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * I2S_INTConfig(I2S0, I2S_INT_TF_EMPTY, ENABLE);
+ * }
+ * \endcode
+ */
+void I2S_INTConfig(I2S_TypeDef *I2Sx, uint32_t I2S_INT, FunctionalState newState);
+
+/**
+ * \brief Get the specified I2S interrupt status.
+ * \param[in] I2S_INT: the specified I2S interrupt.
+ * This parameter can be one of the following values:
+ * \arg I2S_INT_TX_IDLE: Transmit idle interrupt.
+ * \arg I2S_INT_RF_EMPTY: Receive FIFO empty interrupt.
+ * \arg I2S_INT_TF_EMPTY: Transmit FIFO empty interrupt.
+ * \arg I2S_INT_RF_FULL: Receive FIFO full interrupt.
+ * \arg I2S_INT_TF_FULL: Transmit FIFO full interrupt.
+ * \arg I2S_INT_RX_READY: Ready to receive interrupt.
+ * \arg I2S_INT_TX_READY: Ready to transmit interrupt.
+ * \return The new state of I2S_INT (SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * ITStatus int_status = I2S_GetINTStatus(I2S0, I2S_INT_TF_EMPTY);
+ * }
+ * \endcode
+ */
+ITStatus I2S_GetINTStatus(I2S_TypeDef *I2Sx, uint32_t I2S_INT);
+
+/**
+ * \brief Clear the I2S interrupt pending bit.
+ * \param[in] I2S_CLEAR_INT: Specifies the interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * \arg I2S_CLEAR_INT_RX_READY: Clear ready to receive interrupt.
+ * \arg I2S_CLEAR_INT_TX_READY: Clear ready to transmit interrupt.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * I2S_ClearINTPendingBit(I2S0, I2S_CLEAR_INT_RX_READY);
+ * }
+ * \endcode
+ */
+void I2S_ClearINTPendingBit(I2S_TypeDef *I2Sx, uint32_t I2S_CLEAR_INT);
+
+/**
+ * \brief Transmits a data through the SPIx/I2Sx peripheral.
+ * \param[in] I2Sx: To select the I2Sx peripheral, x can be 0.
+ * \param[in] Data: Data to be transmitted.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * I2S_SendData(I2S0, 0x02);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void I2S_SendData(I2S_TypeDef *I2Sx, uint32_t Data)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_PERIPH(I2Sx));
+
+ I2Sx->TX_DR = Data;
+}
+
+/**
+ * \brief Received data by the I2Sx peripheral.
+ * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0.
+ * \return Return the most recent received data.
+ * \
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * uint32_t data = I2S_ReceiveData(I2S0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t I2S_ReceiveData(I2S_TypeDef *I2Sx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_PERIPH(I2Sx));
+
+ return I2Sx->RX_DR;
+}
+
+/**
+ * \brief Get transmit FIFO free length by the I2Sx peripheral.
+ * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0.
+ * \return Return the transmit FIFO free length.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * uint8_t data_len = I2S_GetTxFIFOFreeLen(I2S0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint8_t I2S_GetTxFIFOFreeLen(I2S_TypeDef *I2Sx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_PERIPH(I2Sx));
+
+ return ((I2Sx->FIFO_SR & I2S_TX_FIFO_DEPTH_CNT_MSK) >> I2S_TX_FIFO_DEPTH_CNT_POS);
+}
+
+/**
+ * \brief Get receive FIFO data length by the I2Sx peripheral.
+ * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0.
+ * \return The data length of the receive FIFO.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * uint8_t data_len = I2S_GetRxFIFOLen(I2S0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint8_t I2S_GetRxFIFOLen(I2S_TypeDef *I2Sx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_PERIPH(I2Sx));
+
+ return ((I2Sx->FIFO_SR & I2S_RX_FIFO_DEPTH_CNT_MSK) >> I2S_RX_FIFO_DEPTH_CNT_POS);
+}
+
+/**
+ * \brief Get the send error counter value by the I2Sx peripheral.
+ * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0.
+ * \return The send error counter value .
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * uint8_t counter = I2S_GetTxErrCnt(I2S0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint8_t I2S_GetTxErrCnt(I2S_TypeDef *I2Sx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_PERIPH(I2Sx));
+
+ return ((I2Sx->ERROR_CNT_SR & I2S_TX_ERR_CNT_MSK) >> I2S_TX_ERR_CNT_POS);
+}
+
+/**
+ * \brief Get the reception error counter value by the I2Sx peripheral.
+ * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0.
+ * \retval The reception error counter value .
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * uint8_t counter = I2S_GetRxErrCnt(I2S0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint8_t I2S_GetRxErrCnt(I2S_TypeDef *I2Sx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_PERIPH(I2Sx));
+
+ return ((I2Sx->ERROR_CNT_SR & I2S_RX_ERR_CNT_MSK) >> I2S_RX_ERR_CNT_POS);
+}
+
+/**
+ * \brief Swap audio data bytes sequence which sent by the I2Sx peripheral.
+ * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0.
+ * \param[in] NewState: New state of the bytes sequence.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * I2S_SwapBytesForSend(I2S0, ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void I2S_SwapBytesForSend(I2S_TypeDef *I2Sx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_PERIPH(I2Sx));
+
+ if (NewState == ENABLE)
+ {
+ I2Sx->CTRL1 |= I2S_TX_SRC_BYTE_SWAP_MSK;
+ }
+ else
+ {
+ I2Sx->CTRL1 &= I2S_TX_SRC_BYTE_SWAP_CLR;
+ }
+}
+
+/**
+ * \brief Swap audio data bytes sequence which read by the I2Sx peripheral.
+ * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0.
+ * \param[in] NewState: New state of the bytes sequence.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * I2S_SwapBytesForRead(I2S0, ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void I2S_SwapBytesForRead(I2S_TypeDef *I2Sx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_PERIPH(I2Sx));
+
+ if (NewState == ENABLE)
+ {
+ I2Sx->CTRL1 |= I2S_RX_SNK_BYTE_SWAP_MSK;
+ }
+ else
+ {
+ I2Sx->CTRL1 &= I2S_RX_SNK_BYTE_SWAP_CLR;
+ }
+}
+
+/**
+ * \brief Swap audio channel data which sent by the I2Sx peripheral..
+ * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0.
+ * \param[in] NewState: New state of the left and right channel data sequence.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * I2S_SwapLRChDataForSend(I2S0, ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void I2S_SwapLRChDataForSend(I2S_TypeDef *I2Sx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_PERIPH(I2Sx));
+
+ if (NewState == ENABLE)
+ {
+ I2Sx->CTRL1 |= I2S_TX_SRC_LR_SWAP_MSK;
+ }
+ else
+ {
+ I2Sx->CTRL1 &= I2S_TX_SRC_LR_SWAP_CLR;
+ }
+}
+
+/**
+ * \brief Swap audio channel data which read by the I2Sx peripheral.
+ * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0.
+ * \param[in] NewState: New state of the left and right channel data sequence.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * I2S_SwapLRChDataForRead(I2S0, ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void I2S_SwapLRChDataForRead(I2S_TypeDef *I2Sx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_PERIPH(I2Sx));
+
+ if (NewState == ENABLE)
+ {
+ I2Sx->CTRL1 |= I2S_RX_SNK_LR_SWAP_MSK;
+ }
+ else
+ {
+ I2Sx->CTRL1 &= I2S_RX_SNK_LR_SWAP_CLR;
+ }
+}
+
+/**
+ * \brief MCLK output selection which can be from I2S0.
+ * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0.
+ * \param[in] NewState: New state of MCLK output.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * I2S_MCLKOutputSelectCmd(I2S0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void I2S_MCLKOutputSelectCmd(I2S_TypeDef *I2Sx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_PERIPH(I2Sx));
+
+ if (I2Sx == I2S0)
+ {
+ *((volatile uint32_t *)PERIPH_AUDIO_CLK_228) |= I2S_MCLK_OUTPUT_MSK;
+ }
+}
+
+/**
+ * \brief I2S0 communication selection which can be from intrnal codec or external codec.
+ * \param[in] NewState: New state of I2S0 communication selection.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * I2S0_WithExtCodecCmd(ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void I2S0_WithExtCodecCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState == ENABLE)
+ {
+ *((volatile uint32_t *)PERIPH_AUDIO_CLK_224) |= I2S0_EXT_CODEC_MSK;
+ }
+ else
+ {
+ *((volatile uint32_t *)PERIPH_AUDIO_CLK_224) &= I2S0_EXT_CODEC_CLR;
+ }
+}
+
+/**
+ * \brief Config BClk clock.
+ * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0.
+ * \param[in] I2S_BClockMi: Mi parameter.
+ * \param[in] I2S_BClockNi: Ni parameter.
+ * \return Execution status.
+ * \retval SET: Success.
+ * \retval RESET: Failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * FlagStatus status = I2S_UpdateBClk(I2S0, 0x271, 0x10);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE FlagStatus I2S_UpdateBClk(I2S_TypeDef *I2Sx, uint16_t I2S_BClockMi,
+ uint16_t I2S_BClockNi)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_PERIPH(I2Sx));
+
+ if (!(I2Sx->BCLK_DIV & I2S_MI_NI_UPDATE_MSK))
+ {
+ I2Sx->BCLK_DIV = I2S_BClockMi | (I2S_BCLK_NI_MSK & (I2S_BClockNi << I2S_BCLK_NI_POS)) |
+ I2S_MI_NI_UPDATE_MSK;
+ return SET;
+ }
+
+ return RESET;
+}
+
+/**
+ * \brief Get BClk clock status.
+ * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0.
+ * \return Execution status.
+ * \retval SET: BLCK is updating.
+ * \retval RESET: BLCK update is done.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * FlagStatus status = I2S_GetBClkStatus(I2S0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE FlagStatus I2S_GetBClkStatus(I2S_TypeDef *I2Sx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_PERIPH(I2Sx));
+
+ if (I2Sx->BCLK_DIV & I2S_MI_NI_UPDATE_MSK)
+ {
+ return SET;
+ }
+
+ return RESET;
+}
+
+/**
+ * \brief Config channel type.
+ * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0.
+ * \param[in] I2S_ChannelType: The channel type used for the I2S communication.
+ * This parameter can be one of the following values:
+ * \arg I2S_Channel_Mono: Mono channel.
+ * \arg I2S_Channel_stereo: Stereo channel.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void i2s_demo(void)
+ * {
+ * I2S_ConfigChannelType(I2S0, I2S_Channel_Mono);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void I2S_ConfigChannelType(I2S_TypeDef *I2Sx, uint32_t I2S_ChannelType)
+{
+ I2Sx->CTRL0 &= I2S_CHANNEL_TYPE_CLR;
+ I2Sx->CTRL0 |= I2S_ChannelType;
+}
+
+/** \} */ /*End of group I2S_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876x_I2S_H_ */
+
+
+
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/inc/peripheral/rtl876x_io_dlps.h b/inc/peripheral/rtl876x_io_dlps.h
new file mode 100644
index 0000000..9a7c25c
--- /dev/null
+++ b/inc/peripheral/rtl876x_io_dlps.h
@@ -0,0 +1,109 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file rtl876x_io_dlps.h
+* @brief
+* @details
+* @author tifnan_ge
+* @date 2015-05-18
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+
+#ifndef _RTL876X_IO_DLPS_H_
+#define _RTL876X_IO_DLPS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "rtl876x.h"
+#include "rtl876x_bitfields.h"
+#include "board.h"
+
+#if (PLATFORM_SUPPORT_POWER_MANAGER == 0)
+#include "dlps.h"
+#endif
+
+/** @addtogroup IO Peripheral Drivers
+ *
+ * @defgroup IO_DLPS IO DLPS
+ * @brief IO DLPS dirver module
+ * \ingroup IO
+ * @{
+ */
+
+/** @defgroup IO_DLPS_Exported_Types IO DLPS Exported Types
+ * @{
+ */
+
+typedef void (*DLPS_IO_ExitDlpsCB)(void);
+typedef void (*DLPS_IO_EnterDlpsCB)(void);
+
+/** End of group IO_DLPS_Exported_Types
+ * @}
+ */
+
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+
+/** @defgroup IO_DLPS_Exported_Functions IO DLPS Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Register io restore function in dlps mode
+ * @param None
+ * @retval None
+ */
+extern void DLPS_IORegister(void);
+#if USE_USER_DEFINE_DLPS_EXIT_CB
+
+extern DLPS_IO_ExitDlpsCB User_IO_ExitDlpsCB;
+
+/**
+ * @brief Rrgister user-defined exit dlps callback function
+ * @param func: user-defined callback functon.
+ * @retval None
+ */
+__STATIC_INLINE void DLPS_IORegUserDlpsExitCb(DLPS_IO_ExitDlpsCB func)
+{
+ User_IO_ExitDlpsCB = func;
+}
+
+#endif /* USE_USER_DEFINE_DLPS_EXIT_CB */
+
+#if USE_USER_DEFINE_DLPS_ENTER_CB
+
+extern DLPS_IO_EnterDlpsCB User_IO_EnterDlpsCB;
+
+/**
+ * @brief Rrgister user-defined enter dlps callback function
+ * @param func: user-defined callback functon.
+ * @retval None
+ */
+__STATIC_INLINE void DLPS_IORegUserDlpsEnterCb(DLPS_IO_EnterDlpsCB func)
+{
+ User_IO_EnterDlpsCB = func;
+}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_IO_DLPS_H_ */
+
+/** @} */ /* End of group IO_DLPS_Exported_Functions */
+/** @} */ /* End of group IO_DLPS */
+
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor *****END OF FILE****/
+
diff --git a/inc/peripheral/rtl876x_ir.h b/inc/peripheral/rtl876x_ir.h
new file mode 100644
index 0000000..981850a
--- /dev/null
+++ b/inc/peripheral/rtl876x_ir.h
@@ -0,0 +1,1314 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_ir.h
+* \brief The header file of the peripheral IR driver.
+* \details This file provides all IR firmware functions.
+* \author yuan
+* \date 2020-10-13
+* \version v2.1.2
+* *********************************************************************************************************
+*/
+
+
+#ifndef _RTL876x_IR_H_
+#define _RTL876x_IR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup IR IR
+ *
+ * \brief Manage the IR peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x.h"
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/** \defgroup IR_Exported_Types Init Params Struct
+ *
+ * \ingroup IR
+ */
+
+/**
+ * \brief IR init structure definition.
+ *
+ * \ingroup IR_Exported_Types
+ */
+typedef struct
+{
+ uint32_t IR_Clock;
+ uint32_t IR_Freq; /*!< Specifies the clock frequency. This parameter is IR carrier freqency whose unit is Hz. */
+ float IR_DutyCycle; /*!< Specifies the IR duty cycle. */
+ uint32_t IR_Mode; /*!< Specifies the IR mode.
+ This parameter can be a value of \ref IR_Mode */
+ uint32_t IR_TxIdleLevel; /*!< Specifies the IR output level in Tx mode
+ This parameter can be a value of \ref IR_Idle_Status */
+ uint32_t IR_TxInverse; /*!< Specifies inverse FIFO data or not in TX mode
+ This parameter can be a value of \ref IR_TX_Data_Type */
+ uint32_t IR_TxFIFOThrLevel; /*!< Specifies TX FIFO interrupt threshold in TX mode. When TX FIFO depth <= threshold value, trigger interrupt.
+ This parameter can be a value of 1 ~ 32. */
+ uint32_t IR_RxStartMode; /*!< Specifies Start mode in RX mode
+ This parameter can be a value of \ref IR_Rx_Start_Mode. */
+ uint32_t IR_RxFIFOThrLevel; /*!< Specifies RX FIFO interrupt threshold in RX mode. when RX FIFO depth > threshold value, trigger interrupt.
+ This parameter can be a value of \ref IR_Rx_Threshold */
+ uint32_t IR_RxFIFOFullCtrl; /*!< Specifies data discard mode in RX mode when RX FIFO is full and receiving new data.
+ This parameter can be a value of \ref IR_RX_FIFO_DISCARD_SETTING. */
+ uint32_t IR_RxTriggerMode; /*!< Specifies trigger in RX mode
+ This parameter can be a value of \ref IR_RX_Trigger_Mode. */
+ uint32_t IR_RxFilterTime; /*!< Specifies filter time in RX mode
+ This parameter can be a value of \ref IR_RX_Filter_Time. */
+ uint32_t IR_RxCntThrType; /*!< Specifies counter level type when trigger IR_INT_RX_CNT_THR interrupt in RX mode.
+ This parameter can be a value of \ref IR_RX_COUNTER_THRESHOLD_TYPE. */
+ uint32_t IR_RxCntThr; /*!< Specifies counter threshold value when trigger IR_INT_RX_CNT_THR interrupt in RX mode. */
+ uint8_t IR_TxDmaEn; /*!< Specifies the Tx dma mode.
+ This parameter must be a value of DISABLE and ENABLE. */
+ uint8_t IR_TxWaterLevel; /*!< Specifies the DMA tx water level.
+ This parameter must range from 0 to 32.*/
+ uint8_t IR_RxDmaEn; /*!< Specifies the Rx dma mode.
+ This parameter must be a value of DISABLE and ENABLE. */
+ uint8_t IR_RxWaterLevel; /*!< Specifies the DMA rx water level.
+ This parameter must range from 0 to 32.*/
+} IR_InitTypeDef;
+
+
+/*============================================================================*
+ * Register Defines
+ *============================================================================*/
+
+/* Peripheral: IR */
+/* Description: IR register defines */
+
+/* Register: TX_CONFIG -------------------------------------------------------*/
+/* Description: IR TX CONFIG register. Offset: 0x04. Address: 0x40003004. */
+
+/* TX_CONFIG[31] :IR_MODE_SEL. 0x1: RX mode. 0x0: TX mode. */
+#define IR_MODE_SEL_Pos (31UL)
+#define IR_MODE_SEL_Msk (0x1UL << IR_MODE_SEL_Pos)
+#define IR_MODE_SEL_CLR (~IR_MODE_SEL_Msk)
+/* TX_CONFIG[30] :IR_TX_START. 0x1: Start TX. 0x0: Stop TX. */
+#define IR_TX_START_Pos (30UL)
+#define IR_TX_START_Msk (0x1UL << IR_TX_START_Pos)
+#define IR_TX_START_CLR (~IR_TX_START_Msk)
+/* TX_CONFIG[16] :IR_TX_DUTY_NUM. Duty cycle setting for modulation frequency. */
+/* Example : for 1/3 duty cycle, IR_DUTY_NUM = (IR_DIV_NUM+1)/3 -1. */
+#define IR_TX_DUTY_NUM_Pos (16UL)
+#define IR_TX_DUTY_NUM_Msk (0x1FFFUL << IR_TX_DUTY_NUM_Pos)
+/* TX_CONFIG[14] :IR_OUTPUT_INVERSE. 0x1: Inverse active output. 0x0: Not inverse active output. */
+#define IR_OUTPUT_INVERSE_Pos (14UL)
+#define IR_OUTPUT_INVERSE_Msk (0x1UL << IR_OUTPUT_INVERSE_Pos)
+#define IR_OUTPUT_INVERSE_CLR (~IR_OUTPUT_INVERSE_Msk)
+/* TX_CONFIG[13] :IR_FIFO_INVERSE. 0x1: Inverse FIFO define. 0x0: Not inverse FIFO define. */
+#define IR_FIFO_INVERSE_Pos (13UL)
+#define IR_FIFO_INVERSE_Msk (0x1UL << IR_FIFO_INVERSE_Pos)
+#define IR_FIFO_INVERSE_CLR (~IR_FIFO_INVERSE_Msk)
+/* TX_CONFIG[8] :IR_TX_FIFO_THRESHOLD. TX FIFO interrupt threshold. when TX FIFO depth <= threshold value, trigger interrupt. */
+#define IR_TX_FIFO_THRESHOLD_Pos (8UL)
+#define IR_TX_FIFO_THRESHOLD_Msk (0x1fUL << IR_TX_FIFO_THRESHOLD_Pos)
+#define IR_TX_FIFO_THRESHOLD_CLR (~IR_TX_FIFO_THRESHOLD_Msk)
+/* TX_CONFIG[6] :IR_TX_IDLE_STATE. TX output State in idle. 0x1: High. 0x0: Low. */
+#define IR_TX_IDLE_STATE_Pos (6UL)
+#define IR_TX_IDLE_STATE_Msk (0x1UL << IR_TX_IDLE_STATE_Pos)
+#define IR_TX_IDLE_STATE_CLR (~IR_TX_IDLE_STATE_Msk)
+/* TX_CONFIG[5] :IR_TX_FIFO_OVER_INT_MASK. TX FIFO empty Interrupt. 0x1: Mask. 0x0: Unmask. */
+#define IR_TX_FIFO_OVER_INT_MASK_Pos (5UL)
+#define IR_TX_FIFO_OVER_INT_MASK_Msk (0x1UL << IR_TX_FIFO_OVER_INT_MASK_Pos)
+#define IR_TX_FIFO_OVER_INT_MASK_CLR (~IR_TX_FIFO_OVER_INT_MASK_Msk)
+/* TX_CONFIG[4] :IR_TX_FIFO_OVER_INT_EN. TX FIFO overflow Interrupt. 0x1: Enable. 0x0: Disable. */
+#define IR_TX_FIFO_OVER_INT_EN_Pos (4UL)
+#define IR_TX_FIFO_OVER_INT_EN_Msk (0x1UL << IR_TX_FIFO_OVER_INT_EN_Pos)
+#define IR_TX_FIFO_OVER_INT_EN_CLR (~IR_TX_FIFO_OVER_INT_EN_Msk)
+#define IR_TX_FIFO_OVER_MSK_TO_EN_Pos (IR_TX_FIFO_OVER_INT_MASK_Pos - IR_TX_FIFO_OVER_INT_EN_Pos)
+/* TX_CONFIG[3] :IR_TX_FIFO_LEVEL_INT_MASK. TX FIFO threshold Interrupt. 0x1: Mask. 0x0: Unmask. */
+#define IR_TX_FIFO_LEVEL_INT_MASK_Pos (3UL)
+#define IR_TX_FIFO_LEVEL_INT_MASK_Msk (0x1UL << IR_TX_FIFO_LEVEL_INT_MASK_Pos)
+#define IR_TX_FIFO_LEVEL_INT_MASK_CLR (~IR_TX_FIFO_LEVEL_INT_MASK_Msk)
+/* TX_CONFIG[2] :IR_TX_FIFO_EMPTY_INT_MASK. TX FIFO empty Interrupt. 0x1: Mask. 0x0: Unmask. */
+#define IR_TX_FIFO_EMPTY_INT_MASK_Pos (2UL)
+#define IR_TX_FIFO_EMPTY_INT_MASK_Msk (0x1UL << IR_TX_FIFO_EMPTY_INT_MASK_Pos)
+#define IR_TX_FIFO_EMPTY_INT_MASK_CLR (~IR_TX_FIFO_EMPTY_INT_MASK_Msk)
+/* TX_CONFIG[1] :IR_TX_FIFO_LEVEL_INT_EN. TX FIFO threshold Interrupt. 0x1: Enable. 0x0: Disable. */
+#define IR_TX_FIFO_LEVEL_INT_EN_Pos (1UL)
+#define IR_TX_FIFO_LEVEL_INT_EN_Msk (0x1UL << IR_TX_FIFO_LEVEL_INT_EN_Pos)
+#define IR_TX_FIFO_LEVEL_INT_EN_CLR (~IR_TX_FIFO_LEVEL_INT_EN_Msk)
+/* TX_CONFIG[0] :IR_TX_FIFO_EMPTY_INT_EN. TX FIFO empty Interrupt. 0x1: Enable. 0x0: Disable. */
+#define IR_TX_FIFO_EMPTY_INT_EN_Pos (0UL)
+#define IR_TX_FIFO_EMPTY_INT_EN_Msk (0x1UL << IR_TX_FIFO_EMPTY_INT_EN_Pos)
+#define IR_TX_FIFO_EMPTY_INT_EN_CLR (~IR_TX_FIFO_EMPTY_INT_EN_Msk)
+#define IR_TX_MSK_TO_EN_Pos (IR_TX_FIFO_EMPTY_INT_MASK_Pos - IR_TX_FIFO_EMPTY_INT_EN_Pos)
+#define IR_TX_STATUS_TO_EN_Pos (IR_TX_FIFO_OVER_INT_EN_Pos - IR_TX_FIFO_EMPTY_INT_MASK_Pos)
+
+/* Register: TX_SR -----------------------------------------------------------*/
+/* Description: TX_SR register. Offset: 0x08. Address: 0x40003008. */
+
+/* TX_SR[15] :IR_TX_FIFO_EMPTY. 0x1: empty. 0x0: not empty. */
+#define IR_TX_FIFO_EMPTY_Pos (15UL)
+#define IR_TX_FIFO_EMPTY_Msk (0x1UL << IR_TX_FIFO_EMPTY_Pos)
+/* TX_SR[14] :IR_TX_FIFO_FULL. 0x1: full. 0x0: not full. */
+#define IR_TX_FIFO_FULL_Pos (14UL)
+#define IR_TX_FIFO_FULL_Msk (0x1UL << IR_TX_FIFO_FULL_Pos)
+/* TX_SR[13:7] :IR_TX_FIFO_OFFSET. */
+#define IR_TX_FIFO_OFFSET_Pos (7UL)
+#define IR_TX_FIFO_OFFSET_Msk (0x3fUL << IR_TX_FIFO_OFFSET_Pos)
+/* TX_SR[4] :IR_TX_STATUS. */
+#define IR_TX_STATUS_Pos (4UL)
+#define IR_TX_STATUS_Msk (0x1UL << IR_TX_STATUS_Pos)
+/* TX_SR[2] :IR_TX_FIFO_OVER_INT_STATUS. */
+#define IR_TX_FIFO_OVER_INT_STATUS_Pos (2UL)
+#define IR_TX_FIFO_OVER_INT_STATUS_Msk (0x1UL << IR_TX_FIFO_OVER_INT_STATUS_Pos)
+/* TX_SR[1] :IR_TX_FIFO_LEVEL_INT_STATUS. */
+#define IR_TX_FIFO_LEVEL_INT_STATUS_Pos (1UL)
+#define IR_TX_FIFO_LEVEL_INT_STATUS_Msk (0x1UL << IR_TX_FIFO_LEVEL_INT_STATUS_Pos)
+/* TX_SR[0] :IR_TX_FIFO_EMPTY_INT_STATUS. */
+#define IR_TX_FIFO_EMPTY_INT_STATUS_Pos (0UL)
+#define IR_TX_FIFO_EMPTY_INT_STATUS_Msk (0x1UL << IR_TX_FIFO_EMPTY_INT_STATUS_Pos)
+
+/* Register: TX_INT_CLR -----------------------------------------------------------*/
+/* Description: TX_INT_CLR register. Offset: 0x10. Address: 0x40003010. */
+
+/* TX_INT_CLR[3] :IR_TX_FIFO_OVER_INT_CLR. Write 1 clear. */
+#define IR_TX_FIFO_OVER_INT_CLR_Pos (3UL)
+#define IR_TX_FIFO_OVER_INT_CLR_Msk (0x1UL << IR_TX_FIFO_OVER_INT_CLR_Pos)
+/* TX_INT_CLR[2] :IR_TX_FIFO_LEVEL_INT_CLR. Write 1 clear. */
+#define IR_TX_FIFO_LEVEL_INT_CLR_Pos (2UL)
+#define IR_TX_FIFO_LEVEL_INT_CLR_Msk (0x1UL << IR_TX_FIFO_LEVEL_INT_CLR_Pos)
+/* TX_INT_CLR[1] :IR_TX_FIFO_EMPTY_INT_CLR. Write 1 clear. */
+#define IR_TX_FIFO_EMPTY_INT_CLR_Pos (1UL)
+#define IR_TX_FIFO_EMPTY_INT_CLR_Msk (0x1UL << IR_TX_FIFO_EMPTY_INT_CLR_Pos)
+/* TX_INT_CLR[0] :IR_TX_FIFO_CLR. Write 1 clear. */
+#define IR_TX_FIFO_CLR_Pos (0UL)
+#define IR_TX_FIFO_CLR_Msk (0x1UL << IR_TX_FIFO_CLR_Pos)
+
+#define IR_INT_ALL_CLR (IR_TX_FIFO_OVER_INT_CLR_Msk | \
+ IR_TX_FIFO_LEVEL_INT_CLR_Msk | \
+ IR_TX_FIFO_EMPTY_INT_CLR_Msk)
+
+/* Register: TX_FIFO ---------------------------------------------------------*/
+/* Description: TX_FIFO register. Offset: 0x14. Address: 0x40003014. */
+
+/* TX_FIFO[31] :IR_DATA_TYPE. 0x1: active carrier. 0x0: incative carrier. */
+#define IR_DATA_TYPE_Pos (31UL)
+#define IR_DATA_TYPE_Msk (0x1UL << IR_DATA_TYPE_Pos)
+#define IR_DATA_TYPE_CLR (~IR_DATA_TYPE_Msk)
+/* TX_FIFO[30] :IR_TX_LAST_PACKEET. 0x1: last packet. 0x0: normal packet. */
+#define IR_TX_LAST_PACKEET_Pos (30UL)
+#define IR_TX_LAST_PACKEET_Msk (0x1UL << IR_TX_LAST_PACKEET_Pos)
+#define IR_TX_LAST_PACKEET_CLR (~IR_TX_LAST_PACKEET_Msk)
+/* TX_FIFO[29:28] :IR_LOW_PERIOD_COMPENSATION */
+#define IR_LOW_PERIOD_COMPENSATION_Pos (28UL)
+#define IR_LOW_PERIOD_COMPENSATION_Msk (0x3UL << IR_LOW_PERIOD_COMPENSATION_Pos)
+#define IR_LOW_PERIOD_COMPENSATION_CLR (~IR_LOW_PERIOD_COMPENSATION_Msk)
+
+/* Register: RX_CONFIG ------------------------------------------------------*/
+/* Description: IR RX CONFIG register. Offset: 0x18. Address: 0x40003018. */
+
+/* RX_CONFIG[28] :IR_RX_START. 0x1: Run. 0x0: Stop. */
+#define IR_RX_START_Pos (28UL)
+#define IR_RX_START_Msk (0x1UL << IR_RX_START_Pos)
+#define IR_RX_START_CLR (~IR_RX_START_Msk)
+/* RX_CONFIG[27] :IR_RX_START_MODE. 0x1: auto mode. 0x0: manual mode. */
+#define IR_RX_START_MODE_Pos (27UL)
+#define IR_RX_START_MODE_Msk (0x1UL << IR_RX_START_MODE_Pos)
+#define IR_RX_START_MODE_CLR (~IR_RX_START_MODE_Msk)
+/* RX_CONFIG[26] :IR_RX_MAN_START. 0x1: Start check waveform. */
+#define IR_RX_MAN_START_Pos (26UL)
+#define IR_RX_MAN_START_Msk (0x1UL << IR_RX_MAN_START_Pos)
+#define IR_RX_MAN_START_CLR (~IR_RX_MAN_START_Msk)
+/* RX_CONFIG[24] :IR_TRIGGER_MODE. 0x1: Run. */
+/* 0x0: high->low trigger. 0x1: low->high trigger. 0x02: high->low or low->high trigger. */
+#define IR_TRIGGER_MODE_Pos (24UL)
+#define IR_TRIGGER_MODE_Msk (0x3UL << IR_TRIGGER_MODE_Pos)
+#define IR_TRIGGER_MODE_CLR (~IR_TRIGGER_MODE_Msk)
+/* RX_CONFIG[21] :IR_FILTER_TIME. */
+#define IR_FILTER_TIME_Pos (21UL)
+#define IR_FILTER_TIME_Msk (0x3UL << IR_FILTER_TIME_Pos)
+#define IR_FILTER_TIME_CLR (~IR_FILTER_TIME_Msk)
+/* RX_CONFIG[19] :IR_RX_FIFO_ERROR_MASK_INT. 0x1: mask. 0x0: unmask.*/
+#define IR_RX_FIFO_ERROR_MASK_INT_Pos (19UL)
+#define IR_RX_FIFO_ERROR_MASK_INT_Msk (0x1UL << IR_RX_FIFO_ERROR_MASK_INT_Pos)
+#define IR_RX_FIFO_ERROR_MASK_INT_CLR (~IR_RX_FIFO_ERROR_MASK_INT_Msk)
+/* RX_CONFIG[18] :IR_RX_CNT_THR_MASK_INT. 0x1: enable. 0x0: disable.*/
+#define IR_RX_CNT_THR_MASK_INT_Pos (18UL)
+#define IR_RX_CNT_THR_MASK_INT_Msk (0x1UL << IR_RX_CNT_THR_MASK_INT_Pos)
+#define IR_RX_CNT_THR_MASK_INT_CLR (~IR_RX_CNT_THR_MASK_INT_Msk)
+/* RX_CONFIG[17] :IR_RX_FIFO_OF_MASK_INT. 0x1: enable. 0x0: disable.*/
+#define IR_RX_FIFO_OF_MASK_INT_Pos (17UL)
+#define IR_RX_FIFO_OF_MASK_INT_Msk (0x1UL << IR_RX_FIFO_OF_MASK_INT_Pos)
+#define IR_RX_FIFO_OF_MASK_INT_CLR (~IR_RX_FIFO_OF_MASK_INT_Msk)
+/* RX_CONFIG[16] :IR_RX_CNT_OF_MASK_INT. 0x1: enable. 0x0: disable.*/
+#define IR_RX_CNT_OF_MASK_INT_Pos (16UL)
+#define IR_RX_CNT_OF_MASK_INT_Msk (0x1UL << IR_RX_CNT_OF_MASK_INT_Pos)
+#define IR_RX_CNT_OF_MASK_INT_CLR (~IR_RX_CNT_OF_MASK_INT_Msk)
+/* RX_CONFIG[15] :IR_RX_FIFO_LEVEL_MASK_INT. 0x1: enable. 0x0: disable.*/
+#define IR_RX_FIFO_LEVEL_MASK_INT_Pos (15UL)
+#define IR_RX_FIFO_LEVEL_MASK_INT_Msk (0x1UL << IR_RX_FIFO_LEVEL_MASK_INT_Pos)
+#define IR_RX_FIFO_LEVEL_MASK_INT_CLR (~IR_RX_FIFO_LEVEL_MASK_INT_Msk)
+/* RX_CONFIG[14] :IR_RX_FIFO_FULL_MASK_INT. 0x1: enable. 0x0: disable.*/
+#define IR_RX_FIFO_FULL_MASK_INT_Pos (14UL)
+#define IR_RX_FIFO_FULL_MASK_INT_Msk (0x1UL << IR_RX_FIFO_FULL_MASK_INT_Pos)
+#define IR_RX_FIFO_FULL_MASK_INT_CLR (~IR_RX_FIFO_FULL_MASK_INT_Msk)
+/* RX_CONFIG[13] :IR_RX_FIFO_DISCARD_SET. 0x1: reject new data send to FIFO. 0x0: discard oldest data in FIFO.*/
+#define IR_RX_FIFO_DISCARD_SET_Pos (13UL)
+#define IR_RX_FIFO_DISCARD_SET_Msk (0x1UL << IR_RX_FIFO_DISCARD_SET_Pos)
+#define IR_RX_FIFO_DISCARD_SET_CLR (~IR_RX_FIFO_DISCARD_SET_Msk)
+/* RX_CONFIG[7] :IR_RX_FIFO_LEVE. */
+#define IR_RX_FIFO_LEVEL_Pos (8UL)
+#define IR_RX_FIFO_LEVEL_Msk (0x1fUL << IR_RX_FIFO_LEVEL_Pos)
+#define IR_RX_FIFO_LEVEL_CLR (~IR_RX_FIFO_LEVEL_Msk)
+/* RX_CONFIG[5] :IR_RX_FIFO_ERROR_INT. 0x1: enable. 0x0: disable.*/
+#define IR_RX_FIFO_ERROR_INT_Pos (5UL)
+#define IR_RX_FIFO_ERROR_INT_Msk (0x1UL << IR_RX_FIFO_ERROR_INT_Pos)
+#define IR_RX_FIFO_ERROR_INT_CLR (~IR_RX_FIFO_ERROR_INT_Msk)
+/* RX_CONFIG[4] :IR_RX_CNT_THR_INT. 0x1: enable. 0x0: disable.*/
+#define IR_RX_CNT_THR_INT_Pos (4UL)
+#define IR_RX_CNT_THR_INT_Msk (0x1UL << IR_RX_CNT_THR_INT_Pos)
+#define IR_RX_CNT_THR_INT_CLR (~IR_RX_CNT_THR_INT_Msk)
+/* RX_CONFIG[3] :IR_RX_FIFO_OF_INT. 0x1: enable. 0x0: disable.*/
+#define IR_RX_FIFO_OF_INT_Pos (3UL)
+#define IR_RX_FIFO_OF_INT_Msk (0x1UL << IR_RX_FIFO_OF_INT_Pos)
+#define IR_RX_FIFO_OF_INT_CLR (~IR_RX_FIFO_OF_INT_Msk)
+/* RX_CONFIG[2] :IR_RX_CNT_OF_INT. 0x1: enable. 0x0: disable.*/
+#define IR_RX_CNT_OF_INT_Pos (2UL)
+#define IR_RX_CNT_OF_INT_Msk (0x1UL << IR_RX_CNT_OF_INT_Pos)
+#define IR_RX_CNT_OF_INT_CLR (~IR_RX_CNT_OF_INT_Msk)
+/* RX_CONFIG[1] :IR_RX_FIFO_LEVEL_INT. 0x1: enable. 0x0: disable.*/
+#define IR_RX_FIFO_LEVEL_INT_Pos (1UL)
+#define IR_RX_FIFO_LEVEL_INT_Msk (0x1UL << IR_RX_FIFO_LEVEL_INT_Pos)
+#define IR_RX_FIFO_LEVEL_INT_CLR (~IR_RX_FIFO_LEVEL_INT_Msk)
+/* RX_CONFIG[0] :IR_RX_FIFO_FULL_INT. 0x1: enable. 0x0: disable.*/
+#define IR_RX_FIFO_FULL_INT_Pos (0UL)
+#define IR_RX_FIFO_FULL_INT_Msk (0x1UL << IR_RX_FIFO_FULL_INT_Pos)
+#define IR_RX_FIFO_FULL_INT_CLR (~IR_RX_FIFO_FULL_INT_Msk)
+#define IR_RX_MSK_TO_EN_Pos (IR_RX_FIFO_FULL_MASK_INT_Pos - IR_RX_FIFO_FULL_INT_Pos)
+
+#define IR_RX_MASK_ALL_INT (IR_RX_FIFO_ERROR_MASK_INT_Msk | IR_RX_CNT_THR_MASK_INT_Msk | \
+ IR_RX_FIFO_OF_MASK_INT_Msk | IR_RX_CNT_OF_MASK_INT_Msk | \
+ IR_RX_FIFO_LEVEL_MASK_INT_Msk | IR_RX_FIFO_FULL_MASK_INT_Msk)
+
+/* Register: RX_SR -----------------------------------------------------------*/
+/* Description: RX_SR register. Offset: 0x1C. Address: 0x4000301C. */
+
+/* RX_SR[17] :IR_TX_FIFO_EMPTY. 0x1: empty. 0x0: not empty. */
+#define IR_RX_FIFO_EMPTY_Pos (17UL)
+#define IR_RX_FIFO_EMPTY_Msk (0x1UL << IR_RX_FIFO_EMPTY_Pos)
+/* RX_SR[8] :IR_RX_FIFO_OFFSET. */
+#define IR_RX_FIFO_OFFSET_Pos (8UL)
+#define IR_RX_FIFO_OFFSET_Msk (0x3fUL << IR_RX_FIFO_OFFSET_Pos)
+#define IR_RX_FIFO_OFFSET_CLR (~IR_RX_FIFO_OFFSET_Msk)
+/* RX_SR[7] :IR_RX_STATUS. */
+#define IR_RX_STATUS_Pos (7UL)
+#define IR_RX_STATUS_Msk (0x1UL << IR_RX_STATUS_Pos)
+
+/* Register: RX_INT_CLR -----------------------------------------------------------*/
+/* Description: RX_INT_CLR register. Offset: 0x20. Address: 0x40003020. */
+
+/* RX_INT_CLR[8] :IR_RX_FIFO_CLR. Write 1 clear. */
+#define IR_RX_FIFO_CLR_Pos (8UL)
+#define IR_RX_FIFO_CLR_Msk (0x1UL << IR_RX_FIFO_CLR_Pos)
+/* RX_INT_CLR[5] :IR_RX_FIFO_ERROR_INT_CLR. Write 1 clear. */
+#define IR_RX_FIFO_ERROR_INT_CLR_Pos (5UL)
+#define IR_RX_FIFO_ERROR_INT_CLR_Msk (0x1UL << IR_RX_FIFO_ERROR_INT_CLR_Pos)
+/* RX_INT_CLR[4] :IR_RX_CNT_THR_INT_CLR. Write 1 clear. */
+#define IR_RX_CNT_THR_INT_CLR_Pos (4UL)
+#define IR_RX_CNT_THR_INT_CLR_Msk (0x1UL << IR_RX_CNT_THR_INT_CLR_Pos)
+/* RX_INT_CLR[3] :IR_RX_FIFO_OF_INT_CLR. Write 1 clear. */
+#define IR_RX_FIFO_OF_INT_CLR_Pos (3UL)
+#define IR_RX_FIFO_OF_INT_CLR_Msk (0x1UL << IR_RX_FIFO_OF_INT_CLR_Pos)
+/* RX_INT_CLR[2] :IR_RX_CNT_OF_INT_CLR. Write 1 clear. */
+#define IR_RX_CNT_OF_INT_CLR_Pos (2UL)
+#define IR_RX_CNT_OF_INT_CLR_Msk (0x1UL << IR_RX_CNT_OF_INT_CLR_Pos)
+/* RX_INT_CLR[1] :IR_RX_FIFO_LEVEL_INT_CLR. Write 1 clear. */
+#define IR_RX_FIFO_LEVEL_INT_CLR_Pos (1UL)
+#define IR_RX_FIFO_LEVEL_INT_CLR_Msk (0x1UL << IR_RX_FIFO_LEVEL_INT_CLR_Pos)
+/* RX_INT_CLR[0] :IR_RX_FIFO_FULL_INT_CLR. Write 1 clear. */
+#define IR_RX_FIFO_FULL_INT_CLR_Pos (0UL)
+#define IR_RX_FIFO_FULL_INT_CLR_Msk (0x1UL << IR_RX_FIFO_FULL_INT_CLR_Pos)
+
+#define IR_RX_INT_ALL_CLR (IR_RX_FIFO_CLR_Msk | IR_RX_FIFO_ERROR_INT_CLR_Msk | \
+ IR_RX_CNT_THR_INT_CLR_Msk | IR_RX_FIFO_OF_INT_CLR_Msk | \
+ IR_RX_CNT_OF_INT_CLR_Msk | IR_RX_FIFO_LEVEL_INT_CLR_Msk | \
+ IR_RX_FIFO_FULL_INT_CLR_Msk)
+
+/* Register: RX_CNT_INT_SEL -------------------------------------------------*/
+/* Description: IR RX counter interrupt setting register. Offset: 0x24. Address: 0x40003024. */
+
+/* RX_CNT_INT_SEL[31] :IR_RX_CNT_THR_TRIGGER_LV. */
+/* 0x1: high level couner >= threshlod trigger interrupt. 0x0: low level couner >= threshlod trigger interrupt. */
+#define IR_RX_CNT_THR_TYPE_Pos (31UL)
+#define IR_RX_CNT_THR_TYPE_Msk (0x1UL << IR_RX_CNT_THR_TYPE_Pos)
+#define IR_RX_CNT_THR_TYPE_CLR (~IR_RX_CNT_THR_TYPE_Msk)
+/* RX_CNT_INT_SEL[30:0] :IR_RX_CNT_THR. */
+#define IR_RX_CNT_THR_Pos (0UL)
+#define IR_RX_CNT_THR_Msk (0x7fffffffUL << IR_RX_CNT_THR_Pos)
+#define IR_RX_CNT_THR_CLR (~IR_RX_CNT_THR_Msk)
+
+/* Register: RX_INT_CR -------------------------------------------------*/
+/* Description: IR RX interrupt config register. Offset: 0x34. Address: 0x40003034. */
+
+/* RX_INT_CR[7] :IR_RX_RISING_EDGE_INT_CLR. */
+#define IR_RX_RISING_EDGE_INT_CLR_Pos (7UL)
+#define IR_RX_RISING_EDGE_INT_CLR_Msk (0x1UL << IR_RX_RISING_EDGE_INT_CLR_Pos)
+#define IR_RX_RISING_EDGE_INT_CLR_CLR (~IR_RX_RISING_EDGE_INT_CLR_Msk)
+/* RX_INT_CR[6] :IR_RX_FALLING_EDGE_INT_CLR. */
+#define IR_RX_FALLING_EDGE_INT_CLR_Pos (6UL)
+#define IR_RX_FALLING_EDGE_INT_CLR_Msk (0x1UL << IR_RX_FALLING_EDGE_INT_CLR_Pos)
+#define IR_RX_FALLING_EDGE_INT_CLR_CLR (~IR_RX_FALLING_EDGE_INT_CLR_Msk)
+/* RX_INT_CR[5] :IR_RX_RISING_EDGE_INT_STATUS. */
+#define IR_RX_RISING_EDGE_INT_STATUS_Pos (5UL)
+#define IR_RX_RISING_EDGE_INT_STATUS_Msk (0x1UL << IR_RX_RISING_EDGE_INT_STATUS_Pos)
+#define IR_RX_RISING_EDGE_INT_STATUS_CLR (~IR_RX_RISING_EDGE_INT_STATUS_Msk)
+/* RX_INT_CR[4] :IR_RX_FALLING_EDGE_INT_STATUS. */
+#define IR_RX_FALLING_EDGE_INT_STATUS_Pos (4UL)
+#define IR_RX_FALLING_EDGE_INT_STATUS_Msk (0x1UL << IR_RX_FALLING_EDGE_INT_STATUS_Pos)
+#define IR_RX_FALLING_EDGE_INT_STATUS_CLR (~IR_RX_FALLING_EDGE_INT_STATUS_Msk)
+/* RX_INT_CR[3] :IR_RX_RISING_EDGE_INT_MASK. */
+#define IR_RX_RISING_EDGE_INT_MASK_Pos (3UL)
+#define IR_RX_RISING_EDGE_INT_MASK_Msk (0x1UL << IR_RX_RISING_EDGE_INT_MASK_Pos)
+#define IR_RX_RISING_EDGE_INT_MASK_CLR (~IR_RX_RISING_EDGE_INT_MASK_Msk)
+/* RX_INT_CR[2] :IR_RX_FALLING_EDGE_INT_MASK. */
+#define IR_RX_FALLING_EDGE_INT_MASK_Pos (2UL)
+#define IR_RX_FALLING_EDGE_INT_MASK_Msk (0x1UL << IR_RX_FALLING_EDGE_INT_MASK_Pos)
+#define IR_RX_FALLING_EDGE_INT_MASK_CLR (~IR_RX_FALLING_EDGE_INT_MASK_Msk)
+/* RX_INT_CR[1] :IR_RX_RISING_EDGE_INT_EN. */
+#define IR_RX_RISING_EDGE_INT_EN_Pos (1UL)
+#define IR_RX_RISING_EDGE_INT_EN_Msk (0x1UL << IR_RX_RISING_EDGE_INT_EN_Pos)
+#define IR_RX_RISING_EDGE_INT_EN_CLR (~IR_RX_RISING_EDGE_INT_EN_Msk)
+/* RX_INT_CR[0] :IR_RX_FALLING_EDGE_INT_EN. */
+#define IR_RX_FALLING_EDGE_INT_EN_Pos (0UL)
+#define IR_RX_FALLING_EDGE_INT_EN_Msk (0x1UL << IR_RX_FALLING_EDGE_INT_EN_Pos)
+#define IR_RX_FALLING_EDGE_INT_EN_CLR (~IR_RX_FALLING_EDGE_INT_EN_Msk)
+
+#define IR_RX_EXTENSION_INT 0x8000
+
+/* Register: IR_TX_COMPE -------------------------------------------------*/
+/* Description: IR TX compensation register. Offset: 0x48. Address: 0x40003048. */
+
+/* IR_TX_COMPE[29:16] : IR_TX_COMPENSATION. */
+#define IR_TX_COMPENSATION_Pos (16UL)
+#define IR_TX_COMPENSATION_Msk (0x3FFFUL << IR_TX_COMPENSATION_Pos)
+#define IR_TX_COMPENSATION_CLR (~IR_TX_COMPENSATION_Msk)
+
+/* Register: DMA_CONFIG -------------------------------------------------*/
+/* Description: IR dma config register. Offset: 0x50. Address: 0x40003050. */
+
+/* DMA_CONFIG[0] : IR_TX_DMA_ENABLE. */
+#define IR_TX_DMA_EN_Pos (0UL)
+#define IR_TX_DMA_EN_Msk (0x1UL << IR_TX_DMA_EN_Pos)
+#define IR_TX_DMA_EN_CLR (~IR_TX_DMA_EN_Msk)
+/* DMA_CONFIG[6:1] : IR_TX_WATER_LEVEL. */
+#define IR_TX_WATER_LEVEL_Pos (1UL)
+#define IR_TX_WATER_LEVEL_Msk (0x3FUL << IR_TX_WATER_LEVEL_Pos)
+#define IR_TX_WATER_LEVEL_CLR (~IR_TX_WATER_LEVEL_Msk)
+/* DMA_CONFIG[8] : IR_RX_DMA_ENABLE. */
+#define IR_RX_DMA_EN_Pos (8UL)
+#define IR_RX_DMA_EN_Msk (0x1UL << IR_RX_DMA_EN_Pos)
+#define IR_RX_DMA_EN_CLR (~IR_RX_DMA_EN_Msk)
+/* DMA_CONFIG[14:9] : IR_RX_WATER_LEVEL. */
+#define IR_RX_WATER_LEVEL_Pos (9UL)
+#define IR_RX_WATER_LEVEL_Msk (0x3FUL << IR_RX_WATER_LEVEL_Pos)
+#define IR_RX_WATER_LEVEL_CLR (~IR_RX_WATER_LEVEL_Msk)
+
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup IR_Exported_Constants Marco Defines
+ *
+ * \ingroup IR
+ */
+
+#define IS_IR_PERIPH(PERIPH) ((PERIPH) == IR)
+#define IR_TX_FIFO_SIZE 32
+#define IR_RX_FIFO_SIZE 32
+
+/** \defgroup IR_CLOCK IR Clock
+ * \{
+ * \ingroup IR_Exported_Constants
+ */
+#define IR_CLOCK_40M (40000000)
+#define IR_CLOCK_90M (90000000)
+#define IR_CLOCK_100M (100000000)
+/** \} */
+
+#define IS_IR_CLOCK(CLK) (((CLK) == IR_CLOCK_40M)\
+ || ((CLK) == IR_CLOCK_90M)\
+ || ((CLK) == IR_CLOCK_100M))
+
+#define IS_IR_FREQUENCY_40M(F) (((F) >= 2442) && ((F) <= 2000000))
+#define IS_IR_FREQUENCY_90M(F) (((F) >= 5494) && ((F) <= 2000000))
+#define IS_IR_FREQUENCY_100M(F) (((F) >= 6104) && ((F) <= 2000000))
+
+/**
+ * \defgroup IR_Mode IR Mode
+ * \{
+ * \ingroup IR_Exported_Constants
+ */
+#define IR_MODE_TX ((uint32_t)((uint32_t)0x0 << IR_MODE_SEL_Pos))
+#define IR_MODE_RX ((uint32_t)((uint32_t)0x1 << IR_MODE_SEL_Pos))
+/** \} */
+
+#define IS_IR_MODE(MODE) (((MODE) == IR_MODE_TX) || ((MODE) == IR_MODE_RX))
+
+/**
+ * \defgroup IR_Idle_Status IR Idle Status
+ * \{
+ * \ingroup IR_Exported_Constants
+ */
+
+#define IR_IDLE_OUTPUT_HIGH ((uint32_t)(0x01 << IR_TX_IDLE_STATE_Pos))
+#define IR_IDLE_OUTPUT_LOW ((uint32_t)(0x00 << IR_TX_IDLE_STATE_Pos))
+/** \} */
+
+#define IS_IR_IDLE_STATUS(LEVEL) (((LEVEL) == IR_IDLE_OUTPUT_HIGH) || ((LEVEL) == IR_IDLE_OUTPUT_LOW))
+
+/**
+ * \defgroup IR_TX_Data_Type IR TX Data Type
+ * \{
+ * \ingroup IR_Exported_Constants
+ */
+
+#define IR_TX_DATA_NORMAL ((uint32_t)(0 << IR_FIFO_INVERSE_Pos))
+#define IR_TX_DATA_INVERSE ((uint32_t)(1 << IR_FIFO_INVERSE_Pos))
+/** \} */
+
+#define IS_IR_TX_DATA_TYPE(TYPE) (((TYPE) == IR_TX_DATA_NORMAL) || ((TYPE) == IR_TX_DATA_INVERSE))
+
+/**
+ * \def IR_Tx_Threshold IR TX Threshold
+ */
+#define IS_IR_TX_THRESHOLD(THD) ((THD) <= IR_TX_FIFO_SIZE)
+
+/**
+ * \def IR_Rx_Threshold IR RX Threshold
+ */
+#define IS_IR_RX_THRESHOLD(THD) ((THD) <= IR_RX_FIFO_SIZE)
+
+/**
+ * \defgroup IR_Rx_Start_Mode RX Start Mode
+ * \{
+ * \ingroup IR_Exported_Constants
+ */
+#define IR_RX_AUTO_MODE ((uint32_t)((0x1) << IR_RX_START_MODE_Pos))
+#define IR_RX_MANUAL_MODE ((uint32_t)((0x0) << IR_RX_START_MODE_Pos))
+/** \} */
+
+#define IS_RX_START_MODE(MODE) (((MODE) == IR_RX_AUTO_MODE) || ((MODE) == IR_RX_MANUAL_MODE))
+
+
+/**
+ * \defgroup IR_RX_Trigger_Mode RX Trigger Mode
+ * \{
+ * \ingroup IR_Exported_Constants
+ */
+#define IR_RX_FALL_EDGE ((uint32_t)((0x0) << IR_TRIGGER_MODE_Pos))
+#define IR_RX_RISING_EDGE ((uint32_t)((0x1) << IR_TRIGGER_MODE_Pos))
+#define IR_RX_DOUBLE_EDGE ((uint32_t)((0x2) << IR_TRIGGER_MODE_Pos))
+/** \} */
+
+#define IS_RX_RX_TRIGGER_EDGE(EDGE) (((EDGE) == IR_RX_FALL_EDGE) || ((EDGE) == IR_RX_RISING_EDGE) || ((EDGE) == IR_RX_DOUBLE_EDGE))
+
+/**
+ * \defgroup IR_RX_FIFO_DISCARD_SETTING IR RX FIFO Discard Setting
+ * \{
+ * \ingroup IR_Exported_Constants
+ */
+
+#define IR_RX_FIFO_FULL_DISCARD_NEWEST ((uint32_t)(0 << IR_RX_FIFO_DISCARD_SET_Pos))
+#define IR_RX_FIFO_FULL_DISCARD_OLDEST ((uint32_t)(1 << IR_RX_FIFO_DISCARD_SET_Pos))
+/** \} */
+
+#define IS_IR_RX_FIFO_FULL_CTRL(CTRL) (((CTRL) == IR_RX_FIFO_FULL_DISCARD_NEWEST) || ((CTRL) == IR_RX_FIFO_FULL_DISCARD_OLDEST))
+
+/**
+ * \defgroup IR_RX_Filter_Time RX Filter Time
+ * \{
+ * \ingroup IR_Exported_Constants
+ */
+#define IR_RX_FILTER_TIME_50ns ((uint32_t)((0x0) << IR_FILTER_TIME_Pos))
+#define IR_RX_FILTER_TIME_75ns ((uint32_t)((0x2) << IR_FILTER_TIME_Pos))
+#define IR_RX_FILTER_TIME_100ns ((uint32_t)((0x3) << IR_FILTER_TIME_Pos))
+#define IR_RX_FILTER_TIME_125ns ((uint32_t)((0x4) << IR_FILTER_TIME_Pos))
+#define IR_RX_FILTER_TIME_150ns ((uint32_t)((0x5) << IR_FILTER_TIME_Pos))
+#define IR_RX_FILTER_TIME_175ns ((uint32_t)((0x6) << IR_FILTER_TIME_Pos))
+#define IR_RX_FILTER_TIME_200ns ((uint32_t)((0x7) << IR_FILTER_TIME_Pos))
+/** \} */
+
+#define IS_IR_RX_FILTER_TIME_CTRL(CTRL) (((CTRL) == IR_RX_FILTER_TIME_50ns) || \
+ ((CTRL) == IR_RX_FILTER_TIME_75ns) || \
+ ((CTRL) == IR_RX_FILTER_TIME_100ns) || \
+ ((CTRL) == IR_RX_FILTER_TIME_125ns) || \
+ ((CTRL) == IR_RX_FILTER_TIME_150ns) || \
+ ((CTRL) == IR_RX_FILTER_TIME_175ns) || \
+ ((CTRL) == IR_RX_FILTER_TIME_200ns))
+/**
+ * \defgroup IR_RX_COUNTER_THRESHOLD_TYPE IR RX Counter Threshold Type
+ * \{
+ * \ingroup IR_Exported_Constants
+ */
+
+#define IR_RX_Count_Low_Level ((uint32_t)0 << IR_RX_CNT_THR_TYPE_Pos)
+#define IR_RX_Count_High_Level ((uint32_t)1 << IR_RX_CNT_THR_TYPE_Pos)
+/** \} */
+
+#define IS_IR_RX_COUNT_LEVEL_CTRL(CTRL) (((CTRL) == IR_RX_Count_Low_Level) || ((CTRL) == IR_RX_Count_High_Level))
+
+/**
+ * \def IR_Rx_Counter_Threshold IR RX Counter Threshold
+ */
+#define IS_IR_RX_COUNTER_THRESHOLD(THD) ((THD) <= IR_RX_CNT_THR_Msk)
+
+/**
+ * \defgroup IR_Interrupt_Definition IR Interrupt Definition
+ * \{
+ * \ingroup IR_Exported_Constants
+ */
+/* All interrupts in transmission mode */
+#define IR_INT_TF_EMPTY ((uint32_t)IR_TX_FIFO_EMPTY_INT_EN_Msk)
+#define IR_INT_TF_LEVEL ((uint32_t)IR_TX_FIFO_LEVEL_INT_EN_Msk)
+#define IR_INT_TF_OF ((uint32_t)IR_TX_FIFO_OVER_INT_EN_Msk)
+/* All interrupts in receiving mode */
+#define IR_INT_RF_FULL ((uint32_t)IR_RX_FIFO_FULL_INT_Msk)
+#define IR_INT_RF_LEVEL ((uint32_t)IR_RX_FIFO_LEVEL_INT_Msk)
+#define IR_INT_RX_CNT_OF ((uint32_t)IR_RX_CNT_OF_INT_Msk)
+#define IR_INT_RF_OF ((uint32_t)IR_RX_FIFO_OF_INT_Msk)
+#define IR_INT_RX_CNT_THR ((uint32_t)IR_RX_CNT_THR_INT_Msk)
+#define IR_INT_RF_ERROR ((uint32_t)IR_RX_FIFO_ERROR_INT_Msk)
+#define IR_INT_RISING_EDGE ((uint32_t)(IR_RX_EXTENSION_INT | IR_RX_RISING_EDGE_INT_EN_Msk))
+#define IR_INT_FALLING_EDGE ((uint32_t)(IR_RX_EXTENSION_INT | IR_RX_FALLING_EDGE_INT_EN_Msk))
+/** \} */
+
+#define IS_IR_TX_INT_CONFIG(CONFIG) (((CONFIG) == IR_INT_TF_EMPTY) || \
+ ((CONFIG) == IR_INT_TF_LEVEL) || \
+ ((CONFIG) == IR_INT_TF_OF))
+
+#define IS_IR_RX_INT_CONFIG(CONFIG) (((CONFIG) == IR_INT_RF_FULL) || \
+ ((CONFIG) == IR_INT_RF_LEVEL) || \
+ ((CONFIG) == IR_INT_RX_CNT_OF) || \
+ ((CONFIG) == IR_INT_RF_OF) || \
+ ((CONFIG) == IR_INT_RX_CNT_THR) || \
+ ((CONFIG) == IR_INT_RF_OF) || \
+ ((CONFIG) == IR_INT_RISING_EDGE) || \
+ ((CONFIG) == IR_INT_FALLING_EDGE))
+#define IS_IR_INT_CONFIG(CONFIG) (IS_IR_TX_INT_CONFIG(CONFIG) || IS_IR_RX_INT_CONFIG(CONFIG))
+
+/**
+ * \defgroup IR_Interrupts_Clear_Flag IR Interrupts Clear Flag
+ * \{
+ * \ingroup IR_Exported_Constants
+ */
+/* Clear all interrupts in transmission mode */
+#define IR_INT_TF_EMPTY_CLR ((uint32_t)IR_TX_FIFO_EMPTY_INT_CLR_Msk)
+#define IR_INT_TF_LEVEL_CLR ((uint32_t)IR_TX_FIFO_LEVEL_INT_CLR_Msk)
+#define IR_INT_TF_OF_CLR ((uint32_t)IR_TX_FIFO_OVER_INT_CLR_Msk)
+/* Clear all interrupts in receiving mode */
+#define IR_INT_RF_FULL_CLR ((uint32_t)IR_RX_FIFO_FULL_INT_CLR_Msk)
+#define IR_INT_RF_LEVEL_CLR ((uint32_t)IR_RX_FIFO_LEVEL_INT_CLR_Msk)
+#define IR_INT_RX_CNT_OF_CLR ((uint32_t)IR_RX_CNT_OF_INT_CLR_Msk)
+#define IR_INT_RF_OF_CLR ((uint32_t)IR_RX_FIFO_OF_INT_CLR_Msk)
+#define IR_INT_RX_CNT_THR_CLR ((uint32_t)IR_RX_CNT_THR_INT_CLR_Msk)
+#define IR_INT_RF_ERROR_CLR ((uint32_t)IR_RX_FIFO_ERROR_INT_CLR_Msk)
+#define IR_INT_RX_RISING_EDGE_CLR ((uint32_t)(IR_RX_EXTENSION_INT | IR_RX_RISING_EDGE_INT_CLR_Msk))
+#define IR_INT_RX_FALLING_EDGE_CLR ((uint32_t)(IR_RX_EXTENSION_INT | IR_RX_FALLING_EDGE_INT_CLR_Msk))
+#define IR_RF_CLR ((uint32_t)IR_RX_FIFO_CLR_Msk)
+/** \} */
+
+#define IS_IR_INT_CLEAR(INT) (((INT) == IR_INT_TF_EMPTY_CLR) || ((INT) == IR_INT_TF_LEVEL_CLR) || \
+ ((INT) == IR_INT_TF_OF_CLR) || ((INT) == IR_INT_RF_FULL_CLR) || \
+ ((INT) == IR_INT_RF_LEVEL_CLR) || ((INT) == IR_INT_RX_CNT_OF_CLR) || \
+ ((INT) == IR_INT_RF_OF_CLR) || ((INT) == IR_INT_RX_CNT_THR_CLR) || \
+ ((INT) == IR_INT_RX_RISING_EDGE_CLR) || ((INT) == IR_INT_RX_FALLING_EDGE_CLR) || \
+ ((INT) == IR_INT_RF_ERROR_CLR))
+
+/**
+ * \defgroup IR_Flag IR Flag
+ * \{
+ * \ingroup IR_Exported_Constants
+ */
+#define IR_FLAG_TF_EMPTY ((uint32_t)IR_TX_FIFO_EMPTY_Msk)
+#define IR_FLAG_TF_FULL ((uint32_t)IR_TX_FIFO_FULL_Msk)
+#define IR_FLAG_TX_RUN ((uint32_t)IR_TX_STATUS_Msk)
+#define IR_FLAG_RF_EMPTY ((uint32_t)IR_RX_FIFO_EMPTY_Msk)
+#define IR_FLAG_RX_RUN ((uint32_t)IR_RX_STATUS_Msk)
+/** \} */
+
+#define IS_IR_FLAG(FLAG) (((FLAG) == IR_FLAG_TF_EMPTY) || ((FLAG) == IR_FLAG_TF_FULL) || \
+ ((FLAG) == IR_FLAG_TX_RUN) || ((FLAG) == IR_FLAG_RF_EMPTY) || \
+ ((FLAG) == IR_FLAG_RX_RUN))
+/**
+ * \enum IR_Compensation_Flag IR Compensation Flag
+ * \ingroup IR_Exported_Constants
+ */
+typedef enum
+{
+ IR_COMPEN_FLAG_1_2_CARRIER = ((uint32_t)(1 << IR_LOW_PERIOD_COMPENSATION_Pos)),
+ IR_COMPEN_FLAG_1_4_CARRIER = ((uint32_t)(2 << IR_LOW_PERIOD_COMPENSATION_Pos)),
+ IR_COMPEN_FLAG_1_N_SYSTEM_CLK = ((uint32_t)(3 << IR_LOW_PERIOD_COMPENSATION_Pos)),
+} IR_TX_COMPEN_TYPE;
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup IR_Exported_Functions Peripheral APIs
+ * \{
+ * \ingroup IR
+ */
+
+/**
+ * \brief Deinitializes the IR peripheral registers to their default values.
+ * \param None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_ir_init(void)
+ * {
+ * IR_DeInit();
+ * }
+ * \endcode
+ */
+void IR_DeInit(void);
+
+/**
+ * \brief Initializes the IR peripheral according to the specified
+ * parameters in IR_InitStruct.
+ * \param[in] IR_InitStruct: Pointer to a IR_InitTypeDef structure that
+ * contains the configuration information for the specified IR peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_ir_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, ENABLE);
+
+ * IR_InitTypeDef IR_InitStruct;
+ * IR_StructInit(&IR_InitStruct);
+
+ * IR_InitStruct.IR_Freq = 38000;// IR carrier freqency is 38KHz
+ * IR_InitStruct.IR_Mode = IR_MODE_RX;// IR receiveing mode
+ * IR_InitStruct.IR_RxStartMode = IR_RX_AUTO_MODE;
+ * IR_InitStruct.IR_RxFIFOThrLevel =
+ IR_RX_FIFO_THR_LEVEL; // Configure RX FIFO threshold level to trigger IR_INT_RF_LEVEL interrupt
+ * IR_InitStruct.IR_RxFIFOFullCtrl =
+ * IR_RX_FIFO_FULL_DISCARD_NEWEST;// Discard the latest received dta if RX FIFO is full
+ * IR_InitStruct.IR_RxFilterTime =
+ IR_RX_FILTER_TIME_50ns;// If high to low or low to high transition time <= 50ns,Filter out it.
+ * IR_InitStruct.IR_RxTriggerMode = IR_RX_FALL_EDGE;// Configure trigger type
+ * IR_InitStruct.IR_RxCntThrType =
+ IR_RX_Count_High_Level;// IR_RX_Count_High_Level is counting high level
+ * IR_InitStruct.IR_RxCntThr =
+ 0x1F40;// Configure RX counter threshold.You can use it to decide to stop receiving IR data
+ * IR_Init(&IR_InitStruct);
+ * IR_Cmd(IR_MODE_RX, ENABLE);
+ * IR_ClearRxFIFO();
+ * }
+ * \endcode
+ */
+void IR_Init(IR_InitTypeDef *IR_InitStruct);
+
+/**
+ * \brief Fills each IR_InitStruct member with its default value.
+ * \param[in] IR_InitStruct: Pointer to an IR_InitTypeDef structure which will be initialized.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_ir_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, ENABLE);
+
+ * IR_InitTypeDef IR_InitStruct;
+ * IR_StructInit(&IR_InitStruct);
+
+ * IR_InitStruct.IR_Freq = 38000;// IR carrier freqency is 38KHz
+ * IR_InitStruct.IR_Mode = IR_MODE_RX;// IR receiveing mode
+ * IR_InitStruct.IR_RxStartMode = IR_RX_AUTO_MODE;
+ * IR_InitStruct.IR_RxFIFOThrLevel =
+ IR_RX_FIFO_THR_LEVEL; // Configure RX FIFO threshold level to trigger IR_INT_RF_LEVEL interrupt
+ * IR_InitStruct.IR_RxFIFOFullCtrl =
+ * IR_RX_FIFO_FULL_DISCARD_NEWEST;// Discard the latest received dta if RX FIFO is full
+ * IR_InitStruct.IR_RxFilterTime =
+ IR_RX_FILTER_TIME_50ns;// If high to low or low to high transition time <= 50ns,Filter out it.
+ * IR_InitStruct.IR_RxTriggerMode = IR_RX_FALL_EDGE;// Configure trigger type
+ * IR_InitStruct.IR_RxCntThrType =
+ IR_RX_Count_High_Level;// IR_RX_Count_High_Level is counting high level
+ * IR_InitStruct.IR_RxCntThr =
+ 0x1F40;// Configure RX counter threshold.You can use it to decide to stop receiving IR data
+ * IR_Init(&IR_InitStruct);
+ * IR_Cmd(IR_MODE_RX, ENABLE);
+ * IR_ClearRxFIFO();
+ * }
+ * \endcode
+ */
+void IR_StructInit(IR_InitTypeDef *IR_InitStruct);
+
+/**
+ * \brief Enable or disable the selected IR mode.
+ * \param[in] mode: Selected IR operation mode.
+ * This parameter can be one of the following values:
+ * \arg IR_MODE_TX: Transmission mode.
+ * \arg IR_MODE_RX: Receiving mode.
+ * \param[in] NewState: New state of the operation mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_ir_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, ENABLE);
+
+ * IR_InitTypeDef IR_InitStruct;
+ * IR_StructInit(&IR_InitStruct);
+
+ * IR_InitStruct.IR_Freq = 38000;// IR carrier freqency is 38KHz
+ * IR_InitStruct.IR_Mode = IR_MODE_RX;// IR receiveing mode
+ * IR_InitStruct.IR_RxStartMode = IR_RX_AUTO_MODE;
+ * IR_InitStruct.IR_RxFIFOThrLevel =
+ IR_RX_FIFO_THR_LEVEL; // Configure RX FIFO threshold level to trigger IR_INT_RF_LEVEL interrupt
+ * IR_InitStruct.IR_RxFIFOFullCtrl =
+ * IR_RX_FIFO_FULL_DISCARD_NEWEST;// Discard the latest received dta if RX FIFO is full
+ * IR_InitStruct.IR_RxFilterTime =
+ IR_RX_FILTER_TIME_50ns;// If high to low or low to high transition time <= 50ns,Filter out it.
+ * IR_InitStruct.IR_RxTriggerMode = IR_RX_FALL_EDGE;// Configure trigger type
+ * IR_InitStruct.IR_RxCntThrType =
+ IR_RX_Count_High_Level;// IR_RX_Count_High_Level is counting high level
+ * IR_InitStruct.IR_RxCntThr =
+ 0x1F40;// Configure RX counter threshold.You can use it to decide to stop receiving IR data
+ * IR_Init(&IR_InitStruct);
+ * IR_Cmd(IR_MODE_RX, ENABLE);
+ * IR_ClearRxFIFO();
+ * }
+ * \endcode
+ */
+void IR_Cmd(uint32_t mode, FunctionalState NewState);
+
+/**
+ * \brief Start trigger receive, only in manual receive mode.
+ * \param None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * IR_StartManualRxTrigger();
+ * }
+ * \endcode
+ */
+void IR_StartManualRxTrigger(void);
+
+/**
+ * \brief Config counter threshold value in receiving mode.You can use it to stop receiving IR data.
+ * \param[in] IR_RxCntThrType: Count threshold type.
+ * This parameter can be the following values:
+ * \arg IR_RX_Count_Low_Level: Low level counter value >= IR_RxCntThr, trigger IR_INT_RX_CNT_THR interrupt.
+ * \arg IR_RX_Count_High_Level: High level counter value >= IR_RxCntThr, trigger IR_INT_RX_CNT_THR interrupt.
+ * \param[in] IR_RxCntThr: Configure IR Rx counter threshold value which can be 0 to 0x7fffffffUL.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * IR_SetRxCounterThreshold(IR_RX_Count_Low_Level, 0x100);
+ * }
+ * \endcode
+ */
+void IR_SetRxCounterThreshold(uint32_t IR_RxCntThrType, uint32_t IR_RxCntThr);
+
+/**
+ * \brief Send data.
+ * \param[in] pBuf: Data buffer to send.
+ * \param[in] len: Send data length.
+ * \param[in] IsLastPacket: Is it the last package of data.
+ * This parameter can be one of the following values:
+ * \arg ENABLE: The last data in IR packet and there is no continuous data.In other words, an infrared data transmission is completed.
+ * \arg DISABLE: There is data to be transmitted continuously.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * uint32_t data_buf[80] = {0};
+ * IR_SendBuf(data_buf, 68, DISABLE);
+ * }
+ * \endcode
+ */
+void IR_SendBuf(uint32_t *pBuf, uint32_t len, FunctionalState IsLastPacket);
+
+/**
+ * \brief Send compensation data.
+ * \param[in] comp_type: Compensation data type.
+ * This parameter can be one of the following values:
+ * \arg IR_COMPEN_FLAG_1_2_CARRIER: 1/2 carrier freqency.
+ * \arg IR_COMPEN_FLAG_1_4_CARRIER: 1/4 carrier freqency.
+ * \arg IR_COMPEN_FLAG_1_N_SYSTEM_CLK: MOD((0x48[27:16]+0x00[11:0]), 4095)/40MHz.
+ User can call function of IR_ConfigCompParam to configure 0x48[27:16].
+ * \param[in] buf: Data buffer to send.
+ * \param[in] length: Data length.
+ * \param[in] IsLastPacket: Is it the last package of data.
+ * This parameter can be the following values:
+ * \arg ENABLE: The last data in IR packet and there is no continuous data.In other words, an infrared data transmission is completed.
+ * \arg DISABLE: There is data to be transmitted continuously.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * uint32_t data_buf[80] = {0};
+ * IR_SendCompenBuf(IR_COMPEN_FLAG_1_2_CARRIER, data_buf, 68, DISABLE);
+ * }
+ * \endcode
+ */
+void IR_SendCompenBuf(IR_TX_COMPEN_TYPE comp_type, uint32_t *pBuf, uint32_t len,
+ FunctionalState IsLastPacket);
+
+/**
+ * \brief Read data From RX FIO.
+ * \param[in] pBuf: Buffer address to receive data.
+ * \param[in] length: Read data length.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * uint32_t data_buf[80] = {0};
+ * IR_ReceiveBuf(data_buf, 68);
+ * }
+ * \endcode
+ */
+void IR_ReceiveBuf(uint32_t *pBuf, uint32_t length);
+
+/**
+ * \brief Enables or disables the specified IR interrupt source.
+ * \param[in] IR_INT: Specifies the IR interrupt source to be enabled or disabled.
+ * This parameter can be oen of the following values:
+ * \arg IR_INT_TF_EMPTY: TX FIFO empty interrupt source.
+ * \arg IR_INT_TF_LEVEL: TX FIFO threshold interrupt source.
+ * \arg IR_INT_TF_OF: TX FIFO overflow interrupt source.
+ * \arg IR_INT_RF_FULL: RX FIFO full interrupt source.
+ * \arg IR_INT_RF_LEVEL: RX FIFO threshold interrupt source.
+ * \arg IR_INT_RX_CNT_OF: RX counter overflow interrupt source.
+ * \arg IR_INT_RF_OF: RX FIFO overflow interrupt source.
+ * \arg IR_INT_RX_CNT_THR: RX counter threshold interrupt source.
+ * \arg IR_INT_RF_ERROR: RX FIFO error read interrupt source. Trigger when RX FIFO empty and read RX FIFO.
+ * \arg IR_INT_RISING_EDGE: IR RX Rising edge interrupt.
+ * \arg IR_INT_FALLING_EDGE: IR RX Falling edge interrupt.
+ * \param[in] newState: New state of the specified IR interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * IR_INTConfig(IR_INT_TF_EMPTY, ENABLE);
+ * }
+ * \endcode
+ */
+void IR_INTConfig(uint32_t IR_INT, FunctionalState newState);
+
+/**
+ * \brief Mask or unmask the specified IR interrupt source.
+ * \param[in] IR_INT: Specifies the IR interrupts sources to be mask or unmask.
+ * This parameter can be the following values:
+ * \arg IR_INT_TF_EMPTY: TX FIFO empty interrupt.
+ * \arg IR_INT_TF_LEVEL: TX FIFO threshold interrupt.
+ * \arg IR_INT_TF_OF: TX FIFO overflow interrupt.
+ * \arg IR_INT_RF_FULL: RX FIFO full interrupt.
+ * \arg IR_INT_RF_LEVEL: RX FIFO threshold interrupt.
+ * \arg IR_INT_RX_CNT_OF: RX counter overflow interrupt.
+ * \arg IR_INT_RF_OF: RX FIFO overflow interrupt.
+ * \arg IR_INT_RX_CNT_THR: RX counter threshold interrupt.
+ * \arg IR_INT_RF_ERROR: RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO.
+ * \arg IR_INT_RISING_EDGE: IR RX Rising edge interrupt.
+ * \arg IR_INT_FALLING_EDGE: IR RX Falling edge interrupt.
+ * \param[in] newState: New state of the specified IR interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * IR_MaskINTConfig(IR_INT_TF_EMPTY, ENABLE);
+ * }
+ * \endcode
+ */
+void IR_MaskINTConfig(uint32_t IR_INT, FunctionalState newState);
+
+/**
+ * \brief Get the specified IR interrupt status.
+ * \param[in] IR_INT: the specified IR interrupts.
+ * This parameter can be one of the following values:
+ * \arg IR_INT_TF_EMPTY: TX FIFO empty interrupt.
+ * \arg IR_INT_TF_LEVEL: TX FIFO threshold interrupt.
+ * \arg IR_INT_TF_OF: TX FIFO overflow interrupt.
+ * \arg IR_INT_RF_FULL: RX FIFO full interrupt.
+ * \arg IR_INT_RF_LEVEL: RX FIFO threshold interrupt.
+ * \arg IR_INT_RX_CNT_OF: RX counter overflow interrupt.
+ * \arg IR_INT_RF_OF: RX FIFO overflow interrupt.
+ * \arg IR_INT_RX_CNT_THR: RX counter threshold interrupt.
+ * \arg IR_INT_RF_ERROR: RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO.
+ * \arg IR_INT_RISING_EDGE: IR RX Rising edge interrupt.
+ * \arg IR_INT_FALLING_EDGE: IR RX Falling edge interrupt.
+ * \return The new state of IR_INT (SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * ITStatus int_status = IR_GetINTStatus(IR_INT_TF_EMPTY);
+ * }
+ * \endcode
+ */
+ITStatus IR_GetINTStatus(uint32_t IR_INT);
+
+/**
+ * \brief Clear the IR interrupt pending bit.
+ * \param[in] IR_CLEAR_INT: specifies the interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * \arg IR_INT_TF_EMPTY_CLR: Clear TX FIFO empty interrupt.
+ * \arg IR_INT_TF_LEVEL_CLR: Clear TX FIFO threshold interrupt.
+ * \arg IR_INT_TF_OF_CLR: Clear TX FIFO overflow interrupt.
+ * \arg IR_INT_RF_FULL_CLR: Clear RX FIFO full interrupt.
+ * \arg IR_INT_RF_LEVEL_CLR: Clear RX FIFO threshold interrupt.
+ * \arg IR_INT_RX_CNT_OF_CLR: Clear RX counter overflow interrupt.
+ * \arg IR_INT_RF_OF_CLR: Clear RX FIFO overflow interrupt.
+ * \arg IR_INT_RX_CNT_THR_CLR: Clear RX counter threshold interrupt.
+ * \arg IR_INT_RF_ERROR_CLR: Clear RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO.
+ * \arg IR_INT_RX_RISING_EDGE_CLR: Clear RX Rising edge interrupt.
+ * \arg IR_INT_RX_FALLING_EDGE_CLR: Clear RX Falling edge interrupt.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * IR_ClearINTPendingBit(IR_INT_RX_CNT_OF_CLR);
+ * }
+ * \endcode
+ */
+void IR_ClearINTPendingBit(uint32_t IR_CLEAR_INT);
+
+/**
+ * \brief Get free size of TX FIFO.
+ * \param None.
+ * \return The free size of TX FIFO.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * uint16_t data_len = IR_GetTxFIFOFreeLen();
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint16_t IR_GetTxFIFOFreeLen(void)
+{
+ return (uint16_t)(IR_TX_FIFO_SIZE - ((IR->TX_SR & (IR_TX_FIFO_OFFSET_Msk)) >>
+ IR_TX_FIFO_OFFSET_Pos));
+}
+
+/**
+ * \brief Get data size in RX FIFO.
+ * \param None.
+ * \return Current data size in RX FIFO.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * uint16_t data_len = IR_GetRxDataLen();
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint16_t IR_GetRxDataLen(void)
+{
+ return ((uint16_t)(((IR->RX_SR) & IR_RX_FIFO_OFFSET_Msk) >> IR_RX_FIFO_OFFSET_Pos));
+}
+
+/**
+ * \brief Send one data.
+ * \param[in] data: Send data.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * IR_SendData(0x80000100);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void IR_SendData(uint32_t data)
+{
+ IR->TX_FIFO = data;
+}
+
+/**
+ * \brief Read one data.
+ * \param None.
+ * \return Data which read from RX FIFO.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * uint32_t data = IR_ReceiveData(30);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t IR_ReceiveData(void)
+{
+ return IR->RX_FIFO;
+}
+
+/**
+ * \brief Set tx threshold, when TX FIFO depth <= threshold value trigger interrupt.
+ * \param[in] thd: Tx threshold.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * IR_SetTxThreshold(30);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void IR_SetTxThreshold(uint8_t thd)
+{
+ IR->TX_CONFIG &= IR_TX_FIFO_THRESHOLD_CLR;
+ IR->TX_CONFIG |= (thd << IR_TX_FIFO_THRESHOLD_Pos);
+}
+
+/**
+ * \brief Set tx threshold, when RX FIFO depth >= threshold value trigger interrupt.
+ * \param[in] thd: Rx threshold.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * IR_SetRxThreshold(2);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void IR_SetRxThreshold(uint8_t thd)
+{
+ IR->RX_CONFIG &= IR_RX_FIFO_LEVEL_CLR;
+ IR->RX_CONFIG |= (thd << IR_RX_FIFO_LEVEL_Pos);
+}
+
+/**
+ * \brief Get IR RX current count.
+ * \param None.
+ * \return Current counter.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * uint32_t count = IR_GetRxCurrentCount();
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t IR_GetRxCurrentCount(void)
+{
+ return IR->RX_CUR_CNT ;
+}
+
+/**
+ * \brief Clear IR TX FIFO.
+ * \param None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * IR_ClearTxFIFO();
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void IR_ClearTxFIFO(void)
+{
+ IR->TX_INT_CLR = IR_TX_FIFO_CLR_Msk;
+}
+
+/**
+ * \brief Clear IR RX FIFO.
+ * \param None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * IR_ClearRxFIFO();
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void IR_ClearRxFIFO(void)
+{
+ IR->RX_INT_CLR = IR_RX_FIFO_CLR_Msk;
+}
+
+/**
+ * \brief Check whether the specified IR flag is set.
+ * \param[in] IR_FLAG: Specifies the flag to check.
+ * This parameter can be one of the following values:
+ * \arg IR_FLAG_TF_EMPTY: TX FIFO empty or not. If SET, TX FIFO is empty.
+ * \arg IR_FLAG_TF_FULL: TX FIFO full or not. If SET, TX FIFO is full.
+ * \arg IR_FLAG_TX_RUN: TX run or not. If SET, TX is running.
+ * \arg IR_FLAG_RF_EMPTY: RX FIFO empty or not. If SET, RX FIFO is empty.
+ * \arg IR_FLAG_RX_RUN: RX run or not. If SET, RX is running.
+ * \return The new state of IR_FLAG (SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * FlagStatus flag_status = IR_GetFlagStatus(IR_FLAG_TF_EMPTY);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE FlagStatus IR_GetFlagStatus(uint32_t IR_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_IR_FLAG(IR_FLAG));
+
+ if (IR->TX_CONFIG & IR_MODE_SEL_Msk)
+ {
+ if (IR->RX_SR & IR_FLAG)
+ {
+ bitstatus = SET;
+ }
+ return bitstatus;
+ }
+ else
+ {
+ if (IR->TX_SR & IR_FLAG)
+ {
+ bitstatus = SET;
+ }
+ return bitstatus;
+ }
+}
+
+/**
+ * \brief Set or reset tx data inverse.
+ * \param[in] NewState: This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * IR_SetTxInverse(ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void IR_SetTxInverse(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState == ENABLE)
+ {
+ IR->TX_CONFIG |= IR_FIFO_INVERSE_Msk;
+ }
+ else
+ {
+ IR->TX_CONFIG &= IR_FIFO_INVERSE_CLR;
+ }
+}
+
+/**
+ * \brief Enable TX output inverse or not.
+ * \param[in] NewState: This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void ir_demo(void)
+ * {
+ * IR_TxOutputInverse(ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void IR_TxOutputInverse(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState == ENABLE)
+ {
+ IR->TX_CONFIG |= IR_OUTPUT_INVERSE_Msk;
+ }
+ else
+ {
+ IR->TX_CONFIG &= IR_OUTPUT_INVERSE_CLR;
+ }
+}
+
+/** \} */ /* End of group IR_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876x_IR_H_ */
+
+
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/inc/peripheral/rtl876x_keyscan.h b/inc/peripheral/rtl876x_keyscan.h
new file mode 100644
index 0000000..3bdaef0
--- /dev/null
+++ b/inc/peripheral/rtl876x_keyscan.h
@@ -0,0 +1,627 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_keyscan.h
+* \brief The header file of the peripheral KEYSCAN driver.
+* \details This file provides all KEYSCAN firmware functions.
+* \author tifnan_ge
+* \date 2015-04-29
+* \version v1.0
+* *********************************************************************************************************
+*/
+
+
+#ifndef _RTL876X_KEYSCAN_H_
+#define _RTL876X_KEYSCAN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup KeyScan KeyScan
+ *
+ * \brief Manage the KeyScan peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup KeyScan_Exported_Types Init Params Struct
+ *
+ * \ingroup KeyScan
+ */
+
+/**
+ * \brief KeyScan init structure definition.
+ *
+ * \ingroup KeyScan_Exported_Types
+ */
+typedef struct
+{
+ uint16_t rowSize; /*!< Specifies Keyscan Row Size.
+ This parameter can be a value <=8. */
+ uint16_t colSize; /*!< Specifies Keyscan Column Size.
+ This parameter can be a value <=20. */
+ uint32_t detectPeriod; /*!< Specifies detect period(ms). */
+ uint16_t timeout; /*!< Specifies sw interrupt timeout(s). */
+ uint16_t scanInterval; /*!< Specifies Keyscan release time. */
+ uint32_t debounceEn; /*!< Enable or disable debounce. */
+ uint32_t scantimerEn; /*!< Enable or disable scan timer. */
+ uint32_t detecttimerEn; /*!< Enable or disable detect timer. */
+ uint16_t debounceTime; /*!< Specifies debounce time,debounce time = 31.25us * debounceTime. */
+ uint32_t detectMode; /*!< Specifies Key Detect mode.
+ This parameter can be a value of \ref Keyscan_Press_Detect_Mode */
+ uint32_t fifoOvrCtrl; /*!< Specifies Keyscan fifo over flow control.
+ This parameter can be a value of \ref Keyscan_Fifo_Overflow_Control */
+
+ uint16_t maxScanData; /*!< Specifies max scan data allowable in each scan. */
+ uint32_t scanmode; /*!< Specifies Keyscan mode.
+ This parameter can be a value of \ref Keyscan_Scan_Mode. */
+ uint16_t clockdiv; /*!< Specifies Keyscan clock divider.system clock/(SCAN_DIV+1)=scan clock. */
+ uint8_t delayclk; /*!< Specifies Keyscan delay clock divider.delay clock= scan clock/(DELAY_DIV+1)*/
+ uint16_t fifotriggerlevel; /*!< Specifies Keyscan fifo threshold to trigger interrupt KEYSCAN_INT_THRESHOLD.*/
+ uint8_t debouncecnt; /*!< Specifies Keyscan Debounce time. */
+ uint8_t releasecnt; /*!< Specifies Keyscan release time. */
+ uint8_t keylimit; /*!< Specifies max scan data allowable in each scan. */
+ uint32_t manual_sel; /*!< Specifies trigger mode in manual mode. */
+} KEYSCAN_InitTypeDef;
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup KeyScan_Exported_Constants Marco Definitions
+ *
+ * \ingroup KeyScan
+ */
+
+#define IS_KeyScan_PERIPH(PERIPH) ((PERIPH) == KEYSCAN)
+
+/**
+ * \def Keyscan_Row_Number Keyscan Row Number
+ */
+
+#define IS_KEYSCAN_ROW_NUM(ROW) ((ROW) <= 8)
+
+/**
+ * \def Keyscan_Column_Number Keyscan Column Number
+ */
+
+#define IS_KEYSCAN_COL_NUM(COL) ((COL) <= 20)
+
+/**
+ * \def Keyscan_Debounce_Time Keyscan Debounce Time
+ */
+#define IS_KEYSCAN_MAX_SCAN_DATA(DATA_NUM) ((DATA_NUM) <= 26) //0 means no limit
+
+/**
+ * \defgroup Keyscan_Scan_Mode Keyscan scan mode
+ * \{
+ * \ingroup KeyScan_Exported_Constants
+ */
+#define KeyScan_Manual_Scan_Mode ((uint32_t)(0x0 << 30))
+#define KeyScan_Auto_Scan_Mode ((uint32_t)(0x1 << 30))
+/** \} */
+
+#define IS_KEYSCAN_DETECT_MODE(MODE) (((MODE) == KeyScan_Detect_Mode_Edge) || ((MODE) == KeyScan_Detect_Mode_Level))
+
+/**
+ * \defgroup Keyscan_Manual_Mode Keyscan Manual Mode
+ * \{
+ * \ingroup KeyScan_Exported_Constants
+ */
+#define KeyScan_Manual_Sel_Bit ((uint32_t)(0x0 << 11))
+#define KeyScan_Manual_Sel_Key ((uint32_t)(0x1 << 11))
+/** \} */
+
+/**
+ * \defgroup Keyscan_Fifo_Overflow_Control Keyscan Fifo Overflow Control
+ * \{
+ * \ingroup KeyScan_Exported_Constants
+ */
+
+#define KeyScan_FIFO_OVR_CTRL_DIS_ALL ((uint32_t)(0x0 << 28)) //discard all the new scan data when FIFO is full
+#define KeyScan_FIFO_OVR_CTRL_DIS_LAST ((uint32_t)(0x1 << 28)) //discard the oldest scan data when FIFO is full
+/** \} */
+
+#define IS_KEYSCAN_FIFO_OVR_CTRL(CTRL) (((CTRL) == KeyScan_FIFO_OVR_CTRL_DIS_ALL) || ((CTRL) == KeyScan_FIFO_OVR_CTRL_DIS_LAST))
+
+/**
+ * \defgroup Keyscan_Debounce_Config Keyscan Debounce Config
+ * \{
+ * \ingroup KeyScan_Exported_Constants
+ */
+#define KeyScan_Debounce_Enable ((uint32_t)0x1 << 31)
+#define KeyScan_Debounce_Disable ((uint32_t)0x0 << 31)
+/** \} */
+#define IS_KEYSCAN_DEBOUNCE_EN(EN) (((EN) == KeyScan_Debounce_Enable) || ((EN) == KeyScan_Debounce_Disable)) //0 means no limit
+
+/**
+ * \defgroup Keyscan_Scan_Interval_En Keyscan Scan Interval Enable
+ * \{
+ * \ingroup KeyScan_Exported_Constants
+ */
+#define KeyScan_ScanInterval_Enable ((uint32_t)(0x1 << 30))
+#define KeyScan_ScanInterval_Disable ((uint32_t)(0x0 << 30))
+/** \} */
+#define IS_KEYSCAN_SCANINTERVAL_EN(EN) (((EN) == KeyScan_ScanInterval_Enable) || ((EN) == KeyScan_ScanInterval_Disable)) //0 means no limit
+
+/**
+ * \defgroup Keyscan_Release_Detect_Timer_En Keyscan Release Detect Timer Enable
+ * \{
+ * \ingroup KeyScan_Exported_Constants
+ */
+#define KeyScan_Release_Detect_Enable ((uint32_t)(0x1 << 29))
+#define KeyScan_Release_Detect_Disable ((uint32_t)(0x0 << 29))
+/** \} */
+#define IS_KEYSCAN_RELEASE_DETECT_EN(EN) (((EN) == KeyScan_Release_Detect_Enable) || ((EN) == KeyScan_Release_Detect_Disable)) //0 means no limit
+
+/**
+ * \defgroup Keyscan_Press_Detect_Mode Keyscan Press Detect Mode
+ * \{
+ * \ingroup KeyScan_Exported_Constants
+ */
+
+#define KeyScan_Detect_Mode_Edge ((uint32_t)(0x0 << 29))
+#define KeyScan_Detect_Mode_Level ((uint32_t)(0x1 << 29))
+/** \} */
+
+#define IS_KEYSCAN_DETECT_MODE(MODE) (((MODE) == KeyScan_Detect_Mode_Edge) || ((MODE) == KeyScan_Detect_Mode_Level))
+
+/**
+ * \defgroup Keyscan_Interrupt_Definition Keyscan Interrupt Definition
+ * \{
+ * \ingroup KeyScan_Exported_Constants
+ */
+#define KEYSCAN_INT_THRESHOLD ((uint16_t)(0x1 << 4))
+#define KEYSCAN_INT_OVER_READ ((uint16_t)(0x1 << 3))
+#define KEYSCAN_INT_SCAN_END ((uint16_t)(0x1 << 2))
+#define KEYSCAN_INT_FIFO_NOT_EMPTY ((uint16_t)(0x1 << 1))
+#define KEYSCAN_INT_ALL_RELEASE ((uint16_t)(0x1 << 0))
+/** \} */
+
+#define IS_KEYSCAN_CONFIG_IT(IT) ((((IT) & (uint32_t)0xFFF8) == 0x00) && ((IT) != 0x00))
+
+/**
+ * \defgroup Keyscan_Flag_Definition Keyscan Flag Definition
+ * \{
+ * \ingroup KeyScan_Exported_Constants
+ */
+#define KEYSCAN_FLAG_FIFOLIMIT ((uint32_t)(0x1 << 20))
+#define KEYSCAN_INT_FLAG_THRESHOLD ((uint32_t)(0x1 << 19))
+#define KEYSCAN_INT_FLAG_OVER_READ ((uint32_t)(0x1 << 18))
+#define KEYSCAN_INT_FLAG_SCAN_END ((uint32_t)(0x1 << 17))
+#define KEYSCAN_INT_FLAG_FIFO_NOT_EMPTY ((uint32_t)(0x1 << 16))
+#define KEYSCAN_INT_FLAG_ALL_RELEASE ((uint32_t)(0x1 << 15))
+#define KEYSCAN_FLAG_DATAFILTER ((uint32_t)(0x1 << 3))
+#define KEYSCAN_FLAG_OVR ((uint32_t)(0x1 << 2))
+#define KEYSCAN_FLAG_FULL ((uint32_t)(0x1 << 1))
+#define KEYSCAN_FLAG_EMPTY ((uint32_t)(0x1 << 0))
+/** \} */
+
+#define IS_KEYSCAN_FLAG(FLAG) ((((FLAG) & (uint32_t)0x01FF) == 0x00) && ((FLAG) != (uint32_t)0x00))
+#define IS_KEYSCAN_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0x00C0) == 0x00) && ((FLAG) != (uint32_t)0x00))
+
+/**
+ * \def Keyscan_FIFO_AVAILABLE_MASK
+ */
+
+#define STATUS_FIFO_DATA_NUM_MASK ((uint32_t)(0x3F << 4))
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup Keyscan_Exported_functions Peripheral APIs
+ * \{
+ * \ingroup KeyScan
+ */
+
+/**
+ * \brief Deinitializes the Keyscan peripheral registers to their default reset values(turn off keyscan clock).
+ * \param[in] KeyScan: selected KeyScan peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_keyscan_init(void)
+ * {
+ * KeyScan_DeInit(APBPeriph_KEYSCAN);
+ * }
+ * \endcode
+ */
+void KeyScan_DeInit(KEYSCAN_TypeDef *KeyScan);
+
+/**
+ * \brief Initializes the KeyScan peripheral according to the specified
+ * parameters in the KeyScan_InitStruct
+ * \param[in] KeyScan: Selected KeyScan peripheral.
+ * \param[in] KeyScan_InitStruct: Pointer to a KEYSCAN_InitTypeDef structure that
+ * contains the configuration information for the specified KeyScan peripheral
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_keyscan_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_KEYSCAN, APBPeriph_KEYSCAN_CLOCK, ENABLE);
+
+ * KEYSCAN_InitTypeDef KEYSCAN_InitStruct;
+ * KeyScan_StructInit(&KEYSCAN_InitStruct);
+
+ * KEYSCAN_InitStruct.rowSize = KEYBOARD_ROW_SIZE;
+ * KEYSCAN_InitStruct.colSize = KEYBOARD_COLUMN_SIZE;
+ * KEYSCAN_InitStruct.scanmode = KeyScan_Manual_Scan_Mode;
+ * KEYSCAN_InitStruct.debounceEn = vDebounce_En;
+
+ * KeyScan_Init(KEYSCAN, &KEYSCAN_InitStruct);
+
+ * KeyScan_INTConfig(KEYSCAN, KEYSCAN_INT_SCAN_END, ENABLE);
+ * KeyScan_ClearINTPendingBit(KEYSCAN, KEYSCAN_INT_SCAN_END);
+ * KeyScan_INTMask(KEYSCAN, KEYSCAN_INT_SCAN_END, DISABLE); // Unmask keyscan interrupt
+ * KeyScan_Cmd(KEYSCAN, ENABLE);
+ * }
+ * \endcode
+ */
+void KeyScan_Init(KEYSCAN_TypeDef *KeyScan, KEYSCAN_InitTypeDef *KeyScan_InitStruct);
+
+/**
+ * \brief Fills each Keyscan_InitStruct member with its default value.
+ * \param[in] KeyScan_InitStruct: Pointer to a KEYSCAN_InitTypeDef structure which will be initialized.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_keyscan_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_KEYSCAN, APBPeriph_KEYSCAN_CLOCK, ENABLE);
+
+ * KEYSCAN_InitTypeDef KEYSCAN_InitStruct;
+ * KeyScan_StructInit(&KEYSCAN_InitStruct);
+
+ * KEYSCAN_InitStruct.rowSize = KEYBOARD_ROW_SIZE;
+ * KEYSCAN_InitStruct.colSize = KEYBOARD_COLUMN_SIZE;
+ * KEYSCAN_InitStruct.scanmode = KeyScan_Manual_Scan_Mode;
+ * KEYSCAN_InitStruct.debounceEn = vDebounce_En;
+
+ * KeyScan_Init(KEYSCAN, &KEYSCAN_InitStruct);
+
+ * KeyScan_INTConfig(KEYSCAN, KEYSCAN_INT_SCAN_END, ENABLE);
+ * KeyScan_ClearINTPendingBit(KEYSCAN, KEYSCAN_INT_SCAN_END);
+ * KeyScan_INTMask(KEYSCAN, KEYSCAN_INT_SCAN_END, DISABLE); // Unmask keyscan interrupt
+ * KeyScan_Cmd(KEYSCAN, ENABLE);
+ * }
+ * \endcode
+ */
+void KeyScan_StructInit(KEYSCAN_InitTypeDef *KeyScan_InitStruct);
+
+/**
+ * \brief Enables or disables the specified KeyScan interrupt.
+ * \param[in] KeyScan: Selected KeyScan peripheral.
+ * \param[in] KeyScan_IT: Specifies the KeyScan interrupts sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * \arg KEYSCAN_INT_TIMEOUT: KeyScan timeout interrupt.
+ * \arg KEYSCAN_INT_OVER_THRESHOLD: Kescan FIFO data over threshold interrupt.
+ * \arg KEYSCAN_INT_SCAN_END: KeyScan scan end interrupt.
+ * \param[in] newState: New state of the specified KeyScan interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void keyscan_demo(void)
+ * {
+ * KeyScan_INTMask(KEYSCAN, KEYSCAN_INT_TIMEOUT, ENABLE);
+ * KeyScan_INTConfig(KEYSCAN, KEYSCAN_INT_TIMEOUT, ENABLE);
+ * KeyScan_INTMask(KEYSCAN, KEYSCAN_INT_TIMEOUT, DISABLE);
+ * }
+ * \endcode
+ */
+void KeyScan_INTConfig(KEYSCAN_TypeDef *KeyScan, uint32_t KeyScan_IT,
+ FunctionalState newState);
+
+/**
+ * \brief Mask the specified KeyScan interrupt .
+ * \param[in] KeyScan: selected KeyScan peripheral.
+ * \param[in] KeyScan_IT: Specifies the KeyScan interrupts sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * \arg KEYSCAN_INT_TIMEOUT: KeyScan timeout interrupt mask.
+ * \arg KEYSCAN_INT_OVER_THRESHOLD: Kescan FIFO data over threshold interrupt mask.
+ * \arg KEYSCAN_INT_SCAN_END: KeyScan scan end interrupt mask.
+ * \param[in] newState: New state of the specified KeyScan interrupts mask.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void keyscan_demo(void)
+ * {
+ * KeyScan_INTMask(KEYSCAN, KEYSCAN_INT_TIMEOUT, ENABLE);
+ * }
+ * \endcode
+ */
+void KeyScan_INTMask(KEYSCAN_TypeDef *KeyScan, uint32_t KeyScan_IT,
+ FunctionalState newState);
+
+/**
+ * \brief Read data from keyscan FIFO.
+ * \param[in] KeyScan: Selected KeyScan peripheral.
+ * \param[out] outBuf: Buffer to save data read from KeyScan FIFO.
+ * \param[in] count: Data length to be read.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void keyscan_demo(void)
+ * {
+ * uint16_t data[3] = {0};
+ * KeyScan_Read(KEYSCAN, data, 3);
+ * }
+ * \endcode
+ */
+void KeyScan_Read(KEYSCAN_TypeDef *KeyScan, uint16_t *outBuf, uint16_t count);
+
+/**
+ * \brief Enable or disable the KeyScan peripheral.
+ * \param[in] KeyScan: Selected KeyScan peripheral.
+ * \param[in] NewState: New state of the KeyScan peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void keyscan_demo(void)
+ * {
+ * KeyScan_Cmd(KEYSCAN, ENABLE);
+ * }
+ * \endcode
+ */
+void KeyScan_Cmd(KEYSCAN_TypeDef *KeyScan, FunctionalState NewState);
+
+/**
+ * \brief Set filter data.
+ * \param[in] KeyScan: selected KeyScan peripheral.
+ * \param[in] data: Config the data to be filtered.
+ * This parameter should not be more than 9 bits.
+ * \param[in] NewState: New state of the KeyScan peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void keyscan_demo(void)
+ * {
+ * KeyScan_FilterDataConfig(KEYSCAN, 0x01, ENABLE);
+ *
+ * }
+ * \endcode
+ */
+void KeyScan_FilterDataConfig(KEYSCAN_TypeDef *KeyScan, uint16_t data,
+ FunctionalState NewState);
+
+/**
+ * \brief KeyScan debounce time config.
+ * \param[in] KeyScan: selected KeyScan peripheral.
+ * \param[in] time: Keyscan hardware debounce time.
+ * \param[in] NewState: New state of the KeyScan debounce function.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void keyscan_demo(void)
+ * {
+ * KeyScan_debounceConfig(KEYSCAN, 10, ENABLE);
+ *
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void KeyScan_debounceConfig(KEYSCAN_TypeDef *KeyScan, uint8_t time,
+ FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_KeyScan_PERIPH(KeyScan));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ KeyScan->TIMERCR &= ~((0xff << 16) | BIT31);
+ KeyScan->TIMERCR |= ((NewState << 31) | time << 16);
+
+}
+
+/**
+ * \brief Get KeyScan FIFO data num.
+ * \param[in] KeyScan: selected KeyScan peripheral.
+ * \return Data length in FIFO.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void keyscan_demo(void)
+ * {
+ * uint16_t data_len = KeyScan_GetFifoDataNum(KEYSCAN);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint16_t KeyScan_GetFifoDataNum(KEYSCAN_TypeDef *KeyScan)
+{
+ assert_param(IS_KeyScan_PERIPH(KeyScan));
+
+ return (uint16_t)((KeyScan->STATUS & STATUS_FIFO_DATA_NUM_MASK) >> 4);
+}
+
+/**
+ * \brief Clear the KeyScan interrupt pending bit.
+ * \param[in] KeyScan: selected KeyScan peripheral.
+ * \param[in] KeyScan_IT: specifies the interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * \arg KEYSCAN_INT_TIMEOUT: KeyScan timeout interrupt mask
+ * \arg KEYSCAN_INT_THRESHOLD
+ * \arg KEYSCAN_INT_OVER_READ
+ * \arg KEYSCAN_INT_SCAN_END
+ * \arg KEYSCAN_INT_FIFO_NOT_EMPTY
+ * \arg KEYSCAN_INT_ALL_RELEASE
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void keyscan_demo(void)
+ * {
+ * KeyScan_ClearINTPendingBit(KEYSCAN, KEYSCAN_INT_TIMEOUT);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void KeyScan_ClearINTPendingBit(KEYSCAN_TypeDef *KeyScan, uint32_t KeyScan_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_KeyScan_PERIPH(KeyScan));
+ assert_param(IS_KEYSCAN_CONFIG_IT(KeyScan_IT));
+
+ KeyScan->INTCLR |= KeyScan_IT;
+
+ return;
+}
+
+/**
+ * \brief Clear the specified KeyScan flag.
+ * \param[in] KeyScan: Selected KeyScan peripheral.
+ * \param[in] KeyScan_FLAG: Specifies the flag to clear.
+ * This parameter can be one of the following values:
+ * \arg KEYSCAN_FLAG_FIFOLIMIT
+ * \arg KEYSCAN_FLAG_DATAFILTER
+ * \arg KEYSCAN_FLAG_OVR
+ * \return None.
+ * \note KEYSCAN_FLAG_FULL and KEYSCAN_FLAG_EMPTY can't be cleared manually.
+ * They are cleared by hardware automatically.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void keyscan_demo(void)
+ * {
+ * KeyScan_ClearFlags(KEYSCAN, KEYSCAN_FLAG_FIFOLIMIT);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void KeyScan_ClearFlags(KEYSCAN_TypeDef *KeyScan, uint32_t KeyScan_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_KeyScan_PERIPH(KeyScan));
+ assert_param(IS_KEYSCAN_CLEAR_FLAG(KeyScan_FLAG));
+
+ if (KeyScan_FLAG & KEYSCAN_FLAG_FIFOLIMIT)
+ {
+ KeyScan->INTCLR |= BIT8;
+ }
+ if (KeyScan_FLAG & KEYSCAN_FLAG_DATAFILTER)
+ {
+ KeyScan->INTCLR |= BIT7;
+ }
+ if (KeyScan_FLAG & KEYSCAN_FLAG_OVR)
+ {
+ KeyScan->INTCLR |= BIT5;
+ }
+
+ return;
+}
+
+/**
+ * \brief Check whether the specified KeyScan flag is set.
+ * \param[in] KeyScan: Selected KeyScan peripheral.
+ * \param[in] KeyScan_FLAG: Specifies the flag to check.
+ * This parameter can be one of the following values:
+ * \arg KEYSCAN_FLAG_FIFOLIMIT:
+ * \arg KEYSCAN_FLAG_THRESHOLD:
+ * \arg KEYSCAN_FLAG_OVER_READ:
+ * \arg KEYSCAN_FLAG_SCAN_END:
+ * \arg KEYSCAN_FLAG_FIFO_NOT_EMPTY:
+ * \arg KEYSCAN_FLAG_ALL_RELEASE:
+ * \arg KEYSCAN_FLAG_DATAFILTER:
+ * \arg KEYSCAN_FLAG_OVR:
+ * \arg KEYSCAN_FLAG_FULL:
+ * \arg KEYSCAN_FLAG_EMPTY:
+ * \return The new state of KeyScan_FLAG (SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void keyscan_demo(void)
+ * {
+ * FlagStatus flag_status = KeyScan_GetFlagState(KEYSCAN, KEYSCAN_FLAG_OVR);
+ *
+ * }
+ * \endcode
+ */
+__STATIC_INLINE FlagStatus KeyScan_GetFlagState(KEYSCAN_TypeDef *KeyScan, uint32_t KeyScan_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_KeyScan_PERIPH(KeyScan));
+ assert_param(IS_KEYSCAN_FLAG(KeyScan_FLAG));
+
+ if ((KeyScan->STATUS & KeyScan_FLAG) != 0)
+ {
+ bitstatus = SET;
+ }
+
+ return bitstatus;
+}
+
+/**
+ * \brief Read FIFO data.
+ * \param[in] KeyScan: Selected KeyScan peripheral.
+ * \return Keyscan FIFO data.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void keyscan_demo(void)
+ * {
+ * uint16_t data = KeyScan_ReadFifoData(KEYSCAN);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint16_t KeyScan_ReadFifoData(KEYSCAN_TypeDef *KeyScan)
+{
+ /* Check the parameters */
+ assert_param(IS_KeyScan_PERIPH(KeyScan));
+
+ return (uint16_t)(KeyScan->FIFODATA);
+}
+
+/** \} */ /* End of group KeyScan_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_KEYSCAN_H_ */
+
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor *****END OF FILE****/
diff --git a/inc/peripheral/rtl876x_lpc.h b/inc/peripheral/rtl876x_lpc.h
new file mode 100644
index 0000000..64ce335
--- /dev/null
+++ b/inc/peripheral/rtl876x_lpc.h
@@ -0,0 +1,749 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_lpc.h
+* \brief The header file of the peripheral LPC driver.
+* \details This file provides all LPC firmware functions.
+* \author yuan
+* \date 2020-11-16
+* \version v2.1.1
+* *********************************************************************************************************
+*/
+
+#ifndef _RTL876X_LPC_H_
+#define _RTL876X_LPC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup LPC LPC
+ *
+ * \brief Manage the LPC peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup LPC_Exported_Types Init Params Struct
+ *
+ * \ingroup LPC
+ */
+
+/**
+ * \brief LPC init structure definition
+ *
+ * \ingroup LPC_Exported_Types
+ */
+typedef struct
+{
+ uint16_t LPC_Channel; /*!< Specifies the input pin.
+ This parameter can be a value of ADC_0 to ADC_7. */
+ uint32_t LPC_Edge; /*!< Specifies the comparator output edge. */
+ uint32_t LPC_Threshold; /*!< Specifies the threshold value of comparator voltage. */
+
+} LPC_InitTypeDef;
+
+
+/*============================================================================*
+ * Register Defines
+ *============================================================================*/
+
+/* Peripheral: LPC */
+/* Description: Low Power Comparator register defines */
+
+/* Register: LPC_AON_52 */
+/* Description: LPC AON Register for threshold voltage configuration */
+
+/* LPC_AON_52[5:0] :LPC_Threshold. Specified the threshold value of comparator voltage */
+#define LPC_AON_52_THRESHOLD_Pos (0UL)
+#define LPC_AON_52_THRESHOLD_Msk (0x3FUL << LPC_AON_52_THRESHOLD_Pos)
+#define LPC_AON_52_THRESHOLD_Clr (~LPC_AON_52_THRESHOLD_Msk)
+
+/* Register: LPC_AON_114 */
+/* Description: LPC AON Register for parameters configuration */
+
+/* LPC_AON_114[5] :LPC_Edge. Specified the cmp output edge */
+#define LPC_AON_114_POSEDGE_Pos (5UL)
+#define LPC_AON_114_POSEDGE_Msk (0x1UL << LPC_AON_114_POSEDGE_Pos)
+/* LPC_AON_114[4:1] :LPC_Channel. Specified the input pin */
+#define LPC_AON_114_CH_NUM_Pos (1UL)
+#define LPC_AON_114_CH_NUM_Msk (0xFUL << LPC_AON_114_CH_NUM_Pos)
+/* LPC_AON_114[0] : LPC_POWER. 1: Enable power of low power cmp */
+#define LPC_AON_114_POWER_EN_Pos (0UL)
+#define LPC_AON_114_POWER_EN_Msk (0x1UL << LPC_AON_114_POWER_EN_Pos)
+#define LPC_AON_114_POWER_EN_CLR (~LPC_AON_114_POWER_EN_Msk)
+
+#define LPC_AON_114_DEFAULT_Msk (0x3F)
+#define LPC_AON_114_DEFAULT_Clr (~LPC_AON_114_DEFAULT_Msk)
+
+/* Register: LPC_CR0 */
+/* Description: Control Register 0 */
+/* LPC_CR0[20] :LPC_LPCOMP_OUTPUT_EN. 1: Enable lpcomp out to NVIC and power sequence. */
+#define LPC_LPCOMP_OUTPUT_EN_Pos (20UL)
+#define LPC_LPCOMP_OUTPUT_EN_Msk (0x1UL << LPC_LPCOMP_OUTPUT_EN_Pos)
+#define LPC_LPCOMP_OUTPUT_EN_CLR (~(LPC_LPCOMP_OUTPUT_EN_Msk))
+
+/* LPC_CR0[19] :LPC_SRC_INT_EN. 1: Enable lpcomp out sync signal to AON interrupt */
+#define LPC_INT_LPCOMP_AON_EN_Pos (19UL)
+#define LPC_INT_LPCOMP_AON_EN_Msk (0x1UL << LPC_INT_LPCOMP_AON_EN_Pos)
+#define LPC_INT_LPCOMP_AON_EN_CLR (~(LPC_INT_LPCOMP_AON_EN_Msk))
+
+/* LPC_CR0[9] :LPC_NV_EN. 1: Enable lpcomp out sync signal to CPU interrupt */
+#define LPC_INT_LPCOMP_NV_EN_Pos (9UL)
+#define LPC_INT_LPCOMP_NV_EN_Msk (0x1UL << LPC_INT_LPCOMP_NV_EN_Pos)
+#define LPC_INT_LPCOMP_NV_EN_CLR (~(LPC_INT_LPCOMP_NV_EN_Msk))
+
+/* LPC_CR0[8] :LPC_EVENT_EN. 1: Enable or disable LPCOMP event */
+#define LPC_INT_LPCOMP_CNT_EN_Pos (8UL)
+#define LPC_INT_LPCOMP_CNT_EN_Msk (0x1UL << LPC_INT_LPCOMP_CNT_EN_Pos)
+#define LPC_INT_LPCOMP_CNT_EN_CLR (~(LPC_INT_LPCOMP_CNT_EN_Msk))
+
+/* LPC_CR0[2] :LPC_FLAG_CLEAR. 1: Clear Event Status of LPCOMP */
+#define LPC_LPCOMP_CNT_CLEAR_Pos (2UL)
+#define LPC_LPCOMP_CNT_CLEAR_Msk (0x1UL << LPC_LPCOMP_CNT_CLEAR_Pos)
+#define LPC_LPCOMP_CNT_CLEAR_CLR (~(LPC_LPCOMP_CNT_CLEAR_Msk))
+
+/* LPC_CR0[1] :LPC_COUNTER_START. 1: Start LPCOMP counter. */
+#define LPC_COUNTER_START_Pos (1UL)
+#define LPC_COUNTER_START_Msk (0x1UL << LPC_COUNTER_START_Pos)
+#define LPC_COUNTER_START_CLR (~(LPC_COUNTER_START_Msk))
+
+/* LPC_CR0[0] :LPC_COUNTER_RESET. 1: Reset LPCOMP Counter */
+#define LPC_COUNTER_RESET_Pos (0UL)
+#define LPC_COUNTER_RESET_Msk (0x1UL << LPC_COUNTER_RESET_Pos)
+#define LPC_COUNTER_RESET_CLR (~(LPC_COUNTER_RESET_Msk))
+
+/* Register: LPC_SR */
+/* Description: Status Register */
+
+/* LPC_SR[1] :LPC_COMP_OUTPUT. Event Status of LPCOMP output signal */
+#define LPC_LPCOMP_OUTPUT_AON_Pos (1UL) /*!< Position of */
+#define LPC_LPCOMP_OUTPUT_AON_Msk (0x1UL << LPC_LPCOMP_OUTPUT_AON_Pos)
+
+/* LPC_SR[0] :LPC_COMP. Event Status of LPCOMP */
+#define LPC_LPCOMP_CNT_Pos (0UL) /*!< Position of */
+#define LPC_LPCOMP_CNT_Msk (0x1UL << LPC_LPCOMP_CNT_Pos)
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup LPC_Exported_constants Marco Definitions
+ *
+ * \ingroup LPC
+ */
+
+/**
+ * \defgroup LPC_Channel LPC Channel
+ * \{
+ * \ingroup LPC_Exported_constants
+ */
+#define LPC_CHANNEL_P2_2 ((uint32_t)0)
+#define LPC_CHANNEL_P2_3 ((uint32_t)1)
+#define LPC_CHANNEL_P2_6 ((uint32_t)2)
+#define LPC_CHANNEL_VBAT ((uint32_t)3)
+/** \} */
+
+#define IS_LPC_CHANNEL(CHANNEL) (((CHANNEL) == LPC_CHANNEL_P2_2) || \
+ ((CHANNEL) == LPC_CHANNEL_P2_3) || \
+ ((CHANNEL) == LPC_CHANNEL_P2_6) || \
+ ((CHANNEL) == LPC_CHANNEL_P2_7) || \
+ ((CHANNEL) == LPC_CHANNEL_VBAT))
+
+/** \defgroup LPC_Edge LPC Edge
+ * \{
+ * \ingroup LPC_Exported_constants
+ */
+#define LPC_Vin_Below_Vth ((uint32_t)0)
+#define LPC_Vin_Over_Vth ((uint32_t)(0x0001UL << LPC_AON_114_POSEDGE_Pos))
+/** \} */
+
+#define IS_LPC_EDGE(EDGE) (((EDGE) == LPC_Vin_Below_Vth) || \
+ ((EDGE) == LPC_Vin_Over_Vth))
+
+/** \defgroup LPC_Threshold LPC Threshold
+ * \{
+ * \ingroup LPC_Exported_constants
+ */
+#define LPC_80_mV ((uint32_t)(0x0000 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_160_mV ((uint32_t)(0x0001 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_240_mV ((uint32_t)(0x0002 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_320_mV ((uint32_t)(0x0003 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_400_mV ((uint32_t)(0x0004 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_480_mV ((uint32_t)(0x0005 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_560_mV ((uint32_t)(0x0006 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_640_mV ((uint32_t)(0x0007 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_680_mV ((uint32_t)(0x0008 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_720_mV ((uint32_t)(0x0009 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_760_mV ((uint32_t)(0x000a << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_800_mV ((uint32_t)(0x000b << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_840_mV ((uint32_t)(0x000c << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_880_mV ((uint32_t)(0x000d << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_920_mV ((uint32_t)(0x000e << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_960_mV ((uint32_t)(0x000f << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1000_mV ((uint32_t)(0x0010 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1040_mV ((uint32_t)(0x0011 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1080_mV ((uint32_t)(0x0012 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1120_mV ((uint32_t)(0x0013 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1160_mV ((uint32_t)(0x0014 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1200_mV ((uint32_t)(0x0015 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1240_mV ((uint32_t)(0x0016 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1280_mV ((uint32_t)(0x0017 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1320_mV ((uint32_t)(0x0018 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1360_mV ((uint32_t)(0x0019 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1400_mV ((uint32_t)(0x001a << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1440_mV ((uint32_t)(0x001b << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1480_mV ((uint32_t)(0x001c << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1520_mV ((uint32_t)(0x001d << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1560_mV ((uint32_t)(0x001e << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1600_mV ((uint32_t)(0x001f << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1640_mV ((uint32_t)(0x0020 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1680_mV ((uint32_t)(0x0021 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1720_mV ((uint32_t)(0x0022 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1760_mV ((uint32_t)(0x0023 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1800_mV ((uint32_t)(0x0024 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1840_mV ((uint32_t)(0x0025 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1880_mV ((uint32_t)(0x0026 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1920_mV ((uint32_t)(0x0027 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_1960_mV ((uint32_t)(0x0028 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2000_mV ((uint32_t)(0x0029 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2040_mV ((uint32_t)(0x002a << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2080_mV ((uint32_t)(0x002b << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2120_mV ((uint32_t)(0x002c << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2160_mV ((uint32_t)(0x002d << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2200_mV ((uint32_t)(0x002e << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2240_mV ((uint32_t)(0x002f << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2280_mV ((uint32_t)(0x0030 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2320_mV ((uint32_t)(0x0031 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2360_mV ((uint32_t)(0x0032 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2400_mV ((uint32_t)(0x0033 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2440_mV ((uint32_t)(0x0034 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2480_mV ((uint32_t)(0x0035 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2520_mV ((uint32_t)(0x0036 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2560_mV ((uint32_t)(0x0037 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2640_mV ((uint32_t)(0x0038 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2720_mV ((uint32_t)(0x0039 << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2800_mV ((uint32_t)(0x003a << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2880_mV ((uint32_t)(0x003b << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_2960_mV ((uint32_t)(0x003c << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_3040_mV ((uint32_t)(0x003d << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_3120_mV ((uint32_t)(0x003e << LPC_AON_52_THRESHOLD_Pos))
+#define LPC_3200_mV ((uint32_t)(0x003f << LPC_AON_52_THRESHOLD_Pos))
+/** \} */
+
+#define IS_LPC_THRESHOLD(THRESHOLD) (((THRESHOLD) == LPC_80_mV) || ((THRESHOLD) == LPC_160_mV) || ((THRESHOLD) == LPC_240_mV) || \
+ ((THRESHOLD) == LPC_320_mV) || ((THRESHOLD) == LPC_400_mV) || ((THRESHOLD) == LPC_480_mV) || \
+ ((THRESHOLD) == LPC_560_mV) || ((THRESHOLD) == LPC_640_mV) || ((THRESHOLD) == LPC_680_mV) || \
+ ((THRESHOLD) == LPC_720_mV) || ((THRESHOLD) == LPC_760_mV) || ((THRESHOLD) == LPC_800_mV) || \
+ ((THRESHOLD) == LPC_840_mV) || ((THRESHOLD) == LPC_880_mV) || ((THRESHOLD) == LPC_920_mV) || \
+ ((THRESHOLD) == LPC_960_mV) || ((THRESHOLD) == LPC_1000_mV) || ((THRESHOLD) == LPC_1040_mV) || \
+ ((THRESHOLD) == LPC_1080_mV) || ((THRESHOLD) == LPC_1120_mV) || ((THRESHOLD) == LPC_1160_mV) || \
+ ((THRESHOLD) == LPC_1200_mV) || ((THRESHOLD) == LPC_1240_mV) || ((THRESHOLD) == LPC_1280_mV) || \
+ ((THRESHOLD) == LPC_1320_mV) || ((THRESHOLD) == LPC_1360_mV) || ((THRESHOLD) == LPC_1400_mV) || \
+ ((THRESHOLD) == LPC_1440_mV) || ((THRESHOLD) == LPC_1480_mV) || ((THRESHOLD) == LPC_1520_mV) || \
+ ((THRESHOLD) == LPC_1560_mV) || ((THRESHOLD) == LPC_1600_mV) || ((THRESHOLD) == LPC_1640_mV) || \
+ ((THRESHOLD) == LPC_1680_mV) || ((THRESHOLD) == LPC_1720_mV) || ((THRESHOLD) == LPC_1760_mV) || \
+ ((THRESHOLD) == LPC_1800_mV) || ((THRESHOLD) == LPC_1840_mV) || ((THRESHOLD) == LPC_1880_mV) || \
+ ((THRESHOLD) == LPC_1920_mV) || ((THRESHOLD) == LPC_1960_mV) || ((THRESHOLD) == LPC_2000_mV) || \
+ ((THRESHOLD) == LPC_2040_mV) || ((THRESHOLD) == LPC_2080_mV) || ((THRESHOLD) == LPC_2120_mV) || \
+ ((THRESHOLD) == LPC_2160_mV) || ((THRESHOLD) == LPC_2200_mV) || ((THRESHOLD) == LPC_2240_mV) || \
+ ((THRESHOLD) == LPC_2280_mV) || ((THRESHOLD) == LPC_2320_mV) || ((THRESHOLD) == LPC_2360_mV) || \
+ ((THRESHOLD) == LPC_2400_mV) || ((THRESHOLD) == LPC_2440_mV) || ((THRESHOLD) == LPC_2480_mV) || \
+ ((THRESHOLD) == LPC_2520_mV) || ((THRESHOLD) == LPC_2560_mV) || ((THRESHOLD) == LPC_2640_mV) || \
+ ((THRESHOLD) == LPC_2720_mV) || ((THRESHOLD) == LPC_2800_mV) || ((THRESHOLD) == LPC_2880_mV) || \
+ ((THRESHOLD) == LPC_2960_mV) || ((THRESHOLD) == LPC_3040_mV) || ((THRESHOLD) == LPC_3120_mV) || \
+ ((THRESHOLD) == LPC_3200_mV))
+
+/** \defgroup LPC_Interrupts_Definition LPC Interrupts Definition
+ * \{
+ * \ingroup LPC_Exported_constants
+ */
+#define LPC_INT_LPCOMP_VOL (LPC_LPCOMP_OUTPUT_EN_Msk)
+#define LPC_INT_LPCOMP_CNT (LPC_INT_LPCOMP_CNT_EN_Msk)
+/** \} */
+
+#define IS_LPC_CONFIG_INT(INT) (((INT) == LPC_INT_LPCOMP_VOL) || \
+ ((INT) == LPC_INT_LPCOMP_CNT))
+#define IS_LPC_STATUS_INT(INT) ((INT) == LPC_INT_LPCOMP_CNT)
+#define IS_LPC_CLEAR_INT(INT) ((INT) == LPC_INT_LPCOMP_CNT)
+
+/** \defgroup LPC_Flags_Definition LPC Flags Definition
+ * \{
+ * \ingroup LPC_Exported_constants
+ */
+#define LPC_FLAG_LPCOMP_AON (LPC_INT_LPCOMP_AON_EN_Msk)
+#define LPC_FLAG_LPCOMP_CNT (LPC_INT_LPCOMP_CNT_EN_Msk)
+/** \} */
+
+#define IS_LPC_FLAG(FLAG) (((FLAG) == LPC_FLAG_LPCOMP_AON) || \
+ ((FLAG) == LPC_FLAG_LPCOMP_CNT))
+#define IS_LPC_CLEAR_FLAG(FLAG) ((FLAG) == LPC_FLAG_LPCOMP_CNT)
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup LPC_Exported_Functions Peripheral APIs
+ * \{
+ * \ingroup LPC
+ */
+
+/**
+ * @brief Reset LPC.
+ * @param None
+ * @return None
+ */
+void LPC_DeInit(void);
+
+/**
+ * \brief Initializes LPC peripheral according to
+ * the specified parameters in LPC_InitStruct.
+ * \param[in] LPC_InitStruct: Pointer to a LPC_InitTypeDef structure that contains
+ * the configuration information for the specified LPC peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_lpc_init(void)
+ * {
+ * LPC_InitTypeDef LPC_InitStruct;
+ *
+ * LPC_StructInit(&LPC_InitStruct);
+ * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL;
+ * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE;
+ * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD;
+ * LPC_Init(&LPC_InitStruct);
+ * LPC_Cmd(ENABLE);
+ *
+ * LPC_ResetCounter();
+ * LPC_SetCompValue(LPC_COMP_VALUE);
+ * LPC_CounterCmd(ENABLE);
+ * LPC_INTConfig(LPC_INT_LPCOMP_CNT, ENABLE);
+ *
+ * NVIC_InitTypeDef NVIC_InitStruct;
+ * NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn;
+ * NVIC_InitStruct.NVIC_IRQChannelPriority = 2;
+ * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ * NVIC_Init(&NVIC_InitStruct);
+
+ * LPC_NvCmd(ENABLE);
+ * }
+ * \endcode
+ */
+void LPC_Init(LPC_InitTypeDef *LPC_InitStruct);
+
+/**
+ * \brief Fills each LPC_InitStruct member with its default value.
+ * \param[in] LPC_InitStruct : Pointer to a LPC_InitTypeDef structure which will be initialized.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_lpc_init(void)
+ * {
+ * LPC_InitTypeDef LPC_InitStruct;
+ *
+ * LPC_StructInit(&LPC_InitStruct);
+ * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL;
+ * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE;
+ * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD;
+ * LPC_Init(&LPC_InitStruct);
+ * }
+ * \endcode
+ */
+void LPC_StructInit(LPC_InitTypeDef *LPC_InitStruct);
+
+/**
+ * \brief Enables or disables LPC peripheral.
+ * \param[in] NewState: New state of LPC peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_lpc_init(void)
+ * {
+ * LPC_InitTypeDef LPC_InitStruct;
+ *
+ * LPC_StructInit(&LPC_InitStruct);
+ * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL;
+ * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE;
+ * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD;
+ * LPC_Init(&LPC_InitStruct);
+ * LPC_Cmd(ENABLE);
+ * }
+ * \endcode
+ */
+void LPC_Cmd(FunctionalState NewState);
+
+/**
+ * \brief Start or stop the LPC counter.
+ * \param[in] NewState: New state of the LPC counter.
+ * This parameter can be one of the following values:
+ * \arg ENABLE: Start LPCOMP counter.
+ * \arg DISABLE: Stop LPCOMP counter.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_lpc_init(void)
+ * {
+ * LPC_InitTypeDef LPC_InitStruct;
+ *
+ * LPC_StructInit(&LPC_InitStruct);
+ * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL;
+ * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE;
+ * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD;
+ * LPC_Init(&LPC_InitStruct);
+ * LPC_Cmd(ENABLE);
+ *
+ * LPC_ResetCounter();
+ * LPC_SetCompValue(LPC_COMP_VALUE);
+ * LPC_CounterCmd(ENABLE);
+ * }
+ * \endcode
+ */
+void LPC_CounterCmd(FunctionalState NewState);
+
+/**
+ * \brief Enables or disables the specified LPC interrupts.
+ * \param[in] LPC_INT: Specifies the LPC interrupt source to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * \arg LPC_INT_VOLTAGE_COMP: Voltage detection interrupt source.If Vin<Vth, cause this interrupt.
+ * \arg LPC_INT_COUNT_COMP: Couter comparator interrupt source.
+ * \param[in] NewState: New state of the specified LPC interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_lpc_init(void)
+ * {
+ * LPC_InitTypeDef LPC_InitStruct;
+ *
+ * LPC_StructInit(&LPC_InitStruct);
+ * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL;
+ * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE;
+ * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD;
+ * LPC_Init(&LPC_InitStruct);
+ * LPC_Cmd(ENABLE);
+ *
+ * LPC_ResetCounter();
+ * LPC_SetCompValue(LPC_COMP_VALUE);
+ * LPC_CounterCmd(ENABLE);
+ * LPC_INTConfig(LPC_INT_LPCOMP_CNT, ENABLE);
+ *
+ * NVIC_InitTypeDef NVIC_InitStruct;
+ * NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn;
+ * NVIC_InitStruct.NVIC_IRQChannelPriority = 2;
+ * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ * NVIC_Init(&NVIC_InitStruct);
+
+ * LPC_NvCmd(ENABLE);
+ * }
+ * \endcode
+ */
+void LPC_INTConfig(uint32_t LPC_INT, FunctionalState NewState);
+
+/**
+ * \brief Enable LPC interrupt signal to CPU NVIC.
+ * \param[in] NewState: Enable or disable RTC interrupt signal to CCU.
+ * This parameter can be: ENABLE or DISABLE..
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_lpc_init(void)
+ * {
+ * LPC_InitTypeDef LPC_InitStruct;
+ *
+ * LPC_StructInit(&LPC_InitStruct);
+ * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL;
+ * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE;
+ * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD;
+ * LPC_Init(&LPC_InitStruct);
+ * LPC_Cmd(ENABLE);
+ *
+ * LPC_ResetCounter();
+ * LPC_SetCompValue(LPC_COMP_VALUE);
+ * LPC_CounterCmd(ENABLE);
+ * LPC_INTConfig(LPC_INT_LPCOMP_CNT, ENABLE);
+ * LPC_CompOutputConfig(ENABLE);
+ *
+ * NVIC_InitTypeDef NVIC_InitStruct;
+ * NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn;
+ * NVIC_InitStruct.NVIC_IRQChannelPriority = 2;
+ * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ * NVIC_Init(&NVIC_InitStruct);
+ * }
+ * \endcode
+ */
+void LPC_INTCmd(FunctionalState NewState);
+
+
+/**
+ * \brief Enable wakeup signal to power sequence.
+ * \param[in] NewState: Enable or disable LPC wakeup signal to power sequence.
+ * This parameter can be: ENABLE or DISABLE..
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_lpc_init(void)
+ * {
+ * LPC_InitTypeDef LPC_InitStruct;
+ *
+ * LPC_StructInit(&LPC_InitStruct);
+ * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL;
+ * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE;
+ * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD;
+ * LPC_Init(&LPC_InitStruct);
+ * LPC_Cmd(ENABLE);
+ *
+ * LPC_ResetCounter();
+ * LPC_SetCompValue(LPC_COMP_VALUE);
+ * LPC_CounterCmd(ENABLE);
+ * LPC_INTConfig(LPC_INT_LPCOMP_CNT, ENABLE);
+ * LPC_INTCmd(ENABLE);
+ * LPC_WKCmd(ENABLE);
+ *
+ * NVIC_InitTypeDef NVIC_InitStruct;
+ * NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn;
+ * NVIC_InitStruct.NVIC_IRQChannelPriority = 2;
+ * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ * NVIC_Init(&NVIC_InitStruct);
+ * }
+ * \endcode
+ */
+void LPC_WKCmd(FunctionalState NewState);
+
+/**
+ * \brief Configure LPCOMP counter's comparator value.
+ * \param[in] value: LPCOMP counter's comparator value which can be 0 to 0xfff.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_lpc_init(void)
+ * {
+ * LPC_InitTypeDef LPC_InitStruct;
+ *
+ * LPC_StructInit(&LPC_InitStruct);
+ * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL;
+ * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE;
+ * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD;
+ * LPC_Init(&LPC_InitStruct);
+ * LPC_Cmd(ENABLE);
+ *
+ * LPC_ResetCounter();
+ * LPC_SetCompValue(LPC_COMP_VALUE);
+ * LPC_CounterCmd(ENABLE);
+ * }
+ * \endcode
+ */
+void LPC_SetCompValue(uint32_t value);
+
+/**
+ * \brief Reset the LPC counter.
+ * \param None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_lpc_init(void)
+ * {
+ * LPC_InitTypeDef LPC_InitStruct;
+ *
+ * LPC_StructInit(&LPC_InitStruct);
+ * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL;
+ * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE;
+ * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD;
+ * LPC_Init(&LPC_InitStruct);
+ * LPC_Cmd(ENABLE);
+ *
+ * LPC_ResetCounter();
+ * LPC_SetCompValue(LPC_COMP_VALUE);
+ * LPC_CounterCmd(ENABLE);
+ * }
+ * \endcode
+ */
+void LPC_ResetCounter(void);
+
+/**
+ * @brief Checks whether the specified LPC interrupt is set or not.
+ * @param LPC_FLAG: specifies the LPC interrupt to check.
+ * This parameter can be one of the following values:
+ * @arg LPC_FLAG_LPCOMP_AON: couter comparator AON flag.
+ * @arg LPC_FLAG_LPCOMP_CNT: couter comparator flag.
+ * @retval The new state of SPI_IT (SET or RESET).
+ */
+FlagStatus LPC_GetFlagStatus(uint32_t LPC_FLAG);
+
+/**
+ * @brief Clear the specified LPC flag.
+ * @param LPC_FLAG: specifies the LPC flag to clear.
+ * This parameter can be one of the following values:
+ * @arg LPC_FLAG_LPCOMP_CNT: couter comparator flag.
+ * @retval None
+ */
+void LPC_ClearFlag(uint32_t LPC_FLAG);
+
+/**
+ * \brief Checks whether the specified LPC interrupt is set or not.
+ * \param[in] LPC_INT: specifies the LPC interrupt to check.
+ * This parameter can be one of the following values:
+ * \arg LPC_INT_COUNT_COMP: couter comparator interrupt.
+ * \return The new state of SPI_IT (SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * #define LPC_CAPTURE_PIN P2_3
+ * #define LPC_CAPTURE_CHANNEL LPC_CAPTURE_PIN - P2_0
+
+ * #define LPC_VOLTAGE_DETECT_EDGE LPC_Vin_Over_Vth;
+ * #define LPC_VOLTAGE_DETECT_THRESHOLD LPC_2400_mV;
+ * #define LPC_COMP_VALUE 0x0A//A LPC comparator interrupt occurs every ten times
+ *
+ * void board_lpc_init(void)
+ * {
+ * Pad_Config(LPC_CAPTURE_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ * PAD_OUT_HIGH);
+ * Pinmux_Config(LPC_CAPTURE_PIN, IDLE_MODE);
+ * }
+ *
+ * void driver_lpc_init(void)
+ * {
+ * LPC_InitTypeDef LPC_InitStruct;
+ *
+ * LPC_StructInit(&LPC_InitStruct);
+ * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL;
+ * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE;
+ * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD;
+ * LPC_Init(&LPC_InitStruct);
+ * LPC_Cmd(ENABLE);
+ *
+ * LPC_ResetCounter();
+ * LPC_SetCompValue(LPC_COMP_VALUE);
+ * LPC_CounterCmd(ENABLE);
+ * LPC_INTConfig(LPC_INT_LPCOMP_CNT, ENABLE);
+ *
+ * NVIC_InitTypeDef NVIC_InitStruct;
+ * NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn;
+ * NVIC_InitStruct.NVIC_IRQChannelPriority = 2;
+ * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ * NVIC_Init(&NVIC_InitStruct);
+
+ * LPC_NvCmd(ENABLE);
+ * }
+ *
+ * void lpc_demo(void)
+ * {
+ * board_lpc_init();
+ * driver_lpc_init();
+ * }
+ *
+ * void LPCOMP_Handler(void)
+ * {
+ * if (LPC_GetINTStatus(LPC_INT_LPCOMP_CNT) == SET)
+ * {
+ * LPC_SetCompValue(LPC_GetCounter() + LPC_COMP_VALUE);
+ * LPC_ClearINTPendingBit(LPC_INT_LPCOMP_CNT);
+ * }
+ * }
+ * \endcode
+ */
+ITStatus LPC_GetINTStatus(uint32_t LPC_INT);
+
+/**
+ * \brief Clear the specified LPC interrupt pending bit.
+ * \param[in] LPC_INT: specifies the LPC interrupt to clear.
+ * This parameter can be one of the following values:
+ * \arg LPC_INT_COUNT_COMP: Couter comparator interrupt.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void lpc_demo(void)
+ * {
+ * LPC_ClearINTPendingBit(LPC_INT_COUNT_COMP);
+ * }
+ * \endcode
+ */
+void LPC_ClearINTPendingBit(uint32_t LPC_INT);
+
+/**
+ * \brief Read LPCOMP comparator value.
+ * \param None.
+ * \return LPCOMP comparator value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void lpc_demo(void)
+ * {
+ * uint16_t value = LPC_GetCompValue();
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint16_t LPC_GetCompValue(void)
+{
+ return ((LPC->LPC_CMP) & 0xFFF);
+}
+
+/**
+ * \brief Read LPC counter value.
+ * \return LPCOMP counter value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void lpc_demo(void)
+ * {
+ * uint16_t counter = LPC_GetCounter();
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint16_t LPC_GetCounter(void)
+{
+ return ((LPC->LPC_CNT) & 0xFFF);
+}
+
+/** \} */ /* End of group LPC_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_LPC_H_ */
+
+
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/inc/peripheral/rtl876x_nvic.h b/inc/peripheral/rtl876x_nvic.h
new file mode 100644
index 0000000..6e347a2
--- /dev/null
+++ b/inc/peripheral/rtl876x_nvic.h
@@ -0,0 +1,98 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_nvic.h
+* \brief The header file of NVIC driver.
+* \details This file provides all NVIC firmware functions.
+* \author elliot chen
+* \date 2015-05-19
+* \version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef _RTL876X_NVIC_H_
+#define _RTL876X_NVIC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup NVIC NVIC
+ * \brief Manage the NVIC peripheral functions.
+ * \ingroup IO
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x.h"
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup NVIC_Exported_Types Init Params Struct
+ * \ingroup NVIC
+ */
+
+/**
+ * \brief NVIC init structure definition
+ * \ingroup NVIC_Exported_Types
+ */
+
+typedef struct
+{
+ IRQn_Type NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled.
+ This parameter can be a value of \ref IRQn_Type in rtl876x.h. */
+ uint32_t NVIC_IRQChannelPriority; /*!< Specifies the priority for the IRQ channel.
+ This parameter can be a value between 0 and x as described in the table.*/
+ FunctionalState
+ NVIC_IRQChannelCmd; /*!< Enabled or disabled the IRQ channel defined in NVIC_IRQChannel.*/
+} NVIC_InitTypeDef;
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup NVIC_Exported_Functions Peripheral APIs
+ * \ingroup NVIC
+ * \{
+ */
+
+/**
+ * \brief Initializes the NVIC peripheral according to the specified
+ * parameters in NVIC_InitStruct.
+ * \param[in] NVIC_InitStruct: Pointer to a NVIC_InitTypeDef structure that contains
+ * the configuration information for the specified NVIC peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void nvic_config(void)
+ * {
+ * NVIC_InitTypeDef NVIC_InitStruct;
+ * NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn;
+ * NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ * NVIC_Init(&NVIC_InitStruct);
+ * }
+ * \endcode
+ */
+void NVIC_Init(NVIC_InitTypeDef *NVIC_InitStruct);
+
+/** \} */ /* End of group NVIC_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_NVIC_H_ */
+
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/inc/peripheral/rtl876x_pinmux.h b/inc/peripheral/rtl876x_pinmux.h
new file mode 100644
index 0000000..a23afcd
--- /dev/null
+++ b/inc/peripheral/rtl876x_pinmux.h
@@ -0,0 +1,965 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_pinmux.h
+* \brief The header file of PAD and PINMUX driver.
+* \details This file provides all PAD and PINMUX firmware functions.
+* \author Yuan
+* \date 2020-11-09
+* \version v1.0.0
+* *********************************************************************************************************
+*/
+
+
+#ifndef _RTL876X_PINMUX_H_
+#define _RTL876X_PINMUX_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup PINMUX PINMUX
+ *
+ * \brief Manage the PINMUX peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup PINMUX_Exported_Constants PINMUX Exported Constants
+ * \{
+ * \ingroup PINMUX
+ */
+
+/**
+ * \cond
+ * \brief Internal Macros
+ * \{
+ */
+/* Pad Functions */
+#define Output_Val (BIT0)
+#define Output_En (BIT1)
+#define Pull_En (BIT2)
+#define Pull_Direction (BIT3)
+#define Pull_Resistance (BIT4)
+#define WakeUp_En (BIT5)
+#define WKPOL (BIT6)
+#define SHDN (BIT8)
+#define Pin_Mode (BIT9)
+#define Pin_Debounce (BIT10)
+
+/**
+ * \}
+ * \endcond
+ */
+
+#define MAX_PIN_NUM 39
+
+/**
+ * \defgroup Pin_Function_Number Pin Function Number
+ * \ingroup PINMUX_Exported_Constants
+ * \{
+ */
+#if (IC_TYPE == IC_TYPE_BEE3)
+
+#define TOTAL_PIN_NUM 33
+
+#define IDLE_MODE 0
+#define I2C0_CLK 5
+#define I2C0_DAT 6
+#define I2C1_CLK 7
+#define I2C1_DAT 8
+#define PWM2_P 9
+#define PWM2_N 10
+#define ENPWM0_P 11
+#define ENPWM0_N 12
+#define TIM_PWM0 13
+#define TIM_PWM1 14
+#define TIM_PWM2 15
+#define TIM_PWM3 16
+#define TIM_PWM4 17
+#define TIM_PWM5 18
+#define ENPWM0 19
+#define ENPWM1 20
+#define qdec_phase_a_x 21
+#define qdec_phase_b_x 22
+#define qdec_phase_a_y 23
+#define qdec_phase_b_y 24
+#define qdec_phase_a_z 25
+#define qdec_phase_b_z 26
+#define UART1_TX 29
+#define UART1_RX 30
+#define UART1_CTS 31
+#define UART1_RTS 32
+#define IRDA_TX 33
+#define IRDA_RX 34
+#define UART0_TX 35
+#define UART0_RX 36
+#define UART0_CTS 37
+#define UART0_RTS 38
+#define SPI1_SS_N_0_MASTER 39
+#define SPI1_SS_N_1_MASTER 40
+#define SPI1_SS_N_2_MASTER 41
+#define SPI1_CLK_MASTER 42
+#define SPI1_MO_MASTER 43
+#define SPI1_MI_MASTER 44
+#define SPI0_SS_N_0_SLAVE 45
+#define SPI0_CLK_SLAVE 46
+#define SPI0_SO_SLAVE 47
+#define SPI0_SI_SLAVE 48
+#define SPI0_SS_N_0_MASTER 49
+#define SPI0_CLK_MASTER 50
+#define SPI0_MO_MASTER 51
+#define SPI0_MI_MASTER 52
+#define SPI2W_DATA 53
+#define SPI2W_CLK 54
+#define SPI2W_CS 55
+#define SWD_CLK 56
+#define SWD_DIO 57
+#define KEY_COL_0 58
+#define KEY_COL_1 59
+#define KEY_COL_2 60
+#define KEY_COL_3 61
+#define KEY_COL_4 62
+#define KEY_COL_5 63
+#define KEY_COL_6 64
+#define KEY_COL_7 65
+#define KEY_COL_8 66
+#define KEY_COL_9 67
+#define KEY_COL_10 68
+#define KEY_COL_11 69
+#define KEY_COL_12 70
+#define KEY_COL_13 71
+#define KEY_COL_14 72
+#define KEY_COL_15 73
+#define KEY_COL_16 74
+#define KEY_COL_17 75
+#define KEY_COL_18 76
+#define KEY_COL_19 77
+#define KEY_ROW_0 78
+#define KEY_ROW_1 79
+#define KEY_ROW_2 80
+#define KEY_ROW_3 81
+#define KEY_ROW_4 82
+#define KEY_ROW_5 83
+#define KEY_ROW_6 84
+#define KEY_ROW_7 85
+#define KEY_ROW_8 86
+#define KEY_ROW_9 87
+#define KEY_ROW_10 88
+#define KEY_ROW_11 89
+#define DWGPIO 90
+#define DIGI_DEBUG 95
+#define DMIC1_CLK 96
+#define DMIC1_DAT 97
+#define LRC_I_CODEC_SLAVE 98
+#define BCLK_I_CODEC_SLAVE 99
+#define SDI_CODEC_SLAVE 100
+#define SDO_CODEC_SLAVE 101
+#define BT_COEX_I_0 106
+#define BT_COEX_I_1 107
+#define BT_COEX_I_2 108
+#define BT_COEX_I_3 109
+#define BT_COEX_O_0 110
+#define BT_COEX_O_1 111
+#define BT_COEX_O_2 112
+#define BT_COEX_O_3 113
+#define PTA_I2C_CLK_SLAVE 114
+#define PTA_I2C_DAT_SLAVE 115
+#define PTA_I2C_INT_OUT 116
+#define EN_EXPA 117
+#define EN_EXLNA 118
+#define ANT_SW0 119
+#define ANT_SW1 120
+#define ANT_SW2 121
+#define ANT_SW3 122
+#define LRC_SPORT0 123
+#define BCLK_SPORT0 124
+#define ADCDAT_SPORT0 125
+#define DACDAT_SPORT0 126
+#define MCLK 127
+#else
+#define IDLE_MODE 0
+#define HCI_UART_TX 1
+#define HCI_UART_RX 2
+#define HCI_UART_CTS 3
+#define HCI_UART_RTS 4
+#define I2C0_CLK 5
+#define I2C0_DAT 6
+#define I2C1_CLK 7
+#define I2C1_DAT 8
+#define PWM2_P 9
+#define PWM2_N 10
+#define PWM3_P 11
+#define PWM3_N 12
+#define timer_pwm0 13
+#define timer_pwm1 14
+#define timer_pwm2 15
+#define timer_pwm3 16
+#define timer_pwm4 17
+#define timer_pwm5 18
+#define timer_pwm6 19
+#define timer_pwm7 20
+#define qdec_phase_a_x 21
+#define qdec_phase_b_x 22
+#define qdec_phase_a_y 23
+#define qdec_phase_b_y 24
+#define qdec_phase_a_z 25
+#define qdec_phase_b_z 26
+#define UART2_TX 27
+#define UART2_RX 28
+#define UART1_TX 29
+#define UART1_RX 30
+#define UART1_CTS 31
+#define UART1_RTS 32
+#define IRDA_TX 33
+#define IRDA_RX 34
+#define UART0_TX 35
+#define UART0_RX 36
+#define UART0_CTS 37
+#define UART0_RTS 38
+#define SPI1_SS_N_0_MASTER 39
+#define SPI1_SS_N_1_MASTER 40
+#define SPI1_SS_N_2_MASTER 41
+#define SPI1_CLK_MASTER 42
+#define SPI1_MO_MASTER 43
+#define SPI1_MI_MASTER 44
+#define SPI0_SS_N_0_SLAVE 45
+#define SPI0_CLK_SLAVE 46
+#define SPI0_SO_SLAVE 47
+#define SPI0_SI_SLAVE 48
+#define SPI0_SS_N_0_MASTER 49
+#define SPI0_CLK_MASTER 50
+#define SPI0_MO_MASTER 51
+#define SPI0_MI_MASTER 52
+#define SPI2W_DATA 53
+#define SPI2W_CLK 54
+#define SPI2W_CS 55
+#define SWD_CLK 56
+#define SWD_DIO 57
+#define KEY_COL_0 58
+#define KEY_COL_1 59
+#define KEY_COL_2 60
+#define KEY_COL_3 61
+#define KEY_COL_4 62
+#define KEY_COL_5 63
+#define KEY_COL_6 64
+#define KEY_COL_7 65
+#define KEY_COL_8 66
+#define KEY_COL_9 67
+#define KEY_COL_10 68
+#define KEY_COL_11 69
+#define KEY_COL_12 70
+#define KEY_COL_13 71
+#define KEY_COL_14 72
+#define KEY_COL_15 73
+#define KEY_COL_16 74
+#define KEY_COL_17 75
+#define KEY_COL_18 76
+#define KEY_COL_19 77
+#define KEY_ROW_0 78
+#define KEY_ROW_1 79
+#define KEY_ROW_2 80
+#define KEY_ROW_3 81
+#define KEY_ROW_4 82
+#define KEY_ROW_5 83
+#define KEY_ROW_6 84
+#define KEY_ROW_7 85
+#define KEY_ROW_8 86
+#define KEY_ROW_9 87
+#define KEY_ROW_10 88
+#define KEY_ROW_11 89
+#define DWGPIO 90
+#define LRC_SPORT1 91
+#define BCLK_SPORT1 92
+#define ADCDAT_SPORT1 93
+#define DACDAT_SPORT1 94
+#define DIGI_DEBUG 95
+#define DMIC1_CLK 96
+#define DMIC1_DAT 97
+#define LRC_I_CODEC_SLAVE 98
+#define BCLK_I_CODEC_SLAVE 99
+#define SDI_CODEC_SLAVE 100
+#define SDO_CODEC_SLAVE 101
+#define LRC_I_PCM 102
+#define BCLK_I_PCM 103
+#define UART2_CTS 104
+#define UART2_RTS 105
+#define BT_COEX_I_0 106
+#define BT_COEX_I_1 107
+#define BT_COEX_I_2 108
+#define BT_COEX_I_3 109
+#define BT_COEX_O_0 110
+#define BT_COEX_O_1 111
+#define BT_COEX_O_2 112
+#define BT_COEX_O_3 113
+#define PTA_I2C_CLK_SLAVE 114
+#define PTA_I2C_DAT_SLAVE 115
+#define PTA_I2C_INT_OUT 116
+#define DSP_GPIO_OUT 117
+#define DSP_JTCK 118
+#define DSP_JTDI 119
+#define DSP_JTDO 120
+#define DSP_JTMS 121
+#define DSP_JTRST 122
+#define LRC_SPORT0 123
+#define BCLK_SPORT0 124
+#define ADCDAT_SPORT0 125
+#define DACDAT_SPORT0 126
+#define MCLK 127
+#endif
+/** \} */
+
+/**
+ * \enum PAD_Output_Value PAD Output Value
+ *
+ * \ingroup PINMUX_Exported_Constants
+ */
+
+typedef enum _PAD_OUTPUT_VAL
+{
+ PAD_OUT_LOW,
+ PAD_OUT_HIGH
+} PAD_OUTPUT_VAL;
+
+/**
+ * \enum PAD_Output_Config PAD Output Config
+ *
+ * \ingroup PINMUX_Exported_Constants
+ */
+
+typedef enum _PAD_OUTPUT_ENABLE_Mode
+{
+ PAD_OUT_DISABLE,
+ PAD_OUT_ENABLE
+} PAD_OUTPUT_ENABLE_Mode;
+
+/**
+ * \enum PAD_Pull_Mode PAD Pull Mode
+ * \ingroup PINMUX_Exported_Constants
+ */
+typedef enum _PAD_Pull_Mode
+{
+ PAD_PULL_UP,
+ PAD_PULL_DOWN,
+ PAD_PULL_NONE,
+} PAD_Pull_Mode;
+
+/**
+ * \enum PAD_PULL_CONFIG_VAL PAD Pull Config
+ *
+ * \ingroup PINMUX_Exported_Constants
+ */
+
+typedef enum _PAD_PULL_CONFIG_VAL
+{
+ PAD_WEAK_PULL,
+ PAD_STRONG_PULL
+} PAD_PULL_VAL;
+
+
+/**
+ * \enum PAD_WakeUp_Polarity_Value PAD WakeUp Polarity
+ *
+ * \ingroup PINMUX_Exported_Constants
+ */
+
+typedef enum _PAD_WAKEUP_POL_VAL
+{
+ PAD_WAKEUP_POL_HIGH,
+ PAD_WAKEUP_POL_LOW
+} PAD_WAKEUP_POL_VAL;
+
+/**
+ * \enum PAD_Power_Mode PAD Power Mode
+ *
+ * \ingroup PINMUX_Exported_Constants
+ */
+
+typedef enum _PAD_PWR_Mode
+{
+ PAD_NOT_PWRON,
+ PAD_IS_PWRON = 1
+} PAD_PWR_Mode;
+
+/**
+ * \enum PAD_Mode PAD Mode
+ *
+ * \ingroup PINMUX_Exported_Constants
+ */
+
+typedef enum _PAD_Mode
+{
+ PAD_SW_MODE,
+ PAD_PINMUX_MODE
+} PAD_Mode;
+
+/**
+ * \enum PAD_WakeUp_Debounce_En PAD WakeUp Debounce enable
+ *
+ * \ingroup PINMUX_Exported_Constants
+ */
+
+typedef enum _PAD_WAKEUP_DEBOUNCE_EN
+{
+ PAD_WK_DEBOUNCE_DISABLE,
+ PAD_WK_DEBOUNCE_ENABLE
+} PAD_WAKEUP_DEBOUNCE_EN;
+
+
+/** \} */ /** End of group PINMUX_Exported_Constants */
+
+/**
+ * \brief
+ */
+//extern const uint8_t digi_debug_pin[32];
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup PINMUX_Exported_Functions Peripheral APIs
+ * \ingroup PINMUX
+ * \{
+ */
+
+/**
+ * \brief Configure or reset all pins to idle mode.
+ * \param None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_xxx_init(void)//XXX represents the name of the peripheral to be configured.
+ * {
+ * Pinmux_Reset();
+ * }
+ * \endcode
+ */
+void Pinmux_Reset(void);
+
+/**
+ * \brief Configure the specified pin to idle mode.
+ * \param Pin_Num: Pin number to be configured.
+ * This parameter can be one of the following values:
+ * \arg P0_0~P0_7, P1_0~P1_7, P2_0~P2_7, P3_0~P3_6, P4_0~P4_3, H0~H2.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_xxx_init(void)
+ * {
+ * Pinmux_Deinit(P2_2);
+ * }
+ * \endcode
+ */
+void Pinmux_Deinit(uint8_t Pin_Num);
+
+/**
+ * \brief Config the usage function of the selected pin.
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter can be the following:
+ * \arg P0_0~P0_7, P1_0~P1_7, P2_0~P2_7, P3_0~P3_6, P4_0~P4_3, H0~H2
+ * \param[in] Pin_Func: Use function of pin.
+ * This parameter This parameter refers to \ref Pin_Function_Number
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_uart_init(void)
+ * {
+ * Pad_Config(P2_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+ * Pad_Config(P2_1, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+
+ * Pinmux_Config(P2_0, UART0_TX);
+ * Pinmux_Config(P2_1, UART0_RX);
+ * }
+ * \endcode
+ */
+void Pinmux_Config(uint8_t Pin_Num, uint8_t Pin_Func);
+
+/**
+ * \brief Configure the relevant operation mode,
+ * peripheral circuit and output level value in software mode of the specified pin
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter can be the following:
+ * \arg P0_0~P0_7, P1_0~P1_7, P2_0~P2_7, P3_0~P3_6, P4_0~P4_3, H0~H2
+ * \param[in] AON_PAD_Mode: Use software mode or pinmux mode.
+ * This parameter can be one of the following values:
+ * \arg PAD_SW_MODE: Use software mode.
+ * \arg PAD_PINMUX_MODE: Use pinmux mode.
+ * \param[in] AON_PAD_PwrOn: Config power of pad.
+ * This parameter can be one of the following values:
+ * \arg PAD_NOT_PWRON: Shutdown power of pad.
+ * \arg PAD_IS_PWRON: Enable power of pad.
+ * \param[in] AON_PAD_Pull: config pad pull mode.
+ * This parameter can be one of the following values:
+ * \arg PAD_PULL_NONE: No pull.
+ * \arg PAD_PULL_UP: Pull this pin up.
+ * \arg PAD_PULL_DOWN: Pull this pin down.
+ * \param[in] AON_PAD_E: Config pad out put function.
+ * This parameter can be one of the following values:
+ * \arg PAD_OUT_DISABLE: Disable pin output.
+ * \arg PAD_OUT_ENABLE: Enable pad output.
+ * \param[in] AON_PAD_O: Config pin output level.
+ * This parameter can be one of the following values:
+ * \arg PAD_OUT_LOW: Pad output low.
+ * \arg PAD_OUT_HIGH: Pad output high.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_adc_init(void)
+ * {
+ * Pad_Config(P2_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW);
+ * Pad_Config(P2_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW);
+ * }
+ * \endcode
+ */
+void Pad_Config(uint8_t Pin_Num,
+ PAD_Mode AON_PAD_Mode,
+ PAD_PWR_Mode AON_PAD_PwrOn,
+ PAD_Pull_Mode AON_PAD_Pull,
+ PAD_OUTPUT_ENABLE_Mode AON_PAD_E,
+ PAD_OUTPUT_VAL AON_PAD_O);
+
+/**
+ * \brief Enable the function of the wake-up system of the specified pin.
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter can be the following:
+ * \arg P0_0~P0_7, P1_0~P1_7, P2_0~P2_7, P3_0~P3_6, P4_0~P4_3, H0~H2
+ * \param[in] Polarity: Polarity of wake-up system.
+ * This parameter can be the following:
+ * \arg PAD_WAKEUP_POL_HIGH: Use high level wakeup.
+ * \arg PAD_WAKEUP_POL_LOW: Use low level wakeup.
+ * \param[in] DebounceEn: Enable delay function.
+ * \arg PAD_WK_DEBOUNCE_DISABLE: Disable delay function.
+ * \arg PAD_WK_DEBOUNCE_ENABLE: Enable delay function.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * //IO enter dlps call back function.
+ * void io_uart_dlps_enter(void)
+ * {
+ * // Switch pad to software mode
+ * Pad_ControlSelectValue(P2_0, PAD_SW_MODE);//tx pin
+ * Pad_ControlSelectValue(P2_1, PAD_SW_MODE);//rx pin
+ *
+ * System_WakeUpPinEnable(P2_1, PAD_WAKEUP_POL_LOW, PAD_WK_DEBOUNCE_DISABLE);
+ * }
+ * \endcode
+ */
+void System_WakeUpPinEnable(uint8_t Pin_Num, uint8_t Polarity, uint8_t DebounceEn);
+
+/**
+ * \brief Disable the function of the wake-up system of the specified pin.
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter can be the following:
+ * \arg P0_0~P0_7, P1_0~P1_7, P2_0~P2_7, P3_0~P3_6, P4_0~P4_3, H0~H2
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * #define UART_RX_PIN P4_1
+ *
+ * //System interrupt handler function, for wakeup pin.
+ * void System_Handler(void)
+ * {
+ * if (System_WakeUpInterruptValue(UART_RX_PIN) == SET)
+ * {
+ * Pad_ClearWakeupINTPendingBit(UART_RX_PIN);
+ * System_WakeUpPinDisable(UART_RX_PIN);
+ * //Add user code here.
+ * }
+ * }
+ * \endcode
+ */
+void System_WakeUpPinDisable(uint8_t Pin_Num);
+
+/**
+ * \brief Get pin interrupt status.
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter can be the following:
+ * \arg P0_0~P0_7, P1_0~P1_7, P2_0~P2_7, P3_0~P3_6, P4_0~P4_3, H0~H2
+ * \return Interrupt status.
+ * \retval 1: Pin wake up system.
+ * \retval 0: The pin does not wake up the system.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * #define UART_RX_PIN P4_1
+ *
+ * //System interrupt handler function, for wakeup pin.
+ * void System_Handler(void)
+ * {
+ * if (System_WakeUpInterruptValue(UART_RX_PIN) == SET)
+ * {
+ * Pad_ClearWakeupINTPendingBit(UART_RX_PIN);
+ * System_WakeUpPinDisable(UART_RX_PIN);
+ * //Add user code here.
+ * }
+ * }
+ * \endcode
+ */
+uint8_t System_WakeUpInterruptValue(uint8_t Pin_Num);
+
+/**
+ * @brief Get debounce wake up status.
+ * @note: Call this API will clear the debunce wakeup status bit.
+ * @param None
+ * @retval Debounce wakeup status
+ *
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_xxx_init(void)
+ * {
+ * uint8_t DebounceWakeupStatus = System_DebounceWakeupStatus;
+ * }
+ * \endcode
+ */
+uint8_t System_DebounceWakeupStatus(void);
+
+/**
+ * \brief Config wak-up system debounce time.
+ * \param[in] time: Debounce time,1ms~64ms.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_xxx_init(void)
+ * {
+ * System_WakeUpDebounceTime(10);
+ * }
+ * \endcode
+ */
+void System_WakeUpDebounceTime(uint8_t time);
+
+/**
+ * \brief Configure pad output level.
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "RTL876X_Pin_Number" part.
+ * \param[in] value: Config pin output level.
+ * This parameter can be one of the following values:
+ * \arg PAD_OUT_LOW: Pad output low.
+ * \arg PAD_OUT_HIGH: Pad output high.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_xxx_init(void)
+ * {
+ * Pad_OutputControlValue(P2_0, PAD_OUT_HIGH);
+ * }
+ * \endcode
+ */
+void Pad_OutputControlValue(uint8_t Pin_Num, uint8_t value);
+
+/**
+ * \brief Enable or disable pad output mode.
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter is from P0_0 to H_2, please refer to rtl876x.h "RTL876X_Pin_Number" part.
+ * \param[in] value: This parameter sets whether the pin outputs the level in software mode.
+ * This parameter can be enumerated PAD_OUTPUT_ENABLE_Mod of the values:
+ * \arg PAD_OUT_DISABLE: Disable output.
+ * \arg PAD_OUT_ENABLE: Enable output.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void pad_demo(void)
+ * {
+ * Pad_OutputEnableValue(P2_0, PAD_OUT_ENABLE);
+ * }
+ * \endcode
+ */
+void Pad_OutputEnableValue(uint8_t Pin_Num, uint8_t value);
+
+/**
+ * \brief Enable or disable pad pull-up / pull-down resistance function.
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter is from P0_0 to PH_0, please refer to rtl876x.h "RTL876X_Pin_Number" part.
+ * \param[in] value: This parameter enable or disable the pad pin pull-up/pull-down function.
+ * This parameter can be the following:
+ * \arg DISABLE: Disable pad pull-up / pull-down function.
+ * \arg ENABLE: Enable pad pull-up / pull-down function.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_xxx_init(void)
+ * {
+ * Pad_PullEnableValue(P2_0, ENABLE);
+ * }
+ * \endcode
+ */
+void Pad_PullEnableValue(uint8_t Pin_Num, uint8_t value);
+
+/**
+ * \brief Pad pull-up/pull-down resistance function selection.
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter is from P0_0 to H_2, please refer to rtl876x.h "RTL876X_Pin_Number" part.
+ * \param[in] value: This parameter sets whether the pin pull-up or pull-down.
+ * This parameter can be the following:
+ * \arg 0: Config pad pull-up function.
+ * \arg 1: Config pad pull-down function.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_xxx_init(void)
+ * {
+ * Pad_PullUpOrDownValue(P2_0, 1);
+ * }
+ * \endcode
+ */
+void Pad_PullUpOrDownValue(uint8_t Pin_Num, uint8_t value);
+
+/**
+ * \brief Configure the strength of pull-up/pull-down resistance.
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "RTL876X_Pin_Number" part.
+ * \param[in] value: This parameter sets the strength of pull-up/pull-down resistance.
+ * This parameter can be the following:
+ * \arg PAD_WEAK_PULL: Resistance weak pull.
+ * \arg PAD_STRONG_PULL: Resistance strong pull.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_xxx_init(void)
+ * {
+ * Pad_PullConfigValue(P2_0, PAD_STRONG_PULL);
+ * }
+ * \endcode
+ */
+void Pad_PullConfigValue(uint8_t Pin_Num, uint8_t value);
+
+/**
+ * \brief Set pin power mode.
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "RTL876X_Pin_Number" part.
+ * \param[in] value: This parameter sets the power supply mode of the pin,
+ * and the value is enumeration PAD_PWR_Mode One of the values.
+ * \arg PAD_NOT_PWRON: Power off.
+ * \arg PAD_IS_PWRON: Power on.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_xxx_init(void)
+ * {
+ * Pad_PowerOrShutDownValue(P2_0, PAD_NOT_PWRON);
+ * }
+ * \endcode
+ */
+void Pad_PowerOrShutDownValue(uint8_t Pin_Num, uint8_t value);
+
+/**
+ * \brief Set pin mode.
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter is from P0_0 to H_2, please refer to rtl876x.h "RTL876X_Pin_Number" part.
+ * \param[in] value: This parameter sets the pin mode.
+ * This parameter can be the following:
+ * \arg PAD_SW_MODE: Software mode.
+ * \arg PAD_PINMUX_MODE: Pinmux mode.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_xxx_init(void)
+ * {
+ * Pad_ControlSelectValue(P2_0, PAD_SW_MODE);
+ * }
+ * \endcode
+ */
+void Pad_ControlSelectValue(uint8_t Pin_Num, uint8_t value);
+
+/**
+ * \brief Enable the function of the wake-up system of the specified pin.
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "RTL876X_Pin_Number" part.
+ * \param[in] value: Enable wake-up system function.
+ * \arg 0:Disable wake-up system function.
+ * \arg 1:Enable wake-up system function.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_xxx_init(void)
+ * {
+ * Pad_WakeupEnableValue(P2_0, 1);
+ * }
+ * \endcode
+ */
+void Pad_WakeupEnableValue(uint8_t Pin_Num, uint8_t value);
+
+/**
+ * \brief Set polarity of wake-up system.
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "RTL876X_Pin_Number" part.
+ * \param[in] Polarity: Polarity of wake-up system.
+ * This parameter can be the following:
+ * \arg PAD_WAKEUP_POL_LOW:Use low level wakeup.
+ * \arg PAD_WAKEUP_POL_HIGH: Use high level wakeup.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_xxx_init(void)
+ * {
+ * Pad_WakeupPolarityValue(P2_0, PAD_WAKEUP_POL_HIGH);
+ * }
+ * \endcode
+ */
+void Pad_WakeupPolarityValue(uint8_t Pin_Num, uint8_t value);
+
+/**
+ * \brief Config pin delay function.
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "RTL876X_Pin_Number" part.
+ * \param[in] value: Enable delay function.
+ * \arg 0:Disable delay function.
+ * \arg 1:Enable delay function.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_xxx_init(void)
+ * {
+ * Pad_WKDebounceConfig(P2_0, 1);
+ * }
+ * \endcode
+ */
+void Pad_WKDebounceConfig(uint8_t Pin_Num, uint8_t value);
+
+/**
+ * \brief Get pin interrupt status, function is the same as \see system_WakeUpInterruptValue.
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter can be the following:
+ * \arg P0_0~P0_7, P1_0~P1_7, P2_0~P2_7, P3_0~P3_6, P4_0~P4_3, H0~H2
+ * \return Interrupt status.
+ * \retval 0: The pin does not wake up the system.
+ * \retval 1: Pin wake up system.
+ */
+uint8_t Pad_WakeupInterruptValue(uint8_t Pin_Num);
+
+/**
+ * @brief Check debounce wake up status.
+ * @note: Call this API will clear the debunce wakeup status bit.
+ * @param None
+ * @retval Debounce wakeup status
+ */
+uint8_t Pad_DebounceWakeupStatus(void);
+
+/**
+ * \brief Clear the interrupt pendign bit of the specified pin
+ * \param[in] Pin_Num: Pin number to be configured.
+ * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "RTL876X_Pin_Number" part.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_xxx_init(void)
+ * {
+ * Pad_ClearWakeupINTPendingBit(P2_0);
+ * }
+ * \endcode
+ */
+void Pad_ClearWakeupINTPendingBit(uint8_t Pin_Num);
+
+/**
+ * \brief Clear all wake up pin interrupt pending bit.
+ * \param[in] Pin_Num: pin number.
+ * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "Pin_Number" part.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_xxx_init(void)
+ * {
+ * Pad_ClearAllWakeupINT();
+ * }
+ * \endcode
+ */
+void Pad_ClearAllWakeupINT(void);
+
+void Pinmux_8080Control(uint32_t value, uint8_t VSYNC, uint8_t RD);
+
+/**
+ * \brief Spic0 master enable.
+ * \param[in] value: 0:Disable 1:Enable.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void io_demo(void)
+ * {
+ * Spic0_control(1);
+ * }
+ * \endcode
+ */
+void Spic0_control(uint8_t value);
+
+/**
+ * \brief Spic1 master enable.
+ * \param[in] value: 0:Disable 1:Enable.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void io_demo(void)
+ * {
+ * Spic1_control(1);
+ * }
+ * \endcode
+ */
+void Spic1_control(uint8_t value);
+
+
+/** \} */ /* End of group PINMUX_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_PINMUX_H_ */
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor *****END OF FILE****/
+
diff --git a/inc/peripheral/rtl876x_qdec.h b/inc/peripheral/rtl876x_qdec.h
new file mode 100644
index 0000000..95331a0
--- /dev/null
+++ b/inc/peripheral/rtl876x_qdec.h
@@ -0,0 +1,597 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_qdec.h
+* \brief The header file of the peripheral QDECODER driver.
+* \details This file provides all QDECODER firmware functions.
+* \author howie wang
+* \date 2016-05-10
+* \version v1.0
+* *********************************************************************************************************
+*/
+
+
+#ifndef _RTL876X_QDECODER_H_
+#define _RTL876X_QDECODER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup QDEC QDEC
+ *
+ * \brief Manage the QDEC peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup QDEC_Exported_Types Init Params Struct
+ *
+ * \ingroup QDEC
+ */
+
+/**
+ * \brief Qdecoder init structure definition.
+ *
+ * \ingroup QDEC_Exported_Types
+ */
+typedef struct
+{
+ uint16_t scanClockDiv;
+ uint16_t debounceClockDiv;
+ uint8_t axisConfigX; /*!< Specifies the axis X function.
+ This parameter can be a value of ENABLE or DISABLE */
+ uint8_t axisConfigY; /*!< Specifies the axis Y function.
+ This parameter can be a value of ENABLE or DISABLE */
+ uint8_t axisConfigZ; /*!< Specifies the axis Z function.
+ This parameter can be a value of ENABLE or DISABLE */
+ uint8_t autoLoadInitPhase; /*!< Specifies Auto-load Initphase function .
+ This parameter can be a value of ENABLE or DISABLE */
+ uint16_t counterScaleX; /*!< Specifies the axis X counter scale.
+ This parameter can be a value of \ref QDEC_Axis_counter_Scale */
+ uint16_t debounceEnableX; /*!< Specifies the axis X debounce.
+ This parameter can be a value of \ref Qdec_Debounce */
+ uint16_t debounceTimeX; /*!< Specifies the axis X debounce time. */
+ uint16_t initPhaseX; /*!< Specifies the axis X function.
+ This parameter can be a value of \ref Qdec_init_phase */
+ uint16_t counterScaleY; /*!< Specifies the axis Y counter scale.
+ This parameter can be a value of \ref QDEC_Axis_counter_Scale */
+ uint16_t debounceEnableY; /*!< Specifies the axis Y debounce.
+ This parameter can be a value of \ref Qdec_Debounce */
+ uint16_t debounceTimeY; /*!< Specifies the axis Y debounce time. */
+ uint16_t initPhaseY; /*!< Specifies the axis Y function.
+ This parameter can be a value of \ref Qdec_init_phase */
+ uint16_t counterScaleZ; /*!< Specifies the axis Z counter scale.
+ This parameter can be a value of \ref QDEC_Axis_counter_Scale */
+ uint16_t debounceEnableZ; /*!< Specifies the axis Z debounce.
+ This parameter can be a value of \ref Qdec_Debounce */
+ uint16_t debounceTimeZ; /*!< Specifies the axis Z debounce time. */
+ uint16_t initPhaseZ; /*!< Specifies the axis Z function.
+ This parameter can be a value of \ref Qdec_init_phase */
+} QDEC_InitTypeDef;
+
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup QDEC_Exported_Constants Macro Definitions
+ *
+ * \ingroup QDEC
+ */
+
+#define IS_QDEC_PERIPH(PERIPH) ((PERIPH) == QDEC)
+
+/** \defgroup QDEC_Interrupts_Definition QDEC Interrupts Definition
+ * \{
+ * \ingroup QDEC_Exported_Constants
+ */
+#define QDEC_X_INT_NEW_DATA BIT(0)//get New data and state change
+#define QDEC_X_INT_ILLEAGE BIT(1)//illeage
+#define QDEC_Y_INT_NEW_DATA BIT(2)//get New data and state change
+#define QDEC_Y_INT_ILLEAGE BIT(3)//illeage
+#define QDEC_Z_INT_NEW_DATA BIT(4)//get New data and state change
+#define QDEC_Z_INT_ILLEAGE BIT(5)//illeage
+/** \} */
+
+#define IS_QDEC_INT_CONFIG(CONFIG) (((CONFIG) == QDEC_X_INT_NEW_DATA) || ((CONFIG) == QDEC_X_INT_ILLEAGE)\
+ || ((CONFIG) == QDEC_Y_INT_NEW_DATA) || ((CONFIG) == QDEC_Y_INT_ILLEAGE)\
+ || ((CONFIG) == QDEC_Z_INT_NEW_DATA) || ((CONFIG) == QDEC_Z_INT_ILLEAGE))
+
+/** \defgroup QDEC_Interrupts_Mask QDEC Interrupts Mask
+ * \{
+ * \ingroup QDEC_Exported_Constants
+ */
+#define QDEC_X_CT_INT_MASK BIT(0)//get New data and state change
+#define QDEC_X_ILLEAGE_INT_MASK BIT(4)//illeage
+#define QDEC_Y_CT_INT_MASK BIT(1)//get New data and state change
+#define QDEC_Y_ILLEAGE_INT_MASK BIT(5)//illeage
+#define QDEC_Z_CT_INT_MASK BIT(2)//get New data and state change
+#define QDEC_Z_ILLEAGE_INT_MASK BIT(6)//illeage
+/** \} */
+
+#define IS_QDEC_INT_MASK_CONFIG(CONFIG) (((CONFIG) == QDEC_X_CT_INT_MASK) || ((CONFIG) == QDEC_X_ILLEAGE_INT_MASK)\
+ || ((CONFIG) == QDEC_Y_CT_INT_MASK) || ((CONFIG) == QDEC_Y_ILLEAGE_INT_MASK)\
+ || ((CONFIG) == QDEC_Z_CT_INT_MASK) || ((CONFIG) == QDEC_Z_ILLEAGE_INT_MASK))
+/** \defgroup QDEC_Axis_counter_Scale QDEC Axis Counter
+ * \{
+ * \ingroup QDEC_Exported_Constants
+ */
+#define CounterScale_2_Phase true
+#define CounterScale_1_Phase false
+/** \} */
+
+/** \defgroup QDEC_Debounce QDEC Debounce
+ * \{
+ * \ingroup QDEC_Exported_Constants
+ */
+#define Debounce_Enable true
+#define Debounce_Disable false
+/** \} */
+
+/** \defgroup QDEC_Manual_Phase QDEC manual phase
+ * \{
+ * \ingroup QDEC_Exported_Constants
+ */
+
+#define manualPhaseEnable true
+#define manualPhaseDisable false
+/** \} */
+
+/** \defgroup Qdec_Init_Phase Qdec Init Phase
+ * \{
+ * \ingroup QDEC_Exported_Constants
+ */
+
+#define phaseMode0 0 //phase 00
+#define phaseMode1 1 //phase 01
+#define phaseMode2 2 //phase 10
+#define phaseMode3 3 //phase 11
+/** \} */
+
+/** \defgroup QDEC_Clr_Flag Qdec Clr Flag
+ * \{
+ * \ingroup QDEC_Exported_Constants
+ */
+#define QDEC_CLR_ILLEGAL_CT_X ((uint32_t)(1 << 20))
+#define QDEC_CLR_ILLEGAL_CT_Y ((uint32_t)(1 << 21))
+#define QDEC_CLR_ILLEGAL_CT_Z ((uint32_t)(1 << 22))
+
+#define QDEC_CLR_ACC_CT_X ((uint32_t)(1 << 16))
+#define QDEC_CLR_ACC_CT_Y ((uint32_t)(1 << 17))
+#define QDEC_CLR_ACC_CT_Z ((uint32_t)(1 << 18))
+
+#define QDEC_CLR_ILLEGAL_INT_X ((uint32_t)(1 << 12))
+#define QDEC_CLR_ILLEGAL_INT_Y ((uint32_t)(1 << 13))
+#define QDEC_CLR_ILLEGAL_INT_Z ((uint32_t)(1 << 14))
+
+#define QDEC_CLR_UNDERFLOW_X ((uint32_t)(1 << 8))
+#define QDEC_CLR_UNDERFLOW_Y ((uint32_t)(1 << 9))
+#define QDEC_CLR_UNDERFLOW_Z ((uint32_t)(1 << 10))
+
+#define QDEC_CLR_OVERFLOW_X ((uint32_t)(1 << 4))
+#define QDEC_CLR_OVERFLOW_Y ((uint32_t)(1 << 5))
+#define QDEC_CLR_OVERFLOW_Z ((uint32_t)(1 << 6))
+
+#define QDEC_CLR_NEW_CT_X ((uint32_t)(1 << 0))
+#define QDEC_CLR_NEW_CT_Y ((uint32_t)(1 << 1))
+#define QDEC_CLR_NEW_CT_Z ((uint32_t)(1 << 2))
+/** \} */
+
+#define IS_QDEC_INT_CLR_CONFIG(CONFIG) (((CONFIG) == QDEC_CLR_ACC_CT_X) || ((CONFIG) == QDEC_CLR_ACC_CT_Y)\
+ || ((CONFIG) == QDEC_CLR_ACC_CT_Z) || ((CONFIG) == QDEC_CLR_ILLEGAL_INT_Y)\
+ || ((CONFIG) == QDEC_CLR_ILLEGAL_INT_Z) || ((CONFIG) == QDEC_CLR_UNDERFLOW_X)\
+ || ((CONFIG) == QDEC_CLR_UNDERFLOW_Y) || ((CONFIG) == QDEC_CLR_UNDERFLOW_Z)\
+ || ((CONFIG) == QDEC_CLR_OVERFLOW_X) || ((CONFIG) == QDEC_CLR_OVERFLOW_Y)\
+ || ((CONFIG) == QDEC_CLR_OVERFLOW_Z) || ((CONFIG) == QDEC_CLR_NEW_CT_X)\
+ || ((CONFIG) == QDEC_CLR_NEW_CT_Y) || ((CONFIG) == QDEC_CLR_NEW_CT_Z))
+
+/** \defgroup QDEC_Flag QDEC Flag
+ * \{
+ * \ingroup QDEC_Exported_Constants
+ */
+
+#define QDEC_FLAG_NEW_CT_STATUS_X ((uint32_t)(1 << 0))
+#define QDEC_FLAG_NEW_CT_STATUS_Y ((uint32_t)(1 << 1))
+#define QDEC_FLAG_NEW_CT_STATUS_Z ((uint32_t)(1 << 2))
+#define QDEC_FLAG_OVERFLOW_X ((uint32_t)(1 << 3))
+#define QDEC_FLAG_OVERFLOW_Y ((uint32_t)(1 << 4))
+#define QDEC_FLAG_OVERFLOW_Z ((uint32_t)(1 << 5))
+#define QDEC_FLAG_UNDERFLOW_X ((uint32_t)(1 << 6))
+#define QDEC_FLAG_UNDERFLOW_Y ((uint32_t)(1 << 7))
+#define QDEC_FLAG_UNDERFLOW_Z ((uint32_t)(1 << 8))
+#define QDEC_FLAG_AUTO_STATUS_X ((uint32_t)(1 << 9))
+#define QDEC_FLAG_AUTO_STATUS_Y ((uint32_t)(1 << 10))
+#define QDEC_FLAG_AUTO_STATUS_Z ((uint32_t)(1 << 11))
+#define QDEC_FLAG_ILLEGAL_STATUS_X ((uint32_t)(1 << 12))
+#define QDEC_FLAG_ILLEGAL_STATUS_Y ((uint32_t)(1 << 13))
+#define QDEC_FLAG_ILLEGAL_STATUS_Z ((uint32_t)(1 << 14))
+/** \} */
+
+#define IS_QDEC_CLR_INT_STATUS(INT) (((INT) == QDEC_FLAG_ILLEGAL_STATUS_X) || ((INT) == QDEC_FLAG_ILLEGAL_STATUS_Y)\
+ || ((INT) == QDEC_FLAG_ILLEGAL_STATUS_Z) || ((INT) == QDEC_FLAG_NEW_CT_STATUS_X)\
+ || ((INT) == QDEC_FLAG_NEW_CT_STATUS_Y) || ((INT) == QDEC_FLAG_NEW_CT_STATUS_Z)\
+ || ((INT) == QDEC_FLAG_OVERFLOW_X) || ((INT) == QDEC_FLAG_OVERFLOW_Y)\
+ || ((INT) == QDEC_FLAG_OVERFLOW_Z) || ((INT) == QDEC_FLAG_UNDERFLOW_X)\
+ || ((INT) == QDEC_FLAG_UNDERFLOW_Y) || ((INT) == QDEC_FLAG_UNDERFLOW_Z)\
+ || ((INT) == QDEC_FLAG_AUTO_STATUS_X) || ((INT) == QDEC_FLAG_AUTO_STATUS_Y)\
+ || ((INT) == QDEC_FLAG_AUTO_STATUS_Z))
+
+/** \defgroup QDEC_Axis QDEC Axis
+ * \{
+ * \ingroup QDEC_Exported_Constants
+ */
+
+#define QDEC_AXIS_X ((uint32_t)(1 << 0))
+#define QDEC_AXIS_Y ((uint32_t)(1 << 2))
+#define QDEC_AXIS_Z ((uint32_t)(1 << 3))
+/** \} */
+
+/** \defgroup QDEC_Axis_Direction QDEC Axis Direction
+ * \{
+ * \ingroup QDEC_Exported_Constants
+ */
+
+#define QDEC_AXIS_DIR_UP ((uint16_t)0x01)
+#define QDEC_AXIS_DIR_DOWN ((uint16_t)0x00)
+/** \} */
+
+#define IS_QDEC_AXIS_DIR(QDEC_AXIS) ((QDEC_AXIS == QDEC_AXIS_DIR_UP) || (QDEC_AXIS == QDEC_AXIS_DIR_DOWN))
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup QDEC_Exported_Functions Peripheral APIs
+ * \{
+ * \ingroup QDEC
+ */
+
+/**
+ * \brief Deinitializes the Qdecoder peripheral registers to their default reset values(turn off Qdecoder clock).
+ * \param[in] QDECx: Selected Qdecoder peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_qdec_init(void)
+ * {
+ * QDEC_DeInit();
+ * }
+ * \endcode
+ */
+void QDEC_DeInit(QDEC_TypeDef *QDECx);
+
+/**
+ * \brief Initializes the Qdecoder peripheral according to the specified
+ * parameters in the QDEC_InitStruct
+ * \param[in] QDECx: Selected Qdecoder peripheral.
+ * \param[in] QDEC_InitStruct: Pointer to a QDEC_InitStruct structure that
+ * contains the configuration information for the specified Qdecoder peripheral
+ * \return None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_qdec_init(void)
+ * {
+ * QDEC_DeInit(QDEC);
+ * RCC_PeriphClockCmd(APBPeriph_QDEC, APBPeriph_QDEC_CLOCK, ENABLE);
+ *
+ * QDEC_InitTypeDef QDEC_InitStruct;
+ * QDEC_StructInit(&QDEC_InitStruct);
+ * QDEC_InitStruct.axisConfigY = ENABLE;
+ * QDEC_InitStruct.debounceEnableY = Debounce_Enable;
+ * QDEC_Init(QDEC, &QDEC_InitStruct);
+ *
+ * QDEC_Cmd(QDEC, QDEC_AXIS_Y, ENABLE);
+ * }
+ * \endcode
+ */
+void QDEC_Init(QDEC_TypeDef *QDECx, QDEC_InitTypeDef *QDEC_InitStruct);
+
+/**
+ * \brief Fills each QDEC_InitStruct member with its default value.
+ * \param[in] QDEC_InitStruct: Pointer to a QDEC_InitStruct structure which will be initialized.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_qdec_init(void)
+ * {
+ * QDEC_DeInit(QDEC);
+ * RCC_PeriphClockCmd(APBPeriph_QDEC, APBPeriph_QDEC_CLOCK, ENABLE);
+ *
+ * QDEC_InitTypeDef QDEC_InitStruct;
+ * QDEC_StructInit(&QDEC_InitStruct);
+ * QDEC_InitStruct.axisConfigY = ENABLE;
+ * QDEC_InitStruct.debounceEnableY = Debounce_Enable;
+ * QDEC_Init(QDEC, &QDEC_InitStruct);
+ *
+ * QDEC_Cmd(QDEC, QDEC_AXIS_Y, ENABLE);
+ * }
+ * \endcode
+ */
+void QDEC_StructInit(QDEC_InitTypeDef *QDEC_InitStruct);
+
+/**
+ * \brief Enables or disables the specified Qdecoder interrupt source.
+ * \param[in] QDECx: Selected Qdecoder peripheral.
+ * \param[in] QDEC_IT: Specifies the QDECODER interrupts sources to be enabled or disabled.
+ * This parameter parameter can be one of the following values:
+ * \arg QDEC_X_INT_NEW_DATA: The counter interrupt for X axis.
+ * \arg QDEC_X_INT_ILLEAGE: The illegal interrupt for X axis.
+ * \arg QDEC_Y_INT_NEW_DATA: The counter interrupt for Y axis.
+ * \arg QDEC_Y_INT_ILLEAGE: The illegal interrupt for Y axis.
+ * \arg QDEC_Z_INT_NEW_DATA: The counter interrupt for Z axis.
+ * \arg QDEC_Z_INT_ILLEAGE: The illegal interrupt for Z axis.
+ * \param[in] newState: New state of the specified QDECODER interrupt.
+ * This parameter parameter can be: ENABLE or DISABLE.
+ * \return None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_qdec_init(void)
+ * {
+ * QDEC_INTConfig(QDEC, QDEC_Y_INT_NEW_DATA, ENABLE);
+ * }
+ * \endcode
+ */
+void QDEC_INTConfig(QDEC_TypeDef *QDECx, uint32_t QDEC_IT, FunctionalState newState);
+
+/**
+ * \brief Check whether the specified Qdecoder flag is set.
+ * \param[in] QDECx: Selected Qdecoder peripheral.
+ * \param[in] QDEC_FLAG: Specifies the flag to check.
+ * This parameter can be one of the following values:
+ * \arg QDEC_FLAG_NEW_CT_STATUS_X: Status of the counter interrupt for X axis.
+ * \arg QDEC_FLAG_NEW_CT_STATUS_Y: Status of the counter interrupt for Y axis.
+ * \arg QDEC_FLAG_NEW_CT_STATUS_Z: Status of the counter interrupt for Z axis.
+ * \arg QDEC_FLAG_ILLEGAL_STATUS_X: Status of the illegal interrupt for X axis.
+ * \arg QDEC_FLAG_ILLEGAL_STATUS_Y: Status of the illegal interrupt for Y axis.
+ * \arg QDEC_FLAG_ILLEGAL_STATUS_Z: Status of the illegal interrupt for Z axis.
+ * \arg QDEC_FLAG_OVERFLOW_X: The overflow flag for x-axis accumulation counter.
+ * \arg QDEC_FLAG_OVERFLOW_Y: The overflow flag for y-axis accumulation counter.
+ * \arg QDEC_FLAG_OVERFLOW_Z: The overflow flag for z-axis accumulation counter.
+ * \arg QDEC_FLAG_UNDERFLOW_X: The underflow flag for x-axis accumulation counter.
+ * \arg QDEC_FLAG_UNDERFLOW_Y: The underflow flag for y-axis accumulation counter.
+ * \arg QDEC_FLAG_UNDERFLOW_Z: The underflow flag for z-axis accumulation counter.
+ * \retval The new state of QDEC_FLAG (SET or RESET).
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void qdec_demo(void)
+ * {
+ * FlagStatus flag_status = QDEC_GetFlagState(QDEC, QDEC_Y_INT_NEW_DATA, ENABLE);
+ * }
+ * \endcode
+ */
+FlagStatus QDEC_GetFlagState(QDEC_TypeDef *QDECx, uint32_t QDEC_FLAG);
+
+/**
+ * \brief Enables or disables mask the specified Qdecoder axis interrupts.
+ * \param[in] QDECx: Selected Qdecoder peripheral.
+ * \param[in] QDEC_AXIS: Specifies the Qdecoder axis.
+ * This parameter can be one or logical OR of the following values:
+ * \arg QDEC_X_CT_INT_MASK: The x-axis counter interrupt mask.
+ * \arg QDEC_X_ILLEAGE_INT_MASK: The x-axis illegal interrupt mask.
+ * \arg QDEC_Y_CT_INT_MASK: The y-axis counter interrupt mask.
+ * \arg QDEC_Y_ILLEAGE_INT_MASK: The y-axis illegal interrupt mask.
+ * \arg QDEC_Z_CNT_INT_MASK: The z-axis counter interrupt mask.
+ * \arg QDEC_Z_ILLEAGE_INT_MASK: The z-axis illegal interrupt mask.
+ * \param[in] newState: New state of the specified Qdecoder interrupts mask.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void qdec_demo(void)
+ * {
+ *
+ * QDEC_INTMask(QDEC, QDEC_X_CT_INT_MASK, ENABLE);
+ *
+ * }
+ * \endcode
+ */
+void QDEC_INTMask(QDEC_TypeDef *QDECx, uint32_t QDEC_AXIS, FunctionalState newState);
+
+/**
+ * \brief Enable or disable the selected Qdecoder axis(x/y/z).
+ * \param[in] QDECx: Selected Qdecoder peripheral.
+ * \param[in] QDEC_AXIS: Specifies the Qdecoder axis.
+ * This parameter can be one of the following values:
+ * \arg QDEC_AXIS_X: The qdecoder X axis.
+ * \arg QDEC_AXIS_Y: The qdecoder Y axis.
+ * \arg QDEC_AXIS_Z: The qdecoder Z axis.
+ * \param[in] newState: New state of the selected Qdecoder axis.
+ * This parameter can be : ENABLE or DISABLE.
+ * \retturn The count of the axis.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void qdec_demo(void)
+ * {
+ * QDEC_Cmd(QDEC, QDEC_AXIS_X, ENABLE);
+ * }
+ * \endcode
+ */
+void QDEC_Cmd(QDEC_TypeDef *QDECx, uint32_t QDEC_AXIS,
+ FunctionalState newState);
+
+/**
+ * \brief Clear Qdecoder interrupt pending bit.
+ * \param[in] QDECx: Selected Qdecoder peripheral.
+ * \param[in] QDEC_FLAG: Specifies the flag to clear.
+ * This parameter parameter can be one of the following values:
+ * \arg QDEC_CLR_OVERFLOW_X: The overflow flag for x-axis accumulation counter.
+ * \arg QDEC_CLR_OVERFLOW_Y: The overflow flag for y-axis accumulation counter.
+ * \arg QDEC_CLR_OVERFLOW_Z: The overflow flag for z-axis accumulation counter.
+ * \arg QDEC_CLR_ILLEGAL_INT_X: The illegal interrupt for X axis.
+ * \arg QDEC_CLR_ILLEGAL_INT_Y: The illegal interrupt for Y axis.
+ * \arg QDEC_CLR_ILLEGAL_INT_Z: The illegal interrupt for Z axis.
+ * \arg QDEC_CLR_UNDERFLOW_X: The underflow flag for x-axis accumulation counter.
+ * \arg QDEC_CLR_UNDERFLOW_Y: The underflow flag for y-axis accumulation counter.
+ * \arg QDEC_CLR_UNDERFLOW_Z: The underflow flag for z-axis accumulation counter.
+ * \arg QDEC_CLR_NEW_CT_X: The counter interrupt for X axis.
+ * \arg QDEC_CLR_NEW_CT_Y: The counter interrupt for Y axis.
+ * \arg QDEC_CLR_NEW_CT_Z: The counter interrupt for Z axis.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void qdec_demo(void)
+ * {
+ * QDEC_ClearINTPendingBit(QDEC, QDEC_CLR_OVERFLOW_X);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void QDEC_ClearINTPendingBit(QDEC_TypeDef *QDECx, uint32_t QDEC_CLR_INT)
+{
+ /* Check the parameters */
+ assert_param(IS_QDEC_PERIPH(QDECx));
+ assert_param(IS_QDEC_CLR_INT_STATUS(QDEC_CLR_INT));
+
+ QDECx->INT_CLR |= QDEC_CLR_INT;
+
+ return;
+}
+
+/**
+ * \brief Get Qdecoder Axis(x/y/z) direction.
+ * \param[in] QDECx: Selected Qdecoder peripheral.
+ * \param[in] QDEC_AXIS: Specifies the Qdecoder axis.
+ * This parameter parameter can be one of the following values:
+ * \arg QDEC_AXIS_X: The qdecoder X axis.
+ * \arg QDEC_AXIS_Y: The qdecoder Y axis.
+ * \arg QDEC_AXIS_Z: The qdecoder Z axis.
+ * \return The direction of the axis.
+ * This parameter parameter can be one of the following values:
+ * \retval QDEC_AXIS_DIR_UP: The axis is rolling up.
+ * \retval QDEC_AXIS_DIR_DOWN: The axis is rolling down.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void qdec_demo(void)
+ * {
+ * uint16_t dir = QDEC_GetAxisDirection(QDEC, QDEC_AXIS_X);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint16_t QDEC_GetAxisDirection(QDEC_TypeDef *QDECx, uint32_t QDEC_AXIS)
+{
+ /* Check the parameters */
+ assert_param(IS_QDEC_PERIPH(QDECx));
+ assert_param(IS_QDEC_AXIS_DIR(QDEC_AXIS));
+
+ return ((*((volatile uint32_t *)(&QDECx->REG_SR_X) + QDEC_AXIS / 2) & (1 << 16)) == BIT(16));
+}
+
+/**
+ * \brief Get Qdecoder Axis(x/y/z) count.
+ * \param[in] QDECx: Selected Qdecoder peripheral.
+ * \param[in] QDEC_AXIS: Specifies the Qdecoder axis.
+ * This parameter parameter can be one of the following values:
+ * \arg QDEC_AXIS_X: The qdecoder X axis.
+ * \arg QDEC_AXIS_Y: The qdecoder Y axis.
+ * \arg QDEC_AXIS_Z: The qdecoder Z axis.
+ * \return The count of the axis.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void qdec_demo(void)
+ * {
+ * uint16_t counter = QDEC_GetAxisCount(QDEC, QDEC_AXIS_X);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint16_t QDEC_GetAxisCount(QDEC_TypeDef *QDECx, uint32_t QDEC_AXIS)
+{
+ /* Check the parameters */
+ assert_param(IS_QDEC_PERIPH(QDECx));
+ assert_param(IS_QDEC_AXIS_DIR(QDEC_AXIS));
+
+ return ((uint16_t)(*((volatile uint32_t *)(&QDECx->REG_SR_X) + QDEC_AXIS / 2)));
+}
+
+/**
+ * \brief Pause or resume Qdecoder Axis(x/y/z).
+ * \param[in] QDECx: Selected Qdecoder peripheral.
+ * \param[in] QDEC_AXIS: Specifies the Qdecoder axis.
+ * This parameter parameter can be one of the following values:
+ * \arg QDEC_AXIS_X: The qdecoder X axis.
+ * \arg QDEC_AXIS_Y: The qdecoder Y axis.
+ * \arg QDEC_AXIS_Z: The qdecoder Z axis.
+ * \param[in] newState: New state of the specified Qdecoder Axis.
+ * This parameter parameter can be one of the following values:
+ * \arg ENABLE: Pause.
+ * \arg DISABLE: Resume.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void qdec_demo(void)
+ * {
+ * QDEC_CounterPauseCmd(QDEC, QDEC_AXIS_X, ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void QDEC_CounterPauseCmd(QDEC_TypeDef *QDECx, uint32_t QDEC_AXIS,
+ FunctionalState newState)
+{
+ /* Check the parameters */
+ assert_param(IS_QDEC_PERIPH(QDECx));
+ assert_param(IS_QDEC_AXIS_DIR(QDEC_AXIS));
+
+ if (newState == ENABLE)
+ {
+ *((volatile uint32_t *)(&QDECx->REG_CR_X) + QDEC_AXIS / 2) |= BIT3;
+ }
+ else
+ {
+ *((volatile uint32_t *)(&QDECx->REG_CR_X) + QDEC_AXIS / 2) &= ~BIT3;
+ }
+}
+
+/** \} */ /* End of group QDEC_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_QDECODER_H_ */
+
+
+/******************* (C) COPYRIGHT 2016 Realtek Semiconductor *****END OF FILE****/
+
+
+
diff --git a/inc/peripheral/rtl876x_rcc.h b/inc/peripheral/rtl876x_rcc.h
new file mode 100644
index 0000000..43fadff
--- /dev/null
+++ b/inc/peripheral/rtl876x_rcc.h
@@ -0,0 +1,470 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_rcc.h
+* \brief The header file of the clock control and reset driver.
+* \details This file provides all peripheral clock control firmware functions.
+* \author tifnan_ge
+* \date 2015-05-16
+* \version v0.1
+* *********************************************************************************************************
+*/
+
+
+#ifndef _RTL876X_RCC_H_
+#define _RTL876X_RCC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup RCC RCC
+ *
+ * \brief Manage the RCC peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup RCC_Exported_Constants Macro Definitions
+ *
+ * \ingroup RCC
+ */
+
+/**
+ * \defgroup RCC_Peripheral_Clock RCC Peripheral Clock
+ * \{
+ * \ingroup RCC_Exported_Constants
+ */
+
+#define APBPeriph_I2S0_CLOCK ((uint32_t)((1 << 5) | (1 << 8) | (0x00 << 29)))
+#define APBPeriph_I2S1_CLOCK ((uint32_t)((1 << 6) | (1 << 8) | (0x00 << 29)))
+#define APBPeriph_CODEC_CLOCK ((uint32_t)((1 << 4) | (0x00 << 29)))
+
+#define APBPeriph_GPIO_CLOCK ((uint32_t)((0x01 << 24) | (0x01 << 29)))
+#define APBPeriph_GDMA_CLOCK ((uint32_t)((0x01 << 16) | (0x01 << 29)))
+#define APBPeriph_TIMER_CLOCK ((uint32_t)((0x01 << 14) | (0x01 << 29)))
+#define APBPeriph_ENHTIMER_CLOCK ((uint32_t)((0x01 << 14) | (0x01 << 29)))
+#define APBPeriph_UART2_CLOCK ((uint32_t)((0x01 << 10) | (0x01 << 29)))
+#define APBPeriph_UART1_CLOCK ((uint32_t)((0x01 << 12) | (0x01 << 29)))
+#define APBPeriph_FLASH_CLOCK ((uint32_t)((0x01 << 8) | (0x01 << 29)))
+
+#define APBPeriph_FLASH2_CLOCK ((uint32_t)((0x01 << 26) | (0x02 << 29)))
+#define APBPeriph_FLASH1_CLOCK ((uint32_t)((0x01 << 24) | (0x02 << 29)))
+#define APBPeriph_IR_CLOCK ((uint32_t)((0x01 << 20) | (0x02 << 29)))
+#define APBPeriph_SPI1_CLOCK ((uint32_t)((0x01 << 18) | (0x02 << 29)))
+#define APBPeriph_SPI0_CLOCK ((uint32_t)((0x01 << 16) | (0x02 << 29)))
+#define APBPeriph_CTC_CLOCK ((uint32_t)((0x01 << 12) | (0x02 << 29)))
+#define APBPeriph_UART0_CLOCK ((uint32_t)((0x01 << 0) | (0x02 << 29)))
+
+#define APBPeriph_IF8080_CLOCK ((uint32_t)((0x01 << 28) | (0x03 << 29)))
+#define APBPeriph_ADC_CLOCK ((uint32_t)((0x01 << 24) | (0x03 << 29)))
+#define APBPeriph_SPI2W_CLOCK ((uint32_t)((0x01 << 16) | (0x03 << 29)))
+#define APBPeriph_KEYSCAN_CLOCK ((uint32_t)((0x01 << 6) | (0x03 << 29)))
+#define APBPeriph_QDEC_CLOCK ((uint32_t)((0x01 << 4) | (0x03 << 29)))
+#define APBPeriph_I2C1_CLOCK ((uint32_t)((0x01 << 2) | (0x03 << 29)))
+#define APBPeriph_I2C0_CLOCK ((uint32_t)((0x01 << 0) | (0x03 << 29)))
+/** \} */
+
+#define IS_APB_PERIPH_CLOCK(CLOCK) (((CLOCK) == APBPeriph_GPIO_CLOCK) || ((CLOCK) == APBPeriph_GDMA_CLOCK)\
+ || ((CLOCK) == APBPeriph_TIMER_CLOCK) || ((CLOCK) == APBPeriph_IR_CLOCK)\
+ || ((CLOCK) == APBPeriph_SPI1_CLOCK) || ((CLOCK) == APBPeriph_SPI0_CLOCK)\
+ || ((CLOCK) == APBPeriph_UART0_CLOCK) || ((CLOCK) == APBPeriph_ADC_CLOCK)\
+ || ((CLOCK) == APBPeriph_SPI2W_CLOCK) || ((CLOCK) == APBPeriph_KEYSCAN_CLOCK)\
+ || ((CLOCK) == APBPeriph_QDEC_CLOCK) || ((CLOCK) == APBPeriph_I2C1_CLOCK)\
+ || ((CLOCK) == APBPeriph_I2C0_CLOCK) || ((CLOCK) == APBPeriph_CODEC_CLOCK)\
+ || ((CLOCK) == APBPeriph_UART1_CLOCK) || ((CLOCK) == APBPeriph_UART2_CLOCK)\
+ || ((CLOCK) == APBPeriph_I2S0_CLOCK) || ((CLOCK) == APBPeriph_I2S1_CLOCK)\
+ || ((CLOCK) == APBPeriph_IF8080_CLOCK) || ((CLOCK) == APBPeriph_ENHTIMER_CLOCK))
+
+/**
+ * \defgroup APB_Peripheral_Define APB Peripheral Define
+ * \{
+ * \ingroup RCC_Exported_Constants
+ */
+
+#define APBPeriph_CTC ((uint32_t)((1 << 21) | (0x00 << 26)))
+#define APBPeriph_TIMER ((uint32_t)((1 << 16) | (0x00 << 26)))
+#define APBPeriph_ENHTIMER ((uint32_t)((1 << 16) | (0x00 << 26)))
+#define APBPeriph_GDMA ((uint32_t)((1 << 13) | (0x00 << 26)))
+#define APBPeriph_UART1 ((uint32_t)((1 << 12) | (0x00 << 26)))
+#define APBPeriph_FLASH2 ((uint32_t)((1 << 5) | (0x00 << 26)))
+#define APBPeriph_FLASH ((uint32_t)((1 << 4) | (0x00 << 26)))
+#define APBPeriph_FLASH1 ((uint32_t)((1 << 3) | (0x00 << 26)))
+
+#define APBPeriph_IF8080 ((uint32_t)((1 << 25) | (0x02 << 26)))
+#define APBPeriph_SPI2W ((uint32_t)((1 << 24) | (0x02 << 26)))
+#define APBPeriph_KEYSCAN ((uint32_t)((1 << 19) | (0x02 << 26)))
+#define APBPeriph_QDEC ((uint32_t)((1 << 18) | (0x02 << 26)))
+#define APBPeriph_I2C1 ((uint32_t)((1 << 17) | (0x02 << 26)))
+#define APBPeriph_I2C0 ((uint32_t)((1 << 16) | (0x02 << 26)))
+#define APBPeriph_IR ((uint32_t)((1 << 10) | (0x02 << 26)))
+#define APBPeriph_SPI1 ((uint32_t)((1 << 9) | (0x02 << 26)))
+#define APBPeriph_SPI0 ((uint32_t)((1 << 8) | (0x02 << 26)))
+#define APBPeriph_UART0 ((uint32_t)((1 << 0) | (0x02 << 26)))
+#define APBPeriph_UART2 ((uint32_t)((1 << 1) | (0x02 << 26)))
+
+#define APBPeriph_GPIO ((uint32_t)((1 << 8) | (0x03 << 26)))
+#define APBPeriph_ADC ((uint32_t)((1 << 0) | (0x03 << 26)))
+
+#define APBPeriph_I2S1 ((uint32_t)((1 << 2) | (0x00 << 26)))
+#define APBPeriph_I2S0 ((uint32_t)((1 << 1) | (0x00 << 26)))
+#define APBPeriph_CODEC ((uint32_t)((1 << 0) | (0x00 << 26)))
+/** \} */
+
+#define IS_APB_PERIPH(PERIPH) (((PERIPH) == APBPeriph_TIMER) || ((PERIPH) == APBPeriph_GDMA)\
+ || ((PERIPH) == APBPeriph_SPI2W) || ((PERIPH) == APBPeriph_KEYSCAN)\
+ || ((PERIPH) == APBPeriph_QDEC) || ((PERIPH) == APBPeriph_I2C1)\
+ || ((PERIPH) == APBPeriph_I2C0) || ((PERIPH) == APBPeriph_IR)\
+ || ((PERIPH) == APBPeriph_SPI1) || ((PERIPH) == APBPeriph_SPI0)\
+ || ((PERIPH) == APBPeriph_UART0) || ((PERIPH) == APBPeriph_GPIO)\
+ || ((PERIPH) == APBPeriph_ADC) || ((PERIPH) == APBPeriph_CODEC)\
+ || (PERIPH == APBPeriph_UART1) || (PERIPH == APBPeriph_UART2)\
+ || ((PERIPH) == APBPeriph_I2S0) || ((PERIPH) == APBPeriph_I2S1)\
+ || ((PERIPH) == APBPeriph_IF8080) || ((PERIPH) == APBPeriph_ENHTIMER))
+
+/**
+ * \defgroup RCC_Peripheral_Clock RCC Peripheral Clock
+ * \{
+ * \ingroup RCC_Exported_Constants
+ */
+
+#define CLOCK_GATE_5M ((uint32_t)(0x01 << 29))/* 5M clock source for adc and keyscan */
+#define CLOCK_GATE_20M ((uint32_t)(0x01 << 27))/* 20M clock source for 2wssi and qdec */
+#define CLOCK_GATE_10M ((uint32_t)(0x01 << 28))/* 10M clock source for bluewiz */
+/** \} */
+#define IS_CLOCK_GATE(CLOCK) (((CLOCK) == CLOCK_GATE_5M) || ((CLOCK) == CLOCK_GATE_20M)\
+ || ((CLOCK) == CLOCK_GATE_10M))
+
+/**
+ * \defgroup I2C_Clock_Divider I2C Clock Divider
+ * \{
+ * \ingroup RCC_Exported_Constants
+ */
+
+#define I2C_CLOCK_DIV_1 ((uint16_t)0x0)
+#define I2C_CLOCK_DIV_2 ((uint16_t)0x1)
+#define I2C_CLOCK_DIV_4 ((uint16_t)0x2)
+#define I2C_CLOCK_DIV_8 ((uint16_t)0x3)
+/** \} */
+#define IS_I2C_DIV(DIV) (((DIV) == I2C_CLOCK_DIV_1) || \
+ ((DIV) == I2C_CLOCK_DIV_2) || \
+ ((DIV) == I2C_CLOCK_DIV_4) || \
+ ((DIV) == I2C_CLOCK_DIV_8))
+/**
+ * \defgroup SPI_Clock_Divider SPI Clock Divider
+ * \{
+ * \ingroup RCC_Exported_Constants
+ */
+
+#define SPI_CLOCK_DIV_1 ((uint16_t)0x0)
+#define SPI_CLOCK_DIV_2 ((uint16_t)0x1)
+#define SPI_CLOCK_DIV_4 ((uint16_t)0x2)
+#define SPI_CLOCK_DIV_8 ((uint16_t)0x3)
+/** \} */
+#define IS_SPI_DIV(DIV) (((DIV) == SPI_CLOCK_DIV_1) || \
+ ((DIV) == SPI_CLOCK_DIV_2) || \
+ ((DIV) == SPI_CLOCK_DIV_4) || \
+ ((DIV) == SPI_CLOCK_DIV_8))
+
+/**
+ * \defgroup UART_Clock_Divider UART Clock Divider
+ * \{
+ * \ingroup RCC_Exported_Constants
+ */
+
+#define UART_CLOCK_DIV_1 ((uint16_t)0x0)
+#define UART_CLOCK_DIV_2 ((uint16_t)0x1)
+#define UART_CLOCK_DIV_4 ((uint16_t)0x2)
+#define UART_CLOCK_DIV_16 ((uint16_t)0x3)
+/** \} */
+#define IS_UART_DIV(DIV) (((DIV) == UART_CLOCK_DIV_1) || \
+ ((DIV) == UART_CLOCK_DIV_2) || \
+ ((DIV) == UART_CLOCK_DIV_4) || \
+ ((DIV) == UART_CLOCK_DIV_16))
+/**
+ * \defgroup TIM_Clock_Divider TIM Clock Divider
+ * \{
+ * \ingroup RCC_Exported_Constants
+ */
+
+
+#define TIM_CLOCK_DIV_1 0x00
+#define TIM_CLOCK_DIV_125 0x03
+#define TIM_CLOCK_DIV_2 0x04
+#define TIM_CLOCK_DIV_4 0x05
+#define TIM_CLOCK_DIV_8 0x06
+#define TIM_CLOCK_DIV_40 0x07
+/** \} */
+#define IS_TIM_DIV(DIV) (((DIV) == TIM_CLOCK_DIV_1) || \
+ ((DIV) == TIM_CLOCK_DIV_125) || \
+ ((DIV) == TIM_CLOCK_DIV_2) || \
+ ((DIV) == TIM_CLOCK_DIV_4) || \
+ ((DIV) == TIM_CLOCK_DIV_8) || \
+ ((DIV) == TIM_CLOCK_DIV_40))
+
+/**
+ * \defgroup TIM_Clock_Divider TIM Clock Divider
+ * \{
+ * \ingroup RCC_Exported_Constants
+ */
+
+typedef enum
+{
+ TIM_CLK_2 = 2,
+ TIM_CLK_3,
+ TIM_CLK_4,
+ TIM_CLK_5,
+ TIMENH_CLK_0,
+ TIMENH_CLK_1,
+} E_TIM_NUM;
+
+#define TIM0_CLK 0x00
+#define TIM_CLOCK_DIV_125 0x03
+#define TIM_CLOCK_DIV_2 0x04
+#define TIM_CLOCK_DIV_4 0x05
+#define TIM_CLOCK_DIV_8 0x06
+#define TIM_CLOCK_DIV_40 0x07
+/** \} */
+#define IS_TIM_DIV(DIV) (((DIV) == TIM_CLOCK_DIV_1) || \
+ ((DIV) == TIM_CLOCK_DIV_125) || \
+ ((DIV) == TIM_CLOCK_DIV_2) || \
+ ((DIV) == TIM_CLOCK_DIV_4) || \
+ ((DIV) == TIM_CLOCK_DIV_8) || \
+ ((DIV) == TIM_CLOCK_DIV_40))
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup RCC_Exported_Functions Peripheral APIs
+ * \ingroup RCC
+ * \{
+ */
+
+/**
+ * \brief Enables or disables the APB peripheral clock.
+ * \param APBPeriph: Specifies the APB peripheral to gates its clock.
+ * This parameter can be one of the following values:
+ * \arg APBPeriph_ADC
+ * \arg APBPeriph_CODEC
+ * \arg APBPeriph_GDMA
+ * \arg APBPeriph_GPIO
+ * \arg APBPeriph_I2C1
+ * \arg APBPeriph_I2C0
+ * \arg APBPeriph_I2S0
+ * \arg APBPeriph_I2S1
+ * \arg APBPeriph_IF8080
+ * \arg APBPeriph_IR
+ * \arg APBPeriph_KEYSCAN
+ * \arg APBPeriph_QDEC
+ * \arg APBPeriph_SPI2W
+ * \arg APBPeriph_SPI1
+ * \arg APBPeriph_SPI0
+ * \arg APBPeriph_TIMER
+ * \arg APBPeriph_UART0
+ * \arg APBPeriph_UART1
+ * \arg APBPeriph_UART2
+ * \param APBPeriph_Clock: Specifies the APB peripheral clock config.
+ * This parameter can be one of the following values(must be the same with APBPeriph):
+ * \arg APBPeriph_ADC_CLOCK
+ * \arg APBPeriph_CODEC_CLOCK
+ * \arg APBPeriph_GDMA_CLOCK
+ * \arg APBPeriph_GPIO_CLOCK
+ * \arg APBPeriph_I2C1_CLOCK
+ * \arg APBPeriph_I2C0_CLOCK
+ * \arg APBPeriph_I2S0_CLOCK
+ * \arg APBPeriph_I2S1_CLOCK
+ * \arg APBPeriph_IR_CLOCK
+ * \arg APBPeriph_KEYSCAN_CLOCK
+ * \arg APBPeriph_QDEC_CLOCK
+ * \arg APBPeriph_SPI1_CLOCK
+ * \arg APBPeriph_SPI0_CLOCK
+ * \arg APBPeriph_SPI2W_CLOCK
+ * \arg APBPeriph_TIMER_CLOCK
+ * \arg APBPeriph_UART0_CLOCK
+ * \arg APBPeriph_UART1_CLOCK
+ * \arg APBPeriph_UART2_CLOCK
+ * \param NewState: New state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * \retval None.
+ */
+void RCC_PeriphClockCmd(uint32_t APBPeriph, uint32_t APBPeriph_Clock,
+ FunctionalState NewState);
+/**
+ * \brief I2C clock divider config.
+ * \param I2Cx: Where x can be 0 or 1 to select the I2C peripheral.
+ * \param ClockDiv: Specifies the APB peripheral to gates its clock.
+ * This parameter can be one of the following values:
+ * \arg I2C_CLOCK_DIV_1
+ * \arg I2C_CLOCK_DIV_2
+ * \arg I2C_CLOCK_DIV_4
+ * \arg I2C_CLOCK_DIV_8
+ * \retval None.
+ */
+void RCC_I2CClkDivConfig(I2C_TypeDef *I2Cx, uint16_t ClockDiv);
+
+/**
+ * \brief SPI clock divider config.
+ * \param SPIx: Where x can be 0 or 1 to select the SPI peripheral.
+ * \param ClockDiv: Specifies the APB peripheral to gates its clock.
+ * This parameter can be one of the following values:
+ * \arg SPI_CLOCK_DIV_1
+ * \arg SPI_CLOCK_DIV_2
+ * \arg SPI_CLOCK_DIV_4
+ * \arg SPI_CLOCK_DIV_8
+ * \retval None.
+ */
+void RCC_SPIClkDivConfig(SPI_TypeDef *SPIx, uint16_t ClockDiv);
+
+/**
+ * @brief TIMER & ENH-TIMER clock divider config.
+ * @param TIMx: selected TIM number.
+ * @param ClockDiv: specifies the APB peripheral to gates its clock.
+ * This parameter can be one of the following values:
+ * @arg TIM_CLOCK_DIV_1
+ * @arg TIM_CLOCK_DIV_125
+ * @arg TIM_CLOCK_DIV_2
+ * @arg TIM_CLOCK_DIV_4
+ * @arg TIM_CLOCK_DIV_8
+ * @arg TIM_CLOCK_DIV_40
+ * @retval None
+ */
+void RCC_TIMClkDivConfig(E_TIM_NUM TIMx, uint16_t ClockDiv);
+
+/**
+ * \brief UART clock divider config.
+ * \param UARTx: Selected UART peripheral.
+ * \param ClockDiv: Specifies the APB peripheral to gates its clock.
+ * This parameter can be one of the following values:
+ * \arg UART_CLOCK_DIV_1
+ * \arg UART_CLOCK_DIV_2
+ * \arg UART_CLOCK_DIV_4
+ * \arg UART_CLOCK_DIV_16
+ * \retval None.
+ */
+void RCC_UARTClkDivConfig(UART_TypeDef *UARTx, uint16_t ClockDiv);
+
+/**
+ * \brief Enables or disables the APB peripheral function.
+ * \param APBPeriph: Specifies the APB peripheral .
+ * This parameter can be one of the following values:
+ * \arg APBPeriph_ADC
+ * \arg APBPeriph_CODEC
+ * \arg APBPeriph_GDMA
+ * \arg APBPeriph_GPIO
+ * \arg APBPeriph_I2C1
+ * \arg APBPeriph_I2C0
+ * \arg APBPeriph_I2S0
+ * \arg APBPeriph_I2S1
+ * \arg APBPeriph_IF8080
+ * \arg APBPeriph_IR
+ * \arg APBPeriph_KEYSCAN
+ * \arg APBPeriph_QDEC
+ * \arg APBPeriph_SPI2W
+ * \arg APBPeriph_SPI1
+ * \arg APBPeriph_SPI0
+ * \arg APBPeriph_TIMER
+ * \arg APBPeriph_UART0
+ * \arg APBPeriph_UART1
+ * \arg APBPeriph_UART2
+ * \param NewState: New state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * \retval None.
+ */
+void RCC_PeriFunctionConfig(uint32_t APBPeriph, FunctionalState NewState);
+
+/**
+ * \brief Enables or disables the APB peripheral clock.
+ * \param APBPeriph_Clock: Specifies the APB peripheral clock config.
+ * This parameter can be one of the following values(must be the same with APBPeriph):
+ * \arg APBPeriph_ADC_CLOCK
+ * \arg APBPeriph_CODEC_CLOCK
+ * \arg APBPeriph_GDMA_CLOCK
+ * \arg APBPeriph_GPIO_CLOCK
+ * \arg APBPeriph_I2C1_CLOCK
+ * \arg APBPeriph_I2C0_CLOCK
+ * \arg APBPeriph_I2S0_CLOCK
+ * \arg APBPeriph_I2S1_CLOCK
+ * \arg APBPeriph_IR_CLOCK
+ * \arg APBPeriph_KEYSCAN_CLOCK
+ * \arg APBPeriph_QDEC_CLOCK
+ * \arg APBPeriph_SPI1_CLOCK
+ * \arg APBPeriph_SPI0_CLOCK
+ * \arg APBPeriph_SPI2W_CLOCK
+ * \arg APBPeriph_TIMER_CLOCK
+ * \arg APBPeriph_UART0_CLOCK
+ * \arg APBPeriph_UART1_CLOCK
+ * \arg APBPeriph_UART2_CLOCK
+ * \param NewState: New state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * \retval None.
+ */
+void RCC_PeriClockConfig(uint32_t APBPeriph_Clock, FunctionalState NewState);
+
+/**
+ * \brief Enable clock 5M source.
+ * \param None.
+ * \return None.
+ */
+__STATIC_INLINE void RCC_ClockSrc5MCmd(void)
+{
+ /*Open 5M clock source*/
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26;
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT29;
+}
+
+/**
+ * \brief Enable clock 10M source.
+ * \param None.
+ * \return None.
+ */
+__STATIC_INLINE void RCC_ClockSrc10MCmd(void)
+{
+ /*Open 10M clock source*/
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26;
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT28;
+}
+
+/**
+ * \brief Enable clock 20M source.
+ * \param None.
+ * \return None.
+ */
+__STATIC_INLINE void RCC_ClockSrc20MCmd(void)
+{
+ /*Open 20M clock source*/
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26;
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT27;
+}
+
+/** \} */ /* End of group RCC_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_RCC_H_ */
+
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor *****END OF FILE****/
+
+
+
diff --git a/inc/peripheral/rtl876x_rtc.h b/inc/peripheral/rtl876x_rtc.h
new file mode 100644
index 0000000..1d18233
--- /dev/null
+++ b/inc/peripheral/rtl876x_rtc.h
@@ -0,0 +1,1036 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_rtc.h
+* \brief The header file of the peripheral RTC driver.
+* \details This file provides all RTC firmware functions.
+* \author yuan
+* \date 2020-06-01
+* \version v2.1.0
+* *********************************************************************************************************
+*/
+
+#ifndef _RTL876X_RTC_H_
+#define _RTL876X_RTC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup RTC RTC
+ *
+ * \brief Manage the RTC peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+#include "rtl876x_alias.h"
+
+
+/*============================================================================*
+ * Registers Definitions
+ *============================================================================*/
+
+/* Peripheral: RTC */
+/* Description: Real time counter register defines */
+
+/* Register: CR0 */
+/* Description: RTC Control Register 0. Offset: 0x00. Address: 0x40000100. */
+
+/* CR0[31] :RTC_RST. Enable interrupt signal to MCU. 0x1: Enable. 0x0: Disable. */
+#define RTC_RST_Pos (31UL)
+#define RTC_RST_Msk (0x1UL << RTC_RST_Pos)
+#define RTC_RST_CLR (~(RTC_RST_Msk))
+
+/* CR0[30] :RTC_NV_EN. Enable interrupt signal to MCU. 0x1: Enable. 0x0: Disable. */
+#define RTC_NV_EN_Pos (30UL)
+#define RTC_NV_EN_Msk (0x1UL << RTC_NV_EN_Pos)
+#define RTC_NV_EN_CLR (~(RTC_NV_EN_Msk))
+
+/* CR0[29] :RTC_WAKEUP_EN. Enable wakeup signal to AON register. 0x1: Enable. 0x0: Disable. */
+#define RTC_WAKEUP_EN_Pos (29UL)
+#define RTC_WAKEUP_EN_Msk (0x1UL << RTC_WAKEUP_EN_Pos)
+#define RTC_WAKEUP_EN_CLR (~(RTC_WAKEUP_EN_Msk))
+
+/* CR0[23] :RTC_COMP3_WAKEUP_EN. Enable or disable compare3 wakeup function. 0x1: Enable. 0x0: Disable. */
+#define RTC_COMP3_WAKEUP_EN_Pos (23UL)
+#define RTC_COMP3_WAKEUP_EN_Msk (0x1UL << RTC_COMP3_WAKEUP_EN_Pos)
+#define RTC_COMP3_WAKEUP_EN_Clr (~(RTC_COMP3_WAKEUP_EN_Msk))
+
+/* CR0[22] :RTC_INT_EN. Enable or disable compare2 wakeup function. 0x1: Enable. 0x0: Disable. */
+#define RTC_COMP2_WAKEUP_EN_Pos (22UL)
+#define RTC_COMP2_WAKEUP_EN_Msk (0x1UL << RTC_COMP2_WAKEUP_EN_Pos)
+#define RTC_COMP2_WAKEUP_EN_Clr (~(RTC_COMP2_WAKEUP_EN_Msk))
+
+/* CR0[21] :RTC_INT_EN. Enable or disable compare1 wakeup function. 0x1: Enable. 0x0: Disable. */
+#define RTC_COMP1_WAKEUP_EN_Pos (21UL)
+#define RTC_COMP1_WAKEUP_EN_Msk (0x1UL << RTC_COMP1_WAKEUP_EN_Pos)
+#define RTC_COMP1_WAKEUP_EN_Clr (~(RTC_COMP1_WAKEUP_EN_Msk))
+
+/* CR0[20] :RTC_INT_EN. Enable or disable compare0 wakeup function. 0x1: Enable. 0x0: Disable. */
+#define RTC_COMP0_WAKEUP_EN_Pos (20UL)
+#define RTC_COMP0_WAKEUP_EN_Msk (0x1UL << RTC_COMP0_WAKEUP_EN_Pos)
+#define RTC_COMP0_WAKEUP_EN_Clr (~(RTC_COMP0_WAKEUP_EN_Msk))
+
+/* CR0[19] :RTC_INT_EN. Enable or disable compare3 interrupt. 0x1: Enable. 0x0: Disable. */
+#define RTC_INT_COMP3_EN_Pos (19UL)
+#define RTC_INT_COMP3_EN_Msk (0x1UL << RTC_INT_COMP3_EN_Pos)
+#define RTC_INT_COMP3_EN_Clr (~(RTC_INT_COMP3_EN_Msk))
+
+/* CR0[18] :RTC_INT_EN. Enable or disable compare2 interrupt. 0x1: Enable. 0x0: Disable. */
+#define RTC_INT_COMP2_EN_Pos (18UL)
+#define RTC_INT_COMP2_EN_Msk (0x1UL << RTC_INT_COMP2_EN_Pos)
+#define RTC_INT_COMP2_EN_Clr (~(RTC_INT_COMP2_EN_Msk))
+
+/* CR0[17] :RTC_INT_EN. Enable or disable compare1 interrupt. 0x1: Enable. 0x0: Disable. */
+#define RTC_INT_COMP1_EN_Pos (17UL)
+#define RTC_INT_COMP1_EN_Msk (0x1UL << RTC_INT_COMP1_EN_Pos)
+#define RTC_INT_COMP1_EN_Clr (~(RTC_INT_COMP1_EN_Msk))
+
+/* CR0[16] :RTC_INT_EN. Enable or disable compare0 interrupt. 0x1: Enable. 0x0: Disable. */
+#define RTC_INT_COMP0_EN_Pos (16UL)
+#define RTC_INT_COMP0_EN_Msk (0x1UL << RTC_INT_COMP0_EN_Pos)
+#define RTC_INT_COMP0_EN_Clr (~(RTC_INT_COMP0_EN_Msk))
+
+/* CR0[15] :RTC_INT_EN. Enable or disable compare3gt interrupt. 0x1: Enable. 0x0: Disable. */
+#define RTC_COMP3GT_WAKEUP_EN_Pos (15UL)
+#define RTC_COMP3GT_WAKEUP_EN_Msk (0x1UL << RTC_COMP3GT_WAKEUP_EN_Pos)
+#define RTC_COMP3GT_WAKEUP_EN_Clr (~(RTC_COMP3GT_WAKEUP_EN_Msk))
+
+/* CR0[14] :RTC_INT_EN. Enable or disable compare2gt interrupt. 0x1: Enable. 0x0: Disable. */
+#define RTC_COMP2GT_WAKEUP_EN_Pos (14UL)
+#define RTC_COMP2GT_WAKEUP_EN_Msk (0x1UL << RTC_COMP2GT_WAKEUP_EN_Pos)
+#define RTC_COMP2GT_WAKEUP_EN_Clr (~(RTC_COMP2GT_WAKEUP_EN_Msk))
+
+/* CR0[13] :RTC_INT_EN. Enable or disable compare1gt interrupt. 0x1: Enable. 0x0: Disable. */
+#define RTC_COMP1GT_WAKEUP_EN_Pos (13UL)
+#define RTC_COMP1GT_WAKEUP_EN_Msk (0x1UL << RTC_COMP1GT_WAKEUP_EN_Pos)
+#define RTC_COMP1GT_WAKEUP_EN_Clr (~(RTC_COMP1GT_WAKEUP_EN_Msk))
+
+/* CR0[12] :RTC_INT_EN. Enable or disable compare0gt interrupt. 0x1: Enable. 0x0: Disable. */
+#define RTC_COMP0GT_WAKEUP_EN_Pos (12UL)
+#define RTC_COMP0GT_WAKEUP_EN_Msk (0x1UL << RTC_COMP0GT_WAKEUP_EN_Pos)
+#define RTC_COMP0GT_WAKEUP_EN_Clr (~(RTC_COMP0GT_WAKEUP_EN_Msk))
+
+/* CR0[11] :RTC_INT_EN. Enable or disable prescale & comp3 interrupt. 0x1: Enable. 0x0: Disable. */
+#define RTC_INT_PRE_COMP3_EN_Pos (11UL)
+#define RTC_INT_PRE_COMP3_EN_Msk (0x1UL << RTC_INT_PRE_COMP3_EN_Pos)
+#define RTC_INT_PRE_COMP3_EN_Clr (~(RTC_INT_PRE_COMP3_EN_Msk))
+
+/* CR0[10] :RTC_INT_EN. Enable or disable prescale comp interrupt. 0x1: Enable. 0x0: Disable. */
+#define RTC_INT_PRE_COMP_EN_Pos (10UL)
+#define RTC_INT_PRE_COMP_EN_Msk (0x1UL << RTC_INT_PRE_COMP_EN_Pos)
+#define RTC_INT_PRE_COMP_EN_Clr (~(RTC_INT_PRE_COMP_EN_Msk))
+
+/* CR0[9] :RTC_MASK_TICK_INT. Mask RTC tick interrupt. 0x1: Unmask. 0x0: Mask. */
+#define RTC_INT_OVERFLOW_EN_Pos (9UL)
+#define RTC_INT_OVERFLOW_EN_Msk (0x1UL << RTC_INT_OVERFLOW_EN_Pos)
+#define RTC_INT_OVERFLOW_EN_Clr (~(RTC_INT_OVERFLOW_EN_Msk))
+
+/* CR0[8] :RTC_INT_EN. Enable or disable tick interrupt. 0x1: Enable. 0x0: Disable. */
+#define RTC_INT_TICK_EN_Pos (8UL)
+#define RTC_INT_TICK_EN_Msk (0x1UL << RTC_INT_TICK_EN_Pos)
+#define RTC_INT_TICK_EN_Clr (~(RTC_INT_TICK_EN_Msk))
+
+/* CR0[2] :RTC_PRE_COUNTER_RST. Reset Prescale Counter. 0x1: Reset Counter to 0. */
+#define RTC_PRE_COUNTER_RST_Pos (2UL)
+#define RTC_PRE_COUNTER_RST_Msk (0x1UL << RTC_PRE_COUNTER_RST_Pos)
+#define RTC_PRE_COUNTER_RST_CLR (~(RTC_PRE_COUNTER_RST_Msk))
+
+/* CR0[1] :RTC_COUNTER_RST. Reset 24bit-RTC Counter. 0x1: Reset Counter to 0. */
+#define RTC_COUNTER_RST_Pos (1UL)
+#define RTC_COUNTER_RST_Msk (0x1UL << RTC_COUNTER_RST_Pos)
+#define RTC_COUNTER_RST_CLR (~(RTC_COUNTER_RST_Msk))
+
+/* CR0[0] :RTC_START. Start or stop RTC 24bit-RTC Counter. 0x1: Start 24bit-RTC Counter.0x0: Stop 24bit-RTC Counter. */
+#define RTC_START_Pos (0UL)
+#define RTC_START_Msk (0x1UL << RTC_START_Pos)
+#define RTC_START_CLR (~(RTC_START_Msk))
+
+/* Register: INT_CLR */
+/* Description: Interrupt clear register. Offset: 0x04. Address: 0x40000104. */
+
+/* INT_CLR[15] :RTC_COMP3_WK_CLR. Clear Interrupt Status of Comparator1. */
+/* This status is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_COMP3_WK_CLR_Pos (15UL)
+#define RTC_COMP3_WK_CLR_SET (0x1UL << RTC_COMP3_WK_CLR_Pos)
+#define RTC_COMP3_WK_CLR_RESET (~(RTC_COMP3_WK_CLR_SET))
+
+/* INT_CLR[14] :RTC_COMP2_WK_CLR. Clear Interrupt Status of Comparator1. */
+/* This status is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_COMP2_WK_CLR_Pos (14UL)
+#define RTC_COMP2_WK_CLR_SET (0x1UL << RTC_COMP2_WK_CLR_Pos)
+#define RTC_COMP2_WK_CLR_RESET (~(RTC_COMP2_WK_CLR_SET))
+
+/* INT_CLR[13] :RTC_COMP1_WK_CLR. Clear Interrupt Status of Comparator1. */
+/* This status is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_COMP1_WK_CLR_Pos (13UL)
+#define RTC_COMP1_WK_CLR_SET (0x1UL << RTC_COMP1_WK_CLR_Pos)
+#define RTC_COMP1_WK_CLR_RESET (~(RTC_COMP1_WK_CLR_SET))
+
+/* INT_CLR[12] :RTC_COMP0_WK_CLR. Clear Interrupt Status of Comparator0. */
+/* This status is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_COMP0_WK_CLR_Pos (12UL)
+#define RTC_COMP0_WK_CLR_SET (0x1UL << RTC_COMP0_WK_CLR_Pos)
+#define RTC_COMP0_WK_CLR_RESET (~(RTC_COMP0_WK_CLR_SET))
+
+/* INT_CLR[11] :RTC_COMP3_CLR. Clear Interrupt Status of Comparator1. */
+/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_COMP3_CLR_Pos (11UL)
+#define RTC_COMP3_CLR_SET (0x1UL << RTC_COMP3_CLR_Pos)
+#define RTC_COMP3_CLR_RESET (~(RTC_COMP3_CLR_SET))
+
+/* INT_CLR[10] :RTC_COMP2_CLR. Clear Interrupt Status of Comparator1. */
+/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_COMP2_CLR_Pos (10UL)
+#define RTC_COMP2_CLR_SET (0x1UL << RTC_COMP2_CLR_Pos)
+#define RTC_COMP2_CLR_RESET (~(RTC_COMP2_CLR_SET))
+
+/* INT_CLR[9] :RTC_COMP1_CLR. Clear Interrupt Status of Comparator1. */
+/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_COMP1_CLR_Pos (9UL)
+#define RTC_COMP1_CLR_SET (0x1UL << RTC_COMP1_CLR_Pos)
+#define RTC_COMP1_CLR_RESET (~(RTC_COMP1_CLR_SET))
+
+/* INT_CLR[8] :RTC_COMP0_CLR. Clear Interrupt Status of Comparator0. */
+/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_COMP0_CLR_Pos (8UL)
+#define RTC_COMP0_CLR_SET (0x1UL << RTC_COMP0_CLR_Pos)
+#define RTC_COMP0_CLR_RESET (~(RTC_COMP0_CLR_SET))
+
+/* INT_CLR[7] :RTC_COMP3_CLR. Clear Interrupt Status of Comparator1. */
+/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_COMP3GT_CLR_Pos (7UL)
+#define RTC_COMP3GT_CLR_SET (0x1UL << RTC_COMP3GT_CLR_Pos)
+#define RTC_COMP3GT_CLR_RESET (~(RTC_COMP3GT_CLR_SET))
+
+/* INT_CLR[6] :RTC_COMP2GT_CLR. Clear Interrupt Status of Comparator1. */
+/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_COMP2GT_CLR_Pos (6UL)
+#define RTC_COMP2GT_CLR_SET (0x1UL << RTC_COMP2GT_CLR_Pos)
+#define RTC_COMP2GT_CLR_RESET (~(RTC_COMP2GT_CLR_SET))
+
+/* INT_CLR[5] :RTC_COMP1GT_CLR. Clear Interrupt Status of Comparator1. */
+/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_COMP1GT_CLR_Pos (5UL)
+#define RTC_COMP1GT_CLR_SET (0x1UL << RTC_COMP1GT_CLR_Pos)
+#define RTC_COMP1GT_CLR_RESET (~(RTC_COMP1GT_CLR_SET))
+
+/* INT_CLR[4] :RTC_COMP0GT_CLR. Clear Interrupt Status of Comparator0. */
+/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_COMP0GT_CLR_Pos (4UL)
+#define RTC_COMP0GT_CLR_SET (0x1UL << RTC_COMP0GT_CLR_Pos)
+#define RTC_COMP0GT_CLR_RESET (~(RTC_COMP0GT_CLR_SET))
+
+/* INT_CLR[3] :RTC_PRE_COMP3_CLR. Clear Interrupt Status of prescale and prescale_comp3. */
+/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_PRE_COMP3_CLR_Pos (3UL)
+#define RTC_PRE_COMP3_CLR_SET (0x1UL << RTC_PRE_COMP3_CLR_Pos)
+#define RTC_PRE_COMP3_CLR_RESET (~(RTC_PRE_COMP3_CLR_SET))
+
+/* INT_CLR[6] :RTC_PRE_COMP_CLR. Clear Interrupt Status of Comparator1. */
+/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_PRE_COMP_CLR_Pos (2UL)
+#define RTC_PRE_COMP_CLR_SET (0x1UL << RTC_PRE_COMP_CLR_Pos)
+#define RTC_PRE_COMP_CLR_RESET (~(RTC_PRE_COMP_CLR_SET))
+
+/* INT_CLR[1] :RTC_OVERFLOW_CLR. Clear Interrupt Status of Overflow. */
+/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_OVERFLOW_CLR_Pos (1UL)
+#define RTC_OVERFLOW_CLR_SET (0x1UL << RTC_OVERFLOW_CLR_Pos)
+#define RTC_OVERFLOW_CLR_RESET (~(RTC_OVERFLOW_CLR_SET))
+
+/* INT_CLR[0] :RTC_TICK_CLR. Clear Interrupt Status of Tick. */
+/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */
+#define RTC_TICK_CLR_Pos (0UL)
+#define RTC_TICK_CLR_SET (0x1UL << RTC_TICK_CLR_Pos)
+#define RTC_TICK_CLR_RESET (~(RTC_TICK_CLR_SET))
+
+#define RTC_COMP_INT_EN_OFFSET (RTC_INT_COMP0_EN_Pos - RTC_COMP0_CLR_Pos)
+#define RTC_PRE_COMP_INT_EN_OFFSET (RTC_INT_PRE_COMP_EN_Pos - RTC_PRE_COMP_CLR_Pos)
+
+
+/* Clear all interrupt */
+#define RTC_ALL_INT_CLR_SET (RTC_PRE_COMP3_CLR_SET | RTC_PRE_COMP_CLR_SET | \
+ RTC_COMP3_CLR_SET | RTC_COMP2_CLR_SET | \
+ RTC_COMP1_CLR_SET | RTC_COMP0_CLR_SET | \
+ RTC_OVERFLOW_CLR_SET | RTC_TICK_CLR_SET)
+
+/* Clear all wakeup */
+#define RTC_ALL_WAKEUP_CLR_SET (RTC_COMP3_WK_CLR_SET | RTC_COMP2_WK_CLR_SET | \
+ RTC_COMP1_WK_CLR_SET | RTC_COMP0_WK_CLR_SET | \
+ RTC_COMP3GT_CLR_SET | RTC_COMP2GT_CLR_SET | \
+ RTC_COMP1GT_CLR_SET | RTC_COMP0GT_CLR_SET)
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup RTC_Exported_Constants Macro Definitions
+ *
+ * \ingroup RTC
+ */
+
+/**
+ * \defgroup RTC_Interrupts_Definition RTC Interrupts Definition
+ * \{
+ * \ingroup RTC_Exported_Constants
+ */
+typedef enum
+{
+ RTC_INT_TICK = RTC_INT_TICK_EN_Msk,
+ RTC_INT_OVF = RTC_INT_OVERFLOW_EN_Msk,
+ RTC_INT_PRE_COMP = RTC_INT_PRE_COMP_EN_Msk,
+ RTC_INT_PRE_COMP3 = RTC_INT_PRE_COMP3_EN_Msk,
+ RTC_INT_COMP0 = RTC_INT_COMP0_EN_Msk,
+ RTC_INT_COMP1 = RTC_INT_COMP1_EN_Msk,
+ RTC_INT_COMP2 = RTC_INT_COMP2_EN_Msk,
+ RTC_INT_COMP3 = RTC_INT_COMP3_EN_Msk,
+} E_RTC_INT;
+
+/** \} */
+
+#define IS_RTC_INT(INT) (((INT) == RTC_INT_TICK) || \
+ ((INT) == RTC_INT_OVF) || \
+ ((INT) == RTC_INT_COMP0) || \
+ ((INT) == RTC_INT_COMP1) || \
+ ((INT) == RTC_INT_COMP2) || \
+ ((INT) == RTC_INT_COMP3) || \
+ ((INT) == RTC_INT_PRE_COMP) || \
+ ((INT) == RTC_INT_PRE_COMP3))
+
+/**
+ * \defgroup RTC_Wakeup_Definition RTC Wakeup Definition
+ * \{
+ * \ingroup RTC_Exported_Constants
+ */
+typedef enum
+{
+ RTC_WK_TICK = RTC_INT_TICK_EN_Msk,
+ RTC_WK_OVF = RTC_INT_OVERFLOW_EN_Msk,
+ RTC_WK_PRE_COMP = RTC_INT_PRE_COMP_EN_Msk,
+ RTC_WK_PRE_COMP3 = RTC_INT_PRE_COMP3_EN_Msk,
+ RTC_WK_COMP0GT = RTC_COMP0GT_WAKEUP_EN_Msk,
+ RTC_WK_COMP1GT = RTC_COMP1GT_WAKEUP_EN_Msk,
+ RTC_WK_COMP2GT = RTC_COMP2GT_WAKEUP_EN_Msk,
+ RTC_WK_COMP3GT = RTC_COMP3GT_WAKEUP_EN_Msk,
+ RTC_WK_COMP0 = RTC_COMP0_WAKEUP_EN_Msk,
+ RTC_WK_COMP1 = RTC_COMP1_WAKEUP_EN_Msk,
+ RTC_WK_COMP2 = RTC_COMP2_WAKEUP_EN_Msk,
+ RTC_WK_COMP3 = RTC_COMP3_WAKEUP_EN_Msk,
+} E_RTC_WK;
+
+/** \} */
+
+#define IS_RTC_WK(WK) (((WK) == RTC_WK_TICK) || \
+ ((WK) == RTC_WK_OVF) || \
+ ((WK) == RTC_WK_PRE_COMP) || \
+ ((WK) == RTC_WK_PRE_COMP3) || \
+ ((WK) == RTC_WK_COMP0GT) || \
+ ((WK) == RTC_WK_COMP1GT) || \
+ ((WK) == RTC_WK_COMP2GT) || \
+ ((WK) == RTC_WK_COMP3GT) || \
+ ((WK) == RTC_WK_COMP0) || \
+ ((WK) == RTC_WK_COMP1) || \
+ ((WK) == RTC_WK_COMP2) || \
+ ((WK) == RTC_WK_COMP3))
+
+/**
+ * \defgroup RTC_Comp_Definition RTC Comparator Definition
+ * \{
+ * \ingroup RTC_Exported_Constants
+ */
+typedef enum
+{
+ RTC_COMP0 = 0,
+ RTC_COMP1,
+ RTC_COMP2,
+ RTC_COMP3,
+} E_RTC_COMP_INDEX;
+
+/** \} */
+
+#define IS_RTC_COMP(COMP) (((COMP) == RTC_COMP0) || \
+ ((COMP) == RTC_COMP1) || \
+ ((COMP) == RTC_COMP2) || \
+ ((COMP) == RTC_COMP3))
+
+/**
+ * \defgroup RTC_CompGT_Definition RTC ComparatorGT Definition
+ * \{
+ * \ingroup RTC_Exported_Constants
+ */
+typedef enum
+{
+ RTC_COMP0GT = 0,
+ RTC_COMP1GT,
+ RTC_COMP2GT,
+ RTC_COMP3GT,
+} E_RTC_COMPGT_INDEX;
+
+/** \} */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup RTC_Exported_Functions Peripheral APIs
+ * \{
+ * \ingroup RTC
+ */
+
+/**
+ * \brief Fast write RTC register,internal function.
+ * \param[in] regAddress: The register address.
+ * \param[in] data: Data which write to register.
+ * \return None.
+ */
+void RTC_WriteReg(uint32_t regAddress, uint32_t data);
+
+/**
+ * \brief Deinitializes the RTC peripheral registers to their default reset values(turn off clock).
+ * \param[in] None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_rtc_init(void)
+ * {
+ * RTC_DeInit();
+ * }
+ * \endcode
+ */
+void RTC_DeInit(void);
+
+/**
+ * \brief Set RTC prescaler value.
+ * \param[in] value: The prescaler value to be set.Should be no more than 12 bits!
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * #define RTC_PRESCALER_VALUE 49
+ * #define RTC_COMP_INDEX RTC_COMP3
+ * #define RTC_COMP_INDEX_INT RTC_INT_COMP3
+ * #define RTC_COMP_VALUE (1000)
+ *
+ * void driver_rtc_init(void)
+ * {
+ * RTC_DeInit();
+ *
+ * RTC_SetPrescaler(RTC_PRESCALER_VALUE);
+ * RTC_SetCompValue(RTC_COMP_INDEX, RTC_COMP_VALUE);
+ *
+ * RTC_MaskINTConfig(RTC_COMP_INDEX_INT, DISABLE);
+ * RTC_INTConfig(RTC_COMP_INDEX_INT, ENABLE);
+ *
+ * RTC_NvCmd(ENABLE);
+ * RTC_Cmd(ENABLE);
+ * }
+ * \endcode
+ */
+void RTC_SetPrescaler(uint16_t value);
+
+/**
+ * \brief Start or stop RTC peripheral.
+ * \param[in] NewState: New state of RTC peripheral.
+ * This parameter can be one of the following values:
+ * \arg ENABLE: Start RTC.
+ * \arg DISABLE: Stop RTC.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * #define RTC_PRESCALER_VALUE 49
+ * #define RTC_COMP_INDEX RTC_COMP3
+ * #define RTC_COMP_INDEX_INT RTC_INT_COMP3
+ * #define RTC_COMP_VALUE (1000)
+ *
+ * void driver_rtc_init(void)
+ * {
+ * RTC_DeInit();
+ *
+ * RTC_SetPrescaler(RTC_PRESCALER_VALUE);
+ * RTC_SetCompValue(RTC_COMP_INDEX, RTC_COMP_VALUE);
+ *
+ * RTC_MaskINTConfig(RTC_COMP_INDEX_INT, DISABLE);
+ * RTC_INTConfig(RTC_COMP_INDEX_INT, ENABLE);
+ *
+ * RTC_NvCmd(ENABLE);
+ * RTC_Cmd(ENABLE);
+ * }
+ * \endcode
+ */
+void RTC_Cmd(FunctionalState NewState);
+
+/**
+ * \brief Enable or disable the specified RTC interrupt source.
+ * \param[in] RTC_INT: Specifies the RTC interrupt source which to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * \arg RTC_INT_TICK: Tick interrupt source.
+ * \arg RTC_INT_OVF: counter overflow interrupt
+ * \arg RTC_INT_COMP0: Compare 0 interrupt source.
+ * \arg RTC_INT_COMP1: Compare 1 interrupt source.
+ * \arg RTC_INT_COMP2: Compare 2 interrupt source.
+ * \arg RTC_INT_COMP3: Compare 3 interrupt source.
+ * \arg RTC_INT_PRE_COMP: Prescale compare interrupt source.
+ * \arg RTC_INT_PRE_COMP3: Prescale & compare 3 interrupt source.
+ * \param[in] NewState: New state of the specified RTC interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * #define RTC_PRESCALER_VALUE 49
+ * #define RTC_COMP_INDEX RTC_COMP3
+ * #define RTC_COMP_INDEX_INT RTC_INT_COMP3
+ * #define RTC_COMP_VALUE (1000)
+ *
+ * void driver_rtc_init(void)
+ * {
+ * RTC_DeInit();
+ *
+ * RTC_SetPrescaler(RTC_PRESCALER_VALUE);
+ * RTC_SetCompValue(RTC_COMP_INDEX, RTC_COMP_VALUE);
+ *
+ * RTC_MaskINTConfig(RTC_COMP_INDEX_INT, DISABLE);
+ * RTC_INTConfig(RTC_COMP_INDEX_INT, ENABLE);
+ *
+ * RTC_NvCmd(ENABLE);
+ * RTC_Cmd(ENABLE);
+ * }
+ * \endcode
+ */
+void RTC_INTConfig(E_RTC_INT RTC_INT, FunctionalState NewState);
+
+/**
+ * \brief Enable or disable the specified RTC wakeup function.
+ * \param RTC_WK: specifies the RTC wakeup function to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * \arg RTC_WK_TICK: tick wakeup function
+ * \arg RTC_WK_OVF: tick wakeup function
+ * \arg RTC_WK_PRE_CMP: prescale compare wakeup function
+ * \arg RTC_WK_PRE_CMP3: prescale & compare 3 wakeup function
+ * \arg RTC_WK_COMP0GT: compare 0 gt wakeup function
+ * \arg RTC_WK_COMP1GT: compare 1 gt wakeup function
+ * \arg RTC_WK_COMP2GT: compare 2 gt wakeup function
+ * \arg RTC_WK_COMP3GT: compare 3 gt wakeup function
+ * \arg RTC_WK_CMP0: compare 0 wakeup function
+ * \arg RTC_WK_CMP1: compare 1 wakeup function
+ * \arg RTC_WK_CMP2: compare 2 wakeup function
+ * \arg RTC_WK_CMP3: compare 3 wakeup function
+ * \param NewState: new state of the specified RTC wakeup function.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * #define RTC_PRESCALER_VALUE 49
+ * #define RTC_COMP_INDEX RTC_COMP3
+ * #define RTC_COMP_INDEX_INT RTC_INT_COMP3
+ * #define RTC_COMP_VALUE (1000)
+ *
+ * void driver_rtc_init(void)
+ * {
+ * RTC_DeInit();
+ *
+ * RTC_SetPrescaler(RTC_PRESCALER_VALUE);
+ * RTC_SetCompValue(RTC_COMP_INDEX, RTC_COMP_VALUE);
+ *
+ * RTC_MaskINTConfig(RTC_COMP_INDEX_INT, DISABLE);
+ * RTC_INTConfig(RTC_COMP_INDEX_INT, ENABLE);
+ *
+ * RTC_NvCmd(ENABLE);
+ * RTC_Cmd(ENABLE);
+ * }
+ * \endcode
+ */
+void RTC_WKConfig(E_RTC_WK RTC_WK, FunctionalState NewState);
+
+/**
+ * \brief Enable RTC interrupt signal to CPU NVIC.
+ * \param[in] NewState: Enable or disable RTC interrupt signal to MCU.
+ * This parameter can be: ENABLE or DISABLE..
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * #define RTC_PRESCALER_VALUE 49
+ * #define RTC_COMP_INDEX RTC_COMP3
+ * #define RTC_COMP_INDEX_INT RTC_INT_COMP3
+ * #define RTC_COMP_VALUE (1000)
+ *
+ * void driver_rtc_init(void)
+ * {
+ * RTC_DeInit();
+ *
+ * RTC_SetPrescaler(RTC_PRESCALER_VALUE);
+ * RTC_SetCompValue(RTC_COMP_INDEX, RTC_COMP_VALUE);
+ *
+ * RTC_MaskINTConfig(RTC_COMP_INDEX_INT, DISABLE);
+ * RTC_INTConfig(RTC_COMP_INDEX_INT, ENABLE);
+ *
+ * RTC_NvCmd(ENABLE);
+ * RTC_Cmd(ENABLE);
+ * }
+ * \endcode
+ */
+void RTC_NvCmd(FunctionalState NewState);
+
+/**
+ * \brief Enable or disable system wake up function of RTC.
+ * \param[in] NewState: new state of the wake up function.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void rtc_demo(void)
+ * {
+ * RTC_SystemWakeupConfig(ENABLE);
+ * }
+ * \endcode
+ */
+void RTC_SystemWakeupConfig(FunctionalState NewState);
+
+/**
+ * \brief Reset counter value of RTC.
+ * \param[in] None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void rtc_demo(void)
+ * {
+ * RTC_ResetCounter();
+ * RTC_Cmd(ENABLE);
+ * }
+ * \endcode
+ */
+void RTC_ResetCounter(void);
+
+/**
+ * \brief Reset prescaler counter value of RTC.
+ * \param[in] None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void rtc_demo(void)
+ * {
+ * RTC_ResetPrescalerCounter();
+ * RTC_Cmd(ENABLE);
+ * }
+ * \endcode
+ */
+void RTC_ResetPrescalerCounter(void);
+
+/**
+ * \brief Check whether the specified RTC interrupt is set.
+ * \param[in] RTC_INT: Specifies the RTC interrupt source to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * \arg RTC_INT_TICK: RTC tick interrupt source.
+ * \arg RTC_INT_COMP0: Compare 0 interrupt source.
+ * \arg RTC_INT_COMP1: Compare 1 interrupt source.
+ * \arg RTC_INT_COMP2: Compare 2 interrupt source.
+ * \arg RTC_INT_COMP3: Compare 3 interrupt source.
+ * \arg RTC_INT_PRE_COMP: Prescale compare interrupt source.
+ * \arg RTC_INT_PRE_COMP3: Prescale & compare 3 interrupt source.
+ * \return The new state of RTC_INT (SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void rtc_demo(void)
+ * {
+ * ITStatus int_status = RTC_GetINTStatus(RTC_INT_COMP0);
+ * }
+ * \endcode
+ */
+ITStatus RTC_GetINTStatus(E_RTC_INT RTC_INT);
+
+/**
+ * \brief Clear the interrupt pending bits of RTC.
+ * \param[in] RTC_INT: specifies the RTC interrupt flag to clear.
+ * This parameter can be any combination of the following values:
+ * \arg RTC_INT_TICK: RTC tick interrupt source.
+ * \arg RTC_INT_OVF: RTC counter overflow interrupt source.
+ * \arg RTC_INT_COMP0: Compare 0 interrupt source.
+ * \arg RTC_INT_COMP1: Compare 1 interrupt source.
+ * \arg RTC_INT_COMP2: Compare 2 interrupt source.
+ * \arg RTC_INT_COMP3: Compare 3 interrupt source.
+ * \arg RTC_INT_PRE_COMP: Prescale compare interrupt source.
+ * \arg RTC_INT_PRE_COMP3: Prescale & compare 3 interrupt source.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void rtc_demo(void)
+ * {
+ * RTC_ClearINTPendingBit(RTC_INT_COMP0);
+ * }
+ * \endcode
+ */
+void RTC_ClearINTPendingBit(E_RTC_INT RTC_INT);
+
+/**
+ * \brief Checks whether the specified RTC wakeup state is set or not.
+ * \param RTC_WK: specifies the RTC interrupt source to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * \arg RTC_WK_TICK: tick wakeup function
+ * \arg RTC_WK_OVF: tick wakeup function
+ * \arg RTC_WK_PRE_CMP: prescale compare wakeup function
+ * \arg RTC_WK_PRE_CMP3: prescale & compare 3 wakeup function
+ * \arg RTC_WK_COMP0GT: compare 0 gt wakeup function
+ * \arg RTC_WK_COMP1GT: compare 1 gt wakeup function
+ * \arg RTC_WK_COMP2GT: compare 2 gt wakeup function
+ * \arg RTC_WK_COMP3GT: compare 3 gt wakeup function
+ * \arg RTC_WK_CMP0: compare 0 wakeup function
+ * \arg RTC_WK_CMP1: compare 1 wakeup function
+ * \arg RTC_WK_CMP2: compare 2 wakeup function
+ * \arg RTC_WK_CMP3: compare 3 wakeup function
+ * \return The new state of RTC_INT (SET or RESET).
+ */
+ITStatus RTC_GetWakeupStatus(E_RTC_WK RTC_WK);
+
+/**
+ * \brief Clear the wakeup status bits of RTC.
+ * \param RTC_WK: specifies the RTC wakeup flag to clear.
+ * This parameter can be any combination of the following values:
+ * \arg RTC_WK_TICK: tick wakeup function
+ * \arg RTC_WK_OVF: tick wakeup function
+ * \arg RTC_WK_PRE_CMP: prescale compare wakeup function
+ * \arg RTC_WK_PRE_CMP3: prescale & compare 3 wakeup function
+ * \arg RTC_WK_COMP0GT: compare 0 gt wakeup function
+ * \arg RTC_WK_COMP1GT: compare 1 gt wakeup function
+ * \arg RTC_WK_COMP2GT: compare 2 gt wakeup function
+ * \arg RTC_WK_COMP3GT: compare 3 gt wakeup function
+ * \arg RTC_WK_CMP0: compare 0 wakeup function
+ * \arg RTC_WK_CMP1: compare 1 wakeup function
+ * \arg RTC_WK_CMP2: compare 2 wakeup function
+ * \arg RTC_WK_CMP3: compare 3 wakeup function
+ * \return None.
+ */
+void RTC_ClearWakeupStatusBit(E_RTC_WK RTC_WK);
+
+/**
+ * \brief Clear the interrupt pending bit of the select comparator of RTC.
+ * \param[in] index: the comparator number.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void rtc_demo(void)
+ * {
+ * RTC_ClearCompINT(0);
+ * }
+ * \endcode
+ */
+void RTC_ClearCompINT(E_RTC_COMP_INDEX index);
+
+/**
+ * \brief Clear the overflow interrupt pending bit of RTC.
+ * \param[in] None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void rtc_demo(void)
+ * {
+ * RTC_ClearOverFlowINT();
+ * }
+ * \endcode
+ */
+void RTC_ClearOverFlowINT(void);
+
+/**
+ * \brief Clear the tick interrupt pending bit of RTC.
+ * \param[in] None.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void rtc_demo(void)
+ * {
+ * RTC_ClearTickINT();
+ * }
+ * \endcode
+ */
+void RTC_ClearTickINT(void);
+
+/**
+ * \brief Set RTC comparator value.
+ * \param[in] index: The comparator number,can be 0 ~ 3.
+ * \param[in] value: The comparator value to be set.Should be no more than 24 bits!
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * #define RTC_PRESCALER_VALUE 49
+ * #define RTC_COMP_INDEX RTC_COMP3
+ * #define RTC_COMP_INDEX_INT RTC_INT_COMP3
+ * #define RTC_COMP_VALUE (1000)
+ *
+ * void driver_rtc_init(void)
+ * {
+ * RTC_DeInit();
+ *
+ * RTC_SetPrescaler(RTC_PRESCALER_VALUE);
+ * RTC_SetCompValue(RTC_COMP_INDEX, RTC_COMP_VALUE);
+ *
+ * RTC_MaskINTConfig(RTC_COMP_INDEX_INT, DISABLE);
+ * RTC_INTConfig(RTC_COMP_INDEX_INT, ENABLE);
+ *
+ * RTC_NvCmd(ENABLE);
+ * RTC_Cmd(ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void RTC_SetCompValue(E_RTC_COMP_INDEX index, uint32_t value)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_COMP(index));
+
+ RTC_WriteReg((uint32_t)(&(RTC->COMP0) + index), (value & 0xFFFFFFFF));
+}
+
+/**
+ * \brief Set RTC comparator GT value.
+ * \param[in] index: The comparator gt number, can be 0 ~ 3.
+ * \param[in] value: The comparator value to be set.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * #define RTC_PRESCALER_VALUE 49
+ * #define RTC_COMP_INDEX RTC_COMP3
+ * #define RTC_COMP_INDEX_INT RTC_INT_COMP3
+ * #define RTC_COMP_VALUE (1000)
+ *
+ * void driver_rtc_init(void)
+ * {
+ * RTC_DeInit();
+ *
+ * RTC_SetPrescaler(RTC_PRESCALER_VALUE);
+ * RTC_SetCompValue(RTC_COMP_INDEX, RTC_COMP_VALUE);
+ *
+ * RTC_MaskINTConfig(RTC_COMP_INDEX_INT, DISABLE);
+ * RTC_INTConfig(RTC_COMP_INDEX_INT, ENABLE);
+ *
+ * RTC_NvCmd(ENABLE);
+ * RTC_Cmd(ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void RTC_SetCompGTValue(E_RTC_COMPGT_INDEX index, uint32_t value)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_COMPGT(index));
+
+ RTC_WriteReg((uint32_t)(&(RTC->COMP0GT) + index), (value & 0xFFFFFFFF));
+}
+
+/**
+ * \brief Set RTC prescaler comparator value.
+ * \param[in] value: The comparator value to be set.Should be no more than 12 bits!
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * #define RTC_PRESCALER_VALUE (3200 - 1)//max 4095
+ * #define RTC_PRECOMP_VALUE (320)//max 4095
+ * #define RTC_COMP3_VALUE (10)
+ *
+ * void driver_rtc_init(void)
+ * {
+ * RTC_DeInit();
+ *
+ * RTC_SetPrescaler(RTC_PRESCALER_VALUE);
+ * RTC_SetPreCompValue(RTC_PRECOMP_VALUE);
+ * RTC_SetCompValue(RTC_COMP3, RTC_COMP3_VALUE);
+ *
+ * RTC_MaskINTConfig(RTC_INT_PRE_COMP3, DISABLE);
+ * RTC_INTConfig(RTC_INT_PRE_COMP3, ENABLE);
+ *
+ * RTC_NvCmd(ENABLE);
+ * RTC_Cmd(ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void RTC_SetPreCompValue(uint32_t value)
+{
+ RTC_WriteReg((uint32_t)(&(RTC->PRE_COMP)), (value & 0xFFF));
+}
+
+/**
+ * \brief Get counter value of RTC.
+ * \param[in] None.
+ * \return The counter value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void rtc_demo(void)
+ * {
+ * uitn32_t counter = RTC_GetCounter();
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t RTC_GetCounter(void)
+{
+ return RTC->CNT;
+}
+
+/**
+ * \brief Get prescaler counter value of RTC.
+ * \param[in] None.
+ * \return The prescaler counter value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void rtc_demo(void)
+ * {
+ * uitn32_t pre_counter = RTC_GetPreCounter();
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t RTC_GetPreCounter(void)
+{
+ return RTC->PRE_CNT;
+}
+
+/**
+ * \brief Get RTC comparator value.
+ * \param[in] index: The comparator number.
+ * \return The comparator value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void rtc_demo(void)
+ * {
+ * uint32_t data = RTC_GetCompValue(RTC_COMP0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t RTC_GetCompValue(E_RTC_COMP_INDEX index)
+{
+ return *((volatile uint32_t *)(&(RTC->COMP0) + index));
+}
+
+/**
+ * \brief Get RTC comparator gt value.
+ * \param[in] index: The comparator number 0~3.
+ * \return The comparator value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void rtc_demo(void)
+ * {
+ * uitn32_t data = RTC_GetCompGTValue(0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t RTC_GetCompGTValue(E_RTC_COMPGT_INDEX index)
+{
+ return *((volatile uint32_t *)(&(RTC->COMP0GT) + index));
+}
+
+/**
+ * \brief Get RTC prescaler comparator value.
+ * \param[in] None.
+ * \return The prescaler comparator value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void rtc_demo(void)
+ * {
+ * uitn32_t data = RTC_GetPreCompValue();
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t RTC_GetPreCompValue(void)
+{
+ return RTC->PRE_COMP;
+}
+
+/**
+ * \brief Write backup register for store time information.
+ * \param[in] value: valuer=write to back up reister
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void rtc_demo(void)
+ * {
+ * RTC_WriteBackupReg(0x01020304);
+ * }
+ * \endcode
+ */
+//void RTC_WriteBackupReg(uint32_t value);
+__STATIC_INLINE void RTC_WriteBackupReg(uint32_t value)
+{
+ RTC_WriteReg((uint32_t)(&(RTC->BACKUP)), value);
+}
+
+/**
+ * \brief Read backup register.
+ * \param[in] None.
+ * \return Register value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void rtc_demo(void)
+ * {
+ * uint32_t reg_data = RTC_ReadBackupReg();
+ * }
+ * \endcode
+ */
+//uint32_t RTC_ReadBackupReg(void);
+__STATIC_INLINE uint32_t RTC_ReadBackupReg(void)
+{
+ return (RTC->BACKUP);
+}
+
+/** \} */ /* End of group RTC_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_RTC_H_ */
+
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor *****END OF FILE****/
+
diff --git a/inc/peripheral/rtl876x_spi.h b/inc/peripheral/rtl876x_spi.h
new file mode 100644
index 0000000..6ad0e13
--- /dev/null
+++ b/inc/peripheral/rtl876x_spi.h
@@ -0,0 +1,931 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_spi.h
+* \brief The header file of the peripheral SPI driver.
+* \details This file provides all SPI firmware functions.
+* \author elliot chen
+* \date 2015-5-6
+* \version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef _RTL876X_SPI_H_
+#define _RTL876X_SPI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup SPI SPI
+ *
+ * \brief Manage the SPI peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup SPI_Exported_Types Init Params Struct
+ *
+ * \ingroup SPI
+ */
+
+/**
+ * \brief SPI init structure definition.
+ *
+ * \ingroup SPI_Exported_Types
+ */
+
+typedef struct
+{
+ uint16_t SPI_Direction; /*!< Specifies the SPI unidirectional or bidirectional data mode.
+ This parameter can be a value of \ref SPI_Data_Direction. */
+ uint16_t SPI_Mode; /*!< Specifies the SPI operating mode.
+ This parameter can be a value of \ref SPI_Mode. */
+ uint16_t SPI_DataSize; /*!< Specifies the SPI data size.
+ This parameter can be a value of \ref SPI_Data_Size. */
+ uint16_t SPI_CPOL; /*!< Specifies the serial clock steady state.
+ This parameter can be a value of \ref SPI_Clock_Polarity */
+ uint16_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture.
+ This parameter can be a value of \ref SPI_Clock_Phase */
+ uint32_t SPI_SwapTxBitEn; /*!< Specifies whether to swap spi tx data bit.
+ This parameter can be a value of \ref SPI_Swap_Enable.
+ \note This parameter can only be configed if the SPI0 peripheral is set to Slave Mode.*/
+ uint32_t SPI_SwapRxBitEn; /*!< Specifies whether to swap spi rx data bit
+ This parameter can be a value of \ref SPI_Swap_Enable.
+ \note This parameter can only be configed if the SPI0 peripheral is set to Slave Mode.*/
+ uint32_t SPI_SwapTxByteEn; /*!< Specifies whether to swap spi tx data bit
+ This parameter can be a value of \ref SPI_Swap_Enable.
+ \note This parameter can only be configed if the SPI0 peripheral is set to Slave Mode.*/
+ uint32_t SPI_SwapRxByteEn; /*!< Specifies whether to swap spi rx data bit
+ This parameter can be a value of \ref SPI_Swap_Enable.
+ \note This parameter can only be configed if the SPI0 peripheral is set to Slave Mode.*/
+ uint32_t SPI_ToggleEn; /*!< Specifies whether to toggle when transfer done. */
+ uint32_t SPI_BaudRatePrescaler; /*!< Specifies the speed of SCK clock. SPI Clock Speed = clk source/SPI_ClkDIV
+ \note The communication clock is derived from the master clock. The slave clock does not need to be set. */
+ uint16_t SPI_FrameFormat; /*!< Specifies which serial protocol transfers the data.
+ This parameter can be a value of \ref SPI_Frame_Format. */
+ uint32_t SPI_TxThresholdLevel; /*!< Specifies the transmit FIFO Threshold. */
+ uint32_t SPI_RxThresholdLevel; /*!< Specifies the receive FIFO Threshold. */
+ uint32_t SPI_NDF; /*!< Specifies the trigger condition in EEPROM mode.
+ This parameter should be the value of the length of read data. */
+ uint16_t SPI_TxDmaEn; /*!< Specifies the Tx dma mode. */
+ uint16_t SPI_RxDmaEn; /*!< Specifies the Rx dma mode. */
+ uint8_t SPI_TxWaterlevel; /*!< Specifies the DMA tx water level. */
+ uint8_t SPI_RxWaterlevel; /*!< Specifies the DMA rx water level. */
+
+} SPI_InitTypeDef;
+
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup SPI_Exported_Constants Macro Definitions
+ *
+ * \ingroup SPI
+ */
+
+#define IS_SPI_ALL_PERIPH(PERIPH) (((PERIPH) == SPI0) || \
+ ((PERIPH) == SPI1))
+
+#define IS_SPI_CLOCK_SPEED(SPEED) (((SPEED) >= 0x01) && ((SPEED) <= 40000000))
+
+/**
+ * \defgroup SPI_Data_Direction SPI Data Direction
+ * \{
+ * \ingroup SPI_Exported_Constants
+ */
+#define SPI_Direction_FullDuplex ((uint16_t)0x0000)
+#define SPI_Direction_TxOnly ((uint16_t)0x0001)
+#define SPI_Direction_RxOnly ((uint16_t)0x0002)
+#define SPI_Direction_EEPROM ((uint16_t)0x0003)
+/** \} */
+
+#define IS_SPI_DIRECTION_MODE(MODE) (((MODE) == SPI_Direction_FullDuplex) || \
+ ((MODE) == SPI_Direction_RxOnly) || \
+ ((MODE) == SPI_Direction_TxOnly) || \
+ ((MODE) == SPI_Direction_EEPROM))
+
+/**
+ * \defgroup SPI_Mode SPI Mode
+ * \{
+ * \ingroup SPI_Exported_Constants
+ */
+
+#define SPI_Mode_Master ((uint16_t)0x0104)
+#define SPI_Mode_Slave ((uint16_t)0x0000)
+/** \} */
+#define IS_SPI_MODE(MODE) (((MODE) == SPI_Mode_Master) || \
+ ((MODE) == SPI_Mode_Slave))
+
+/**
+ * \defgroup SPI_Data_Size SPI Data Size
+ * \{
+ * \ingroup SPI_Exported_Constants
+ */
+
+#define SPI_DataSize_4b ((uint16_t)0x0003)
+#define SPI_DataSize_5b ((uint16_t)0x0004)
+#define SPI_DataSize_6b ((uint16_t)0x0005)
+#define SPI_DataSize_7b ((uint16_t)0x0006)
+#define SPI_DataSize_8b ((uint16_t)0x0007)
+#define SPI_DataSize_9b ((uint16_t)0x0008)
+#define SPI_DataSize_10b ((uint16_t)0x0009)
+#define SPI_DataSize_11b ((uint16_t)0x000a)
+#define SPI_DataSize_12b ((uint16_t)0x000b)
+#define SPI_DataSize_13b ((uint16_t)0x000c)
+#define SPI_DataSize_14b ((uint16_t)0x000d)
+#define SPI_DataSize_15b ((uint16_t)0x000e)
+#define SPI_DataSize_16b ((uint16_t)0x000f)
+#define SPI_DataSize_17b ((uint16_t)0x0010)
+#define SPI_DataSize_18b ((uint16_t)0x0011)
+#define SPI_DataSize_19b ((uint16_t)0x0012)
+#define SPI_DataSize_20b ((uint16_t)0x0013)
+#define SPI_DataSize_21b ((uint16_t)0x0014)
+#define SPI_DataSize_22b ((uint16_t)0x0015)
+#define SPI_DataSize_23b ((uint16_t)0x0016)
+#define SPI_DataSize_24b ((uint16_t)0x0017)
+#define SPI_DataSize_25b ((uint16_t)0x0018)
+#define SPI_DataSize_26b ((uint16_t)0x0019)
+#define SPI_DataSize_27b ((uint16_t)0x001A)
+#define SPI_DataSize_28b ((uint16_t)0x001B)
+#define SPI_DataSize_29b ((uint16_t)0x001C)
+#define SPI_DataSize_30b ((uint16_t)0x001D)
+#define SPI_DataSize_31b ((uint16_t)0x001E)
+#define SPI_DataSize_32b ((uint16_t)0x001F)
+/** \} */
+#define IS_SPI_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DataSize_4b) || \
+ ((DATASIZE) == SPI_DataSize_5b) || \
+ ((DATASIZE) == SPI_DataSize_6b) || \
+ ((DATASIZE) == SPI_DataSize_7b) || \
+ ((DATASIZE) == SPI_DataSize_8b) || \
+ ((DATASIZE) == SPI_DataSize_9b) || \
+ ((DATASIZE) == SPI_DataSize_10b) || \
+ ((DATASIZE) == SPI_DataSize_11b) || \
+ ((DATASIZE) == SPI_DataSize_12b) || \
+ ((DATASIZE) == SPI_DataSize_13b) || \
+ ((DATASIZE) == SPI_DataSize_14b) || \
+ ((DATASIZE) == SPI_DataSize_15b) || \
+ ((DATASIZE) == SPI_DataSize_16b) || \
+ ((DATASIZE) == SPI_DataSize_17b) || \
+ ((DATASIZE) == SPI_DataSize_18b) || \
+ ((DATASIZE) == SPI_DataSize_19b) || \
+ ((DATASIZE) == SPI_DataSize_20b) || \
+ ((DATASIZE) == SPI_DataSize_21b) || \
+ ((DATASIZE) == SPI_DataSize_22b) || \
+ ((DATASIZE) == SPI_DataSize_23b) || \
+ ((DATASIZE) == SPI_DataSize_24b) || \
+ ((DATASIZE) == SPI_DataSize_25b) || \
+ ((DATASIZE) == SPI_DataSize_26b) || \
+ ((DATASIZE) == SPI_DataSize_27b) || \
+ ((DATASIZE) == SPI_DataSize_28b) || \
+ ((DATASIZE) == SPI_DataSize_29b) || \
+ ((DATASIZE) == SPI_DataSize_30b) || \
+ ((DATASIZE) == SPI_DataSize_31b) || \
+ ((DATASIZE) == SPI_DataSize_32b))
+
+/**
+ * \defgroup SPI_BaudRate_Prescaler SPI BaudRate Prescaler Value
+ * \{
+ * \ingroup SPI_Exported_Constants
+ */
+
+#define SPI_BaudRatePrescaler_2 ((uint32_t)0x0002)
+#define SPI_BaudRatePrescaler_4 ((uint32_t)0x0004)
+#define SPI_BaudRatePrescaler_6 ((uint32_t)0x0006)
+#define SPI_BaudRatePrescaler_8 ((uint32_t)0x0008)
+#define SPI_BaudRatePrescaler_10 ((uint32_t)0x000A)
+#define SPI_BaudRatePrescaler_12 ((uint32_t)0x000C)
+#define SPI_BaudRatePrescaler_14 ((uint32_t)0x000E)
+#define SPI_BaudRatePrescaler_16 ((uint32_t)0x0010)
+#define SPI_BaudRatePrescaler_32 ((uint32_t)0x0020)
+#define SPI_BaudRatePrescaler_64 ((uint32_t)0x0040)
+#define SPI_BaudRatePrescaler_128 ((uint32_t)0x0080)
+#define SPI_BaudRatePrescaler_256 ((uint32_t)0x0100)
+/** \} */
+#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BaudRatePrescaler_2) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_4) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_8) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_10) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_12) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_14) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_16) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_32) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_64) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_128) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_256))
+
+/**
+ * \defgroup SPI_Clock_Polarity SPI Clock Polarity
+ * \{
+ * \ingroup SPI_Exported_Constants
+ */
+
+#define SPI_CPOL_Low ((uint16_t)0x0000)
+#define SPI_CPOL_High ((uint16_t)0x0001)
+/** \} */
+#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_CPOL_Low) || \
+ ((CPOL) == SPI_CPOL_High))
+
+/**
+ * \defgroup SPI_Clock_Phase SPI Clock Phase
+ * \{
+ * \ingroup SPI_Exported_Constants
+ */
+
+#define SPI_CPHA_1Edge ((uint16_t)0x0000)
+#define SPI_CPHA_2Edge ((uint16_t)0x0001)
+/** \} */
+#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_CPHA_1Edge) || \
+ ((CPHA) == SPI_CPHA_2Edge))
+
+/**
+ * \defgroup SPI_Frame_Format SPI Frame Format
+ * \{
+ * \ingroup SPI_Exported_Constants
+ */
+
+#define SPI_Frame_Motorola ((uint16_t)0x0000)
+#define SPI_Frame_TI_SSP ((uint16_t)0x0001)
+#define SPI_Frame_NS_MICROWIRE ((uint16_t)0x0002)
+#define SPI_Frame_Reserve ((uint16_t)0x0003)
+/** \} */
+#define IS_SPI_FRAME_FORMAT(FRAME) (((FRAME) == SPI_Frame_Motorola) || \
+ ((FRAME) == SPI_Frame_TI_SSP) || \
+ ((FRAME) == SPI_Frame_NS_MICROWIRE) || \
+ ((FRAME) == SPI_Frame_Reserve))
+
+/**
+ * \defgroup SPI_Flags_Definition SPI Flags Definition
+ * \{
+ * \ingroup SPI_Exported_Constants
+ */
+
+#define SPI_FLAG_BUSY ((uint16_t)0x0001)
+#define SPI_FLAG_TFNF ((uint16_t)0x0002)
+#define SPI_FLAG_TFE ((uint16_t)0x0004)
+#define SPI_FLAG_RFNE ((uint16_t)0x0008)
+#define SPI_FLAG_RFF ((uint16_t)0x0010)
+#define SPI_FLAG_TXE ((uint16_t)0x0020)
+#define SPI_FLAG_DCOL ((uint16_t)0x0040)
+/** \} */
+#define IS_SPI_GET_FLAG(FLAG) (((FLAG) == SPI_FLAG_DCOL) || ((FLAG) == SPI_FLAG_TXE) || \
+ ((FLAG) == SPI_FLAG_RFF) || ((FLAG) == SPI_FLAG_RFNE) || \
+ ((FLAG) == SPI_FLAG_TFE) || ((FLAG) == SPI_FLAG_TFNF) || \
+ ((FLAG) == SPI_FLAG_BUSY))
+
+/**
+ * \defgroup SPI_Interrupt_Definition SPI Interrupt Definition
+ * \{
+ * \ingroup SPI_Exported_Constants
+ */
+
+#define SPI_INT_TXE ((uint8_t)BIT(0))
+#define SPI_INT_TXO ((uint8_t)BIT(1))
+#define SPI_INT_RXU ((uint8_t)BIT(2))
+#define SPI_INT_RXO ((uint8_t)BIT(3))
+#define SPI_INT_RXF ((uint8_t)BIT(4))
+#define SPI_INT_MST ((uint8_t)BIT(5))
+#define SPI_INT_TUF ((uint8_t)BIT(6))
+#define SPI_INT_RIG ((uint8_t)BIT(7))
+/** \} */
+
+#define IS_SPI_CONFIG_IT(IT) (((IT) == SPI_INT_TXE) || \
+ ((IT) == SPI_INT_TXO) || \
+ ((IT) == SPI_INT_RXU) || \
+ ((IT) == SPI_INT_RXO) || \
+ ((IT) == SPI_INT_RXF) || \
+ ((IT) == SPI_INT_MST) || \
+ ((IT) == SPI_INT_TUF) || \
+ ((IT) == SPI_INT_RIG) )
+/**
+ * \defgroup SPI_GDMA_Transfer_Request SPI GDMA Transfer Request
+ * \{
+ * \ingroup SPI_Exported_Constants
+ */
+
+#define SPI_GDMAReq_Tx ((uint16_t)0x0002)
+#define SPI_GDMAReq_Rx ((uint16_t)0x0001)
+/** \} */
+#define IS_SPI_GDMAREQ(GDMAREQ) ((((GDMAREQ) & (uint16_t)0xFFFC) == 0x00) && ((GDMAREQ) != 0x00))
+
+/**
+ * \defgroup SPI_Swap_Enable SPI Swap Enable
+ * \{
+ * \ingroup SPI_Exported_Constants
+ */
+
+#define SPI_SWAP_ENABLE ((uint32_t)0x0001)
+#define SPI_SWAP_DISABLE ((uint32_t)0x0000)
+/** \} */
+#define IS_SPI_SWAPMODE(mode) (((mode) == SPI_SWAP_ENABLE) || \
+ ((mode) == SPI_SWAP_DISABLE))
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup SPI_Exported_functions Peripheral APIs
+ * \{
+ * \ingroup SPI
+ */
+
+/**
+ * \brief Deinitializes the SPIx peripheral registers to their default reset values.
+ * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_spi_init(void)
+ * {
+ * SPI_DeInit(SPI0);
+ * }
+ * \endcode
+ */
+void SPI_DeInit(SPI_TypeDef *SPIx);
+
+/**
+ * \brief Initializes the SPIx peripheral according to the specified
+ * parameters in the SPI_InitStruct.
+ * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral.
+ * \param[in] SPI_InitStruct: Pointer to a SPI_InitTypeDef structure that
+ * contains the configuration information for the specified SPI peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_spi_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE);
+
+ * SPI_InitTypeDef SPI_InitStruct;
+ * SPI_StructInit(&SPI_InitStruct);
+ *
+ * SPI_InitStruct.SPI_Direction = SPI_Direction_EEPROM;
+ * SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
+ * SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
+ * SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
+ * SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
+ * SPI_InitStruct.SPI_BaudRatePrescaler = 100;
+ * SPI_InitStruct.SPI_RxThresholdLevel = 1 - 1;
+ * SPI_InitStruct.SPI_NDF = 1 - 1;
+ * SPI_InitStruct.SPI_FrameFormat = SPI_Frame_Motorola;
+ *
+ * SPI_Init(SPI0, &SPI_InitStruct);
+ * }
+ * \endcode
+ */
+void SPI_Init(SPI_TypeDef *SPIx, SPI_InitTypeDef *SPI_InitStruct);
+
+/**
+ * \brief Fills each SPI_InitStruct member with its default value.
+ * \param[in] SPI_InitStruct: Pointer to a SPI_InitTypeDef structure which will be initialized.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_spi_init(void)
+ * {
+ *
+ * RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE);
+
+ * SPI_InitTypeDef SPI_InitStruct;
+ * SPI_StructInit(&SPI_InitStruct);
+ *
+ * SPI_InitStruct.SPI_Direction = SPI_Direction_EEPROM;
+ * SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
+ * SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
+ * SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
+ * SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
+ * SPI_InitStruct.SPI_BaudRatePrescaler = 100;
+ * SPI_InitStruct.SPI_RxThresholdLevel = 1 - 1;
+ * SPI_InitStruct.SPI_NDF = 1 - 1;
+ * SPI_InitStruct.SPI_FrameFormat = SPI_Frame_Motorola;
+ *
+ * SPI_Init(SPI0, &SPI_InitStruct);
+ * }
+ * \endcode
+ */
+void SPI_StructInit(SPI_InitTypeDef *SPI_InitStruct);
+
+/**
+ * \brief Enables or disables the selected SPI peripheral.
+ * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral.
+ * \param[in] NewState: New state of the SPIx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_spi_init(void)
+ * {
+ *
+ * RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE);
+ *
+ * SPI_InitTypeDef SPI_InitStruct;
+ * SPI_StructInit(&SPI_InitStruct);
+ *
+ * SPI_InitStruct.SPI_Direction = SPI_Direction_EEPROM;
+ * SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
+ * SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
+ * SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
+ * SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
+ * SPI_InitStruct.SPI_BaudRatePrescaler = 100;
+ * SPI_InitStruct.SPI_RxThresholdLevel = 1 - 1;
+ * SPI_InitStruct.SPI_NDF = 1 - 1;
+ * SPI_InitStruct.SPI_FrameFormat = SPI_Frame_Motorola;
+ *
+ * SPI_Init(SPI0, &SPI_InitStruct);
+ * SPI_Cmd(SPI0, ENABLE);
+ * }
+ * \endcode
+ */
+void SPI_Cmd(SPI_TypeDef *SPIx, FunctionalState NewState);
+
+/**
+ * \brief Transmits a number of bytes through the SPIx peripheral.
+ * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral.
+ * \param[in] pBuf: Bytes to be transmitted.
+ * \param[in] len: Byte length to be transmitted.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * uint8_t data_buf[] = {0x01,0x02,0x03};
+ * SPI_SendBuffer(SPI0, data_buf, sizeof(data_buf));
+ * }
+ * \endcode
+ */
+void SPI_SendBuffer(SPI_TypeDef *SPIx, uint8_t *pBuf, uint16_t len);
+
+/**
+ * \brief Transmits a number of halfWords through the SPIx peripheral.
+ * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral.
+ * \param[in] pBuf: Halfwords to be transmitted.
+ * \param[in] len: Halfwords length to be transmitted.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * uint16_t data_buf[] = {0x0102,0x0203,0x0304};
+ * SPI_SendHalfWord(SPI0, data_buf, sizeof(data_buf));
+ * }
+ * \endcode
+ */
+void SPI_SendHalfWord(SPI_TypeDef *SPIx, uint16_t *pBuf, uint16_t len);
+
+/**
+ * \brief Transmits a number of words through the SPIx peripheral.
+ * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral.
+ * \param[in] pBuf: Words to be transmitted.
+ * \param[in] len: Word length to be transmitted.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * uint32_t data_buf[] = {0x01020304,0x02030405,0x03040506};
+ * SPI_SendWord(SPI0, data_buf, sizeof(data_buf));
+ * }
+ * \endcode
+ */
+void SPI_SendWord(SPI_TypeDef *SPIx, uint32_t *pBuf, uint16_t len);
+
+/**
+ * \brief Enable or disable the specified SPI interrupt source.
+ * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral.
+ * \param[in] SPI_IT: Specifies the SPI interrupt source to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * \arg SPI_INT_TXE: Transmit FIFO empty interrupt source.
+ * \arg SPI_INT_TXO: Transmit FIFO overflow interrupt source.
+ * \arg SPI_INT_RXU: Receive FIFO underflow interrupt source.
+ * \arg SPI_INT_RXO: Receive FIFO overflow interrupt source.
+ * \arg SPI_INT_RXF: Receive FIFO full interrupt source.
+ * \arg SPI_INT_MST: Multi-Master contention interrupt source.
+ * \param[in] NewState: New state of the specified SPI interrupt source.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * SPI_INTConfig(SPI0, SPI_INT_RXF, ENABLE);
+ * }
+ * \endcode
+ */
+void SPI_INTConfig(SPI_TypeDef *SPIx, uint8_t SPI_IT, FunctionalState NewState);
+
+/**
+ * \brief Clear the specified SPI interrupt pending bit.
+ * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral.
+ * \param[in] SPI_IT: Specifies the SPI interrupt to clear.
+ * This parameter can be one of the following values:
+ * \arg SPI_INT_MST: Multi-Master Contention Interrupt.
+ * \arg SPI_INT_RXO: Receive FIFO Overflow Interrupt.
+ * \arg SPI_INT_RXU: Receive FIFO Underflow Interrupt.
+ * \arg SPI_INT_TXO: Transmit FIFO Overflow Interrupt.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * SPI_ClearINTPendingBit(SPI0, SPI_INT_RXF);
+ * }
+ * \endcode
+ */
+void SPI_ClearINTPendingBit(SPI_TypeDef *SPIx, uint16_t SPI_IT);
+
+/**
+ * \brief Transmits a data through the SPIx peripheral.
+ * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral.
+ * \param[in] Data: Data to be transmitted.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * uint32_t data = 0x01020304;
+ * SPI_SendData(SPI0, data);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void SPI_SendData(SPI_TypeDef *SPIx, uint32_t Data)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ SPIx->DR[0] = Data;
+ while (!(SPIx->SR & BIT(1)));
+}
+
+/**
+ * \brief Received data by the SPIx peripheral.
+ * \param[in] SPIx: Where x can be 0 or 1.
+ * \retval The most recent received data.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * uint32_t data = SPI_ReceiveData(SPI0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t SPI_ReceiveData(SPI_TypeDef *SPIx)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ return (uint32_t)SPIx->DR[0];
+}
+
+/**
+ * \brief Get data length in Tx FIFO through the SPIx peripheral.
+ * \param[in] SPIx: Where x can be 0 or 1.
+ * \return Data length in Tx FIFO.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * uint8_t data_len = SPI_GetTxFIFOLen(SPI0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint8_t SPI_GetTxFIFOLen(SPI_TypeDef *SPIx)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ return (uint8_t)SPIx->TXFLR;
+}
+
+/**
+ * \brief Get data length in Rx FIFO through the SPIx peripheral.
+ * \param[in] SPIx: Where x can be 0 or 1.
+ * \return Data length in Rx FIFO.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * uint8_t data_len = SPI_GetRxFIFOLen(SPI0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint8_t SPI_GetRxFIFOLen(SPI_TypeDef *SPIx)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ return (uint8_t)SPIx->RXFLR;
+}
+
+/**
+ * \brief Change SPI direction mode.
+ * \param[in] SPIx: Where x can be 0 or 1.
+ * \param[in] dir: Value of direction mode.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * SPI_ChangeDirection(SPI0, SPI_Direction_EEPROM);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void SPI_ChangeDirection(SPI_TypeDef *SPIx, uint16_t dir)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_DIRECTION_MODE(dir));
+
+ /* Disable the selected SPI peripheral */
+ SPIx->SSIENR &= ~0x01;
+
+ /* Change SPI direction mode */
+ SPIx->CTRLR0 &= ~(0x03 << 8);
+ SPIx->CTRLR0 |= dir << 8;
+
+ /* Enable the selected SPI peripheral */
+ SPIx->SSIENR |= 0x01;
+}
+
+/**
+ * \brief Set read Data length only in EEPROM mode through the SPIx peripheral,which
+ enables you to receive up to 64 KB of data in a continuous transfer.
+ * \param[in] SPIx: Where x can be 0 or 1
+ * \param[in] len: Length of read data which can be 1 to 65536.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * SPI_SetReadLen(SPI0, 100);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void SPI_SetReadLen(SPI_TypeDef *SPIx, uint16_t len)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ /* Disable the selected SPI peripheral */
+ SPIx->SSIENR &= ~0x01;
+ /* set read length in SPI EEPROM mode */
+ SPIx->CTRLR1 = len - 1;
+ /* Enable the selected SPI peripheral */
+ SPIx->SSIENR |= 0x01;
+}
+
+/**
+ * \brief Set cs number through the SPIx peripheral.
+ * \param[in] SPIx: Where x can be 0 or 1
+ * \param[in] number: If SPIx is SPI0, number must be 0. If SPIx is SPI1, number can be 0 to 2.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * SPI_SetCSNumber(SPI1, 1);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void SPI_SetCSNumber(SPI_TypeDef *SPIx, uint8_t number)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ /* set cs number */
+ SPIx->SER = BIT(number);
+}
+
+/**
+ * \brief Check whether the specified SPI interrupt is set.
+ * \param[in] SPIx: Where x can be 0 or 1
+ * \param[in] SPI_IT: Specifies the SPI interrupt to check.
+ * This parameter can be one of the following values:
+ * \arg SPI_INT_MST: Multi-Master Contention Interrupt.
+ * \arg SPI_INT_RXF: Receive FIFO Full Interrupt.
+ * \arg SPI_INT_RXO: Receive FIFO Overflow Interrupt.
+ * \arg SPI_INT_RXU: Receive FIFO Underflow Interrupt.
+ * \arg SPI_INT_TXO: Transmit FIFO Overflow Interrupt .
+ * \arg SPI_INT_TXE: Transmit FIFO Empty Interrupt.
+ * \return The new state of SPI_IT (SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * ITStatus int_status = SPI_GetINTStatus(SPI0, SPI_INT_RXF);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE ITStatus SPI_GetINTStatus(SPI_TypeDef *SPIx, uint32_t SPI_IT)
+{
+ ITStatus bit_status = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_CONFIG_IT(SPI_IT));
+
+ if ((SPIx->ISR & SPI_IT) != (uint32_t)RESET)
+ {
+ bit_status = SET;
+ }
+
+ /* Return the SPI_IT status */
+ return bit_status;
+}
+
+/**
+ * \brief Check whether the specified SPI flag is set.
+ * \param[in] SPIx: Where x can be 0 or 1
+ * \param[in] SPI_FLAG: Specifies the SPI flag to check.
+ * This parameter can be one of the following values:
+ * \arg SPI_FLAG_DCOL: Data Collision Error flag.Set if it is actively transmitting in master mode when another master selects this device as a slave.
+ * \arg SPI_FLAG_TXE: Transmission error flag.Set if the transmit FIFO is empty when a transfer is started in slave mode.
+ * \arg SPI_FLAG_RFF: Receive FIFO full flag. Set if the receive FIFO is completely full.
+ * \arg SPI_FLAG_RFNE: Receive FIFO Not Empty flag.Set if receive FIFO is not empty.
+ * \arg SPI_FLAG_TFE: Transmit FIFO Empty flag.Set if transmit FIFO is empty.
+ * \arg SPI_FLAG_TFNF: Transmit FIFO Not Full flag.Set if transmit FIFO is not full.
+ * \arg SPI_FLAG_BUSY: SPI Busy flag.Set if it is actively transferring data.reset if it is idle or disabled.
+ * \return The new state of SPI_FLAG (SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * FlagStatus flag_status = SPI_GetFlagState(SPI0, SPI_FLAG_TXE);
+ *
+ * }
+ * \endcode
+ */
+__STATIC_INLINE FlagStatus SPI_GetFlagState(SPI_TypeDef *SPIx, uint8_t SPI_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_GET_FLAG(SPI_FLAG));
+
+ /* Check the status of the specified SPI flag */
+ if ((SPIx->SR & SPI_FLAG) != (uint8_t)RESET)
+ {
+ /* SPI_FLAG is set */
+ bitstatus = SET;
+ }
+
+ /* Return the SPI_FLAG status */
+ return bitstatus;
+}
+
+/**
+ * \brief Enables or disables the SPIx GDMA interface.
+ * \param[in] SPIx: Where x can be 0 or 1
+ * \param[in] SPI_GDMAReq: Specifies the SPI GDMA transfer request to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * \arg SPI_GDMAReq_Tx: Tx buffer DMA transfer request.
+ * \arg SPI_GDMAReq_Rx: Rx buffer DMA transfer request.
+ * \param[in] NewState: New state of the selected SPI GDMA transfer request.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * SPI_GDMACmd(SPI0, SPI_GDMAReq_Tx, ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void SPI_GDMACmd(SPI_TypeDef *SPIx, uint16_t SPI_GDMAReq, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_SPI_GDMAREQ(SPI_GDMAReq));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SPI GDMA request */
+ SPIx->DMACR |= SPI_GDMAReq;
+ }
+ else
+ {
+ /* Disable the selected SPI GDMA request */
+ SPIx->DMACR &= (uint16_t)~(SPI_GDMAReq);
+ }
+}
+/**
+ * \brief Change SPI speed daynamically.
+ * \param[in] SPIx: Where x can be 0 or 1.
+ * \param[in] precalser: Value of prescaler.
+ * This parameter can be one of the following values:
+ * \arg SPI_BaudRatePrescaler_2
+ * \arg SPI_BaudRatePrescaler_4
+ * \arg SPI_BaudRatePrescaler_6
+ * \arg SPI_BaudRatePrescaler_8
+ * \arg SPI_BaudRatePrescaler_10
+ * \arg SPI_BaudRatePrescaler_12
+ * \arg SPI_BaudRatePrescaler_14
+ * \arg SPI_BaudRatePrescaler_16
+ * \arg SPI_BaudRatePrescaler_32
+ * \arg SPI_BaudRatePrescaler_64
+ * \arg SPI_BaudRatePrescaler_128
+ * \arg SPI_BaudRatePrescaler_256
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * SPI_Change_CLK(SPI0, SPI_BaudRatePrescaler_2);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void SPI_Change_CLK(SPI_TypeDef *SPIx, uint32_t prescaler)
+{
+ SPIx->BAUDR = prescaler % 0xFFFF;
+}
+
+/**
+ * \brief Set SPI Rx sample delay.
+ * \param[in] SPIx: Where x can be 0 or 1.
+ * \param[in] delay: This parameter can be 0 to 255.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void spi_demo(void)
+ * {
+ * SPI_SetRxSampleDly(SPI0, 1);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void SPI_SetRxSampleDly(SPI_TypeDef *SPIx, uint32_t delay)
+{
+ SPIx->RX_SAMPLE_DLY = delay & 0xFF;
+}
+
+/** \} */ /* End of group SPI_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_SPI_H_ */
+
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/inc/peripheral/rtl876x_tim.h b/inc/peripheral/rtl876x_tim.h
new file mode 100644
index 0000000..1ef1101
--- /dev/null
+++ b/inc/peripheral/rtl876x_tim.h
@@ -0,0 +1,641 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_tim.h
+* \brief The header file of the peripheral TIMER driver.
+* \details This file provides all TIMER firmware functions.
+* \author Yuan
+* \date 2020-09-29
+* \version v1.0.0
+* *********************************************************************************************************
+*/
+
+#ifndef _RTL876X_TIM_H_
+#define _RTL876X_TIM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup TIM TIM
+ * \brief Manage the TIM peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup TIM_Exported_Types Init Params Struct
+ *
+ * \ingroup TIM
+ */
+
+/**
+ * \brief TIM init structure definition.
+ *
+ * \ingroup TIM_Exported_Types
+ */
+typedef struct
+{
+ uint16_t TIM_ClockSrc; /*!< <b>Deprecated</b> use RCC instead.*/
+ uint16_t TIM_DIV; /*!< Clock fix at 40Mhz,add this parameter div the clock*/
+ uint16_t TIM_SOURCE_DIV; /*!< Specifies the clock source div.
+ This parameter can be a value of \ref TIM_Clock_Divider*/
+ uint16_t TIM_SOURCE_DIV_En; /*!< Timer source clock div enable. */
+ uint16_t TIM_Mode; /*!< Specifies the counter mode.
+ This parameter can be a value of \ref TIM_Mode. */
+ uint16_t TIM_PWM_En; /*!< Specifies the PWM mode.
+ This parameter can be a value of DISABLE or ENABLE */
+ uint32_t TIM_Period; /*!< Specifies the period value to be loaded into the active
+ Auto-Reload Register at the next update event.
+ This parameter must range from 0x0000 to 0xFFFFFFFF. */
+ uint32_t TIM_PWM_High_Count; /*!< Specifies the PWM High Count.
+ This parameter must range from 0x0000 to 0xFFFFFFFF. */
+ uint32_t TIM_PWM_Low_Count; /*!< Specifies the PWM Low Count.
+ This parameter must range from 0x0000 to 0xFFFFFFFF. */
+ uint32_t TIM_EventMode; /*!< Specifies the TIM event mode. */
+ uint32_t TIM_EventIndex; /*!< Specifies the TIM event index. */
+ uint32_t TIM_EventDuration; /*!< Specifies the TIM event duration.*/
+ uint8_t ClockDepend; /*!< Specifies TIM Source depend.timer3 depend timer2 ,timer5 depend timer4.
+ This parameter can be a value of ENABLE or DISABLE */
+ uint32_t PWM_Deazone_Size; /*!<Size of deadzone time, DeadzoneTime=deadzonesize/(32000 or 32768).
+ This parameter must range from 1 to 0xff. */
+ uint16_t PWMDeadZone_En; /*!<PWM Deadzone enable, pwm0_pn: timer2
+ This parameter can be a value of ENABLE or DISABLE. */
+ uint16_t PWM_Stop_State_P; /*!< Specifies the PWM P stop state.
+ This parameter can be a value of \ref PWMDeadZone_Stop_state. */
+ uint16_t PWM_Stop_State_N; /*!< Specifies the PWM N stop state.
+ This parameter can be a value of \ref PWMDeadZone_Stop_state. */
+} TIM_TimeBaseInitTypeDef;
+
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/* TIM private defines */
+#define TIMER0_LOAD_COUNT2 *((volatile uint32_t *)0x400020B0UL)
+#define TIMER1_LOAD_COUNT2 *((volatile uint32_t *)0x400020B4UL)
+#define TIMER2_LOAD_COUNT2 *((volatile uint32_t *)0x400020B8UL)
+#define TIMER3_LOAD_COUNT2 *((volatile uint32_t *)0x400020BCUL)
+#define TIMER4_LOAD_COUNT2 *((volatile uint32_t *)0x400020C0UL)
+#define TIMER5_LOAD_COUNT2 *((volatile uint32_t *)0x400020C4UL)
+
+#define TIMER_PWM2_CR *((volatile uint32_t *)0x40000364UL)
+
+/**
+ * \defgroup TIM_Exported_constants Macro Definitions
+ *
+ * \ingroup TIM
+ */
+
+#define IS_TIM_ALL_PERIPH(PERIPH) (((PERIPH) == TIM0) || \
+ ((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM2) || \
+ ((PERIPH) == TIM3) || \
+ ((PERIPH) == TIM4) || \
+ ((PERIPH) == TIM5))
+
+/**
+ * \def PWMDeadZone_Peripheral PWMDeadZone
+ */
+
+#define IS_PWM_ALL_PERIPH(PERIPH) ((PERIPH) == PWM2)
+
+/**
+ * \defgroup TIM_Clock_Divider TIM Clock Divider
+ * \{
+ * \ingroup TIM_Exported_constants
+ */
+#define TIM_CLOCK_DIVIDER_1 ((uint16_t)0x0)
+#define TIM_CLOCK_DIVIDER_2 ((uint16_t)0x4)
+#define TIM_CLOCK_DIVIDER_4 ((uint16_t)0x5)
+#define TIM_CLOCK_DIVIDER_8 ((uint16_t)0x6)
+#define TIM_CLOCK_DIVIDER_40 ((uint16_t)0x7)
+/** \} */
+#define IS_TIM_SOURCE_DIVIDER(DIV) (((DIV) == TIM_CLOCK_DIVIDER_1) || \
+ ((DIV) == TIM_CLOCK_DIVIDER_2) || \
+ ((DIV) == TIM_CLOCK_DIVIDER_4) || \
+ ((DIV) == TIM_CLOCK_DIVIDER_8) ||\
+ ((DIV) == TIM_CLOCK_DIVIDER_40))
+
+/**
+ * \defgroup TIM_Mode TIM Mode
+ * \{
+ * \ingroup TIM_Exported_constants
+ */
+#define TIM_Mode_FreeRun ((uint16_t)0x0000)
+#define TIM_Mode_UserDefine ((uint16_t)0x0001)
+/** \} */
+#define IS_TIM_MODE(mode) (((mode) == TIM_Mode_FreeRun) || \
+ ((mode) == TIM_Mode_UserDefine))
+
+/**
+ * \defgroup TIM_PWM_En TIM PWM Mode Enable
+ * \{
+ * \ingroup TIM_Exported_constants
+ */
+#define PWM_ENABLE ((uint16_t)0x1)
+#define PWM_DISABLE ((uint16_t)0x0)
+/** \} */
+#define IS_TIM_PWM_En(mode) (((mode) == PWM_ENABLE) || \
+ ((mode) == PWM_DISABLE))
+
+/**
+ * \defgroup TIM_Event_Duration TIM Event Duration
+ * \{
+ * \ingroup TIM_Exported_constants
+ */
+#define TIM_EventDuration_32us ((uint16_t)0x0000)
+#define TIM_EventDuration_64us ((uint16_t)0x0001)
+#define TIM_EventDuration_128us ((uint16_t)0x0002)
+#define TIM_EventDuration_256us ((uint16_t)0x0003)
+/** \} */
+
+#define IS_TIM_Event_DURATION(duration) (((duration) == TIM_EventDuration_32us) || \
+ ((duration) == TIM_EventDuration_64us) || \
+ ((duration) == TIM_EventDuration_128us) || \
+ ((duration) == TIM_EventDuration_256us))
+
+/**
+ * \defgroup PWMDeadZone_En PWM DeadZone enable
+ * \{
+ * \ingroup TIM_Exported_constants
+ */
+#define DEADZONE_ENABLE ((uint16_t)0x1)
+#define DEADZONE_DISABLE ((uint16_t)0x0)
+/** \} */
+#define IS_TIM_PWM_DeadZone_En(mode) (((mode) == DEADZONE_ENABLE) || \
+ ((mode) == DEADZONE_DISABLE))
+
+/**
+ * \defgroup PWMDeadZone_Stop_State PWM DeadZone Stop State
+ * \{
+ * \ingroup TIM_Exported_constants
+ */
+#define PWM_STOP_AT_HIGH ((uint16_t)0x1)
+#define PWM_STOP_AT_LOW ((uint16_t)0x0)
+/** \} */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup TIM_Exported_Functions Peripheral APIs
+ * \{
+ * \ingroup TIM
+ */
+
+/**
+ * \brief Deinitialize the TIMx peripheral registers to their default reset values.
+ * \return None.
+ */
+void TIM_DeInit(void);
+
+/**
+ * \brief Initialize the TIMx time base unit peripheral according to
+ * the specified parameters in TIM_TimeBaseInitStruct.
+ * \param[in] TIMx: where x can be 2 to 5 to select the TIM peripheral.
+ * \param[in] TIM_TimeBaseInitStruct: Pointer to a TIM_TimeBaseInitTypeDef
+ * structure that contains the configuration information for the selected TIM peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_timer_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+ *
+ * TIM_TimeBaseInitTypeDef TIM_InitStruct;
+ * TIM_StructInit(&TIM_InitStruct);
+ *
+ * TIM_InitStruct.TIM_PWM_En = PWM_DISABLE;
+ * TIM_InitStruct.TIM_Period = 1000000 - 1 ;
+ * TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ * TIM_TimeBaseInit(TIMER_NUM, &TIM_InitStruct);
+ * }
+ * \endcode
+ */
+void TIM_TimeBaseInit(TIM_TypeDef *TIMx, TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct);
+
+/**
+ * \brief Fills each TIM_InitStruct member with its default value.
+ * \param[in] TIM_TimeBaseInitStruct: Pointer to a TIM_TimeBaseInitTypeDef structure which will be initialized.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_timer_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+ *
+ * TIM_TimeBaseInitTypeDef TIM_InitStruct;
+ * TIM_StructInit(&TIM_InitStruct);
+ *
+ * TIM_InitStruct.TIM_PWM_En = PWM_DISABLE;
+ * TIM_InitStruct.TIM_Period = 1000000 - 1;
+ * TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ * TIM_TimeBaseInit(TIM4, &TIM_InitStruct);
+ * }
+ * \endcode
+ */
+void TIM_StructInit(TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct);
+
+/**
+ * \brief Enables or disables the specified TIM peripheral.
+ * \param[in] TIMx: Where x can be 2 to 5 to select the TIMx peripheral.
+ * \param[in] NewState: New state of the TIMx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_timer_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+ *
+ * TIM_TimeBaseInitTypeDef TIM_InitStruct;
+ * TIM_StructInit(&TIM_InitStruct);
+ *
+ * TIM_InitStruct.TIM_PWM_En = PWM_DISABLE;
+ * TIM_InitStruct.TIM_Period = 1000000 - 1;
+ * TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ * TIM_TimeBaseInit(TIM4, &TIM_InitStruct);
+ * TIM_Cmd(TIM4, ENABLE);
+ * }
+ * \endcode
+ */
+void TIM_Cmd(TIM_TypeDef *TIMx, FunctionalState NewState);
+
+/**
+ * \brief Enables or disables the specified TIMx interrupt.
+ * \param[in] TIMx: Where x can be 2 to 5 to select the TIMx peripheral.
+ * \param[in] NewState: New state of the TIMx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_timer_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+ *
+ * TIM_TimeBaseInitTypeDef TIM_InitStruct;
+ * TIM_StructInit(&TIM_InitStruct);
+ *
+ * TIM_InitStruct.TIM_PWM_En = PWM_DISABLE;
+ * TIM_InitStruct.TIM_Period = 1000000 - 1;
+ * TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ * TIM_TimeBaseInit(TIM4, &TIM_InitStruct);
+ * TIM_ClearINT(TIM4);
+ * TIM_INTConfig(TIM4, ENABLE);
+ */
+void TIM_INTConfig(TIM_TypeDef *TIMx, FunctionalState NewState);
+
+/**
+ * \brief Change TIM period value.
+ * \param[in] TIMx: Where x can be 2 to 5 to select the TIMx peripheral.
+ * \param[in] period: Period value to be changed.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void timer_demo(void)
+ * {
+ * uint32_t new_period = 1000000 - 1;
+ * TIM_Cmd(TIM4, DISABLE);
+ * TIM_ChangePeriod(TIM4, new_period);
+ *
+ * }
+ * \endcode
+ */
+void TIM_ChangePeriod(TIM_TypeDef *TIMx, uint32_t period);
+
+/**
+ * \brief Change PWM freq and duty according high_cnt and low_cnt
+ * \param[in] TIMx: Where x can be 2 to 5 to select the TIMx peripheral.
+ * \param[in] high_count: This parameter can be 0x00~0xFFFFFFFF.
+ * \param[in] low_count: This parameter can be 0x00~0xFFFFFFFF.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void timer_demo(void)
+ * {
+ * uint32_t high_count = 1000000 - 1;
+ * uint32_t low_count = 1000000 - 1;
+ * TIM_Cmd(TIM4, DISABLE);
+ * TIM_ChangePeriod(TIM4, high_count, low_count);
+ * }
+ * \endcode
+ */
+void TIM_PWMChangeFreqAndDuty(TIM_TypeDef *TIMx, uint32_t high_count, uint32_t low_count);
+
+/**
+ * \brief Get TIMx current value when timer is running.
+ * \param[in] TIMx: where x can be 2 to 5 to select the TIMx peripheral.
+ * \return The counter value.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void timer_demo(void)
+ * {
+ * uint32_t cur_value = TIM_GetCurrentValue(TIM4);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint32_t TIM_GetCurrentValue(TIM_TypeDef *TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ return TIMx->CurrentValue;
+}
+
+/**
+ * \brief Check whether the TIM interrupt has occurred or not.
+ * \param[in] TIMx: Where x can be 2 to 5 to select the TIMx peripheral.
+ * \return The new state of the TIM_IT(SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void timer_demo(void)
+ * {
+ * ITStatus int_status = TIM_GetINTStatus(TIM4);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE ITStatus TIM_GetINTStatus(TIM_TypeDef *TIMx)
+{
+ ITStatus bitstatus = RESET;
+ uint16_t itstatus = (uint16_t)TIMx->IntStatus;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ if (itstatus != (uint16_t)RESET)
+ {
+ bitstatus = SET;
+ }
+
+ return bitstatus;
+}
+
+/**
+ * \brief Clear TIM interrupt.
+ * \param[in] TIMx: Where x can be 2 to 5 to select the TIMx peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void timer_demo(void)
+ * {
+ * TIM_ClearINT(TIM4);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void TIM_ClearINT(TIM_TypeDef *TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ /* Clear the IT */
+ TIMx->EOI;
+}
+
+/**
+ * \brief Check whether the TIM is in operation or not.
+ * \param[in] TIMx: Where x can be 2 to 5 to select the TIMx peripheral.
+ * \return The new state of the timer operation status (SET or RESET).
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void timer_demo(void)
+ * {
+ * ITStatus intstatus = TIM_GetOperationStatus(TIM4);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE ITStatus TIM_GetOperationStatus(TIM_TypeDef *TIMx)
+{
+ ITStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ if (TIMx->ControlReg & BIT(0))
+ {
+ bitstatus = SET;
+ }
+
+ return bitstatus;
+}
+
+/**
+ * \brief PWM complementary output emergency stop and resume.
+ * PWM_P emergency stop level state is configured by PWM_Stop_State_P,
+ * PWM_N emergency stop level state is configured by PWM_Stop_State_N.
+ * \param[in] PWMx: PWM2.
+ * \param[in] NewState: New state of complementary output.
+ * \ref DISABLE: Resume PWM complementary output.
+ * \ref ENABLE: PWM complementary output emergency stop.
+ * \note To use this function, need to configure the corresponding timer.
+ * PWM2 ->> TIM2.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_pwm_init(void)
+ * {
+ * Pad_Config(P0_1, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ * Pad_Config(P0_2, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ * PAD_OUT_HIGH);
+ * Pad_Config(P2_2, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ * PAD_OUT_HIGH);
+ *
+ * Pinmux_Config(P0_1, PWM_OUT_PIN_PINMUX);
+ * Pinmux_Config(P0_2, PWM_OUT_P_PIN_PINMUX);
+ * Pinmux_Config(P2_2, PWM_OUT_N_PIN_PINMUX);
+ * }
+ *
+ * void driver_pwm_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+ *
+ * TIM_TimeBaseInitTypeDef TIM_InitStruct;
+ * TIM_StructInit(&TIM_InitStruct);
+ * TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ * TIM_InitStruct.TIM_PWM_En = PWM_ENABLE;
+ * TIM_InitStruct.TIM_PWM_High_Count = PWM_HIGH_COUNT;
+ * TIM_InitStruct.TIM_PWM_Low_Count = PWM_LOW_COUNT;
+ * TIM_InitStruct.PWM_Stop_State_P = PWM_STOP_AT_HIGH;
+ * TIM_InitStruct.PWM_Stop_State_N = PWM_STOP_AT_LOW;
+ * TIM_InitStruct.PWMDeadZone_En = DEADZONE_ENABLE; //enable to use pwn p/n output
+ * TIM_InitStruct.PWM_Deazone_Size = 255;
+ * TIM_TimeBaseInit(TIM2, &TIM_InitStruct);
+ *
+ * TIM_Cmd(TIM2, ENABLE);
+ * }
+ *
+ * void pwm_demo(void)
+ * {
+ * board_pwm_init();
+ * driver_pwm_init();
+ * //Add delay.
+ * TIM_PWMComplOutputEMCmd(PWM2,ENABLE);
+ * }
+ * \endcode
+ */
+void TIM_PWMComplOutputEMCmd(PWM_TypeDef *PWMx, FunctionalState NewState);
+
+/**
+ * \brief Enable or disable bypass dead zone function of PWM complementary output.
+ * After enabling, PWM_P = ~PWM_N.
+ * \param[in] PWMx: PWM2.
+ * \param[in] NewState: New state of the PWMx peripheral.
+ * \ref DISABLE: Disable bypass dead zone function.
+ * \ref ENABLE: Enable bypass dead zone function.
+ * \return None.
+ * \note To use this function, need to configure the corresponding timer.
+ * PWM2 ->> TIM2.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_pwm_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+ *
+ * TIM_TimeBaseInitTypeDef TIM_InitStruct;
+ * TIM_StructInit(&TIM_InitStruct);
+ * TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ * TIM_InitStruct.TIM_PWM_En = PWM_ENABLE;
+ * TIM_InitStruct.TIM_PWM_High_Count = PWM_HIGH_COUNT;
+ * TIM_InitStruct.TIM_PWM_Low_Count = PWM_LOW_COUNT;
+ * TIM_InitStruct.PWM_Stop_State_P = PWM_STOP_AT_HIGH;
+ * TIM_InitStruct.PWM_Stop_State_N = PWM_STOP_AT_LOW;
+ * TIM_InitStruct.PWMDeadZone_En = DEADZONE_ENABLE; //enable to use pwn p/n output
+ * TIM_InitStruct.PWM_Deazone_Size = 255;
+ * TIM_TimeBaseInit(TIM2, &TIM_InitStruct);
+ *
+ * TIM_Cmd(TIM2, ENABLE);
+ * TIM_PWMDZBypassCmd(PWM2, ENABLE);
+ * }
+ * \endcode
+ */
+void TIM_PWMDZBypassCmd(PWM_TypeDef *PWMx, FunctionalState NewState);
+
+/**
+ * \brief Change the PWM dead time clock source.
+ * \param[in] PWMx: PWM2.
+ * \param[in] NewState: New state of the PWMx peripheral.
+ * \ref DISABLE: Use 32k clock source.
+ * \ref ENABLE: Use 5M clock source.
+ * \return None.
+ * \note To use this function, need to configure the corresponding timer.
+ * PWM2 ->> TIM2.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_pwm_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+ * //Open 5M clock source.
+ * RCC_ClockSrc5MCmd();
+ *
+ * TIM_TimeBaseInitTypeDef TIM_InitStruct;
+ *
+ * TIM_StructInit(&TIM_InitStruct);
+ * TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ * TIM_InitStruct.TIM_PWM_En = PWM_ENABLE;
+ * TIM_InitStruct.TIM_PWM_High_Count = PWM_HIGH_COUNT;
+ * TIM_InitStruct.TIM_PWM_Low_Count = PWM_LOW_COUNT;
+ * TIM_InitStruct.PWM_Stop_State_P = PWM_STOP_AT_HIGH;
+ * TIM_InitStruct.PWM_Stop_State_N = PWM_STOP_AT_LOW;
+ * TIM_InitStruct.PWMDeadZone_En = DEADZONE_ENABLE; //enable to use pwn p/n output
+ * TIM_InitStruct.PWM_Deazone_Size = PWM_DEAD_ZONE_SIZE;
+ * TIM_TimeBaseInit(TIM2, &TIM_InitStruct);
+ *
+ * //Use 5M clock source.
+ * TIM_PWMChangeDZClockSrc(PWM2,ENABLE);
+ *
+ * TIM_Cmd(TIM2, ENABLE);
+ * }
+ * \endcode
+ */
+void TIM_PWMChangeDZClockSrc(PWM_TypeDef *PWMx, FunctionalState NewState);
+
+/**
+ * \brief PWM complementary output emergency stop.
+ * \param[in] PWMx: PWM2.
+ * \return None.
+ */
+__STATIC_INLINE void PWM_Deadzone_EMStop(PWM_TypeDef *PWMx)
+{
+ /* Check the parameters. */
+ assert_param(IS_PWM_ALL_PERIPH(PWMx));
+
+ PWMx->CR |= BIT(8);
+}
+
+/**
+ * @brief Get PWM current output status.
+ * @param TIMx: where x can be 2 to 5 to select the TIMx peripheral.
+ * @retval The output state of the timer(SET: High or RESET: Low).
+ */
+__STATIC_INLINE FlagStatus TIM_GetPWMOutputStatus(TIM_TypeDef *TIMx)
+{
+ uint32_t timer_index = 0;
+ uint32_t reg_value = 0;
+ ITStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ timer_index = ((uint32_t)TIMx - TIM0_REG_BASE) / (TIM1_REG_BASE - TIM0_REG_BASE);
+ reg_value = *((volatile uint32_t *)0x40006024UL);
+
+ if ((reg_value >> timer_index) & BIT(0))
+ {
+ bitstatus = SET;
+ }
+
+ return bitstatus;
+}
+/** \} */ /* End of group TIM_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_RTL876X_TIM_H_*/
+
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/inc/peripheral/rtl876x_trng.h b/inc/peripheral/rtl876x_trng.h
new file mode 100644
index 0000000..bac5167
--- /dev/null
+++ b/inc/peripheral/rtl876x_trng.h
@@ -0,0 +1,162 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file rtl876x_trng.h
+* @brief
+* @details
+* @author eason li
+* @date 2019-05-06
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef __RTL876X_TRNG_H
+#define __RTL876X_TRNG_H
+// *INDENT-OFF*
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* Includes ------------------------------------------------------------------*/
+#include <stdbool.h>
+#include "rtl876x.h"
+
+/**
+ * @brief referenc to IO_MODULE (sheet: SoC-VENDOR_REG)
+ */
+typedef struct
+{
+ union /* 0x00 */
+ {
+ __IO uint32_t CTRL;
+ struct
+ {
+ __IO uint32_t rng_srst: 1; /* RNG Software Reset, High Active. It will reset all digital except programmable registers, except Calibration Degital. */
+ __IO uint32_t clk_hf_sel: 1; /* Selection of High Speed Clock: 0: clk_hfosc_rng, 1: clk_hfosc_rng/2 */
+ __IO uint32_t corrector_bypass: 1; /* Random Bias Corrector will be bypassed if corrector_bypass = 1 */
+ __IO uint32_t rsvd0: 2;
+ __IO uint32_t corrector_imode: 1; /* Random Bias Corrector sample rate, 0: 4 valid TRNG, 1: 2 valid TRNG (But corrector_bypass is the highest priority) */
+ __IO uint32_t dbg0_sel: 5; /* The Debug Signal Group 0 Selection. */
+ __IO uint32_t dbg1_sel: 5; /* The Debug Signal Group 1 Selection. */
+ __IO uint32_t lfsr_bypass_1: 1; /* LFSR_1 will be bypassed if lfsr_bypass_1 = 1. */
+ __IO uint32_t lfsr_mode: 1;
+ __IO uint32_t st_en: 1; /* Self test enable */
+ __IO uint32_t mode: 1; /* 0: TRNG -> BIAS -> LFSR -> self-test -> buf; 1: TRNG -> BIAS -> self-test -> LFSR -> buf */
+ __IO uint32_t rsvd1: 12;
+ } CTRL_field;
+ };
+
+ __IO uint32_t rsvd0[6]; // 0x04 - 0x18
+
+ union /* 0x1C */
+ {
+ __IO uint32_t RNG_return0;
+ struct
+ {
+ __I uint32_t out_ready: 1; /* The Random Number for Realtek is Ready to Read. */
+ __IO uint32_t rsvd0: 31;
+ } return0_field;
+ };
+
+ __I uint32_t valid_bit_num; /* 0x20, The Bit Number of Realtek Random Number is Generated after reset. It will be wrapped around if reach the top. */
+ __I uint32_t drop_num; /* 0x24, The Bit Number of Realtek Random Number is Dropped after reset. It will be wrapped around if reach the top. */
+ __I uint32_t random_out; /* 0x28, Random Number for Realtek. It will return all zeros if random number is not ready. */
+ __IO uint32_t lfsr_poly_lsb; /* 0x2C, RNG LFSR_1 Polynomial LSB 32-bit from register (for Realtek) */
+ __IO uint32_t lfsr_poly_msb; /* 0x30, RNG LFSR_1 Polynomial MSB 32-bit from register (for Realtek) */
+ __IO uint32_t rsvd1; /* 0x34 */
+
+ union /* 0x38 */
+ {
+ __IO uint32_t RNG_POWER;
+ struct
+ {
+ __IO uint32_t gating_en: 1; /* Enable power gating function. */
+ __IO uint32_t rsvd: 31;
+ } power_field;
+ };
+
+ union /* 0x3C */
+ {
+ __IO uint32_t RNG_st;
+ struct
+ {
+ __IO uint32_t thr_done_rep: 8; /* Done threshold for repetition count test */
+ __IO uint32_t thr_err_rep: 8; /* Error threshold for repetition count test */
+ __IO uint32_t window_size_adap2: 2;
+ __IO uint32_t window_size_adap1: 2;
+ __IO uint32_t compare_unit_adap2: 1; /* Compare unit for adaptive test 2, 0 : bit mode, 1 : byte mode */
+ __IO uint32_t compare_unit_adap1: 1; /* Compare unit for adaptive test 1, 0 : bit mode, 1 : byte mode */
+ __IO uint32_t compare_unit_rep: 1; /* Compare unit for repetition test, 0 : bit mode, 1 : byte mode */
+ __IO uint32_t rsvd: 1;
+ __IO uint32_t thr_done_adap2: 4; /* Done threshold for adaptive proportion test (pass times), Default : pass four times, done_adap2 will be asserted */
+ __IO uint32_t thr_done_adap1: 4; /* Done threshold for adaptive proportion test (pass times), Default : pass four times, done_adap1 will be asserted */
+ } st_field;
+ };
+
+ union /* 0x40 */
+ {
+ __IO uint32_t RNG_st_return;
+ struct
+ {
+ __IO uint32_t err_adap2: 1; /* Error will be asserted when adaptive proportion test detects error */
+ __IO uint32_t err_adap1: 1; /* Error will be asserted when adaptive proportion test detects error */
+ __IO uint32_t err_rep: 1; /* Error will be asserted when repetition count test detects error */
+ __IO uint32_t err: 1; /* Error will be asserted when self test detects error */
+ __I uint32_t done_adap2: 1; /* Adaptive proportion test 2 is ready */
+ __I uint32_t done_adap1: 1; /* Adaptive proportion test 1 is ready */
+ __I uint32_t done_rep: 1; /* Repetition count test is ready */
+ __I uint32_t done: 1; /* Repetition count test is ready */
+ __IO uint32_t rsvd: 24;
+ } st_return_field;
+ };
+
+ __IO uint32_t rsvd2[4]; /* 0x44 - 0x50 */
+
+ union /* 0x54 */
+ {
+ __IO uint32_t RNG_interrupt_st;
+ struct
+ {
+ __O uint32_t write_data: 1; /* 1 to set, 0 to clear bit with 1. */
+ __IO uint32_t rsvd0: 1;
+ __IO uint32_t parity: 1; /* interrupt for buffer parity check */
+ __IO uint32_t rsvd1: 29;
+ } interrupt_st_field;
+ };
+
+ __IO uint32_t rsvd3[2]; /* 0x58 - 0x5C */
+
+ union /* 0x60 */
+ {
+ __IO uint32_t RNG_st_thr_err;
+ struct
+ {
+ __IO uint32_t adap2: 16; /* Error threshold for adaptive proportion test, Bit-mode: Max = 3/4 * window size, Byte-mode: Max = 1/4 * window size */
+ __IO uint32_t adap1: 16; /* Error threshold for adaptive proportion test, Bit-mode: Max = 3/4 * window size, Byte-mode: Max = 1/4 * window size */
+ } st_thr_err_field;
+ };
+
+ union /* 0x64 */
+ {
+ __IO uint32_t RNG_interrupt_enable;
+ struct
+ {
+ __O uint32_t write_data: 1; /* 1 to set, 0 to clear bit with 1. */
+ __IO uint32_t rsvd0: 1;
+ __IO uint32_t parity: 1; /* set 1 to enable interrupt */
+ __IO uint32_t rsvd1: 29;
+ } interrupt_enable_field;
+ };
+} TRNG_TypeDef;
+
+#define TRNG_BASE 0x40006200UL
+#define TRNG ((TRNG_TypeDef *) TRNG_BASE)
+
+extern void (*init_true_random_generator)(void);
+extern uint32_t (*get_true_random_number)(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__RTL876X_TRNG_H*/
+
diff --git a/inc/peripheral/rtl876x_uart.h b/inc/peripheral/rtl876x_uart.h
new file mode 100644
index 0000000..0c2bda2
--- /dev/null
+++ b/inc/peripheral/rtl876x_uart.h
@@ -0,0 +1,896 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* \file rtl876x_uart.h
+* \brief The header file of the peripheral UART driver.
+* \details This file provides all UART firmware functions.
+* \author yuan
+* \date 2019-11-14
+* \version v2.1.0
+* *********************************************************************************************************
+*/
+
+
+#ifndef _RTL876X_UART_H_
+#define _RTL876X_UART_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup IO Peripheral Drivers
+ * \defgroup UART UART
+ *
+ * \brief Manage the UART peripheral functions.
+ *
+ * \ingroup IO
+ */
+
+/*============================================================================*
+ * Includes
+ *============================================================================*/
+#include "rtl876x.h"
+#include "rtl876x_alias.h"
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+/**
+ * \defgroup UART_Exported_Types Init Params Struct
+ * \brief
+ * \ingroup UART
+ */
+
+/**
+ * \brief UART init structure definition.
+ *
+ * \ingroup UART_Exported_Types
+ */
+typedef struct
+{
+ //baudrate calibration
+ uint16_t UART_OvsrAdj; /*!< Specifies the baud rate setting, ovsr_adj, please refer to baudrate setting table.*/
+ uint16_t UART_Div; /*!< Specifies the baud rate setting, div, please refer to baudrate setting table.*/
+ uint16_t UART_Ovsr; /*!< Specifies the baud rate setting, ovsr, please refer to baudrate setting table.*/
+ uint16_t UART_WordLen; /*!< Specifies the UART Wordlength
+ This parameter can be a value of \ref UART_Word_Length. */
+ uint16_t UART_StopBits; /*!< Specifies the stop bit.
+ This parameter can be a value of \ref UART_Stop_Bits. */
+ uint16_t UART_Parity; /*!< Specifies the parity.
+ This parameter can be a value of \ref UART_Parity. */
+ uint16_t UART_TxThdLevel; /*!< Specifies the Tx threshold level.
+ This parameter must range from 1 to 29.*/
+ uint16_t UART_RxThdLevel; /*!< Specifies the Rx threshold level.
+ This parameter must range from 1 to 29.*/
+ uint16_t UART_IdleTime; /*!< Specifies the idle time.
+ This parameter can be a value of \ref UART_Rx_Idle_Time. */
+ uint16_t UART_HardwareFlowControl; /*!< Specifies the hardware flow control.
+ This parameter can be a value of \ref UART_Hardware_Flow_Control. */
+ uint16_t UART_DmaEn; /*!< Specifies the dma mode.
+ This parameter must be a value of DISABLE and ENABLE */
+ uint16_t UART_TxDmaEn; /*!< Specifies the Tx dma mode.
+ This parameter must be a value of DISABLE and ENABLE */
+ uint16_t UART_RxDmaEn; /*!< Specifies the Rx dma mode.
+ This parameter must be a value of DISABLE and ENABLE */
+ uint8_t UART_TxWaterLevel; /*!< Specifies the DMA tx water level.
+ This parameter must range from 1 to 16.*/
+ uint8_t UART_RxWaterLevel; /*!< Specifies the DMA rx water level.
+ This parameter must range from 1 to 31.*/
+} UART_InitTypeDef;
+
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/**
+ * \defgroup UART_Exported_Constants Macro Definitions
+ *
+ * \ingroup UART
+ */
+
+#define IS_UART_PERIPH(PERIPH) (((PERIPH) == UART0) || ((PERIPH) == UART1))
+
+#define UART_TX_FIFO_SIZE 16
+#define UART_RX_FIFO_SIZE 32
+
+/** \defgroup UART_Interrupts_Definition UART Interrupts Definition
+ * \{
+ * \ingroup UART_Exported_Constants
+ */
+
+#define UART_INT_RD_AVA ((uint16_t)(1 << 0))//receive data available
+#define UART_INT_TX_FIFO_EMPTY ((uint16_t)(1 << 1))
+#define UART_INT_RX_LINE_STS ((uint16_t)(1 << 2))
+#define UART_INT_MODEM_STS ((uint16_t)(1 << 3))
+#define UART_INT_TX_DONE ((uint16_t)(1 << 4))
+#define UART_INT_TX_THD ((uint16_t)(1 << 5))
+#define UART_INT_RX_BREAK ((uint16_t)(1 << 6))
+#define UART_INT_RX_IDLE ((uint16_t)(1 << 7))
+/** \} */
+
+#define IS_UART_INT(INT) ((((INT) & 0xFFFFFF80) == 0x00) && ((INT) != 0x00))
+
+#define IS_UART_GET_INT(INT) ((INT) & (UART_INT_RD_AVA | UART_INT_TX_FIFO_EMPTY | UART_INT_RX_LINE_STS |\
+ UART_INT_MODEM_STS | UART_INT_TX_DONE | UART_INT_TX_THD |\
+ UART_INT_RX_IDLE))
+
+/** \defgroup UART_Interrupt_Identifier UART Interrupt Identifier
+ * \{
+ * \ingroup UART_Exported_Constants
+ */
+
+#define UART_INT_PENDING ((uint16_t)(1 << 0))
+#define UART_INT_ID_LINE_STATUS ((uint16_t)(0x03 << 1))
+#define UART_INT_ID_RX_LEVEL_REACH ((uint16_t)(0x02 << 1))
+#define UART_INT_ID_RX_DATA_TIMEOUT ((uint16_t)(0x06 << 1))
+#define UART_INT_ID_TX_EMPTY ((uint16_t)(0x01 << 1))
+#define UART_INT_ID_MODEM_STATUS ((uint16_t)(0x00 << 1))
+/** \} */
+
+#define IS_UART_INT_ID(ID) (((ID) == UART_INT_ID_LINE_STATUS) || ((ID) == UART_INT_ID_RX_LEVEL_REACH)\
+ || ((ID) == UART_INT_ID_RX_TMEOUT) || ((ID) == UART_INT_ID_TX_EMPTY)\
+ || ((ID) == UART_INT_ID_MODEM_STATUS))
+
+/** \defgroup UART_Parity UART Parity
+ * \{
+ * \ingroup UART_Exported_Constants
+ */
+
+#define UART_PARITY_NO_PARTY ((uint16_t)(0x00 << 3))
+#define UART_PARITY_ODD ((uint16_t)(0x01 << 3))
+#define UART_PARITY_EVEN ((uint16_t)(0x03 << 3))
+/** \} */
+
+#define IS_UART_PARITY(PARITY) (((PARITY) == UART_PARITY_NO_PARTY) || ((PARITY) == UART_PARITY_ODD)\
+ || ((PARITY) == UART_PARITY_EVEN))
+
+/** \defgroup UART_Stop_Bits UART Stop Bits
+ * \{
+ * \ingroup UART_Exported_Constants
+ */
+
+#define UART_STOP_BITS_1 ((uint16_t)(0 << 2))
+#define UART_STOP_BITS_2 ((uint16_t)(1 << 2))
+/** \} */
+
+#define IS_UART_STOPBITS(STOP) (((STOP) == UART_STOP_BITS_1) || ((STOP) == UART_STOP_BITS_2))
+
+/**
+ * \defgroup UART_Word_Length UART Word Length
+ * \{
+ * \ingroup UART_Exported_Constants
+ */
+#define UART_WORD_LENGTH_7BIT ((uint16_t)(0 << 0))
+#define UART_WORD_LENGTH_8BIT ((uint16_t)(1 << 0))
+/** \} */
+
+#define IS_UART_WORD_LENGTH(LEN) ((((LEN)) == UART_WORD_LENGTH_7BIT) || (((LEN)) == UART_WORD_LENGTH_8BIT))
+
+/** \defgroup UART_Hardware_Flow_Control UART Hardware Flow Control
+ * \{
+ * \ingroup UART_Exported_Constants
+ */
+
+#define UART_HW_FLOW_CTRL_DISABLE ((uint16_t)0x00)
+#define UART_HW_FLOW_CTRL_ENABLE ((uint16_t)((1 << 5) | (1 << 1)))
+/** \} */
+
+#define IS_UART_AUTO_FLOW_CTRL(CTRL) (((CTRL) == UART_AUTO_FLOW_CTRL_EN) || ((CTRL) == UART_AUTO_FLOW_CTRL_DIS))
+
+/** \defgroup UART_Flag UART Flag
+ * \{
+ * \ingroup UART_Exported_Constants
+ */
+
+#define UART_FLAG_RX_DATA_AVA ((uint16_t)(1 << 0))
+#define UART_FLAG_RX_OVERRUN ((uint16_t)(1 << 1))
+#define UART_FLAG_RX_PARITY_ERR ((uint16_t)(1 << 2))
+#define UART_FLAG_RX_FRAME_ERR ((uint16_t)(1 << 3))
+#define UART_FLAG_RX_BREAK_ERR ((uint16_t)(1 << 4))
+#define UART_FLAG_TX_FIFO_EMPTY ((uint16_t)(1 << 5)) //Transmitter Holding Register or Transmitter FIFO empty
+#define UART_FLAG_TX_EMPTY ((uint16_t)(1 << 6)) //Transmitter Holding Register(or tx FIFO) and Transmitter shift Register both empty
+#define UART_FLAG_RX_FIFO_ERR ((uint16_t)(1 << 7))
+#define UART_FLAG_RX_BREAK ((uint16_t)(1 << 8))
+#define UART_FLAG_RX_IDLE ((uint16_t)(1 << 9)) //Only to show difference cause the address of UART RX Ilde flag is isolate
+#define UART_FLAG_TX_DONE ((uint16_t)(1 << 10)) //Interrupt status of tx waveform done & TX_FIFO_EMPTY = 1
+#define UART_FLAG_TX_THD ((uint16_t)(1 << 11)) //Interrupt status of TX_FIFO_LEVEL<=txfifo_trigger_level
+/** \} */
+
+#define IS_UART_GET_FLAG(FLAG) (((FLAG) == UART_FLAG_RX_DATA_RDY) || ((FLAG) == UART_FLAG_RX_OVERRUN)\
+ || ((FLAG) == UART_FLAG_PARTY_ERR) || ((FLAG) == UART_FLAG_FRAME_ERR)\
+ || ((FLAG) == UART_FLAG_BREAK_ERR) || ((FLAG) == UART_FLAG_THR_EMPTY)\
+ || ((FLAG) == UART_FLAG_THR_TSR_EMPTY) || ((FLAG) == UART_FLAG_RX_FIFO_ERR)\
+ || ((FLAG) == UART_FLAG_RX_IDLE))
+
+/** \defgroup UART_DMA UART DMA
+ * \{
+ * \ingroup UART_Exported_Constants
+ */
+
+#define UART_DMA_DISABLE ((uint16_t)(0 << 3))
+#define UART_DMA_ENABLE ((uint16_t)(1 << 3))
+/** \} */
+
+#define IS_UART_DMA_CFG(CFG) (((CFG) == UART_DMA_ENABLE) || ((CFG) == UART_DMA_DISABLE))
+
+/** \defgroup UART_Rx_Idle_Time UART Rx Idle Time
+ * \{
+ * \ingroup UART_Exported_Constants
+ */
+#define UART_RX_IDLE_1BYTE ((uint16_t)(0x00))
+#define UART_RX_IDLE_2BYTE ((uint16_t)(0x01))
+#define UART_RX_IDLE_4BYTE ((uint16_t)(0x02))
+#define UART_RX_IDLE_8BYTE ((uint16_t)(0x03))
+#define UART_RX_IDLE_16BYTE ((uint16_t)(0x04))
+#define UART_RX_IDLE_32BYTE ((uint16_t)(0x05))
+#define UART_RX_IDLE_64BYTE ((uint16_t)(0x06))
+#define UART_RX_IDLE_128BYTE ((uint16_t)(0x07))
+#define UART_RX_IDLE_256BYTE ((uint16_t)(0x08))
+#define UART_RX_IDLE_512BYTE ((uint16_t)(0x09))
+#define UART_RX_IDLE_1024BYTE ((uint16_t)(0x0A))
+#define UART_RX_IDLE_2048BYTE ((uint16_t)(0x0B))
+#define UART_RX_IDLE_4096BYTE ((uint16_t)(0x0C))
+#define UART_RX_IDLE_8192BYTE ((uint16_t)(0x0D))
+#define UART_RX_IDLE_16384BYTE ((uint16_t)(0x0E))
+#define UART_RX_IDLE_32768BYTE ((uint16_t)(0x0F))
+/** \} */
+
+#define IS_UART_IDLE_TIME(TIME) ((TIME) <= 0x0F)
+
+/** \defgroup UART_Interrupts_Mask_Definition UART Interrupts Mask Definition
+ * \{
+ * \ingroup UART_Exported_Constants
+ */
+#define UART_INT_MASK_RD_AVA ((uint16_t)(1 << 0))
+#define UART_INT_MASK_TX_FIFO_EMPTY ((uint16_t)(1 << 1))
+#define UART_INT_MASK_RX_LINE_STS ((uint16_t)(1 << 2))
+#define UART_INT_MASK_MODEM_STS ((uint16_t)(1 << 3))
+#define UART_INT_MASK_RX_BREAK ((uint16_t)(1 << 4))
+#define UART_INT_MASK_RX_IDLE ((uint16_t)(1 << 5))
+#define UART_INT_MASK_TX_DONE ((uint16_t)(1 << 6))//Transmitter Holding Register(or tx FIFO) and Transmitter shift Register both empty
+#define UART_INT_MASK_TX_THD ((uint16_t)(1 << 7))
+/** \} */
+
+#define IS_UART_INT_MASK(INT) ((INT) & (UART_INT_MASK_RD_AVA | UART_INT_MASK_TX_FIFO_EMPTY | UART_INT_MASK_RX_LINE_STS |\
+ UART_INT_MASK_MODEM_STS | UART_INT_MASK_RX_BREAK | UART_INT_MASK_RX_IDLE |\
+ UART_INT_MASK_TX_DONE | UART_INT_MASK_TX_THD))
+
+/** \cond Private
+ * \defgroup UART_Tx_Rx_FIFO_CLEAR_BIT UART TRx Fifo Clear Bits
+ * \{
+ */
+#define FCR_CLEAR_RX_FIFO_Set ((uint32_t)(1 << 1))
+#define FCR_CLEAR_RX_FIFO_Reset ((uint32_t)~(1 << 1))
+#define FCR_CLEAR_TX_FIFO_Set ((uint32_t)(1 << 2))
+#define FCR_CLEAR_TX_FIFO_Reset ((uint32_t)~(1 << 2))
+
+/**
+ * \}
+ * \endcond
+ */
+
+/** \} */ /* End of group UART_Exported_Constants */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * \defgroup UART_Exported_Functions Peripheral APIs
+ * \{
+ * \ingroup UART
+ */
+
+/**
+ * \brief Deinitialize the selected UART peripheral registers to their default reset values(turn off UART clock).
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_uart_init(void)
+ * {
+ * UART_DeInit(UART0);
+ * }
+ * \endcode
+ */
+void UART_DeInit(UART_TypeDef *UARTx);
+
+/**
+ * \brief Initialize the selected UART peripheral according to the specified
+ * parameters in UART_InitStruct.
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \param[in] UART_InitStruct: Pointer to a UART_InitTypeDef structure that
+ * contains the configuration information for the selected UART peripheral.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_uart_init(void)
+ * {
+ * UART_DeInit(UART0);
+ *
+ * RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+ *
+ * UART_InitTypeDef UART_InitStruct;
+ * UART_StructInit(&UART_InitStruct);
+ * UART_InitStruct.UART_Div = 20;
+ * UART_InitStruct.UART_Ovsr = 12;
+ * UART_InitStruct.UART_OvsrAdj = 0x252;
+ * UART_InitStruct.UART_RxThdLevel = 16;
+ * //Add other initialization parameters that need to be configured here.
+ * UART_Init(UART0, &UART_InitStruct);
+ * }
+ * \endcode
+ */
+void UART_Init(UART_TypeDef *UARTx, UART_InitTypeDef *UART_InitStruct);
+
+/**
+ * \brief Fills each UART_InitStruct member with its default value.
+ * \param[in] UART_InitStruct: pointer to an UART_InitTypeDef structure which will be initialized.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_uart_init(void)
+ * {
+ * UART_DeInit(UART0);
+ *
+ * RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+ *
+ * UART_InitTypeDef UART_InitStruct;
+ * UART_StructInit(&UART_InitStruct);
+ * UART_InitStruct.UART_Div = 20;
+ * UART_InitStruct.UART_Ovsr = 12;
+ * UART_InitStruct.UART_OvsrAdj = 0x252;
+ * UART_InitStruct.UART_RxThdLevel = 16;
+ * //Add other initialization parameters that need to be configured here.
+ * UART_Init(UART0, &UART_InitStruct);
+ * }
+ * \endcode
+ */
+void UART_StructInit(UART_InitTypeDef *UART_InitStruct);
+
+/**
+ * \brief Mask or unmask the specified UART interrupt source.
+ * \param[in] UART_INT: Specified the UART interrupt source that to be mask or unmask.
+ * This parameter can be one of the following values:
+ * \arg UART_INT_MASK_RD_AVA: Mask INTCR(erbi).
+ * \arg UART_INT_MASK_FIFO_EMPTY: Mask INTCR(etbei).
+ * \arg UART_INT_MASK_LINE_STS: Mask INTCR(elsi).
+ * \arg UART_INT_MASK_MODEM_STS: Mask INTCR(edssi).
+ * \arg UART_INT_MASK_RX_BREAK: Mask rx break interrupt.
+ * \arg UART_INT_MASK_RX_IDLE: Mask rx break interrupt.
+ * \arg UART_INT_MASK_TX_DONE: Mask the interrupt tx done interrupt.
+ * \arg UART_INT_MASK_TX_THD: Mask tx fifo threshold interrupt.
+ * \param[in] NewState: New state of the specified UART interrupt source.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_uart_init(void)
+ * {
+ * UART_DeInit(UART0);
+ *
+ * RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+ *
+ * UART_InitTypeDef UART_InitStruct;
+ * UART_StructInit(&UART_InitStruct);
+ * UART_InitStruct.UART_Div = 20;
+ * UART_InitStruct.UART_Ovsr = 12;
+ * UART_InitStruct.UART_OvsrAdj = 0x252;
+ * UART_InitStruct.UART_RxThdLevel = 16;
+ * //Add other initialization parameters that need to be configured here.
+ * UART_Init(UART0, &UART_InitStruct);
+ *
+ * UART_MaskINTConfig(UART0, UART_INT_MASK_RD_AVA, ENABLE);
+ * UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+ * UART_MaskINTConfig(UART0, UART_INT_MASK_RD_AVA, DISABLE);
+ * }
+ * \endcode
+ */
+void UART_MaskINTConfig(UART_TypeDef *UARTx, uint32_t UART_INT_MASK,
+ FunctionalState newState);
+/**
+ * rtl876x_uart.h
+ * \brief Enables or disables the specified UART interrupts.
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \param[in] UART_IT: Specified the UART interrupt source that to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * \arg UART_INT_RD_AVA: Rx data available interrupt source.
+ * \arg UART_INT_TX_FIFO_EMPTY: Tx FIFO empty interrupt source.
+ * \arg UART_INT_RX_LINE_STS: Rx line status interrupt source.
+ * \arg UART_INT_MODEM_STS: Modem status interrupt source.
+ * \arg UART_INT_TX_DONE: Tx done interrupt source.
+ * \arg UART_INT_TX_THD: Tx threshold(FIFO data length <= thredhold) interrupt source.
+ * \arg UART_INT_RX_BREAK: Rx break signal interrupt source.
+ * \arg UART_INT_RX_IDLE: Rx bus ilde interrupt source.
+ * \param[in] newState: New state of the specified UART interrupt source.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void driver_uart_init(void)
+ * {
+ * UART_DeInit(UART0);
+ *
+ * RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+ *
+ * UART_InitTypeDef UART_InitStruct;
+ * UART_StructInit(&UART_InitStruct);
+ * UART_InitStruct.UART_Div = 20;
+ * UART_InitStruct.UART_Ovsr = 12;
+ * UART_InitStruct.UART_OvsrAdj = 0x252;
+ * UART_InitStruct.UART_RxThdLevel = 16;
+ * //Add other initialization parameters that need to be configured here.
+ * UART_Init(UART0, &UART_InitStruct);
+ *
+ * UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+ * }
+ * \endcode
+ */
+void UART_INTConfig(UART_TypeDef *UARTx, uint32_t UART_IT, FunctionalState newState);
+
+/**
+ * \brief Send data.
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \param[in] inBuf: Buffer of data to be sent.
+ * \param[in] count: Length of data to be sent.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void uart_demo(void)
+ * {
+ * uint8_t data[] = "UART demo";
+ * UART_SendData(UART0, data, sizeof(data));
+ * }
+ * \endcode
+ */
+void UART_SendData(UART_TypeDef *UARTx, const uint8_t *inBuf, uint16_t count);
+
+/**
+ * \brief Receive data from RX FIFO.
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \param[out] outBuf: Buffer to store data which read from RX FIFO.
+ * \param[in] count: Length of data to read.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void uart_demo(void)
+ * {
+ * uint8_t data[32] = {10};
+ * UART_ReceiveData(UART0, data, 10);
+ * }
+ * \endcode
+ */
+void UART_ReceiveData(UART_TypeDef *UARTx, uint8_t *outBuf, uint16_t count);
+
+/**
+ * \brief Set UART communication baudrate.
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \param[in] div: Parameter of the selected UART baudrate.
+ * \param[in] ovsr: Parameter of the selected UART baudrate.
+ * \param[in] ovsr_adj: Parameter of the selected UART baudrate.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ * UART_BaudRate_Table
+ * div/ovsr/ovsr_adj: These three parameters set the baud rate calibration parameters of UART.
+ baudrate | div | ovsr | ovsr_adj
+ ------------------------------------------------
+ 1200Hz | 2589 | 7 | 0x7F7
+ 2400Hz | 1200 | 8 | 0x3EF
+ 4800Hz | 600 | 8 | 0x3EF
+ 9600Hz | 271 | 10 | 0x24A
+ 14400Hz | 271 | 5 | 0x222
+ 19200Hz | 165 | 7 | 0x5AD
+ 28800Hz | 110 | 7 | 0x5AD
+ 38400Hz | 85 | 7 | 0x222
+ 57600Hz | 55 | 7 | 0x5AD
+ 76800Hz | 35 | 9 | 0x7EF
+ 115200Hz | 20 | 12 | 0x252
+ 128000Hz | 25 | 7 | 0x555
+ 153600Hz | 15 | 12 | 0x252
+ 230400Hz | 10 | 12 | 0x252
+ 460800Hz | 5 | 12 | 0x252
+ 500000Hz | 8 | 5 | 0
+ 921600Hz | 4 | 5 | 0x3F7
+ 1000000Hz | 4 | 5 | 0
+ 1382400Hz | 2 | 9 | 0x2AA
+ 1444400Hz | 2 | 8 | 0x5F7
+ 1500000Hz | 2 | 8 | 0x492
+ 1843200Hz | 2 | 5 | 0x3F7
+ 2000000Hz | 2 | 5 | 0
+ 2100000Hz | 1 | 14 | 0x400
+ 2764800Hz | 1 | 9 | 0x2AA
+ 3000000Hz | 1 | 8 | 0x492
+ 3250000Hz | 1 | 7 | 0x112
+ 3692300Hz | 1 | 5 | 0x5F7
+ 3750000Hz | 1 | 5 | 0x36D
+ 4000000Hz | 1 | 5 | 0
+ 6000000Hz | 1 | 1 | 0x36D
+ ------------------------------------------------
+ * void uart_demo(void)
+ * {
+ * uint16_t div = 20;
+ * uint16_t ovsr = 12;
+ * uint16_t ovsr_adj = 0x252;
+ * UART_SetBaudRate(UART0, div, ovsr, ovsr_adj);
+ * }
+ * \endcode
+ */
+void UART_SetBaudRate(UART_TypeDef *UARTx, uint16_t div, uint16_t ovsr, uint16_t ovsr_adj);
+
+/**
+ * \brief Set UART communication parameters.
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \param[in] wordLen: Data width of the selected UART peripheral.
+ * This parameter can be one of the following values:
+ * \arg UART_WORD_LENGTH_7BIT: 7-bit data length.
+ * \arg UART_WORD_LENGTH_8BIT: 8-bit data length.
+ * \param[in] parity: parity of the selected UART peripheral.
+ * This parameter can be one of the following values:
+ * \arg UART_STOP_BITS_1: 1-bit stop bit.
+ * \arg UART_STOP_BITS_2: 2-bit stop bit.
+ * \param[in] stopBits: Stop bit of the selected UART peripheral.
+ * This parameter can be one of the following values:
+ * \arg UART_PARITY_NO_PARTY: No parity.
+ * \arg UART_PARITY_ODD: Odd parity.
+ * \arg UART_PARITY_EVEN: Even parity.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void uart_demo(void)
+ * {
+ * uint16_t word_len = UART_WORD_LENGTH_8BIT;
+ * uint16_t parity = UART_PARITY_NO_PARTY;
+ * uint16_t stop_bits = UART_STOP_BITS_1;
+ * UART_SetParams(UART0, wordLen, parity, stopBits);
+ * }
+ * \endcode
+ */
+void UART_SetParams(UART_TypeDef *UARTx, uint16_t wordLen, uint16_t parity, uint16_t stopBits);
+
+/**
+ * \brief Config UART loopback function.
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \param[in] NewState: Enable or disable UART loopback function.
+ * This parameter can be: ENABLE or DISABLE.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void uart_demo(void)
+ * {
+ * UART_LoopBackCmd(UART0, ENABLE);
+ * }
+ * \endcode
+ */
+void UART_LoopBackCmd(UART_TypeDef *UARTx, FunctionalState NewState);
+
+/**
+ * \brief Check whether the specified UART flag is set.
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \param[in] UART_FLAG: Specified UART flag to check.
+ * This parameter can be one of the following values:
+ * \arg UART_FLAG_RX_DATA_AVA: Rx data is available.
+ * \arg UART_FLAG_RX_OVERRUN: Rx FIFO overrun.
+ * \arg UART_FLAG_RX_PARITY_ERR: Rx parity error.
+ * \arg UART_FLAG_RX_FRAME_ERR: Rx frame error.
+ * \arg UART_FLAG_RX_BREAK_ERR: Rx break error.
+ * \arg UART_FLAG_TX_FIFO_EMPTY: Tx Holding Register or Tx FIFO empty
+ * \arg UART_FLAG_TX_EMPTY: Tx FIFO and Tx shift register are both empty.
+ * \arg UART_FLAG_RX_FIFO_ERR: Rx FIFO error.
+ * \arg UART_FLAG_RX_BREAK: Rx break.
+ * \arg UART_FLAG_RX_IDLE: Rx idle.
+ * \arg UART_FLAG_TX_DONE: Tx waveform done & TX_FIFO_EMPTY = 1.
+ * \arg UART_FLAG_TX_THD: TX_FIFO_LEVEL<=txfifo_trigger_level.
+ * \return New status of UART flag.
+ * \retval SET: The specified UART flag bit is set.
+ * \retval RESET: The specified flag is not set.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount)
+ * {
+ * uint8_t count;
+ *
+ * while (vCount / UART_TX_FIFO_SIZE > 0)
+ * {
+ * while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ * for (count = UART_TX_FIFO_SIZE; count > 0; count--)
+ * {
+ * UARTx->RB_THR = *pSend_Buf++;
+ * }
+ * vCount -= UART_TX_FIFO_SIZE;
+ * }
+ *
+ * while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ * while (vCount--)
+ * {
+ * UARTx->RB_THR = *pSend_Buf++;
+ * }
+ * }
+ * \endcode
+ */
+FlagStatus UART_GetFlagStatus(UART_TypeDef *UARTx, uint32_t UART_FLAG);
+
+/**
+ * \brief Send one byte of data.
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \param[in] data: Byte data to send.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void uart_demo(void)
+ * {
+ * uint8_t data = 0x55;
+ * UART_SendByte(UART0, data);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void UART_SendByte(UART_TypeDef *UARTx, uint8_t data)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_PERIPH(UARTx));
+
+ UARTx->RB_THR = data;
+
+ return;
+}
+
+/**
+ * \brief Read a byte of data from UART RX FIFO.
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \return Which byte data has been read.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void uart_demo(void)
+ * {
+ * uint8_t data = UART_ReceiveByte(UART0);
+ *
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint8_t UART_ReceiveByte(UART_TypeDef *UARTx)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_PERIPH(UARTx));
+
+ return (uint8_t)(UARTx->RB_THR);
+}
+
+/**
+ * \brief Get interrupt identifier of the selected UART peripheral.
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \return The interrupt identifier value.
+ * This return value can be one or a combination of the following:
+ * \retval UART_INT_ID_LINE_STATUS: Rx line status interrupt ID.
+ * \retval UART_INT_ID_RX_LEVEL_REACH: Rx data available or trigger level reached interrupt ID.
+ * \retval UART_INT_ID_RX_TMEOUT: Rx FIFO data timeout interrupt ID.
+ * \retval UART_INT_ID_TX_EMPTY: Tx FIFO empty interrupt ID.
+ * \retval UART_INT_ID_MODEM_STATUS: Modem status interrupt ID.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void board_uart_init(void)
+ * {
+ * Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+ * Pad_Config(UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+ *
+ * Pinmux_Config(UART_TX_PIN, UART0_TX);
+ * Pinmux_Config(UART_RX_PIN, UART0_RX);
+ * }
+ *
+ * void driver_uart_init(void)
+ * {
+ * RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+ *
+ * UART_InitTypeDef UART_InitStruct;
+ * UART_StructInit(&UART_InitStruct);
+ *
+ * UART_Init(UART0, &UART_InitStruct);
+ *
+ * //enable rx interrupt and line status interrupt
+ * UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+ * UART_INTConfig(UART0, UART_INT_RX_IDLE, ENABLE);
+ *
+ * NVIC_InitTypeDef NVIC_InitStruct;
+ * NVIC_InitStruct.NVIC_IRQChannel = UART0_IRQn;
+ * NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ * NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ * NVIC_Init(&NVIC_InitStruct);
+ * }
+ *
+ * void UART0_Handler()
+ * {
+ * uint16_t rx_len = 0;
+ * uint8_t uart_rev_data[32];
+ *
+ * //Get interrupt ID.
+ * uint32_t int_status = UART_GetIID(UART0);
+ *
+ * //Disable interrupt.
+ * UART_INTConfig(UART0, UART_INT_RD_AVA, DISABLE);
+ *
+ * if (UART_GetFlagStatus(UART0, UART_FLAG_RX_IDLE) == SET)
+ * {
+ * UART_INTConfig(UART0, UART_INT_RX_IDLE, DISABLE);
+ * //Add user code here.
+ * UART_ClearRxFIFO(UART0);
+ * UART_INTConfig(UART0, UART_INT_RX_IDLE, ENABLE);
+ * }
+ *
+ * switch (int_status & 0x0E)
+ * {
+ * case UART_INT_ID_RX_DATA_TIMEOUT:
+ * rx_len = UART_GetRxFIFODataLen(UART0);
+ * UART_ReceiveData(UART0, uart_rev_data, rx_len);
+ * //Add user code here.
+ * break;
+ *
+ * case UART_INT_ID_LINE_STATUS:
+ * //Add user code here.
+ * break;
+ *
+ * case UART_INT_ID_RX_LEVEL_REACH:
+ * rx_len = UART_GetRxFIFODataLen(UART0);
+ * UART_ReceiveData(UART0, uart_rev_data, rx_len);
+ * //Add user code here.
+ * break;
+ *
+ * case UART_INT_ID_TX_EMPTY:
+ * //Add user code here.
+ * break;
+ *
+ * case UART_INT_ID_MODEM_STATUS:
+ * //Add user code here.
+ * break;
+ *
+ * default:
+ * break;
+ * }
+ *
+ * UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint16_t UART_GetIID(UART_TypeDef *UARTx)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_PERIPH(UARTx));
+
+ return (uint16_t)(UARTx->INTID_FCR & (0x0000000E));
+}
+
+/**
+ * \brief Clear Tx FIFO of the selected UART peripheral.
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void uart_demo(void)
+ * {
+ * UART_ClearTxFIFO(UART0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void UART_ClearTxFIFO(UART_TypeDef *UARTx)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_PERIPH(UARTx));
+
+ UARTx->INTID_FCR = (((UARTx->STSR & BIT24) >> 21) | ((UARTx->STSR & 0x7C000000) >> 18) | ((
+ UARTx->STSR & BIT25) >> 25) | FCR_CLEAR_TX_FIFO_Set);
+
+ return;
+}
+
+/**
+ * \brief Clear Rx FIFO of the selected UART peripheral.
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void uart_demo(void)
+ * {
+ * UART_ClearRxFIFO(UART0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE void UART_ClearRxFIFO(UART_TypeDef *UARTx)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_PERIPH(UARTx));
+
+ UARTx->INTID_FCR = (((UARTx->STSR & BIT24) >> 21) | ((UARTx->STSR & 0x7C000000) >> 18) | ((
+ UARTx->STSR & BIT25) >> 25) | FCR_CLEAR_RX_FIFO_Set);
+
+ return;
+}
+
+/**
+ * \brief Get the data length in Tx FIFO of the selected UART peripheral.
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \return Data length in UART TX FIFO.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void uart_demo(void)
+ * {
+ * uint8_t data_len = UART_GetTxFIFODataLen(UART0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint8_t UART_GetTxFIFODataLen(UART_TypeDef *UARTx)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_PERIPH(UARTx));
+
+ return (uint8_t)(UARTx->FIFO_LEVEL & 0x1F);
+}
+
+/**
+ * \brief Get the data length in Rx FIFO of the selected UART peripheral.
+ * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1.
+ * \return Data length in UART RX FIFO.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void uart_demo(void)
+ * {
+ * uint8_t data_len = UART_GetRxFIFODataLen(UART0);
+ * }
+ * \endcode
+ */
+__STATIC_INLINE uint8_t UART_GetRxFIFODataLen(UART_TypeDef *UARTx)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_PERIPH(UARTx));
+
+ return (uint8_t)((UARTx->FIFO_LEVEL >> 8) & 0x3F);
+}
+
+/** \} */ /* End of group UART_Exported_Functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_UART_H_ */
+
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor *****END OF FILE****/
+
diff --git a/inc/peripheral/rtl876x_wdg.h b/inc/peripheral/rtl876x_wdg.h
new file mode 100644
index 0000000..ccf5a39
--- /dev/null
+++ b/inc/peripheral/rtl876x_wdg.h
@@ -0,0 +1,152 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file rtl876x_wdg.h
+* @brief header file of watch dog driver.
+* @details
+* @author Lory_xu
+* @date 2016-06-12
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _RTL876X_WDG_H_
+#define _RTL876X_WDG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x.h"
+#include "rtl876x_bitfields.h"
+
+/** @addtogroup IO Peripheral Drivers
+ *
+ * @defgroup WATCH_DOG WATCH_DOG
+ * @brief Watch Dog driver module
+ * \ingroup IO
+ * @{
+ */
+
+/** @defgroup WATCH_DOG_Exported_Types Watch Dog Exported Types
+ * @{
+ */
+typedef enum
+{
+ INTERRUPT_CPU = 0,
+ RESET_ALL_EXCEPT_AON = 1,
+ RESET_CORE_DOMAIN = 2,
+ RESET_ALL = 3
+} T_WDG_MODE;
+
+/**
+ * wdg reset reason introduction:
+ * 1.If you want to get reset reason from aon 0x16, dividing three types:
+ * a) HW reset: aon reg 0x16 is cleared to 0, magic pattern on ram will change
+ * b) SW RESET_ALL: aon reg 0x16 is cleared to 0,but magic pattern on ram not change
+ * c) SW RESET_ALL_EXCEPT_AON: obtain reset reason by reading aon reg 0x16 .
+ * 2. Attention: don't use 0x1 as your reset reason when using RESET_ALL_EXCEPT_AON type! Because 0x1 is default value.
+ */
+typedef enum
+{
+ RESET_REASON_HW = 0x0, /* HW reset */
+ RESET_REASON_WDG_TIMEOUT = 0x1,
+ SW_RESET_APP_START = 0xD0,
+ SWITCH_HCI_MODE = 0xD1,
+ SWITCH_TEST_MODE = 0xD2,
+ DFU_SWITCH_TO_OTA_MODE = 0xD3,
+ DFU_ACTIVE_RESET = 0xD4,
+ DFU_FAIL_RESET = 0xD5,
+ UPPER_CMD_RESET,
+ SINGLE_TONE_TIMEOUT_RESET,
+ UART_CMD_RESET,
+ RESET_REASON_FACTORY_RESET,
+ RESET_REASON_LPC_TRIGGER,
+ KEYBOARD_LOW_POWER_RESET,
+ MOUSE_LOW_POWER_RESET,
+ SW_RESET_APP_END = 0xFF,
+} T_SW_RESET_REASON;
+
+typedef void (*APP_CB_WDG_RESET_TYPE)(T_WDG_MODE wdg_mode, T_SW_RESET_REASON reset_reason);
+typedef bool (*BOOL_WDG_CB)(T_WDG_MODE wdg_mode, T_SW_RESET_REASON reset_reason);
+
+/**
+ * @}
+ */
+
+/** @defgroup WATCH_DOG_Exported_Variables Watch Dog Exported Variables
+ * @{
+ */
+
+extern APP_CB_WDG_RESET_TYPE app_cb_wdg_reset;
+extern BOOL_WDG_CB user_wdg_cb;
+
+/**
+ * @}
+ */
+
+/** @defgroup WATCH_DOG_Exported_Functions Watch Dog Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Watch Dog Clock Enable.
+ */
+extern void WDG_ClockEnable(void);
+
+/**
+ * @brief Watch Dog Timer Config.
+ * @param div_factor: 16Bit: 32.768k/(1+divfactor).
+ * @param cnt_limit: 2^(cnt_limit+1) - 1 ; max 11~15 = 0xFFF.
+ * @param wdg_mode: 0: interrupt CPU
+ * 1: reset all except aon
+ * 2: reset core domain
+ * 3: reset all
+ * @retval none.
+ */
+extern void WDG_Config(uint16_t div_factor, uint8_t cnt_limit, T_WDG_MODE wdg_mode);
+
+/**
+ * @brief Watch Dog Timer Enable.
+ NOTE: When call WDG_Disable() before entering dlps, must call WDG_Config() before WDG_Enable() when exiting dlps!
+ */
+extern void WDG_Enable(void);
+
+/**
+ * @brief Watch Dog Timer Disable.
+ */
+extern void WDG_Disable(void);
+
+/**
+ * @brief Watch Dog Timer Restart.
+ */
+extern void WDG_Restart(void);
+
+/**
+ * @brief Watch Dog System Reset.
+ * @param wdg_mode: 0: interrupt CPU
+ * 1: reset all except aon
+ * 2: reset core domain
+ * 3: reset all
+ */
+extern void WDG_SystemReset(T_WDG_MODE wdg_mode, T_SW_RESET_REASON reset_reason);
+
+
+extern T_SW_RESET_REASON reset_reason_get(void);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_RTL876X_WDG_H_
diff --git a/inc/platform/adc_lib.h b/inc/platform/adc_lib.h
new file mode 100644
index 0000000..d70948e
--- /dev/null
+++ b/inc/platform/adc_lib.h
@@ -0,0 +1,47 @@
+#ifndef __ADC_K_LIB_H
+#define __ADC_K_LIB_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#define SOC_VERSION_CHECK 1
+
+#define ADC_K_VERSION_N2 1
+#define ADC_K_VERSION_N1 1
+#define ADC_K_VERSION_0 1
+#define ADC_K_VERSION_P1 1
+
+#define USE_ADC_DIVIDE_SINGLE_MODE 1
+#define USE_ADC_BYPASS_SINGLE_MODE 1
+#define USE_ADC_DIVIDE_DIFF_MODE 1
+#define USE_ADC_BYPASS_DIFF_MODE 1
+
+typedef enum
+{
+ DIVIDE_SINGLE_MODE = 1,
+ BYPASS_SINGLE_MODE = 2,
+ DIVIDE_DIFFERENTIAL_MODE = 3,
+ BYPASS_DIFFERENTIAL_MODE = 4,
+} ADC_SampleMode;
+
+typedef enum
+{
+ NO_ERROR = 0,
+ PARAMETER_ERROR = -1,
+ RAM_DATA_ERROR = -2,
+ NO_CALIBRATION = -3,
+ VERSION_ERROR = -4,
+} ADC_ErrorStatus;
+
+extern int8_t ADC_K_Version;
+extern uint16_t ADC_Resistance_Value;
+
+bool ADC_CalibrationInit(void);
+float ADC_GetVoltage(const ADC_SampleMode vSampleMode, int32_t vSampleData,
+ ADC_ErrorStatus *pErrorStatus);
+uint16_t ADC_GetResistance(void);
+
+
+
+
+#endif
diff --git a/inc/platform/aes_api.h b/inc/platform/aes_api.h
new file mode 100644
index 0000000..cd43cee
--- /dev/null
+++ b/inc/platform/aes_api.h
@@ -0,0 +1,409 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file aes_api.h
+ * @brief aes apis abstracted for encryption related.
+ * @details AES encryption APIs which delivers HW/SW implemented reliable and safe AES solution.
+ * @author Abel
+ * @date 2017.5.17
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ * *************************************************************************************
+ */
+
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef _AES_API_H_
+#define _AES_API_H_
+
+/*============================================================================*
+ * Header Files
+*============================================================================*/
+#include <stdint.h>
+#include <stdbool.h>
+
+
+/** @defgroup AES_API AES API Sets
+ * @brief API sets for aes encryption implementation
+ * @{
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup AES_API_Exported_Functions AES API Sets Exported Functions
+ * @{
+ */
+
+/**
+ * @brief 128 bit AES ECB encryption on speicified plaintext and keys
+ * @param plaintext specified plain text to be encrypted
+ * @param key keys to encrypt the plaintext
+ * @param encrypted output buffer to store encrypted data
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes128_ecb_encrypt(uint8_t plaintext[16], const uint8_t key[16], uint8_t *encrypted);
+
+/**
+ * @brief 128 bit AES ECB encryption on speicified plaintext and keys
+ * @param plaintext specified plain text to be encrypted
+ * @param key keys to encrypt the plaintext
+ * @param encrypted output buffer to store encrypted data
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes128_ecb_encrypt_buffer(uint8_t *plaintext, const uint8_t key[16], uint8_t *encrypted,
+ uint32_t data_word_len);
+
+/**
+ * @brief 128 bit AES ECB decryption on speicified encrypted data and keys
+ * @param input specified encrypted data to be decrypted
+ * @param key keys to decrypt the data
+ * @param output output buffer to store plain data
+ * @return decryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+*/
+bool aes128_ecb_decrypt(uint8_t *input, const uint8_t *key, uint8_t *output);
+
+/**
+ * @brief 128 bit AES ECB decryption on speicified encrypted data and keys
+ * @param input specified encrypted data to be decrypted
+ * @param key keys to decrypt the data
+ * @param output output buffer to store plain data
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return decryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+*/
+bool aes128_ecb_decrypt_buffer(uint8_t *input, const uint8_t key[16], uint8_t *output,
+ uint32_t data_word_len);
+
+/**
+ * @brief 128 bit AES ECB encryption on speicified plaintext and keys
+ * @param plaintext specified plain text to be encrypted
+ * @param key keys to encrypt the plaintext
+ * @param encrypted output buffer to store encrypted data
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note most significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes128_ecb_encrypt_msb2lsb(uint8_t plaintext[16], const uint8_t key[16],
+ uint8_t *encrypted);
+
+/**
+ * @brief 128 bit AES ECB encryption on speicified plaintext and keys
+ * @param plaintext specified plain text to be encrypted
+ * @param key keys to encrypt the plaintext
+ * @param encrypted output buffer to store encrypted data
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note most significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes128_ecb_encrypt_msb2lsb_buffer(uint8_t *plaintext, const uint8_t key[16],
+ uint8_t *encrypted, uint32_t data_word_len);
+
+/**
+ * @brief 128 bit AES ECB decryption on speicified encrypted data and keys
+ * @param input specified encrypted data to be decrypted
+ * @param key keys to decrypt the data
+ * @param output output buffer to store plain data
+ * @return decryption results
+ * @retval true successful
+ * @retval false fail
+ * @note most significant octet of encrypted data corresponds to encrypted[0]
+*/
+bool aes128_ecb_decrypt_msb2lsb(uint8_t *input, const uint8_t *key, uint8_t *output);
+
+/**
+ * @brief 128 bit AES ECB decryption on speicified encrypted data and keys
+ * @param input specified encrypted data to be decrypted
+ * @param key keys to decrypt the data
+ * @param output output buffer to store plain data
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return decryption results
+ * @retval true successful
+ * @retval false fail
+ * @note most significant octet of encrypted data corresponds to encrypted[0]
+*/
+bool aes128_ecb_decrypt_msb2lsb_buffer(uint8_t *input, const uint8_t key[16], uint8_t *output,
+ uint32_t data_word_len);
+
+/**
+ * @brief 256 bit AES ECB encryption on speicified plaintext and keys
+ * @param plaintext specified plain text to be encrypted
+ * @param key keys to encrypt the plaintext
+ * @param encrypted output buffer to store encrypted data
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes256_ecb_encrypt(uint8_t plaintext[16], const uint8_t key[32], uint8_t *encrypted);
+
+/**
+ * @brief 256 bit AES ECB encryption on speicified plaintext and keys
+ * @param plaintext specified plain text to be encrypted
+ * @param key keys to encrypt the plaintext
+ * @param encrypted output buffer to store encrypted data
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes256_ecb_encrypt_buffer(uint8_t *plaintext, const uint8_t key[32], uint8_t *encrypted,
+ uint32_t data_word_len);
+
+/**
+ * @brief 256 bit AES ECB decryption on speicified encrypted data and keys
+ * @param input specified encrypted data to be decrypted
+ * @param key keys to decrypt the data
+ * @param output output buffer to store plain data
+ * @return decryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+*/
+bool aes256_ecb_decrypt(uint8_t *input, const uint8_t *key, uint8_t *output);
+
+/**
+ * @brief 256 bit AES ECB decryption on speicified encrypted data and keys
+ * @param input specified encrypted data to be decrypted
+ * @param key keys to decrypt the data
+ * @param output output buffer to store plain data
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return decryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+*/
+bool aes256_ecb_decrypt_buffer(uint8_t *input, const uint8_t key[32], uint8_t *output,
+ uint32_t data_word_len);
+
+/**
+ * @brief 256 bit AES ECB encryption on speicified plaintext and keys
+ * @param plaintext specified plain text to be encrypted
+ * @param key keys to encrypt the plaintext
+ * @param encrypted output buffer to store encrypted data
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note most significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes256_ecb_encrypt_msb2lsb(uint8_t plaintext[16], const uint8_t key[32],
+ uint8_t *encrypted);
+
+/**
+ * @brief 256 bit AES ECB encryption on speicified plaintext and keys
+ * @param plaintext specified plain text to be encrypted
+ * @param key keys to encrypt the plaintext
+ * @param encrypted output buffer to store encrypted data
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note most significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes256_ecb_encrypt_msb2lsb_buffer(uint8_t *plaintext, const uint8_t key[32],
+ uint8_t *encrypted, uint32_t data_word_len);
+
+/**
+ * @brief 256 bit AES ECB decryption on speicified encrypted data and keys
+ * @param input specified encrypted data to be decrypted
+ * @param key keys to decrypt the data
+ * @param output output buffer to store plain data
+ * @return decryption results
+ * @retval true successful
+ * @retval false fail
+ * @note most significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes256_ecb_decrypt_msb2lsb(uint8_t *input, const uint8_t *key, uint8_t *output);
+
+/**
+ * @brief 256 bit AES ECB decryption on speicified encrypted data and keys
+ * @param input specified encrypted data to be decrypted
+ * @param key keys to decrypt the data
+ * @param output output buffer to store plain data
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return decryption results
+ * @retval true successful
+ * @retval false fail
+ * @note most significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes256_ecb_decrypt_msb2lsb_buffer(uint8_t *input, const uint8_t key[32], uint8_t *output,
+ uint32_t data_word_len);
+
+
+/**
+ * @brief 128 bit AES CBC encryption on speicified plaintext and keys
+ * @param plaintext specified plain text to be encrypted
+ * @param key keys to encrypt the plaintext
+ * @param encrypted output buffer to store encrypted data
+ * @param p_iv initialization vector (IV) for CBC mode
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes128_cbc_encrypt(uint8_t *plaintext, const uint8_t key[16], uint8_t *encrypted,
+ uint32_t *p_iv, uint32_t data_word_len);
+
+/**
+ * @brief 128 bit AES CBC descryption on speicified plaintext and keys
+ * @param input specified encrypted data to be decrypted
+ * @param key keys to decrypt the data
+ * @param output output buffer to store plain data
+ * @param p_iv initialization vector (IV) for CBC mode
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes128_cbc_decrypt(uint8_t *input, const uint8_t key[16], uint8_t *output, uint32_t *p_iv,
+ uint32_t data_word_len);
+
+/**
+ * @brief 128 bit AES CBC encryption on speicified plaintext and keys
+ * @param plaintext specified plain text to be encrypted
+ * @param key keys to encrypt the plaintext
+ * @param encrypted output buffer to store encrypted data
+ * @param p_iv initialization vector (IV) for CBC mode
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note most significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes128_cbc_encrypt_msb2lsb(uint8_t plaintext[16], const uint8_t key[16], uint8_t *encrypted,
+ uint32_t *p_iv, uint32_t data_word_len);
+
+/**
+ * @brief 128 bit AES CBC descryption on speicified plaintext and keys
+ * @param input specified encrypted data to be decrypted
+ * @param key keys to decrypt the data
+ * @param output output buffer to store plain data
+ * @param p_iv initialization vector (IV) for CBC mode
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note most significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes128_cbc_decrypt_msb2lsb(uint8_t *input, const uint8_t key[16], uint8_t *output,
+ uint32_t *p_iv, uint32_t data_word_len);
+
+/**
+ * @brief 256 bit AES CBC encryption on speicified plaintext and keys
+ * @param plaintext specified plain text to be encrypted
+ * @param key keys to encrypt the plaintext
+ * @param encrypted output buffer to store encrypted data
+ * @param p_iv initialization vector (IV) for CBC mode
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes256_cbc_encrypt(uint8_t *plaintext, const uint8_t key[32], uint8_t *encrypted,
+ uint32_t *p_iv, uint32_t data_word_len);
+
+/**
+ * @brief 256 bit AES CBC descryption on speicified plaintext and keys
+ * @param input specified encrypted data to be decrypted
+ * @param key keys to decrypt the data
+ * @param output output buffer to store plain data
+ * @param p_iv initialization vector (IV) for CBC mode
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes256_cbc_decrypt(uint8_t *input, const uint8_t key[32], uint8_t *output, uint32_t *p_iv,
+ uint32_t data_word_len);
+
+/**
+ * @brief 128 bit AES CTR encryption on speicified plaintext and keys
+ * @param plaintext specified plain text to be encrypted
+ * @param key keys to encrypt the plaintext
+ * @param encrypted output buffer to store encrypted data
+ * @param p_iv initialization vector (IV) for CBC mode
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes128_ctr_encrypt(uint8_t *plaintext, const uint8_t key[16], uint8_t *encrypted,
+ uint32_t *p_iv, uint32_t data_word_len);
+
+/**
+ * @brief 128 bit AES CTR descryption on speicified plaintext and keys
+ * @param input specified encrypted data to be decrypted
+ * @param key keys to decrypt the data
+ * @param output output buffer to store plain data
+ * @param p_iv initialization vector (IV) for CBC mode
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes128_ctr_decrypt(uint8_t *input, const uint8_t key[16], uint8_t *output, uint32_t *p_iv,
+ uint32_t data_word_len);
+
+/**
+ * @brief 256 bit AES CTR encryption on speicified plaintext and keys
+ * @param plaintext specified plain text to be encrypted
+ * @param key keys to encrypt the plaintext
+ * @param encrypted output buffer to store encrypted data
+ * @param p_iv initialization vector (IV) for CBC mode
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes256_ctr_encrypt(uint8_t *plaintext, const uint8_t key[32], uint8_t *encrypted,
+ uint32_t *p_iv, uint32_t data_word_len);
+
+/**
+ * @brief 256 bit AES CTR descryption on speicified plaintext and keys
+ * @param input specified encrypted data to be decrypted
+ * @param key keys to decrypt the data
+ * @param output output buffer to store plain data
+ * @param p_iv initialization vector (IV) for CBC mode
+ * @param data_word_len word length of the data to be descrypted, must be multiples of 4
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note least significant octet of encrypted data corresponds to encrypted[0]
+ */
+bool aes256_ctr_decrypt(uint8_t *input, const uint8_t key[32], uint8_t *output, uint32_t *p_iv,
+ uint32_t data_word_len);
+
+/** @} */ /* End of group AES_API_Exported_Functions */
+
+/** @} */ /* End of group AES_API */
+
+
+#endif
diff --git a/inc/platform/app_define.h b/inc/platform/app_define.h
new file mode 100644
index 0000000..6ad379a
--- /dev/null
+++ b/inc/platform/app_define.h
@@ -0,0 +1,84 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_define.h
+ * @brief
+ * @author
+ * @date
+ * @version
+ ***************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2015 Realtek Semiconductor Corporation</center></h2>
+ ***************************************************************************************
+ */
+
+#ifndef APP_DEFINE_H
+#define APP_DEFINE_H
+
+/** @defgroup APP_DEFINE APP Define
+ * @{
+ */
+
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup APP_DEFINE_Exported_Macros App Define Exported Macros
+ * @brief
+ * @{
+ */
+#ifndef UNUSED
+#define UNUSED(expr) do { (void)(expr); } while (0)
+#endif
+
+//#pragma diag_suppress 174 // expression has no effect
+//#pragma diag_suppress 223 // function declared implicitly
+
+///////////////////////////////////////////////////////////////////
+
+#define SPIFLASH0IntrHandler SPI_Flash0_Handler
+#define SPIFLASH1IntrHandler SPI_Flash1_Handler
+#define Gpio2IntrHandler GPIO2_Handler
+#define Gpio3IntrHandler GPIO3_Handler
+#define Gpio4IntrHandler GPIO4_Handler
+#define Gpio5IntrHandler GPIO5_Handler
+#define Timer3IntrHandler Timer3_Handler
+#define Timer4IntrHandler Timer4_Handler
+#define Timer5IntrHandler Timer5_Handler
+#define Timer6IntrHandler Timer6_Handler
+#define Timer7IntrHandler Timer7_Handler
+#define Gpio6IntrHandler GPIO6_Handler
+#define Gpio7IntrHandler GPIO7_Handler
+#define Gpio8IntrHandler GPIO8_Handler
+#define Gpio9IntrHandler GPIO9_Handler
+#define Gpio10IntrHandler GPIO10_Handler
+#define Gpio11IntrHandler GPIO11_Handler
+#define Gpio12IntrHandler GPIO12_Handler
+#define Gpio13IntrHandler GPIO13_Handler
+#define Gpio14IntrHandler GPIO14_Handler
+#define Gpio15IntrHandler GPIO15_Handler
+#define Gpio16IntrHandler GPIO16_Handler
+#define Gpio17IntrHandler GPIO17_Handler
+#define Gpio18IntrHandler GPIO18_Handler
+#define Gpio19IntrHandler GPIO19_Handler
+#define Gpio20IntrHandler GPIO20_Handler
+#define Gpio21IntrHandler GPIO21_Handler
+#define Gpio22IntrHandler GPIO22_Handler
+#define Gpio23IntrHandler GPIO23_Handler
+#define Gpio24IntrHandler GPIO24_Handler
+#define Gpio25IntrHandler GPIO25_Handler
+#define Gpio26IntrHandler GPIO26_Handler
+#define Gpio27IntrHandler GPIO27_Handler
+#define Gpio28IntrHandler GPIO28_Handler
+#define Gpio29IntrHandler GPIO29_Handler
+#define Gpio30IntrHandler GPIO30_Handler
+#define Gpio31IntrHandler GPIO31_Handler
+/** End of APP_DEFINE_Exported_Macros
+ * @}
+ */
+
+/** @} */ /* End of group APP_DEFINE */
+
+#endif // APP_DEFINE_H
diff --git a/inc/platform/app_section.h b/inc/platform/app_section.h
new file mode 100644
index 0000000..5a70c57
--- /dev/null
+++ b/inc/platform/app_section.h
@@ -0,0 +1,64 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_section.h
+ * @brief
+ * @author
+ * @date 2017.6.7
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ * *************************************************************************************
+ */
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef _APP_SECTION_H_
+#define _APP_SECTION_H_
+
+/** @defgroup APP_SECTION APP Section
+ * @brief memory section definition for user application.
+ * @{
+ */
+/* app encryption */
+#define APP_ENCRYPTION_SIGNATURE __attribute__((section(".encryption.signature")))
+#define APP_ENCRYPION_DUMMY_ALIGN __attribute__((section(".encryption.dummy.align"))) __attribute__((aligned(16)))
+/* app encryption code*/
+#define APP_ENCRYPTION_TEXT_SECTION __attribute__((section(".app.encryption.text")))
+
+/*flash const data or flash function */
+#define APP_FLASH_HEADER __attribute__((section(".app.flash.header"))) __attribute__((used))
+#define APP_FLASH_HEADER_AUTH __attribute__((section(".app.flash.header.auth"))) __attribute__((used))
+#define APP_FLASH_HEADER_EXT __attribute__((section(".app.flash.header_ext"))) __attribute__((used))
+/* flash code */
+#define APP_FLASH_TEXT_SECTION __attribute__((section(".app.flash.text")))
+/* flash ro data */
+#define APP_FLASH_RODATA_SECTION __attribute__((section(".app.flash.rodata")))
+/* ram code */
+#define DATA_RAM_FUNCTION __attribute__((section(".app.data_ram.text"))) /*!< data ram code */
+#define SHARE_CACHE_RAM_SECTION __attribute__((section(".ram.sharecacheram.text"))) /*!< share cache ram code or data*/
+
+/* global variable or ram function, data on (default) */
+#define RAM_DATAON_DATA_SECTION __attribute__((section(".ram.dataon.data"))) /*!< DATA ON */
+#define RAM_DATAON_BSS_SECTION __attribute__((section(".ram.dataon.bss"))) /*!< DATA ON */
+#define RAM_DATAON_UNINIT_SECTION __attribute__((section(".uninit.ram"))) /*!< DATA ON */
+
+/* buffer on */
+#define RAM_BUFFERON_DATA_SECTION __attribute__((section(".ram.bufferon.data"))) /*!< BUFFER ON */
+#define RAM_BUFFERON_BSS_SECTION __attribute__((section(".ram.bufferon.bss"))) /*!< BUFFER ON */
+
+
+/* overlay section, only support three overlay sections now. */
+#define OVERLAY_SECTION_BOOT_ONCE __attribute__((section(".app.overlay_a"))) /*!< overlay a section */
+#define OVERLAY_B_SECTION __attribute__((section(".app.overlay_b"))) /*!< overlay b section */
+#define OVERLAY_C_SECTION __attribute__((section(".app.overlay_c"))) /*!< overlay c section */
+
+
+
+
+/** @} */ /* End of group APP_SECTION */
+
+#endif /* _APP_SECTION_H_ */
diff --git a/inc/platform/auto_k_rf.h b/inc/platform/auto_k_rf.h
new file mode 100644
index 0000000..ebf98ff
--- /dev/null
+++ b/inc/platform/auto_k_rf.h
@@ -0,0 +1,107 @@
+#ifndef _AUTO_K_RF_H_
+#define _AUTO_K_RF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define FLT_MAX 40000
+
+#define K_RF_SUCCESS 0
+#define K_RF_READ_DRIFT_FAIL 1
+#define K_RF_K_FAIL 2
+#define K_RF_WRITE_CONFIG_FAIL 3
+
+#define BASE_MAGNIFIED 1000000
+#define BIT0 0x00000001
+#define BIT1 0x00000002
+#define BIT2 0x00000004
+#define BIT3 0x00000008
+#define BIT4 0x00000010
+#define BIT5 0x00000020
+#define BIT6 0x00000040
+#define BIT7 0x00000080
+#define BIT8 0x00000100
+#define BIT9 0x00000200
+#define BIT10 0x00000400
+#define BIT11 0x00000800
+#define BIT12 0x00001000
+#define BIT13 0x00002000
+#define BIT14 0x00004000
+#define BIT15 0x00008000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+
+typedef unsigned char BOOLEAN;
+typedef void VOID;
+typedef unsigned char UCHAR;
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef unsigned int UINT32;
+typedef unsigned long long UINT64;
+typedef signed char CHAR;
+typedef signed char INT8;
+typedef signed short INT16;
+typedef signed int INT32;
+typedef signed long long INT64;
+
+#define MODEM_PI_PAGE_0 0
+#define MODEM_PI_PAGE_1 1
+#define MODEM_PI_PAGE_2 2
+#define MODEM_PI_PAGE_3 3
+#define MODEM_PI_PAGE_4 4
+#define MODEM_PI_PAGE_5 5
+#define MODEM_PI_PAGE_6 6
+#define MODEM_PI_PAGE_7 7
+
+#define TRANS_MODEM_REG(x) (((x) >> 1) | 0x40) /* this is used to translate byte address to word address*/
+
+extern UINT32(*rtk_read_modem_radio_reg_pi)(UCHAR modem_page, UCHAR addr, UCHAR type);
+extern void (*rtk_write_modem_radio_reg_pi)(UCHAR modem_page, UCHAR addr, UCHAR type, UINT16 val);
+extern UINT16(*rtk_ioq_read_rfc_reg)(UINT8);
+extern void (*rtk_write_rfc_reg_pi)(UINT8, UINT16);
+extern void (*rtk_update_rfc_reg_pi)(UINT8, UINT16, UINT16);
+
+#define RTK_WRITE_RF_REG_PI(waddr, value) rtk_write_rfc_reg_pi(waddr, value)
+#define RTK_READ_RF_REG_PI(waddr) rtk_ioq_read_rfc_reg(waddr)
+#define RTK_UPDATE_RF_REG_PI(waddr, bm_mask, value) rtk_update_rfc_reg_pi(waddr, bm_mask, value)
+#define RTK_WRITE_MODEM_REG_PI(modem_page, waddr, value) \
+ rtk_write_modem_radio_reg_pi(modem_page, waddr, TYPE_MODEM, value)
+#define RTK_READ_MODEM_REG_PI(modem_page, waddr) rtk_read_modem_radio_reg_pi(modem_page, waddr, TYPE_MODEM)
+#define RTK_UPDATE_MODEM_REG_PI(modem_page, waddr, bm_mask, value) \
+ { \
+ UINT16 temp = RTK_READ_MODEM_REG_PI(modem_page, waddr); \
+ RTK_WRITE_MODEM_REG_PI(modem_page, waddr, (temp & ~(bm_mask)) | ((bm_mask) & (value))); \
+ }
+
+void init_dft(UINT8 rx_channel, UINT16 rx_gain, UINT16 dft_size, UINT16 pwr_avg_times,
+ UINT8 reg_dft_sum_scale, UINT32 *reg08, UINT32 *reg0A);
+void deinit_dft(UINT32 reg08, UINT32 reg0A);
+
+double modem_dft(double IF_val, UINT32 *raw_data);
+
+uint8_t Auto_K_RF(uint8_t rx_channel, uint32_t freq_drift_threshold, uint8_t *cal_xtal_result);
+
+uint8_t Auto_K_RF_MP(uint8_t rx_channel, uint32_t freq_drift_threshold, uint8_t *cal_xtal_result,
+ uint8_t cl_type, uint8_t calMethod);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _AUTO_K_RF_H_ */
diff --git a/inc/platform/auto_k_rf_bonding_dut.h b/inc/platform/auto_k_rf_bonding_dut.h
new file mode 100644
index 0000000..9c22923
--- /dev/null
+++ b/inc/platform/auto_k_rf_bonding_dut.h
@@ -0,0 +1,38 @@
+#ifndef _AUTO_K_RF_BONDING_DUT_H
+#define _AUTO_K_RF_BONDING_DUT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+
+/**
+ * @brief get information from the DUT.
+ * @param golden_info golden information
+ * @param dut_info DUT information
+ * @return Status of Operation.
+ * @retval true success
+ * @retval false fail
+ * @note the function will firstly check the golden_info, if check success return the dut_info.
+*/
+bool dut_info_get(uint8_t golden_info[32], uint8_t dut_info[32]);
+
+/**
+ * @brief check the verify result.
+ * @param result_info result information
+ * @return Status of Operation.
+ * @retval true success
+ * @retval false fail
+*/
+bool check_verify_result(uint8_t result_info[16]);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_AUTO_K_RF_BONDING_DUT_H*/
diff --git a/inc/platform/auto_k_rf_bonding_golden.h b/inc/platform/auto_k_rf_bonding_golden.h
new file mode 100644
index 0000000..29e3ffc
--- /dev/null
+++ b/inc/platform/auto_k_rf_bonding_golden.h
@@ -0,0 +1,57 @@
+#ifndef _AUTO_K_RF_BONDING_GOLDEN_H
+#define _AUTO_K_RF_BONDING_GOLDEN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#define BEE1_DUT_DEV_TYPE 0x11
+#define BEE1_GOLDEN_DEV_TYPE 0x12
+#define BEE2_DUT_DEV_TYPE 0x21
+#define BEE2_GOLDEN_DEV_TYPE 0x22
+#define SBEE2_DUT_DEV_TYPE 0x31
+#define SBEE2_GOLDEN_DEV_TYPE 0x32
+
+/**
+ * @brief get information from golden sample.
+ * @param golden_info golden sample information
+ * @param dut_ic_type DUT IC type
+ * @return Status of Operation.
+ * @retval true success
+ * @retval false fail
+*/
+bool golden_info_get(uint8_t golden_info[32], uint8_t dut_ic_type);
+
+/**
+ * @brief verify the information from the DUT.
+ * @param dut_info DUT information
+ * @param dut_ic_type DUT IC type
+ * @return Status of Operation.
+ * @retval true verify success
+ * @retval false verify fail
+*/
+bool dut_info_verify(uint8_t dut_info[32], uint8_t dut_ic_type);
+
+/**
+ * @brief get verify result information.
+ * @param result_info result information
+ * @param verify_result verify result from dut_info_verify
+ * @param dut_ic_type DUT IC type
+ * @return Status of Operation.
+ * @retval true success
+ * @retval false fail
+*/
+bool verify_result_info_get(uint8_t result_info[16], bool verify_result, uint8_t dut_ic_type);
+
+uint32_t platform_random(uint32_t max);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_AUTO_K_RF_BONDING_GOLDEN_H*/
+
diff --git a/inc/platform/bee2_adc_lib.h b/inc/platform/bee2_adc_lib.h
new file mode 100644
index 0000000..d44bb1c
--- /dev/null
+++ b/inc/platform/bee2_adc_lib.h
@@ -0,0 +1,33 @@
+#ifndef __ADC_K_LIB_H
+#define __ADC_K_LIB_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+typedef enum
+{
+ DIVIDE_SINGLE_MODE = 1,
+ BYPASS_SINGLE_MODE = 2,
+ DIVIDE_DIFFERENTIAL_MODE = 3,
+ BYPASS_DIFFERENTIAL_MODE = 4,
+} ADC_SampleMode;
+
+typedef enum
+{
+ NO_ERROR = 0,
+ PARAMETER_ERROR = -1,
+ RAM_DATA_ERROR = -2,
+ NO_CALIBRATION = -3,
+ VERSION_ERROR = -4,
+} ADC_ErrorStatus;
+
+extern int16_t ADC_K_Version;
+
+bool ADC_CalibrationInit(void);
+float ADC_GetVoltage(const ADC_SampleMode vSampleMode, int32_t vSampleData,
+ ADC_ErrorStatus *pErrorStatus);
+uint16_t ADC_GetResistance(void);
+
+
+
+#endif
diff --git a/inc/platform/cmsis_armcc.h b/inc/platform/cmsis_armcc.h
new file mode 100644
index 0000000..82d742f
--- /dev/null
+++ b/inc/platform/cmsis_armcc.h
@@ -0,0 +1,867 @@
+/**************************************************************************//**
+ * @file cmsis_armcc.h
+ * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file
+ * @version V5.0.4
+ * @date 10. January 2018
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2018 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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
+ *
+ * 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 __CMSIS_ARMCC_H
+#define __CMSIS_ARMCC_H
+
+/* *INDENT-OFF* */
+
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
+ #error "Please use Arm Compiler Toolchain V4.0.677 or later!"
+#endif
+
+/* CMSIS compiler control architecture macros */
+#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \
+ (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) )
+ #define __ARM_ARCH_6M__ 1
+#endif
+
+#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1))
+ #define __ARM_ARCH_7M__ 1
+#endif
+
+#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1))
+ #define __ARM_ARCH_7EM__ 1
+#endif
+
+ /* __ARM_ARCH_8M_BASE__ not applicable */
+ /* __ARM_ARCH_8M_MAIN__ not applicable */
+
+
+/* CMSIS compiler specific defines */
+#ifndef __ASM
+ #define __ASM __asm
+#endif
+#ifndef __INLINE
+ #define __INLINE __inline
+#endif
+#ifndef __STATIC_INLINE
+ #define __STATIC_INLINE static __inline
+#endif
+#ifndef __STATIC_FORCEINLINE
+ #define __STATIC_FORCEINLINE static __forceinline
+#endif
+#ifndef __NO_RETURN
+ #define __NO_RETURN __declspec(noreturn)
+#endif
+#ifndef __USED
+ #define __USED __attribute__((used))
+#endif
+#ifndef __WEAK
+ #define __WEAK __attribute__((weak))
+#endif
+#ifndef __PACKED
+ #define __PACKED __attribute__((packed))
+#endif
+#ifndef __PACKED_STRUCT
+ #define __PACKED_STRUCT __packed struct
+#endif
+#ifndef __PACKED_UNION
+ #define __PACKED_UNION __packed union
+#endif
+#ifndef __UNALIGNED_UINT32 /* deprecated */
+ #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
+#endif
+#ifndef __UNALIGNED_UINT16_WRITE
+ #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
+#endif
+#ifndef __UNALIGNED_UINT16_READ
+ #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
+#endif
+#ifndef __UNALIGNED_UINT32_WRITE
+ #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
+#endif
+#ifndef __UNALIGNED_UINT32_READ
+ #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
+#endif
+#ifndef __ALIGNED
+ #define __ALIGNED(x) __attribute__((aligned(x)))
+#endif
+#ifndef __RESTRICT
+ #define __RESTRICT __restrict
+#endif
+
+/* ########################### Core Function Access ########################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+ @{
+ */
+
+/**
+ \brief Enable IRQ Interrupts
+ \details Enables IRQ interrupts by clearing the I-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+/* intrinsic void __enable_irq(); */
+
+
+/**
+ \brief Disable IRQ Interrupts
+ \details Disables IRQ interrupts by setting the I-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+/* intrinsic void __disable_irq(); */
+
+/**
+ \brief Get Control Register
+ \details return the content of the Control Register.
+ \return Control Register value
+ */
+__STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+ register uint32_t __regControl __ASM("control");
+ return(__regControl);
+}
+
+
+/**
+ \brief Set Control Register
+ \details Writes the given value to the Control Register.
+ \param [in] control Control Register value to set
+ */
+__STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+ register uint32_t __regControl __ASM("control");
+ __regControl = control;
+}
+
+
+/**
+ \brief Get IPSR Register
+ \details return the content of the IPSR Register.
+ \return IPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_IPSR(void)
+{
+ register uint32_t __regIPSR __ASM("ipsr");
+ return(__regIPSR);
+}
+
+
+/**
+ \brief Get APSR Register
+ \details return the content of the APSR Register.
+ \return APSR Register value
+ */
+__STATIC_INLINE uint32_t __get_APSR(void)
+{
+ register uint32_t __regAPSR __ASM("apsr");
+ return(__regAPSR);
+}
+
+
+/**
+ \brief Get xPSR Register
+ \details return the content of the xPSR Register.
+ \return xPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_xPSR(void)
+{
+ register uint32_t __regXPSR __ASM("xpsr");
+ return(__regXPSR);
+}
+
+
+/**
+ \brief Get Process Stack Pointer
+ \details return the current value of the Process Stack Pointer (PSP).
+ \return PSP Register value
+ */
+__STATIC_INLINE uint32_t __get_PSP(void)
+{
+ register uint32_t __regProcessStackPointer __ASM("psp");
+ return(__regProcessStackPointer);
+}
+
+
+/**
+ \brief Set Process Stack Pointer
+ \details Assigns the given value to the Process Stack Pointer (PSP).
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+ register uint32_t __regProcessStackPointer __ASM("psp");
+ __regProcessStackPointer = topOfProcStack;
+}
+
+
+/**
+ \brief Get Main Stack Pointer
+ \details return the current value of the Main Stack Pointer (MSP).
+ \return MSP Register value
+ */
+__STATIC_INLINE uint32_t __get_MSP(void)
+{
+ register uint32_t __regMainStackPointer __ASM("msp");
+ return(__regMainStackPointer);
+}
+
+
+/**
+ \brief Set Main Stack Pointer
+ \details Assigns the given value to the Main Stack Pointer (MSP).
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+ register uint32_t __regMainStackPointer __ASM("msp");
+ __regMainStackPointer = topOfMainStack;
+}
+
+
+/**
+ \brief Get Priority Mask
+ \details return the current state of the priority mask bit from the Priority Mask Register.
+ \return Priority Mask value
+ */
+__STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ return(__regPriMask);
+}
+
+
+/**
+ \brief Set Priority Mask
+ \details Assigns the given value to the Priority Mask Register.
+ \param [in] priMask Priority Mask
+ */
+__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ __regPriMask = (priMask);
+}
+
+
+#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
+
+/**
+ \brief Enable FIQ
+ \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+#define __enable_fault_irq __enable_fiq
+
+
+/**
+ \brief Disable FIQ
+ \details Disables FIQ interrupts by setting the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+#define __disable_fault_irq __disable_fiq
+
+
+/**
+ \brief Get Base Priority
+ \details return the current value of the Base Priority register.
+ \return Base Priority register value
+ */
+__STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ return(__regBasePri);
+}
+
+
+/**
+ \brief Set Base Priority
+ \details Assigns the given value to the Base Priority register.
+ \param [in] basePri Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ __regBasePri = (basePri & 0xFFU);
+}
+
+
+/**
+ \brief Set Base Priority with condition
+ \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+ or the new value increases the BASEPRI priority level.
+ \param [in] basePri Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
+{
+ register uint32_t __regBasePriMax __ASM("basepri_max");
+ __regBasePriMax = (basePri & 0xFFU);
+}
+
+
+/**
+ \brief Get Fault Mask
+ \details return the current value of the Fault Mask register.
+ \return Fault Mask register value
+ */
+__STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ return(__regFaultMask);
+}
+
+
+/**
+ \brief Set Fault Mask
+ \details Assigns the given value to the Fault Mask register.
+ \param [in] faultMask Fault Mask value to set
+ */
+__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ __regFaultMask = (faultMask & (uint32_t)1U);
+}
+
+#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
+
+
+/**
+ \brief Get FPSCR
+ \details return the current value of the Floating Point Status/Control register.
+ \return Floating Point Status/Control register value
+ */
+__STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
+ (defined (__FPU_USED ) && (__FPU_USED == 1U)) )
+ register uint32_t __regfpscr __ASM("fpscr");
+ return(__regfpscr);
+#else
+ return(0U);
+#endif
+}
+
+
+/**
+ \brief Set FPSCR
+ \details Assigns the given value to the Floating Point Status/Control register.
+ \param [in] fpscr Floating Point Status/Control value to set
+ */
+__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
+ (defined (__FPU_USED ) && (__FPU_USED == 1U)) )
+ register uint32_t __regfpscr __ASM("fpscr");
+ __regfpscr = (fpscr);
+#else
+ (void)fpscr;
+#endif
+}
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ########################## Core Instruction Access ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+ Access to dedicated instructions
+ @{
+*/
+
+/**
+ \brief No Operation
+ \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP __nop
+
+
+/**
+ \brief Wait For Interrupt
+ \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+#define __WFI __wfi
+
+
+/**
+ \brief Wait For Event
+ \details Wait For Event is a hint instruction that permits the processor to enter
+ a low-power state until one of a number of events occurs.
+ */
+#define __WFE __wfe
+
+
+/**
+ \brief Send Event
+ \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV __sev
+
+
+/**
+ \brief Instruction Synchronization Barrier
+ \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+ so that all instructions following the ISB are fetched from cache or memory,
+ after the instruction has been completed.
+ */
+#define __ISB() do {\
+ __schedule_barrier();\
+ __isb(0xF);\
+ __schedule_barrier();\
+ } while (0U)
+
+/**
+ \brief Data Synchronization Barrier
+ \details Acts as a special kind of Data Memory Barrier.
+ It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB() do {\
+ __schedule_barrier();\
+ __dsb(0xF);\
+ __schedule_barrier();\
+ } while (0U)
+
+/**
+ \brief Data Memory Barrier
+ \details Ensures the apparent order of the explicit memory operations before
+ and after the instruction, without ensuring their completion.
+ */
+#define __DMB() do {\
+ __schedule_barrier();\
+ __dmb(0xF);\
+ __schedule_barrier();\
+ } while (0U)
+
+
+/**
+ \brief Reverse byte order (32 bit)
+ \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#define __REV __rev
+
+
+/**
+ \brief Reverse byte order (16 bit)
+ \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
+{
+ rev16 r0, r0
+ bx lr
+}
+#endif
+
+
+/**
+ \brief Reverse byte order (16 bit)
+ \details Reverses the byte order in a 16-bit value and return the signed 16-bit result. For example, 0x0080 becomes 0x8000.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value)
+{
+ revsh r0, r0
+ bx lr
+}
+#endif
+
+
+/**
+ \brief Rotate Right in unsigned value (32 bit)
+ \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+ \param [in] op1 Value to rotate
+ \param [in] op2 Number of Bits to rotate
+ \return Rotated value
+ */
+#define __ROR __ror
+
+
+/**
+ \brief Breakpoint
+ \details Causes the processor to enter Debug state.
+ Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+ \param [in] value is ignored by the processor.
+ If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value) __breakpoint(value)
+
+
+/**
+ \brief Reverse bit order of value
+ \details Reverses the bit order of the given value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
+ #define __RBIT __rbit
+#else
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+ uint32_t result;
+ uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
+
+ result = value; /* r will be reversed bits of v; first get LSB of v */
+ for (value >>= 1U; value != 0U; value >>= 1U)
+ {
+ result <<= 1U;
+ result |= value & 1U;
+ s--;
+ }
+ result <<= s; /* shift when v's highest bits are zero */
+ return result;
+}
+#endif
+
+
+/**
+ \brief Count leading zeros
+ \details Counts the number of leading zeros of a data value.
+ \param [in] value Value to count the leading zeros
+ \return number of leading zeros in value
+ */
+#define __CLZ __clz
+
+
+#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
+
+/**
+ \brief LDR Exclusive (8 bit)
+ \details Executes a exclusive LDR instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
+#else
+ #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
+#endif
+
+
+/**
+ \brief LDR Exclusive (16 bit)
+ \details Executes a exclusive LDR instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
+#else
+ #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
+#endif
+
+
+/**
+ \brief LDR Exclusive (32 bit)
+ \details Executes a exclusive LDR instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
+#else
+ #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
+#endif
+
+
+/**
+ \brief STR Exclusive (8 bit)
+ \details Executes a exclusive STR instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __STREXB(value, ptr) __strex(value, ptr)
+#else
+ #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
+#endif
+
+
+/**
+ \brief STR Exclusive (16 bit)
+ \details Executes a exclusive STR instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __STREXH(value, ptr) __strex(value, ptr)
+#else
+ #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
+#endif
+
+
+/**
+ \brief STR Exclusive (32 bit)
+ \details Executes a exclusive STR instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __STREXW(value, ptr) __strex(value, ptr)
+#else
+ #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
+#endif
+
+
+/**
+ \brief Remove the exclusive lock
+ \details Removes the exclusive lock which is created by LDREX.
+ */
+#define __CLREX __clrex
+
+
+/**
+ \brief Signed Saturate
+ \details Saturates a signed value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+#define __SSAT __ssat
+
+
+/**
+ \brief Unsigned Saturate
+ \details Saturates an unsigned value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+#define __USAT __usat
+
+
+/**
+ \brief Rotate Right with Extend (32 bit)
+ \details Moves each bit of a bitstring right by one bit.
+ The carry input is shifted in at the left end of the bitstring.
+ \param [in] value Value to rotate
+ \return Rotated value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
+{
+ rrx r0, r0
+ bx lr
+}
+#endif
+
+
+/**
+ \brief LDRT Unprivileged (8 bit)
+ \details Executes a Unprivileged LDRT instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
+
+
+/**
+ \brief LDRT Unprivileged (16 bit)
+ \details Executes a Unprivileged LDRT instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
+
+
+/**
+ \brief LDRT Unprivileged (32 bit)
+ \details Executes a Unprivileged LDRT instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
+
+
+/**
+ \brief STRT Unprivileged (8 bit)
+ \details Executes a Unprivileged STRT instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+#define __STRBT(value, ptr) __strt(value, ptr)
+
+
+/**
+ \brief STRT Unprivileged (16 bit)
+ \details Executes a Unprivileged STRT instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+#define __STRHT(value, ptr) __strt(value, ptr)
+
+
+/**
+ \brief STRT Unprivileged (32 bit)
+ \details Executes a Unprivileged STRT instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+#define __STRT(value, ptr) __strt(value, ptr)
+
+#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
+
+/**
+ \brief Signed Saturate
+ \details Saturates a signed value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
+{
+ if ((sat >= 1U) && (sat <= 32U))
+ {
+ const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
+ const int32_t min = -1 - max ;
+ if (val > max)
+ {
+ return max;
+ }
+ else if (val < min)
+ {
+ return min;
+ }
+ }
+ return val;
+}
+
+/**
+ \brief Unsigned Saturate
+ \details Saturates an unsigned value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
+{
+ if (sat <= 31U)
+ {
+ const uint32_t max = ((1U << sat) - 1U);
+ if (val > (int32_t)max)
+ {
+ return max;
+ }
+ else if (val < 0)
+ {
+ return 0U;
+ }
+ }
+ return (uint32_t)val;
+}
+
+#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+ Access to dedicated SIMD instructions
+ @{
+*/
+
+#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
+
+#define __SADD8 __sadd8
+#define __QADD8 __qadd8
+#define __SHADD8 __shadd8
+#define __UADD8 __uadd8
+#define __UQADD8 __uqadd8
+#define __UHADD8 __uhadd8
+#define __SSUB8 __ssub8
+#define __QSUB8 __qsub8
+#define __SHSUB8 __shsub8
+#define __USUB8 __usub8
+#define __UQSUB8 __uqsub8
+#define __UHSUB8 __uhsub8
+#define __SADD16 __sadd16
+#define __QADD16 __qadd16
+#define __SHADD16 __shadd16
+#define __UADD16 __uadd16
+#define __UQADD16 __uqadd16
+#define __UHADD16 __uhadd16
+#define __SSUB16 __ssub16
+#define __QSUB16 __qsub16
+#define __SHSUB16 __shsub16
+#define __USUB16 __usub16
+#define __UQSUB16 __uqsub16
+#define __UHSUB16 __uhsub16
+#define __SASX __sasx
+#define __QASX __qasx
+#define __SHASX __shasx
+#define __UASX __uasx
+#define __UQASX __uqasx
+#define __UHASX __uhasx
+#define __SSAX __ssax
+#define __QSAX __qsax
+#define __SHSAX __shsax
+#define __USAX __usax
+#define __UQSAX __uqsax
+#define __UHSAX __uhsax
+#define __USAD8 __usad8
+#define __USADA8 __usada8
+#define __SSAT16 __ssat16
+#define __USAT16 __usat16
+#define __UXTB16 __uxtb16
+#define __UXTAB16 __uxtab16
+#define __SXTB16 __sxtb16
+#define __SXTAB16 __sxtab16
+#define __SMUAD __smuad
+#define __SMUADX __smuadx
+#define __SMLAD __smlad
+#define __SMLADX __smladx
+#define __SMLALD __smlald
+#define __SMLALDX __smlaldx
+#define __SMUSD __smusd
+#define __SMUSDX __smusdx
+#define __SMLSD __smlsd
+#define __SMLSDX __smlsdx
+#define __SMLSLD __smlsld
+#define __SMLSLDX __smlsldx
+#define __SEL __sel
+#define __QADD __qadd
+#define __QSUB __qsub
+
+#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
+ ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
+
+#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
+ ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
+
+#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
+ ((int64_t)(ARG3) << 32U) ) >> 32U))
+
+#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+/* *INDENT-ON* */
+
+#endif /* __CMSIS_ARMCC_H */
diff --git a/inc/platform/cmsis_gcc.h b/inc/platform/cmsis_gcc.h
new file mode 100644
index 0000000..15dff24
--- /dev/null
+++ b/inc/platform/cmsis_gcc.h
@@ -0,0 +1,2097 @@
+/**************************************************************************//**
+ * @file cmsis_gcc.h
+ * @brief CMSIS compiler GCC header file
+ * @version V5.0.4
+ * @date 09. April 2018
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2018 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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
+ *
+ * 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 __CMSIS_GCC_H
+#define __CMSIS_GCC_H
+
+/* ignore some GCC warnings */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+
+/* Fallback for __has_builtin */
+#ifndef __has_builtin
+#define __has_builtin(x) (0)
+#endif
+
+/* CMSIS compiler specific defines */
+#ifndef __ASM
+#define __ASM __asm
+#endif
+#ifndef __INLINE
+#define __INLINE inline
+#endif
+#ifndef __STATIC_INLINE
+#define __STATIC_INLINE static inline
+#endif
+#ifndef __STATIC_FORCEINLINE
+#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
+#endif
+#ifndef __NO_RETURN
+#define __NO_RETURN __attribute__((__noreturn__))
+#endif
+#ifndef __USED
+#define __USED __attribute__((used))
+#endif
+#ifndef __WEAK
+#define __WEAK __attribute__((weak))
+#endif
+#ifndef __PACKED
+#define __PACKED __attribute__((packed, aligned(1)))
+#endif
+#ifndef __PACKED_STRUCT
+#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
+#endif
+#ifndef __PACKED_UNION
+#define __PACKED_UNION union __attribute__((packed, aligned(1)))
+#endif
+#ifndef __UNALIGNED_UINT32 /* deprecated */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpacked"
+#pragma GCC diagnostic ignored "-Wattributes"
+struct __attribute__((packed)) T_UINT32 { uint32_t v; };
+#pragma GCC diagnostic pop
+#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
+#endif
+#ifndef __UNALIGNED_UINT16_WRITE
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpacked"
+#pragma GCC diagnostic ignored "-Wattributes"
+__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
+#pragma GCC diagnostic pop
+#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
+#endif
+#ifndef __UNALIGNED_UINT16_READ
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpacked"
+#pragma GCC diagnostic ignored "-Wattributes"
+__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
+#pragma GCC diagnostic pop
+#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
+#endif
+#ifndef __UNALIGNED_UINT32_WRITE
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpacked"
+#pragma GCC diagnostic ignored "-Wattributes"
+__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
+#pragma GCC diagnostic pop
+#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
+#endif
+#ifndef __UNALIGNED_UINT32_READ
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpacked"
+#pragma GCC diagnostic ignored "-Wattributes"
+__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
+#pragma GCC diagnostic pop
+#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
+#endif
+#ifndef __ALIGNED
+#define __ALIGNED(x) __attribute__((aligned(x)))
+#endif
+#ifndef __RESTRICT
+#define __RESTRICT __restrict
+#endif
+
+
+/* ########################### Core Function Access ########################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+ @{
+ */
+
+/**
+ \brief Enable IRQ Interrupts
+ \details Enables IRQ interrupts by clearing the I-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__STATIC_FORCEINLINE void __enable_irq(void)
+{
+ __ASM volatile("cpsie i" : : : "memory");
+}
+
+
+/**
+ \brief Disable IRQ Interrupts
+ \details Disables IRQ interrupts by setting the I-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__STATIC_FORCEINLINE void __disable_irq(void)
+{
+ __ASM volatile("cpsid i" : : : "memory");
+}
+
+
+/**
+ \brief Get Control Register
+ \details return the content of the Control Register.
+ \return Control Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_CONTROL(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, control" : "=r"(result));
+ return (result);
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Control Register (non-secure)
+ \details return the content of the non-secure Control Register when in secure mode.
+ \return non-secure Control Register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, control_ns" : "=r"(result));
+ return (result);
+}
+#endif
+
+
+/**
+ \brief Set Control Register
+ \details Writes the given value to the Control Register.
+ \param [in] control Control Register value to set
+ */
+__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control)
+{
+ __ASM volatile("MSR control, %0" : : "r"(control) : "memory");
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Control Register (non-secure)
+ \details Writes the given value to the non-secure Control Register when in secure state.
+ \param [in] control Control Register value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control)
+{
+ __ASM volatile("MSR control_ns, %0" : : "r"(control) : "memory");
+}
+#endif
+
+
+/**
+ \brief Get IPSR Register
+ \details return the content of the IPSR Register.
+ \return IPSR Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_IPSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, ipsr" : "=r"(result));
+ return (result);
+}
+
+
+/**
+ \brief Get APSR Register
+ \details return the content of the APSR Register.
+ \return APSR Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_APSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, apsr" : "=r"(result));
+ return (result);
+}
+
+
+/**
+ \brief Get xPSR Register
+ \details return the content of the xPSR Register.
+ \return xPSR Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_xPSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, xpsr" : "=r"(result));
+ return (result);
+}
+
+
+/**
+ \brief Get Process Stack Pointer
+ \details return the current value of the Process Stack Pointer (PSP).
+ \return PSP Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_PSP(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, psp" : "=r"(result));
+ return (result);
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Process Stack Pointer (non-secure)
+ \details return the current value of the non-secure Process Stack Pointer (PSP) when in secure state.
+ \return PSP Register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, psp_ns" : "=r"(result));
+ return (result);
+}
+#endif
+
+
+/**
+ \brief Set Process Stack Pointer
+ \details Assigns the given value to the Process Stack Pointer (PSP).
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack)
+{
+ __ASM volatile("MSR psp, %0" : : "r"(topOfProcStack) :);
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Process Stack Pointer (non-secure)
+ \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state.
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack)
+{
+ __ASM volatile("MSR psp_ns, %0" : : "r"(topOfProcStack) :);
+}
+#endif
+
+
+/**
+ \brief Get Main Stack Pointer
+ \details return the current value of the Main Stack Pointer (MSP).
+ \return MSP Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_MSP(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, msp" : "=r"(result));
+ return (result);
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Main Stack Pointer (non-secure)
+ \details return the current value of the non-secure Main Stack Pointer (MSP) when in secure state.
+ \return MSP Register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, msp_ns" : "=r"(result));
+ return (result);
+}
+#endif
+
+
+/**
+ \brief Set Main Stack Pointer
+ \details Assigns the given value to the Main Stack Pointer (MSP).
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack)
+{
+ __ASM volatile("MSR msp, %0" : : "r"(topOfMainStack) :);
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Main Stack Pointer (non-secure)
+ \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state.
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack)
+{
+ __ASM volatile("MSR msp_ns, %0" : : "r"(topOfMainStack) :);
+}
+#endif
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Stack Pointer (non-secure)
+ \details return the current value of the non-secure Stack Pointer (SP) when in secure state.
+ \return SP Register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, sp_ns" : "=r"(result));
+ return (result);
+}
+
+
+/**
+ \brief Set Stack Pointer (non-secure)
+ \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state.
+ \param [in] topOfStack Stack Pointer value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack)
+{
+ __ASM volatile("MSR sp_ns, %0" : : "r"(topOfStack) :);
+}
+#endif
+
+
+/**
+ \brief Get Priority Mask
+ \details return the current state of the priority mask bit from the Priority Mask Register.
+ \return Priority Mask value
+ */
+__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, primask" : "=r"(result) :: "memory");
+ return (result);
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Priority Mask (non-secure)
+ \details return the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state.
+ \return Priority Mask value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, primask_ns" : "=r"(result) :: "memory");
+ return (result);
+}
+#endif
+
+
+/**
+ \brief Set Priority Mask
+ \details Assigns the given value to the Priority Mask Register.
+ \param [in] priMask Priority Mask
+ */
+__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask)
+{
+ __ASM volatile("MSR primask, %0" : : "r"(priMask) : "memory");
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Priority Mask (non-secure)
+ \details Assigns the given value to the non-secure Priority Mask Register when in secure state.
+ \param [in] priMask Priority Mask
+ */
+__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask)
+{
+ __ASM volatile("MSR primask_ns, %0" : : "r"(priMask) : "memory");
+}
+#endif
+
+
+#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
+ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
+/**
+ \brief Enable FIQ
+ \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__STATIC_FORCEINLINE void __enable_fault_irq(void)
+{
+ __ASM volatile("cpsie f" : : : "memory");
+}
+
+
+/**
+ \brief Disable FIQ
+ \details Disables FIQ interrupts by setting the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__STATIC_FORCEINLINE void __disable_fault_irq(void)
+{
+ __ASM volatile("cpsid f" : : : "memory");
+}
+
+
+/**
+ \brief Get Base Priority
+ \details return the current value of the Base Priority register.
+ \return Base Priority register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, basepri" : "=r"(result));
+ return (result);
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Base Priority (non-secure)
+ \details return the current value of the non-secure Base Priority register when in secure state.
+ \return Base Priority register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, basepri_ns" : "=r"(result));
+ return (result);
+}
+#endif
+
+
+/**
+ \brief Set Base Priority
+ \details Assigns the given value to the Base Priority register.
+ \param [in] basePri Base Priority value to set
+ */
+__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri)
+{
+ __ASM volatile("MSR basepri, %0" : : "r"(basePri) : "memory");
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Base Priority (non-secure)
+ \details Assigns the given value to the non-secure Base Priority register when in secure state.
+ \param [in] basePri Base Priority value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri)
+{
+ __ASM volatile("MSR basepri_ns, %0" : : "r"(basePri) : "memory");
+}
+#endif
+
+
+/**
+ \brief Set Base Priority with condition
+ \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+ or the new value increases the BASEPRI priority level.
+ \param [in] basePri Base Priority value to set
+ */
+__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri)
+{
+ __ASM volatile("MSR basepri_max, %0" : : "r"(basePri) : "memory");
+}
+
+
+/**
+ \brief Get Fault Mask
+ \details return the current value of the Fault Mask register.
+ \return Fault Mask register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, faultmask" : "=r"(result));
+ return (result);
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Fault Mask (non-secure)
+ \details return the current value of the non-secure Fault Mask register when in secure state.
+ \return Fault Mask register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile("MRS %0, faultmask_ns" : "=r"(result));
+ return (result);
+}
+#endif
+
+
+/**
+ \brief Set Fault Mask
+ \details Assigns the given value to the Fault Mask register.
+ \param [in] faultMask Fault Mask value to set
+ */
+__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ __ASM volatile("MSR faultmask, %0" : : "r"(faultMask) : "memory");
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Fault Mask (non-secure)
+ \details Assigns the given value to the non-secure Fault Mask register when in secure state.
+ \param [in] faultMask Fault Mask value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask)
+{
+ __ASM volatile("MSR faultmask_ns, %0" : : "r"(faultMask) : "memory");
+}
+#endif
+
+#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
+ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
+
+
+#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
+
+/**
+ \brief Get Process Stack Pointer Limit
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence zero is returned always in non-secure
+ mode.
+
+ \details return the current value of the Process Stack Pointer Limit (PSPLIM).
+ \return PSPLIM Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void)
+{
+#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
+ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
+ // without main extensions, the non-secure PSPLIM is RAZ/WI
+ return 0U;
+#else
+ uint32_t result;
+ __ASM volatile("MRS %0, psplim" : "=r"(result));
+ return result;
+#endif
+}
+
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Process Stack Pointer Limit (non-secure)
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence zero is returned always.
+
+ \details return the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
+ \return PSPLIM Register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void)
+{
+#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
+ // without main extensions, the non-secure PSPLIM is RAZ/WI
+ return 0U;
+#else
+ uint32_t result;
+ __ASM volatile("MRS %0, psplim_ns" : "=r"(result));
+ return result;
+#endif
+}
+#endif
+
+
+/**
+ \brief Set Process Stack Pointer Limit
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence the write is silently ignored in non-secure
+ mode.
+
+ \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM).
+ \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
+ */
+__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit)
+{
+#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
+ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
+ // without main extensions, the non-secure PSPLIM is RAZ/WI
+ (void)ProcStackPtrLimit;
+#else
+ __ASM volatile("MSR psplim, %0" : : "r"(ProcStackPtrLimit));
+#endif
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Process Stack Pointer (non-secure)
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence the write is silently ignored.
+
+ \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
+ \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit)
+{
+#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
+ // without main extensions, the non-secure PSPLIM is RAZ/WI
+ (void)ProcStackPtrLimit;
+#else
+ __ASM volatile("MSR psplim_ns, %0\n" : : "r"(ProcStackPtrLimit));
+#endif
+}
+#endif
+
+
+/**
+ \brief Get Main Stack Pointer Limit
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence zero is returned always in non-secure
+ mode.
+
+ \details return the current value of the Main Stack Pointer Limit (MSPLIM).
+ \return MSPLIM Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void)
+{
+#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
+ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
+ // without main extensions, the non-secure MSPLIM is RAZ/WI
+ return 0U;
+#else
+ uint32_t result;
+ __ASM volatile("MRS %0, msplim" : "=r"(result));
+ return result;
+#endif
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Main Stack Pointer Limit (non-secure)
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence zero is returned always.
+
+ \details return the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state.
+ \return MSPLIM Register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void)
+{
+#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
+ // without main extensions, the non-secure MSPLIM is RAZ/WI
+ return 0U;
+#else
+ uint32_t result;
+ __ASM volatile("MRS %0, msplim_ns" : "=r"(result));
+ return result;
+#endif
+}
+#endif
+
+
+/**
+ \brief Set Main Stack Pointer Limit
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence the write is silently ignored in non-secure
+ mode.
+
+ \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM).
+ \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set
+ */
+__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit)
+{
+#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
+ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
+ // without main extensions, the non-secure MSPLIM is RAZ/WI
+ (void)MainStackPtrLimit;
+#else
+ __ASM volatile("MSR msplim, %0" : : "r"(MainStackPtrLimit));
+#endif
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Main Stack Pointer Limit (non-secure)
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence the write is silently ignored.
+
+ \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state.
+ \param [in] MainStackPtrLimit Main Stack Pointer value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit)
+{
+#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
+ // without main extensions, the non-secure MSPLIM is RAZ/WI
+ (void)MainStackPtrLimit;
+#else
+ __ASM volatile("MSR msplim_ns, %0" : : "r"(MainStackPtrLimit));
+#endif
+}
+#endif
+
+#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */
+
+
+/**
+ \brief Get FPSCR
+ \details return the current value of the Floating Point Status/Control register.
+ \return Floating Point Status/Control register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_FPSCR(void)
+{
+#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
+ (defined (__FPU_USED ) && (__FPU_USED == 1U)) )
+#if __has_builtin(__builtin_arm_get_fpscr)
+// Re-enable using built-in when GCC has been fixed
+// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
+ /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */
+ return __builtin_arm_get_fpscr();
+#else
+ uint32_t result;
+
+ __ASM volatile("VMRS %0, fpscr" : "=r"(result));
+ return (result);
+#endif
+#else
+ return (0U);
+#endif
+}
+
+
+/**
+ \brief Set FPSCR
+ \details Assigns the given value to the Floating Point Status/Control register.
+ \param [in] fpscr Floating Point Status/Control value to set
+ */
+__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
+ (defined (__FPU_USED ) && (__FPU_USED == 1U)) )
+#if __has_builtin(__builtin_arm_set_fpscr)
+// Re-enable using built-in when GCC has been fixed
+// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
+ /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */
+ __builtin_arm_set_fpscr(fpscr);
+#else
+ __ASM volatile("VMSR fpscr, %0" : : "r"(fpscr) : "vfpcc", "memory");
+#endif
+#else
+ (void)fpscr;
+#endif
+}
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ########################## Core Instruction Access ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+ Access to dedicated instructions
+ @{
+*/
+
+/* Define macros for porting to both thumb1 and thumb2.
+ * For thumb1, use low register (r0-r7), specified by constraint "l"
+ * Otherwise, use general registers, specified by constraint "r" */
+#if defined (__thumb__) && !defined (__thumb2__)
+#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
+#define __CMSIS_GCC_RW_REG(r) "+l" (r)
+#define __CMSIS_GCC_USE_REG(r) "l" (r)
+#else
+#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
+#define __CMSIS_GCC_RW_REG(r) "+r" (r)
+#define __CMSIS_GCC_USE_REG(r) "r" (r)
+#endif
+
+/**
+ \brief No Operation
+ \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP() __ASM volatile ("nop")
+
+/**
+ \brief Wait For Interrupt
+ \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+#define __WFI() __ASM volatile ("wfi")
+
+
+/**
+ \brief Wait For Event
+ \details Wait For Event is a hint instruction that permits the processor to enter
+ a low-power state until one of a number of events occurs.
+ */
+#define __WFE() __ASM volatile ("wfe")
+
+
+/**
+ \brief Send Event
+ \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV() __ASM volatile ("sev")
+
+
+/**
+ \brief Instruction Synchronization Barrier
+ \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+ so that all instructions following the ISB are fetched from cache or memory,
+ after the instruction has been completed.
+ */
+__STATIC_FORCEINLINE void __ISB(void)
+{
+ __ASM volatile("isb 0xF"::: "memory");
+}
+
+
+/**
+ \brief Data Synchronization Barrier
+ \details Acts as a special kind of Data Memory Barrier.
+ It completes when all explicit memory accesses before this instruction complete.
+ */
+__STATIC_FORCEINLINE void __DSB(void)
+{
+ __ASM volatile("dsb 0xF"::: "memory");
+}
+
+
+/**
+ \brief Data Memory Barrier
+ \details Ensures the apparent order of the explicit memory operations before
+ and after the instruction, without ensuring their completion.
+ */
+__STATIC_FORCEINLINE void __DMB(void)
+{
+ __ASM volatile("dmb 0xF"::: "memory");
+}
+
+
+/**
+ \brief Reverse byte order (32 bit)
+ \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__STATIC_FORCEINLINE uint32_t __REV(uint32_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+ return __builtin_bswap32(value);
+#else
+ uint32_t result;
+
+ __ASM volatile("rev %0, %1" : __CMSIS_GCC_OUT_REG(result) : __CMSIS_GCC_USE_REG(value));
+ return result;
+#endif
+}
+
+
+/**
+ \brief Reverse byte order (16 bit)
+ \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile("rev16 %0, %1" : __CMSIS_GCC_OUT_REG(result) : __CMSIS_GCC_USE_REG(value));
+ return result;
+}
+
+
+/**
+ \brief Reverse byte order (16 bit)
+ \details Reverses the byte order in a 16-bit value and return the signed 16-bit result. For example, 0x0080 becomes 0x8000.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__STATIC_FORCEINLINE int16_t __REVSH(int16_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ return (int16_t)__builtin_bswap16(value);
+#else
+ int16_t result;
+
+ __ASM volatile("revsh %0, %1" : __CMSIS_GCC_OUT_REG(result) : __CMSIS_GCC_USE_REG(value));
+ return result;
+#endif
+}
+
+
+/**
+ \brief Rotate Right in unsigned value (32 bit)
+ \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+ \param [in] op1 Value to rotate
+ \param [in] op2 Number of Bits to rotate
+ \return Rotated value
+ */
+__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+ op2 %= 32U;
+ if (op2 == 0U)
+ {
+ return op1;
+ }
+ return (op1 >> op2) | (op1 << (32U - op2));
+}
+
+
+/**
+ \brief Breakpoint
+ \details Causes the processor to enter Debug state.
+ Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+ \param [in] value is ignored by the processor.
+ If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value) __ASM volatile ("bkpt "#value)
+
+
+/**
+ \brief Reverse bit order of value
+ \details Reverses the bit order of the given value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value)
+{
+ uint32_t result;
+
+#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
+ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
+ __ASM volatile("rbit %0, %1" : "=r"(result) : "r"(value));
+#else
+ uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
+
+ result = value; /* r will be reversed bits of v; first get LSB of v */
+ for (value >>= 1U; value != 0U; value >>= 1U)
+ {
+ result <<= 1U;
+ result |= value & 1U;
+ s--;
+ }
+ result <<= s; /* shift when v's highest bits are zero */
+#endif
+ return result;
+}
+
+
+/**
+ \brief Count leading zeros
+ \details Counts the number of leading zeros of a data value.
+ \param [in] value Value to count the leading zeros
+ \return number of leading zeros in value
+ */
+#define __CLZ (uint8_t)__builtin_clz
+
+
+#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
+ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
+/**
+ \brief LDR Exclusive (8 bit)
+ \details Executes a exclusive LDR instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr)
+{
+ uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ __ASM volatile("ldrexb %0, %1" : "=r"(result) : "Q"(*addr));
+#else
+ /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+ accepted by assembler. So has to use following less efficient pattern.
+ */
+ __ASM volatile("ldrexb %0, [%1]" : "=r"(result) : "r"(addr) : "memory");
+#endif
+ return ((uint8_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDR Exclusive (16 bit)
+ \details Executes a exclusive LDR instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr)
+{
+ uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ __ASM volatile("ldrexh %0, %1" : "=r"(result) : "Q"(*addr));
+#else
+ /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+ accepted by assembler. So has to use following less efficient pattern.
+ */
+ __ASM volatile("ldrexh %0, [%1]" : "=r"(result) : "r"(addr) : "memory");
+#endif
+ return ((uint16_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDR Exclusive (32 bit)
+ \details Executes a exclusive LDR instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile("ldrex %0, %1" : "=r"(result) : "Q"(*addr));
+ return (result);
+}
+
+
+/**
+ \brief STR Exclusive (8 bit)
+ \details Executes a exclusive STR instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile("strexb %0, %2, %1" : "=&r"(result), "=Q"(*addr) : "r"((uint32_t)value));
+ return (result);
+}
+
+
+/**
+ \brief STR Exclusive (16 bit)
+ \details Executes a exclusive STR instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile("strexh %0, %2, %1" : "=&r"(result), "=Q"(*addr) : "r"((uint32_t)value));
+ return (result);
+}
+
+
+/**
+ \brief STR Exclusive (32 bit)
+ \details Executes a exclusive STR instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile("strex %0, %2, %1" : "=&r"(result), "=Q"(*addr) : "r"(value));
+ return (result);
+}
+
+
+/**
+ \brief Remove the exclusive lock
+ \details Removes the exclusive lock which is created by LDREX.
+ */
+__STATIC_FORCEINLINE void __CLREX(void)
+{
+ __ASM volatile("clrex" ::: "memory");
+}
+
+#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
+ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */
+
+
+#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
+ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
+/**
+ \brief Signed Saturate
+ \details Saturates a signed value.
+ \param [in] ARG1 Value to be saturated
+ \param [in] ARG2 Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+#define __SSAT(ARG1,ARG2) \
+ __extension__ \
+ ({ \
+ int32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+
+/**
+ \brief Unsigned Saturate
+ \details Saturates an unsigned value.
+ \param [in] ARG1 Value to be saturated
+ \param [in] ARG2 Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+#define __USAT(ARG1,ARG2) \
+ __extension__ \
+ ({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+
+/**
+ \brief Rotate Right with Extend (32 bit)
+ \details Moves each bit of a bitstring right by one bit.
+ The carry input is shifted in at the left end of the bitstring.
+ \param [in] value Value to rotate
+ \return Rotated value
+ */
+__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile("rrx %0, %1" : __CMSIS_GCC_OUT_REG(result) : __CMSIS_GCC_USE_REG(value));
+ return (result);
+}
+
+
+/**
+ \brief LDRT Unprivileged (8 bit)
+ \details Executes a Unprivileged LDRT instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr)
+{
+ uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ __ASM volatile("ldrbt %0, %1" : "=r"(result) : "Q"(*ptr));
+#else
+ /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+ accepted by assembler. So has to use following less efficient pattern.
+ */
+ __ASM volatile("ldrbt %0, [%1]" : "=r"(result) : "r"(ptr) : "memory");
+#endif
+ return ((uint8_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDRT Unprivileged (16 bit)
+ \details Executes a Unprivileged LDRT instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr)
+{
+ uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ __ASM volatile("ldrht %0, %1" : "=r"(result) : "Q"(*ptr));
+#else
+ /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+ accepted by assembler. So has to use following less efficient pattern.
+ */
+ __ASM volatile("ldrht %0, [%1]" : "=r"(result) : "r"(ptr) : "memory");
+#endif
+ return ((uint16_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDRT Unprivileged (32 bit)
+ \details Executes a Unprivileged LDRT instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile("ldrt %0, %1" : "=r"(result) : "Q"(*ptr));
+ return (result);
+}
+
+
+/**
+ \brief STRT Unprivileged (8 bit)
+ \details Executes a Unprivileged STRT instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr)
+{
+ __ASM volatile("strbt %1, %0" : "=Q"(*ptr) : "r"((uint32_t)value));
+}
+
+
+/**
+ \brief STRT Unprivileged (16 bit)
+ \details Executes a Unprivileged STRT instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr)
+{
+ __ASM volatile("strht %1, %0" : "=Q"(*ptr) : "r"((uint32_t)value));
+}
+
+
+/**
+ \brief STRT Unprivileged (32 bit)
+ \details Executes a Unprivileged STRT instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr)
+{
+ __ASM volatile("strt %1, %0" : "=Q"(*ptr) : "r"(value));
+}
+
+#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
+ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
+
+/**
+ \brief Signed Saturate
+ \details Saturates a signed value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat)
+{
+ if ((sat >= 1U) && (sat <= 32U))
+ {
+ const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
+ const int32_t min = -1 - max ;
+ if (val > max)
+ {
+ return max;
+ }
+ else if (val < min)
+ {
+ return min;
+ }
+ }
+ return val;
+}
+
+/**
+ \brief Unsigned Saturate
+ \details Saturates an unsigned value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat)
+{
+ if (sat <= 31U)
+ {
+ const uint32_t max = ((1U << sat) - 1U);
+ if (val > (int32_t)max)
+ {
+ return max;
+ }
+ else if (val < 0)
+ {
+ return 0U;
+ }
+ }
+ return (uint32_t)val;
+}
+
+#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
+ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
+
+
+#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
+/**
+ \brief Load-Acquire (8 bit)
+ \details Executes a LDAB instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile("ldab %0, %1" : "=r"(result) : "Q"(*ptr));
+ return ((uint8_t) result);
+}
+
+
+/**
+ \brief Load-Acquire (16 bit)
+ \details Executes a LDAH instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile("ldah %0, %1" : "=r"(result) : "Q"(*ptr));
+ return ((uint16_t) result);
+}
+
+
+/**
+ \brief Load-Acquire (32 bit)
+ \details Executes a LDA instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile("lda %0, %1" : "=r"(result) : "Q"(*ptr));
+ return (result);
+}
+
+
+/**
+ \brief Store-Release (8 bit)
+ \details Executes a STLB instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr)
+{
+ __ASM volatile("stlb %1, %0" : "=Q"(*ptr) : "r"((uint32_t)value));
+}
+
+
+/**
+ \brief Store-Release (16 bit)
+ \details Executes a STLH instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr)
+{
+ __ASM volatile("stlh %1, %0" : "=Q"(*ptr) : "r"((uint32_t)value));
+}
+
+
+/**
+ \brief Store-Release (32 bit)
+ \details Executes a STL instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr)
+{
+ __ASM volatile("stl %1, %0" : "=Q"(*ptr) : "r"((uint32_t)value));
+}
+
+
+/**
+ \brief Load-Acquire Exclusive (8 bit)
+ \details Executes a LDAB exclusive instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile("ldaexb %0, %1" : "=r"(result) : "Q"(*ptr));
+ return ((uint8_t) result);
+}
+
+
+/**
+ \brief Load-Acquire Exclusive (16 bit)
+ \details Executes a LDAH exclusive instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile("ldaexh %0, %1" : "=r"(result) : "Q"(*ptr));
+ return ((uint16_t) result);
+}
+
+
+/**
+ \brief Load-Acquire Exclusive (32 bit)
+ \details Executes a LDA exclusive instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile("ldaex %0, %1" : "=r"(result) : "Q"(*ptr));
+ return (result);
+}
+
+
+/**
+ \brief Store-Release Exclusive (8 bit)
+ \details Executes a STLB exclusive instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile("stlexb %0, %2, %1" : "=&r"(result), "=Q"(*ptr) : "r"((uint32_t)value));
+ return (result);
+}
+
+
+/**
+ \brief Store-Release Exclusive (16 bit)
+ \details Executes a STLH exclusive instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile("stlexh %0, %2, %1" : "=&r"(result), "=Q"(*ptr) : "r"((uint32_t)value));
+ return (result);
+}
+
+
+/**
+ \brief Store-Release Exclusive (32 bit)
+ \details Executes a STL exclusive instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile("stlex %0, %2, %1" : "=&r"(result), "=Q"(*ptr) : "r"((uint32_t)value));
+ return (result);
+}
+
+#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+ Access to dedicated SIMD instructions
+ @{
+*/
+
+#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1))
+
+__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("sadd8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("qadd8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("shadd8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uadd8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uqadd8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uhadd8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+
+__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("ssub8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("qsub8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("shsub8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("usub8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uqsub8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uhsub8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+
+__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("sadd16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("qadd16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("shadd16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uadd16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uqadd16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uhadd16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("ssub16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("qsub16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("shsub16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("usub16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uqsub16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uhsub16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("sasx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("qasx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("shasx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uasx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uqasx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uhasx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("ssax %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("qsax %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("shsax %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("usax %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uqsax %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uhsax %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("usad8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile("usada8 %0, %1, %2, %3" : "=r"(result) : "r"(op1), "r"(op2), "r"(op3));
+ return (result);
+}
+
+#define __SSAT16(ARG1,ARG2) \
+ ({ \
+ int32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+#define __USAT16(ARG1,ARG2) \
+ ({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1)
+{
+ uint32_t result;
+
+ __ASM volatile("uxtb16 %0, %1" : "=r"(result) : "r"(op1));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("uxtab16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1)
+{
+ uint32_t result;
+
+ __ASM volatile("sxtb16 %0, %1" : "=r"(result) : "r"(op1));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("sxtab16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SMUAD(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("smuad %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SMUADX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("smuadx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SMLAD(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile("smlad %0, %1, %2, %3" : "=r"(result) : "r"(op1), "r"(op2), "r"(op3));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SMLADX(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile("smladx %0, %1, %2, %3" : "=r"(result) : "r"(op1), "r"(op2), "r"(op3));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint64_t __SMLALD(uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u
+ {
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile("smlald %0, %1, %2, %3" : "=r"(llr.w32[0]), "=r"(llr.w32[1]): "r"(op1), "r"(op2),
+ "0"(llr.w32[0]), "1"(llr.w32[1]));
+#else /* Big endian */
+ __ASM volatile("smlald %0, %1, %2, %3" : "=r"(llr.w32[1]), "=r"(llr.w32[0]): "r"(op1), "r"(op2),
+ "0"(llr.w32[1]), "1"(llr.w32[0]));
+#endif
+
+ return (llr.w64);
+}
+
+__STATIC_FORCEINLINE uint64_t __SMLALDX(uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u
+ {
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile("smlaldx %0, %1, %2, %3" : "=r"(llr.w32[0]), "=r"(llr.w32[1]): "r"(op1), "r"(op2),
+ "0"(llr.w32[0]), "1"(llr.w32[1]));
+#else /* Big endian */
+ __ASM volatile("smlaldx %0, %1, %2, %3" : "=r"(llr.w32[1]), "=r"(llr.w32[0]): "r"(op1), "r"(op2),
+ "0"(llr.w32[1]), "1"(llr.w32[0]));
+#endif
+
+ return (llr.w64);
+}
+
+__STATIC_FORCEINLINE uint32_t __SMUSD(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("smusd %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SMUSDX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("smusdx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SMLSD(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile("smlsd %0, %1, %2, %3" : "=r"(result) : "r"(op1), "r"(op2), "r"(op3));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint32_t __SMLSDX(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile("smlsdx %0, %1, %2, %3" : "=r"(result) : "r"(op1), "r"(op2), "r"(op3));
+ return (result);
+}
+
+__STATIC_FORCEINLINE uint64_t __SMLSLD(uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u
+ {
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile("smlsld %0, %1, %2, %3" : "=r"(llr.w32[0]), "=r"(llr.w32[1]): "r"(op1), "r"(op2),
+ "0"(llr.w32[0]), "1"(llr.w32[1]));
+#else /* Big endian */
+ __ASM volatile("smlsld %0, %1, %2, %3" : "=r"(llr.w32[1]), "=r"(llr.w32[0]): "r"(op1), "r"(op2),
+ "0"(llr.w32[1]), "1"(llr.w32[0]));
+#endif
+
+ return (llr.w64);
+}
+
+__STATIC_FORCEINLINE uint64_t __SMLSLDX(uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u
+ {
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile("smlsldx %0, %1, %2, %3" : "=r"(llr.w32[0]), "=r"(llr.w32[1]): "r"(op1), "r"(op2),
+ "0"(llr.w32[0]), "1"(llr.w32[1]));
+#else /* Big endian */
+ __ASM volatile("smlsldx %0, %1, %2, %3" : "=r"(llr.w32[1]), "=r"(llr.w32[0]): "r"(op1), "r"(op2),
+ "0"(llr.w32[1]), "1"(llr.w32[0]));
+#endif
+
+ return (llr.w64);
+}
+
+__STATIC_FORCEINLINE uint32_t __SEL(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile("sel %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE int32_t __QADD(int32_t op1, int32_t op2)
+{
+ int32_t result;
+
+ __ASM volatile("qadd %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+__STATIC_FORCEINLINE int32_t __QSUB(int32_t op1, int32_t op2)
+{
+ int32_t result;
+
+ __ASM volatile("qsub %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2));
+ return (result);
+}
+
+#if 0
+#define __PKHBT(ARG1,ARG2,ARG3) \
+ ({ \
+ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+ __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
+ __RES; \
+ })
+
+#define __PKHTB(ARG1,ARG2,ARG3) \
+ ({ \
+ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+ if (ARG3 == 0) \
+ __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
+ else \
+ __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
+ __RES; \
+ })
+#endif
+
+#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
+ ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
+
+#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
+ ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
+
+__STATIC_FORCEINLINE int32_t __SMMLA(int32_t op1, int32_t op2, int32_t op3)
+{
+ int32_t result;
+
+ __ASM volatile("smmla %0, %1, %2, %3" : "=r"(result): "r"(op1), "r"(op2), "r"(op3));
+ return (result);
+}
+
+#endif /* (__ARM_FEATURE_DSP == 1) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#pragma GCC diagnostic pop
+
+#endif /* __CMSIS_GCC_H */
diff --git a/inc/platform/core_cm0plus.h b/inc/platform/core_cm0plus.h
new file mode 100644
index 0000000..eeeeb70
--- /dev/null
+++ b/inc/platform/core_cm0plus.h
@@ -0,0 +1,969 @@
+/**************************************************************************//**
+ * @file core_cm0plus.h
+ * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of ARM nor the names of its contributors may be used
+ to endorse or promote products derived from this software without
+ specific prior written permission.
+ *
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+#pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+#pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM0PLUS_H_GENERIC
+#define __CORE_CM0PLUS_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
+ CMSIS violates the following MISRA-C:2004 rules:
+
+ \li Required Rule 8.5, object/function definition in header file.<br>
+ Function definitions in header files are used to allow 'inlining'.
+
+ \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+ Unions are used for effective representation of core registers.
+
+ \li Advisory Rule 19.7, Function-like macro defined.<br>
+ Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/**
+ \ingroup Cortex-M0+
+ @{
+ */
+
+/* CMSIS CM0+ definitions */
+#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
+#define __CM0PLUS_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
+#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \
+ __CM0PLUS_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x00U) /*!< Cortex-M Core */
+
+
+#if defined ( __CC_ARM )
+#define __ASM __asm /*!< asm keyword for ARM Compiler */
+#define __INLINE __inline /*!< inline keyword for ARM Compiler */
+#define __STATIC_INLINE static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+#define __ASM __asm /*!< asm keyword for ARM Compiler */
+#define __INLINE __inline /*!< inline keyword for ARM Compiler */
+#define __STATIC_INLINE static __inline
+
+#elif defined ( __GNUC__ )
+#define __ASM __asm /*!< asm keyword for GNU Compiler */
+#define __INLINE inline /*!< inline keyword for GNU Compiler */
+#define __STATIC_INLINE static inline
+
+#elif defined ( __ICCARM__ )
+#define __ASM __asm /*!< asm keyword for IAR Compiler */
+#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+#define __STATIC_INLINE static inline
+
+#elif defined ( __TMS470__ )
+#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
+#define __STATIC_INLINE static inline
+
+#elif defined ( __TASKING__ )
+#define __ASM __asm /*!< asm keyword for TASKING Compiler */
+#define __INLINE inline /*!< inline keyword for TASKING Compiler */
+#define __STATIC_INLINE static inline
+
+#elif defined ( __CSMC__ )
+#define __packed
+#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
+#define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+#define __STATIC_INLINE static inline
+
+#else
+#error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+ This core does not support an FPU at all
+*/
+#define __FPU_USED 0U
+
+#if defined ( __CC_ARM )
+#if defined __TARGET_FPU_VFP
+#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+#endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+#if defined __ARM_PCS_VFP
+#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+#endif
+
+#elif defined ( __GNUC__ )
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+#endif
+
+#elif defined ( __ICCARM__ )
+#if defined __ARMVFP__
+#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+#endif
+
+#elif defined ( __TMS470__ )
+#if defined __TI_VFP_SUPPORT__
+#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+#endif
+
+#elif defined ( __TASKING__ )
+#if defined __FPU_VFP__
+#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+#endif
+
+#elif defined ( __CSMC__ )
+#if ( __CSMC__ & 0x400U)
+#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+#endif
+
+#endif
+
+#include "core_cmInstr.h" /* Core Instruction Access */
+#include "core_cmFunc.h" /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0PLUS_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM0PLUS_H_DEPENDANT
+#define __CORE_CM0PLUS_H_DEPENDANT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __VTOR_PRESENT 1U
+#define __MPU_PRESENT 1U
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+#ifndef __CM0PLUS_REV
+#define __CM0PLUS_REV 0x0000U
+#warning "__CM0PLUS_REV not defined in device header file; using default!"
+#endif
+
+#ifndef __MPU_PRESENT
+#define __MPU_PRESENT 0U
+#warning "__MPU_PRESENT not defined in device header file; using default!"
+#endif
+
+#ifndef __VTOR_PRESENT
+#define __VTOR_PRESENT 0U
+#warning "__VTOR_PRESENT not defined in device header file; using default!"
+#endif
+
+#ifndef __NVIC_PRIO_BITS
+#define __NVIC_PRIO_BITS 2U
+#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+#endif
+
+#ifndef __Vendor_SysTickConfig
+#define __Vendor_SysTickConfig 0U
+#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+#endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+ <strong>IO Type Qualifiers</strong> are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+#define __I volatile /*!< Defines 'read only' permissions */
+#else
+#define __I volatile const /*!< Defines 'read only' permissions */
+#endif
+#define __O volatile /*!< Defines 'write only' permissions */
+#define __IO volatile /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#define __IOM volatile /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex-M0+ */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ - Core MPU Register
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_core_register Defines and Type Definitions
+ \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE Status and Control Registers
+ \brief Core Register type definitions.
+ @{
+ */
+
+/**
+ \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0: 28; /*!< bit: 0..27 Reserved */
+ uint32_t V: 1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C: 1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z: 1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N: 1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos 31U /*!< APSR: N Position */
+#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
+
+#define APSR_Z_Pos 30U /*!< APSR: Z Position */
+#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
+
+#define APSR_C_Pos 29U /*!< APSR: C Position */
+#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
+
+#define APSR_V_Pos 28U /*!< APSR: V Position */
+#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
+
+
+/**
+ \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR: 9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0: 23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR: 9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0: 15; /*!< bit: 9..23 Reserved */
+ uint32_t T: 1; /*!< bit: 24 Thumb bit (read 0) */
+ uint32_t _reserved1: 3; /*!< bit: 25..27 Reserved */
+ uint32_t V: 1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C: 1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z: 1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N: 1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos 31U /*!< xPSR: N Position */
+#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
+#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos 29U /*!< xPSR: C Position */
+#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos 28U /*!< xPSR: V Position */
+#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
+
+#define xPSR_T_Pos 24U /*!< xPSR: T Position */
+#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t nPRIV: 1; /*!< bit: 0 Execution privilege in Thread mode */
+ uint32_t SPSEL: 1; /*!< bit: 1 Stack to be used */
+ uint32_t _reserved1: 30; /*!< bit: 2..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
+ \brief Type definitions for the NVIC Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[31U];
+ __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[31U];
+ __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[31U];
+ __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[31U];
+ uint32_t RESERVED4[64U];
+ __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
+} NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB System Control Block (SCB)
+ \brief Type definitions for the System Control Block Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IOM uint32_t
+ ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+#if (__VTOR_PRESENT == 1U)
+ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
+#else
+ uint32_t RESERVED0;
+#endif
+ __IOM uint32_t
+ AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ uint32_t RESERVED1;
+ __IOM uint32_t
+ SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
+ __IOM uint32_t
+ SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
+
+#if (__VTOR_PRESENT == 1U)
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+#endif
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick System Tick Timer (SysTick)
+ \brief Type definitions for the System Timer Registers.
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IOM uint32_t
+ CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+#if (__MPU_PRESENT == 1U)
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_MPU Memory Protection Unit (MPU)
+ \brief Type definitions for the Memory Protection Unit (MPU)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+ __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
+ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
+ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
+ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
+ __IOM uint32_t
+ RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
+
+#define MPU_DEFS_RASR_SIZE_32B (0x04 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_64B (0x05 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_128B (0x06 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_256B (0x07 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_512B (0x08 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_1KB (0x09 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_2KB (0x0A << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_4KB (0x0B << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_8KB (0x0C << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_16KB (0x0D << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_32KB (0x0E << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_64KB (0x0F << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_128KB (0x10 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_256KB (0x11 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_512KB (0x12 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_1MB (0x13 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_2MB (0x14 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_4MB (0x15 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_8MB (0x16 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_16MB (0x17 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_32MB (0x18 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_64MB (0x19 << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_128MB (0x1A << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_256MB (0x1B << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_512MB (0x1C << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_1GB (0x1D << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_2GB (0x1E << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASR_SIZE_4GB (0x1F << MPU_RASR_SIZE_Pos)
+#define MPU_DEFS_RASE_AP_NO_ACCESS (0x0 << MPU_RASR_AP_Pos)
+#define MPU_DEFS_RASE_AP_PRIV_RW (0x1 << MPU_RASR_AP_Pos)
+#define MPU_DEFS_RASE_AP_PRIV_RW_USER_RO (0x2 << MPU_RASR_AP_Pos)
+#define MPU_DEFS_RASE_AP_FULL_ACCESS (0x3 << MPU_RASR_AP_Pos)
+#define MPU_DEFS_RASE_AP_PRIV_RO (0x5 << MPU_RASR_AP_Pos)
+#define MPU_DEFS_RASE_AP_RO (0x6 << MPU_RASR_AP_Pos)
+#define MPU_DEFS_NORMAL_MEMORY_WT (MPU_RASR_C_Msk)
+#define MPU_DEFS_NORMAL_MEMORY_WB (MPU_RASR_C_Msk | MPU_RASR_B_Msk)
+#define MPU_DEFS_NORMAL_SHARED_MEMORY_WT (MPU_RASR_C_Msk |MPU_RASR_S_Msk)
+#define MPU_DEFS_NORMAL_SHARED_MEMORY_WB (MPU_DEFS_NORMAL_MEMORY_WB |MPU_RASR_S_Msk)
+#define MPU_DEFS_SHARED_DEVICE (MPU_RASR_B_Msk)
+#define MPU_DEFS_STRONGLY_ORDERED_DEVICE (0x0)
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
+ \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
+ Therefore they are not covered by the Cortex-M0+ header file.
+ @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_bitfield Core register bit field macros
+ \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+ @{
+ */
+
+/**
+ \brief Mask and shift a bit field value for use in a register bit range.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of the bit field.
+ \return Masked and shifted value.
+*/
+#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
+
+/**
+ \brief Mask and shift a register value to extract a bit filed value.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of register.
+ \return Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_base Core Definitions
+ \brief Definitions for base addresses, unions, and structures.
+ @{
+ */
+
+/* Memory mapping of Cortex-M0+ Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
+#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Register Access Functions
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+ \brief Functions that manage interrupts and exceptions via the NVIC.
+ @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
+#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
+#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
+
+
+/**
+ \brief Enable External Interrupt
+ \details Enables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Disable External Interrupt
+ \details Disables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Get Pending Interrupt
+ \details Reads the pending register in the NVIC and return the pending bit for the specified interrupt.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not pending.
+ \return 1 Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return ((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL :
+ 0UL));
+}
+
+
+/**
+ \brief Set Pending Interrupt
+ \details Sets the pending bit of an external interrupt.
+ \param [in] IRQn Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Clear Pending Interrupt
+ \details Clears the pending bit of an external interrupt.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Set Interrupt Priority
+ \details Sets the priority of an interrupt.
+ \note The priority cannot be set for every core interrupt.
+ \param [in] IRQn Interrupt number.
+ \param [in] priority Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if ((int32_t)(IRQn) < 0)
+ {
+ SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ }
+ else
+ {
+ NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ }
+}
+
+
+/**
+ \brief Get Interrupt Priority
+ \details Reads the priority of an interrupt.
+ The interrupt number can be positive to specify an external (device specific) interrupt,
+ or negative to specify an internal (core) interrupt.
+ \param [in] IRQn Interrupt number.
+ \return Interrupt Priority.
+ Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if ((int32_t)(IRQn) < 0)
+ {
+ return ((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn)) & (uint32_t)0xFFUL) >>
+ (8U - __NVIC_PRIO_BITS)));
+ }
+ else
+ {
+ return ((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn)) & (uint32_t)0xFFUL) >>
+ (8U - __NVIC_PRIO_BITS)));
+ }
+}
+
+
+/**
+ \brief System Reset
+ \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ SCB_AIRCR_SYSRESETREQ_Msk);
+ __DSB(); /* Ensure completion of memory access */
+
+ for (;;) /* wait until reset */
+ {
+ __NOP();
+ }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+ \brief Functions that configure the System.
+ @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+ \brief System Tick Configuration
+ \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ Counter is in free running mode to generate periodic interrupts.
+ \param [in] ticks Number of ticks between two interrupts.
+ \return 0 Function succeeded.
+ \return 1 Function failed.
+ \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+ function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+ must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+ {
+ return (1UL); /* Reload value impossible */
+ }
+
+ SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
+ NVIC_SetPriority(SysTick_IRQn,
+ (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+ SysTick->VAL =
+ 0UL; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0UL); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0PLUS_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/inc/platform/core_cmFunc.h b/inc/platform/core_cmFunc.h
new file mode 100644
index 0000000..95b27b8
--- /dev/null
+++ b/inc/platform/core_cmFunc.h
@@ -0,0 +1,87 @@
+/**************************************************************************//**
+ * @file core_cmFunc.h
+ * @brief CMSIS Cortex-M Core Function Access Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of ARM nor the names of its contributors may be used
+ to endorse or promote products derived from this software without
+ specific prior written permission.
+ *
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+#pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+#pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CMFUNC_H
+#define __CORE_CMFUNC_H
+
+
+/* ########################### Core Function Access ########################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+ @{
+*/
+
+/*------------------ RealView Compiler -----------------*/
+#if defined ( __CC_ARM )
+#include "cmsis_armcc.h"
+
+/*------------------ ARM Compiler V6 -------------------*/
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+#include "cmsis_armcc_V6.h"
+
+/*------------------ GNU Compiler ----------------------*/
+#elif defined ( __GNUC__ )
+#include "cmsis_gcc.h"
+
+/*------------------ ICC Compiler ----------------------*/
+#elif defined ( __ICCARM__ )
+#include <cmsis_iar.h>
+
+/*------------------ TI CCS Compiler -------------------*/
+#elif defined ( __TMS470__ )
+#include <cmsis_ccs.h>
+
+/*------------------ TASKING Compiler ------------------*/
+#elif defined ( __TASKING__ )
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+/*------------------ COSMIC Compiler -------------------*/
+#elif defined ( __CSMC__ )
+#include <cmsis_csm.h>
+
+#endif
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+#endif /* __CORE_CMFUNC_H */
diff --git a/inc/platform/core_cmInstr.h b/inc/platform/core_cmInstr.h
new file mode 100644
index 0000000..c1ab637
--- /dev/null
+++ b/inc/platform/core_cmInstr.h
@@ -0,0 +1,87 @@
+/**************************************************************************//**
+ * @file core_cmInstr.h
+ * @brief CMSIS Cortex-M Core Instruction Access Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of ARM nor the names of its contributors may be used
+ to endorse or promote products derived from this software without
+ specific prior written permission.
+ *
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+#pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+#pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CMINSTR_H
+#define __CORE_CMINSTR_H
+
+
+/* ########################## Core Instruction Access ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+ Access to dedicated instructions
+ @{
+*/
+
+/*------------------ RealView Compiler -----------------*/
+#if defined ( __CC_ARM )
+#include "cmsis_armcc.h"
+
+/*------------------ ARM Compiler V6 -------------------*/
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+#include "cmsis_armcc_V6.h"
+
+/*------------------ GNU Compiler ----------------------*/
+#elif defined ( __GNUC__ )
+#include "cmsis_gcc.h"
+
+/*------------------ ICC Compiler ----------------------*/
+#elif defined ( __ICCARM__ )
+#include <cmsis_iar.h>
+
+/*------------------ TI CCS Compiler -------------------*/
+#elif defined ( __TMS470__ )
+#include <cmsis_ccs.h>
+
+/*------------------ TASKING Compiler ------------------*/
+#elif defined ( __TASKING__ )
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+/*------------------ COSMIC Compiler -------------------*/
+#elif defined ( __CSMC__ )
+#include <cmsis_csm.h>
+
+#endif
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+#endif /* __CORE_CMINSTR_H */
diff --git a/inc/platform/core_cmSimd.h b/inc/platform/core_cmSimd.h
new file mode 100644
index 0000000..af5337d
--- /dev/null
+++ b/inc/platform/core_cmSimd.h
@@ -0,0 +1,96 @@
+/**************************************************************************//**
+ * @file core_cmSimd.h
+ * @brief CMSIS Cortex-M SIMD Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ - Neither the name of ARM nor the names of its contributors may be used
+ to endorse or promote products derived from this software without
+ specific prior written permission.
+ *
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+#pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+#pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CMSIMD_H
+#define __CORE_CMSIMD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+ Access to dedicated SIMD instructions
+ @{
+*/
+
+/*------------------ RealView Compiler -----------------*/
+#if defined ( __CC_ARM )
+#include "cmsis_armcc.h"
+
+/*------------------ ARM Compiler V6 -------------------*/
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+#include "cmsis_armcc_V6.h"
+
+/*------------------ GNU Compiler ----------------------*/
+#elif defined ( __GNUC__ )
+#include "cmsis_gcc.h"
+
+/*------------------ ICC Compiler ----------------------*/
+#elif defined ( __ICCARM__ )
+#include <cmsis_iar.h>
+
+/*------------------ TI CCS Compiler -------------------*/
+#elif defined ( __TMS470__ )
+#include <cmsis_ccs.h>
+
+/*------------------ TASKING Compiler ------------------*/
+#elif defined ( __TASKING__ )
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+/*------------------ COSMIC Compiler -------------------*/
+#elif defined ( __CSMC__ )
+#include <cmsis_csm.h>
+
+#endif
+
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CMSIMD_H */
diff --git a/inc/platform/cp.h b/inc/platform/cp.h
new file mode 100644
index 0000000..16c2f3e
--- /dev/null
+++ b/inc/platform/cp.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file cp.h
+* @brief apple's authentication coprocessor driver header file.
+* @details none.
+* @author tifnan
+* @date 2015-09-09
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef _CP_H_
+#define _CP_H_
+
+/*============================================================================*
+ * Header Files
+*============================================================================*/
+#include <stdint.h>
+#include <stdbool.h>
+
+//cp device address, if reset pin pull low, 0x10; if reset pin pull high, 0x11
+#define CP_DEVICE_ADDRESS_RESET_POLL_LOW 0x10
+#define CP_DEVICE_ADDRESS_RESET_POLL_HIGH 0x11
+
+
+//cp register address (block 1)
+#define CP_REG_DEV_VER 0x00 //RO, device verision
+#define CP_REG_FW_VER 0x01 //RO, firmware verision
+#define CP_REG_MAJ_VER 0x02 //RO, authentication protocol major verision
+#define CP_REG_MIN_VER 0x03 //RO, authentication protocol minor verision
+#define CP_dev_id 0x04 //RO, device id, 4bytes(0x00000200)
+#define CP_ERR_CODE 0x05 //RO, error code -- read clear
+
+//cp register address (block 2)
+#define CP_REG_CS 0x10 //RW, authentication control & status
+#define CP_SIG_LEN 0x11 //RW, signature data length, 2bytes(128)
+#define CP_SIG_DATA 0x12 //RW, signature data, 128 bytes
+#define CP_REG_CHA_LEN 0x20 //RW, challenge data length, 2bytes(20)
+#define CP_REG_CHA_DATA 0x21 //RW, challenge data, 128bytes
+
+//cp register address (block 3)
+#define CP_REG_ACD_LEN 0x30 //RO, accessory certificate data length, 2bytes(<=1280)
+#define CP_REG_ACD1 0x31 //RO, accessory certificate data page1, 128bytes
+#define CP_REG_ACD2 0x32 //RO, accessory certificate data page2, 128bytes
+#define CP_REG_ACD3 0x33 //RO, accessory certificate data page3, 128bytes
+#define CP_REG_ACD4 0x34 //RO, accessory certificate data page4, 128bytes
+#define CP_REG_ACD5 0x35 //RO, accessory certificate data page5, 128bytes
+#define CP_REG_ACD6 0x36 //RO, accessory certificate data page6, 128bytes
+#define CP_REG_ACD7 0x37 //RO, accessory certificate data page7, 128bytes
+#define CP_REG_ACD8 0x38 //RO, accessory certificate data page8, 128bytes
+#define CP_REG_ACD9 0x39 //RO, accessory certificate data page9, 128bytes
+#define CP_REG_ACD10 0x3A //RO, accessory certificate data page10, 128bytes
+
+//cp register address (block 4)
+#define CP_REG_ST_CS 0x40 //RW, self-test control & status
+#define CP_REG_SEC 0x4D //RO, system event counter
+
+//cp register address (block 5)
+#define CP_REG_ADCD_LEN 0x50 //RW, apple device certificate data length, 2bytes(0x0000)
+#define CP_REG_ADCD1 0x51 //RW, apple device certificate data page1, 128bytes
+#define CP_REG_ADCD2 0x52 //RW, apple device certificate data page2, 128bytes
+#define CP_REG_ADCD3 0x53 //RW, apple device certificate data page3, 128bytes
+#define CP_REG_ADCD4 0x54 //RW, apple device certificate data page4, 128bytes
+#define CP_REG_ADCD5 0x55 //RW, apple device certificate data page5, 128bytes
+#define CP_REG_ADCD6 0x56 //RW, apple device certificate data page6, 128bytes
+#define CP_REG_ADCD7 0x57 //RW, apple device certificate data page7, 128bytes
+#define CP_REG_ADCD8 0x58 //RW, apple device certificate data page8, 128bytes
+
+
+
+/** @defgroup ACP Authentication Coprocessor
+ * @brief apple's authentication coprocessor module driver
+ * @{
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup ACP_Exported_Types Authentication Coprocessor Exported Types
+ * @{
+ */
+
+//cp process result
+/** @brief ACP process response value */
+typedef enum
+{
+ CP_PRO_RES_NO_VALID = 0x80, //!<Most recent process did not produce valid results
+ CP_PRO_RES_SIG_GEN_OK = 0x10, //!<Accessory signature successfully generated.
+ CP_PRO_RES_CHA_GEN_OK = 0x20, //!<Challenge successfully generated.
+ CP_PRO_RES_SIG_VEFY_OK = 0x30, //!<Apple device signature successfully verified
+ CP_PRO_RES_CER_VAL_OK = 0x40 //!<Apple device certificate successfully validated
+} T_CP_PRO_RES;
+
+/** @brief ACP command value */
+typedef enum
+{
+ CP_CMD_START_SIG_GEN = 0x01, //!<start signature generate process
+ CP_CMD_START_CHA_GEN, //!<start challenge generate process
+ CP_CMD_START_SIG_VEFY, //!<start signature-verification process
+ CP_CMD_START_CER_VAL //!<start certificate-validation process
+} T_CP_CMD;
+
+//cp error code enum
+/** @brief ACP error code */
+typedef enum
+{
+ CP_ERR_NO_ERR = 0x00, //!<No error
+ CP_ERR_INV_READ_REG, //!<Invalid register for read
+ CP_ERR_INV_WR_REG, //!<Invalid register for write
+ CP_ERR_INV_SIG_LEN, //!<Invalid signature length
+ CP_ERR_INV_CHA_LEN, //!<Invalid challenge length
+ CP_ERR_INV_CER_LEN, //!<Invalid certificate length
+ CP_ERR_INTR_SIG_GEN, //!<Internal process error during signature generation
+ CP_ERR_INTR_CHA_GEN, //!<Internal process error during challenge generation
+ CP_ERR_INTR_SIG_VEFY, //!<Internal process error during signature verification
+ CP_ERR_INTR_VER_VAL, //!<Internal process error during certificate validation
+ CP_ERR_INV_CTRL, //!<Invalid process control
+ CP_ERR_PRO_OUT_OF_SEQ, //!<Process control out of sequence
+ CP_ERR_RESVD
+} T_CP_ERR_CODE;
+
+/** @brief ACP device information */
+typedef struct
+{
+ uint8_t dev_ver;
+ uint8_t fw_ver;
+ uint8_t aup_mar_ver; //!<authentication protocol major verision
+ uint8_t aup_mir_ver; //!<authentication protocol minor verision
+ uint8_t dev_id[4];
+} T_CP_INFO;
+
+/** @brief ACP function return status */
+typedef enum
+{
+ CP_CAUSE_SUCCESS = 0x00,
+ CP_CAUSE_TIMEOUT = 0x01,
+ CP_CAUSE_INVALID_PARAM = 0x02,
+ CP_CAUSE_INVALID_STATE = 0x03,
+} T_CP_CAUSE;
+
+/** End of ACP_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @defgroup ACP_EXPORT_Functions Authentication Coprocessor Exported Functions
+ * @{
+ */
+/**
+ * @brief reset CP module
+ * @param void
+ * @return none
+ */
+void cp_reset(void);
+
+/**
+ * @brief set CP module I2C address
+ * @param poll_low to specify the CP I2C address
+ * @return none
+ */
+void cp_set_slave_address(bool poll_low);
+
+/**
+ * @brief CP hardware init with specific I2C, reset pin number
+ * @param p_i2c to specify the CP I2C pin
+ * @param reset_pin to specify the CP reset pin
+ * @param poll_low to specify the CP I2C address
+ * @return none
+ */
+void cp_hw_init(void *p_i2c, uint8_t reset_pin, bool poll_low);
+/**
+ * @brief read CP information
+ * @param info to store the cp information
+ * @return function status @ref T_CP_CAUSE
+ */
+T_CP_CAUSE cp_read_cp_info(T_CP_INFO *info);
+/**
+ * @brief read CP signature data
+ * @param sig_buf to store the cp signature data
+ * @param length the signature data length
+ * @return function status @ref T_CP_CAUSE
+ */
+T_CP_CAUSE cp_read_signature_data(uint8_t *sig_buf, uint16_t length);
+
+/**
+ * @brief read CP signature length
+ * @param p_signature_len to store the signature length
+ * @return function status @ref T_CP_CAUSE
+ */
+T_CP_CAUSE cp_read_signature_len(uint16_t *p_signature_len);
+
+/**
+ * @brief write challenge info.
+ * @param[in] cha_buf challenge info buffer.
+ * @param[in] buf_len challenge info buffer length.
+ * @return function status @ref T_CP_CAUSE
+ * @note the first 2 bytes in challenge info buffer are challenge data length.
+*/
+T_CP_CAUSE cp_write_cha_info(uint8_t *cha_buf, uint16_t buf_len);
+
+/**
+ * @brief read certificate data length.
+ * @param p_crf_data_le to store certificate data length
+ * @return function status @ref T_CP_CAUSE
+ */
+T_CP_CAUSE cp_read_crf_data_len(uint16_t *p_crf_data_le);
+
+/**
+ * @brief read certificate data.
+ * @param[in] cert_data_page
+ * @param[in] data certificate data buffer.
+ * @param[in] length certificate data length.
+ * @return function status @ref T_CP_CAUSE
+ */
+T_CP_CAUSE cp_read_crf_data(uint8_t cert_data_page, uint8_t *data, uint16_t length);
+/**
+ * @brief start cp control process.
+ * @param[in] cmd cp control comamnd.
+ * @return function status @ref T_CP_CAUSE
+ */
+T_CP_CAUSE cp_ctrl(T_CP_CMD cmd);
+/**
+ * @brief write challenge data.
+ * @param[in] cha_buf challenge data buffer.
+ * @param[in] buf_len challenge data buffer length.
+ * @return function status @ref T_CP_CAUSE
+ */
+T_CP_CAUSE cp_write_cha_data(uint8_t *cha_buf, uint16_t buf_len);
+
+/**
+ * @brief write challenge data length.
+ * @param[in] len challenge data length.
+ * @return function status @ref T_CP_CAUSE
+ */
+T_CP_CAUSE cp_write_cha_len(uint16_t len);
+/**
+ * @brief read CP process result.
+ * @param[out] p_cp_pro_res_m result buffer
+ * @return function status @ref T_CP_CAUSE
+ */
+T_CP_CAUSE cp_read_proc_result(T_CP_PRO_RES *p_cp_pro_res_m);
+/**
+ * @brief read CP error code.
+ * @param[out] p_cp_err_code_m error code buffer
+ * @return function status @ref T_CP_CAUSE
+ */
+T_CP_CAUSE cp_read_err_code(T_CP_ERR_CODE *p_cp_err_code_m);
+
+//void cp_test(void);
+/** @} */ /* End of group ACP_EXPORT_Functions */
+/** @} */ /* End of group ACP */
+
+#endif /*_CP_H_ */
+
diff --git a/inc/platform/crc16btx.h b/inc/platform/crc16btx.h
new file mode 100644
index 0000000..ef19ba7
--- /dev/null
+++ b/inc/platform/crc16btx.h
@@ -0,0 +1,75 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file crc16btx.h
+* @brief Cyclic Redundancy Check (CRC) Implementation for BTX,
+* Polynomial: X**0 + X**2 + X**15 + X16
+*
+* @author gordon
+* @date 2015-07-13
+* @version v1.0
+ * *************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2015 Realtek Semiconductor Corporation</center></h2>
+ * *************************************************************************************
+ */
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#if ! defined (__CRC16BTX_H)
+#define __CRC16BTX_H
+
+/*============================================================================*
+ * Header Files
+*============================================================================*/
+#include <stdint.h>
+
+
+/** @defgroup CRC_FCS CRC Implementation
+ * @brief CRC implementation for specified polynomial
+ * @{
+ */
+
+/*============================================================================*
+ * Macro
+*============================================================================*/
+/** @defgroup CRC_FCS_Exported_Macros CRC Implementation Exported Macros
+ * @{
+ */
+/** defines and macros */
+#define BTXFCS_INIT 0x0000 /**< Initial FCS value */
+#define BTXFCS_GOOD 0x0000 /**< Good final FCS value */
+/** @} */ /* End of group CRC_FCS_Exported_Macros */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup CRC_FCS_Exported_Functions CRC Implementation Exported Functions
+ * @brief
+ * @{
+ */
+/**
+* @brief Calculate a new fcs given the current fcs and the new data.
+* Polynomial: X**0 + X**2 + X**15 + X16
+*
+* @param fcs: init or good final
+* @param cp: data point
+* @param len: length
+*
+* @return
+*
+*/
+uint16_t btxfcs(uint16_t fcs,
+ uint8_t *cp,
+ uint32_t len);
+
+/** @} */ /* End of group CRC_FCS_Exported_Functions */
+
+/** @} */ /* End of group CRC_FCS */
+
+#endif /**< #if ! defined (__CRC16BTX_H) */
+
+/** End of CRC16BTX.H */
+
diff --git a/inc/platform/crc8ets.h b/inc/platform/crc8ets.h
new file mode 100644
index 0000000..b498c19
--- /dev/null
+++ b/inc/platform/crc8ets.h
@@ -0,0 +1,48 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file crc8ets.h
+ * @brief CRC/FCS routines based on ETSI TS 101 369 V6.3.0 (1999-03) /
+ * GSM 07.10 version 6.3.0 Release 1997, B.3.5 Reversed CRC table.
+ * Generator polynomial: x**8 + x**2 + x + 1
+ * @author gordon
+ * @date 2015-07-13
+ * @version v1.0
+ ***************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2015 Realtek Semiconductor Corporation</center></h2>
+ ***************************************************************************************
+ */
+
+#if ! defined (__CRC8ETS_H)
+#define __CRC8ETS_H
+
+/*
+#if ! defined (__BASETYPE_H)
+#include <basetype.h>
+#endif
+*/
+#include <stdint.h>
+
+/** @defgroup CRC_FCS CRC Implementation
+ * @brief CRC implementation for specified polynomial
+ * @{
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup CRC_FCS_Exported_Functions CRC Implementation Exported Functions
+ * @brief
+ * @{
+ */
+
+uint8_t crc8EtsGen(uint8_t *p, uint16_t len);
+uint8_t crc8EtsCheck(uint8_t *p, uint16_t len, uint8_t rfcs);
+/** @} */ /* End of group CRC_FCS_Exported_Functions */
+
+/** @} */ /* End of group CRC_FCS */
+
+#endif /**< ! defined (__CRC8ETS_H) */
+
diff --git a/inc/platform/dfu_flash.h b/inc/platform/dfu_flash.h
new file mode 100644
index 0000000..ba4daf9
--- /dev/null
+++ b/inc/platform/dfu_flash.h
@@ -0,0 +1,199 @@
+#ifndef DFU_FLASH_H
+#define DFU_FLASH_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "patch_header_check.h"
+#include "dfu_api.h"
+
+/** @defgroup DFU_API DFU API Sets
+ * @brief API sets for device firmware update implementation
+ * @{
+ */
+
+
+/*******************************OTA ERROR CODE********************/
+#define DFU_UPDATE_SUCCESS 0x0
+#define DFU_UPDATE_ERROR_LEN_NOT_ALIGN 0x1
+#define DFU_UPDATE_ERROR_EMPTY_BUFFER 0x2
+#define DFU_UPDATE_ERROR_BASE_ADDR_INVALID 0x3
+#define DFU_UPDATE_ERROR_IMAGE_SIZE_TOO_LARGE 0x4
+#define DFU_UPDATE_ERROR_PACKET_SIZE_TOO_LARGE 0x5
+#define DFU_UPDATE_ERROR_FLASH_ERASE_LEN_NOT_ALIGN 0x6
+#define DFU_UPDATE_ERROR_FLASH_ERASE_FAIL 0x7
+#define DFU_UPDATE_ERROR_FLASH_WRITE_FAIL 0x8
+#define DFU_UPDATE_ERROR_FLASH_READBACK_FAIL 0x9
+#define DFU_UPDATE_ERROR_FLASH_READBACK_MISMATCH 0xa
+
+#define DFU_CHECKSUM_SUCCESS 0x0
+#define DFU_CHECKSUM_ERROR_BASE_ADDR_INVALID 0x1
+#define DFU_CHECKSUM_ERROR_IMAGE_TYPE_INVALID 0x2
+#define DFU_CHECKSUM_ERROR_CHECK_FAIL 0x3
+
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup DFU_API_Exported_Types DFU API Sets Exported Types
+ * @brief
+ * @{
+ */
+
+typedef enum
+{
+ DFU_START = 0,
+ DFU_DOING,
+ DFU_END,
+} T_DFU_STATUS;
+
+typedef union
+{
+ T_IMG_CTRL_HEADER_FORMAT *p_header; //for DFU_START
+ uint32_t dfu_length; //for DFU_DOING
+ bool image_check_result; //for DFU_END
+} T_DFU_DATA;
+
+typedef void (*P_FUNC_DFU_STATUS_CB)(T_DFU_STATUS status, T_DFU_DATA data);
+
+/**
+ * @}
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup DFU_API_Exported_Functions DFU API Sets Exported Variables
+ * @brief
+ * @{
+ */
+
+
+
+/**
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup DFU_API_Exported_Functions DFU API Sets Exported Functions
+ * @{
+ */
+/**
+ * @brief check whether in OTA mode.
+*/
+bool dfu_check_ota_mode_flag(void);
+
+/**
+ * @brief set aon reg value means whether in OTA mode or not.
+*/
+void dfu_set_ota_mode_flag(bool enable);
+
+/**
+ * @brief switch to the OTA mode, if support normal ota app need call it.
+*/
+void dfu_switch_to_ota_mode(void);
+
+/**
+ * @brief OTA procedure do wdg system reset.
+ * @param is_active_fw true means dfu success! otherwise fail.
+*/
+void dfu_fw_reboot(bool is_active_fw);
+
+
+/**
+ * @brief OTA image default ecb mode aes decrypt, last less than 16bytes no encrypted.
+*/
+void dfu_hw_aes_decrypt_image(uint8_t *input, uint8_t *output, uint32_t length);
+
+/**
+ * @brief report specified target ic type.
+ * @param image_id image_id to identify FW.
+ * @param p_ic_type To store ic type.
+ * @return 0 if report ic type info successfully, error line number otherwise
+*/
+uint32_t dfu_report_target_ic_type(uint16_t image_id, uint8_t *p_ic_type);
+
+/**
+ * @brief report specified FW info and current OTA offset.
+ * @param image_id image_id to identify FW.
+ * @param p_origin_fw_version To store current FW version.
+ * @param p_offset To store current file offset.
+ * @return 0 if report FW info successfully, error line number otherwise
+*/
+uint32_t dfu_report_target_fw_info(uint16_t image_id, uint32_t *p_origin_fw_version,
+ uint32_t *p_offset);
+
+/**
+* @brief calculate checksum of length of buffer in flash.
+* @param image_id image_id to identify FW.
+* @param offset offset of the image.
+* @param length length of data.
+* @param crc_val ret crc value point.
+* @return 0 if buffer checksum calcs successfully, error line number otherwise
+*/
+uint32_t dfu_check_buf_crc(uint8_t *buf, uint32_t length, uint16_t crc_val);
+
+
+/**
+ * @brief unlock flash is need when erase or write flash.
+*/
+bool unlock_flash_bp_all(void);
+
+/**
+ * @brief lock flash after erase or write flash.
+*/
+void lock_flash_bp(void);
+/**
+ * @brief erase a sector of the flash, will retry three times at most
+ * @param image_id image_id to identify FW.
+ * @param offset offset of the image.
+ * @return 0 if erase successfully, error line number otherwise,
+*/
+uint32_t dfu_flash_erase_sector_with_retry(uint16_t image_id, uint32_t offset);
+
+
+/**
+ * @brief write specified image data with specified length to flash
+ * @param image_id image_id to identify FW.
+ * @param offset offset of the image.
+ * @param length length of data.
+ * @param p_void pointer to data.
+ * @return 0 if write FW image successfully, error line number otherwise
+*/
+uint32_t dfu_update(uint16_t image_id, uint32_t offset, uint32_t length,
+ uint32_t *p_void, bool is_new_image);
+
+
+/**
+ * @brief calculate checksum of the image and compare with given checksum value.
+ * @param image_id image_id to identify image.
+ * @return true if the image integrity check passes, false otherwise
+*/
+bool dfu_check_checksum(uint16_t image_id, uint32_t offset);
+
+
+void dfu_set_image_ready(T_IMG_CTRL_HEADER_FORMAT *p_header);
+
+
+/**
+ * @brief copy appdata from active bank to updating bank.
+ * @param image_id image_id to identify image.
+ * @param dlAddress address the img copy to.
+ * @param dlSize copy size.
+ * @return true if the image copied success, false otherwise
+*/
+bool dfu_copy_img(uint16_t image_id, uint32_t dlAddress, uint32_t dlSize);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+
+
+#endif //DFU_FLASH_H
diff --git a/inc/platform/dlps.h b/inc/platform/dlps.h
new file mode 100644
index 0000000..fcec3ac
--- /dev/null
+++ b/inc/platform/dlps.h
@@ -0,0 +1,360 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file dlps.h
+ * @brief DLPS implementation head file.
+ * @author lory_xu
+ * @date 2014-08-05
+ * @version v1.0
+ * *************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ * *************************************************************************************
+ */
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef __DLPS_H
+#define __DLPS_H
+
+
+/*============================================================================*
+ * Header Files
+*============================================================================*/
+#include <stdint.h>
+#include <stdbool.h>
+#include "os_queue.h"
+#include "otp.h"
+#include "system_rtl876x.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+
+/** @defgroup DLPS_PLATFORM DLPS Platform
+ * @brief Deep low power state support
+ * @{
+ */
+
+/*============================================================================*
+ * Types
+*============================================================================*/
+/** @defgroup DLPS_PLATFORM_Exported_Types DLPS Platform Exported Types
+ * @{
+ */
+
+/** @brief This CB is used for any module which needs to be checked before entering DLPS */
+typedef bool (*DLPSEnterCheckFunc)();
+
+/** @brief This CB is used for any module which needs to control the hw before entering or after exiting from DLPS */
+typedef void (*DLPSHWControlFunc)();
+
+/*============================================================================*
+ * Platform Unit
+*============================================================================*/
+
+/** @brief PlatformPMStage struct */
+typedef enum
+{
+ PLATFORM_PM_CHECK = 0,
+ PLATFORM_PM_STORE = 1,
+ PLATFORM_PM_ENTER = 2,
+ PLATFORM_PM_EXIT = 3,
+ PLATFORM_PM_RESTORE = 4,
+ PLATFORM_PM_PEND = 5,
+} PlatformPMStage;
+
+
+/** @brief PlatformPowerMode struct */
+typedef enum
+{
+ PLATFORM_POWERDOWN = 1, /**< Power down */
+ PLATFORM_DLPS_PFM = 2, /**< DLPS (PFM) */
+ PLATFORM_DLPS_RET = 3, /**< DLPS (RET) */
+ PLATFORM_ACTIVE = 5, /**< Active */
+} PlatformPowerMode;
+
+typedef enum
+{
+ PLATFORM_PM_WAKEUP_UNKNOWN = 0x0000,
+ PLATFORM_PM_WAKEUP_USER = 0x0001,
+ PLATFORM_PM_WAKEUP_OS = 0x0002,
+ PLATFORM_PM_WAKEUP_PRE_SYSTEM_LEVEL = 0x0003,
+ PLATFORM_PM_WAKEUP_PF_RTC = 0x0100,
+ PLATFORM_PM_WAKEUP_RTC = 0x0200,
+ PLATFORM_PM_WAKEUP_MAC = 0x0400,
+ PLATFORM_PM_WAKEUP_GPIO = 0x0800,
+ PLATFORM_PM_WAKEUP_CTC = 0x1000,
+} PlatformWakeupReason;
+
+typedef enum
+{
+ PLATFORM_PM_ERROR_UNKNOWN = 0x0,
+ PLATFORM_PM_ERROR_POWER_MODE = 0x1,
+ PLATFORM_PM_ERROR_DISABLE_DLPS_TIME = 0x2,
+ PLATFORM_PM_ERROR_32K_CHECK_LOCK = 0x3,
+ PLATFORM_PM_ERROR_LOG_DMA_NOT_IDLE = 0x4,
+ PLATFORM_PM_ERROR_CALLBACK_CHECK = 0x5,
+ PLATFORM_PM_ERROR_INTERRUPT_OCCURRED = 0x6,
+ PLATFORM_PM_ERROR_WAKEUP_TIME = 0x7,
+ PLATFORM_PM_ERROR_DATA_UART = 0x8,
+} PlatformPowerModeErrorCode;
+
+typedef enum
+{
+ BTMAC_PM_WAKEUP_UNKNOWN = 0x0,
+ BTMAC_PM_WAKEUP_LEGACY = 0x1,
+ BTMAC_PM_WAKEUP_LE = 0x2,
+ BTMAC_PM_WAKEUP_PRE_SYSTEM_LEVEL = 0x3,
+} BtmacWakeupReason;
+
+typedef enum
+{
+ BTMAC_PM_ERROR_UNKNOWN = 0x0,
+ BTMAC_PM_ERROR_POWER_MODE = 0x1,
+ BTMAC_PM_ERROR_ROLE_SWITCH = 0x3,
+ BTMAC_PM_ERROE_BQB = 0x4,
+ BTMAC_PM_ERROR_PSD = 0x5,
+ BTMAC_PM_ERROR_CSB_ENABLE = 0x6,
+ BTMAC_PM_ERROR_NOT_EMPTY_QUEUE_OF_LOWER = 0x7,
+ BTMAC_PM_ERROR_CONTROLLER_TO_HOST_BUSY = 0x8,
+ BTMAC_PM_ERROR_TX_BUSY = 0x9,
+ BTMAC_PM_ERROR_LE_REG_S_INST = 0xB,
+ BTMAC_PM_ERROR_ADV_STATE_NOT_IDLE = 0xC,
+ BTMAC_PM_ERROR_SCAN_STATE_NOT_IDLE = 0xD,
+ BTMAC_PM_ERROR_INITIATOR_UNIT_ENABLE = 0xE,
+ BTMAC_PM_ERROR_CHANNEL_MAP_UPDATE = 0xF,
+ BTMAC_PM_ERROR_CONNECTION_UPDATE = 0x10,
+ BTMAC_PM_ERROR_PHY_UPDATE = 0x11,
+ BTMAC_PM_ERROR_CONN_STATE_NOT_IDLE = 0x12,
+ BTMAC_PM_ERROR_LE_SCHE_NOT_READY = 0x13,
+ BTMAC_PM_ERROR_INTERRUPT_PENDING = 0x14,
+ BTMAC_PM_ERROR_WAKEUP_TIME = 0x15,
+ BTMAC_PM_ERROR_32K_CHECK_LOCK = 0x16,
+} BtmacPowerModeErrorCode;
+
+typedef enum
+{
+ NO_DATARAM_SHUTDOWN,
+ LAST_4K_DATARAM_SHUTDOWN, /**< 4k */
+ LAST_8K_DATARAM_SHUTDOWN, /**< 4k + 4k */
+ LAST_24K_DATARAM_SHUTDOWN, /**< 16k + 4k + 4k */
+ LAST_56K_DATARAM_SHUTDOWN /**< 32k + 16k + 4k + 4k */
+} DATARAM_SHUTDOWN_LEVEL;
+
+/*============================================================================*
+ * BTMAC Unit
+*============================================================================*/
+
+typedef enum
+{
+ BTMAC_DEEP_SLEEP = 0, /**< Deep sleep */
+ BTMAC_ACTIVE = 1, /**< Active */
+} BtmacPowerMode;
+
+/** @brief DLPS error code*/
+
+
+/** @} */ /* End of group DLPS_PLATFORM_Exported_Types */
+
+/*============================================================================*
+ * Variables
+*============================================================================*/
+/** @defgroup DLPS_PLATFORM_Exported_Variables DLPS Platform Exported Variables
+ * @{
+ */
+
+
+/** @} */ /* End of group DLPS_PLATFORM_Exported_Variables */
+
+/*============================================================================*
+ * Functions
+*============================================================================*/
+
+extern void platform_pm_set_power_mode(PlatformPowerMode pf_power_mode_user);
+extern PlatformPowerMode platform_pm_get_power_mode(void);
+extern void btmac_pm_set_power_mode(BtmacPowerMode bz_power_mode_user);
+extern void power_manager_suspend_all(void);
+extern void power_manager_resume_all(void);
+extern void platform_pm_register_callback_func(void *cb_func, PlatformPMStage pf_pm_stage);
+extern void platform_pm_get_statistics(uint32_t *wakeup_count, uint32_t *last_wakeup_clk,
+ uint32_t *last_sleep_clk);
+extern void btmac_pm_get_statistics(uint32_t *wakeup_count, uint32_t *last_wakeup_clk,
+ uint32_t *last_sleep_clk);
+extern void platform_pm_stop_all_non_excluded_timer(void);
+
+extern PlatformPowerModeErrorCode platform_pm_get_error_code(void);
+extern uint32_t *platform_pm_get_refuse_reason(void);
+extern PlatformWakeupReason platform_pm_get_wakeup_reason(void);
+
+extern BtmacPowerModeErrorCode btmac_pm_get_error_code(void);
+extern BtmacWakeupReason btmac_pm_get_wakeup_reason(void);
+/** @defgroup DLPS_PLATFORM_Exported_Functions DLPS Platform Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Register Check CB to DlpsPlatform which will call it before entering Dlps.
+ * @param func DLPSEnterCheckFunc
+ * @return Status of Operation.
+ * @retval true success
+ * @retval false fail
+*/
+static inline bool dlps_check_cb_reg(DLPSEnterCheckFunc func)
+{
+ platform_pm_register_callback_func(func, PLATFORM_PM_CHECK);
+ return true;
+}
+
+/**
+ * @brief Register HW Control CB to DlpsPlatform which will call it before entering Dlps or after exiting from Dlps (according to dlpsState) .
+ * @param func DLPSHWControlFunc
+ * @param dlpsState tell the DlpsPlatform the CB should be called when DLPS_ENTER or DLPS_EXITx_XXX.
+ * @return Status of Operation.
+ * @retval true success
+ * @retval false fail
+*/
+static inline bool dlps_hw_control_cb_reg(DLPSHWControlFunc func, PlatformPMStage dlpsState)
+{
+ platform_pm_register_callback_func(func, dlpsState);
+ return true;
+}
+
+/**
+ * @brief Keep platform in @ref LPM_ACTIVE_MODE which means will stop platform enter any lower power mode.
+ * @param none
+ * @return none
+*/
+static inline void lps_mode_pause(void)
+{
+ power_manager_suspend_all();
+}
+
+/**
+ * @brief Restore to original LPSMode.
+ * @param none
+ * @return none
+*/
+static inline void lps_mode_resume(void)
+{
+ power_manager_resume_all();
+}
+
+/**
+ * @brief Set active time after boot before entering into dlps
+ * @param active_time_ms time to keep active, unit ms
+ * @return none
+*/
+void set_boot_active_time(uint32_t active_time_ms);
+
+/**
+ * @brief LPSMode Set .
+ * @param mode LPSMode
+ * @return none
+*/
+static inline void lps_mode_set(PlatformPowerMode mode)
+{
+ btmac_pm_set_power_mode(BTMAC_DEEP_SLEEP);
+ platform_pm_set_power_mode(mode);
+}
+
+/**
+ * @brief LPSMode Get .
+ * @param none
+ * @return @ref LPSMode
+*/
+static inline PlatformPowerMode lps_mode_get(void)
+{
+ return platform_pm_get_power_mode();
+}
+
+/**
+ * @brief Return Pause LPSMode stack, only 0 can enter any low power mode.
+ * @param none
+ * @return stack num
+*/
+extern int8_t lps_mode_stack_get(void);
+
+/**
+ * @brief Return dlps wakeup counts .
+ * @param none
+ * @return count value
+*/
+static inline uint32_t lps_wakeup_count_get(void)
+{
+ uint32_t wakeup_count, last_wakeup_clk, last_sleep_clk;
+ platform_pm_get_statistics(&wakeup_count, &last_wakeup_clk, &last_sleep_clk);
+ return wakeup_count;
+}
+
+/**
+ * @brief Return dlps remain time.
+ * @param none
+ * @return dlps remain time with unit of us
+*/
+extern uint32_t last_lps_remain_us_get(void);
+
+/**
+ * @brief Set data ram to shut down instead of deep sleep when enter dlps to reduce power consumption.
+ Data ram(totol 88k) divides into 5 blocks: 32k + 32k + 16k + 4k + 4k.
+ * @param level
+ * @return none
+ */
+static inline void set_dataram_to_shutdown(DATARAM_SHUTDOWN_LEVEL level)
+{
+ switch (level)
+ {
+ case LAST_4K_DATARAM_SHUTDOWN:
+ {
+ OTP->ram_cfg[MEMCFG_DEEPSLEEP].mcu_data_sram = 0xf;
+ OTP->ram_cfg[MEMCFG_SHUTDOWN].mcu_data_sram = 0x10;
+ }
+ break;
+ case LAST_8K_DATARAM_SHUTDOWN:
+ {
+ OTP->ram_cfg[MEMCFG_DEEPSLEEP].mcu_data_sram = 0x7;
+ OTP->ram_cfg[MEMCFG_SHUTDOWN].mcu_data_sram = 0x18;
+ }
+ break;
+ case LAST_24K_DATARAM_SHUTDOWN:
+ {
+ OTP->ram_cfg[MEMCFG_DEEPSLEEP].mcu_data_sram = 0x3;
+ OTP->ram_cfg[MEMCFG_SHUTDOWN].mcu_data_sram = 0x1c;
+ }
+ break;
+ case LAST_56K_DATARAM_SHUTDOWN:
+ {
+ OTP->ram_cfg[MEMCFG_DEEPSLEEP].mcu_data_sram = 0x1;
+ OTP->ram_cfg[MEMCFG_SHUTDOWN].mcu_data_sram = 0x1e;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief LPSMode enter powerdown mode directly .
+ * @param none
+ * @return none
+*/
+static inline void lps_mode_enter_powerdown_directly(void)
+{
+ SystemCall(SYSTEM_CALL_ENTER_POWERDOWN_DIRECTLY, 0);
+}
+
+/** @} */ /* End of group DLPS_PLATFORM_Exported_Functions */
+
+/** @} */ /* End of group DLPS_PLATFORM */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DLPS_PLATFORM_H */
diff --git a/inc/platform/flash_adv_cfg.h b/inc/platform/flash_adv_cfg.h
new file mode 100644
index 0000000..2b45b51
--- /dev/null
+++ b/inc/platform/flash_adv_cfg.h
@@ -0,0 +1,154 @@
+/**
+****************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+****************************************************************************************************
+* @file flash_adv_cfg.h
+* @brief
+* @note flash advanced functions
+* @author Grace
+* @date 2018-04-19
+* @version v0.1
+* **************************************************************************************************
+*/
+
+#ifndef _FLASH_ADV_CFG_H_
+#define _FLASH_ADV_CFG_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "flash_device.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+/** @defgroup FLASH_DEVICE Flash Device
+ * @{
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup FLASH_DEVICE_Exported_Types Flash Device Exported Types
+ * @brief
+ * @{
+ */
+
+/** End of FLASH_DEVICE_Exported_Types
+ * @}
+ */
+/*************************************************************************************************
+ * Functions
+*************************************************************************************************/
+/** @defgroup FLASH_DEVICE_Exported_Functions Flash Device Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+* @brief get block protect level
+* @param *bp_lv a set of BPx ~ BP0
+* @return success or not
+*/
+bool flash_get_block_protect_locked(uint8_t *bp_lv);
+
+/**
+* @brief set block protect by map
+* @param bp_lv a set of BPx ~ BP0
+* @return success or not
+*/
+bool flash_set_block_protect_locked(uint8_t bp_lv);
+
+/**
+* @brief only unlock prefer section by addres
+* @param unlock_addr address section to be unlocked
+* @param *old_bp_lv before unlock
+* @return success or not
+*/
+bool flash_sw_protect_unlock_by_addr_locked(uint32_t unlock_addr, uint8_t *old_bp_lv);
+
+/**
+* @brief read vendor_id to switch callback
+* @return true if success
+* false if not support
+*/
+bool flash_otp_init(void);
+
+/**
+* @brief safe version of flash_otp_erase
+* @param type erase type
+* @param addr address to erase when erase block or sector
+* @return true if success
+*/
+bool flash_otp_erase_locked(T_ERASE_TYPE type, uint32_t addr);
+
+/**
+* @brief safe version of flash_otp_write
+* @param start_addr start_addr address where is going to be flash in flash
+* @param data_len data length to be program
+* @param data data buffer to be program into
+* @return true if success
+*/
+bool flash_otp_write_locked(uint32_t start_addr, uint32_t data_len, uint8_t *data);
+
+/**
+* @brief safe version of flash_otp_read
+* @param start_addr start_addr address where is going to be read in flash
+* @param data_len data length to be read
+* @param data data buffer to be read into
+* @return true if success
+*/
+bool flash_otp_read_locked(uint32_t start_addr, uint32_t data_len, uint8_t *data);
+
+/**
+* @brief safe version of flash_otp_enter
+* @return true if success
+*/
+bool flash_otp_enter_locked(void);
+
+/**
+* @brief safe version of flash_otp_exit
+* @return true if success
+*/
+bool flash_otp_exit_locked(void);
+
+/**
+* @brief safe version of flash_otp_set_lb
+* @return true if success
+*/
+bool flash_otp_set_lb_locked(void);
+
+/**
+* @brief safe version of flash_otp_get_lb
+* @return true if success
+*/
+bool flash_otp_get_lb_locked(void);
+
+/**
+ * @brief read SFDP data
+ * @param start_addr start_addr address in SFDP table
+ * @param data_len data length to be read
+ * @param data data buffer to be read into
+ * @return true if success
+*/
+bool flash_sfdp_read_locked(uint32_t start_addr, uint32_t data_len, uint8_t *data);
+
+/**
+ * @brief The quick user mode read (use split read to improve read speed)
+ * @param start_addr start_addr address where is going to be read in flash (4 byte aligned)
+ * @param data_len data length to be read
+ * @param data data buffer to be read into
+ * @return true if success
+*/
+bool flash_read_quick_locked(uint32_t start_addr, uint32_t data_len, uint8_t *data);
+
+/** @} */ /* End of group FLASH_DEVICE_Exported_Functions */
+
+
+/** @} */ /* End of group FLASH_DEVICE */
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _FLASH_ADV_CFG_H_
diff --git a/inc/platform/flash_device.h b/inc/platform/flash_device.h
new file mode 100644
index 0000000..a2e763a
--- /dev/null
+++ b/inc/platform/flash_device.h
@@ -0,0 +1,430 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file flash_device.h
+* @brief This file contains structures the functions regarding flash device.
+* @author Brenda_li
+* @date 2016-11-9
+* @version v1.0
+
+ ******************************************************************************
+ * @attention
+ *
+ * This module is a confidential and proprietary property of RealTek and
+ * possession or use of this module requires written permission of RealTek.
+ *
+ * Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+ ******************************************************************************
+ */
+
+/*****************************************************************************************
+* Introduction
+*****************************************************************************************
+* - Flash function would be split into two modules: flash_driver and flash_device
+* - flash_driver will handle flash_spic register to provide flash basic read/write function
+* - flash_device would provide flash layout or other functions.
+******************************************************************************************/
+#ifndef _FLASH_DEVICE_H
+#define _FLASH_DEVICE_H
+/*============================================================================*
+ * Header Files
+*============================================================================*/
+#include <stdbool.h>
+#include <stdint.h>
+
+/** @defgroup FLASH_DEVICE Flash Device
+ * @brief Flash image layout and APIs
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup FLASH_DEVICE_Exported_Macros Flash Device Exported Macros
+ * @brief
+ * @{
+ */
+#define FMC_PAGE_SIZE 0x1000
+#define FMC_SEC_SECTION_LEN (4 * 1024)
+#define FMC_BLK_SECTION_LEN (64 * 1024)
+#define FMC_ERASE_PATTERN (0xffffffff)
+
+#if (IC_TYPE == IC_TYPE_BEE3)
+#define FLASH_OFFSET_TO_NO_CACHE 0x01000000 /*!< memory offset between no cache and cache flash address */
+#elif (IC_TYPE == IC_TYPE_SBEE2)
+#define FLASH_OFFSET_TO_NO_CACHE 0x04000000
+#endif
+
+//leverage config signature from bee1
+#define SIGNATURE_CONFIG 0x8721bee2
+
+/******** bit definitions of hardfault configuration ********/
+#define BIT_ENABLE_SAVE_HARDFAULT 0x00000001 /* BIT0 */
+#define BIT_ENABLE_DUMP_HARDFAULT 0x00000004 /* BIT2 */
+#define BIT_CLEAR_HISTORY_AFTER_DUMP 0x00000008 /* BIT3 */
+#define BIT_CLEAR_HISTORY_BEFORE_SAVING 0x00000010 /* BIT4 */
+
+/** End of FLASH_DEVICE_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup FLASH_DEVICE_Exported_Types Flash Device Exported Types
+ * @brief
+ * @{
+ */
+
+/******************** flash erase type *******************
+FLASH_ERASE_CHIP: erase whole chip
+FLASH_ERASE_SECTOR: erase specified sector(page, 4K always)
+FLASH_ERASE_BLOCK: erase specified block(16 sector always)
+****************************************************************/
+typedef enum
+{
+ FLASH_ERASE_CHIP = 1, /*!<erase whole chip*/
+ FLASH_ERASE_SECTOR = 2, /*!<erase specified sector(page, 4K always)*/
+ FLASH_ERASE_BLOCK = 4, /*!<erase specified block(16 sector always)*/
+} T_ERASE_TYPE;
+
+typedef enum
+{
+ FLASH_SUCCESS = 1,
+ FLASH_NOT_SUPPORT = 0,
+ FLASH_ERROR_NOT_DEF = -1,
+ FLASH_ERROR_INVALID_INPUT = -2,
+ FLASH_ERROR_OUT_OF_RANGE = -3,
+ FLASH_ERROR_TIMEOUT = -4,
+ FLASH_NOT_EXIST = -5,
+ FLASH_CONFIG_FAILED = -6,
+ FLASH_CAL_FAILED = -7
+} T_FLASH_RET;
+
+
+typedef enum
+{
+ FLASH_EXIST_NONE = 0,
+ FLASH_EXIST_BASIC_CFG = 0x01,
+ FLASH_EXIST_ADV_CFG = 0x02,
+ FLASH_EXIST_QUERY_INFO = 0x04,
+ FLASH_EXIST_ALL = 0x07
+} T_FLASH_EXIST_LV;
+
+/******************** Access mode of DR register in user mode *******************/
+typedef enum
+{
+ FLASH_MODE_1BIT = 0,
+ FLASH_MODE_2BIT = 1,
+ FLASH_MODE_4BIT = 2
+} T_FLASH_MODE;
+
+typedef enum
+{
+ FLASH_DMA_AUTO_F2R = 0,
+ FLASH_DMA_AUTO_R2F,
+ FLASH_DMA_USER_F2R,
+ FLASH_DMA_USER_R2F
+} T_FLASH_DMA_TYPE;
+
+typedef enum
+{
+ FLASH_SCCD,
+ FLASH_OCCD,
+ FLASH_OTA_BANK_0,
+ FLASH_OTA_BANK_1,
+ FLASH_OTA_TMP,
+ FLASH_BKP_DATA1,
+ FLASH_BKP_DATA2,
+ FLASH_FTL,
+ FLASH_HARDFAULT_RECORD,
+ FLASH_TOTAL,
+} T_FLASH_LAYOUT_NAME;
+
+typedef enum
+{
+ flash_ioctl_get_size_main = 0x03,
+ flash_ioctl_rsvd0 = 0xD,
+ flash_ioctl_set_seq_trans_enable = 0x1008,
+ flash_ioctl_exec_flash_sw_reset = 0x3005,
+ flash_ioctl_app_base = 0x5000,
+ //add more here
+ flash_ioctl_time_consuming_test_for_Byte_Program,
+} T_IOCTL_CODE;
+
+typedef void (*FlashCB)(void);
+
+/** End of FLASH_DEVICE_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup FLASH_DEVICE_Exported_Variables Flash Device Exported Variables
+ * @brief
+ * @{
+ */
+
+extern void *flash_sem;
+
+/** End of FLASH_DEVICE_Exported_Variables
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup FLASH_DEVICE_Exported_Functions Flash Device Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief dump spic register for debug purpose
+ * @param none
+ * @return none
+*/
+extern void flash_dump_flash_info(void);
+
+/**
+ * @brief calculate crc based on given algorism
+ * @param data_p data buffer to calculate
+ * @param length length of data buffer
+ * @return crc value.
+*/
+extern unsigned short crc16(const unsigned char *data_p, unsigned int length);
+
+
+/**
+ * @brief get ota bank start address by signature in flash
+ * @param name name to specify which image
+ * @return bank address in flash
+*/
+extern uint32_t flash_get_bank_addr(T_FLASH_LAYOUT_NAME name);
+
+
+/**
+ * @brief get specific image bank size
+ * @param name name to specify which image
+ * @return bank size of specified image
+*/
+extern uint32_t flash_get_bank_size(T_FLASH_LAYOUT_NAME name);
+
+
+/**
+ * @brief vendor command interface for flash related control
+ * @param cmd command id
+ * @param param_1 parameter 1
+ * @param param_2 parameter 2
+ * @retval 0 if any error
+ * @retval otherwise return value back via return value
+ * @note add more ctrl code here if necessary
+*/
+extern uint32_t flash_ioctl(uint32_t cmd, uint32_t param_1, uint32_t param_2);
+
+
+/**
+ * @brief get flash_exists status
+ * @param none
+ * @return flash_exists
+*/
+extern T_FLASH_EXIST_LV flash_get_flash_exist(void);
+
+
+/**
+ * @brief erase flash with semaphore locked, it could be used for concorrent usage with other flash task.
+ * @param type erase type
+ * @param addr address to erase when erase block or sector
+ * @return access flash successfully or not
+ * @retval true succeed to access flash
+ * @retval false fail to access flash because other flash access is not finished
+ * @note not used in isr mode.
+*/
+extern bool flash_erase_locked(T_ERASE_TYPE type, uint32_t addr);
+
+/**
+ * @brief safe version of program bunch of data to flash via user mode
+ * @param start_addr start_addr address where is going to be flash in flash
+ * @param data_len data length to be program
+ * @param data data buffer to be program into
+ * @return access flash successfully or not
+ * @retval true succeed to access flash
+ * @retval false fail to access flash because other flash access is not finished
+*/
+extern bool flash_write_locked(uint32_t start_addr, uint32_t data_len, uint8_t *data);
+
+/**
+ * @brief safe version of program data to flash via auto mode with lock
+ * @param start_addr start_addr address where is going to be flash in flash
+ * @param data data to be program into
+ * @retval true succeed to access flash
+ * @retval false fail to access flash because other flash access is not finished
+ * @note
+ * 1. auto write is sync with auto read. so if your use auto read, this api is preferred
+ * 2. this API will not be interrupted by other flash operation
+ * 3. recommandate to use this other than flash_write
+*/
+extern bool flash_auto_write_locked(uint32_t start_addr, uint32_t data);
+
+/**
+ * @brief safe version of program bunch of data to flash via auto mode
+ * @param start_addr start_addr address where is going to be flash in flash
+ * @param data data to be program into
+ * @param len len of data buffer
+ * @retval true succeed to access flash
+ * @retval false fail to access flash because other flash access is not finished
+ * @note start address should be 4 byte align
+*/
+extern bool flash_auto_write_buffer_locked(uint32_t start_addr, uint32_t *data, uint32_t len);
+
+/**
+ * @brief safe version of flash_read
+ * @param start_addr start_addr address where is going to be read in flash
+ * @param data_len data length to be read
+ * @param data data buffer to be read into
+ * @retval true succeed to access flash
+ * @retval false fail to access flash because other flash access is not finished
+ * @note SPIC only supports SPIC_FIFO_SIZE FIFO, so max SPIC_FIFO_SIZE-4 bytes allowed to be written.
+ * auto mode performance is better than this function, and auto mode read is suggested.
+ * recommend to use auto read other than this api
+*/
+extern bool flash_read_locked(uint32_t start_addr, uint32_t data_len, uint8_t *data);
+
+/**
+ * @brief safe version of flash_auto_read
+ * @param addr address to read
+ * @param data data at addr
+ * @retval true succeed to access flash
+ * @retval false fail to access flash because other flash access is not finished
+*/
+extern bool flash_auto_read_locked(uint32_t addr, uint32_t *data);
+
+/**
+ * @brief safe version of flash_split_read
+ * @param start_addr start_addr address where is going to be read in flash
+ * @param data_len data length to be read
+ * @param data data buffer to be read into
+ * @param counter split counter to info that how many split times occur
+ * return 0xFFFFFFFF if not align 4
+ * @retval true succeed to access flash
+ * @retval false fail to access flash because other flash access is not finished
+ * @note In order to enhance throughput, only word align (4 bytes) is allowed to be written.
+ * auto mode performance is better than this function, and auto mode read is suggested.
+ * recommend to use auto read other than this api
+*/
+extern bool flash_split_read_locked(uint32_t start_addr, uint32_t data_len, uint8_t *data,
+ uint32_t *counter);
+
+/**
+ * @brief safe version of flash auto dma read
+ * @param dma_type identify user / auto mode and flash_2_ram / ram_2_flash
+ * @param flash_cb callback function after DMA transmit completed if need
+ * @param src_addr address where is going to be read in flash
+ * @param dst_addr address where is going to write data to
+ * @param data_len data length to be read
+ * @retval true succeed to access flash
+ * @retval false fail to access flash because other flash access is not finished
+ * @note @ref FLASH_GDMA_HANDLER() will be executed after flash transmit by DMA complete.
+*/
+extern bool flash_auto_dma_read_locked(T_FLASH_DMA_TYPE dma_type, FlashCB flash_cb,
+ uint32_t src_addr, uint32_t dst_addr, uint32_t data_len);
+
+/**
+ * @brief safe version of flash auto seqential transition dma read
+ * @param dma_type identify user / auto mode and flash_2_ram / ram_2_flash
+ * @param flash_cb callback function after DMA transmit completed if need
+ * @param src_addr address where is going to be read in flash
+ * @param dst_addr address where is going to write data to
+ * @param data_len data length to be read
+ * @retval true succeed to access flash
+ * @retval false fail to access flash because other flash access is not finished
+ * @note FLASH_GDMA_HANDLER() will be executed after flash transmit by DMA complete.
+*/
+extern bool flash_auto_seq_trans_dma_read_locked(T_FLASH_DMA_TYPE dma_type, FlashCB flash_cb,
+ uint32_t src_addr, uint32_t dst_addr, uint32_t data_len);
+
+/**
+ * @brief setup user split read by DMA + HW HSK
+ * @param flash_cb flash callback using dma
+ * @param start_addr start address to read
+ * @param dst_addr destination address of the read data
+ * @param data_len data length to be read
+ * @return
+*/
+extern bool flash_split_read_by_dma_locked(FlashCB flash_cb, uint32_t start_addr, uint32_t dst_addr,
+ uint32_t data_len);
+
+/**
+ * @brief set specific bit to specific address with flash lock mechanism
+ * @param addr specific address, should not be flash address!
+ * @param bit bit position to write
+ * @return none
+*/
+extern void flash_set_bit(uint32_t *addr, uint32_t bit);
+
+/**
+ * @brief check if specific bit has been set with flash lock mechanism.
+ * @param flag value to be checked
+ * @param bit bit position to check
+ * @retval true if specified bit position of the flag has been set
+ * @retval false otherwise
+*/
+extern bool flash_get_bit(uint32_t flag, uint32_t bit);
+
+
+/**
+* @brief get block protect level
+* @param *bp_lv a set of BPx ~ BP0
+* @return success or not
+*/
+extern bool flash_get_block_protect_locked(uint8_t *bp_lv);
+
+/**
+* @brief set block protect by map
+* @param bp_lv a set of BPx ~ BP0
+* @return success or not
+*/
+extern bool flash_set_block_protect_locked(uint8_t bp_lv);
+
+/**
+* @brief only unlock prefer section by addres
+* @param unlock_addr address section to be unlocked
+* @param *old_bp_lv before unlock
+* @return success or not
+*/
+extern bool flash_sw_protect_unlock_by_addr_locked(uint32_t unlock_addr, uint8_t *old_bp_lv);
+
+/**
+ * @brief flash try to switch to high speed bit mode
+ * @note switch back to 1 bit mode, if flash switch to high speed bit mode fail
+ * @param bit_mode config bit mode @ref T_FLASH_MODE
+ * @retval FLASH_SUCCESS success
+ * @retval others1 fail
+ */
+extern T_FLASH_RET flash_try_high_speed(T_FLASH_MODE bit_mode);
+
+#if (IC_TYPE == IC_TYPE_SBEE2)
+extern bool flash_ds_erase(T_ERASE_TYPE type, uint32_t addr);
+
+extern bool flash_ds_auto_write(uint32_t addr, uint32_t data);
+
+extern bool flash_ds_auto_read(uint32_t addr, uint32_t *data);
+
+extern bool flash_ds_write(uint32_t addr, uint32_t data_len, uint8_t *data);
+
+extern bool flash_ds_read(uint32_t addr, uint32_t data_len, uint8_t *data);
+#endif
+
+/** @} */ /* End of group FLASH_DEVICE_Exported_Functions */
+
+
+/** @} */ /* End of group FLASH_DEVICE */
+
+
+#endif //_FLASH_DEVICE_H
+
+
+
+
diff --git a/inc/platform/ftl.h b/inc/platform/ftl.h
new file mode 100644
index 0000000..231f9d9
--- /dev/null
+++ b/inc/platform/ftl.h
@@ -0,0 +1,159 @@
+/**
+****************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+****************************************************************************************************
+* @file ftl.h
+* @brief flash transport layer is used as abstraction layer for user application to save read/write
+* parameters in flash.
+* @note ftl is dedicate block in flash, only used for save read/write value, and offset here is
+* logical offset which is defined for whole ftl section.If value is only for one time read,
+* refer to fs_load_app_data_8 or other APIs in flash_device.h
+* @author Brenda_li
+* @date 2016-12-27
+* @version v1.0
+* **************************************************************************************************
+*/
+
+#ifndef _FTL_H_
+#define _FTL_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+/** @defgroup FTL Flash Transport Layer
+ * @brief simple implementation of file system for flash
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup FTL_Exported_Macros Flash Transport Layer Exported Macros
+ * @brief
+ * @{
+ */
+
+/** @defgroup FTL_WRITE_ERROR_CODE FTL Write Error Code
+ * @{
+ */
+#define FTL_WRITE_SUCCESS (0x00)
+#define FTL_WRITE_ERROR_IN_INTR (0x01) /**< can't write ftl in a interrupt */
+#define FTL_WRITE_ERROR_INVALID_ADDR (0x02) /**< logical addr is not 4byte align or exceed the max logical address */
+#define FTL_WRITE_ERROR_OUT_OF_SPACE (0x03) /**< ftl have no space for store new data */
+#define FTL_WRITE_ERROR_READ_BACK (0x04) /**< ftl write to flash error */
+#define FTL_WRITE_ERROR_VERIFY (0x05)
+#define FTL_WRITE_ERROR_INVALID_SIZE (0x06) /**< write length is not 4byte align */
+#define FTL_WRITE_ERROR_ERASE_FAIL (0x07) /**< flash erase fail result in ftl write fail */
+#define FTL_WRITE_ERROR_NOT_INIT (0x08) /**< write ftl too early before ftl init */
+#define FTL_WRITE_ERROR_NEED_GC (0x09) /**< ftl_only_gc_in_idle is opened */
+/**
+ * @}
+ */
+
+/** @defgroup FTL_READ_ERROR_CODE FTL Read Error Code
+* @{
+*/
+#define FTL_READ_SUCCESS (0x00)
+#define FTL_READ_ERROR_INVALID_LOGICAL_ADDR (0x01) /**< logical addr is not 4byte align or exceed the max logical address */
+#define FTL_READ_ERROR_READ_NOT_FOUND (0x02) /**< logical addr never be wrote so that can't found */
+#define FTL_READ_ERROR_PARSE_ERROR (0x03) /**< recorded logical addr is changed even though crc check pass*/
+#define FTL_READ_ERROR_INVALID_SIZE (0x04) /**< read length is not 4byte align */
+#define FTL_READ_ERROR_NOT_INIT (0x05) /**< read ftl too early before ftl init */
+#define FTL_READ_ERROR_CRC_CHECK_FAIL (0x06) /**< crc check fail */
+/**
+ * @}
+ */
+
+#define FTL_INIT_ERROR_ERASE_FAIL (0x01) /**< flash erase fail result in ftl init fail */
+#define FTL_INIT_ERROR_NOT_INIT (0x02) /**< ftl init fail because of empty function*/
+
+#define FTL_IOCTL_ERROR_NOT_INIT (0x01) /**< ftl ioctl fail because of empty function*/
+/** End of FTL_Exported_Macros
+ * @}
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup FTL_Exported_Types Flash Transport Layer Exported Types
+ * @brief
+ * @{
+ */
+typedef enum
+{
+ FTL_IOCTL_DEBUG = 0, /**< IO code for ftl debug */
+ FTL_IOCTL_CLEAR_ALL = 2, /**< IO code for clear ftl section*/
+ FTL_IOCTL_ERASE_INVALID_PAGE = 3, /**< IO code to erase invalid page*/
+ FTL_IOCTL_ENABLE_GC_IN_IDLE = 4, /**< IO code to enable garbage collection in idle task*/
+ FTL_IOCTL_DISABLE_GC_IN_IDLE = 5, /**< IO code to disable garbage collection in idle task*/
+ FTL_IOCTL_DO_GC_IN_APP = 6, /**< IO code to do garbage collection in app*/
+} T_FTL_IOCTL_CODE;
+
+/** End of FTL_Exported_Types
+ * @}
+ */
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup FTL_Exported_Functions Flash Transport Layer Exported Functions
+ * @brief
+ * @{
+ */
+/**
+ * @brief Save specified value to specified ftl offset
+ * @param pdata specify data buffer
+ * @param offset specify FTL offset to store
+ * @arg Min: 0
+ * @arg Max: depend on configuried ftl size
+ * @param size size to store
+ * @arg Min: 4
+ * @arg Max: depend on configuried ftl size
+ * @return status
+ * @retval 0 status successful
+ * @retval otherwise fail
+ * @note FTL offset is pre-defined and no conflict
+ */
+uint32_t ftl_save(void *pdata, uint16_t offset, uint16_t size);
+
+/**
+ * @brief Load specified ftl offset parameter to specified buffer
+ * @param pdata specify data buffer
+ * @param offset specify FTL offset to load
+ * @arg Min: 0
+ * @arg Max: depend on configuried ftl size
+ * @param size size to load
+ * @arg Min: 4
+ * @arg Max: depend on configuried ftl size
+ * @return status
+ * @retval 0 status successful
+ * @retval otherwise fail
+ * @note FTL offset is pre-defined and no conflict
+ */
+uint32_t ftl_load(void *pdata, uint16_t offset, uint16_t size);
+
+
+/**
+ * @brief Control function entry for ftl
+ * @param cmd command code for different operation
+ * @param p1 command parameter @ref T_FTL_IOCTL_CODE
+ * @param p2 extended command parameters
+ * @return results of control
+ * @retval 0 status successful
+ * @retval otherwise fail
+ */
+uint32_t ftl_ioctl(uint32_t cmd, uint32_t p1, uint32_t p2);
+
+/** @} */ /* End of group FTL_Exported_Functions */
+
+
+/** @} */ /* End of group FTL */
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _FTL_H_
diff --git a/inc/platform/hw_aes.h b/inc/platform/hw_aes.h
new file mode 100644
index 0000000..98adf39
--- /dev/null
+++ b/inc/platform/hw_aes.h
@@ -0,0 +1,139 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hw_aes.h
+ * @brief HW aes apis abstracted for encryption related.
+ * @details AES encryption APIs which delivers HW implemented reliable and safe AES solution.
+ * @author Lory Xu
+ * @date 2017.5.17
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#ifndef HW_AES_H
+#define HW_AES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/** @defgroup HW_AES Hardware AES
+ * @brief API Sets for hardware AES engine
+ * @{
+ */
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup HW_AES_Exported_Types HW AES Exported Types
+ * @{
+ */
+
+/** @brief encryption zone for image encryption feature. */
+typedef enum
+{
+ ZONE0,
+ ZONE1,
+ ZONE_NOT_USED
+} T_PROTECT_ZONE;
+
+/** @brief AES mode definition for HW AES. */
+typedef enum
+{
+ AES_MODE_NONE,
+ AES_MODE_CBC,
+ AES_MODE_ECB,
+ AES_MODE_CFB,
+ AES_MODE_OFB,
+ AES_MODE_CTR
+} T_HW_AES_MODE;
+
+/** End of HW_AES_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup HW_AES_Exported_Functions HW AES Exported Functions
+ * @brief
+ * @{
+ */
+
+extern bool hw_aes_decrypt_16byte(uint8_t *input, uint8_t *output);
+
+/**
+ * @brief 128 bit AES encryption via DMA on speicified plain data and keys
+ * @param p_in specified plain data to be encrypted
+ * @param p_out output buffer to store encrypted data
+ * @param data_word_len input buffer length
+ * @param key key buffer
+ * @param iv initialization vector for AES CBC mode
+ * @param mode aes mode specified by @ref T_HW_AES_MODE
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note HWAES_DMA_RX_CH_NUM and HWAES_DMA_TX_CH_NUM DMA channels are occupied by this function
+ */
+bool hw_aes_encrypt128_use_dma(uint32_t *p_in, uint32_t *p_out, uint16_t data_word_len,
+ uint32_t *key, uint32_t *iv, T_HW_AES_MODE mode);
+/**
+ * @brief 128 bit AES decryption via DMA on speicified data and keys
+ * @param p_in specified encrypted data to be decrypted
+ * @param p_out output buffer to store plain data
+ * @param data_word_len input buffer length
+ * @param key key buffer
+ * @param iv initialization vector for AES CBC mode
+ * @param mode aes mode specified by @ref T_HW_AES_MODE
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note HWAES_DMA_RX_CH_NUM and HWAES_DMA_TX_CH_NUM DMA channels are occupied by this function
+ */
+bool hw_aes_decrypt128_use_dma(uint32_t *p_in, uint32_t *p_out, uint16_t data_word_len,
+ uint32_t *key, uint32_t *iv, T_HW_AES_MODE mode);
+/**
+ * @brief 256 bit AES encryption via DMA on speicified plain data and keys
+ * @param p_in specified plain data to be encrypted
+ * @param p_out output buffer to store encrypted data
+ * @param data_word_len input buffer length
+ * @param key key buffer
+ * @param iv initialization vector for AES CBC mode
+ * @param mode aes mode specified by @ref T_HW_AES_MODE
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note HWAES_DMA_RX_CH_NUM and HWAES_DMA_TX_CH_NUM DMA channels are occupied by this function
+ */
+bool hw_aes_encrypt256_use_dma(uint32_t *p_in, uint32_t *p_out, uint16_t data_word_len,
+ uint32_t *key, uint32_t *iv, T_HW_AES_MODE mode);
+/**
+ * @brief 256 bit AES decryption via DMA on speicified data and keys
+ * @param p_in specified encrypted data to be decrypted
+ * @param p_out output buffer to store plain data
+ * @param data_word_len input buffer length
+ * @param key key buffer
+ * @param iv initialization vector for AES CBC mode
+ * @param mode aes mode specified by @ref T_HW_AES_MODE
+ * @return encryption results
+ * @retval true successful
+ * @retval false fail
+ * @note HWAES_DMA_RX_CH_NUM and HWAES_DMA_TX_CH_NUM DMA channels are occupied by this function
+ */
+bool hw_aes_decrypt256_use_dma(uint32_t *p_in, uint32_t *p_out, uint16_t data_word_len,
+ uint32_t *key, uint32_t *iv, T_HW_AES_MODE mode);
+
+/** @} */ /* End of group HW_AES_Exported_Functions */
+
+
+/** @} */ /* End of group HW_AES */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/inc/platform/log_uart_dma.h b/inc/platform/log_uart_dma.h
new file mode 100644
index 0000000..d8c506c
--- /dev/null
+++ b/inc/platform/log_uart_dma.h
@@ -0,0 +1,86 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file log_uart_dma.h
+* @brief This file provides APIs of log uart with DMA channel.
+* @details
+* @author Lory Xu
+* @date 2016-01-11
+* @version v0.1
+*********************************************************************************************************
+*/
+
+#ifndef LOG_UART_DMA_H
+#define LOG_UART_DMA_H
+
+#include "pingpong_buffer.h"
+#include "rtl876x.h"
+#include "trace.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ LOG_DMA_STATE_IDLE = 0,
+ LOG_DMA_STATE_PROCESS_MCU,
+ LOG_DMA_STATE_PENDING_MCU,
+ LOG_DMA_STATE_MAX
+} T_LOG_DMA_STATE;
+
+typedef enum
+{
+ LOG_DMA_SIGNAL_MCU_REQUEST = 0,
+ LOG_DMA_SIGNAL_MCU_DONE,
+ LOG_DMA_SIGNAL_MAX
+} T_LOG_DMA_SIGNAL;
+
+typedef struct
+{
+ uint16_t MCU_LogMissed;
+ uint16_t PendedMCU_BufferSize;
+ uint8_t *PendedMCU_Buffer; /* MCU uses ping pong buffer */
+ volatile T_LOG_DMA_STATE State;
+ T_LOG_DMA_STATE LastState;
+} T_LOG_DMA_SM;
+
+typedef struct
+{
+ uint32_t ReadIndex; /* DSP uses ring buffer */
+ uint32_t WriteIndex;
+ uint8_t *Buffer;
+ uint16_t BufferSize; /* MCU uses ping pong buffer */
+ T_LOG_DMA_SIGNAL Signal;
+} T_LOG_DMA_EVT;
+
+#define LogDMA_StateTran(State_) (me->LastState = me->State, me->State = (State_))
+
+/* Config Log DMA Channel */
+#define LogDMAChannelNum 3
+#define LogDMAChannel GDMA_Channel3
+#define LogDMAIRQn GDMA0_Channel3_IRQn
+#define LogUartDMAIntrHandler GDMA0_Channel3_Handler
+
+extern PingpongBuffer *pMCU_PPB;
+extern T_LOG_DMA_SM *pLogDMA_SM;
+
+void LogUartDMAInit(void);
+void LogUartDMAStart(uint8_t *p_outputbuf, uint16_t output_size);
+void LogUartDMAIntrHandler(void);
+void LogUartDMAIdleHook(void);
+bool log_pm_check(void);
+
+void LogDMA_SM_Dispatch(T_LOG_DMA_SM *me, T_LOG_DMA_EVT const *e);
+
+__STATIC_INLINE void NEVER_HAPPEN(uint32_t line_no, T_LOG_DMA_SM *me, T_LOG_DMA_EVT const *e)
+{
+ OS_PRINT_WARN3("Line %d: Log SM Error: state: %d, signal: %d", line_no, me->State, e->Signal);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/inc/platform/mem_types.h b/inc/platform/mem_types.h
new file mode 100644
index 0000000..508e3f1
--- /dev/null
+++ b/inc/platform/mem_types.h
@@ -0,0 +1,49 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file Mem_types.h
+ * @brief define memory types for RAM
+ * @date 2017.6.6
+ * @version v1.0
+ * *************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ * *************************************************************************************
+ */
+
+#ifndef _MEM_TYPES_H_
+#define _MEM_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup MEM_CONFIG Memory Configure
+ * @{
+ */
+
+/*============================================================================*
+ * Types
+*============================================================================*/
+/** @defgroup MEM_CONFIG_Exported_Types Memory Configure Exported Types
+ * @{
+ */
+
+typedef enum
+{
+ RAM_TYPE_DATA_ON = 0,
+ RAM_TYPE_BUFFER_ON = 1,
+ RAM_TYPE_NUM = 2
+} RAM_TYPE;
+
+/** @} */ /* End of group MEM_TYPES_Exported_Types */
+
+/** @} */ /* End of group MEM_CONFIG */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MEM_TYPES_H_ */
diff --git a/inc/platform/otp.h b/inc/platform/otp.h
new file mode 100644
index 0000000..815a35d
--- /dev/null
+++ b/inc/platform/otp.h
@@ -0,0 +1,281 @@
+/**
+****************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+****************************************************************************************************
+* @file otp.h
+* @brief
+* @date 2018-04-04
+* @version v1.0
+* **************************************************************************************************
+*/
+
+#ifndef _OTP_H_
+#define _OTP_H_
+
+#include <stdint.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ OS_TICK_10MS = 0,
+ OS_TICK_5MS = 1,
+ OS_TICK_2MS = 2,
+ OS_TICK_1MS = 3,
+} OS_TICK;
+
+/**
+ * @struct EFUSE_RAM_CONFIG
+ * @brief RAM EFuse settings.
+ *
+ * Refer to EFUSE[0x].
+ */
+typedef struct EFUSE_RAM_CONFIG_
+{
+ uint32_t phy_retram: 1;
+ uint32_t cam: 2;
+ uint32_t cache: 9;
+ uint32_t mcu_data_sram: 5;
+ uint32_t mcu_buffer_sram: 2;
+ uint32_t reserved: 13;
+} __attribute__((packed)) EFUSE_RAM_CONFIG;
+
+enum
+{
+ MEMCFG_LOWPOWER, // active mode: set deep sleep
+ MEMCFG_UNUSED, // active mode: set shut down
+ MEMCFG_DEEPSLEEP, // lps/dlps mode: set deep sleep
+ MEMCFG_SHUTDOWN, // lps/dlps mode: set shut down
+ MEMCFG_MAX
+};
+
+/* OTP start addr: 0x00200164, size: 0x394 */
+typedef struct otp_struct
+{
+ uint8_t rsvd0[130]; //start addr:0x00200164
+ uint8_t timer_diff_threshold; //start addr:0x002001e6
+ uint8_t rsvd01[5]; //start addr:0x002001e7
+ uint8_t bw_rf_low_clk_frac; //0x002001ec, 0: 32768 Hz, 1: 32000 Hz
+ uint8_t rsvd02[207];
+
+ /*****************upper *********************/
+ /* start addr:0x002002bc,size:0x78*/
+ uint64_t trace_mask[4];
+ uint16_t stack_en: 1; //start addr:0x002002dc
+ uint16_t upper_rsvd1: 15;
+ uint8_t upper_rsvd2[86];
+ /****************end upper *******************/
+
+ /*****************boot_cfg *******************/
+ /* start addr:0x00200334, size:0x8*/
+ uint32_t SWD_ENABLE: 1;
+ uint32_t boot_cfg_rsvd1: 15;
+ uint8_t boot_cfg_rsvd2;
+ uint8_t bt_tx_power; // start addr:0x00200337
+ uint32_t boot_cfg_rsvd3;
+ /*************end boot_cfg *******************/
+
+ /*****************flash_cfg *******************/
+ /* start addr:0x0020033c,size:0x10*/
+ uint32_t flash_cfg_rsvd0: 27;
+ uint32_t is_support_deep_power_down: 1;
+ uint32_t rsvd: 1;
+ uint32_t data_byte_for_toggle_cs: 2;
+ uint32_t basic_cfg_from_otp: 1; /*!< basic configuration source ( 0: QVL; 1: OTP) */
+ uint32_t flash_wait_max; //0x00200340
+ uint32_t spic_wait_max; //0x00200344
+ uint8_t flash_cfg_rsvd1[4];
+
+ /*************end flash_cfg *******************/
+
+ /*****************flash_setting ***************/
+ /* start addr:0x0020034c,size:0x8 */
+ uint8_t bit_mode: 2;
+ uint8_t flash_setting_rsvd0: 6;
+ uint8_t flash_setting_rsvd1: 3;
+ uint8_t bp_enable : 1;
+ uint8_t bp_lv : 4;
+ uint8_t delay_10us_before_toggle_cs; //start addr:0x0020034e
+ uint8_t delay_10us_after_toggle_cs;
+ uint8_t disable_irq_lv: 3;
+ uint8_t read_turn_on_off_rf: 1;
+ uint8_t flash_setting_rsvd2: 4;
+ uint8_t flash_setting_rsvd3[2]; //start addr:0x00200351
+ uint8_t flash_dma_ch: 4;
+ uint8_t flash_setting_rsvd4: 4;
+ /*************end flash_setting *******************/
+
+ uint8_t pmu_cfg[15]; //start addr:0x00200354, size:0x24
+ uint8_t pmu_cfg_rsvd: 5;
+ uint8_t ldo_311_aux_power_domain: 3;
+ uint8_t pmu_cfg_rsvd2[20];
+
+ /*****************os_cfg *********************/
+ /* start addr: 0x00200378, size:0x1e,padding 2 bytes to ensure 4 bytes align */
+ uint8_t getStackHighWaterMark : 1; /* 0 for release version, 1 for debug version */
+ uint8_t checkForStackOverflow : 1; /* 0 for release version, 1 for debug version */
+ uint8_t printAllLogBeforeEnterDLPS : 1; /* 0 for release version, 1 for debug version */
+ uint8_t dumpMemoryWhenHardFaultOrWDG : 1; /* 0 for release version, 1 for debug version */
+ uint8_t dumpMemoryUsage : 1; /* 0 for release version, 1 for debug version */
+ uint8_t enableASSERT: 1; /* 0 for release version, 1 for debug version */
+ uint8_t cpu_sleep_en: 1; /* default = 1 */
+ uint8_t printDLPSCheckLog: 1; /* default = 0 */
+
+ uint8_t wdgConfigDivfactor; //addr=0x00200379, default = 31
+ uint8_t wdgConfigCntLimit : 4; /* refer to WDG_Config(), default = 15 */
+ uint8_t wdgEnableInRom : 1; /* 1 for release version, 0 for debug version */
+ uint8_t wdgResetInRom : 1; /* 1 for release version, 0 for debug version */
+ uint8_t wdgMode : 2; /* 0: interrupt CPU, 1: reset all but aon
+ 2: reset core domain, 3: reset all */
+
+ uint8_t timerMaxNumber; /* default = 0x20 */
+ uint8_t timerQueueLength; /* default = 0x20 */
+ uint8_t UseAliOS : 1;
+ uint8_t reserved : 7;
+ uint16_t dyn_malloc_task_stack_size;
+
+ uint32_t appDataAddr; //0x00200380
+ uint32_t appDataSize; //0x00200384
+ uint32_t heapDataONSize; //0x00200388
+ uint32_t heapBufferONSize; //0x0020038c
+
+ uint16_t idle_task_stack_size; /* measured in bytes, default 256 * 4 bytes */
+ uint16_t timer_task_stack_size; /* measured in bytes, default 256 * 4 bytes */
+ uint16_t lower_task_stack_size; /* measured in bytes, default 768 * 4 bytes */
+ uint8_t os_cfg_padding[2];
+ /****************end os_cfg *******************/
+
+ /****************platform config****************/
+ /* start addr: 0x00200398, size: 0xfe, padding size: 0x2 */
+ uint32_t logPin : 6; /* default = P0_3 */
+ uint32_t logChannel : 2; /* LogChannel_TypeDef: default is LOG_CHANNEL_LOG1_UART */
+ uint32_t logBaudRate : 4; /* UartBaudRate_TypeDef: default is BAUD_RATE_2000000 */
+ uint32_t platform_cfg_rsvd0 : 4;
+ uint32_t logDisable : 1; /* Disable all DBG_DIRECT and DBG_BUFFER log */
+ uint32_t dump_info_before_reset : 1;
+ uint32_t write_info_to_flash_before_reset : 1;
+ uint32_t platform_cfg_rsvd1 : 1;
+ uint32_t log_ram_type : 1;
+ uint32_t image_split_read : 1; /* using split read in image integrity check */
+ uint32_t ftl_mapping_table_ram_type : 1;
+ uint32_t ftl_enable_write_skip : 1; /*if enable, if read value equal write value will skip*/
+ uint32_t ftl_logic_addr_map_bit_num : 3; /*4bit by step, default value is 3 means 12bit*/
+ uint32_t platform_cfg_rsvd2 : 4;
+ uint32_t run_in_app : 1;
+ uint32_t aes_key[8]; /* for OTA encryption/decryption */
+ uint32_t reboot_record_address; // 0x002003bc
+
+ uint32_t reboot_record_item_limit_power_2 : 4; /* max number of reboot record (2^n), 0x002003c0*/
+ uint32_t platform_cfg_rsvd3: 12;
+ uint32_t wdgIP : 1; /* default = 0 */
+ uint32_t resetWhenHardFault : 1;
+ uint32_t log_ram_size : 3;
+ uint32_t hardfault_print_buf_log : 1;
+ uint32_t platform_cfg_rsvd4: 8;
+ uint32_t log_timestamp_src : 2;
+
+ uint32_t platform_cfg_rsvd5: 13; //adc_channel, 0x002003c4
+ uint32_t systick_clk_src: 1;
+ uint32_t platform_cfg_rsvd51: 12;
+ uint32_t ftl_use_mapping_table: 1;
+ uint32_t ftl_app_logical_addr_base: 3;
+ uint32_t ftl_only_gc_in_idle: 1;
+ uint32_t write_info_to_flash_when_hardfault: 1;
+
+ uint32_t systick_ext_clk_freq; //0x002003c8
+ uint32_t share_cache_ram_reg; //0x002003cc
+ uint32_t ftl_real_logic_addr_size; /* FTL real logic address size */
+
+ uint32_t Version; //start addr: 0x002003d4, size = 0x50
+ uint32_t Info; // flash info
+ uint32_t PageSize;
+ uint32_t Main_Addr;
+ /*** flash layout table, 12 words***/
+ uint32_t ota_bank0_addr; //0x002003e4
+ uint32_t ota_bank0_size;
+ uint32_t ota_bank1_addr;
+ uint32_t ota_bank1_size;
+ uint32_t ftl_addr; //0x002003f4
+ uint32_t ftl_size;
+ uint32_t ota_tmp_addr;
+ uint32_t ota_tmp_size;
+ uint32_t bkp_data1_addr; //0x00200404
+ uint32_t bkp_data1_size;
+ uint32_t bkp_data2_addr;
+ uint32_t bkp_data2_size; //0x00200410
+ /***** end flash layout table*******/
+ uint32_t HardFault_Record_CFG;
+ uint32_t HardFault_Record_BegAddr;
+ uint32_t HardFault_Record_EndAddr;
+ uint8_t flash_info_tbl_rsvd1[3];
+ uint8_t flash_info_tbl_padding; //padding 1 byte
+
+ uint8_t flash_basic_cfg_rsvd[18]; // start addr: 0x00200424, size:0x12
+ uint8_t flash_adv_cfg_rsvd[12]; //start addr: 0x00200436 , size:0xc
+ uint8_t flash_query_info_rsvd[12]; // start addr: 0x00200442, size:0xc
+ uint8_t flash_spec_cfg_rsvd1[54]; //start addr: 0x0020044e ,size:0x36
+ uint32_t os_tick_rate_HZ;
+ uint8_t flash_spec_cfg_rsvd2[14];
+ uint8_t flash_padding[2];
+ /****************end platform config****************/
+
+ EFUSE_RAM_CONFIG ram_cfg[MEMCFG_MAX] __attribute__((aligned(
+ 4))); //start addr = 0x00200498, size=0x10
+ uint8_t phy_init_cfg_rsvd0[3]; //start addr = 0x002004a8, size=0x28
+ uint8_t tpm_max_txgain_LE1M; //start addr = 0x002004ab
+ uint8_t tpm_max_txgain_LE2M;
+ uint8_t tpm_max_txgain_LE2M_2402; //start addr = 0x002004ad
+ uint8_t tpm_max_txgain_LE2M_2480; //start addr = 0x002004ae
+ uint8_t phy_init_cfg_rsvd1[33];
+ uint8_t cap_touch_cfg_rsvd[48]; //start addr = 0x002004d0, size=0x30, padding 1byte
+
+ /*****************OTA Config *******************/
+ /* start addr:0x00200500, size:0x16*/
+ uint32_t ota_use_randon_address: 1;
+ uint32_t ota_adv_with_image_version: 1;
+ uint32_t ota_with_encryption_data: 1;
+ uint32_t ota_with_encryption_use_aes256: 1;
+ uint32_t ota_with_encryption_aes_type: 2;
+ uint32_t ota_resvd: 1;
+ uint32_t ota_link_loss_reset: 1;
+ uint32_t ota_use_buffer_check: 1;
+ uint32_t ota_rsrvd: 23;
+ uint8_t ota_rst_tgt_name[8];
+ uint8_t ota_timeout_total; //0x0020050c
+ uint8_t ota_timeout_wait4_conn;
+ uint8_t ota_timeout_wait4_image_transfer;
+ uint8_t ota_timeout_ctittv;
+ uint8_t ota_adv_random_address[6]; //end addr = 0x002004f6
+
+ /* start addr:0x00200516, size: 0x8*/
+ uint8_t clk_cfg_rsvd[12];
+} __attribute__((packed))T_OTP_CFG;
+/*end otp, addr = 0x00200522*/
+
+typedef enum
+{
+ EXTERNAL_CLOCK = 0,
+ CORE_CLOCK = 1
+} SYSTICK_CLK_SRC_TYPE;
+
+typedef enum
+{
+ ALWAYS_ACTIVE = 0,
+ AON_DOMAIN = 1,
+ PON_DOMAIN = 2,
+ CORE_DOMAIN = 4,
+ ALWAYS_INACTIVE = 6,
+} LDO_POWER_DOMAIN_TYPE;
+
+#define OTP_STRUCT_BASE 0x00200164UL
+#define OTP ((T_OTP_CFG *) OTP_STRUCT_BASE)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OTP_H_ */
+
diff --git a/inc/platform/overlay_mgr.h b/inc/platform/overlay_mgr.h
new file mode 100644
index 0000000..bb3febc
--- /dev/null
+++ b/inc/platform/overlay_mgr.h
@@ -0,0 +1,95 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file overlay_mgr.h
+ * @brief
+ * @author
+ * @date
+ * @version
+ ***************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2015 Realtek Semiconductor Corporation</center></h2>
+ ***************************************************************************************
+ */
+
+#ifndef _OVERLAY_MGR_H_
+#define _OVERLAY_MGR_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup OVERLAY_MANAGER Overlay Manager
+ * @{
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup OVERLAY_MANAGER_Exported_Types Overlay Manager Exported Types
+ * @{
+ */
+typedef enum
+{
+ OVERLAY_SCENARIO_BOOT_ONCE = 0,
+ OVERLAY_SCENARIO_B,
+ OVERLAY_SCENARIO_C,
+ OVERLAY_SCENARIO_NUM,
+} T_OVERLAY_SCENARIO_IDX;
+
+typedef struct
+{
+ char *signature;
+
+ void *load_ro_base;
+ void *load_rw_base;
+
+ void *image_ro_base;
+ void *image_rw_base;
+ void *image_zi_base;
+
+ uint32_t ro_length;
+ uint32_t rw_length;
+ uint32_t zi_length;
+} T_OVERLAY_SECTION;
+/** End of OVERLAY_MANAGER_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup OVERLAY_MANAGER_Exported_Functions Overlay Manager Exported Functions
+ * @brief
+ * @{
+ */
+/**
+ * @brief Load Code(RO), RW Data and ZI Data of a given overlay section.
+ * @param scenario_idx Overlay section index, support only three sections now.
+ * @return None
+ */
+bool load_overlay(T_OVERLAY_SCENARIO_IDX scenario_idx);
+
+/**
+ * @brief return the current scenario index
+ * @param none.
+ * @return @ref T_OVERLAY_SCENARIO_IDX
+ * @retval OVERLAY_SCENARIO_NUM, invalid scenario index
+ * @retval other T_OVERLAY_SCENARIO_IDX value, valid secnario index
+ */
+T_OVERLAY_SCENARIO_IDX get_current_scenario_index(void);
+
+/** @} */ /* End of group OVERLAY_MANAGER_Exported_Functions */
+
+
+/** @} */ /* End of group OVERLAY_MANAGER */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OVERLAY_MGR_H_ */
diff --git a/inc/platform/patch_header_check.h b/inc/platform/patch_header_check.h
new file mode 100644
index 0000000..f5a4b5c
--- /dev/null
+++ b/inc/platform/patch_header_check.h
@@ -0,0 +1,330 @@
+/**
+ ******************************************************************************
+ * @file patch_header_check.h
+ * @author
+ * @version V0.0.1
+ * @date 2017-09-01
+ * @brief This file contains all the functions regarding patch header check.
+ ******************************************************************************
+ * @attention
+ *
+ * This module is a confidential and proprietary property of RealTek and
+ * possession or use of this module requires written permission of RealTek.
+ *
+ * Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+ ******************************************************************************
+ */
+
+#ifndef _PATCH_HEADER_CHECK_H_
+#define _PATCH_HEADER_CHECK_H_
+#include <stdbool.h>
+#include <stdint.h>
+#include "rtl876x.h"
+#include "flash_device.h"
+#include "rtl876x_ic_type.h"
+
+/** @addtogroup FLASH_DEVICE Flash Device
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @defgroup FLASH_DEVICE_Exported_Constants Flash Device Exported Constants
+ * @brief
+ * @{
+ */
+
+#define SIGNATURE_APP_CB 0x0e85d101 /**< patch callback app signature definition*/
+#define UUID_SIZE 16
+
+#define DEFINED_IC_TYPE IC_TYPE
+
+#define DFU_HEADER_SIZE 12 /*currently, first 12 byte only will be treated as image header*/
+#define IMG_HEADER_SIZE 1024
+
+#define UP_ALIGN(size, align) (((size) + (align) - 1) & ~(align - 1))
+
+
+/** End of FLASH_DEVICE_Exported_Constants
+ * @}
+ */
+
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup FLASH_DEVICE_Exported_Types Flash Device Exported Types
+ * @brief
+ * @{
+ */
+
+typedef enum
+{
+ IMAGE_FIRST = 0x278D,
+ SCCD = 0x278D,
+ OCCD = 0x278E,
+ FactoryCode = 0x278F,
+ OTA = 0x2790, /**< OTA header */
+ SecureBoot = 0x2791,
+ RomPatch = 0x2792,
+ AppPatch = 0x2793,
+ AppData1 = 0x2794,
+ AppData2 = 0x2795,
+ AppData3 = 0x2796,
+ AppData4 = 0x2797,
+ AppData5 = 0x2798,
+ AppData6 = 0x2799,
+ UpperStack = 0x279a,
+ IMAGE_MAX = 0x279b,
+ IMAGE_USER_DATA = 0xFFFE, /**<the image only support unsafe single bank ota*/
+} T_IMG_ID;
+
+typedef enum
+{
+ ENC_KEY_SCEK = 0,
+ ENC_KEY_SCEK_WITH_RTKCONST,
+ ENC_KEY_OCEK,
+ ENC_KEY_OCEK_WITH_OEMCONST,
+ ENC_KEY_ON_FLASH,
+ ENC_KEY_MAX,
+} T_ENC_KEY_SELECT;
+
+typedef struct
+{
+ uint8_t N[256];
+ uint8_t E[4];
+} T_RSA_PUBLIC_KEY;
+
+typedef enum _APP_IMAGE_TYPE
+{
+ IMAGE_NORMAL = 0,
+ IMAGE_COMPRESSED = 1,
+ //2-7 are reserved
+} T_IMAGE_TYPE;
+
+typedef struct
+{
+ uint8_t ic_type; //!< indicate different ic, bee2 is 5
+ uint8_t secure_version; //!< secure version info
+ union
+ {
+ uint16_t value;
+ struct
+ {
+ uint16_t xip: 1; //!< payload is executed on flash
+ uint16_t enc: 1; //!< all the payload is encrypted
+ uint16_t load_when_boot: 1; //!< load image when boot
+ uint16_t enc_load: 1; //!< encrypt load part or not
+ uint16_t enc_key_select: 3; //!< referenced to ENC_KEY_SELECT
+ uint16_t not_ready : 1; //!< for copy image in ota
+ uint16_t not_obsolete : 1; //!< for copy image in ota
+ uint16_t integrity_check_en_in_boot : 1; //!< enable image integrity check in boot flow
+ uint16_t compressed_not_ready: 1;
+ uint16_t compressed_not_obsolete: 1;
+ uint16_t rsvd: 1;
+ uint16_t image_type: 3; /*for app 000b: normal image, 001b:compressed image, other for more types
+ for patch in temp bank consist of 001b: patch+fsbl, 010b: patch+app, 011b: patch+fsbl+app*/
+ } flag_value;
+ } ctrl_flag;
+ uint16_t image_id; //!< indicate different image
+ uint16_t crc16; //!<when enable image integrity check in boot flow, crc16 check image integrity if crc16 is not zero, otherwise SHA256 check.
+ uint32_t payload_len; //!< image length in bytes exclude 1KB image header
+} T_IMG_CTRL_HEADER_FORMAT;
+
+typedef struct _COMPRESS_IMG_HEADER_FORMAT //96 bytes
+{
+ T_IMG_CTRL_HEADER_FORMAT ctrl_header; //12bytes
+ uint8_t uuid[16];
+ uint32_t version;
+ uint32_t compress_algo;
+ uint8_t sha256[32];
+ uint8_t reverved[28];
+} T_COMPRESS_IMG_HEADER_FORMAT;
+
+typedef struct
+{
+ union
+ {
+ uint32_t version;
+ struct
+ {
+ uint32_t _version_reserve: 8; //!< reserved
+ uint32_t _version_revision: 8; //!< revision version
+ uint32_t _version_minor: 8; //!< minor version
+ uint32_t _version_major: 8; //!< major version
+ } header_sub_version; //!< ota header sub version
+ struct
+ {
+ uint32_t _version_major: 4; //!< major version
+ uint32_t _version_minor: 8; //!< minor version
+ uint32_t _version_revision: 15; //!< revision version
+ uint32_t _version_reserve: 5; //!< reserved
+ } img_sub_version; //!< other image sub version including patch, app, app data1-6
+
+ } ver_info;
+} T_IMAGE_VERSION;
+
+typedef struct
+{
+ union
+ {
+ uint32_t version;
+ struct
+ {
+ uint32_t _version_major: 4; //!< major version
+ uint32_t _version_minor: 8; //!< minor version
+ uint32_t _version_revision: 15; //!< revision version
+ uint32_t _version_reserve: 5; //!< reserved
+ } sub_version;
+ } ver_info;
+ uint32_t _version_commitid; //!< git commit id
+ uint8_t _customer_name[8]; //!< branch name for customer patch
+} T_VERSION_FORMAT;
+
+typedef struct
+{
+ T_IMG_CTRL_HEADER_FORMAT ctrl_header;
+ uint8_t uuid[16];
+ uint32_t exe_base;
+ uint32_t load_base;
+ uint32_t load_len;
+ uint32_t image_base;
+ uint8_t rsvd0[4];
+ uint32_t magic_pattern;
+ uint8_t dec_key[16];
+ uint8_t rsvd1[28];
+ T_VERSION_FORMAT git_ver;
+ T_RSA_PUBLIC_KEY rsaPubKey;
+ uint8_t sha256[32];
+ uint8_t rsvd2[68];
+ uint32_t app_cb_signature;
+ uint32_t app_cb_table_base_address;
+} T_IMG_HEADER_FORMAT;
+
+typedef struct
+{
+ uint8_t payload_signature[256];
+ uint8_t payload_mac[16];
+ uint8_t header_signature[256];
+ uint8_t header_mac[16];
+
+} T_AUTH_HEADER_FORMAT;
+
+typedef struct
+{
+ T_IMG_CTRL_HEADER_FORMAT ctrl_header;
+ uint8_t uuid[16];
+ uint32_t exe_base;
+ uint32_t load_base;
+ uint8_t rsvd0[8];
+ uint16_t auto_enter_dfu_mode_pattern;
+ uint16_t single_bank_ota_pattern;
+ uint32_t magic_pattern;
+ uint8_t rsvd1[44];
+ T_VERSION_FORMAT git_ver;
+ T_RSA_PUBLIC_KEY rsaPubKey;
+ uint8_t sha256[32];
+ uint32_t ver_val;
+ uint32_t secure_boot_addr;
+ uint32_t secure_boot_size;
+ uint32_t rom_patch_addr;
+ uint32_t rom_patch_size;
+ uint32_t app_addr;
+ uint32_t app_size;
+ uint32_t app_data1_addr;
+ uint32_t app_data1_size;
+ uint32_t app_data2_addr;
+ uint32_t app_data2_size;
+ uint32_t app_data3_addr;
+ uint32_t app_data3_size;
+ uint32_t app_data4_addr;
+ uint32_t app_data4_size;
+ uint32_t app_data5_addr;
+ uint32_t app_data5_size;
+ uint32_t app_data6_addr;
+ uint32_t app_data6_size;
+} T_OTA_HEADER_FORMAT;
+
+
+/** End of FLASH_DEVICE_Exported_Types
+ * @}
+ */
+
+/*************************************************************************************************
+* functions
+*************************************************************************************************/
+/** @defgroup FLASH_DEVICE_Exported_Functions Flash Device Exported Functions
+ * @brief
+ * @{
+ */
+/**
+ * @brief get start address of active ota bank
+ * @param none
+ * @return start address of active ota bank
+*/
+extern uint32_t get_active_ota_bank_addr(void);
+
+/**
+ * @brief check configurated flash layout support bank switch
+ * @param none
+ * @retval true support bank switch
+ * @retval false otherwise
+*/
+extern bool is_ota_support_bank_switch(void);
+
+/**
+ * @brief calculated checksum(CRC16 or SHA256 determined by image) over the image, and compared
+ * with given checksum value.
+ * @param p_header image header info of the given image.
+ * @retval true if image integrity check pass via checksum compare
+ * @retval false otherwise
+*/
+extern bool check_image_chksum(T_IMG_CTRL_HEADER_FORMAT *p_header);
+/**
+ * @brief Check the validity of the specified image
+ * @param image_id specify the image
+ * @param header_addr specify image header address
+ * @retval true if image check pass
+ * @retval false otherwise
+*/
+extern bool check_header_valid(uint32_t header_addr, T_IMG_ID image_id);
+/**
+ * @brief get specified image header address in active bank
+ * @param image_id specify the image
+ * @return specified image header address
+*/
+extern uint32_t get_header_addr_by_img_id(T_IMG_ID image_id);
+
+/**
+ * @brief get image size of specified image which located in ota active bank
+ * @param image_id specify the image which located in ota active bank
+ * @return image size of specified image which located in ota active bank
+*/
+extern uint32_t get_active_bank_image_size_by_img_id(T_IMG_ID image_id);
+/**
+ * @brief get start address of specified image which located in ota temp bank
+ * @param image_id specify the image
+ * @return start address of specified image which located in ota temp bank
+*/
+extern uint32_t get_temp_ota_bank_addr_by_img_id(T_IMG_ID image_id);
+
+/**
+ * @brief get size of specified image which located in ota temp bank
+ * @param image_id specify the image
+ * @return size of specified image which located in ota temp bank
+*/
+extern uint32_t get_temp_ota_bank_size_by_img_id(T_IMG_ID image_id);
+
+/**
+ * @brief get version info of specified image which located in active bank
+ * @param image_id specify the image
+ * @return version info of specified image which located in active bank
+*/
+extern bool get_active_bank_image_version(T_IMG_ID image_id, T_IMAGE_VERSION *p_image_version);
+
+/** @} */ /* End of group FLASH_DEVICE_Exported_Functions */
+/** @} */ /* End of group FLASH_DEVICE */
+
+#endif // _PATCH_HEADER_CHECK_H_
diff --git a/inc/platform/pingpong_buffer.h b/inc/platform/pingpong_buffer.h
new file mode 100644
index 0000000..4da0c77
--- /dev/null
+++ b/inc/platform/pingpong_buffer.h
@@ -0,0 +1,85 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file pingpong_buffer.h
+* @brief This file provides APIs of PingPong Buffer.
+* @details
+* @author Lory Xu
+* @date 2015-12-20
+* @version v0.1
+*********************************************************************************************************
+*/
+
+#ifndef PINGPONG_BUFFER_H
+#define PINGPONG_BUFFER_H
+
+#include <stdint.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @brief LogMissedCounter records the number of log missed.
+ If the value is greater than 0, please reduce logs or speed up log uart/DMA.
+ */
+typedef struct
+{
+ uint8_t *pInputBuffer;
+ uint8_t *pOutputBuffer;
+ uint16_t InputBufferSize;
+ uint16_t OutputBufferSize;
+ uint32_t LogMissedCounter;
+ uint32_t MaxBufferSize;
+} PingpongBuffer;
+
+static inline uint32_t PPB_GetLogMissedCounter(PingpongBuffer *pPPB)
+{
+ return pPPB->LogMissedCounter;
+}
+
+static inline void PPB_ClearLogMissedCounter(PingpongBuffer *pPPB)
+{
+ pPPB->LogMissedCounter = 0;
+}
+
+static inline bool PPB_IsInit(PingpongBuffer *pPPB)
+{
+ return ((pPPB->pInputBuffer != NULL) && (pPPB->pOutputBuffer != NULL));
+}
+
+static inline bool PPB_IsOutputBufEmpty(PingpongBuffer *pPPB)
+{
+ return (pPPB->OutputBufferSize == 0);
+}
+
+static inline bool PPB_IsInputBufEmpty(PingpongBuffer *pPPB)
+{
+ return (pPPB->InputBufferSize == 0);
+}
+
+static inline uint16_t PPB_GetOutputBufSize(PingpongBuffer *pPPB)
+{
+ return pPPB->OutputBufferSize;
+}
+
+static inline uint16_t PPB_GetInputBufSize(PingpongBuffer *pPPB)
+{
+ return pPPB->InputBufferSize;
+}
+
+void PPB_Init(PingpongBuffer *pPPB);
+void PPB_Uninit(PingpongBuffer *pPPB);
+void PPB_Init_DLPS_Restore(PingpongBuffer *pPPB);
+void PPB_Write(PingpongBuffer *pPPB, const uint8_t *source, uint16_t size);
+void PPB_ClearOutputBuffer(PingpongBuffer *pPPB);
+void PPB_BufSwitch(PingpongBuffer *pPPB);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/inc/platform/platform_autoconf.h b/inc/platform/platform_autoconf.h
new file mode 100644
index 0000000..8d50f4b
--- /dev/null
+++ b/inc/platform/platform_autoconf.h
@@ -0,0 +1,48 @@
+/**
+************************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+************************************************************************************************************
+* @file platform_autoconf.h
+* @brief Platform configuration
+* @author
+* @date 2018-04-16
+* @version v0.1
+*************************************************************************************************************
+*/
+#ifndef _PLATFORM_AUTOCONF_H_
+#define _PLATFORM_AUTOCONF_H_
+
+
+/** @defgroup BUILD_CONFIGURATION Build Configuration
+ * @brief Platform build configuration
+ * @{
+ */
+
+//#define RELEASE_VERSION
+
+#ifdef RELEASE_VERSION
+#define CHECK_STACK_OVERFLOW_ENABLE 0
+#define CHECK_LOG_BUFFER_BEFORE_DLPS_ENABLE 0
+#define PLATFORM_ASSERT_ENABLE 0
+#define CONFIG_LOG_FUNCTION_ENABLE 0
+#define RUN_APP_IN_HCIMODE_ENABLE 0
+#define SUPPORT_FTL_IN_APP 0
+/*disable it if need reduce code size*/
+#define ENABLE_FULL_FEATURED_DIRECT_LOG 1
+#else
+#define CHECK_STACK_OVERFLOW_ENABLE 1
+#define CHECK_LOG_BUFFER_BEFORE_DLPS_ENABLE 1
+#define PLATFORM_ASSERT_ENABLE 1
+#define CONFIG_LOG_FUNCTION_ENABLE 1
+#define RUN_APP_IN_HCIMODE_ENABLE 0
+#define SUPPORT_FTL_IN_APP 0
+/*disable it if need reduce code size*/
+#define ENABLE_FULL_FEATURED_DIRECT_LOG 1
+#endif
+
+
+/** End of BUILD_CONFIGURATION
+ * @}
+ */
+
+#endif /* End of _PLATFORM_AUTOCONF_H_ */
diff --git a/inc/platform/platform_utils.h b/inc/platform/platform_utils.h
new file mode 100644
index 0000000..c946f4d
--- /dev/null
+++ b/inc/platform/platform_utils.h
@@ -0,0 +1,110 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+************************************************************************************************************
+ * @file platform_utils.h
+ * @brief utility helper function for user application
+ * @author lory_xu
+ * @date 2017-02
+ * @version v1.0
+ ***************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ ***************************************************************************************
+ */
+
+#ifndef _PLATFORM_UTILS_H_
+#define _PLATFORM_UTILS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*============================================================================*
+ * Header Files
+*============================================================================*/
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "rtl876x.h"
+/** @defgroup PLATFORM_UTILS Platform Utilities
+ * @brief Utility helper functions
+ * @{
+ */
+
+#if (PLATFORM_SUPPORT_CLOCK_MANAGER == 1)
+#include "clock_manager.h"
+#else
+#define CLOCK_100MHZ 100000000
+#define CLOCK_90MHZ 90000000
+#define CLOCK_40MHZ 40000000
+#define CLOCK_53MHZ 53333333
+#define CLOCK_80MHZ 80000000
+#define CLOCK_20MHZ 20000000
+#define CLOCK_10MHZ 10000000
+#define CLOCK_5MHZ 5000000
+#define CLOCK_2P5MHZ 2500000
+#define CLOCK_1P25MHZ 1250000
+#define CLOCK_625KHZ 625000
+#endif
+
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PLATFORM_UTILS_Exported_Functions Platform Utilities Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Generate random number given max number allowed
+ * @param max to specify max number that allowed
+ * @return random number
+ */
+
+extern uint32_t platform_random(uint32_t max);
+
+
+/**
+ * @brief Busy delay for specified millisecond
+ * @param t to specify t milliseconds to delay
+ * @return none
+ */
+extern volatile void (*platform_delay_ms)(uint32_t t);
+
+/**
+ * @brief Busy delay for specified micro second
+ * @param t to specify t micro seconds to delay
+ * @return none
+ */
+extern volatile void (*platform_delay_us)(uint32_t t);
+
+/**
+ * @brief Get the vendor timer tick
+
+ * @param none
+ * @return none
+ * @note Features of the vendor timer:
+ * (1) clock rate is 40M
+ * (2) width is 26 bits (max 0x3FFFFFF)
+ * (3) tick counter is incremental
+ *
+ */
+static inline uint32_t platform_vendor_tick(void)
+{
+ return HAL_READ32(VENDOR_REG_BASE, 0x30);
+}
+
+/** @} */ /* End of group PLATFORM_UTILS_Exported_Functions */
+
+/** @} */ /* End of group PLATFORM_UTILS */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/inc/platform/psram_platform.h b/inc/platform/psram_platform.h
new file mode 100644
index 0000000..7b7b6de
--- /dev/null
+++ b/inc/platform/psram_platform.h
@@ -0,0 +1,27 @@
+#ifndef _PSRAM_PLATFORM_H_
+#define _PSRAM_PLATFORM_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void psram_init(void);
+
+void psram_config(uint8_t bit_mode);
+
+void psram_try_high_speed(void);
+
+bool psram_read(uint32_t addr, uint32_t len, uint8_t *data);
+
+bool psram_write(uint32_t addr, uint32_t len, uint8_t *data);
+
+void psram_deinit(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PSRAM_PLATFORM_H_ */
diff --git a/inc/platform/qspi_lcd_platform.h b/inc/platform/qspi_lcd_platform.h
new file mode 100644
index 0000000..e4d9f48
--- /dev/null
+++ b/inc/platform/qspi_lcd_platform.h
@@ -0,0 +1,17 @@
+#ifndef _QSPI_LCD_PLATFORM_H_
+#define _QSPI_LCD_PLATFORM_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void qspi_lcd_platform_init(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _QSPI_LCD_PLATFORM_H_ */
diff --git a/inc/platform/readme b/inc/platform/readme
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/inc/platform/readme
diff --git a/inc/platform/rom_uuid.h b/inc/platform/rom_uuid.h
new file mode 100644
index 0000000..f46e6ad
--- /dev/null
+++ b/inc/platform/rom_uuid.h
@@ -0,0 +1,4 @@
+#ifndef _rom_uuid_h
+#define _rom_uuid_h
+#define DEFINE_rom_uuid { 0xf9,0x4c,0x6b,0x7e,0x11,0xc5,0xeb,0x11,0x82,0x82,0xf7,0x4a,0x0c,0x0c,0xef,0x5b }
+#endif
diff --git a/inc/platform/rtl876x.h b/inc/platform/rtl876x.h
new file mode 100644
index 0000000..4e9826d
--- /dev/null
+++ b/inc/platform/rtl876x.h
@@ -0,0 +1,3593 @@
+
+/**
+*****************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file rtl876x.h
+ * @brief CMSIS Cortex-M0+ Peripheral Access Layer Header File for
+ * RTL876X from Realtek Semiconductor.
+ * @date 2020.10.10
+ * @version v1.0
+
+ * @date 3. March 2015
+ *
+ * @note Generated with SVDConv Vx.xxp
+ * from CMSIS SVD File 'RTL876X.xml' Version x.xC,
+ *
+ * @par Copyright (c) 2020 Realtek Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Realtek Semiconductor.
+ * Terms and conditions of usage are described in detail in Realtek
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ *
+
+ * *************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2020 Realtek Semiconductor Corporation</center></h2>
+ * *************************************************************************************
+*/
+
+#ifndef RTL876X_H
+#define RTL876X_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @defgroup RTL876X Rtl876x
+ * @brief CMSIS Cortex-M0+ peripheral access layer header file for
+ * RTL876X from Realtek Semiconductor
+ * @{
+ */
+
+/*============================================================================*
+ * Types
+*============================================================================*/
+/** @defgroup RTL876x_Exported_types RTL876X Exported types
+ * @{
+ */
+
+/** brief Interrupt Number Definition */
+typedef enum IRQn
+{
+ /* ------------------- Cortex-M0+ Processor Exceptions Numbers ------------------- */
+ NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */
+ HardFault_IRQn = -13, /**< 3 HardFault Interrupt */
+ SVCall_IRQn = -5, /**< 11 SV Call Interrupt */
+ DebugMonitor_IRQn = -4, /**< 12 Debug Monitor Interrupt */
+ PendSV_IRQn = -2, /**< 14 Pend SV Interrupt */
+ SysTick_IRQn = -1, /**< 15 System Tick Interrupt */
+
+ System_IRQn = 0, /**< [0] System Interrupt */
+ WDG_IRQn, /**< [1] Watch Dog Interrupt */
+ BTMAC_IRQn, /**< [2] BTMAC Interrupt ( an Extension of interrupt ) */
+ Timer3_IRQn, /**< [3] Timer3 global interrupt */
+ Timer2_IRQn, /**< [4] Timer2 global interrupt */
+ Platform_IRQn, /**< [5] Platform error interrupt */
+ I2S0_RX_IRQn, /**< [6] I2S0 RX interrupt */
+ I2S0_TX_IRQn, /**< [7] I2S0 TX interrupt */
+ Timer4_5_IRQn, /**< [8] Timer 4 to 5 interrupt ( an Extension of interrupt ) */
+ GPIO4_IRQn, /**< [9] GPIO 4 interrupt */
+ GPIO5_IRQn, /**< [10] GPIO 5 interrupt */
+ UART1_IRQn, /**< [11] UART1 interrupt */
+ UART0_IRQn, /**< [12] UART0 interrupt */
+ RTC_IRQn, /**< [13] Realtime counter interrupt */
+ SPI0_IRQn, /**< [14] SPI0 interrupt */
+ SPI1_IRQn, /**< [15] SPI1 interrupt */
+ I2C0_IRQn, /**< [16] I2C0 interrupt */
+ I2C1_IRQn, /**< [17] I2C1 interrupt */
+ ADC_IRQn, /**< [18] ADC global interrupt */
+ Peripheral_IRQn, /**< [19] Peripheral Interrupt ( an Extension of interrupt ) */
+ GDMA0_Channel0_IRQn, /**< [20] RTK-DMA0 channel 0 global interrupt */
+ GDMA0_Channel1_IRQn, /**< [21] RTK-DMA0 channel 1 global interrupt */
+ GDMA0_Channel2_IRQn, /**< [22] RTK-DMA0 channel 2 global interrupt */
+ GDMA0_Channel3_IRQn, /**< [23] RTK-DMA0 channel 3 global interrupt */
+ ENHANCED_TIMER0_IRQn, /**< [24] Enhanced timer0 interrupt */
+ ENHANCED_TIMER1_IRQn, /**< [25] Enhanced timer1 interrupt */
+ GPIO_Group3_IRQn, /**< [26] GPIO Group3 Interrupt ( an Extension of interrupt ) */
+ GPIO_Group2_IRQn, /**< [27] GPIO Group2 Interrupt ( an Extension of interrupt ) */
+ IR_IRQn, /**< [28] IR Interrupt */
+ GPIO_Group1_IRQn, /**< [29] GPIO Group1 Interrupt ( an Extension of interrupt ) */
+ GPIO_Group0_IRQn, /**< [30] GPIO Group0 Interrupt ( an Extension of interrupt ) */
+ Reserved_IRQn, /**< [31] Reserved */
+ /****** Bee3 Extension Interrupt Numbers ************/
+ TIMER4_IRQ = 8,
+ TIMER5_IRQ = 8,
+ GPIO3_IRQn = 26,
+ GPIO7_IRQn = 26,
+ GPIO11_IRQn = 26,
+ GPIO15_IRQn = 26,
+ GPIO19_IRQn = 26,
+ GPIO23_IRQn = 26,
+ GPIO27_IRQn = 26,
+ GPIO31_IRQn = 26,
+ GPIO2_IRQn = 27,
+ GPIO6_IRQn = 27,
+ GPIO10_IRQn = 27,
+ GPIO14_IRQn = 27,
+ GPIO18_IRQn = 27,
+ GPIO22_IRQn = 27,
+ GPIO26_IRQn = 27,
+ GPIO30_IRQn = 27,
+ GPIO1_IRQn = 29,
+ GPIO9_IRQn = 29,
+ GPIO13_IRQn = 29,
+ GPIO17_IRQn = 29,
+ GPIO21_IRQn = 29,
+ GPIO25_IRQn = 29,
+ GPIO29_IRQn = 29,
+ GPIO0_IRQn = 30,
+ GPIO8_IRQn = 30,
+ GPIO12_IRQn = 30,
+ GPIO16_IRQn = 30,
+ GPIO20_IRQn = 30,
+ GPIO24_IRQn = 30,
+ GPIO28_IRQn = 30,
+ Peripheral_First_IRQn = 50,
+ SPIC0_IRQn = 50,
+ qdecode_IRQn = 51,
+ KeyScan_IRQn = 52,
+ SPI2W_IRQn = 53,
+ LPCOMP_IRQn = 54,
+ PTA_Mailbox_IRQn = 55,
+ CAP_TOUCH_IRQn = 56,
+ TRNG_IRQn = 57,
+} IRQn_Type, *PIRQn_Type;
+/** @} */ /* End of group RTL876x_Exported_types */
+
+/** @defgroup Configuration_of_CMSIS Configuration of CMSIS
+ * @brief Configuration of the cm4 Processor and Core Peripherals
+ * @{
+ */
+/* ----------------Configuration of the cm0+ Processor and Core Peripherals---------------- */
+#define __FPU_PRESENT 0 /* FPU present */
+#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */
+#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
+/** @} */ /* End of group Configuration_of_CMSIS */
+
+/*============================================================================*
+ * Header Files
+*============================================================================*/
+/* Processor and core peripherals */
+#include "core_cm0plus.h"
+#include "system_rtl876x.h"
+#include "rtl876x_ic_type.h"
+
+/*============================================================================*
+ * Types
+*============================================================================*/
+/** @addtogroup RTL876x_Exported_types RTL876X Exported types
+ * @{
+ */
+
+typedef enum
+{
+ RESET = 0,
+ SET = !RESET
+} FlagStatus, ITStatus;
+
+typedef enum
+{
+ DISABLE = 0,
+ ENABLE = !DISABLE
+} FunctionalState;
+
+#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
+//typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
+
+/** @} */ /* End of group RTL876x_Exported_types */
+
+
+/*============================================================================*
+ * RTL876X Pin Number
+*============================================================================*/
+/** @defgroup RTL876X_Pin_Number RTL876X Pin Number
+ * @{
+ */
+#if (IC_TYPE == IC_TYPE_BEE3)
+
+#define P0_0 0 /**<GPIO0 */
+#define P0_1 1 /**<GPIO1 */
+#define P0_2 2 /**<GPIO2 */
+#define P0_3 3 /**<GPIO3 */
+#define P0_4 4 /**<GPIO4 */
+#define P0_5 5 /**<GPIO5 */
+#define P0_6 6 /**<GPIO6 */
+#define P0_7 7 /**<GPIO7 */
+#define P1_0 8 /**<GPIO8 */
+#define P1_1 9 /**<GPIO9 */
+#define P1_3 11
+#define P1_4 12
+#define P1_6 14 /**<GPIO14 */
+#define P1_7 15 /**<GPIO15 */
+#define P2_0 16 /**<GPIO16 */
+#define P2_1 17 /**<GPIO17 */
+#define P2_2 18 /**<GPIO18 */
+#define P2_3 19 /**<GPIO19 */
+#define P2_4 20 /**<GPIO20 */
+#define P2_5 21 /**<GPIO21 */
+#define P2_6 22 /**<GPIO22 */
+#define P2_7 23 /**<GPIO23 */
+#define P3_0 24 /**<GPIO24 */
+#define P3_1 25 /**<GPIO25 */
+#define P3_2 26 /**<GPIO26 */
+#define P3_3 27 /**<GPIO27 */
+#define P3_4 28 /**<GPIO28 */
+#define P3_5 29 /**<GPIO29 */
+#define P3_6 30 /**<GPIO30 */
+#define P4_0 32 /**<GPIO13 */
+#define P4_1 33 /**<GPIO29 */
+#define P4_2 34 /**<GPIO30 */
+#define P4_3 35 /**<GPIO31 */
+#define H_0 36 /**<GPIO10 MICBIAS */
+#define P5_1 37 /**<GPIO11 */
+#define P5_2 38 /**<GPIO12 */
+
+#else
+
+#define P0_0 0 /**<GPIO0 */
+#define P0_1 1 /**<GPIO1 */
+#define P0_2 2 /**<GPIO2 */
+#define P0_3 3 /**<GPIO3 */
+#define P0_4 4 /**<GPIO4 */
+#define P0_5 5 /**<GPIO5 */
+#define P0_6 6 /**<GPIO6 */
+#define P0_7 7 /**<GPIO7 */
+#define P1_0 8 /**<GPIO8 */
+#define P1_1 9 /**<GPIO9 */
+#define P1_2 10 /**<GPIO10 */
+#define P1_3 11 /**<GPIO11 */
+#define P1_4 12 /**<GPIO12 */
+#define P1_5 13 /**<GPIO13 */
+#define P1_6 14 /**<GPIO14 */
+#define P1_7 15 /**<GPIO15 */
+#define P2_0 16 /**<GPIO16 */
+#define P2_1 17 /**<GPIO17 */
+#define P2_2 18 /**<GPIO18 */
+#define P2_3 19 /**<GPIO19 */
+#define P2_4 20 /**<GPIO20 */
+#define P2_5 21 /**<GPIO21 */
+#define P2_6 22 /**<GPIO22 */
+#define P2_7 23 /**<GPIO23 */
+#define P3_0 24 /**<GPIO24 */
+#define P3_1 25 /**<GPIO25 */
+#define P3_2 26 /**<GPIO26 */
+#define P3_3 27 /**<GPIO27 */
+#define P3_4 28 /**<GPIO28 */
+#define P3_5 29 /**<GPIO29 */
+#define P3_6 30 /**<GPIO30 */
+#define P4_0 32 /**<GPIO28 */
+#define P4_1 33 /**<GPIO29 */
+#define P4_2 34 /**<GPIO30 */
+#define P4_3 35 /**<GPIO31 */
+#define H_0 36 /**<GPIO25 MICBIAS */
+#define H_1 37 /**<GPIO26 32K_XI */
+#define H_2 38 /**<GPIO27 32K_XO */
+#endif
+
+/** @} */ /* End of group RTL876X_Pin_Number */
+
+
+/* ================================================================================ */
+/* ================ Peripheral Registers Structures Section ================ */
+/* ================================================================================ */
+
+/** @defgroup RTL876X_Peripheral_Registers_Structures RTL876X Register Structure
+ * @{
+ */
+
+/* ================================================================================ */
+/* ================ ADC ================ */
+/* ================================================================================ */
+
+/**
+ * @brief Analog to digital converter. (ADC)
+ */
+
+typedef struct /*!< ADC Structure */
+{
+ __O uint32_t FIFO; //!<0x00
+ __IO uint32_t CR; //!<0x04
+ __IO uint32_t SCHCR; //!<0x08
+ __IO uint32_t INTCR; //!<0x0C
+ __IO uint32_t SCHTAB0; //!<0x10
+ __IO uint32_t SCHTAB1; //!<0x14
+ __IO uint32_t SCHTAB2; //!<0x18
+ __IO uint32_t SCHTAB3; //!<0x1C
+ __IO uint32_t SCHTAB4; //!<0x20
+ __IO uint32_t SCHTAB5; //!<0x24
+ __IO uint32_t SCHTAB6; //!<0x28
+ __IO uint32_t SCHTAB7; //!<0x2C
+ __IO uint32_t SCHD0; //!<0x30
+ __IO uint32_t SCHD1; //!<0x34
+ __IO uint32_t SCHD2; //!<0x38
+ __IO uint32_t SCHD3; //!<0x3C
+ __IO uint32_t SCHD4; //!<0x40
+ __IO uint32_t SCHD5; //!<0x44
+ __IO uint32_t SCHD6; //!<0x48
+ __IO uint32_t SCHD7; //!<0x4C
+ __IO uint32_t PWRDLY; //!<0x50
+ __IO uint32_t DATCLK; //!<0x54
+ __IO uint32_t ANACTL; //!<0x58
+ __IO uint32_t SAMTIM; //!<0x5C
+
+} ADC_TypeDef;
+
+/* ================================================================================ */
+/* ================ CODEC ================ */
+/* ================================================================================ */
+
+typedef struct
+{
+ __IO uint32_t ANA_CR0; /*!< 0x00 */
+ __IO uint32_t ANA_CR1; /*!< 0x04 */
+ __IO uint32_t ANA_CR2; /*!< 0x08 */
+} CODEC_AnalogTypeDef;
+
+typedef struct
+{
+ __IO uint32_t CR0; /*!< 0x00 */
+ __IO uint32_t ANA_CR1; /*!< 0x04 */
+ __IO uint32_t CLK_CR1; /*!< 0x08 */
+ __IO uint32_t CLK_CR2; /*!< 0x0C */
+ __IO uint32_t CLK_CR3; /*!< 0x10 */
+ __IO uint32_t RSVD0[2];
+ __IO uint32_t I2S_CTRL; /*!< 0x1C */
+ __IO uint32_t ADC0_CTRL0; /*!< 0x20 */
+ __IO uint32_t ADC0_CTRL1; /*!< 0x24 */
+} CODEC_TypeDef;
+
+/* ================================================================================ */
+/* ================ CAP TOUCH ================ */
+/* ================================================================================ */
+
+typedef struct
+{
+ __IO uint32_t CR; /*!< 0x00 */
+ __IO uint32_t SCAN_PERIOD; /*!< 0x04 */
+ __IO uint32_t ETC_CR; /*!< 0x08 */
+ __IO uint32_t SNR_INF; /*!< 0x0C */
+ __IO uint32_t DEBUG_CR; /*!< 0x10 */
+ __IO uint32_t FIFO; /*!< 0x14 */
+ __IO uint32_t RAW_FIFO; /*!< 0x18 */
+ __IO uint32_t GUARD_CNT; /*!< 0x1C */
+ __IO uint32_t INT_EN; /*!< 0x20 */
+ __IO uint32_t INT_SR; /*!< 0x24 */
+ __IO uint32_t RAW_INT_SR; /*!< 0x28 */
+ __IO uint32_t RSVD0; /*!< 0x2C */
+ __IO uint32_t INT_CLR; /*!< 0x30 */
+ __IO uint32_t INT_SCLR; /*!< 0x34 */
+ __IO uint32_t RSVD1[2];
+ __IO uint32_t DBG_SEL; /*!< 0x40 */
+ __IO uint32_t DBG_PORT; /*!< 0x44 */
+ __IO uint32_t ECO_INF0; /*!< 0x48 */
+ __IO uint32_t ECO_INF1; /*!< 0x4C */
+ __IO uint32_t VERSION; /*!< 0x50 */
+} CTC_TypeDef;
+
+typedef struct
+{
+ __IO uint32_t CR; /*!< 0x00 */
+ __IO uint32_t TOUCH_TH; /*!< 0x04 */
+ __IO uint32_t MBIAS; /*!< 0x08 */
+ __IO uint32_t DATA; /*!< 0x0C */
+} CTC_ChannelTypeDef;
+
+typedef struct
+{
+ __IO uint32_t SCAN_INI; /*!< 0x00 */
+ __IO uint32_t SET_CNT; /*!< 0x04 */
+ __O uint32_t TOUCH_CNT01; /*!< 0x08 */
+ __O uint32_t TOUCH_CNT23; /*!< 0x0C */
+ __O uint32_t TOUCH_SR; /*!< 0x10 */
+} CTC_FSModeTypeDef;
+
+/* ================================================================================ */
+/* ================ GDMA ================ */
+/* ================================================================================ */
+/**
+ * @brief GDMA
+ */
+typedef struct
+{
+ __I uint32_t RAW_TFR;
+ uint32_t RSVD0;
+ __I uint32_t RAW_BLOCK;
+ uint32_t RSVD1;
+ __I uint32_t RAW_SRC_TRAN;
+ uint32_t RSVD2;
+ __I uint32_t RAW_DST_TRAN;
+ uint32_t RSVD3;
+ __I uint32_t RAW_ERR;
+ uint32_t RSVD4;
+
+ __I uint32_t STATUS_TFR;
+ uint32_t RSVD5;
+ __I uint32_t STATUS_BLOCK;
+ uint32_t RSVD6;
+ __I uint32_t STATUS_SRC_TRAN;
+ uint32_t RSVD7;
+ __I uint32_t STATUS_DST_TRAN;
+ uint32_t RSVD8;
+ __I uint32_t STATUS_ERR;
+ uint32_t RSVD9;
+
+ __IO uint32_t MASK_TFR;
+ uint32_t RSVD10;
+ __IO uint32_t MASK_BLOCK;
+ uint32_t RSVD11;
+ __IO uint32_t MASK_SRC_TRAN;
+ uint32_t RSVD12;
+ __IO uint32_t MASK_DST_TRAN;
+ uint32_t RSVD13;
+ __IO uint32_t MASK_ERR;
+ uint32_t RSVD14;
+
+ __O uint32_t CLEAR_TFR;
+ uint32_t RSVD15;
+ __O uint32_t CLEAR_BLOCK;
+ uint32_t RSVD16;
+ __O uint32_t CLEAR_SRC_TRAN;
+ uint32_t RSVD17;
+ __O uint32_t CLEAR_DST_TRAN;
+ uint32_t RSVD18;
+ __O uint32_t CLEAR_ERR;
+ uint32_t RSVD19;
+ __O uint32_t StatusInt;
+ uint32_t RSVD191;
+
+ __IO uint32_t ReqSrcReg;
+ uint32_t RSVD20;
+ __IO uint32_t ReqDstReg;
+ uint32_t RSVD21;
+ __IO uint32_t SglReqSrcReg;
+ uint32_t RSVD22;
+ __IO uint32_t SglReqDstReg;
+ uint32_t RSVD23;
+ __IO uint32_t LstSrcReg;
+ uint32_t RSVD24;
+ __IO uint32_t LstDstReg;
+ uint32_t RSVD25;
+
+ __IO uint32_t DmaCfgReg;
+ uint32_t RSVD26;
+ __IO uint32_t ChEnReg;
+ uint32_t RSVD27;
+ __I uint32_t DmaIdReg;
+ uint32_t RSVD28;
+ __IO uint32_t DmaTestReg;
+ uint32_t RSVD29;
+} GDMA_TypeDef;
+
+typedef struct
+{
+ __IO uint32_t SAR;
+ uint32_t RSVD0;
+ __IO uint32_t DAR;
+ uint32_t RSVD1;
+ __IO uint32_t LLP;
+ uint32_t RSVD2;
+ __IO uint32_t CTL_LOW;
+ __IO uint32_t CTL_HIGH;
+ __IO uint32_t SSTAT;
+ uint32_t RSVD4;
+ __IO uint32_t DSTAT;
+ uint32_t RSVD5;
+ __IO uint32_t SSTATAR;
+ uint32_t RSVD6;
+ __IO uint32_t DSTATAR;
+ uint32_t RSVD7;
+ __IO uint32_t CFG_LOW;
+ __IO uint32_t CFG_HIGH;
+ __IO uint32_t SGR;
+ uint32_t RSVD9;
+ __IO uint32_t DSR;
+ uint32_t RSVD10;
+} GDMA_ChannelTypeDef;
+
+/* ================================================================================ */
+/* ================ GPIO ================ */
+/* ================================================================================ */
+
+/**
+ * @brief General purpose input and output. (GPIO)
+ */
+
+typedef struct
+{
+ __IO uint32_t DATAOUT; /*!< Data register: data output */
+ __IO uint32_t DATADIR; /*!< Data direction register */
+ __IO uint32_t DATASRC; /*!< Data source register */
+ uint32_t RSVD[9];
+ __IO uint32_t INTEN; /*!< Interrupt enable register */
+ __IO uint32_t INTMASK; /*!< Interrupt mask register */
+ __IO uint32_t INTTYPE; /*!< Interrupt level register */
+ __IO uint32_t INTPOLARITY; /*!< Interrupt polarity register */
+ __IO uint32_t INTSTATUS; /*!< Interrupt status of Port A */
+ __IO uint32_t RAWINTSTATUS; /*!< Raw interrupt status of Port A (premasking) */
+ __IO uint32_t DEBOUNCE; /*!< Debounce enable register */
+ __O uint32_t INTCLR; /*!< clear interrupt register */
+ __I uint32_t DATAIN; /*!< external port register */
+ uint32_t RSVD1[3];
+ __IO uint32_t LSSYNC; /*!< Level-sensitive synchronization enable register*/
+ __I uint32_t IDCODE; /*!< ID code register */
+ __IO uint32_t INTBOTHEDGE; /*!< Both edge to trigger interrupt*/
+} GPIO_TypeDef;
+
+/* ================================================================================ */
+/* ================ I2C ================= */
+/* ================================================================================ */
+
+/**
+ * @brief I2C
+ */
+typedef struct
+{
+ __IO uint32_t IC_CON;
+ __IO uint32_t IC_TAR;
+ __IO uint32_t IC_SAR;
+ __IO uint32_t IC_HS_MADDR;
+ __IO uint32_t IC_DATA_CMD;
+ __IO uint32_t IC_SS_SCL_HCNT;
+ __IO uint32_t IC_SS_SCL_LCNT;
+ __IO uint32_t IC_FS_SCL_HCNT;
+ __IO uint32_t IC_FS_SCL_LCNT;
+ __IO uint32_t IC_HS_SCL_HCNT;
+ __IO uint32_t IC_HS_SCL_LCNT;
+ __I uint32_t IC_INTR_STAT;
+ __IO uint32_t IC_INTR_MASK;
+ __I uint32_t IC_RAW_INTR_STAT;
+ __IO uint32_t IC_RX_TL;
+ __IO uint32_t IC_TX_TL;
+ __I uint32_t IC_CLR_INTR;
+ __I uint32_t IC_CLR_RX_UNDER;
+ __I uint32_t IC_CLR_RX_OVER;
+ __I uint32_t IC_CLR_TX_OVER;
+ __I uint32_t IC_CLR_RD_REQ;
+ __I uint32_t IC_CLR_TX_ABRT;
+ __I uint32_t IC_CLR_RX_DONE;
+ __I uint32_t IC_CLR_ACTIVITY;
+ __I uint32_t IC_CLR_STOP_DET;
+ __I uint32_t IC_CLR_START_DET;
+ __I uint32_t IC_CLR_GEN_CALL;
+ __IO uint32_t IC_ENABLE;
+ __I uint32_t IC_STATUS;
+ __I uint32_t IC_TXFLR;
+ __I uint32_t IC_RXFLR;
+ __IO uint32_t IC_SDA_HOLD;
+ __I uint32_t IC_TX_ABRT_SOURCE;
+ __IO uint32_t IC_SLV_DATA_NACK_ONLY;
+ __IO uint32_t IC_DMA_CR;
+ __IO uint32_t IC_DMA_TDLR;
+ __IO uint32_t IC_DMA_RDLR;
+ __IO uint32_t IC_SDA_SETUP;
+ __IO uint32_t IC_ACK_GENERAL_CALL;
+ __IO uint32_t IC_ENABLE_STATUS;
+} I2C_TypeDef;
+
+/* ================================================================================ */
+/* ================ I2S ================= */
+/* ================================================================================ */
+
+/**
+ * @brief I2S
+ */
+typedef struct
+{
+ __O uint32_t TX_DR; /*!< 0x00 */
+ __IO uint32_t CTRL0; /*!< 0x04 */
+ __IO uint32_t CTRL1; /*!< 0x08 */
+ __IO uint32_t DSP_INT_CR; /*!< 0x0C */
+ __I uint32_t RX_DR; /*!< 0x10 */
+ __I uint32_t FIFO_SR; /*!< 0x14 */
+ __IO uint32_t ERROR_CNT_SR; /*!< 0x18 */
+ __IO uint32_t BCLK_DIV; /*!< 0x1C */
+ __IO uint32_t DMA_TRDLR; /*!< 0x20 */
+ __I uint32_t SR; /*!< 0x24 */
+} I2S_TypeDef;
+
+/* ================================================================================ */
+/* ================ IR ================ */
+/* ================================================================================ */
+
+/**
+ * @brief IR.
+ */
+
+typedef struct
+{
+ __IO uint32_t CLK_DIV; /*!< 0x00 */
+ __IO uint32_t TX_CONFIG; /*!< 0x04 */
+ __IO uint32_t TX_SR; /*!< 0x08 */
+ __IO uint32_t RSVD0; /*!< 0x0c */
+ __IO uint32_t TX_INT_CLR; /*!< 0x10 */
+ __IO uint32_t TX_FIFO; /*!< 0x14 */
+ __IO uint32_t RX_CONFIG; /*!< 0x18 */
+ __IO uint32_t RX_SR; /*!< 0x1c */
+ __IO uint32_t RX_INT_CLR; /*!< 0x20 */
+ __IO uint32_t RX_CNT_INT_SEL; /*!< 0x24 */
+ __IO uint32_t RX_FIFO; /*!< 0x28 */
+ __IO uint32_t IR_VERSION; /*!< 0x2c */
+ __O uint32_t RX_CUR_CNT; /*!< 0x30 */
+ __IO uint32_t RX_EX_INT; /*!< 0x34 */
+ __IO uint32_t RSVD1[4];
+ __IO uint32_t IR_TX_COMPE; /*!< 0x48 */
+ __IO uint32_t RSVD2; /*!< 0x4C */
+ __IO uint32_t DMA_CONFIG; /*!< 0x50 */
+} IR_TypeDef;
+
+/* ================================================================================ */
+/* ================ Key Scan ================ */
+/* ================================================================================ */
+
+/**
+ * @brief Key Scan. (KeyScan)
+ */
+
+typedef struct /*!< KeyScan Structure */
+{
+
+ __IO uint32_t CLKDIV; /*!< 0x00 */
+ __IO uint32_t TIMERCR; /*!< 0x04 */
+ __IO uint32_t CR; /*!< 0x08 */
+ __IO uint32_t COLCR; /*!< 0x0C */
+ __IO uint32_t ROWCR; /*!< 0x10 */
+ __I uint32_t FIFODATA; /*!< 0x14 */
+ __IO uint32_t INTMASK; /*!< 0x18 */
+ __IO uint32_t INTCLR; /*!< 0x1C */
+ __I uint32_t STATUS; /*!< 0x20 */
+
+} KEYSCAN_TypeDef;
+
+/* ================================================================================ */
+/* ================ LPC ================= */
+/* ================================================================================ */
+
+/**
+ * @brief Real time for LP (RTC)
+ */
+typedef struct
+{
+ __IO uint32_t LPC_CR0;
+ __IO uint32_t LPC_SR;
+ __IO uint32_t LPC_CMP;
+ __IO uint32_t LPC_CNT;
+} LPC_TypeDef;
+
+/* ================================================================================ */
+/* ================ Pinmux ================ */
+/* ================================================================================ */
+
+/**
+ * @brief Pinmux. (Pinmux)
+ */
+
+typedef struct /*!< Pinmux Structure */
+{
+ __IO uint32_t
+ CFG[10]; /*!< */
+} PINMUX_TypeDef;
+
+/* ================================================================================ */
+/* ================ PWM ================ */
+/* ================================================================================ */
+
+/**
+ * @brief PWM
+ */
+typedef struct
+{
+ __IO uint32_t CR; /*!< 0x00*/
+} PWM_TypeDef;
+
+typedef struct
+{
+ __IO uint32_t CR; /*!< 0x00*/
+} ENHPWM_TypeDef;
+
+/* ================================================================================ */
+/* ================ QDEC ================ */
+/* ================================================================================ */
+
+/**
+ * @brief Rotary decoder. (QDEC)
+ */
+
+typedef struct /*!< QDEC Structure */
+{
+ __IO uint32_t REG_DIV; /*!< 0x00 */
+ __IO uint32_t REG_CR_X; /*!< 0x04 */
+ __IO uint32_t REG_SR_X; /*!< 0x08 */
+ __IO uint32_t REG_CR_Y; /*!< 0x0C */
+ __IO uint32_t REG_SR_Y; /*!< 0x10 */
+ __IO uint32_t REG_CR_Z; /*!< 0x14 */
+ __IO uint32_t REG_SR_Z; /*!< 0x18 */
+ __IO uint32_t INT_MASK; /*!< 0x1C */
+ __IO uint32_t INT_SR; /*!< 0x20 */
+ __IO uint32_t INT_CLR; /*!< 0x24 */
+ __IO uint32_t REG_DBG; /*!< 0x28 */
+ __IO uint32_t REG_VERSION; /*!< 0x2C */
+} QDEC_TypeDef;
+
+/* ================================================================================ */
+/* ================ RTC ================ */
+/* ================================================================================ */
+
+/**
+ * @brief Real time counter 0. (RTC)
+ */
+typedef struct /*!< RTC Structure */
+{
+ __IO uint32_t CR0; /*!< 0x00 */
+ __IO uint32_t INT_CLR; /*!< 0x04 */
+ __IO uint32_t INT_SR; /*!< 0x08 */
+ __IO uint32_t PRESCALER; /*!< 0x0C */
+ __IO uint32_t COMP0; /*!< 0x10 */
+ __IO uint32_t COMP1; /*!< 0x14 */
+ __IO uint32_t COMP2; /*!< 0x18 */
+ __IO uint32_t COMP3; /*!< 0x1C */
+ __IO uint32_t COMP0GT; /*!< 0x20 */
+ __IO uint32_t COMP1GT; /*!< 0x24 */
+ __IO uint32_t COMP2GT; /*!< 0x28 */
+ __IO uint32_t COMP3GT; /*!< 0x2C */
+ __I uint32_t CNT; /*!< 0x30 */
+ __IO uint32_t PRE_CNT; /*!< 0x34 */
+ __IO uint32_t PRE_COMP; /*!< 0x38 */
+ __IO uint32_t BACKUP; /*!< 0x3C */
+} RTC_TypeDef;
+
+/* ================================================================================ */
+/* ================ 2WIRE_SPI ================ */
+/* ================================================================================ */
+
+/**
+ * @brief 2wire spi, mostly used with mouse sensor. (2WIRE_SPI)
+ */
+
+typedef struct /*!< 3WIRE_SPI Structure */
+{
+ __IO uint32_t RSVD0[12]; /*!< 0x00 -- 0x2C for Q-decode */
+ __IO uint32_t CFGR; /*!< 0x30 */
+ __IO uint32_t CR;
+ __IO uint32_t INTCR;
+ __I uint32_t SR;
+ __IO uint32_t RD0; /*!< 0x40 */
+ __IO uint32_t RD1;
+ __IO uint32_t RD2;
+ __IO uint32_t RD3;
+} SPI3WIRE_TypeDef;
+
+/* ================================================================================ */
+/* ================ SPI ================ */
+/* ================================================================================ */
+
+/**
+ * @brief SPI master 0. (SPI)
+ */
+typedef struct /*!< SPI Structure */
+{
+ __IO uint32_t CTRLR0; /*!< 0x00 */
+ __IO uint32_t CTRLR1; /*!< 0x04 */
+ __IO uint32_t SSIENR; /*!< 0x08 */
+ __IO uint32_t RSVD_0C; /*!< 0x0C */
+ __IO uint32_t SER; /*!< 0x10 */
+ __IO uint32_t BAUDR; /*!< 0x14 */
+ __IO uint32_t TXFTLR; /*!< 0x18 */
+ __IO uint32_t RXFTLR; /*!< 0x1C */
+ __I uint32_t TXFLR; /*!< 0x20 */
+ __I uint32_t RXFLR; /*!< 0x24 */
+ __I uint32_t SR; /*!< 0x28 */
+ __IO uint32_t IMR; /*!< 0x2C */
+ __I uint32_t ISR; /*!< 0x30 */
+ __I uint32_t RISR; /*!< 0x34 */
+ __I uint32_t TXOICR; /*!< 0x38 */
+ __I uint32_t RXOICR; /*!< 0x3C */
+ __I uint32_t RXUICR; /*!< 0x40 */
+ __I uint32_t FAEICR;/*RSVD_44;*/ /*!< 0x44 */
+ __I uint32_t ICR; /*!< 0x48 */
+ __IO uint32_t DMACR; /*!< 0x4C */
+ __IO uint32_t DMATDLR; /*!< 0x50 */
+ __IO uint32_t DMARDLR; /*!< 0x54 */
+ __I uint32_t TXUICR;/*IDR;*/ /*!< 0x58 */
+ __I uint32_t SSRICR; /*!< 0x5C */
+ __IO uint32_t DR[36]; /*!< 0x60 - 0xEC */
+ __IO uint32_t RX_SAMPLE_DLY; /*!< 0xF0 */
+} SPI_TypeDef;
+
+/* ================================================================================ */
+/* ================ TIM ================ */
+/* ================================================================================ */
+
+/**
+ * @brief TIM
+ */
+typedef struct
+{
+ __IO uint32_t LoadCount; /*!< 0x00*/
+ __I uint32_t CurrentValue; /*!< 0x04*/
+ __IO uint32_t ControlReg; /*!< 0x08*/
+ __I uint32_t EOI; /*!< 0x0C*/
+ __I uint32_t IntStatus; /*!< 0x10*/
+} TIM_TypeDef;
+
+/* ================================================================================ */
+/* ================ ENH_TIM ================ */
+/* ================================================================================ */
+
+/**
+ * @brief ENHTIMER
+ */
+typedef struct
+{
+ __O uint32_t CUR_CNT; /*!< 0x00*/
+ __O uint32_t LATCH_CNT0; /*!< 0x04*/
+ __O uint32_t LATCH_CNT1; /*!< 0x08*/
+ __O uint32_t LATCH_CNT2; /*!< 0x0C*/
+ __IO uint32_t CR; /*!< 0x10*/
+ __IO uint32_t MAX_CNT; /*!< 0x14*/
+ __IO uint32_t CCR; /*!< 0x18*/
+ __IO uint32_t CCR_FIFO; /*!< 0x1C*/
+} ENHTIM_TypeDef;
+
+/**
+ * @brief ENHTIMER
+ */
+typedef struct
+{
+ __O uint32_t FIFO_SR0; /*!< 0x00*/
+ __O uint32_t RSVD0; /*!< 0x04*/
+ __O uint32_t FIFO_SR2; /*!< 0x08*/
+ __IO uint32_t FIFO_CLR; /*!< 0x0C*/
+ __IO uint32_t CMD; /*!< 0x10*/
+ __IO uint32_t INT_CMD; /*!< 0x14*/
+ __IO uint32_t INT_SR; /*!< 0x18*/
+ __O uint32_t MASK_INT_SR; /*!< 0x1C*/
+ __IO uint32_t LC_INT_CMD0; /*!< 0x20*/
+ __IO uint32_t RSVD1; /*!< 0x24*/
+ __IO uint32_t LC_INT_CMD2; /*!< 0x28*/
+ __IO uint32_t RSVD2; /*!< 0x2C*/
+ __O uint32_t LC_FIFO_LEVEL0; /*!< 0x30*/
+ __O uint32_t LC_FIFO_LEVEL1; /*!< 0x34*/
+
+} ENHTIM_ShareTypeDef;
+
+/* ================================================================================ */
+/* ================ UART ================ */
+/* ================================================================================ */
+
+/**
+ * @brief Universal Asynchronous Receiver/Transmitter, version 1.0. (UART)
+ */
+
+typedef struct /*!< UART Structure */
+{
+ __IO uint32_t DLL;
+ __IO uint32_t DLH_INTCR;
+ __IO uint32_t INTID_FCR;
+ __IO uint32_t LCR;
+ __IO uint32_t MCR; /*!<0x10 */
+ __I uint32_t LSR;
+ __I uint32_t MSR;
+ __IO uint32_t SPR;
+ __IO uint32_t STSR; /*!<0x20 */
+ __IO uint32_t RB_THR;
+ __IO uint32_t MISCR; /*!<may not be seen for client */
+ __IO uint32_t TXPLSR;
+ __IO uint32_t RSVD0; /*!<0x30 */
+ __IO uint32_t RSVD1; /*!<0x34 */
+ __IO uint32_t RSVD2; /*!<0x38 */
+ __IO uint32_t DBG_UART; /*!<0x3C */
+ __IO uint32_t RX_IDLE_TOCR; /*!<0x40 */
+ __IO uint32_t RX_IDLE_INTSR;
+ __IO uint32_t RX_IDLE_INTCR;
+ __I uint32_t FIFO_LEVEL;
+ __IO uint32_t INTMASK; /*!<0x50 */
+ __I uint32_t TX_DONE_INTSR;
+ __I uint32_t TX_THR_INTSR;
+} UART_TypeDef;
+
+typedef enum
+{
+ LOG_CHANNEL_UART0,
+ LOG_CHANNEL_UART1,
+ LOG_CHANNEL_UART2
+} LogChannel_TypeDef;
+
+/* ================================================================================ */
+/* ================ Watch Dog ================ */
+/* ================================================================================ */
+
+/**
+ * @brief Watch Dog. (WDG)
+ */
+
+typedef struct /*!< WDG Structure */
+{
+ __IO uint32_t WDG_CTL; /*!< 0x00 */
+} WDG_TypeDef;
+
+/**
+ * @brief AON Watchdog
+ */
+typedef struct
+{
+ union
+ {
+ __IO uint32_t CRT; /*!< 0x00 (R/W) Control Register */
+ struct
+ {
+ uint32_t EN: 2; /*!< R/W WDT2 Enable, 2'b10: OFF, the other value: ON */
+ uint32_t CNT_CTL: 1; /*!< R/W Counter Control,
+ 1: WDG continue count in DLPS/Power Down/Hibernate,
+ 0: WDG stop count in DLPS/Power Down/Hibernate */
+ uint32_t RST_LVL: 1; /*!< R/W Reset Level,
+ 1: Level 2 reset (reset whole chip),
+ 0: Level 1 reset (reset whole chip except partial AON and RTC) */
+ uint32_t CNT_RELOAD: 1; /*!< R/W Reload Counter,
+ 1: Reload counter when exit DLPS/Power Down/Hibernate,
+ 0: Not reload counter when exit DLPS/Power Down/Hibernate */
+ uint32_t RSVD0: 3;
+ uint32_t COMP: 18; /*!< R/W Set the period of AON WDG : 1/450Hz ~ 1/2.3KHz */
+ uint32_t RSVD1: 6;
+ } CRT_BITS;
+ } u;
+ __IO uint32_t CNT_CLR; /*!< 0x04 (R/W) Clear Register, write 1 to reload AON WDG counter */
+ __IO uint32_t WP; /*!< 0x08 (R/W) Write Protect Register, write 1 to enable write CRT */
+} AON_WDG_TypeDef;
+
+/* ================================================================================ */
+/* ================ random generator ================ */
+/* ================================================================================ */
+
+/**
+ * @brief random generator. (RAN_GEN)
+ */
+
+typedef struct /*!< RAN_GEN Structure */
+{
+ union
+ {
+ __IO uint32_t CTL; /*!< 0x00 */
+ struct
+ {
+ __IO uint32_t rand_gen_en: 1;
+ __IO uint32_t seed_upd: 1;
+ __IO uint32_t random_req: 1;
+ __IO uint32_t opt_rand_upd: 1;
+ __IO uint32_t soft_rst: 1;
+ __IO uint32_t rsvd: 27;
+ } CTL_BITS;
+ } u;
+ __IO uint32_t POLYNOMIAL; /*!< 0x04 */
+ __IO uint32_t SEED; /*!< 0x08 */
+ __IO uint32_t RAN_NUM; /*!< 0x0C */
+} RAN_GEN_TypeDef;
+
+/* ================================================================================ */
+/* ================ System Block Control ================ */
+/* ================================================================================ */
+
+/**
+ * @brief System Block Control. (SYS_BLKCTRL)
+ */
+
+typedef struct /*!< SYS_BLKCTRL Structure */
+{
+ /* 0x0200 0x4000_0200
+ 0 R/W r_cpu_slow_en 0
+ 1 R/W r_cpu_slow_opt_wfi 0
+ 2 R/W r_cpu_slow_opt_at_tx 1
+ 3 R/W r_cpu_slow_opt_at_rx 1
+ 4 R/W r_cpu_slow_opt_lcd 0
+ 5 R/W r_auto_slow_opt 0
+ 6 W1O reg_zone1_wrp_en 0
+ 7 W1O reg_zone2_wrp_en 0
+ 8 W1O reg_wrp_lock 0
+ 12:9 R/W r_cpu_low_rate_valid_num 4'h3
+ 13 R/W r_cpu_auto_slow_force_update 0
+ 14 R/W r_cpu_slow_opt_spi0 0
+ 18:15 R/W r_cpu_low_rate_valid_num1 4'h3
+ 24:19 R/W r_bt_ahb_wait_cnt 6'h0C
+ 27:25 R/W DUMMY 3'h0
+ 28 R/W r_aon_rd_opt 1
+ 29 R/W r_btaon_acc_no_block 0
+ 30 R/W bzdma_autoslow_eco_disable 0
+ 31 R/W r_clk_cpu_32k_en 0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_SYS_CLK_SEL_0;
+ struct
+ {
+ __IO uint32_t r_cpu_slow_en: 1;
+ __IO uint32_t r_cpu_slow_opt_wfi: 1;
+ __IO uint32_t r_cpu_slow_opt_at_tx: 1;
+ __IO uint32_t r_cpu_slow_opt_at_rx: 1;
+ __IO uint32_t r_cpu_slow_opt_lcd: 1;
+ __IO uint32_t r_auto_slow_opt: 1;
+ __IO uint32_t reg_zone1_wrp_en: 1;
+ __IO uint32_t reg_zone2_wrp_en: 1;
+ __IO uint32_t reg_wrp_lock: 1;
+ __IO uint32_t r_cpu_low_rate_valid_num: 4;
+ __IO uint32_t r_cpu_auto_slow_force_update: 1;
+ __IO uint32_t r_cpu_slow_opt_spi0: 1;
+ __IO uint32_t r_cpu_low_rate_valid_num1: 4;
+ __IO uint32_t r_bt_ahb_wait_cnt: 6;
+ __IO uint32_t RESERVED_0: 3;
+ __IO uint32_t r_aon_rd_opt: 1;
+ __IO uint32_t r_btaon_acc_no_block: 1;
+ __IO uint32_t bzdma_autoslow_eco_disable: 1;
+ __IO uint32_t r_clk_cpu_32k_en: 1;
+ } BITS_200;
+ } u_200;
+
+ /* 0x0204 0x4000_0204
+ 3:0 R RF_RL_ID 4'd0
+ 7:4 R RF_RTL_ID 4'd0
+ 31:8 R RSVD 24'd0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_ID;
+ struct
+ {
+ __I uint32_t RF_RL_ID: 4;
+ __I uint32_t RF_RTL_ID: 4;
+ __I uint32_t RESERVED_0: 24;
+ } BITS_204;
+ } u_204;
+
+ /* 0x0208 0x4000_0208
+ 3:0 R/W r_cpu_div_sel 4'h0
+ 7:4 R/W r_cpu_div_sel_slow 4'h0
+ 8 R/W r_cpu_div_en 1
+ 9 R/W r_CPU_CLK_SRC_EN 1
+ 10 R/W r_cpu_auto_slow_filter_en 1
+ 11 R/W r_cpu_clk_mux_0_cg_en 1
+ 12 R/W DUMMY 1
+ 13 R/W r_cpu_xtal_clk_cg_en 1
+ 14 R/W r_cpu_ocs40_clk_cg_en 1
+ 15 R/W r_cpu_div_en_slow 1
+ 16 W1O DUMMY 0
+ 17 W1O r_cpu_div_sel_opt 0
+ 18 W1O r_spi0_div_sel_opt 0
+ 19 W1O r_spi1_div_sel_opt 0
+ 20 W1O RSVD 0
+ 21 W1O RSVD 0
+ 22 W1O RSVD 0
+ 23 W1O r_spi0_div_sel_opt1 0
+ 24 W1O r_spi1_div_sel_opt1 0
+ 25 W1O DUMMY 0
+ 26 W1O DUMMY 0
+ 27 R/W r_CKE_SYSON 0
+ 28 R/W r_cpu_auto_slow_filter1_en 0
+ 31:29 R/W DUMMY 3'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_SYS_CLK_SEL_1;
+ struct
+ {
+ __IO uint32_t r_cpu_div_sel: 4;
+ __IO uint32_t r_cpu_div_sel_slow: 4;
+ __IO uint32_t r_cpu_div_en: 1;
+ __IO uint32_t r_CPU_CLK_SRC_EN: 1;
+ __IO uint32_t r_cpu_auto_slow_filter_en: 1;
+ __IO uint32_t r_cpu_clk_mux_0_cg_en: 1;
+ __IO uint32_t RESERVED_7: 1;
+ __IO uint32_t r_cpu_xtal_clk_cg_en: 1;
+ __IO uint32_t r_cpu_ocs40_clk_cg_en: 1;
+ __IO uint32_t r_cpu_div_en_slow: 1;
+ __IO uint32_t RESERVED_6: 1;
+ __IO uint32_t r_cpu_div_sel_opt: 1;
+ __IO uint32_t r_spi0_div_sel_opt: 1;
+ __IO uint32_t r_spi1_div_sel_opt: 1;
+ __IO uint32_t RESERVED_5: 1;
+ __IO uint32_t RESERVED_4: 1;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t r_spi0_div_sel_opt1: 1;
+ __IO uint32_t r_spi1_div_sel_opt1: 1;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t r_CKE_SYSON: 1;
+ __IO uint32_t r_cpu_auto_slow_filter1_en: 1;
+ __IO uint32_t RESERVED_0: 3;
+ } BITS_208;
+ } u_208;
+
+ /* 0x020C 0x4000_020c
+ 1:0 R/W r_flash_div_sel 2'h0
+ 3:2 R/W DUMMY 2'h0
+ 4 R/W r_flash_div_en 0
+ 5 R/W r_FLASH_CLK_SRC_EN 1
+ 6 R/W r_flash_clk_src_sel_1 0
+ 7 R/W r_flash_clk_src_sel_0 0
+ 8 R/W r_flash_mux_1_clk_cg_en 1
+ 9 R/W r_rng_sfosc_sel 0
+ 12:10 R/W r_rng_sfosc_div_sel 3'h0
+ 15:13 R/W DUMMY 0
+ 18:16 R/W DUMMY 3'h0
+ 19 R/W DUMMY 0
+ 20 R/W DUMMY 0
+ 21 R/W DUMMY 1
+ 22 R/W r_CLK_40M_SRC_EN 1
+ 23 R/W DUMMY 0
+ 24 R/W r_40m_clk_src_sel_0 1
+ 25 R/W DUMMY 0
+ 26 R/W r_CLK_40M_SRC_DIV_EN 1
+ 27 R/W r_CLK_20M_SRC_EN 0
+ 28 R/W r_CLK_10M_SRC_EN 1
+ 29 R/W r_CLK_5M_SRC_EN 0
+ 31:30 R/W DUMMY 2'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_SYS_CLK_SEL_2;
+ struct
+ {
+ __IO uint32_t r_flash_div_sel: 2;
+ __IO uint32_t RESERVED_8: 2;
+ __IO uint32_t r_flash_div_en: 1;
+ __IO uint32_t r_FLASH_CLK_SRC_EN: 1;
+ __IO uint32_t r_flash_clk_src_sel_1: 1;
+ __IO uint32_t r_flash_clk_src_sel_0: 1;
+ __IO uint32_t r_flash_mux_1_clk_cg_en: 1;
+ __IO uint32_t r_rng_sfosc_sel: 1;
+ __IO uint32_t r_rng_sfosc_div_sel: 3;
+ __IO uint32_t RESERVED_7: 3;
+ __IO uint32_t RESERVED_6: 3;
+ __IO uint32_t RESERVED_5: 1;
+ __IO uint32_t RESERVED_4: 1;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t r_CLK_40M_SRC_EN: 1;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t r_40m_clk_src_sel_0: 1;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t r_CLK_40M_SRC_DIV_EN: 1;
+ __IO uint32_t r_CLK_20M_SRC_EN: 1;
+ __IO uint32_t r_CLK_10M_SRC_EN: 1;
+ __IO uint32_t r_CLK_5M_SRC_EN: 1;
+ __IO uint32_t RESERVED_0: 2;
+ } BITS_20C;
+ } u_20C;
+
+ /* 0x210 0x4000_0210
+ 0 R/W DUMMY 0
+ 1 R/W DUMMY 0
+ 2 R/W r_PON_FEN_LXBUS 1
+ 3 R/W DUMMY 0
+ 4 R/W r_PON_FEN_FLASH 1
+ 5 R/W DUMMY 1
+ 6 R/W DUMMY 0
+ 7 R/W DUMMY 0
+ 8 R/W DUMMY 0
+ 11:9 R/W DUMMY 3'h0
+ 12 R/W r_PON_FEN_UART 0
+ 13 R/W r_PON_FEN_GDMA0 0
+ 14 R/W DUMMY 0
+ 15 R/W DUMMY 0
+ 16 R/W r_PON_FEN_TIMER 0
+ 19:17 R/W DUMMY 0
+ 20 R/W r_PON_FEN_AAC_XTAL 0
+ 21 R/W r_PON_FEN_CAP_TOUCH 0
+ 22 R/W DUMMY 0
+ 23 R/W DUMMY 0
+ 31:24 R DUMMY 8'd0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_SOC_FUNC_EN;
+ struct
+ {
+ __IO uint32_t RESERVED_13: 1;
+ __IO uint32_t RESERVED_12: 1;
+ __IO uint32_t r_PON_FEN_LXBUS: 1;
+ __IO uint32_t RESERVED_11: 1;
+ __IO uint32_t r_PON_FEN_FLASH: 1;
+ __IO uint32_t RESERVED_10: 1;
+ __IO uint32_t RESERVED_9: 1;
+ __IO uint32_t RESERVED_8: 1;
+ __IO uint32_t RESERVED_7: 1;
+ __IO uint32_t RESERVED_6: 3;
+ __IO uint32_t r_PON_FEN_UART: 1;
+ __IO uint32_t r_PON_FEN_GDMA0: 1;
+ __IO uint32_t RESERVED_5: 1;
+ __IO uint32_t RESERVED_4: 1;
+ __IO uint32_t r_PON_FEN_TIMER: 1;
+ __IO uint32_t RESERVED_3: 3;
+ __IO uint32_t r_PON_FEN_AAC_XTAL: 1;
+ __IO uint32_t r_PON_FEN_CAP_TOUCH: 1;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t RESERVED_1: 1;
+ __I uint32_t RESERVED_0: 8;
+ } BITS_210;
+ } u_210;
+
+ /* 0x0214 0x4000_0214
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_214;
+
+ /* 0x0218 0x4000_0218
+ 0 R/W r_PON_FEN_URT0_GLB 0
+ 1 R/W DUMMY 0
+ 2 R/W r_PON_FEN_AES 0
+ 3 R/W r_PON_FEN_RNG 0
+ 7:4 R/W DUMMY 4'h0
+ 8 R/W r_PON_FEN_SPI0 0
+ 9 R/W r_PON_FEN_SPI1 0
+ 10 R/W r_PON_FEN_IRRC 0
+ 15:11 R/W DUMMY 5'd0
+ 16 R/W r_PON_FEN_I2C0 0
+ 17 R/W r_PON_FEN_I2C1 0
+ 18 R/W r_PON_FEN_QDEC 0
+ 19 R/W r_PON_FEN_KEYSCAN 0
+ 23:20 R/W DUMMY 4'h0
+ 24 R/W r_PON_FEN_SPI2W 0
+ 25 R/W DUMMY 1
+ 26 R/W r_PON_FEN_DSP_IPC 1
+ 27 R/W r_PON_FEN_DSP_MEM 1
+ 28 R/W r_PON_FEN_ASRC 0
+ 29 R/W r_PON_FEN_DSP_WDT 0
+ 30 R/W r_PON_FEN_EFUSE 0
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_SOC_PERI_FUNC0_EN;
+ struct
+ {
+ __IO uint32_t r_PON_FEN_URT0_GLB: 1;
+ __IO uint32_t RESERVED_5: 1;
+ __IO uint32_t r_PON_FEN_AES: 1;
+ __IO uint32_t r_PON_FEN_RNG: 1;
+ __IO uint32_t RESERVED_4: 4;
+ __IO uint32_t r_PON_FEN_SPI0: 1;
+ __IO uint32_t r_PON_FEN_SPI1: 1;
+ __IO uint32_t r_PON_FEN_IRRC: 1;
+ __IO uint32_t RESERVED_3: 5;
+ __IO uint32_t r_PON_FEN_I2C0: 1;
+ __IO uint32_t r_PON_FEN_I2C1: 1;
+ __IO uint32_t r_PON_FEN_QDEC: 1;
+ __IO uint32_t r_PON_FEN_KEYSCAN: 1;
+ __IO uint32_t RESERVED_2: 4;
+ __IO uint32_t r_PON_FEN_SPI2W: 1;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t r_PON_FEN_DSP_IPC: 1;
+ __IO uint32_t r_PON_FEN_DSP_MEM: 1;
+ __IO uint32_t r_PON_FEN_ASRC: 1;
+ __IO uint32_t r_PON_FEN_DSP_WDT: 1;
+ __IO uint32_t r_PON_FEN_EFUSE: 1;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_218;
+ } u_218;
+
+ /* 0x021C 0x4000_021c
+ 0 R/W r_PON_FEN_ADC0 0
+ 7:1 R/W DUMMY 6'd0
+ 8 R/W r_PON_FEN_GPIO0 0
+ 31 :9 R/W DUMMY 23'd0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_SOC_PERI_FUNC1_EN;
+ struct
+ {
+ __IO uint32_t r_PON_FEN_ADC0: 1;
+ __IO uint32_t RESERVED_1: 7;
+ __IO uint32_t r_PON_FEN_GPIO0: 1;
+ __IO uint32_t RESERVED_0: 23;
+ } BITS_21C;
+ } u_21C;
+
+ /* 0x0220 0x4000_0220
+ 0 R/W r_PON_FEN_AUDIO 0
+ 1 R/W r_PON_FEN_SPORT0 0
+ 2 R/W DUMMY 0
+ 3 R/W DUMMY 0
+ 4 R/W r_CLK_EN_AUDIO 0
+ 5 R/W r_CLK_EN_SPORT0 0
+ 6 R/W DUMMY 0
+ 7 R/W DUMMY 0
+ 8 R/W r_CLK_EN_SPORT_40M 0
+ 9 R/W r_CLK_EN_AUDIO_REG 1
+ 31:10 R/W DUMMY 22'd0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_SOC_AUDIO_IF_EN;
+ struct
+ {
+ __IO uint32_t r_PON_FEN_AUDIO: 1;
+ __IO uint32_t r_PON_FEN_SPORT0: 1;
+ __IO uint32_t RESERVED_4: 1;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t r_CLK_EN_AUDIO: 1;
+ __IO uint32_t r_CLK_EN_SPORT0: 1;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t r_CLK_EN_SPORT_40M: 1;
+ __IO uint32_t r_CLK_EN_AUDIO_REG: 1;
+ __IO uint32_t RESERVED_0: 22;
+ } BITS_220;
+ } u_220;
+
+ /* 0x0224 0x4000_0224
+ 2:0 R/W DUMMY 3'h4
+ 3 R/W r_SPORT0_EXT_CODEC 0
+ 6:4 R/W DUMMY 3'h1
+ 7 R/W r_CODEC_STANDALONE 0
+ 31:8 R/W DUMMY 24'd0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_SOC_AUDIO_CLK_CTRL_A;
+ struct
+ {
+ __IO uint32_t RESERVED_2: 3;
+ __IO uint32_t r_SPORT0_EXT_CODEC: 1;
+ __IO uint32_t RESERVED_1: 3;
+ __IO uint32_t r_CODEC_STANDALONE: 1;
+ __IO uint32_t RESERVED_0: 24;
+ } BITS_224;
+ } u_224;
+
+ /* 0x0228 0x4000_0228
+ 3:0 R/W DUMMY 4'h1
+ 4 R/W r_SPORT0_MCLK_OUT 0
+ 6:5 R/W DUMMY 0
+ 7 R/W DUMMY 0
+ 31:8 R/W DUMMY 24'd0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_SOC_AUDIO_CLK_CTRL_B;
+ struct
+ {
+ __IO uint32_t RESERVED_3: 4;
+ __IO uint32_t r_SPORT0_MCLK_OUT: 1;
+ __IO uint32_t RESERVED_2: 2;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t RESERVED_0: 24;
+ } BITS_228;
+ } u_228;
+
+ /* 0x022C 0x4000_022c
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_22C;
+
+ /* 0x0230 0x4000_0230
+ 0 R/W DUMMY 1
+ 1 R/W DUMMY 0
+ 2 R/W r_PON_CKE_PLFM 1
+ 3 R/W DUMMY 1
+ 4 R/W r_CKE_BUS_RAM_SLP 0
+ 5 R/W r_CKE_BT_VEN 1
+ 6 R/W r_PON_ACTCKE_VDREG 0
+ 7 R/W r_PON_SLPCKE_VDREG 0
+ 8 R/W r_PON_ACTCKE_FLASH 1
+ 9 R/W r_PON_SLPCKE_FLASH 0
+ 10 R/W DUMMY 0
+ 11 R/W DUMMY 0
+ 12 R/W r_PON_ACTCKE_LUART 0
+ 13 R/W r_PON_SLPCKE_LUART 0
+ 14 R/W r_PON_ACTCKE_TIMER 0
+ 15 R/W r_PON_SLPCKE_TIMER 0
+ 16 R/W r_PON_ACTCKE_GDMA0 0
+ 17 R/W r_PON_SLPCKE_GDMA0 0
+ 23:18 R/W DUMMY 6'd0
+ 24 R/W r_PON_ACTCKE_GPIO 0
+ 25 R/W r_PON_SLPCKE_GPIO 0
+ 26 R/W DUMMY 0
+ 27 R/W DUMMY 0
+ 28 R/W DUMMY 0
+ 29 R/W DUMMY 0
+ 30 R/W DUMMY 0
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_PESOC_CLK_CTRL;
+ struct
+ {
+ __IO uint32_t RESERVED_11: 1;
+ __IO uint32_t RESERVED_10: 1;
+ __IO uint32_t r_PON_CKE_PLFM: 1;
+ __IO uint32_t RESERVED_9: 1;
+ __IO uint32_t r_CKE_BUS_RAM_SLP: 1;
+ __IO uint32_t r_CKE_BT_VEN: 1;
+ __IO uint32_t r_PON_ACTCKE_VDREG: 1;
+ __IO uint32_t r_PON_SLPCKE_VDREG: 1;
+ __IO uint32_t r_PON_ACTCKE_FLASH: 1;
+ __IO uint32_t r_PON_SLPCKE_FLASH: 1;
+ __IO uint32_t RESERVED_8: 1;
+ __IO uint32_t RESERVED_7: 1;
+ __IO uint32_t r_PON_ACTCKE_LUART: 1;
+ __IO uint32_t r_PON_SLPCKE_LUART: 1;
+ __IO uint32_t r_PON_ACTCKE_TIMER: 1;
+ __IO uint32_t r_PON_SLPCKE_TIMER: 1;
+ __IO uint32_t r_PON_ACTCKE_GDMA0: 1;
+ __IO uint32_t r_PON_SLPCKE_GDMA0: 1;
+ __IO uint32_t RESERVED_6: 6;
+ __IO uint32_t r_PON_ACTCKE_GPIO: 1;
+ __IO uint32_t r_PON_SLPCKE_GPIO: 1;
+ __IO uint32_t RESERVED_5: 1;
+ __IO uint32_t RESERVED_4: 1;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_230;
+ } u_230;
+
+ /* 0x0234 0x4000_0234
+ 0 R/W r_PON_ACTCKE_UART0 0
+ 1 R/W r_PON_SLPCKE_UART0 0
+ 2 R/W DUMMY 0
+ 3 R/W DUMMY 0
+ 4 R/W r_CKE_MODEM 1
+ 5 R/W r_CKE_CAL32K 0
+ 6 R/W r_CKE_RNG 0
+ 7 R/W DUMMY 0
+ 8 R/W DUMMY 0
+ 9 R/W r_CKE_PDCK 0
+ 10 R/W r_CKE_AAC_XTAL 0
+ 11 R/W r_PON_CKE_BT_FREQ_DET 0
+ 12 R/W r_PON_CKE_CAP_TOUCH 0
+ 15:13 R/W DUMMY 3'h0
+ 16 R/W r_PON_ACTCK_SPI0 0
+ 17 R/W r_PON_SLPCK_SPI0 0
+ 18 R/W r_PON_ACTCK_SPI1 0
+ 19 R/W r_PON_SLPCK_SPI1 0
+ 20 R/W r_PON_ACTCK_IRRC 0
+ 21 R/W r_PON_SLPCKE_IRRC 0
+ 23:22 R/W DUMMY 2'h0
+ 24 R/W DUMMY 0
+ 25 R/W DUMMY 0
+ 26 R/W DUMMY 0
+ 27 R/W DUMMY 0
+ 31:28 R/W DUMMY 4'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_PESOC_PERI_CLK_CTRL0;
+ struct
+ {
+ __IO uint32_t r_PON_ACTCKE_UART0: 1;
+ __IO uint32_t r_PON_SLPCKE_UART0: 1;
+ __IO uint32_t RESERVED_10: 1;
+ __IO uint32_t RESERVED_9: 1;
+ __IO uint32_t r_CKE_MODEM: 1;
+ __IO uint32_t r_CKE_CAL32K: 1;
+ __IO uint32_t r_CKE_RNG: 1;
+ __IO uint32_t RESERVED_8: 1;
+ __IO uint32_t RESERVED_7: 1;
+ __IO uint32_t r_CKE_PDCK: 1;
+ __IO uint32_t r_CKE_AAC_XTAL: 1;
+ __IO uint32_t r_PON_CKE_BT_FREQ_DET: 1;
+ __IO uint32_t r_PON_CKE_CAP_TOUCH: 1;
+ __IO uint32_t RESERVED_6: 3;
+ __IO uint32_t r_PON_ACTCK_SPI0: 1;
+ __IO uint32_t r_PON_SLPCK_SPI0: 1;
+ __IO uint32_t r_PON_ACTCK_SPI1: 1;
+ __IO uint32_t r_PON_SLPCK_SPI1: 1;
+ __IO uint32_t r_PON_ACTCK_IRRC: 1;
+ __IO uint32_t r_PON_SLPCKE_IRRC: 1;
+ __IO uint32_t RESERVED_5: 2;
+ __IO uint32_t RESERVED_4: 1;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t RESERVED_0: 4;
+ } BITS_234;
+ } u_234;
+
+ /* 0x0238 0x4000_0238
+ 0 R/W r_PON_ACTCKE_I2C0 0
+ 1 R/W r_PON_SLPCKE_I2C0 0
+ 2 R/W r_PON_ACTCKE_I2C1 0
+ 3 R/W r_PON_SLPCKE_I2C1 0
+ 4 R/W r_PON_ACTCKE_QDEC 0
+ 5 R/W r_PON_SLPCKE_QDEC 0
+ 6 R/W r_PON_ACTCKE_KEYSCAN 0
+ 7 R/W r_PON_SLPCKE_KEYSCAN 0
+ 8 R/W r_PON_ACTCKE_AES 0
+ 9 R/W r_PON_SLPCKE_AES 0
+ 15:10 R/W DUMMY 6'h0
+ 16 R/W r_PON_ACTCKE_SPI2W 0
+ 17 R/W r_PON_SLPCKE_SPI2W 0
+ 19:18 R/W DUMMY 2'h0
+ 20 R/W DUMMY 0
+ 21 R/W DUMMY 0
+ 22 R/W DUMMY 0
+ 23 R/W DUMMY 0
+ 24 R/W r_PON_ACTCKE_ADC 0
+ 25 R/W r_PON_SLPCKE_ADC 0
+ 26 R/W DUMMY 0
+ 27 R/W DUMMY 0
+ 28 R/W DUMMY 0
+ 29 R/W DUMMY 0
+ 30 R/W r_PON_CKE_DSP_WDT 0
+ 31 R/W r_PON_CKE_EFUSE 0
+ */
+ union
+ {
+ __IO uint32_t PERION_r_PON_PERI_CLK_CTRL1;
+ struct
+ {
+ __IO uint32_t r_PON_ACTCKE_I2C0: 1;
+ __IO uint32_t r_PON_SLPCKE_I2C0: 1;
+ __IO uint32_t r_PON_ACTCKE_I2C1: 1;
+ __IO uint32_t r_PON_SLPCKE_I2C1: 1;
+ __IO uint32_t r_PON_ACTCKE_QDEC: 1;
+ __IO uint32_t r_PON_SLPCKE_QDEC: 1;
+ __IO uint32_t r_PON_ACTCKE_KEYSCAN: 1;
+ __IO uint32_t r_PON_SLPCKE_KEYSCAN: 1;
+ __IO uint32_t r_PON_ACTCKE_AES: 1;
+ __IO uint32_t r_PON_SLPCKE_AES: 1;
+ __IO uint32_t RESERVED_9: 6;
+ __IO uint32_t r_PON_ACTCKE_SPI2W: 1;
+ __IO uint32_t r_PON_SLPCKE_SPI2W: 1;
+ __IO uint32_t RESERVED_8: 2;
+ __IO uint32_t RESERVED_7: 1;
+ __IO uint32_t RESERVED_6: 1;
+ __IO uint32_t RESERVED_5: 1;
+ __IO uint32_t RESERVED_4: 1;
+ __IO uint32_t r_PON_ACTCKE_ADC: 1;
+ __IO uint32_t r_PON_SLPCKE_ADC: 1;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t RESERVED_0: 1;
+ __IO uint32_t r_PON_CKE_DSP_WDT: 1;
+ __IO uint32_t r_PON_CKE_EFUSE: 1;
+ } BITS_238;
+ } u_238;
+
+ /* 0x023C 0x4000_023c
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_23C;
+
+ /* 0x0240 0x4000_0240
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_240;
+
+ /* 0x0244 0x4000_0244
+ 0 R/W r_PON_ACTCKE_BTBUS 1
+ 1 R/W r_PON_SLPCKE_BTBUS 1
+ 15:2 R/W DUMMY 14'h0
+ 21:16 R/W DUMMY 6'h0
+ 22 R/W r_LS_mcu_rom 0
+ 31:23 R/W DUMMY 9'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_r_OFF_MEM_PWR_CRTL_r_PON_COM_CLK_CTRL;
+ struct
+ {
+ __IO uint32_t r_PON_ACTCKE_BTBUS: 1;
+ __IO uint32_t r_PON_SLPCKE_BTBUS: 1;
+ __IO uint32_t RESERVED_2: 14;
+ __IO uint32_t RESERVED_1: 6;
+ __IO uint32_t r_LS_mcu_rom: 1;
+ __IO uint32_t RESERVED_0: 9;
+ } BITS_244;
+ } u_244;
+
+ /* 0x0248 0x4000_0248
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_248;
+
+ /* 0x024C 0x4000_024c
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_24C;
+
+ /* 0x0250 0x4000_0250
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_250;
+
+ /* 0x0254 0x4000_0254
+ 7:0 R/W DUMMY 8'h1
+ 13:8 R/W DUMMY 6'h0
+ 14 R/W DUMMY 0
+ 15 R/W DUMMY 0
+ 31:16 R/W DUMMY 16'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_r_DSP_TOP_CTRL;
+ struct
+ {
+ __IO uint32_t RESERVED_4: 8;
+ __IO uint32_t RESERVED_3: 6;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t RESERVED_0: 16;
+ } BITS_254;
+ } u_254;
+
+ /* 0x0258 0x4000_0258
+ 1:0 RW CORE_XTAL_LPS_CAP_STEP 2'b01
+ 3:2 RW CORE_XTAL_LPS_CAP_CYC 2'b00
+ 6:4 RW CORE_XTAL_OV_UNIT 3'b000
+ 8:7 RW CORE_XTAL_OV_RATIO 2'b01
+ 11:9 RW CORE_XTAL_MODE 3'b100
+ 13:12 RW CORE_XTAL_CTRL1_2t1 2'b00
+ 31:14 R RSVD 18'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_0_1;
+ struct
+ {
+ __IO uint32_t CORE_XTAL_LPS_CAP_STEP: 2;
+ __IO uint32_t CORE_XTAL_LPS_CAP_CYC: 2;
+ __IO uint32_t CORE_XTAL_OV_UNIT: 3;
+ __IO uint32_t CORE_XTAL_OV_RATIO: 2;
+ __IO uint32_t CORE_XTAL_MODE: 3;
+ __IO uint32_t CORE_XTAL_CTRL1_2t1: 2;
+ __I uint32_t RESERVED_0: 18;
+ } BITS_258;
+ } u_258;
+
+ /* 0x025C 0x4000_025c
+ 1:0 RW CORE_XTAL_LPS_CAP_STEP 2'b01
+ 3:2 RW CORE_XTAL_LPS_CAP_CYC 2'b00
+ 6:4 RW CORE_XTAL_OV_UNIT 3'b000
+ 8:7 RW CORE_XTAL_OV_RATIO 2'b01
+ 11:9 RW CORE_XTAL_MODE 3'b100
+ 13:12 RW CORE_XTAL_CTRL1_2t1 2'b00
+ 31:14 R RSVD 18'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_4_1;
+ struct
+ {
+ __IO uint32_t CORE_XTAL_LPS_CAP_STEP: 2;
+ __IO uint32_t CORE_XTAL_LPS_CAP_CYC: 2;
+ __IO uint32_t CORE_XTAL_OV_UNIT: 3;
+ __IO uint32_t CORE_XTAL_OV_RATIO: 2;
+ __IO uint32_t CORE_XTAL_MODE: 3;
+ __IO uint32_t CORE_XTAL_CTRL1_2t1: 2;
+ __I uint32_t RESERVED_0: 18;
+ } BITS_25C;
+ } u_25C;
+
+ /* 0x0260 0x4000_0260
+ 1:0 RW CORE_XTAL_LPS_CAP_STEP 2'b01
+ 3:2 RW CORE_XTAL_LPS_CAP_CYC 2'b00
+ 6:4 RW CORE_XTAL_OV_UNIT 3'b000
+ 8:7 RW CORE_XTAL_OV_RATIO 2'b01
+ 11:9 RW CORE_XTAL_MODE 3'b100
+ 13:12 RW CORE_XTAL_CTRL1_2t1 2'b00
+ 31:14 R RSVD 18'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_5_1;
+ struct
+ {
+ __IO uint32_t CORE_XTAL_LPS_CAP_STEP: 2;
+ __IO uint32_t CORE_XTAL_LPS_CAP_CYC: 2;
+ __IO uint32_t CORE_XTAL_OV_UNIT: 3;
+ __IO uint32_t CORE_XTAL_OV_RATIO: 2;
+ __IO uint32_t CORE_XTAL_MODE: 3;
+ __IO uint32_t CORE_XTAL_CTRL1_2t1: 2;
+ __I uint32_t RESERVED_0: 18;
+ } BITS_260;
+ } u_260;
+
+ /* 0x0264 0x4000_0264
+ 1:0 RW CORE_XTAL_LPS_CAP_STEP 2'b01
+ 3:2 RW CORE_XTAL_LPS_CAP_CYC 2'b00
+ 6:4 RW CORE_XTAL_OV_UNIT 3'b000
+ 8:7 RW CORE_XTAL_OV_RATIO 2'b01
+ 11:9 RW CORE_XTAL_MODE 3'b100
+ 13:12 RW CORE_XTAL_CTRL1_2t1 2'b00
+ 31:14 R RSVD 18'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_6_1;
+ struct
+ {
+ __IO uint32_t CORE_XTAL_LPS_CAP_STEP: 2;
+ __IO uint32_t CORE_XTAL_LPS_CAP_CYC: 2;
+ __IO uint32_t CORE_XTAL_OV_UNIT: 3;
+ __IO uint32_t CORE_XTAL_OV_RATIO: 2;
+ __IO uint32_t CORE_XTAL_MODE: 3;
+ __IO uint32_t CORE_XTAL_CTRL1_2t1: 2;
+ __I uint32_t RESERVED_0: 18;
+ } BITS_264;
+ } u_264;
+
+ /* 0x0268 0x4000_0268
+ 1:0 RW CORE_XTAL_LPS_CAP_STEP 2'b01
+ 3:2 RW CORE_XTAL_LPS_CAP_CYC 2'b00
+ 6:4 RW CORE_XTAL_OV_UNIT 3'b000
+ 8:7 RW CORE_XTAL_OV_RATIO 2'b01
+ 11:9 RW CORE_XTAL_MODE 3'b100
+ 13:12 RW CORE_XTAL_CTRL1_2t1 2'b00
+ 31:14 R RSVD 18'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_7_1;
+ struct
+ {
+ __IO uint32_t CORE_XTAL_LPS_CAP_STEP: 2;
+ __IO uint32_t CORE_XTAL_LPS_CAP_CYC: 2;
+ __IO uint32_t CORE_XTAL_OV_UNIT: 3;
+ __IO uint32_t CORE_XTAL_OV_RATIO: 2;
+ __IO uint32_t CORE_XTAL_MODE: 3;
+ __IO uint32_t CORE_XTAL_CTRL1_2t1: 2;
+ __I uint32_t RESERVED_0: 18;
+ } BITS_268;
+ } u_268;
+
+ /* 0x026C 0x4000_026c
+ 0 RW CORE_BUCK_PFM_AOT_EN 1'b0
+ 1 RW CORE_BUCK_PFM_COT_EN 1'b1
+ 2 RW CORE_BUCK_ENOFFSAWPFM_H 1'b1
+ 3 RW CORE_BUCK_POW_EA_Iqx2_H 1'b1
+ 4 RW CORE_BUCK_POW_EA_Iqx3_H 1'b1
+ 5 RW CORE_BUCK_POW_EA_IqEhance_H 1'b1
+ 8:6 RW CORE_BUCK_PFM_STEP_INI 3'b0
+ 16:9 RW CORE_AUTO_SET 8'haa
+ 22:17 RW CORE_D300k_REG_MANU_CCOT 6'b010000
+ 31:23 R RSVD 9'b0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_0_2;
+ struct
+ {
+ __IO uint32_t CORE_BUCK_PFM_AOT_EN: 1;
+ __IO uint32_t CORE_BUCK_PFM_COT_EN: 1;
+ __IO uint32_t CORE_BUCK_ENOFFSAWPFM_H: 1;
+ __IO uint32_t CORE_BUCK_POW_EA_Iqx2_H: 1;
+ __IO uint32_t CORE_BUCK_POW_EA_Iqx3_H: 1;
+ __IO uint32_t CORE_BUCK_POW_EA_IqEhance_H: 1;
+ __IO uint32_t CORE_BUCK_PFM_STEP_INI: 3;
+ __IO uint32_t CORE_AUTO_SET: 8;
+ __IO uint32_t CORE_D300k_REG_MANU_CCOT: 6;
+ __I uint32_t RESERVED_0: 9;
+ } BITS_26C;
+ } u_26C;
+
+ /* 0x0270 0x4000_0270
+ 0 RW CORE_BUCK_PFM_AOT_EN 1'b0
+ 1 RW CORE_BUCK_PFM_COT_EN 1'b1
+ 2 RW CORE_BUCK_ENOFFSAWPFM_H 1'b1
+ 3 RW CORE_BUCK_POW_EA_Iqx2_H 1'b1
+ 4 RW CORE_BUCK_POW_EA_Iqx3_H 1'b1
+ 5 RW CORE_BUCK_POW_EA_IqEhance_H 1'b1
+ 8:6 RW CORE_BUCK_PFM_STEP_INI 3'b0
+ 16:9 RW CORE_AUTO_SET 8'haa
+ 22:17 RW CORE_D300k_REG_MANU_CCOT 6'b010000
+ 31:23 R RSVD 9'b0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_4_2;
+ struct
+ {
+ __IO uint32_t CORE_BUCK_PFM_AOT_EN: 1;
+ __IO uint32_t CORE_BUCK_PFM_COT_EN: 1;
+ __IO uint32_t CORE_BUCK_ENOFFSAWPFM_H: 1;
+ __IO uint32_t CORE_BUCK_POW_EA_Iqx2_H: 1;
+ __IO uint32_t CORE_BUCK_POW_EA_Iqx3_H: 1;
+ __IO uint32_t CORE_BUCK_POW_EA_IqEhance_H: 1;
+ __IO uint32_t CORE_BUCK_PFM_STEP_INI: 3;
+ __IO uint32_t CORE_AUTO_SET: 8;
+ __IO uint32_t CORE_D300k_REG_MANU_CCOT: 6;
+ __I uint32_t RESERVED_0: 9;
+ } BITS_270;
+ } u_270;
+
+ /* 0x0274 0x4000_0274
+ 0 RW CORE_BUCK_PFM_AOT_EN 1'b0
+ 1 RW CORE_BUCK_PFM_COT_EN 1'b1
+ 2 RW CORE_BUCK_ENOFFSAWPFM_H 1'b1
+ 3 RW CORE_BUCK_POW_EA_Iqx2_H 1'b1
+ 4 RW CORE_BUCK_POW_EA_Iqx3_H 1'b1
+ 5 RW CORE_BUCK_POW_EA_IqEhance_H 1'b1
+ 8:6 RW CORE_BUCK_PFM_STEP_INI 3'b0
+ 16:9 RW CORE_AUTO_SET 8'haa
+ 22:17 RW CORE_D300k_REG_MANU_CCOT 6'b010000
+ 31:23 R RSVD 9'b0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_5_2;
+ struct
+ {
+ __IO uint32_t CORE_BUCK_PFM_AOT_EN: 1;
+ __IO uint32_t CORE_BUCK_PFM_COT_EN: 1;
+ __IO uint32_t CORE_BUCK_ENOFFSAWPFM_H: 1;
+ __IO uint32_t CORE_BUCK_POW_EA_Iqx2_H: 1;
+ __IO uint32_t CORE_BUCK_POW_EA_Iqx3_H: 1;
+ __IO uint32_t CORE_BUCK_POW_EA_IqEhance_H: 1;
+ __IO uint32_t CORE_BUCK_PFM_STEP_INI: 3;
+ __IO uint32_t CORE_AUTO_SET: 8;
+ __IO uint32_t CORE_D300k_REG_MANU_CCOT: 6;
+ __I uint32_t RESERVED_0: 9;
+ } BITS_274;
+ } u_274;
+
+ /* 0x0278 0x4000_0278
+ 0 RW CORE_BUCK_PFM_AOT_EN 1'b0
+ 1 RW CORE_BUCK_PFM_COT_EN 1'b1
+ 2 RW CORE_BUCK_ENOFFSAWPFM_H 1'b1
+ 3 RW CORE_BUCK_POW_EA_Iqx2_H 1'b1
+ 4 RW CORE_BUCK_POW_EA_Iqx3_H 1'b1
+ 5 RW CORE_BUCK_POW_EA_IqEhance_H 1'b1
+ 8:6 RW CORE_BUCK_PFM_STEP_INI 3'b0
+ 16:9 RW CORE_AUTO_SET 8'haa
+ 22:17 RW CORE_D300k_REG_MANU_CCOT 6'b010000
+ 31:23 R RSVD 9'b0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_6_2;
+ struct
+ {
+ __IO uint32_t CORE_BUCK_PFM_AOT_EN: 1;
+ __IO uint32_t CORE_BUCK_PFM_COT_EN: 1;
+ __IO uint32_t CORE_BUCK_ENOFFSAWPFM_H: 1;
+ __IO uint32_t CORE_BUCK_POW_EA_Iqx2_H: 1;
+ __IO uint32_t CORE_BUCK_POW_EA_Iqx3_H: 1;
+ __IO uint32_t CORE_BUCK_POW_EA_IqEhance_H: 1;
+ __IO uint32_t CORE_BUCK_PFM_STEP_INI: 3;
+ __IO uint32_t CORE_AUTO_SET: 8;
+ __IO uint32_t CORE_D300k_REG_MANU_CCOT: 6;
+ __I uint32_t RESERVED_0: 9;
+ } BITS_278;
+ } u_278;
+
+ /* 0x027C 0x4000_027c
+ 0 RW CORE_BUCK_PFM_AOT_EN 1'b0
+ 1 RW CORE_BUCK_PFM_COT_EN 1'b1
+ 2 RW CORE_BUCK_ENOFFSAWPFM_H 1'b1
+ 3 RW CORE_BUCK_POW_EA_Iqx2_H 1'b1
+ 4 RW CORE_BUCK_POW_EA_Iqx3_H 1'b1
+ 5 RW CORE_BUCK_POW_EA_IqEhance_H 1'b1
+ 8:6 RW CORE_BUCK_PFM_STEP_INI 3'b0
+ 16:9 RW CORE_AUTO_SET 8'haa
+ 22:17 RW CORE_D300k_REG_MANU_CCOT 6'b010000
+ 31:23 R RSVD 9'b0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_7_2;
+ struct
+ {
+ __IO uint32_t CORE_BUCK_PFM_AOT_EN: 1;
+ __IO uint32_t CORE_BUCK_PFM_COT_EN: 1;
+ __IO uint32_t CORE_BUCK_ENOFFSAWPFM_H: 1;
+ __IO uint32_t CORE_BUCK_POW_EA_Iqx2_H: 1;
+ __IO uint32_t CORE_BUCK_POW_EA_Iqx3_H: 1;
+ __IO uint32_t CORE_BUCK_POW_EA_IqEhance_H: 1;
+ __IO uint32_t CORE_BUCK_PFM_STEP_INI: 3;
+ __IO uint32_t CORE_AUTO_SET: 8;
+ __IO uint32_t CORE_D300k_REG_MANU_CCOT: 6;
+ __I uint32_t RESERVED_0: 9;
+ } BITS_27C;
+ } u_27C;
+
+ /* 0x0280 0x4000_0280
+ 6:0 R/W r_PMUX_GPIO_P0_0 7'h0
+ 7 R/W DUMMY 0
+ 14:8 R/W r_PMUX_GPIO_P0_1 7'h0
+ 15 R/W DUMMY 0
+ 22:16 R/W r_PMUX_GPIO_P0_2 7'h0
+ 23 R/W DUMMY 0
+ 30:24 R/W r_PMUX_GPIO_P0_3 7'h1D
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_r_PMUX_GPIO_P0_0_3;
+ struct
+ {
+ __IO uint32_t r_PMUX_GPIO_P0_0: 7;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t r_PMUX_GPIO_P0_1: 7;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t r_PMUX_GPIO_P0_2: 7;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t r_PMUX_GPIO_P0_3: 7;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_280;
+ } u_280;
+
+ /* 0x0284 0x4000_0284
+ 6:0 R/W r_PMUX_GPIO_P0_4 7'h0
+ 7 R/W DUMMY 0
+ 14:8 R/W r_PMUX_GPIO_P0_5 7'h0
+ 15 R/W DUMMY 0
+ 22:16 R/W r_PMUX_GPIO_P0_6 7'h0
+ 23 R/W DUMMY 0
+ 30:24 R/W r_PMUX_GPIO_P0_7 7'h0
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_r_PMUX_GPIO_P0_4_7;
+ struct
+ {
+ __IO uint32_t r_PMUX_GPIO_P0_4: 7;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t r_PMUX_GPIO_P0_5: 7;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t r_PMUX_GPIO_P0_6: 7;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t r_PMUX_GPIO_P0_7: 7;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_284;
+ } u_284;
+
+ /* 0x0288 0x4000_0288
+ 6:0 R/W r_PMUX_GPIO_P1_0 7'h39
+ 7 R/W DUMMY 0
+ 14:8 R/W r_PMUX_GPIO_P1_1 7'h38
+ 15 R/W DUMMY 0
+ 22:16 R/W r_PMUX_GPIO_P1_2 7'h0
+ 23 R/W DUMMY 0
+ 30:24 R/W r_PMUX_GPIO_P1_3 7'h0
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_r_PMUX_GPIO_P1_0_3;
+ struct
+ {
+ __IO uint32_t r_PMUX_GPIO_P1_0: 7;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t r_PMUX_GPIO_P1_1: 7;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t r_PMUX_GPIO_P1_2: 7;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t r_PMUX_GPIO_P1_3: 7;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_288;
+ } u_288;
+
+ /* 0x028C 0x4000_028c
+ 6:0 R/W r_PMUX_GPIO_P1_4 7'h0
+ 7 R/W DUMMY 0
+ 14:8 R/W r_PMUX_GPIO_P1_5 7'h0
+ 15 R/W DUMMY 0
+ 22:16 R/W r_PMUX_GPIO_P1_6 7'h0
+ 23 R/W DUMMY 0
+ 30:24 R/W r_PMUX_GPIO_P1_7 7'h0
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_r_PMUX_GPIO_P1_4_7;
+ struct
+ {
+ __IO uint32_t r_PMUX_GPIO_P1_4: 7;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t r_PMUX_GPIO_P1_5: 7;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t r_PMUX_GPIO_P1_6: 7;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t r_PMUX_GPIO_P1_7: 7;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_28C;
+ } u_28C;
+
+ /* 0x0290 0x4000_0290
+ 6:0 R/W r_PMUX_GPIO_P2_0 7'h0
+ 7 R/W DUMMY 0
+ 14:8 R/W r_PMUX_GPIO_P2_1 7'h0
+ 15 R/W DUMMY 0
+ 22:16 R/W r_PMUX_GPIO_P2_2 7'h0
+ 23 R/W DUMMY 0
+ 30:24 R/W r_PMUX_GPIO_P2_3 7'h0
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_r_PMUX_GPIO_P2_0_3;
+ struct
+ {
+ __IO uint32_t r_PMUX_GPIO_P2_0: 7;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t r_PMUX_GPIO_P2_1: 7;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t r_PMUX_GPIO_P2_2: 7;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t r_PMUX_GPIO_P2_3: 7;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_290;
+ } u_290;
+
+ /* 0x0294 0x4000_0294
+ 6:0 R/W r_PMUX_GPIO_P2_4 7'h0
+ 7 R/W DUMMY 0
+ 14:8 R/W r_PMUX_GPIO_P2_5 7'h0
+ 15 R/W DUMMY 0
+ 22:16 R/W r_PMUX_GPIO_P2_6 7'h0
+ 23 R/W DUMMY 0
+ 30:24 R/W r_PMUX_GPIO_P2_7 7'h0
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_r_PMUX_GPIO_P2_4_7;
+ struct
+ {
+ __IO uint32_t r_PMUX_GPIO_P2_4: 7;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t r_PMUX_GPIO_P2_5: 7;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t r_PMUX_GPIO_P2_6: 7;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t r_PMUX_GPIO_P2_7: 7;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_294;
+ } u_294;
+
+ /* 0x0298 0x4000_0298
+ 6:0 R/W r_PMUX_GPIO_P3_0 7'h23
+ 7 R/W DUMMY 0
+ 14:8 R/W r_PMUX_GPIO_P3_1 7'h24
+ 15 R/W DUMMY 0
+ 22:16 R/W r_PMUX_GPIO_P3_2 7'h0
+ 23 R/W DUMMY 0
+ 30:24 R/W r_PMUX_GPIO_P3_3 7'h0
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_r_PMUX_GPIO_P3_0_3;
+ struct
+ {
+ __IO uint32_t r_PMUX_GPIO_P3_0: 7;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t r_PMUX_GPIO_P3_1: 7;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t r_PMUX_GPIO_P3_2: 7;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t r_PMUX_GPIO_P3_3: 7;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_298;
+ } u_298;
+
+ /* 0x029C 0x4000_029c
+ 6:0 R/W r_PMUX_GPIO_P3_4 7'h0
+ 7 R/W DUMMY 0
+ 14:8 R/W r_PMUX_GPIO_P3_5 7'h0
+ 15 R/W DUMMY 0
+ 22:16 R/W r_PMUX_GPIO_P3_6 7'h0
+ 23 R/W DUMMY 0
+ 30:24 R/W r_PMUX_GPIO_P3_7 7'h0
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_r_PMUX_GPIO_P3_4_7;
+ struct
+ {
+ __IO uint32_t r_PMUX_GPIO_P3_4: 7;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t r_PMUX_GPIO_P3_5: 7;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t r_PMUX_GPIO_P3_6: 7;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t r_PMUX_GPIO_P3_7: 7;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_29C;
+ } u_29C;
+
+ /* 0x02A0 0x4000_02a0
+ 6:0 R/W r_PMUX_GPIO_P4_0 7'h2e
+ 7 R/W DUMMY 0
+ 14:8 R/W r_PMUX_GPIO_P4_1 7'h2f
+ 15 R/W DUMMY 0
+ 22:16 R/W r_PMUX_GPIO_P4_2 7'h30
+ 23 R/W DUMMY 0
+ 30:24 R/W r_PMUX_GPIO_P4_3 7'h2d
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_r_PMUX_GPIO_P4_0_3;
+ struct
+ {
+ __IO uint32_t r_PMUX_GPIO_P4_0: 7;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t r_PMUX_GPIO_P4_1: 7;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t r_PMUX_GPIO_P4_2: 7;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t r_PMUX_GPIO_P4_3: 7;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_2A0;
+ } u_2A0;
+
+ /* 0x02A4 0x4000_02a4
+ 6:0 R/W r_PMUX_GPIO_H_0 7'h0
+ 7 R/W DUMMY 0
+ 14:8 R/W r_PMUX_GPIO_H_1 7'h0
+ 15 R/W DUMMY 0
+ 22:16 R/W r_PMUX_GPIO_H_2 7'h0
+ 31:23 R/W DUMMY 9'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_r_PMUX_GPIO_H_0_2;
+ struct
+ {
+ __IO uint32_t r_PMUX_GPIO_H_0: 7;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t r_PMUX_GPIO_H_1: 7;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t r_PMUX_GPIO_H_2: 7;
+ __IO uint32_t RESERVED_0: 9;
+ } BITS_2A4;
+ } u_2A4;
+
+ /* 0x02A8 0x4000_02a8
+ 3:0 R/W r_PMUX_TEST_MODE 4'h1
+ 6:4 R/W DUMMY 0
+ 7 R/W r_PMUX_TEST_MODE_EN 0
+ 8 R/W DUMMY 0
+ 9 R/W DUMMY 0
+ 11:10 R/W r_PMUX_1_WIRE_UART_EN 2'h0
+ 15:12 R/W DUMMY 6'h0
+ 19:16 R/W r_PMUX_DBG_MODE_SEL 4'h2
+ 20 R/W DUMMY 0
+ 21 R/W DUMMY 0
+ 22 R/W DUMMY 0
+ 23 R/W r_PMUX_DIG_SMUX_EN 0
+ 24 R/W r_PON_PMUX_SPIM0_EN 0
+ 25 R/W r_PMUX_SPIM_EN_OPT 0
+ 26 R/W r_PMUX_FLASH_EXTC_EN 0
+ 27 R/W r_PMUX_FLASH_EN 0
+ 28 R/W DUMMY 0
+ 29 R/W DUMMY 0
+ 30 R/W DUMMY 0
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_r_PMUX_TEST_MODE;
+ struct
+ {
+ __IO uint32_t r_PMUX_TEST_MODE: 4;
+ __IO uint32_t RESERVED_10: 3;
+ __IO uint32_t r_PMUX_TEST_MODE_EN: 1;
+ __IO uint32_t RESERVED_9: 1;
+ __IO uint32_t RESERVED_8: 1;
+ __IO uint32_t r_PMUX_1_WIRE_UART_EN: 2;
+ __IO uint32_t RESERVED_7: 4;
+ __IO uint32_t r_PMUX_DBG_MODE_SEL: 4;
+ __IO uint32_t RESERVED_6: 1;
+ __IO uint32_t RESERVED_5: 1;
+ __IO uint32_t RESERVED_4: 1;
+ __IO uint32_t r_PMUX_DIG_SMUX_EN: 1;
+ __IO uint32_t r_PON_PMUX_SPIM0_EN: 1;
+ __IO uint32_t r_PMUX_SPIM_EN_OPT: 1;
+ __IO uint32_t r_PMUX_FLASH_EXTC_EN: 1;
+ __IO uint32_t r_PMUX_FLASH_EN: 1;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_2A8;
+ } u_2A8;
+
+ /* 0x02AC 0x4000_02ac
+ 31:0 R/W DUMMY 32'h0
+ */
+ __IO uint32_t PERION_REG_DUMMY_2AC;
+
+ /* 0x02B0 0x4000_02b0
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_2B0;
+
+ /* 0x02B4 0x4000_02b4
+ 31:0 R/W DUMMY 32'h0
+ */
+ __IO uint32_t PERION_REG_DUMMY_2B4;
+
+ /* 0x02B8 0x4000_02b8
+ 31:0 R/W DUMMY 32'h0
+ */
+ __IO uint32_t PERION_REG_DUMMY_2B8;
+
+ /* 0x02BC 0x4000_02bc
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_2BC;
+
+ /* 0x02C0 0x4000_02c0
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_2C0;
+
+ /* 0x02C4 0x4000_02c4
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_2C4;
+
+ /* 0x02C8 0x4000_02c8
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_2C8;
+
+ /* 0x02CC 0x4000_02cc
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_2CC;
+
+ /* 0x02D0 0x4000_02d0
+ 1:0 R/W DUMMY 2'h0
+ 3:2 R/W DUMMY 2'h0
+ 4 R/W DUMMY 0
+ 5 R/W DUMMY 0
+ 6 R/W DUMMY 0
+ 7 R/W DUMMY 0
+ 8 R/W DUMMY 0
+ 31:9 R/W DUMMY 23'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_RSVD_2D0;
+ struct
+ {
+ __IO uint32_t RESERVED_7: 2;
+ __IO uint32_t RESERVED_6: 2;
+ __IO uint32_t RESERVED_5: 1;
+ __IO uint32_t RESERVED_4: 1;
+ __IO uint32_t RESERVED_3: 1;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t RESERVED_0: 23;
+ } BITS_2D0;
+ } u_2D0;
+
+ /* 0x02D4 0x4000_02d4
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_2D4;
+
+ /* 0x02D8 0x4000_02d8
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_2D8;
+
+ /* 0x02DC 0x4000_02dc
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_2DC;
+
+ /* 0x02E0 0x4000_02e0
+ 7:0 R/W DUMMY 8'hC0
+ 18:8 R RSVD 11'h0
+ 31:19 R/W DUMMY 13'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_RSVD_2E0;
+ struct
+ {
+ __IO uint32_t RESERVED_2: 8;
+ __I uint32_t RESERVED_1: 11;
+ __IO uint32_t RESERVED_0: 13;
+ } BITS_2E0;
+ } u_2E0;
+
+ /* 0x02E4 0x4000_02e4
+ 15:0 R/W DUMMY 16'h0
+ 25:16 R RSVD 10'h0
+ 31:26 R/W DUMMY 6'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_RSVD_2E4;
+ struct
+ {
+ __IO uint32_t RESERVED_2: 16;
+ __I uint32_t RESERVED_1: 10;
+ __IO uint32_t RESERVED_0: 6;
+ } BITS_2E4;
+ } u_2E4;
+
+ /* 0x02E8 0x4000_02e8
+ 0 R/W CORE_BUCK_POW_EA_Initial 1'b1
+ 1 R/W CORE_BUCK_FPWM_H 1'b1
+ 2 R/W CORE_BG_ENPC_DIGI 1'b0
+ 7:3 R/W CORE_BG_VDIGI_TUNE 5'b10111
+ 8 R/W DUMMY 1'b0
+ 9 R/W CORE_BUCK_PMOS_DRIH_H 1'b1
+ 10 R/W CORE_BUCK_PMOS_DRIL_H 1'b1
+ 12:11 R/W CORE_BUCK_OCPRES_H 2'b01
+ 17:13 R/W DUMMY 0
+ 20:18 R/W CORE_BUCK_VREFOCP_H 3'b001
+ 26:21 R/W CORE_BUCK_SWRTUNE_H 6'b011101
+ 30:27 R/W CORE_BUCK_VREFPFM_H 4'b1011
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_0_0;
+ struct
+ {
+ __IO uint32_t CORE_BUCK_POW_EA_Initial: 1;
+ __IO uint32_t CORE_BUCK_FPWM_H: 1;
+ __IO uint32_t CORE_BG_ENPC_DIGI: 1;
+ __IO uint32_t CORE_BG_VDIGI_TUNE: 5;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t CORE_BUCK_PMOS_DRIH_H: 1;
+ __IO uint32_t CORE_BUCK_PMOS_DRIL_H: 1;
+ __IO uint32_t CORE_BUCK_OCPRES_H: 2;
+ __IO uint32_t RESERVED_1: 5;
+ __IO uint32_t CORE_BUCK_VREFOCP_H: 3;
+ __IO uint32_t CORE_BUCK_SWRTUNE_H: 6;
+ __IO uint32_t CORE_BUCK_VREFPFM_H: 4;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_2E8;
+ } u_2E8;
+
+ /* 0x02EC 0x4000_02ec
+ 0 R/W CORE_BUCK_POW_EA_Initial 1'b1
+ 1 R/W CORE_BUCK_FPWM_H 1'b1
+ 2 R/W CORE_BG_ENPC_DIGI 1'b0
+ 7:3 R/W CORE_BG_VDIGI_TUNE 5'b10111
+ 8 R/W DUMMY 1'b0
+ 9 R/W CORE_BUCK_PMOS_DRIH_H 1'b1
+ 10 R/W CORE_BUCK_PMOS_DRIL_H 1'b1
+ 12:11 R/W CORE_BUCK_OCPRES_H 2'b01
+ 17:13 R/W dummy 0
+ 20:18 R/W CORE_BUCK_VREFOCP_H 3'b001
+ 26:21 R/W CORE_BUCK_SWRTUNE_H 6'b011101
+ 30:27 R/W CORE_BUCK_VREFPFM_H 4'b1011
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_4_0;
+ struct
+ {
+ __IO uint32_t CORE_BUCK_POW_EA_Initial: 1;
+ __IO uint32_t CORE_BUCK_FPWM_H: 1;
+ __IO uint32_t CORE_BG_ENPC_DIGI: 1;
+ __IO uint32_t CORE_BG_VDIGI_TUNE: 5;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t CORE_BUCK_PMOS_DRIH_H: 1;
+ __IO uint32_t CORE_BUCK_PMOS_DRIL_H: 1;
+ __IO uint32_t CORE_BUCK_OCPRES_H: 2;
+ __IO uint32_t RESERVED_1: 5;
+ __IO uint32_t CORE_BUCK_VREFOCP_H: 3;
+ __IO uint32_t CORE_BUCK_SWRTUNE_H: 6;
+ __IO uint32_t CORE_BUCK_VREFPFM_H: 4;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_2EC;
+ } u_2EC;
+
+ /* 0x02F0 0x4000_02f0
+ 0 R/W CORE_BUCK_POW_EA_Initial 1'b1
+ 1 R/W CORE_BUCK_FPWM_H 1'b1
+ 2 R/W CORE_BG_ENPC_DIGI 1'b0
+ 7:3 R/W CORE_BG_VDIGI_TUNE 5'b10111
+ 8 R/W DUMMY 1'b0
+ 9 R/W CORE_BUCK_PMOS_DRIH_H 1'b1
+ 10 R/W CORE_BUCK_PMOS_DRIL_H 1'b1
+ 12:11 R/W CORE_BUCK_OCPRES_H 2'b01
+ 17:13 R/W dummy 0
+ 20:18 R/W CORE_BUCK_VREFOCP_H 3'b001
+ 26:21 R/W CORE_BUCK_SWRTUNE_H 6'b011101
+ 30:27 R/W CORE_BUCK_VREFPFM_H 4'b1011
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_5_0;
+ struct
+ {
+ __IO uint32_t CORE_BUCK_POW_EA_Initial: 1;
+ __IO uint32_t CORE_BUCK_FPWM_H: 1;
+ __IO uint32_t CORE_BG_ENPC_DIGI: 1;
+ __IO uint32_t CORE_BG_VDIGI_TUNE: 5;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t CORE_BUCK_PMOS_DRIH_H: 1;
+ __IO uint32_t CORE_BUCK_PMOS_DRIL_H: 1;
+ __IO uint32_t CORE_BUCK_OCPRES_H: 2;
+ __IO uint32_t RESERVED_1: 5;
+ __IO uint32_t CORE_BUCK_VREFOCP_H: 3;
+ __IO uint32_t CORE_BUCK_SWRTUNE_H: 6;
+ __IO uint32_t CORE_BUCK_VREFPFM_H: 4;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_2F0;
+ } u_2F0;
+
+ /* 0x02F4 0x4000_02f4
+ 0 R/W CORE_BUCK_POW_EA_Initial 1'b1
+ 1 R/W CORE_BUCK_FPWM_H 1'b1
+ 2 R/W CORE_BG_ENPC_DIGI 1'b0
+ 7:3 R/W CORE_BG_VDIGI_TUNE 5'b10111
+ 8 R/W DUMMY 1'b0
+ 9 R/W CORE_BUCK_PMOS_DRIH_H 1'b1
+ 10 R/W CORE_BUCK_PMOS_DRIL_H 1'b1
+ 12:11 R/W CORE_BUCK_OCPRES_H 2'b01
+ 17:13 R/W dummy 0
+ 20:18 R/W CORE_BUCK_VREFOCP_H 3'b001
+ 26:21 R/W CORE_BUCK_SWRTUNE_H 6'b011101
+ 30:27 R/W CORE_BUCK_VREFPFM_H 4'b1011
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_6_0;
+ struct
+ {
+ __IO uint32_t CORE_BUCK_POW_EA_Initial: 1;
+ __IO uint32_t CORE_BUCK_FPWM_H: 1;
+ __IO uint32_t CORE_BG_ENPC_DIGI: 1;
+ __IO uint32_t CORE_BG_VDIGI_TUNE: 5;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t CORE_BUCK_PMOS_DRIH_H: 1;
+ __IO uint32_t CORE_BUCK_PMOS_DRIL_H: 1;
+ __IO uint32_t CORE_BUCK_OCPRES_H: 2;
+ __IO uint32_t RESERVED_1: 5;
+ __IO uint32_t CORE_BUCK_VREFOCP_H: 3;
+ __IO uint32_t CORE_BUCK_SWRTUNE_H: 6;
+ __IO uint32_t CORE_BUCK_VREFPFM_H: 4;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_2F4;
+ } u_2F4;
+
+ /* 0x02F8 0x4000_02f8
+ 0 R/W CORE_BUCK_POW_EA_Initial 1'b1
+ 1 R/W CORE_BUCK_FPWM_H 1'b1
+ 2 R/W CORE_BG_ENPC_DIGI 1'b0
+ 7:3 R/W CORE_BG_VDIGI_TUNE 5'b10111
+ 8 R/W DUMMY 1'b0
+ 9 R/W CORE_BUCK_PMOS_DRIH_H 1'b1
+ 10 R/W CORE_BUCK_PMOS_DRIL_H 1'b1
+ 12:11 R/W CORE_BUCK_OCPRES_H 2'b01
+ 17:13 R/W dummy 5'h0
+ 20:18 R/W CORE_BUCK_VREFOCP_H 3'b001
+ 26:21 R/W CORE_BUCK_SWRTUNE_H 6'b011101
+ 30:27 R/W CORE_BUCK_VREFPFM_H 4'b1011
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_7_0;
+ struct
+ {
+ __IO uint32_t CORE_BUCK_POW_EA_Initial: 1;
+ __IO uint32_t CORE_BUCK_FPWM_H: 1;
+ __IO uint32_t CORE_BG_ENPC_DIGI: 1;
+ __IO uint32_t CORE_BG_VDIGI_TUNE: 5;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t CORE_BUCK_PMOS_DRIH_H: 1;
+ __IO uint32_t CORE_BUCK_PMOS_DRIL_H: 1;
+ __IO uint32_t CORE_BUCK_OCPRES_H: 2;
+ __IO uint32_t RESERVED_1: 5;
+ __IO uint32_t CORE_BUCK_VREFOCP_H: 3;
+ __IO uint32_t CORE_BUCK_SWRTUNE_H: 6;
+ __IO uint32_t CORE_BUCK_VREFPFM_H: 4;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_2F8;
+ } u_2F8;
+
+ /* 0x02FC 0x4000_02fc
+ 5:0 R/W CORE_SWR_PAR_TAB_0[36:31] 6'b1
+ 11:6 R/W CORE_SWR_PAR_TAB_4[36:31] 6'b1
+ 17:12 R/W CORE_SWR_PAR_TAB_5[36:31] 6'b1
+ 23:18 R/W CORE_SWR_PAR_TAB_6[36:31] 6'b1
+ 29:24 R/W CORE_SWR_PAR_TAB_7[36:31] 6'b1
+ 31:30 R/W DUMMY 2'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_CORE_SWR_PAR_TAB_ext;
+ struct
+ {
+ __IO uint32_t CORE_SWR_PAR_TAB_0_36_31: 6;
+ __IO uint32_t CORE_SWR_PAR_TAB_4_36_31: 6;
+ __IO uint32_t CORE_SWR_PAR_TAB_5_36_31: 6;
+ __IO uint32_t CORE_SWR_PAR_TAB_6_36_31: 6;
+ __IO uint32_t CORE_SWR_PAR_TAB_7_36_31: 6;
+ __IO uint32_t RESERVED_0: 2;
+ } BITS_2FC;
+ } u_2FC;
+
+ /* 0x0300 0x4000_0300
+ 7:0 R/W PON_PERI_DLYSEL_CTRL 8'h0
+ 15:8 R/W DUMMY 8'h0
+ 23:16 R/W DUMMY 8'h0
+ 24 R/W r_flash0_clk_inv_en 0
+ 25 R/W DUMMY 0
+ 26 R/W DUMMY 0
+ 30:27 R/W DUMMY 3'h0
+ 31 R/W r_spic2_dma_tx_req_as_single 0
+ */
+ union
+ {
+ __IO uint32_t PERION_PON_PERI_DLYSEL_CTRL;
+ struct
+ {
+ __IO uint32_t PON_PERI_DLYSEL_CTRL: 8;
+ __IO uint32_t RESERVED_4: 8;
+ __IO uint32_t RESERVED_3: 8;
+ __IO uint32_t r_flash0_clk_inv_en: 1;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t RESERVED_0: 4;
+ __IO uint32_t r_spic2_dma_tx_req_as_single: 1;
+ } BITS_300;
+ } u_300;
+
+ /* 0x0304 0x4000_0304
+ 31:0 R/W DUMMY 32'h1FC00001
+ */
+ __IO uint32_t PERION_REG_DUMMY_304;
+
+ /* 0x0308 0x4000_0308
+ 0 R/W PON_SPIO_MST 0
+ 3:1 R/W DUMMY 3'h0
+ 4 R/W PON_SPI0_BRG_EN 0
+ 5 R/W PON_SPI0_H2S_BRG_EN 0
+ 6 R/W PON_SPI1_BRG_EN 0
+ 7 R/W r_spi0_clk_src_sel 0
+ 8 R/W r_spi1_clk_src_sel 0
+ 9 R/W r_sclk_irrc_src_sel 0
+ 31:10 R/W DUMMY 22'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_RSVD_308;
+ struct
+ {
+ __IO uint32_t PON_SPIO_MST: 1;
+ __IO uint32_t RESERVED_1: 3;
+ __IO uint32_t PON_SPI0_BRG_EN: 1;
+ __IO uint32_t PON_SPI0_H2S_BRG_EN: 1;
+ __IO uint32_t PON_SPI1_BRG_EN: 1;
+ __IO uint32_t r_spi0_clk_src_sel: 1;
+ __IO uint32_t r_spi1_clk_src_sel: 1;
+ __IO uint32_t r_sclk_irrc_src_sel: 1;
+ __IO uint32_t RESERVED_0: 22;
+ } BITS_308;
+ } u_308;
+
+ __IO uint32_t RSVD_0x30c[3];
+
+ /* 0x0318 0x4000_0318
+ 23:0 R RSVD 24'd0
+ 31:24 R/W DUMMY 8'd0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_DUMMY_318;
+ struct
+ {
+ __I uint32_t RESERVED_1: 24;
+ __IO uint32_t RESERVED_0: 8;
+ } BITS_318;
+ } u_318;
+
+ __IO uint32_t RSVD_0x31c[1];
+
+ /* 0x0320 0x4000_0320
+ 15:0 R/W DUMMY 16'h7E02
+ 31:16 R/W DUMMY 16'h0912
+ */
+ union
+ {
+ __IO uint32_t PERION_BT_ANAPAR_PLL;
+ struct
+ {
+ __IO uint32_t RESERVED_1: 16;
+ __IO uint32_t RESERVED_0: 16;
+ } BITS_320;
+ } u_320;
+
+ /* 0x0324 0x4000_0324
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_324;
+
+ /* 0x0328 0x4000_0328
+ 31:0 R RSVD 32'hEAEAEAEA
+ */
+ __IO uint32_t PERION_REG_RSVD_328;
+
+ /* 0x032C 0x4000_032c
+ 3:0 R OSC40_FSET 4'h0
+ 7:4 R RSVD 4'h0
+ 31:8 R/W DUMMY 24'h000109
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_DUMMY_32C;
+ struct
+ {
+ __I uint32_t OSC40_FSET: 4;
+ __I uint32_t RESERVED_1: 4;
+ __IO uint32_t RESERVED_0: 24;
+ } BITS_32C;
+ } u_32C;
+
+ /* 0x0330 0x4000_0330
+ 0 R/W rst_n_aac 0
+ 1 R/W Offset_plus 0
+ 7:2 R/W XAAC_GM_offset 6'b000000
+ 8 R/W GM_STEP 0
+ 14:9 R/W GM_INIT 6'b111110
+ 17:15 R/W XTAL_CLK_SET 3'b101
+ 23:18 R/W GM_STUP 6'b111111
+ 29:24 R/W GM_MANUAL 6'b111111
+ 30 R/W r_EN_XTAL_AAC_DIGI 0
+ 31 R/W r_EN_XTAL_AAC_TRIG 0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_AAC_0;
+ struct
+ {
+ __IO uint32_t rst_n_aac: 1;
+ __IO uint32_t Offset_plus: 1;
+ __IO uint32_t XAAC_GM_offset: 6;
+ __IO uint32_t GM_STEP: 1;
+ __IO uint32_t GM_INIT: 6;
+ __IO uint32_t XTAL_CLK_SET: 3;
+ __IO uint32_t GM_STUP: 6;
+ __IO uint32_t GM_MANUAL: 6;
+ __IO uint32_t r_EN_XTAL_AAC_DIGI: 1;
+ __IO uint32_t r_EN_XTAL_AAC_TRIG: 1;
+ } BITS_330;
+ } u_330;
+
+ /* 0x0334 0x4000_0334
+ 0 R XAAC_BUSY 0
+ 1 R XAAC_READY 0
+ 7:2 R XTAL_GM_OUT 6'h3F
+ 11:8 R xaac_curr_state 4'h0
+ 12 R/W EN_XTAL_AAC_GM 0
+ 13 R/W EN_XTAL_AAC_PKDET 0
+ 14 R XTAL_PKDET_OUT 0
+ 15 R/W DUMMY 0
+ 31:16 R/W DUMMY 16'h0129
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_AAC_1;
+ struct
+ {
+ __I uint32_t XAAC_BUSY: 1;
+ __I uint32_t XAAC_READY: 1;
+ __I uint32_t XTAL_GM_OUT: 6;
+ __I uint32_t xaac_curr_state: 4;
+ __IO uint32_t EN_XTAL_AAC_GM: 1;
+ __IO uint32_t EN_XTAL_AAC_PKDET: 1;
+ __I uint32_t XTAL_PKDET_OUT: 1;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t RESERVED_0: 16;
+ } BITS_334;
+ } u_334;
+
+ /* 0x0338 0x4000_0338
+ 0 R/W disable_pll_pre_gating 0
+ 15:1 R/W DUMMY 15'h0
+ 17:16 R/W DUMMY 2'h3
+ 23:18 R RSVD 6'h0
+ 24 R BT_PLL_READY 0
+ 25 R XTAL_OK 0
+ 31:26 R RSVD 6'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_XTAL_PLL;
+ struct
+ {
+ __IO uint32_t disable_pll_pre_gating: 1;
+ __IO uint32_t RESERVED_3: 15;
+ __IO uint32_t RESERVED_2: 2;
+ __I uint32_t RESERVED_1: 6;
+ __I uint32_t BT_PLL_READY: 1;
+ __I uint32_t XTAL_OK: 1;
+ __I uint32_t RESERVED_0: 6;
+ } BITS_338;
+ } u_338;
+
+ /* 0x033c 0x4000_033c
+ 0 R/W resetn 0
+ 1 R/W EN_XTAL_PDCK_DIGI 1
+ 2 R/W PDCK_SEARCH_MODE 0
+ 4:3 R/W PDCK_WAIT_CYC[1:0] 2'b01
+ 9:5 R/W VREF_MANUAL[4:0] 5'b10000
+ 14:10 R/W VREF_INIT[4:0] 5'b11111
+ 16:15 R/W XTAL_PDCK_UNIT[1:0] 2'b10
+ 21:17 R/W XPDCK_VREF_SEL[4:0] 5'b00000
+ 22 R/W PDCK_LPOW 0
+ 27:23 R/W Reserved 5'h0
+ 31:28 R pdck_state[3:0] 4'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_XTAL_PDCK;
+ struct
+ {
+ __IO uint32_t resetn: 1;
+ __IO uint32_t EN_XTAL_PDCK_DIGI: 1;
+ __IO uint32_t PDCK_SEARCH_MODE: 1;
+ __IO uint32_t PDCK_WAIT_CYC_1_0: 2;
+ __IO uint32_t VREF_MANUAL_4_0: 5;
+ __IO uint32_t VREF_INIT_4_0: 5;
+ __IO uint32_t XTAL_PDCK_UNIT_1_0: 2;
+ __IO uint32_t XPDCK_VREF_SEL_4_0: 5;
+ __IO uint32_t PDCK_LPOW: 1;
+ __IO uint32_t RESERVED_0: 5;
+ __I uint32_t pdck_state_3_0: 4;
+ } BITS_33c;
+ } u_33c;
+
+ /* 0x0340 0x4000_0340
+ 31:0 R/W DUMMY 32'hAAAAAAAA
+ */
+ __IO uint32_t PERION_REG_DUMMY_340;
+
+ /* 0x0344 0x4000_0344
+ 7:0 R/W dbnc_cnt_limit 8'h1
+ 11:8 R/W dbnc_div_sel 4'h1
+ 12 R/W dbnc_div_en 1'b0
+ 15:13 R/W DUMMY 3'h0
+ 31:16 R/W DUMMY 16'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_DBNC;
+ struct
+ {
+ __IO uint32_t dbnc_cnt_limit: 8;
+ __IO uint32_t dbnc_div_sel: 4;
+ __IO uint32_t dbnc_div_en: 1;
+ __IO uint32_t RESERVED_1: 3;
+ __IO uint32_t RESERVED_0: 16;
+ } BITS_344;
+ } u_344;
+
+ /* 0x0348 0x4000_0348
+ 31:0 R RSVD 32'h0
+ */
+ __IO uint32_t PERION_REG_RSVD_348;
+
+ /* 0x034C 0x4000_034c
+ 31:0 R RSVD 32'h0
+ */
+ __IO uint32_t PERION_REG_RSVD_34C;
+
+ __IO uint32_t RSVD_0x350[3];
+
+ /* 0x035C 0x4000_035c
+ 0 R/W BIT_PERI_GT3_CLK_SEL 0
+ 1 R/W BIT_PERI_GT5_CLK_SEL 0
+ 2 R/W BIT_PERI_GT7_CLK_SEL 0
+ 7:3 R/W DUMMY 5'h0
+ 8 R/W DUMMY 0
+ 10:9 R/W BIT_PERI_UART0_CLK_DIV 2'h0
+ 12:11 R/W BIT_PERI_UART1_CLK_DIV 2'h0
+ 14:13 R/W BIT_PERI_UART2_CLK_DIV 2'h0
+ 16:15 R/W BIT_PERI_I2C0_CLK_DIV 2'h0
+ 18:17 R/W BIT_PERI_I2C1_CLK_DIV 2'h0
+ 20:19 R/W BIT_PERI_SPI0_CLK_DIV 2'h0
+ 22:21 R/W BIT_PERI_SPI1_CLK_DIV 2'h0
+ 23 R/W DUMMY 0
+ 24 R/W TIMER2_CLK_SRC_SEL 0
+ 25 R/W TIMER3_CLK_SRC_SEL 0
+ 26 R/W TIMER4_CLK_SRC_SEL 0
+ 27 R/W TIMER5_CLK_SRC_SEL 0
+ 28 R/W TIMER6_CLK_SRC_SEL 0
+ 29 R/W TIMER7_CLK_SRC_SEL 0
+ 31:30 R/W DUMMY 2'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_PERI_GTIMER_CLK_SRC1;
+ struct
+ {
+ __IO uint32_t BIT_PERI_GT3_CLK_SEL: 1;
+ __IO uint32_t BIT_PERI_GT5_CLK_SEL: 1;
+ __IO uint32_t BIT_PERI_GT7_CLK_SEL: 1;
+ __IO uint32_t RESERVED_3: 5;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t BIT_PERI_UART0_CLK_DIV: 2;
+ __IO uint32_t BIT_PERI_UART1_CLK_DIV: 2;
+ __IO uint32_t BIT_PERI_UART2_CLK_DIV: 2;
+ __IO uint32_t BIT_PERI_I2C0_CLK_DIV: 2;
+ __IO uint32_t BIT_PERI_I2C1_CLK_DIV: 2;
+ __IO uint32_t BIT_PERI_SPI0_CLK_DIV: 2;
+ __IO uint32_t BIT_PERI_SPI1_CLK_DIV: 2;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t TIMER2_CLK_SRC_SEL: 1;
+ __IO uint32_t TIMER3_CLK_SRC_SEL: 1;
+ __IO uint32_t TIMER4_CLK_SRC_SEL: 1;
+ __IO uint32_t TIMER5_CLK_SRC_SEL: 1;
+ __IO uint32_t TIMER6_CLK_SRC_SEL: 1;
+ __IO uint32_t TIMER7_CLK_SRC_SEL: 1;
+ __IO uint32_t RESERVED_0: 2;
+ } BITS_35C;
+ } u_35C;
+
+ /* 0x0360 0x4000_0360
+ 2:0 R/W BIT_PERI_GT0_CLK_DIV 3'h0
+ 5:3 R/W BIT_PERI_GT1_CLK_DIV 3'h0
+ 7:6 R/W DUMMY 2'h0
+ 8 R/W BIT_TIMER_CLK_32K_EN 1
+ 9 R/W BIT_TIMER_CLK_f40M_EN 1
+ 10 R/W timer_apb_clk_disable 0
+ 11 R/W gpio_intr_trig_en 0
+ 12 R/W DUMMY 1'h0
+ 15:13 R/W BIT_PERI_GT2_CLK_DIV 3'h0
+ 18:16 R/W BIT_PERI_GT3_CLK_DIV 3'h0
+ 21:19 R/W BIT_PERI_GT4_CLK_DIV 3'h0
+ 24:22 R/W BIT_PERI_GT5_CLK_DIV 3'h0
+ 27:25 R/W BIT_PERI_GT6_CLK_DIV 3'h0
+ 30:28 R/W BIT_PERI_GT7_CLK_DIV 3'h0
+ 31 R/W DUMMY 0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_PERI_GTIMER_CLK_SRC0;
+ struct
+ {
+ __IO uint32_t BIT_PERI_GT0_CLK_DIV: 3;
+ __IO uint32_t BIT_PERI_GT1_CLK_DIV: 3;
+ __IO uint32_t RESERVED_2: 2;
+ __IO uint32_t BIT_TIMER_CLK_32K_EN: 1;
+ __IO uint32_t BIT_TIMER_CLK_f40M_EN: 1;
+ __IO uint32_t timer_apb_clk_disable: 1;
+ __IO uint32_t gpio_intr_trig_en: 1;
+ __IO uint32_t RESERVED_1: 1;
+ __IO uint32_t BIT_PERI_GT2_CLK_DIV: 3;
+ __IO uint32_t BIT_PERI_GT3_CLK_DIV: 3;
+ __IO uint32_t BIT_PERI_GT4_CLK_DIV: 3;
+ __IO uint32_t BIT_PERI_GT5_CLK_DIV: 3;
+ __IO uint32_t BIT_PERI_GT6_CLK_DIV: 3;
+ __IO uint32_t BIT_PERI_GT7_CLK_DIV: 3;
+ __IO uint32_t RESERVED_0: 1;
+ } BITS_360;
+ } u_360;
+
+ /* 0x0364 0x4000_0364
+ 7:0 R/W dead_zone_size 8'h0
+ 8 R/W emg_stop 0
+ 9 R/W stop_state[0] 0
+ 10 R/W stop_state[1] 0
+ 11 R/W DUMMY 0
+ 12 R/W dead_zone_en 0
+ 13 R/W pwm_pn_invserse_sel 0
+ 15:14 R/W DUMMY 2'h0
+ 16 R/W r_clk_timer_pwm_wrap0_sel 0
+ 17 R/W r_FEN_TIMER_PWM_WRAP0 0
+ 18 R/W r_CKE_TIMER_PWM_WRAP0 0
+ 19 R/W r_clk_timer_pwm_wrap0_sel1 0
+ 31:20 R/W DUMMY 12'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_PERI_PWM2_DZONE_CTRL;
+ struct
+ {
+ __IO uint32_t dead_zone_size: 8;
+ __IO uint32_t emg_stop: 1;
+ __IO uint32_t stop_state_0: 1;
+ __IO uint32_t stop_state_1: 1;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t dead_zone_en: 1;
+ __IO uint32_t pwm_pn_invserse_sel: 1;
+ __IO uint32_t RESERVED_1: 2;
+ __IO uint32_t r_clk_timer_pwm_wrap0_sel: 1;
+ __IO uint32_t r_FEN_TIMER_PWM_WRAP0: 1;
+ __IO uint32_t r_CKE_TIMER_PWM_WRAP0: 1;
+ __IO uint32_t r_clk_timer_pwm_wrap0_sel1: 1;
+ __IO uint32_t RESERVED_0: 12;
+ } BITS_364;
+ } u_364;
+
+ /* 0x0368 0x4000_0368
+ 7:0 R/W dead_zone_size 8'h0
+ 8 R/W emg_stop 0
+ 9 R/W stop_state[0] 0
+ 10 R/W stop_state[1] 0
+ 11 R/W DUMMY 0
+ 12 R/W dead_zone_en 0
+ 13 R/W pwm_pn_invserse_sel 0
+ 15:14 R/W DUMMY 2'h0
+ 16 R/W r_clk_timer_pwm_wrap0_sel 0
+ 17 R/W r_FEN_TIMER_PWM_WRAP0 0
+ 18 R/W r_CKE_TIMER_PWM_WRAP0 0
+ 19 R/W r_clk_timer_pwm_wrap0_sel1 0
+ 31:20 R/W DUMMY 12'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_PERI_ENHTIMER0_DZONE_CTRL;
+ struct
+ {
+ __IO uint32_t dead_zone_size: 8;
+ __IO uint32_t emg_stop: 1;
+ __IO uint32_t stop_state_0: 1;
+ __IO uint32_t stop_state_1: 1;
+ __IO uint32_t RESERVED_2: 1;
+ __IO uint32_t dead_zone_en: 1;
+ __IO uint32_t pwm_pn_invserse_sel: 1;
+ __IO uint32_t RESERVED_1: 2;
+ __IO uint32_t r_clk_timer_pwm_wrap0_sel: 1;
+ __IO uint32_t r_FEN_TIMER_PWM_WRAP0: 1;
+ __IO uint32_t r_CKE_TIMER_PWM_WRAP0: 1;
+ __IO uint32_t r_clk_timer_pwm_wrap0_sel1: 1;
+ __IO uint32_t RESERVED_0: 12;
+ } BITS_368;
+ } u_368;
+
+ __IO uint32_t RSVD_0x36c[34];
+
+ /* 0x03F4 0x4000_03f4
+ 31:0 R RSVD 32'h0
+ */
+ __IO uint32_t PERION_REG_RSVD_3F4;
+
+ /* 0x03F8 0x4000_03f8
+ 0 R r_cap_touch_clk_src_sel 1'h0
+ 31:1 R RSVD 31'h0
+ */
+ union
+ {
+ __IO uint32_t PERION_REG_CTC_CLK_SRC_SEL;
+ struct
+ {
+ __I uint32_t r_cap_touch_clk_src_sel: 1;
+ __I uint32_t RESERVED_0: 31;
+ } BITS_3F8;
+ } u_3F8;
+
+} SYS_BLKCTRL_TypeDef;
+
+/* ================================================================================ */
+/* ================ Peripheral ================ */
+/* ================================================================================ */
+
+/**
+ * @brief Peripheral. (Peripheral)
+ */
+
+typedef struct /*!< Peripheral Structure */
+{
+ uint32_t RSVD0[134]; /*!< Reserved */
+ __IO uint32_t PERI_FUNC0_EN; /*!< 0x218 */
+ __IO uint32_t PERI_FUNC1_EN; /*!< 0x21C */
+ __IO uint32_t PERI_BD_FUNC0_EN; /*!< 0x220 */
+ uint32_t RSVD1[3]; /*!< Reserved */
+ __IO uint32_t PERI_CLK_CTRL; /*!< 0x230 */
+ __IO uint32_t PERI_CLK_CTRL0; /*!< 0x234 */
+ __IO uint32_t PERI_CLK_CTRL1; /*!< 0x238 */
+} PHERIPHERIAL_TypeDef;
+
+/* ================================================================================ */
+/* ================ Peripheral Interrupt ================ */
+/* ================================================================================ */
+
+/**
+ * @brief Peripheral Interrupt. (Peripheral Interrupt)
+ */
+
+typedef struct /*!< Peripheral Interrupt Structure */
+{
+ __IO uint32_t RSVD0; /*!< 0x00 */
+ __IO uint32_t STATUS; /*!< 0x04 */
+ __IO uint32_t MODE; /*!< 0x08, 0: high level active, 1: edge trigger */
+ __IO uint32_t EN; /*!< 0x0C */
+ __IO uint32_t RSVD1; /*!< 0x10 */
+ __IO uint32_t RSVD2; /*!< 0x14 */
+ __IO uint32_t EDGE_MODE; /*!< 0x18, 0: rising edge (HW default), 1: both edge */
+} PERI_INT_TypeDef;
+
+/* ================================================================================ */
+/* ================ Security ================ */
+/* ================================================================================ */
+
+/**
+ * @brief Security. (Security)
+ */
+
+typedef union /*!< Security Structure */
+{
+ __IO uint32_t d32;
+ struct
+ {
+ __IO uint32_t reg_pon_debug_port_wp: 1;
+ __IO uint32_t reg_pon_debug_port: 1;
+ __IO uint32_t reg_pon_hwspi_en_wp: 1;
+ __IO uint32_t reg_pon_hwspi_en: 1;
+ __IO uint32_t is_efuse_invalid: 1;
+ __IO uint32_t reg_efuse_system_general_ctrl_lock: 1;
+ __IO uint32_t rsvd0: 2;
+ __IO uint32_t is_enable_efuse_read_protect: 1;
+ __IO uint32_t is_enable_efuse_write_protect: 1;
+ __IO uint32_t is_disable_hci_ram_patch: 1;
+ __IO uint32_t is_disable_hci_flash_access: 1;
+ __IO uint32_t is_disable_hci_system_access: 1;
+ __IO uint32_t is_disable_hci_efuse_access: 1;
+ __IO uint32_t is_disable_hci_bt_test: 1;
+ __IO uint32_t is_debug_password_invalid: 1;
+ __IO uint32_t rsvd1: 4;
+ __IO uint32_t reg_pon_clk_flash_dis: 1;
+ __IO uint32_t rsvd2: 11;
+ };
+} SECURITY_TypeDef;
+
+/* ================================================================================ */
+/* ================ Peri clock reg ================ */
+/* ================================================================================ */
+
+/**
+ * @brief PWM
+ */
+typedef struct
+{
+ __IO uint32_t CLKSELE; /*!< 0x348*/
+ uint32_t RSVD[4];
+ __IO uint32_t CLK_SRCL;
+ __IO uint32_t CLK_SRCH; /*!< 0x360*/
+ __IO uint32_t PWM0_CTRL_L;
+ __IO uint32_t PWM0_CTRL_H;
+ __IO uint32_t PWM1_CTRL_L;
+ __IO uint32_t PWM1_CTRL_H; /*!< 0x370*/
+ __IO uint32_t PWM2_CTRL_L;
+ __IO uint32_t PWM2_CTRL_H;
+ __IO uint32_t PWM3_CTRL_L;
+ __IO uint32_t PWM3_CTRL_H; /*!< 0x380*/
+ __IO uint32_t TIM_EVT_CTRL;
+
+} Peri_ClockGate_TypeDef;
+
+
+/* ================================================================================ */
+/* ================ CACHE ================ */
+/* ================================================================================ */
+
+/**
+ * @brief cache for flash
+ */
+typedef struct
+{
+ __IO uint32_t CACHE_ENABLE; /*!< SPIC cache Enable Register, Address Offset: 0x00*/
+ __IO uint32_t FLUSH; /*!< Cache Flush register, Address Offset: 0x04*/
+ __IO uint32_t INTR; /*!< Cache Interrupt register, Address Offset: 0x08*/
+ __O uint32_t RST_CNT; /*!< Cache Reset Counter register, Address Offset: 0x0C*/
+ __I uint32_t RD_EVT_CNT; /*!< Cache Read Event Counter register, Address Offset: 0x10*/
+ __I uint32_t HIT_EVT_CNT; /*!< Cache HIT Event Counter register, Address Offset: 0x14*/
+ __I uint32_t HIT_LSTW_EVT_CNT; /*!< Cache Hit lastway event counter register, Offset: 0x18*/
+ __I uint32_t RD_PND_CNT; /*!< Cache Read pending counter register, Offset: 0x1c*/
+ __I uint32_t RSVD0[4]; /*!< Reserved, Offset: 0x20 ~ 0x2C */
+ __IO uint32_t HITWAYBUF_CTRL; /*!< Cache Hit way buffer control register, Offset: 0x30 */
+ __IO uint32_t CACHE_RAM_CTRL; /*!< Cache Two way function control register, Offset: 0x34 */
+ __IO uint32_t COUNTER_ENABLE; /*!< Cache counter enable register, Offset: 0x38 */
+} CACHE_TypeDef;
+
+/* ================================================================================ */
+/* ================ SPIC ================ */
+/* ================================================================================ */
+typedef struct
+{
+ __IO uint32_t ctrlr0; /*!< SPIC control register0, Address offset: 0x000 */
+ __IO uint32_t
+ rx_ndf; /*!< SPIC receiving data frame number register, Address offset: 0x004 */
+ __IO uint32_t ssienr; /*!< SPIC enable register, Address offset: 0x008 */
+ __IO uint32_t mwcr; /*!< N/A, Address offset: 0x00C */
+ __IO uint32_t ser; /*!< SPIC slave enable register, Address offset: 0x010 */
+ __IO uint32_t baudr; /*!< SPIC baudrate select register, Address offset: 0x014 */
+ __IO uint32_t txftlr; /*!< SPIC transmit FIFO threshold level, Address offset: 0x018 */
+ __IO uint32_t rxftlr; /*!< SPIC receive FIFO threshold level, Address offset: 0x01C */
+ __IO uint32_t txflr; /*!< SPIC transmit FIFO level register, Address offset: 0x020 */
+ __IO uint32_t rxflr; /*!< SPIC receive FIFO level register, Address offset: 0x024 */
+ __IO uint32_t sr; /*!< SPIC status register, Address offset: 0x028 */
+ __IO uint32_t imr; /*!< SPIC interrupt mask register, Address offset: 0x02C */
+ __IO uint32_t isr; /*!< SPIC interrupt status register, Address offset: 0x030 */
+ __IO uint32_t risr; /*!< SPIC raw interrupt status register, Address offset: 0x034 */
+ __IO uint32_t
+ txoicr; /*!< SPIC transmit FIFO overflow interrupt clear register,offset: 0x038 */
+ __IO uint32_t
+ rxoicr; /*!< SPIC receive FIFO overflow interrupt clear register, offset: 0x03C */
+ __IO uint32_t
+ rxuicr; /*!< SPIC receive FIFO underflow interrupt clear register,offset: 0x040 */
+ __IO uint32_t
+ msticr; /*!< SPIC master error interrupt clear register, Address offset: 0x044 */
+ __IO uint32_t icr; /*!< SPIC interrupt clear register, Address offset: 0x048 */
+ __IO uint32_t dmacr; /*!< N/A, Address offset: 0x04C */
+ __IO uint32_t dmatdlr; /*!< N/A, Address offset: 0x050 */
+ __IO uint32_t dmardlr; /*!< N/A, Address offset: 0x054 */
+ __IO uint32_t idr; /*!< SPIC Identiation register, Address offset: 0x058 */
+ __IO uint32_t spi_flash_version; /*!< SPIC version ID register, Address offset: 0x05C */
+ union
+ {
+ __IO uint8_t byte;
+ __IO uint16_t half;
+ __IO uint32_t word;
+ } dr[32]; /*!< SPIC data register, Address offset: 0x060~0x09C */
+ __IO uint32_t rd_fast_single; /*!< Fast read data command of SPI Flash, offset: 0x0E0 */
+ __IO uint32_t rd_dual_o; /*!< Dual output read command of SPI Flash, offset: 0x0E4 */
+ __IO uint32_t rd_dual_io; /*!< Dual I/O read command of SPI Flash, offset: 0x0E8 */
+ __IO uint32_t rd_quad_o; /*!< Quad output read command of SPI Flash, offset: 0x0EC */
+ __IO uint32_t rd_quad_io; /*!< Quad I/O read command of SPI Flash, offset: 0x0F0 */
+ __IO uint32_t wr_single; /*!< Page program command of SPI Flash, offset: 0x0F4 */
+ __IO uint32_t
+ wr_dual_i; /*!< Dual data input program command of SPI Flash, offset: 0x0F8 */
+ __IO uint32_t
+ wr_dual_ii; /*!< Dual address&data program command of SPI Flash,offset: 0x0FC */
+ __IO uint32_t wr_quad_i; /*!< Quad data input program command of SPI Flash,offset: 0x100 */
+ __IO uint32_t
+ wr_quad_ii; /*!< Quad address&data program command of SPI Flash,offset: 0x104 */
+ __IO uint32_t wr_enable; /*!< Write enabe command of SPI Flash, Address offset: 0x108 */
+ __IO uint32_t rd_status; /*!< Read status command of SPI Flash, offset: 0x10C */
+ __IO uint32_t ctrlr2; /*!< SPIC control register2, Address offset: 0x110 */
+ __IO uint32_t fbaudr; /*!< SPIC fast baudrate select, Address offset: 0x114 */
+ __IO uint32_t user_length; /*!< SPIC address length register, Address offset: 0x118 */
+ __IO uint32_t auto_length; /*!< SPIC auto address length register, Address offset: 0x11C */
+ __IO uint32_t valid_cmd; /*!< SPIC valid command register, Address offset: 0x120 */
+ __IO uint32_t flash_size; /*!< SPIC flash size register, Address offset: 0x124 */
+ __IO uint32_t flush_fifo; /*!< SPIC flush FIFO register, Address offset: 0x128 */
+ __IO uint32_t dum_byte; /*!< SPIC dummy byte register, Address offset: 0x12c */
+ __IO uint32_t
+ tx_ndf; /*!< SPIC transmitting data frame number register, Address offset: 0x130 */
+ __IO uint32_t device_info; /*!< SPIC device info register, Address offset: 0x134 */
+ __IO uint32_t tpr0; /*!< SPIC timing parameter register, Address offset: 0x138 */
+ __IO uint32_t auto_length2; /*!< SPIC auto length 2 register, Address offset: 0x13c */
+} SPIC_TypeDef;
+
+/** @} */ /* End of group RTL876X_Peripheral_Registers_Structures */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+
+/** @defgroup RTL876X_Exported_Macros RTL876X Exported Macros
+ * @brief
+ * @{
+ */
+
+/* ================================================================================ */
+/* ================ Peripheral memory map ================ */
+/* ================================================================================ */
+#define SYSTEM_REG_BASE 0x40000000UL
+#define PERIPH_REG_BASE 0x40000000UL
+#define RTC_REG_BASE 0x40000100UL
+#define RTC_LP_REG_BASE 0x40000180UL
+#define LPC_REG_BASE 0x40000180UL
+#define AON_WDG_REG_BASE 0x40000190UL
+#define SYSBLKCTRL_REG_BASE 0x40000200UL
+#define PINMUX_REG_BASE 0x40000280UL
+#define SPIC_DLY_CTRL_BASE 0x40000300UL
+#define PWM2_REG_BASE 0x40000364UL
+#define ENHPWM0_REG_BASE 0x40000368UL
+#define RTC_LED_REG_BASE 0x40000400UL
+
+#define GPIO_REG_BASE 0x40001000UL
+#define TIM0_REG_BASE 0x40002000UL
+#define TIM1_REG_BASE 0x40002014UL
+#define TIM2_REG_BASE 0x40002028UL
+#define TIM3_REG_BASE 0x4000203CUL
+#define TIM4_REG_BASE 0x40002050UL
+#define TIM5_REG_BASE 0x40002064UL
+#if (IC_TYPE == IC_TYPE_SBEE2)
+#define TIM6_REG_BASE 0x40002078UL
+#define TIM7_REG_BASE 0x4000208CUL
+#endif
+#define QDEC_REG_BASE 0x40004000UL
+#define SPI2WIRE_REG_BASE 0x40004000UL
+#define KEYSCAN_REG_BASE 0x40005000UL
+#define VENDOR_REG_BASE 0x40006000UL
+#define WDG_REG_BASE 0x40006000UL
+#define PERI_INT_REG_BASE 0x40006004UL
+#define RANDOM_GEN_REG_BASE 0x40006150UL
+#define CACHE_REG_BASE 0x40007000UL
+#define ENHANCED_TIM_BASE 0x40008000UL
+#define ENHTIM0_REG_BASE 0x40008000UL
+#define ENHTIM1_REG_BASE 0x40008024UL
+#define ENHTIM_SHARE_REG_BASE 0x40008120UL
+#define CAP_TOUCH_BASE 0x40009000UL
+#define CTC_Channel0_BASE 0x40009100UL
+#define CTC_Channel1_BASE 0x40009110UL
+#define CTC_Channel2_BASE 0x40009120UL
+#define CTC_Channel3_BASE 0x40009130UL
+#define CTC_Channel4_BASE 0x40009140UL
+#define CTC_FAST_BASE 0x40009150UL
+#define ADC_REG_BASE 0x40010000UL
+#define UART1_REG_BASE 0x40011000UL //log
+#define UART0_REG_BASE 0x40012000UL //data
+#define SPI0_REG_BASE 0x40013000UL
+#define SPI1_REG_BASE 0x40013400UL
+#define HW_AES_REG_BASE 0x40014000UL
+#define I2C0_REG_BASE 0x40015000UL
+#define I2C1_REG_BASE 0x40015400UL
+#if (IC_TYPE == IC_TYPE_BEE3)
+#define IR_REG_BASE 0x40015800UL
+#else
+#define IR_REG_BASE 0x40016000UL
+#endif
+#if (IC_TYPE != IC_TYPE_BEE3)
+#define SPORT0_REG_BASE 0x40020000UL
+#define I2S0_REG_BASE 0x40020000UL
+#define SPORT1_REG_BASE 0x40021000UL
+#define I2S1_REG_BASE 0x40021000UL
+#endif
+#define SPDIF_REG_BASE 0x40021800UL
+#define CODEC_ANA_REG_BASE 0x40022000UL
+#define CODEC_REG_BASE 0x40022100UL
+#define H2D_D2H_REG_BASE 0x40023000UL
+#if (IC_TYPE == IC_TYPE_SBEE2)
+#define UART2_REG_BASE 0x40024000UL
+#define IF8080_REG_BASE 0x40024800UL
+#define IF8080_LLI_REG1_BASE 0x40024850UL
+#define IF8080_LLI_REG1_GDMA_BASE 0x400248A0UL
+#define IF8080_LLI_REG2_BASE 0x40024880UL
+#define IF8080_LLI_REG2_GDMA_BASE 0x400248C0UL
+#define IF8080_LLI_REG1_OFT_BASE 0x40024870UL
+#define IF8080_LLI_REG2_OFT_BASE 0x40024878UL
+#define IF8080_LLI_CR_REG_BASE 0x40024894UL
+#endif
+#define GDMA_CHANNEL_REG_BASE 0x40027000UL // for platform_1_1_1_20160323 later
+#define GDMA_Channel0_BASE (GDMA_CHANNEL_REG_BASE + 0x0000)
+#define GDMA_Channel1_BASE (GDMA_CHANNEL_REG_BASE + 0x0058)
+#define GDMA_Channel2_BASE (GDMA_CHANNEL_REG_BASE + 0x00b0)
+#define GDMA_Channel3_BASE (GDMA_CHANNEL_REG_BASE + 0x0108)
+#if (IC_TYPE == IC_TYPE_SBEE2)
+#define GDMA_Channel4_BASE (GDMA_CHANNEL_REG_BASE + 0x0160)
+#define GDMA_Channel5_BASE (GDMA_CHANNEL_REG_BASE + 0x01b8)
+#endif
+#define GDMA_REG_BASE (GDMA_CHANNEL_REG_BASE + 0x02c0)
+#define I2S0_REG_BASE 0x40029000UL
+#define RTL_SPI0_BASE 0x40042000UL
+#define RTL_SPI1_BASE 0x40042400UL
+#define BT_BB_REG_BASE 0x40050000UL
+#define HCI_DMA_REG_BASE 0x40064000UL
+#define HCI_UART_REG_BASE 0x40068000UL
+#define BT_VENDOR_REG_BASE 0x40058000UL
+#define SECURITY_REG_BASE 0x40058f28UL
+#define GDMA0_REG_BASE 0x40060000UL
+#define SPIC0_REG_BASE 0x40080000UL
+#define SPIC1_REG_BASE 0x40090000UL
+#define SPIC2_REG_BASE 0x400A0000UL
+
+#define SPI0_MASTER_MODE_REG *((volatile uint32_t *)0x40000308UL)
+#define SPI0_MASTER_MODE_BIT BIT(8)
+
+/** @brief clock divider for peripheral */
+#define SYSTEM_CLK_CTRL *((volatile uint32_t *)0x4000020CUL)
+#define CLK_SOURCE_REG_1 *((volatile uint32_t *)0x4000035CUL)
+#define CLK_SOURCE_REG_2 *((volatile uint32_t *)0x40000360UL)
+
+#define REG_PEON_SYS_CLK_SEL 0x0200
+#define REG_PEON_SYS_CLK_SEL_2 0x0208
+#define REG_PEON_SYS_CLK_SEL_3 0x020C
+#define REG_SOC_FUNC_EN 0x0210
+#define REG_SOC_HCI_COM_FUNC_EN 0x0214
+#define REG_SOC_PERI_FUNC0_EN 0x0218
+#define REG_SOC_PERI_FUNC1_EN 0x021C
+#define REG_PESOC_CLK_CTRL 0x0230
+#define REG_PESOC_PERI_CLK_CTRL0 0x0234
+#define REG_PESOC_PERI_CLK_CTRL1 0x0238
+#define REG_PESOC_DSP_SHARE_RAM 0x0250
+#define REG_TEST_MODE 0x02a8
+#define REG_ANAPAR_PLL1_0 0x0320
+#define REG_ANAPAR_PLL3_2 0x0324
+#define REG_ANAPAR_PLL5_4 0x0328
+#define REG_XTAL_PLL_READY 0x0338
+
+#define GPIO_OUTPUT_OFFSET 0x00
+#define GPIO_DIRECTION_OFFSET 0x04
+
+/** @brief AON PAD AREA */
+#define REG_PAD_WKEN_ADDRESS 0x20
+#define REG_PAD_WK_CTRL_ADDRESS 0x12d
+#define REG_PAD_WKPOL_ADDRESS 0x25
+#define REG_PAD_O_ADDRESS 0x2A
+#define REG_AON_PAD_E_ADDRESS 0x2F
+#define REG_AON_PAD_S_ADDRESS 0x34
+#define REG_AON_PAD_PU_ADDRESS 0x39
+#define REG_AON_PAD_PD_ADDRESS 0x3E
+#define REG_AON_PAD_PWRON_ADDRESS 0x4C
+
+#define BIT_WK_INTEN (1U << 7) /**< BIT7 */
+#define BIT_WK_FLAG_GPIO (1U << 6) /**< BIT6 */
+
+#define BIT_SOC_ACTCK_GPIO_EN (1U << 24) /**< BIT24 */
+#define BIT_PERI_GPIO_EN (1U << 8) /**< BIT8 */
+
+#define BIT_PERI_KEYSCAN_EN (1U << 19) /**< BIT19 */
+#define BIT_SOC_ACTCK_KEYSCAN_EN (1U << 6) /**< BIT6 */
+
+
+/* ================================================================================ */
+/* ================ Peripheral declaration ================ */
+/* ================================================================================ */
+/** @brief System */
+#define PERIPH ((PHERIPHERIAL_TypeDef *) PERIPH_REG_BASE)
+#define SYSBLKCTRL ((SYS_BLKCTRL_TypeDef *) SYSBLKCTRL_REG_BASE)
+#define PERIPHINT ((PERI_INT_TypeDef *) VENDOR_REG_BASE)
+#define SECURITY ((SECURITY_TypeDef *) SECURITY_REG_BASE)
+
+/** @brief IO */
+#define PINMUX ((PINMUX_TypeDef *) PINMUX_REG_BASE)
+#define KEYSCAN ((KEYSCAN_TypeDef *) KEYSCAN_REG_BASE)
+#define GPIO ((GPIO_TypeDef *) GPIO_REG_BASE)
+#define QDEC ((QDEC_TypeDef *) QDEC_REG_BASE)
+#define ADC ((ADC_TypeDef *) ADC_REG_BASE)
+#define CODEC_ANA ((CODEC_AnalogTypeDef *) CODEC_ANA_REG_BASE)
+#define CODEC ((CODEC_TypeDef *) CODEC_REG_BASE)
+#define CTC ((CTC_TypeDef *) CAP_TOUCH_BASE)
+#define CTC_Channel0 ((CTC_ChannelTypeDef *) CTC_Channel0_BASE)
+#define CTC_Channel1 ((CTC_ChannelTypeDef *) CTC_Channel1_BASE)
+#define CTC_Channel2 ((CTC_ChannelTypeDef *) CTC_Channel2_BASE)
+#define CTC_Channel3 ((CTC_ChannelTypeDef *) CTC_Channel3_BASE)
+#define CTC_Channel4 ((CTC_ChannelTypeDef *) CTC_Channel4_BASE)
+#define CTC_FAST ((CTC_FSModeTypeDef *) CTC_FAST_BASE)
+#define ENH_TIM0 ((ENHTIM_TypeDef *) ENHTIM0_REG_BASE)
+#define ENH_TIM1 ((ENHTIM_TypeDef *) ENHTIM1_REG_BASE)
+#define ENH_TIM_SHARE ((ENHTIM_ShareTypeDef *) ENHTIM_SHARE_REG_BASE)
+#define GDMA_BASE ((GDMA_TypeDef *) GDMA_REG_BASE)
+#define GDMA_Channel0 ((GDMA_ChannelTypeDef *) GDMA_Channel0_BASE)
+#define GDMA_Channel1 ((GDMA_ChannelTypeDef *) GDMA_Channel1_BASE)
+#define GDMA_Channel2 ((GDMA_ChannelTypeDef *) GDMA_Channel2_BASE)
+#define GDMA_Channel3 ((GDMA_ChannelTypeDef *) GDMA_Channel3_BASE)
+#define I2C0 ((I2C_TypeDef *) I2C0_REG_BASE)
+#define I2C1 ((I2C_TypeDef *) I2C1_REG_BASE)
+#define I2S0 ((I2S_TypeDef *) I2S0_REG_BASE)
+#define IR ((IR_TypeDef *) IR_REG_BASE)
+#define LPC ((LPC_TypeDef *) LPC_REG_BASE)
+#define HWAES ((HW_AES_TypeDef *) HW_AES_REG_BASE)
+#define WDG ((WDG_TypeDef *) WDG_REG_BASE)
+#define AON_WDG ((AON_WDG_TypeDef *) AON_WDG_REG_BASE)
+#define RAN_GEN ((RAN_GEN_TypeDef *) RANDOM_GEN_REG_BASE)
+#define ICG ((ICG_TypeDef *) ICG_REG_BASE)
+#define CACHE ((CACHE_TypeDef *) CACHE_REG_BASE)
+#define RTC ((RTC_TypeDef *) RTC_REG_BASE)
+#define RTC_LED ((RTC_LED_TypeDef *) RTC_LED_REG_BASE)
+#define RTC_LP ((RTC_LP_TypeDef *) RTC_LP_REG_BASE)
+#define SPI0 ((SPI_TypeDef *) SPI0_REG_BASE)
+#define SPI1 ((SPI_TypeDef *) SPI1_REG_BASE)
+#define SPI3WIRE ((SPI3WIRE_TypeDef *) SPI2WIRE_REG_BASE)
+#define SPIC ((SPIC_TypeDef *) SPIC0_REG_BASE)
+#define SPIC0 ((SPIC_TypeDef *) SPIC0_REG_BASE)
+#define SPIC1 ((SPIC_TypeDef *) SPIC1_REG_BASE)
+#define SPIC2 ((SPIC_TypeDef *) SPIC2_REG_BASE)
+#define TIM0 ((TIM_TypeDef *) TIM0_REG_BASE)
+#define TIM1 ((TIM_TypeDef *) TIM1_REG_BASE)
+#define TIM2 ((TIM_TypeDef *) TIM2_REG_BASE)
+#define TIM3 ((TIM_TypeDef *) TIM3_REG_BASE)
+#define TIM4 ((TIM_TypeDef *) TIM4_REG_BASE)
+#define TIM5 ((TIM_TypeDef *) TIM5_REG_BASE)
+#define UART0 ((UART_TypeDef *) UART0_REG_BASE)
+#define UART1 ((UART_TypeDef *) UART1_REG_BASE)
+
+#define CLK_GATE ((Peri_ClockGate_TypeDef*) PERI_CLOCKGATE_REG_BASE)
+
+//Add by Vendor
+#define LITTLE_ENDIAN 0
+#define BIG_ENDIAN 1
+#define SYSTEM_ENDIAN LITTLE_ENDIAN
+
+#define SWAP32(x) ((uint32_t)(\
+ (((uint32_t)(x) & (uint32_t)0x000000ff) << 24) |\
+ (((uint32_t)(x) & (uint32_t)0x0000ff00) << 8) |\
+ (((uint32_t)(x) & (uint32_t)0x00ff0000) >> 8) |\
+ (((uint32_t)(x) & (uint32_t)0xff000000) >> 24)))
+
+#define WAP16(x) ((uint16_t)(\
+ (((uint16_t)(x) & (uint16_t)0x00ff) << 8) |\
+ (((uint16_t)(x) & (uint16_t)0xff00) >> 8)))
+
+#if SYSTEM_ENDIAN == LITTLE_ENDIAN
+#ifndef rtk_le16_to_cpu
+#define rtk_cpu_to_le32(x) ((uint32_t)(x))
+#define rtk_le32_to_cpu(x) ((uint32_t)(x))
+#define rtk_cpu_to_le16(x) ((uint16_t)(x))
+#define rtk_le16_to_cpu(x) ((uint16_t)(x))
+#define rtk_cpu_to_be32(x) SWAP32((x))
+#define rtk_be32_to_cpu(x) SWAP32((x))
+#define rtk_cpu_to_be16(x) WAP16((x))
+#define rtk_be16_to_cpu(x) WAP16((x))
+#endif
+
+#elif SYSTEM_ENDIAN == BIG_ENDIAN
+#ifndef rtk_le16_to_cpu
+#define rtk_cpu_to_le32(x) SWAP32((x))
+#define rtk_le32_to_cpu(x) SWAP32((x))
+#define rtk_cpu_to_le16(x) WAP16((x))
+#define rtk_le16_to_cpu(x) WAP16((x))
+#define rtk_cpu_to_be32(x) ((uint32_t)(x))
+#define rtk_be32_to_cpu(x) ((uint32_t)(x))
+#define rtk_cpu_to_be16(x) ((uint16_t)(x))
+#define rtk_be16_to_cpu(x) ((uint16_t)(x))
+#endif
+#endif
+
+#define HAL_READ32(base, addr) \
+ rtk_le32_to_cpu(*((volatile uint32_t *)(base + addr)))
+
+#define HAL_WRITE32(base, addr, value32) \
+ ((*((volatile uint32_t *)(base + addr))) = rtk_cpu_to_le32(value32))
+
+#define HAL_UPDATE32(addr, mask, value32) \
+ HAL_WRITE32(0, addr, (HAL_READ32(0, addr) & ~mask) | (value32 & mask))
+
+#define HAL_READ16(base, addr) \
+ rtk_le16_to_cpu(*((volatile uint16_t *)(base + addr)))
+
+#define HAL_WRITE16(base, addr, value) \
+ ((*((volatile uint16_t *)(base + addr))) = rtk_cpu_to_le16(value))
+
+#define HAL_UPDATE16(addr, mask, value16) \
+ HAL_WRITE16(0, addr, (HAL_READ16(0, addr) & ~mask) | (value16 & mask))
+
+#define HAL_READ8(base, addr) \
+ (*((volatile uint8_t *)(base + addr)))
+
+#define HAL_WRITE8(base, addr, value) \
+ ((*((volatile uint8_t *)(base + addr))) = value)
+
+#define HAL_UPDATE8(addr, mask, value8) \
+ HAL_WRITE8(0, addr, (HAL_READ8(0, addr) & ~mask) | (value8 & mask))
+
+#define BIT0 0x00000001
+#define BIT1 0x00000002
+#define BIT2 0x00000004
+#define BIT3 0x00000008
+#define BIT4 0x00000010
+#define BIT5 0x00000020
+#define BIT6 0x00000040
+#define BIT7 0x00000080
+#define BIT8 0x00000100
+#define BIT9 0x00000200
+#define BIT10 0x00000400
+#define BIT11 0x00000800
+#define BIT12 0x00001000
+#define BIT13 0x00002000
+#define BIT14 0x00004000
+#define BIT15 0x00008000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+
+#ifdef BIT
+#undef BIT
+#endif
+#define BIT(_n) (uint32_t)(1U << (_n))
+
+#ifdef BIT64
+#undef BIT64
+#endif
+#define BIT64(n) (1ULL << (n))
+
+#define BIT_BAND(reg, bit_pos) (*((volatile uint32_t*)(0x42000000 + ((uint32_t)&reg - 0x40000000) * 32 + bit_pos * 4)))
+
+
+/* Uncomment the line below to expanse the "assert_param" macro in the
+ Standard Peripheral Library drivers code */
+
+//#define USE_FULL_ASSERT
+
+/** @} */ /* End of group RTL876X_Exported_Macros */
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup RTL876X_Exported_Functions RTL876X Sets Exported Functions
+ * @brief
+ * @{
+ */
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief The assert_param macro is used for function's parameters check.
+ * @param expr: If expr is false, it calls assert_failed function which reports
+ * the name of the source file and the source line number of the call
+ * that failed. If expr is true, it return no value.
+ * @retval None
+ */
+#define assert_param(expr) ((expr) ? (void)0 : io_assert_failed((uint8_t *)__FILE__, __LINE__))
+void io_assert_failed(uint8_t *file, uint32_t line);
+#else
+#define assert_param(expr) ((void)0)
+#endif /* USE_FULL_ASSERT */
+
+/**
+ * @brief Read data from aon register
+ * @param offset: register address
+ * @return data read from register
+ */
+extern uint16_t btaon_fast_read(uint16_t offset);
+extern uint8_t btaon_fast_read_8b(uint16_t offset);
+
+/**
+ * @brief Read data from aon register safely
+ * @param offset: register address
+ * @return data read from register
+ */
+extern uint16_t btaon_fast_read_safe(uint16_t offset);
+extern uint8_t btaon_fast_read_safe_8b(uint16_t offset);
+
+/**
+ * @brief Write data to aon register
+ * @param offset: register address
+ * @param data: data to be written to register
+ * @return
+ */
+extern void btaon_fast_write(uint16_t offset, uint16_t data);
+extern void btaon_fast_write_8b(uint16_t offset, uint8_t data);
+
+/**
+ * @brief Write data to aon egister safely
+ * @param offset: register address
+ * @param data: data to be written to register
+ * @return
+ */
+extern void btaon_fast_write_safe(uint16_t offset, uint16_t data);
+extern void btaon_fast_write_safe_8b(uint16_t offset, uint8_t data);
+
+/**
+ * @brief Write data to aon egister
+ * @param offset: register address
+ * @param mask: indicate which bit in data will be updated
+ * @param data: data to be written to register
+ * @return
+ */
+extern void btaon_fast_update(uint16_t offset, uint16_t mask, uint16_t data);
+extern void btaon_fast_update_8b(uint16_t offset, uint8_t mask, uint8_t data);
+
+/**
+ * @brief Write data to aon egister safely
+ * @param offset: register address
+ * @param mask: indicate which bit in data will be updated
+ * @param data: data to be written to register
+ * @return
+ */
+extern void btaon_fast_update_safe(uint16_t offset, uint16_t mask, uint16_t data);
+extern void btaon_fast_update_safe_8b(uint16_t offset, uint8_t mask, uint8_t data);
+
+/** @} */ /* End of RTL876X_Exported_Functions */
+
+/** @} */ /* End of group RTL876X */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* RTL876X_H */
+
diff --git a/inc/platform/rtl876x_ic_type.h b/inc/platform/rtl876x_ic_type.h
new file mode 100644
index 0000000..9c006b2
--- /dev/null
+++ b/inc/platform/rtl876x_ic_type.h
@@ -0,0 +1,33 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+************************************************************************************************************
+ * @file rtl876x_ic_type.h
+ * @brief IC type selection
+ * @author
+ * @date
+ * @version v1.0
+ ***************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2020 Realtek Semiconductor Corporation</center></h2>
+ ***************************************************************************************
+ */
+
+#ifndef _RTL876X_IC_TYPE_H_
+#define _RTL876X_IC_TYPE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define IC_TYPE_SBEE2 9
+#define IC_TYPE_BEE3 12
+
+#define IC_TYPE IC_TYPE_BEE3
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/inc/platform/rtl876x_lib_platform.h b/inc/platform/rtl876x_lib_platform.h
new file mode 100644
index 0000000..b5de50f
--- /dev/null
+++ b/inc/platform/rtl876x_lib_platform.h
@@ -0,0 +1,247 @@
+/**
+************************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+************************************************************************************************************
+* @file rtl876x_lib_platform.h
+* @brief
+* @details
+* @author
+* @date
+* @version
+*************************************************************************************************************
+*/
+
+#ifndef _RTL876X_LIB_PLATFORM_H_
+#define _RTL876X_LIB_PLATFORM_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include "mem_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ READ_SUCCESS = 0,
+ READ_NOT_FIND_CONFIG = 1,
+ READ_NOT_FIND_BDADDR = 2,
+ READ_NOT_FIND_XTAL_OFFSET = 3,
+ READ_FAIL = 4,
+} T_READ_BDADDR_RESULT;
+
+typedef enum
+{
+ EFUSE_UPDATE_SUCCESS = 0,
+ EFUSE_UPDATE_READ_PROTECTED,
+ EFUSE_UPDATE_WRITE_MAC_FAIL,
+ EFUSE_UPDATE_SPACE_EXHAUSTED,
+ EFUSE_UPDATE_READ_FAIL,
+} T_EFUSE_UPDATE_RESULT;
+
+typedef enum
+{
+ DSN = 0,
+ HWREV,
+ PSN,
+ SKUID,
+ IRID,
+ PRO_PID
+} T_FLASH_READ_PROVISION;
+
+typedef enum
+{
+ BT_MAC = 0, //BD address
+ BT_MAX_LE_LINK_NUM,
+ BT_LE_MASTER_LINK_NUM,
+ BT_LE_SLAVE_LINK_NUM,
+} T_READ_PARAMETER;
+
+/**
+ * @brief another log buffer API, the fmt string will occupy flash space
+ */
+void log_buffer_retarget(uint32_t info, const char *fmt, ...);
+
+#define DBG_BUFFER_RETARGET(...) do {\
+ log_buffer_retarget(COMBINE_TRACE_INFO(TYPE_BEE2, SUBTYPE_DIRECT, 0, 0), __VA_ARGS__);\
+ } while (0)
+
+/*============================================================================*
+ * Log Retarget Sample Usage
+ *============================================================================*/
+/**
+ * @brief retarget other library code log to bee2 buffer log print.
+ * @note If enable, increase code size because more log will occupy flash space
+ *
+* <b>Example usage</b>
+ * \code{.c}
+
+//enable retarget other library code log to bee2 buffer log print or not
+#define ENABLE_RETARGET_LOG 1
+
+#if ENABLE_RETARGET_LOG
+#define LogDebug(...) DBG_BUFFER_RETARGET(__VA_ARGS__)
+#else
+#define LogDebug(...)
+#endif
+
+void test_log_retarget(void)
+{
+ char str[] = {'a','b','c', '\0'};
+ float data1 = 3.14125;
+ uint32_t data2 = 1024;
+ LogDebug("test");
+ LogDebug("string:%s", str);
+ LogDebug("float:%f", data1);
+ LogDebug("uint:%d", data2);
+}
+ * \endcode
+ */
+/*============================================================================*/
+
+/**
+ * @brief peek max free block size of specified ram type heap
+ */
+size_t os_mem_max_free_block_peek(RAM_TYPE ram_type);
+
+
+void show_sdk_lib_version(void);
+
+/**
+ * @brief read bd addr set in config file
+ * @param p_bdaddr: buffer to save bd addr
+ * @retval read result
+ * @arg 0: read success
+ * @arg 1: no config file in flash
+ * @arg 2: no bd setting found
+ */
+T_READ_BDADDR_RESULT read_config_bdaddr(uint8_t *p_bdaddr);
+
+/**
+ * @brief read mp config parameter
+ * @param type: the item of config file
+ * @param p_data: the return data
+ * @arg true: read success
+ * @arg false: read fail
+ */
+T_READ_BDADDR_RESULT read_config_item(T_READ_PARAMETER type, uint8_t *p_data);
+
+/**
+ * @brief read xtal offset set in config file
+ * @param p_xtal_offset: buffer to save xtal offset
+ * @retval read result
+ * @arg 0: read success
+ * @arg 1: no config file in flash
+ * @arg 3: no xtal offset found
+ */
+T_READ_BDADDR_RESULT read_config_xtal_offset(uint8_t *p_xtal_offset);
+
+/**
+ * @brief update bd address set in config file
+ * @param p_cfg_read_addr: the address of read config file
+ * @param p_cfg_write_addr: the address of write config file
+ * @param p_bdaddr: buffer to the updated bd address
+ * @retval update result
+ * @arg true: update success
+ * @arg false: update fail
+ */
+bool update_bdaddr(uint8_t *p_cfg_read_addr, uint8_t *p_cfg_write_addr, uint8_t *p_bdaddr);
+
+/**
+ * @brief update xtal offset set in config file
+ * @param p_cfg_read_addr: the address of read config file
+ * @param p_cfg_write_addr: the address of write config file
+ * @param xtal: the updated xtal offset
+ * @retval update result
+ * @arg true: update success
+ * @arg false: update fail
+ */
+bool update_xtal_offset(uint8_t *p_cfg_read_addr, uint8_t *p_cfg_write_addr, uint8_t xtal);
+
+/**
+ * @brief Write MAC address to config, this is mainly used on production line.
+ * @param[in] p_mac_addr The buffer hold MAC address (48 bits).
+ * @return Write MAC to config fail or success.
+ * @retval true Write MAC to config success.
+ * @retval false Write MAC to config fails or not write existed MAC.
+ */
+bool UpdateMAC(uint8_t *p_mac_addr);
+
+/**
+ * @brief update tx power in config file
+ * @param[in] tx_power index for power. tx_power = power*2
+ tx_power Power
+ 0x10 8 dBm
+ 0x8 4 dBm
+ 0x6 3 dBm
+ 0x0 0 dBm
+ 0xD8 -20 dBm
+ * @return update tx power to config fail or success.
+ * @retval true update tx power to config success.
+ * @retval false update tx power to config fails or not write existed tx power.
+ */
+bool UpdateTxPower(uint8_t tx_power);
+
+/**
+ * @brief Write MAC address to eFuse, this is mainly used on production line.
+ * Because eFuse space limitation, only write MAC to eFuse once supported.
+ * @param[in] p_mac_addr The buffer hold MAC address (48 bits).
+ * @return Write MAC to config fail or success.
+ * @retval EFUSE_UPDATE_SUCCESS Write MAC to eFuse success.
+ * @retval EFUSE_UPDATE_READ_PROTECTED Can not update eFuse while it is read protected.
+ * @retval EFUSE_UPDATE_WRITE_MAC_FAIL Write MAC to eFuse fails.
+ * @retval EFUSE_UPDATE_SPACE_EXHAUSTED eFuse space is exhausted.
+ */
+T_EFUSE_UPDATE_RESULT update_mac_to_efuse(uint8_t *p_mac_addr);
+
+/**
+ * @brief Write 40M XTAL calibration data to config, this is mainly used on production line.
+ * @param[in] xtal The value of 40M XTAL calibration data
+ * @return Write calibration data to config fail or success.
+ * @retval true Success.
+ * @retval false Fail.
+ */
+bool WriteXtalToConfig(uint8_t xtal);
+
+/**
+ * @brief Write 40M XTAL calibration data to Efuse, this is mainly used on production line.
+ * @param[in] xtal The value of 40M XTAL calibration data
+ * @return Write calibration data to Efuse fail or success.
+ * @retval true Success.
+ * @retval false Fail.
+ * @note The Efuse space is limited, please don't call this function more than 5 five times.
+ */
+bool WriteXtalToEfuse(uint8_t xtal);
+
+
+/**
+ * @brief allow customers to write provision data to specific flash region
+ * @param data input data
+ * @param region input region
+ * @ret true if success
+ */
+bool flash_provision_write(uint8_t *data, T_FLASH_READ_PROVISION region);
+
+/**
+ * @brief allow customers to read provision data from specific flash region
+ * @param data output data
+ * @param region output region
+ * @ret true if success
+ */
+bool flash_provision_read(uint8_t *data, T_FLASH_READ_PROVISION region);
+
+/**
+ * @brief get 14 bytes EUID
+ * @param none
+ * @return uint8_t *, the pointer to a copy of EUID.
+ */
+uint8_t *get_ic_euid(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTL876X_LIB_PLATFORM_H_ */
diff --git a/inc/platform/sha256.h b/inc/platform/sha256.h
new file mode 100644
index 0000000..c5dfd0f
--- /dev/null
+++ b/inc/platform/sha256.h
@@ -0,0 +1,92 @@
+/*********************************************************************
+* Filename: sha256.h
+* Author: Brad Conte (brad AT bradconte.com)
+* Copyright:
+* Disclaimer: This code is presented "as is" without any guarantees.
+* Details: Defines the API for the corresponding SHA1 implementation.
+*********************************************************************/
+
+/*
+ This code is released into the public domain free of any restrictions.
+ The author requests acknowledgement if the code is used, but does not require it.
+ This code is provided free of any liability and without any quality claims by the author.
+ https://github.com/B-Con/crypto-algorithms
+ */
+
+#ifndef SHA256_H
+#define SHA256_H
+
+/*************************** HEADER FILES ***************************/
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+/** @defgroup SHA256_API Sha256
+ * @brief APIs for using SHA256
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup SHA256_API_Exported_Macros SHA256 APIs Exported Macros
+ * @{
+ */
+
+#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest
+
+#define SHA256_USE_DYNAMIC_ALLOC 0
+
+/** End of SHA256_API_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup SHA256_API_Exported_Types SHA256 APIs Exported Types
+ * @{
+ */
+
+typedef unsigned char BYTE; // 8-bit byte
+typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines
+
+/** @brief Context structure to store SHA256 algorithm intermediate information */
+typedef struct
+{
+ BYTE data[64];
+ WORD datalen;
+ unsigned long long bitlen;
+ WORD state[8];
+} SHA256_CTX;
+
+/** End of SHA256_API_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup SHA256_API_Exported_Functions SHA256 APIs Exported Functions
+ * @brief
+ * @{
+ */
+
+void SHA256_Init(SHA256_CTX *ctx);
+void SHA256_Update(SHA256_CTX *ctx, const BYTE data[], size_t len);
+void SHA256_Final(SHA256_CTX *ctx, BYTE hash[]);
+void SHA256(const void *in, size_t len, uint8_t *result);
+bool SHA256_Alloc(SHA256_CTX **ctx);
+void SHA256_Free(SHA256_CTX *ctx);
+
+/** End of SHA256_API_Exported_Functions
+ * @}
+ */
+
+
+/** End of SHA256_API
+ * @}
+ */
+
+#endif // SHA256_H
+
diff --git a/inc/platform/system_rtl876x.h b/inc/platform/system_rtl876x.h
new file mode 100644
index 0000000..5ce5810
--- /dev/null
+++ b/inc/platform/system_rtl876x.h
@@ -0,0 +1,238 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file System_rtl876x.h
+ * @brief CMSIS Device System Header file
+ * @details CMSIS Device System Header File for RTL876x Device Series
+ * @author
+ * @date 3. March 2016
+ * @version v1.0
+ * *************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2016 Realtek Semiconductor Corporation</center></h2>
+ * ************************************************************************************
+ */
+
+/*============================================================================*
+ * Define to prevent recursive inclusion
+ *============================================================================*/
+#ifndef SYSTEM_RTL876X_H
+#define SYSTEM_RTL876X_H
+
+
+/*============================================================================*
+ * Headers
+ *============================================================================*/
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup SYSTEM_RTL876X System RTL876X
+ * @brief CMSIS API sets for RTL876x Device Series
+ * @{
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup SYSTEM_RTL876X_Exported_Types System RTL876X Exported Types
+ * @{
+ */
+typedef void (*IRQ_Fun)(); /**< ISR Handler Prototype */
+
+typedef enum
+{
+ LOG_TIMESTAMP_OS = 0,
+ LOG_TIMESTAMP_HW_TIMER = 1,
+ LOG_TIMESTAMP_RSVD = 2,
+ LOG_TIMESTAMP_MAX = 3
+} T_LOG_TIMESTAMP_TYPE;
+
+typedef enum
+{
+ LOG_BAUD_RATE_9600,
+ LOG_BAUD_RATE_19200,
+ LOG_BAUD_RATE_115200,
+ LOG_BAUD_RATE_230400,
+ LOG_BAUD_RATE_460800,
+ LOG_BAUD_RATE_921600,
+ LOG_BAUD_RATE_2000000,
+ LOG_BAUD_RATE_3000000,
+ LOG_BAUD_RATE_4000000,
+ LOG_BAUD_RATE_6000000
+} LOG_BAUD_RATE_TypeDef;
+
+typedef enum
+{
+ InitialSP_VECTORn = 0,
+ Reset_VECTORn,
+ NMI_VECTORn,
+ HardFault_VECTORn,
+ RSVD_MemMang_VECTORn,
+ RSVD_BusFault_VECTORn,
+ RSVD_UsageFault_VECTORn,
+ RSVD0_VECTORn,
+ RSVD1_VECTORn,
+ RSVD2_VECTORn,
+ RSVD3_VECTORn,
+ SVC_VECTORn,
+ DebugMonitor_VECTORn,
+ RSVD4_VECTORn,
+ PendSV_VECTORn,
+ SysTick_VECTORn,
+ System_VECTORn = 16,
+ WDG_VECTORn,
+ BTMAC_VECTORn,
+ Timer3_VECTORn,
+ Timer2_VECTORn,
+ Platform_VECTORn,
+ I2S0_TX_VECTORn,
+ I2S0_RX_VECTORn,
+ Timer4_5_VECTORn,
+ GPIO4_VECTORn,
+ GPIO5_VECTORn,
+ Uart1_VECTORn,
+ Uart0_VECTORn,
+ RTC_VECTORn,
+ SPI0_VECTORn,
+ SPI1_VECTORn,
+ I2C0_VECTORn,
+ I2C1_VECTORn,
+ ADC_VECTORn,
+ Peripheral_VECTORn,
+ GDMA0_Channel0_VECTORn,
+ GDMA0_Channel1_VECTORn,
+ GDMA0_Channel2_VECTORn,
+ GDMA0_Channel3_VECTORn,
+ Enhanced_Timer0_VECTORn,
+ Enhanced_Timer1_VECTORn,
+ GPIO_Group3_VECTORn,
+ GPIO_Group2_VECTORn,
+ IR_VECTORn,
+ GPIO_Group1_VECTORn,
+ GPIO_Group0_VECTORn,
+ RSVD5_VECTORn,
+ Timer4_VECTORn = 48,
+ Timer5_VECTORn,
+ SPIC0_VECTORn = 50,
+ Qdecode_VECTORn,
+ Keyscan_VECTORn,
+ SPI2W_VECTORn,
+ LPCOMP_VECTORn,
+ PTA_Mailbox_VECTORn,
+ CAP_Touch_VECTORn,
+ TRNG_VECTORn = 57,
+} VECTORn_Type;
+
+typedef enum _SYSTEM_CALL_OPCODE
+{
+ SYSTEM_CALL_BASE = 0x0,
+ SYSTEM_CALL_WDG_RESET,
+ SYSTEM_CALL_AUTO_K_RF,
+ SYSTEM_CALL_PMU_FORCE_PWM_MODE,
+ SYSTEM_CALL_ENTER_POWERDOWN_DIRECTLY,
+} T_SYSTEM_CALL_OPCODE;
+
+typedef bool (*APP_MAIN_FUNC)();
+typedef void (*USER_CALL_BACK)();
+
+/** @} */ /* End of group SYSTEM_RTL876X_Exported_types */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup SYSTEM_RTL876X_Exported_Variables System RTL876X Exported Variables
+ * @brief
+ * @{
+ */
+extern APP_MAIN_FUNC upperstack_entry;
+extern APP_MAIN_FUNC app_pre_main;
+extern APP_MAIN_FUNC app_main;
+extern USER_CALL_BACK app_pre_main_cb;
+/** @} */ /* End of group SYSTEM_RTL876X_Exported_Variables */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup SYSTEM_RTL876X_Exported_Functions System RTL876X Exported Functions
+ * @brief
+ * @{
+ */
+
+/**
+ * @brief Initialize RAM vector table to a given RAM address.
+ * @param ram_vector_addr: RAM Vector Address.
+ * @retval TRUE Success
+ * @retval FALSE Fail
+ * @note When using vector table relocation, the base address of the new vector
+ * table must be aligned to the size of the vector table extended to the
+ * next larger power of 2. In RTL8762C, the base address is aligned at 0x100.
+ */
+extern bool RamVectorTableInit(uint32_t ram_vector_addr);
+
+/**
+ * @brief Update ISR Handler in RAM Vector Table.
+ * @param v_num: Vector number(index)
+ * @param isr_handler: User defined ISR Handler.
+ * @retval TRUE Success
+ * @retval FALSE Fail
+ */
+extern bool RamVectorTableUpdate(VECTORn_Type v_num, IRQ_Fun isr_handler);
+
+/*
+ * @brief Call the system service.
+ * @param opcode: operation code.
+ * @param parm: parameter.
+ * @return none
+ */
+extern void SystemCall(uint32_t opcode, uint32_t parm);
+
+/*
+ * @brief update ram layout for app.
+ * @param app_global_size: app global ram size.
+ * @param data_heap_size: data on heap total size.
+ * @param share_cache_ram_size: the size of share cache to ram.
+ * @return none
+ */
+extern void update_ram_layout(uint32_t app_global_size, uint32_t data_heap_size,
+ uint32_t share_cache_ram_size);
+
+
+/**
+ * @brief get cpu clock
+ * @param none
+ * @return uint32, for example 40000000 is 40M, 20000000 is 20M.
+ */
+extern uint32_t get_cpu_clock(void);
+
+
+/**
+ * @brief get ic type
+ * @param none
+ * @return uint8_t, ic type:
+ * #define RTL8762ESF 0x1D
+ * #define RTL8762EGF 0x18
+ * #define RTL8762ERF 0x28
+ * #define RTL8762EJF 0x29
+ * #define RTL8762EMF 0x39
+ * #define RS625MF 0x49
+ * #define RTL8762EKF 0x5A
+ * #define RTL8762EKO 0x6C
+ */
+extern uint8_t get_ic_type(void);
+
+
+/** @} */ /* End of group SYSTEM_RTL876X_Exported_Functions */
+
+/** @} */ /* End of group SYSTEM_RTL876X */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SYSTEM_RTL876X_H */
+
diff --git a/inc/platform/test_mode.h b/inc/platform/test_mode.h
new file mode 100644
index 0000000..3aa94c7
--- /dev/null
+++ b/inc/platform/test_mode.h
@@ -0,0 +1,162 @@
+/**
+****************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+****************************************************************************************************
+* @file test_mode.h
+* @brief test mode definition.
+* @author Serval Li
+* @date 2017-08-29
+* @version v1.0
+****************************************************************************************************
+*/
+
+#ifndef _TEST_MODE_H_
+#define _TEST_MODE_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "rtl876x.h"
+#include "rtl876x_wdg.h"
+#include "patch_header_check.h"
+#include "flash_device.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup TEST_MODE Test Mode
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup TEST_MODE_Exported_Macros Test Mode Exported Macros
+ * @brief
+ * @{
+ */
+/* ascii value of "test" */
+#define TEST_MODE_FLAG_DEFAULT 0x74657374
+#define TEST_MODE_FLAG_DISABLE 0x50245150
+
+/* General Purpose FW register */
+#define BTAON_FAST_TEST_MODE 0x16
+/** End of TEST_MODE_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup TEST_MODE_Exported_Types Test Mode Exported Types
+ * @brief
+ * @{
+ */
+
+/* 0x16 (BTAON_FAST_TEST_MODE) */
+typedef union
+{
+ uint16_t d16;
+ struct
+ {
+ uint8_t rsvd : 5; /* bit[4:0]: reserved for ROM code */
+ uint8_t test_mode : 3; /* bit[7:5]: test mode */
+ uint8_t reset_reason : 8; /* bit[15:8]: reset reason */
+ } s;
+} T_BTAON_FAST_TEST_MODE_TYPE;
+
+typedef enum
+{
+ NOT_TEST_MODE = 0,
+ DIRECT_TEST_MODE = 1,
+ SINGLE_TONE_MODE = 2,
+ AUTO_PAIR_WITH_FIX_ADDR_MODE = 3,
+ DATA_UART_TEST_MODE = 4,
+ WRISTBAND_TEST_MODE = 5,
+ MOUSE_TEST_MODE = 6,
+ //add more
+} T_TEST_MODE;
+/** End of TEST_MODE_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup TEST_MODE_Exported_Functions Test Mode Exported Functions
+ * @brief
+ * @{
+ */
+static inline T_TEST_MODE get_test_mode(void)
+{
+ T_BTAON_FAST_TEST_MODE_TYPE aon;
+ aon.d16 = btaon_fast_read_safe(BTAON_FAST_TEST_MODE);
+ return (T_TEST_MODE)(aon.s.test_mode);
+}
+
+static inline void switch_to_test_mode(T_TEST_MODE test_mode)
+{
+ T_BTAON_FAST_TEST_MODE_TYPE aon;
+ aon.d16 = btaon_fast_read_safe(BTAON_FAST_TEST_MODE);
+ aon.s.test_mode = test_mode;
+ btaon_fast_write_safe(BTAON_FAST_TEST_MODE, aon.d16);
+
+ WDG_SystemReset(RESET_ALL_EXCEPT_AON, SWITCH_TEST_MODE);
+}
+
+static inline void reset_test_mode(void)
+{
+ T_BTAON_FAST_TEST_MODE_TYPE aon;
+ aon.d16 = btaon_fast_read_safe(BTAON_FAST_TEST_MODE);
+ aon.s.test_mode = NOT_TEST_MODE;
+ btaon_fast_write_safe(BTAON_FAST_TEST_MODE, aon.d16);
+}
+
+static inline bool is_test_mode_enable(void)
+{
+ uint32_t start_addr = flash_get_bank_addr(FLASH_BKP_DATA1);
+ if (start_addr)
+ {
+ uint32_t r_data = 0;
+ flash_auto_read_locked(start_addr, &r_data);
+ return r_data == TEST_MODE_FLAG_DEFAULT;
+ }
+ return false;
+}
+
+static inline bool test_mode_disable(void)
+{
+ bool retval = false;
+ uint32_t start_addr = flash_get_bank_addr(FLASH_BKP_DATA1);
+ if (start_addr)
+ {
+ retval = flash_auto_write_locked(start_addr, TEST_MODE_FLAG_DISABLE);
+ }
+ return retval;
+}
+
+void set_hci_mode_flag(bool enable);
+
+bool check_hci_mode_flag(void);
+
+static inline void switch_to_hci_mode(void)
+{
+ set_hci_mode_flag(true);
+ WDG_SystemReset(RESET_ALL_EXCEPT_AON, SWITCH_HCI_MODE);
+}
+
+#if (BUILD_DATATRANS == 1)
+void set_datatrans_patch_flag(bool enable);
+
+bool check_datatrans_patch_flag(void);
+#endif
+
+/** @} */ /* End of group TEST_MODE_Exported_Functions*/
+
+/** @} */ /* End of group TEST_MODE*/
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TEST_MODE_H_ */
+
diff --git a/inc/platform/trace.h b/inc/platform/trace.h
new file mode 100644
index 0000000..d764ca8
--- /dev/null
+++ b/inc/platform/trace.h
@@ -0,0 +1,2015 @@
+/**
+ * Copyright (c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+ */
+
+#ifndef _TRACE_H_
+#define _TRACE_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <platform_autoconf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * \defgroup TRACE Trace
+ *
+ * \brief Defines debug trace macros for each module.
+ *
+ */
+
+
+/* Log Section Definition */
+#define TRACE_DATA __attribute__((section(".TRACE"))) __attribute__((aligned(4))) __attribute__((used))
+
+/**
+ * trace.h
+ *
+ * \name TRACE_LEVEL
+ * \brief Log Level Definition.
+ * \anchor TRACE_LEVEL
+ */
+/**
+ * \ingroup TRACE
+ */
+/**@{*/
+#define LEVEL_ERROR 0
+#define LEVEL_WARN 1
+#define LEVEL_INFO 2
+#define LEVEL_TRACE 3
+#define LEVEL_NUM 4
+/**@}*/
+
+/*
+ * DBG_LEVEL is used to control the log printed by DBG_BUFFER().
+ * -1 : Print None
+ * LEVEL_ERROR : Print ERROR
+ * LEVEL_WARN : Print ERROR, WARN
+ * LEVEL_INFO : Print ERROR, WARN, INFO
+ * LEVEL_TRACE : Print ERROR, WARN, INFO, TRACE
+ */
+#define DBG_LEVEL LEVEL_TRACE
+
+/* Log type definition */
+typedef enum
+{
+ TYPE_UPPERSTACK_RESET = 0, /* Bee1(deprecated) */
+ TYPE_UPPERSTACK_FORMAT = 1, /* Bee1 */
+ TYPE_UPPERSTACK_MESSAGE = 2, /* Bee1 */
+ TYPE_UPPERSTACK_BINARY = 3, /* Bee1 */
+ TYPE_UPPERSTACK_STRING = 4, /* Bee1 */
+ TYPE_UPPERSTACK_BDADDR1 = 5, /* Bee1 */
+ TYPE_UPPERSTACK_BDADDR2 = 6, /* Bee1 */
+ TYPE_UPPERSTACK_RAMDATA1 = 7, /* Bee1 */
+ TYPE_UPPERSTACK_RAMDATA2 = 8, /* Bee1 */
+ TYPE_UPPERSTACK_RAMDATA3 = 9, /* Bee1 */
+ TYPE_UPPERSTACK_RAMDATA4 = 10, /* Bee1 */
+ TYPE_UPPERSTACK_RAMDATA5 = 11, /* Bee1 */
+ TYPE_UPPERSTACK_RAMDATA6 = 12, /* Bee1 */
+ TYPE_UPPERSTACK_RAMDATA7 = 13, /* Bee1 */
+ TYPE_UPPERSTACK_RAMDATA8 = 14, /* Bee1 */
+
+ TYPE_PLATFORM_DBG_DIRECT = 16, /* Bee1 */
+
+ /* type 32~127 reserved for project id, e.g. bumblebee3, bee2 */
+ TYPE_BUMBLEBEE3 = 32,
+ TYPE_BEE2 = 33,
+ TYPE_BEE3 = 35,
+
+ /* type 128~207 reserved for 3rd party definition */
+
+ /* type 220~251 reserved for Bee1 platform debug buffer */
+} T_LOG_TYPE;
+
+
+/* Log subtype definition */
+typedef enum
+{
+ SUBTYPE_DIRECT = 0x00,
+
+ SUBTYPE_FORMAT = 0x10,
+ SUBTYPE_DOWN_MESSAGE = 0x11,
+ SUBTYPE_UP_MESSAGE = 0x12,
+
+ SUBTYPE_DOWN_SNOOP = 0x20,
+ SUBTYPE_UP_SNOOP = 0x28,
+
+ SUBTYPE_BDADDR = 0x30,
+
+ SUBTYPE_STRING = 0x40,
+
+ SUBTYPE_BINARY = 0x50,
+
+ SUBTYPE_INDEX = 0x60,
+} T_LOG_SUBTYPE;
+
+/**
+ * trace.h
+ *
+ * \name MODULE_ID
+ * \brief Module ID definition.
+ * \anchor MODULE_ID
+ */
+/**
+ * \ingroup TRACE
+ */
+/**@{*/
+typedef enum
+{
+ /* platform modules */
+ MODULE_PATCH = 0,
+ MODULE_OS = 1,
+ MODULE_OSIF = 2,
+ MODULE_BOOT = 3,
+ MODULE_PM = 4,
+ MODULE_AES = 5,
+ MODULE_FS = 6,
+
+ /* device modules */
+ MODULE_KEYSCAN = 12,
+ MODULE_QDECODE = 13,
+ MODULE_IR = 14,
+ MODULE_3DG = 15,
+ MODULE_ADC = 16,
+ MODULE_GDMA = 17,
+ MODULE_I2C = 18,
+ MODULE_RTC = 19,
+ MODULE_SPI = 20,
+ MODULE_TIMER = 21,
+ MODULE_UART = 22,
+ MODULE_FLASH = 23,
+ MODULE_GPIO = 24,
+ MODULE_PINMUX = 25,
+ MODULE_PWM = 26,
+ MODULE_USB = 27,
+ MODULE_SDIO = 28,
+ MODULE_CHARGER = 29,
+ MODULE_DSP = 30,
+ MODULE_EFUSE = 31,
+ MODULE_CTC = 32,
+
+ /* stack modules */
+ MODULE_APP = 48,
+ MODULE_DFU = 49,
+ MODULE_RFCOMM = 50,
+ MODULE_PROFILE = 51,
+ MODULE_PROTOCOL = 52,
+ MODULE_GAP = 53,
+ MODULE_BTE = 54,
+ MODULE_BTIF = 55,
+ MODULE_GATT = 56,
+ MODULE_SMP = 57,
+ MODULE_SDP = 58,
+ MODULE_L2CAP = 59,
+ MODULE_HCI = 60,
+ MODULE_SNOOP = 61,
+ MODULE_UPPERSTACK = 62,
+ MODULE_LOWERSTACK = 63,
+
+ MODULE_NUM = 64
+} T_MODULE_ID;
+/**@}*/
+
+/**
+ * trace.h
+ *
+ * \name MODULE_BITMAP
+ * \brief Module bitmap definition.
+ * \anchor MODULE_BITMAP
+ */
+/**
+ * \ingroup TRACE
+ */
+/**@{*/
+#define MODULE_BIT_PATCH ((uint64_t)1 << MODULE_PATCH )
+#define MODULE_BIT_OS ((uint64_t)1 << MODULE_OS )
+#define MODULE_BIT_OSIF ((uint64_t)1 << MODULE_OSIF )
+#define MODULE_BIT_BOOT ((uint64_t)1 << MODULE_BOOT )
+#define MODULE_BIT_PM ((uint64_t)1 << MODULE_PM )
+#define MODULE_BIT_AES ((uint64_t)1 << MODULE_AES )
+#define MODULE_BIT_FS ((uint64_t)1 << MODULE_FS )
+
+#define MODULE_BIT_KEYSCAN ((uint64_t)1 << MODULE_KEYSCAN )
+#define MODULE_BIT_QDECODE ((uint64_t)1 << MODULE_QDECODE )
+#define MODULE_BIT_IR ((uint64_t)1 << MODULE_IR )
+#define MODULE_BIT_3DG ((uint64_t)1 << MODULE_3DG )
+#define MODULE_BIT_ADC ((uint64_t)1 << MODULE_ADC )
+#define MODULE_BIT_GDMA ((uint64_t)1 << MODULE_GDMA )
+#define MODULE_BIT_I2C ((uint64_t)1 << MODULE_I2C )
+#define MODULE_BIT_RTC ((uint64_t)1 << MODULE_RTC )
+#define MODULE_BIT_SPI ((uint64_t)1 << MODULE_SPI )
+#define MODULE_BIT_TIMER ((uint64_t)1 << MODULE_TIMER )
+#define MODULE_BIT_UART ((uint64_t)1 << MODULE_UART )
+#define MODULE_BIT_FLASH ((uint64_t)1 << MODULE_FLASH )
+#define MODULE_BIT_GPIO ((uint64_t)1 << MODULE_GPIO )
+#define MODULE_BIT_PINMUX ((uint64_t)1 << MODULE_PINMUX )
+#define MODULE_BIT_PWM ((uint64_t)1 << MODULE_PWM )
+#define MODULE_BIT_USB ((uint64_t)1 << MODULE_USB )
+#define MODULE_BIT_SDIO ((uint64_t)1 << MODULE_SDIO )
+#define MODULE_BIT_CHARGER ((uint64_t)1 << MODULE_CHARGER )
+#define MODULE_BIT_DSP ((uint64_t)1 << MODULE_DSP )
+#define MODULE_BIT_EFUSE ((uint64_t)1 << MODULE_EFUSE )
+#define MODULE_BIT_CTC ((uint64_t)1 << MODULE_CTC )
+
+#define MODULE_BIT_APP ((uint64_t)1 << MODULE_APP )
+#define MODULE_BIT_DFU ((uint64_t)1 << MODULE_DFU )
+#define MODULE_BIT_RFCOMM ((uint64_t)1 << MODULE_RFCOMM )
+#define MODULE_BIT_PROFILE ((uint64_t)1 << MODULE_PROFILE )
+#define MODULE_BIT_PROTOCOL ((uint64_t)1 << MODULE_PROTOCOL )
+#define MODULE_BIT_GAP ((uint64_t)1 << MODULE_GAP )
+#define MODULE_BIT_BTIF ((uint64_t)1 << MODULE_BTIF )
+#define MODULE_BIT_GATT ((uint64_t)1 << MODULE_GATT )
+#define MODULE_BIT_SMP ((uint64_t)1 << MODULE_SMP )
+#define MODULE_BIT_SDP ((uint64_t)1 << MODULE_SDP )
+#define MODULE_BIT_L2CAP ((uint64_t)1 << MODULE_L2CAP )
+#define MODULE_BIT_HCI ((uint64_t)1 << MODULE_HCI )
+#define MODULE_BIT_SNOOP ((uint64_t)1 << MODULE_SNOOP )
+#define MODULE_BIT_LOWERSTACK ((uint64_t)1 << MODULE_LOWERSTACK)
+#define MODULE_BIT_UPPERSTACK ((uint64_t)1 << MODULE_UPPERSTACK)
+/**@}*/
+
+/* Internal function that is used by internal macro DBG_DIRECT. */
+extern void log_direct(uint32_t info, const char *fmt, ...);
+extern void log_direct_app(uint32_t info, const char *fmt, ...);
+
+#if (ENABLE_FULL_FEATURED_DIRECT_LOG == 1)
+#define log_direct_retarget log_direct_app
+#else
+#define log_direct_retarget log_direct
+#endif
+
+/* Internal function that is used by internal macro DBG_LOWERSTACK. */
+void LogBufferLowerStack(uint32_t control, uint16_t log_str_index, uint8_t param_num, ...);
+
+/* Internal function that is used by internal macro DBG_LOWERSTACKDATA. */
+void LogBufferLowerStackData(uint32_t control, uint16_t log_str_index, uint16_t length,
+ uint8_t *p_str);
+
+/* Internal function that is used by internal macro DBG_BUFFER. */
+void log_buffer(uint32_t info, uint32_t log_str_index, uint8_t param_num, ...);
+
+/* Internal function that is used by internal macro DBG_INDEX. */
+void log_index(uint32_t info, uint32_t log_str_index, uint8_t param_num, ...);
+
+/* Internal function that is used by internal macro DBG_SNOOP. */
+void log_snoop(uint32_t info, uint16_t length, uint8_t *p_snoop);
+
+/* Internal function that is used by public macro TRACE_BDADDR. */
+const char *trace_bdaddr(uint32_t info, char *bd_addr);
+
+/* Internal function that is used by public macro TRACE_STRING. */
+const char *trace_string(uint32_t info, char *p_data);
+
+/* Internal function that is used by public macro TRACE_BINARY. */
+const char *trace_binary(uint32_t info, uint16_t length, uint8_t *p_data);
+
+#define COMBINE_TRACE_INFO(type, subtype, module, level) (uint32_t)(((type)<<24) | ((subtype)<<16) | ((module)<<8) | (level))
+
+/* Internal macro that is wrapped by internal macro DBG_BUFFER. */
+#define DBG_BUFFER_INTERNAL(type, sub_type, module, level, fmt, param_num, ...) do {\
+ static const char format[] TRACE_DATA = fmt;\
+ log_buffer(COMBINE_TRACE_INFO(type, sub_type, module, level), (uint32_t)format, param_num, ##__VA_ARGS__);\
+ } while (0)
+
+#if (DBG_LEVEL >= LEVEL_ERROR)
+#define DBG_BUFFER_LEVEL_ERROR(type, sub_type, module, fmt, param_num, ...) do {\
+ DBG_BUFFER_INTERNAL(type, sub_type, module, LEVEL_ERROR, fmt, param_num, ##__VA_ARGS__);\
+ } while (0)
+#define DBG_INDEX_LEVEL_ERROR(type, sub_type, module, fmt, param_num, ...) do {\
+ log_index(COMBINE_TRACE_INFO(type, sub_type, module, LEVEL_ERROR), fmt, param_num, ##__VA_ARGS__);\
+ } while (0)
+#else
+#define DBG_BUFFER_LEVEL_ERROR(type, sub_type, module, fmt, param_num, ...)
+#define DBG_INDEX_LEVEL_ERROR(type, sub_type, module, fmt, param_num, ...)
+#endif
+
+#if (DBG_LEVEL >= LEVEL_WARN)
+#define DBG_BUFFER_LEVEL_WARN(type, sub_type, module, fmt, param_num, ...) do {\
+ DBG_BUFFER_INTERNAL(type, sub_type, module, LEVEL_WARN, fmt, param_num, ##__VA_ARGS__);\
+ } while (0)
+#define DBG_INDEX_LEVEL_WARN(type, sub_type, module, fmt, param_num, ...) do {\
+ log_index(COMBINE_TRACE_INFO(type, sub_type, module, LEVEL_WARN), fmt, param_num, ##__VA_ARGS__);\
+ } while (0)
+#else
+#define DBG_BUFFER_LEVEL_WARN(type, sub_type, module, fmt, param_num, ...)
+#define DBG_INDEX_LEVEL_WARN(type, sub_type, module, fmt, param_num, ...)
+#endif
+
+#if (DBG_LEVEL >= LEVEL_INFO)
+#define DBG_BUFFER_LEVEL_INFO(type, sub_type, module, fmt, param_num, ...) do {\
+ DBG_BUFFER_INTERNAL(type, sub_type, module, LEVEL_INFO, fmt, param_num, ##__VA_ARGS__);\
+ } while (0)
+#define DBG_INDEX_LEVEL_INFO(type, sub_type, module, fmt, param_num, ...) do {\
+ log_index(COMBINE_TRACE_INFO(type, sub_type, module, LEVEL_INFO), fmt, param_num, ##__VA_ARGS__);\
+ } while (0)
+#else
+#define DBG_BUFFER_LEVEL_INFO(type, sub_type, module, fmt, param_num, ...)
+#define DBG_INDEX_LEVEL_INFO(type, sub_type, module, fmt, param_num, ...)
+#endif
+
+#if (DBG_LEVEL >= LEVEL_TRACE)
+#define DBG_BUFFER_LEVEL_TRACE(type, sub_type, module, fmt, param_num, ...) do {\
+ DBG_BUFFER_INTERNAL(type, sub_type, module, LEVEL_TRACE, fmt, param_num, ##__VA_ARGS__);\
+ } while (0)
+#define DBG_INDEX_LEVEL_TRACE(type, sub_type, module, fmt, param_num, ...) do {\
+ log_index(COMBINE_TRACE_INFO(type, sub_type, module, LEVEL_TRACE), fmt, param_num, ##__VA_ARGS__);\
+ } while (0)
+#else
+#define DBG_BUFFER_LEVEL_TRACE(type, sub_type, module, fmt, param_num, ...)
+#define DBG_INDEX_LEVEL_TRACE(type, sub_type, module, fmt, param_num, ...)
+#endif
+
+#define DBG_BUFFER(type, sub_type, module, level, fmt, param_num,...) \
+ DBG_BUFFER_##level(type, sub_type, module, fmt, param_num, ##__VA_ARGS__)
+
+#define DBG_INDEX(type, sub_type, module, level, fmt, param_num,...) \
+ DBG_INDEX_##level(type, sub_type, module, fmt, param_num, ##__VA_ARGS__)
+
+#define DBG_DIRECT(...) do {\
+ log_direct_retarget(COMBINE_TRACE_INFO(TYPE_BEE3, SUBTYPE_DIRECT, 0, 0), __VA_ARGS__);\
+ } while (0)
+
+#define DBG_LOWERSTACK(color, file_num, line_num, log_str_index, param_num, ...) do {\
+ LogBufferLowerStack(((file_num)<<16)|(line_num), (uint16_t)(log_str_index), param_num, ##__VA_ARGS__);\
+ } while (0)
+
+#define DBG_LOWERSTACKDATA(color, file_num, line_num, log_str_index, length, str) do {\
+ LogBufferLowerStackData(((color)<<24)|((file_num)<<16)|(line_num), (uint16_t)(log_str_index), length, str);\
+ } while (0)
+
+#define DBG_SNOOP(type, sub_type, module, level, length, snoop) do {\
+ log_snoop(COMBINE_TRACE_INFO(type, sub_type, module, level), length, snoop);\
+ } while (0)
+
+
+extern bool is_log_init;
+
+/**
+ * trace.h
+ *
+ * \brief Initialize module trace mask.
+ *
+ * \param[in] mask Module trace mask array. Set NULL to load default mask array.
+ *
+ * \return None.
+ *
+ * \ingroup TRACE
+ */
+void log_module_trace_init(uint64_t mask[LEVEL_NUM]);
+
+/**
+ * trace.h
+ *
+ * \brief Enable/Disable the module ID's trace.
+ *
+ * \param[in] module_id The specific module ID defined in \ref MODULE_ID.
+ *
+ * \param[in] trace_level The trace level of the module ID defined in \ref TRACE_LEVEL.
+ *
+ * \param[in] set Enable or disable the module ID's trace.
+ * \arg \c true Enable the module ID's trace.
+ * \arg \c false Disable the module ID's trace.
+ *
+ * \return The status of setting module ID's trace.
+ * \retval true Module ID's trace was set successfully.
+ * \retval false Module ID's trace was failed to set.
+ *
+ * \ingroup TRACE
+ */
+bool log_module_trace_set(T_MODULE_ID module_id, uint8_t trace_level, bool set);
+
+/**
+ * trace.h
+ *
+ * \brief Enable/Disable module bitmap's trace.
+ *
+ * \param[in] module_bitmap The module bitmap defined in \ref MODULE_BITMAP.
+ *
+ * \param[in] trace_level The trace level of the module bitmap defined in \ref TRACE_LEVEL.
+ *
+ * \param[in] set Enable or disable the module bitmap's trace.
+ * \arg \c true Enable the module bitmap's trace.
+ * \arg \c false Disable the module bitmap's trace.
+ *
+ * \return The status of setting module bitmap's trace.
+ * \retval true Module bitmap's trace was set successfully.
+ * \retval false Module bitmap's trace was failed to set.
+ *
+ * \ingroup TRACE
+ */
+bool log_module_bitmap_trace_set(uint64_t module_bitmap, uint8_t trace_level, bool set);
+
+/**
+ * trace.h
+ *
+ * \name AUXILIARY_PRINT_BDADDR
+ * \brief Auxiliary Interface that is used to print BD address.
+ * \anchor AUXILIARY_PRINT_BDADDR
+ */
+/**
+ * \ingroup TRACE
+ */
+#define TRACE_BDADDR(bd_addr) \
+ trace_bdaddr(COMBINE_TRACE_INFO(TYPE_BEE3, SUBTYPE_BDADDR, 0, 0), (char *)(bd_addr))
+
+/**
+ * trace.h
+ *
+ * \name AUXILIARY_PRINT_STRING
+ * \brief Auxiliary Interface that is used to print string.
+ * \anchor AUXILIARY_PRINT_STRING
+ */
+/**
+ * \ingroup TRACE
+ */
+#define TRACE_STRING(data) \
+ trace_string(COMBINE_TRACE_INFO(TYPE_BEE3, SUBTYPE_STRING, 0, 0), (char *)(data))
+
+/**
+ * trace.h
+ *
+ * \name AUXILIARY_PRINT_BINARY
+ * \brief Auxiliary Interface that is used to print binary string.
+ * \anchor AUXILIARY_PRINT_BINARY
+ */
+/**
+ * \ingroup TRACE
+ */
+/**@{*/
+#define TRACE_BINARY(length, data) \
+ trace_binary(COMBINE_TRACE_INFO(TYPE_BEE3, SUBTYPE_BINARY, 0, 0), length, (uint8_t *)(data))
+/**@}*/
+
+
+/* Bluetooth HCI Snoop Trace Interfaces */
+#define BT_SNOOP_DOWN_TRACE(length, snoop) \
+ DBG_SNOOP(TYPE_BEE3, SUBTYPE_DOWN_SNOOP, MODULE_SNOOP, LEVEL_ERROR, length, snoop);
+#define BT_SNOOP_UP_TRACE(length, snoop) \
+ DBG_SNOOP(TYPE_BEE3, SUBTYPE_UP_SNOOP, MODULE_SNOOP, LEVEL_ERROR, length, snoop);
+
+
+/* Bluetooth Message Trace Interfaces */
+#define BT_MESSAGE_DOWN_PRINT_ERROR(length, message) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_DOWN_MESSAGE, MODULE_UPPERSTACK, LEVEL_ERROR, "", 2, length, message)
+#define BT_MESSAGE_DOWN_PRINT_WARN(length, message) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_DOWN_MESSAGE, MODULE_UPPERSTACK, LEVEL_WARN, "", 2, length, message)
+#define BT_MESSAGE_DOWN_PRINT_INFO(length, message) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_DOWN_MESSAGE, MODULE_UPPERSTACK, LEVEL_INFO, "", 2, length, message)
+#define BT_MESSAGE_DOWN_PRINT_TRACE(length, message) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_DOWN_MESSAGE, MODULE_UPPERSTACK, LEVEL_TRACE, "", 2, length, message)
+#define BT_MESSAGE_UP_PRINT_ERROR(length, message) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_UP_MESSAGE, MODULE_UPPERSTACK, LEVEL_ERROR, "", 2, length, message)
+#define BT_MESSAGE_UP_PRINT_WARN(length, message) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_UP_MESSAGE, MODULE_UPPERSTACK, LEVEL_WARN, "", 2, length, message)
+#define BT_MESSAGE_UP_PRINT_INFO(length, message) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_UP_MESSAGE, MODULE_UPPERSTACK, LEVEL_INFO, "", 2, length, message)
+#define BT_MESSAGE_UP_PRINT_TRACE(length, message) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_UP_MESSAGE, MODULE_UPPERSTACK, LEVEL_TRACE, "", 2, length, message)
+
+
+/* Patch Trace Interfaces */
+#define PATCH_PRINT_ERROR0(fmt) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 0)
+#define PATCH_PRINT_ERROR1(fmt, arg0) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 1, arg0)
+#define PATCH_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 2, arg0, arg1)
+#define PATCH_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 3, arg0, arg1, arg2)
+#define PATCH_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 4, arg0, arg1, arg2, arg3)
+#define PATCH_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define PATCH_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define PATCH_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define PATCH_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define PATCH_PRINT_WARN0(fmt) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 0)
+#define PATCH_PRINT_WARN1(fmt, arg0) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 1, arg0)
+#define PATCH_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 2, arg0, arg1)
+#define PATCH_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 3, arg0, arg1, arg2)
+#define PATCH_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 4, arg0, arg1, arg2, arg3)
+#define PATCH_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define PATCH_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define PATCH_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define PATCH_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define PATCH_PRINT_INFO0(fmt) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 0)
+#define PATCH_PRINT_INFO1(fmt, arg0) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 1, arg0)
+#define PATCH_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 2, arg0, arg1)
+#define PATCH_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 3, arg0, arg1, arg2)
+#define PATCH_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 4, arg0, arg1, arg2, arg3)
+#define PATCH_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define PATCH_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define PATCH_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define PATCH_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define PATCH_PRINT_TRACE0(fmt) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 0)
+#define PATCH_PRINT_TRACE1(fmt, arg0) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 1, arg0)
+#define PATCH_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define PATCH_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define PATCH_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define PATCH_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define PATCH_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define PATCH_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define PATCH_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+
+/* Bluetooth Lower Stack Trace Interfaces */
+#define LOWERSTACK_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 0)
+#define LOWERSTACK_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define LOWERSTACK_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define LOWERSTACK_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define LOWERSTACK_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define LOWERSTACK_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define LOWERSTACK_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define LOWERSTACK_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define LOWERSTACK_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define LOWERSTACK_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 0)
+#define LOWERSTACK_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define LOWERSTACK_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define LOWERSTACK_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define LOWERSTACK_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define LOWERSTACK_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define LOWERSTACK_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define LOWERSTACK_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define LOWERSTACK_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define LOWERSTACK_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 0)
+#define LOWERSTACK_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define LOWERSTACK_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define LOWERSTACK_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define LOWERSTACK_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define LOWERSTACK_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define LOWERSTACK_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define LOWERSTACK_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define LOWERSTACK_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define LOWERSTACK_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 0)
+#define LOWERSTACK_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 1, arg0)
+#define LOWERSTACK_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define LOWERSTACK_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define LOWERSTACK_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define LOWERSTACK_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define LOWERSTACK_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define LOWERSTACK_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define LOWERSTACK_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+
+/* OS Trace Interfaces */
+#define OS_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 0)
+#define OS_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define OS_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define OS_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define OS_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define OS_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define OS_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define OS_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define OS_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define OS_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 0)
+#define OS_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define OS_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define OS_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define OS_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define OS_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define OS_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define OS_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define OS_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define OS_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 0)
+#define OS_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define OS_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define OS_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define OS_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define OS_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define OS_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define OS_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define OS_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define OS_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 0)
+#define OS_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 1, arg0)
+#define OS_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define OS_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define OS_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define OS_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define OS_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define OS_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define OS_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+
+/* OSIF Trace Interfaces */
+#define OSIF_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 0)
+#define OSIF_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define OSIF_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define OSIF_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define OSIF_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define OSIF_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define OSIF_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define OSIF_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define OSIF_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define OSIF_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 0)
+#define OSIF_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define OSIF_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define OSIF_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define OSIF_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define OSIF_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define OSIF_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define OSIF_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define OSIF_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define OSIF_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 0)
+#define OSIF_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define OSIF_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define OSIF_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define OSIF_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define OSIF_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define OSIF_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define OSIF_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define OSIF_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define OSIF_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 0)
+#define OSIF_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 1, arg0)
+#define OSIF_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define OSIF_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define OSIF_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define OSIF_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define OSIF_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define OSIF_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define OSIF_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+/* CTC Trace Interfaces */
+#define CTC_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 0)
+#define CTC_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define CTC_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define CTC_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define CTC_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define CTC_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define CTC_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define CTC_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define CTC_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define CTC_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 0)
+#define CTC_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define CTC_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define CTC_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define CTC_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define CTC_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define CTC_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define CTC_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define CTC_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define CTC_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 0)
+#define CTC_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define CTC_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define CTC_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define CTC_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define CTC_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define CTC_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define CTC_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define CTC_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define CTC_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 0)
+#define CTC_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 1, arg0)
+#define CTC_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define CTC_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define CTC_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define CTC_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define CTC_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define CTC_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define CTC_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+/* Bluetooth HCI Trace Interfaces */
+#define HCI_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 0)
+#define HCI_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define HCI_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define HCI_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define HCI_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define HCI_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define HCI_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define HCI_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define HCI_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define HCI_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 0)
+#define HCI_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define HCI_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define HCI_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define HCI_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define HCI_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define HCI_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define HCI_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define HCI_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define HCI_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 0)
+#define HCI_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define HCI_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define HCI_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define HCI_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define HCI_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define HCI_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define HCI_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define HCI_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define HCI_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 0)
+#define HCI_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 1, arg0)
+#define HCI_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define HCI_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define HCI_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define HCI_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define HCI_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define HCI_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define HCI_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+
+/* Bluetooth L2CAP Trace Interfaces */
+#define L2CAP_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 0)
+#define L2CAP_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define L2CAP_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define L2CAP_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define L2CAP_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define L2CAP_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define L2CAP_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define L2CAP_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define L2CAP_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define L2CAP_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 0)
+#define L2CAP_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define L2CAP_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define L2CAP_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define L2CAP_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define L2CAP_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define L2CAP_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define L2CAP_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define L2CAP_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define L2CAP_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 0)
+#define L2CAP_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define L2CAP_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define L2CAP_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define L2CAP_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define L2CAP_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define L2CAP_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define L2CAP_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define L2CAP_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define L2CAP_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 0)
+#define L2CAP_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 1, arg0)
+#define L2CAP_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define L2CAP_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define L2CAP_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define L2CAP_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define L2CAP_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define L2CAP_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define L2CAP_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+
+/* Bluetooth SDP Trace Interfaces */
+#define SDP_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 0)
+#define SDP_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define SDP_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define SDP_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define SDP_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define SDP_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define SDP_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define SDP_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define SDP_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define SDP_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 0)
+#define SDP_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define SDP_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define SDP_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define SDP_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define SDP_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define SDP_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define SDP_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define SDP_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define SDP_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 0)
+#define SDP_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define SDP_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define SDP_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define SDP_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define SDP_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define SDP_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define SDP_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define SDP_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define SDP_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 0)
+#define SDP_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 1, arg0)
+#define SDP_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define SDP_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define SDP_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define SDP_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define SDP_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define SDP_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define SDP_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+
+/* Bluetooth SMP Trace Interfaces */
+#define SMP_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 0)
+#define SMP_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define SMP_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define SMP_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define SMP_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define SMP_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define SMP_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define SMP_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define SMP_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define SMP_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 0)
+#define SMP_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define SMP_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define SMP_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define SMP_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define SMP_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define SMP_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define SMP_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define SMP_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define SMP_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 0)
+#define SMP_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define SMP_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define SMP_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define SMP_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define SMP_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define SMP_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define SMP_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define SMP_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define SMP_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 0)
+#define SMP_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 1, arg0)
+#define SMP_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define SMP_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define SMP_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define SMP_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define SMP_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define SMP_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define SMP_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+
+/* Bluetooth GATT Trace Interfaces */
+#define GATT_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 0)
+#define GATT_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define GATT_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define GATT_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define GATT_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define GATT_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define GATT_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define GATT_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define GATT_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define GATT_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 0)
+#define GATT_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define GATT_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define GATT_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define GATT_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define GATT_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define GATT_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define GATT_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define GATT_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define GATT_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 0)
+#define GATT_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define GATT_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define GATT_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define GATT_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define GATT_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define GATT_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define GATT_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define GATT_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define GATT_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 0)
+#define GATT_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 1, arg0)
+#define GATT_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define GATT_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define GATT_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define GATT_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define GATT_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define GATT_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define GATT_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+
+/* Bluetooth BTIF Trace Interfaces */
+#define BTIF_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 0)
+#define BTIF_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define BTIF_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define BTIF_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define BTIF_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define BTIF_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define BTIF_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define BTIF_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define BTIF_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define BTIF_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 0)
+#define BTIF_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define BTIF_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define BTIF_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define BTIF_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define BTIF_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define BTIF_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define BTIF_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define BTIF_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define BTIF_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 0)
+#define BTIF_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define BTIF_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define BTIF_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define BTIF_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define BTIF_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define BTIF_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define BTIF_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define BTIF_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define BTIF_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 0)
+#define BTIF_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 1, arg0)
+#define BTIF_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define BTIF_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define BTIF_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define BTIF_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define BTIF_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define BTIF_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define BTIF_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+
+/* Bluetooth BTE Trace Interfaces */
+#define BTE_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 0)
+#define BTE_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define BTE_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define BTE_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define BTE_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define BTE_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define BTE_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define BTE_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define BTE_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define BTE_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 0)
+#define BTE_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define BTE_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define BTE_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define BTE_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define BTE_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define BTE_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define BTE_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define BTE_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define BTE_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 0)
+#define BTE_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define BTE_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define BTE_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define BTE_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define BTE_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define BTE_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define BTE_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define BTE_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define BTE_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 0)
+#define BTE_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 1, arg0)
+#define BTE_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define BTE_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define BTE_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define BTE_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define BTE_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define BTE_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define BTE_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+
+/* Bluetooth GAP Trace Interfaces */
+#define GAP_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 0)
+#define GAP_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define GAP_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define GAP_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define GAP_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define GAP_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define GAP_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define GAP_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define GAP_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define GAP_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 0)
+#define GAP_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define GAP_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define GAP_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define GAP_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define GAP_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define GAP_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define GAP_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define GAP_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define GAP_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 0)
+#define GAP_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define GAP_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define GAP_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define GAP_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define GAP_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define GAP_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define GAP_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define GAP_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define GAP_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 0)
+#define GAP_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 1, arg0)
+#define GAP_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define GAP_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define GAP_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define GAP_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define GAP_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define GAP_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define GAP_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+
+/* Bluetooth RFCOMM Trace Interfaces */
+#define RFCOMM_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 0)
+#define RFCOMM_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define RFCOMM_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define RFCOMM_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define RFCOMM_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define RFCOMM_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define RFCOMM_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define RFCOMM_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define RFCOMM_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define RFCOMM_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 0)
+#define RFCOMM_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define RFCOMM_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define RFCOMM_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define RFCOMM_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define RFCOMM_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define RFCOMM_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define RFCOMM_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define RFCOMM_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define RFCOMM_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 0)
+#define RFCOMM_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define RFCOMM_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define RFCOMM_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define RFCOMM_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define RFCOMM_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define RFCOMM_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define RFCOMM_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define RFCOMM_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define RFCOMM_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 0)
+#define RFCOMM_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 1, arg0)
+#define RFCOMM_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define RFCOMM_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define RFCOMM_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define RFCOMM_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define RFCOMM_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define RFCOMM_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define RFCOMM_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+
+/* Bluetooth Protocol Trace Interfaces */
+#define PROTOCOL_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 0)
+#define PROTOCOL_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define PROTOCOL_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define PROTOCOL_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define PROTOCOL_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define PROTOCOL_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define PROTOCOL_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define PROTOCOL_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define PROTOCOL_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define PROTOCOL_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 0)
+#define PROTOCOL_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define PROTOCOL_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define PROTOCOL_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define PROTOCOL_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define PROTOCOL_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define PROTOCOL_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define PROTOCOL_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define PROTOCOL_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define PROTOCOL_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 0)
+#define PROTOCOL_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define PROTOCOL_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define PROTOCOL_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define PROTOCOL_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define PROTOCOL_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define PROTOCOL_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define PROTOCOL_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define PROTOCOL_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define PROTOCOL_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 0)
+#define PROTOCOL_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 1, arg0)
+#define PROTOCOL_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define PROTOCOL_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define PROTOCOL_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define PROTOCOL_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define PROTOCOL_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define PROTOCOL_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define PROTOCOL_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+
+/* Bluetooth Profile Trace Interfaces */
+#define PROFILE_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 0)
+#define PROFILE_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define PROFILE_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define PROFILE_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define PROFILE_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define PROFILE_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define PROFILE_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define PROFILE_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define PROFILE_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define PROFILE_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 0)
+#define PROFILE_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define PROFILE_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define PROFILE_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define PROFILE_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define PROFILE_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define PROFILE_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define PROFILE_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define PROFILE_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define PROFILE_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 0)
+#define PROFILE_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define PROFILE_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define PROFILE_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define PROFILE_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define PROFILE_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define PROFILE_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define PROFILE_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define PROFILE_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define PROFILE_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 0)
+#define PROFILE_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 1, arg0)
+#define PROFILE_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define PROFILE_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define PROFILE_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define PROFILE_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define PROFILE_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define PROFILE_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define PROFILE_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+
+/**
+ * trace.h
+ *
+ * \name APP_PRINT_TRACE
+ * \brief Bluetooth APP Trace Interfaces.
+ * \anchor APP_PRINT_TRACE
+ */
+/**
+ * \ingroup TRACE
+ */
+/**@{*/
+#define APP_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 0)
+#define APP_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define APP_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define APP_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define APP_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define APP_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define APP_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define APP_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define APP_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define APP_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 0)
+#define APP_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define APP_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define APP_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define APP_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define APP_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define APP_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define APP_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define APP_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define APP_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 0)
+#define APP_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define APP_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define APP_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define APP_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define APP_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define APP_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define APP_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define APP_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define APP_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 0)
+#define APP_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 1, arg0)
+#define APP_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define APP_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define APP_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define APP_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define APP_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define APP_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define APP_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+/**@}*/
+
+
+/* AES Trace Interfaces */
+#define AES_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_ERROR, "!!!"fmt, 0)
+#define AES_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define AES_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define AES_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define AES_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define AES_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_WARN, "!!*"fmt, 0)
+#define AES_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define AES_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define AES_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define AES_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define AES_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_INFO, "!**"fmt, 0)
+#define AES_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define AES_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define AES_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define AES_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+
+/* Power Manager Trace Interfaces */
+#define PM_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_ERROR, "!!!"fmt, 0)
+#define PM_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define PM_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define PM_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define PM_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define PM_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_WARN, "!!*"fmt, 0)
+#define PM_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define PM_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define PM_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define PM_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define PM_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 0)
+#define PM_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define PM_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define PM_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define PM_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define PM_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define PM_PRINT_INFO9(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 9, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
+#define PM_PRINT_INFO10(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 10, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
+#define PM_PRINT_INFO13(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 13, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12)
+
+/* Boot Trace Interfaces */
+#define BOOT_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_ERROR, "!!!"fmt, 0)
+#define BOOT_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define BOOT_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define BOOT_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define BOOT_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define BOOT_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_WARN, "!!*"fmt, 0)
+#define BOOT_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define BOOT_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define BOOT_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define BOOT_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define BOOT_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_INFO, "!**"fmt, 0)
+#define BOOT_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define BOOT_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define BOOT_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define BOOT_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+
+
+/* Bluetooth OTA/DFU Trace Interfaces */
+#define DFU_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 0)
+#define DFU_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define DFU_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define DFU_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define DFU_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define DFU_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define DFU_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define DFU_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define DFU_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define DFU_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 0)
+#define DFU_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define DFU_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define DFU_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define DFU_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define DFU_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define DFU_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define DFU_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define DFU_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define DFU_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 0)
+#define DFU_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define DFU_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define DFU_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define DFU_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define DFU_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define DFU_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define DFU_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define DFU_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define DFU_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 0)
+#define DFU_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 1, arg0)
+#define DFU_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define DFU_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define DFU_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define DFU_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define DFU_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define DFU_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define DFU_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+
+/* Bluetooth FLASH/CACHE Trace Interfaces */
+#define FLASH_PRINT_ERROR0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 0)
+#define FLASH_PRINT_ERROR1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 1, arg0)
+#define FLASH_PRINT_ERROR2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1)
+#define FLASH_PRINT_ERROR3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2)
+#define FLASH_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3)
+#define FLASH_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define FLASH_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define FLASH_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define FLASH_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define FLASH_PRINT_WARN0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 0)
+#define FLASH_PRINT_WARN1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 1, arg0)
+#define FLASH_PRINT_WARN2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1)
+#define FLASH_PRINT_WARN3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2)
+#define FLASH_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3)
+#define FLASH_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define FLASH_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define FLASH_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define FLASH_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define FLASH_PRINT_INFO0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 0)
+#define FLASH_PRINT_INFO1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 1, arg0)
+#define FLASH_PRINT_INFO2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 2, arg0, arg1)
+#define FLASH_PRINT_INFO3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2)
+#define FLASH_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3)
+#define FLASH_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define FLASH_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define FLASH_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define FLASH_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define FLASH_PRINT_TRACE0(fmt) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 0)
+#define FLASH_PRINT_TRACE1(fmt, arg0) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 1, arg0)
+#define FLASH_PRINT_TRACE2(fmt, arg0, arg1) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 2, arg0, arg1)
+#define FLASH_PRINT_TRACE3(fmt, arg0, arg1, arg2) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2)
+#define FLASH_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3)
+#define FLASH_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4)
+#define FLASH_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5)
+#define FLASH_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#define FLASH_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TRACE_H_ */
diff --git a/inc/platform/version.h b/inc/platform/version.h
new file mode 100644
index 0000000..85f487b
--- /dev/null
+++ b/inc/platform/version.h
@@ -0,0 +1,21 @@
+#define VERSION_MAJOR 1
+#define VERSION_MINOR 1
+#define VERSION_REVISION 0
+#define VERSION_BUILDNUM 99
+#define VERSION_GCID 0x1201a39e
+#define VERSION_GCID2 0x8c2a12bf
+#define CUSTOMER_NAME sdk
+#define CN_1 's'
+#define CN_2 'd'
+#define CN_3 'k'
+#define CN_4 '#'
+#define CN_5 '#'
+#define CN_6 '#'
+#define CN_7 '#'
+#define CN_8 '#'
+#define BUILDING_TIME "Thu Mar 17 10:58:10 2022"
+#define NAME2STR(a) #a
+#define CUSTOMER_NAME_S #NAME2STR(CUSTOMER_NAME)
+#define NUM4STR(a,b,c,d) #a "." #b "." #c "." #d
+#define VERSIONBUILDSTR(a,b,c,d) NUM4STR(a,b,c,d)
+#define VERSION_BUILD_STR VERSIONBUILDSTR(VERSION_MAJOR,VERSION_MINOR,VERSION_REVISION,VERSION_BUILDNUM)
diff --git a/inc/rcu/ima_adpcm_enc.h b/inc/rcu/ima_adpcm_enc.h
new file mode 100644
index 0000000..4c5f06e
--- /dev/null
+++ b/inc/rcu/ima_adpcm_enc.h
@@ -0,0 +1,29 @@
+/**
+************************************************************************************************************
+* Copyright(c) 2014-2015, Realtek Semiconductor Corporation. All rights reserved.
+************************************************************************************************************
+* @file ima_adpcm_enc.h
+* @brief
+* @author Chenjie Jin
+* @date 2018-05-14
+* @version v0.2
+*************************************************************************************************************
+*/
+
+#ifndef __IMA_ADPCM_ENCODE_H__
+#define __IMA_ADPCM_ENCODE_H__
+
+#include "stdint.h"
+
+typedef struct
+{
+ short valprev; /* Previous output value */
+ char index; /* Index into stepsize table */
+ uint16_t seq_id; /* sequence index */
+} T_IMA_ADPCM_STATE;
+
+int ima_adpcm_encode(short *indata, unsigned char *outdata, int len, T_IMA_ADPCM_STATE *state);
+
+extern T_IMA_ADPCM_STATE ima_adpcm_global_state;
+
+#endif /* __CVSD_ENCODE_H__ */
diff --git a/inc/rcu/opus_inc/config.h b/inc/rcu/opus_inc/config.h
new file mode 100644
index 0000000..d94c7a0
--- /dev/null
+++ b/inc/rcu/opus_inc/config.h
@@ -0,0 +1,64 @@
+/***********************************************************************
+Copyright (c) 2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Internet Society, IETF or IETF Trust, nor the
+names of specific contributors, may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#define USE_ALLOCA 1
+
+/* Comment out the next line for floating-point code */
+#define FIXED_POINT 1
+
+#define OPUS_BUILD 1
+
+#if defined(_M_IX86) || defined(_M_X64)
+/* Can always compile SSE intrinsics (no special compiler flags necessary) */
+#define OPUS_X86_MAY_HAVE_SSE
+#define OPUS_X86_MAY_HAVE_SSE2
+#define OPUS_X86_MAY_HAVE_SSE4_1
+
+/* Presume SSE functions, if compiled to use SSE/SSE2/AVX (note that AMD64 implies SSE2, and AVX
+ implies SSE4.1) */
+#if defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1)) || defined(__AVX__)
+#define OPUS_X86_PRESUME_SSE 1
+#endif
+#if defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__AVX__)
+#define OPUS_X86_PRESUME_SSE2 1
+#endif
+#if defined(__AVX__)
+#define OPUS_X86_PRESUME_SSE4_1 1
+#endif
+
+#if !defined(OPUS_X86_PRESUME_SSE4_1) || !defined(OPUS_X86_PRESUME_SSE2) || !defined(OPUS_X86_PRESUME_SSE)
+#define OPUS_HAVE_RTCD 1
+#endif
+
+#endif
+
+//#include "version.h"
+
+#endif /* CONFIG_H */
diff --git a/inc/rcu/opus_inc/opus.h b/inc/rcu/opus_inc/opus.h
new file mode 100644
index 0000000..933eb78
--- /dev/null
+++ b/inc/rcu/opus_inc/opus.h
@@ -0,0 +1,994 @@
+/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited
+ Written by Jean-Marc Valin and Koen Vos */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * @file opus.h
+ * @brief Opus reference implementation API
+ */
+
+#ifndef OPUS_H
+#define OPUS_H
+
+#include "opus_types.h"
+#include "opus_defines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @mainpage Opus
+ *
+ * The Opus codec is designed for interactive speech and audio transmission over the Internet.
+ * It is designed by the IETF Codec Working Group and incorporates technology from
+ * Skype's SILK codec and Xiph.Org's CELT codec.
+ *
+ * The Opus codec is designed to handle a wide range of interactive audio applications,
+ * including Voice over IP, videoconferencing, in-game chat, and even remote live music
+ * performances. It can scale from low bit-rate narrowband speech to very high quality
+ * stereo music. Its main features are:
+
+ * @li Sampling rates from 8 to 48 kHz
+ * @li Bit-rates from 6 kb/s to 510 kb/s
+ * @li Support for both constant bit-rate (CBR) and variable bit-rate (VBR)
+ * @li Audio bandwidth from narrowband to full-band
+ * @li Support for speech and music
+ * @li Support for mono and stereo
+ * @li Support for multichannel (up to 255 channels)
+ * @li Frame sizes from 2.5 ms to 60 ms
+ * @li Good loss robustness and packet loss concealment (PLC)
+ * @li Floating point and fixed-point implementation
+ *
+ * Documentation sections:
+ * @li @ref opus_encoder
+ * @li @ref opus_decoder
+ * @li @ref opus_repacketizer
+ * @li @ref opus_multistream
+ * @li @ref opus_libinfo
+ * @li @ref opus_custom
+ */
+
+/** @defgroup opus_encoder Opus Encoder
+ * @{
+ *
+ * @brief This page describes the process and functions used to encode Opus.
+ *
+ * Since Opus is a stateful codec, the encoding process starts with creating an encoder
+ * state. This can be done with:
+ *
+ * @code
+ * int error;
+ * OpusEncoder *enc;
+ * enc = opus_encoder_create(Fs, channels, application, &error);
+ * @endcode
+ *
+ * From this point, @c enc can be used for encoding an audio stream. An encoder state
+ * @b must @b not be used for more than one stream at the same time. Similarly, the encoder
+ * state @b must @b not be re-initialized for each frame.
+ *
+ * While opus_encoder_create() allocates memory for the state, it's also possible
+ * to initialize pre-allocated memory:
+ *
+ * @code
+ * int size;
+ * int error;
+ * OpusEncoder *enc;
+ * size = opus_encoder_get_size(channels);
+ * enc = malloc(size);
+ * error = opus_encoder_init(enc, Fs, channels, application);
+ * @endcode
+ *
+ * where opus_encoder_get_size() return the required size for the encoder state. Note that
+ * future versions of this code may change the size, so no assuptions should be made about it.
+ *
+ * The encoder state is always continuous in memory and only a shallow copy is sufficient
+ * to copy it (e.g. memcpy())
+ *
+ * It is possible to change some of the encoder's settings using the opus_encoder_ctl()
+ * interface. All these settings already default to the recommended value, so they should
+ * only be changed when necessary. The most common settings one may want to change are:
+ *
+ * @code
+ * opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate));
+ * opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
+ * opus_encoder_ctl(enc, OPUS_SET_SIGNAL(signal_type));
+ * @endcode
+ *
+ * where
+ *
+ * @arg bitrate is in bits per second (b/s)
+ * @arg complexity is a value from 1 to 10, where 1 is the lowest complexity and 10 is the highest
+ * @arg signal_type is either OPUS_AUTO (default), OPUS_SIGNAL_VOICE, or OPUS_SIGNAL_MUSIC
+ *
+ * See @ref opus_encoderctls and @ref opus_genericctls for a complete list of parameters that can be set or queried. Most parameters can be set or changed at any time during a stream.
+ *
+ * To encode a frame, opus_encode() or opus_encode_float() must be called with exactly one frame (2.5, 5, 10, 20, 40 or 60 ms) of audio data:
+ * @code
+ * len = opus_encode(enc, audio_frame, frame_size, packet, max_packet);
+ * @endcode
+ *
+ * where
+ * <ul>
+ * <li>audio_frame is the audio data in opus_int16 (or float for opus_encode_float())</li>
+ * <li>frame_size is the duration of the frame in samples (per channel)</li>
+ * <li>packet is the byte array to which the compressed data is written</li>
+ * <li>max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended).
+ * Do not use max_packet to control VBR target bitrate, instead use the #OPUS_SET_BITRATE CTL.</li>
+ * </ul>
+ *
+ * opus_encode() and opus_encode_float() return the number of bytes actually written to the packet.
+ * The return value <b>can be negative</b>, which indicates that an error has occurred. If the return value
+ * is 2 bytes or less, then the packet does not need to be transmitted (DTX).
+ *
+ * Once the encoder state if no longer needed, it can be destroyed with
+ *
+ * @code
+ * opus_encoder_destroy(enc);
+ * @endcode
+ *
+ * If the encoder was created with opus_encoder_init() rather than opus_encoder_create(),
+ * then no action is required aside from potentially freeing the memory that was manually
+ * allocated for it (calling free(enc) for the example above)
+ *
+ */
+
+/** Opus encoder state.
+ * This contains the complete state of an Opus encoder.
+ * It is position independent and can be freely copied.
+ * @see opus_encoder_create,opus_encoder_init
+ */
+typedef struct OpusEncoder OpusEncoder;
+
+/** Gets the size of an <code>OpusEncoder</code> structure.
+ * @param[in] channels <tt>int</tt>: Number of channels.
+ * This must be 1 or 2.
+ * @return The size in bytes.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels);
+
+/**
+ */
+
+/** Allocates and initializes an encoder state.
+ * There are three coding modes:
+ *
+ * @ref OPUS_APPLICATION_VOIP gives best quality at a given bitrate for voice
+ * signals. It enhances the input signal by high-pass filtering and
+ * emphasizing formants and harmonics. Optionally it includes in-band
+ * forward error correction to protect against packet loss. Use this
+ * mode for typical VoIP applications. Because of the enhancement,
+ * even at high bitrates the output may sound different from the input.
+ *
+ * @ref OPUS_APPLICATION_AUDIO gives best quality at a given bitrate for most
+ * non-voice signals like music. Use this mode for music and mixed
+ * (music/voice) content, broadcast, and applications requiring less
+ * than 15 ms of coding delay.
+ *
+ * @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY configures low-delay mode that
+ * disables the speech-optimized mode in exchange for slightly reduced delay.
+ * This mode can only be set on an newly initialized or freshly reset encoder
+ * because it changes the codec delay.
+ *
+ * This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution).
+ * @param [in] Fs <tt>opus_int32</tt>: Sampling rate of input signal (Hz)
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) in input signal
+ * @param [in] application <tt>int</tt>: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY)
+ * @param [out] error <tt>int*</tt>: @ref opus_errorcodes
+ * @note Regardless of the sampling rate and number channels selected, the Opus encoder
+ * can switch to a lower audio bandwidth or number of channels if the bitrate
+ * selected is too low. This also means that it is safe to always use 48 kHz stereo input
+ * and let the encoder optimize the encoding.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create(
+ opus_int32 Fs,
+ int channels,
+ int application,
+ int *error
+);
+
+/** Initializes a previously allocated encoder state
+ * The memory pointed to by st must be at least the size returned by opus_encoder_get_size().
+ * This is intended for applications which use their own allocator instead of malloc.
+ * @see opus_encoder_create(),opus_encoder_get_size()
+ * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+ * @param [in] st <tt>OpusEncoder*</tt>: Encoder state
+ * @param [in] Fs <tt>opus_int32</tt>: Sampling rate of input signal (Hz)
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) in input signal
+ * @param [in] application <tt>int</tt>: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY)
+ * @retval #OPUS_OK Success or @ref opus_errorcodes
+ */
+OPUS_EXPORT int opus_encoder_init(
+ OpusEncoder *st,
+ opus_int32 Fs,
+ int channels,
+ int application
+) OPUS_ARG_NONNULL(1);
+
+/** Encodes an Opus frame.
+ * @param [in] st <tt>OpusEncoder*</tt>: Encoder state
+ * @param [in] pcm <tt>opus_int16*</tt>: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16)
+ * @param [in] frame_size <tt>int</tt>: Number of samples per channel in the
+ * input signal.
+ * This must be an Opus frame size for
+ * the encoder's sampling rate.
+ * For example, at 48 kHz the permitted
+ * values are 120, 240, 480, 960, 1920,
+ * and 2880.
+ * Passing in a duration of less than
+ * 10 ms (480 samples at 48 kHz) will
+ * prevent the encoder from using the LPC
+ * or hybrid modes.
+ * @param [out] data <tt>unsigned char*</tt>: Output payload.
+ * This must contain storage for at
+ * least \a max_data_bytes.
+ * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+ * memory for the output
+ * payload. This may be
+ * used to impose an upper limit on
+ * the instant bitrate, but should
+ * not be used as the only bitrate
+ * control. Use #OPUS_SET_BITRATE to
+ * control the bitrate.
+ * @return The length of the encoded packet (in bytes) on success or a
+ * negative error code (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode(
+ OpusEncoder *st,
+ const opus_int16 *pcm,
+ int frame_size,
+ unsigned char *data,
+ opus_int32 max_data_bytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Encodes an Opus frame from floating point input.
+ * @param [in] st <tt>OpusEncoder*</tt>: Encoder state
+ * @param [in] pcm <tt>float*</tt>: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0.
+ * Samples with a range beyond +/-1.0 are supported but will
+ * be clipped by decoders using the integer API and should
+ * only be used if it is known that the far end supports
+ * extended dynamic range.
+ * length is frame_size*channels*sizeof(float)
+ * @param [in] frame_size <tt>int</tt>: Number of samples per channel in the
+ * input signal.
+ * This must be an Opus frame size for
+ * the encoder's sampling rate.
+ * For example, at 48 kHz the permitted
+ * values are 120, 240, 480, 960, 1920,
+ * and 2880.
+ * Passing in a duration of less than
+ * 10 ms (480 samples at 48 kHz) will
+ * prevent the encoder from using the LPC
+ * or hybrid modes.
+ * @param [out] data <tt>unsigned char*</tt>: Output payload.
+ * This must contain storage for at
+ * least \a max_data_bytes.
+ * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+ * memory for the output
+ * payload. This may be
+ * used to impose an upper limit on
+ * the instant bitrate, but should
+ * not be used as the only bitrate
+ * control. Use #OPUS_SET_BITRATE to
+ * control the bitrate.
+ * @return The length of the encoded packet (in bytes) on success or a
+ * negative error code (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float(
+ OpusEncoder *st,
+ const float *pcm,
+ int frame_size,
+ unsigned char *data,
+ opus_int32 max_data_bytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Frees an <code>OpusEncoder</code> allocated by opus_encoder_create().
+ * @param[in] st <tt>OpusEncoder*</tt>: State to be freed.
+ */
+OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st);
+
+/** Perform a CTL function on an Opus encoder.
+ *
+ * Generally the request and subsequent arguments are generated
+ * by a convenience macro.
+ * @param st <tt>OpusEncoder*</tt>: Encoder state.
+ * @param request This and all remaining parameters should be replaced by one
+ * of the convenience macros in @ref opus_genericctls or
+ * @ref opus_encoderctls.
+ * @see opus_genericctls
+ * @see opus_encoderctls
+ */
+OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);
+/**@}*/
+
+/** @defgroup opus_decoder Opus Decoder
+ * @{
+ *
+ * @brief This page describes the process and functions used to decode Opus.
+ *
+ * The decoding process also starts with creating a decoder
+ * state. This can be done with:
+ * @code
+ * int error;
+ * OpusDecoder *dec;
+ * dec = opus_decoder_create(Fs, channels, &error);
+ * @endcode
+ * where
+ * @li Fs is the sampling rate and must be 8000, 12000, 16000, 24000, or 48000
+ * @li channels is the number of channels (1 or 2)
+ * @li error will hold the error code in case of failure (or #OPUS_OK on success)
+ * @li the return value is a newly created decoder state to be used for decoding
+ *
+ * While opus_decoder_create() allocates memory for the state, it's also possible
+ * to initialize pre-allocated memory:
+ * @code
+ * int size;
+ * int error;
+ * OpusDecoder *dec;
+ * size = opus_decoder_get_size(channels);
+ * dec = malloc(size);
+ * error = opus_decoder_init(dec, Fs, channels);
+ * @endcode
+ * where opus_decoder_get_size() return the required size for the decoder state. Note that
+ * future versions of this code may change the size, so no assuptions should be made about it.
+ *
+ * The decoder state is always continuous in memory and only a shallow copy is sufficient
+ * to copy it (e.g. memcpy())
+ *
+ * To decode a frame, opus_decode() or opus_decode_float() must be called with a packet of compressed audio data:
+ * @code
+ * frame_size = opus_decode(dec, packet, len, decoded, max_size, 0);
+ * @endcode
+ * where
+ *
+ * @li packet is the byte array containing the compressed data
+ * @li len is the exact number of bytes contained in the packet
+ * @li decoded is the decoded audio data in opus_int16 (or float for opus_decode_float())
+ * @li max_size is the max duration of the frame in samples (per channel) that can fit into the decoded_frame array
+ *
+ * opus_decode() and opus_decode_float() return the number of samples (per channel) decoded from the packet.
+ * If that value is negative, then an error has occurred. This can occur if the packet is corrupted or if the audio
+ * buffer is too small to hold the decoded audio.
+ *
+ * Opus is a stateful codec with overlapping blocks and as a result Opus
+ * packets are not coded independently of each other. Packets must be
+ * passed into the decoder serially and in the correct order for a correct
+ * decode. Lost packets can be replaced with loss concealment by calling
+ * the decoder with a null pointer and zero length for the missing packet.
+ *
+ * A single codec state may only be accessed from a single thread at
+ * a time and any required locking must be performed by the caller. Separate
+ * streams must be decoded with separate decoder states and can be decoded
+ * in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK
+ * defined.
+ *
+ */
+
+/** Opus decoder state.
+ * This contains the complete state of an Opus decoder.
+ * It is position independent and can be freely copied.
+ * @see opus_decoder_create,opus_decoder_init
+ */
+typedef struct OpusDecoder OpusDecoder;
+
+/** Gets the size of an <code>OpusDecoder</code> structure.
+ * @param [in] channels <tt>int</tt>: Number of channels.
+ * This must be 1 or 2.
+ * @return The size in bytes.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_size(int channels);
+
+/** Allocates and initializes a decoder state.
+ * @param [in] Fs <tt>opus_int32</tt>: Sample rate to decode at (Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) to decode
+ * @param [out] error <tt>int*</tt>: #OPUS_OK Success or @ref opus_errorcodes
+ *
+ * Internally Opus stores data at 48000 Hz, so that should be the default
+ * value for Fs. However, the decoder can efficiently decode to buffers
+ * at 8, 12, 16, and 24 kHz so if for some reason the caller cannot use
+ * data at the full sample rate, or knows the compressed data doesn't
+ * use the full frequency range, it can request decoding at a reduced
+ * rate. Likewise, the decoder is capable of filling in either mono or
+ * interleaved stereo pcm buffers, at the caller's request.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusDecoder *opus_decoder_create(
+ opus_int32 Fs,
+ int channels,
+ int *error
+);
+
+/** Initializes a previously allocated decoder state.
+ * The state must be at least the size returned by opus_decoder_get_size().
+ * This is intended for applications which use their own allocator instead of malloc. @see opus_decoder_create,opus_decoder_get_size
+ * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+ * @param [in] st <tt>OpusDecoder*</tt>: Decoder state.
+ * @param [in] Fs <tt>opus_int32</tt>: Sampling rate to decode to (Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) to decode
+ * @retval #OPUS_OK Success or @ref opus_errorcodes
+ */
+OPUS_EXPORT int opus_decoder_init(
+ OpusDecoder *st,
+ opus_int32 Fs,
+ int channels
+) OPUS_ARG_NONNULL(1);
+
+/** Decode an Opus packet.
+ * @param [in] st <tt>OpusDecoder*</tt>: Decoder state
+ * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
+ * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload*
+ * @param [out] pcm <tt>opus_int16*</tt>: Output signal (interleaved if 2 channels). length
+ * is frame_size*channels*sizeof(opus_int16)
+ * @param [in] frame_size Number of samples per channel of available space in \a pcm.
+ * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will
+ * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1),
+ * then frame_size needs to be exactly the duration of audio that is missing, otherwise the
+ * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and
+ * FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms.
+ * @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be
+ * decoded. If no such data is available, the frame is decoded as if it were lost.
+ * @return Number of decoded samples or @ref opus_errorcodes
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode(
+ OpusDecoder *st,
+ const unsigned char *data,
+ opus_int32 len,
+ opus_int16 *pcm,
+ int frame_size,
+ int decode_fec
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Decode an Opus packet with floating point output.
+ * @param [in] st <tt>OpusDecoder*</tt>: Decoder state
+ * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
+ * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload
+ * @param [out] pcm <tt>float*</tt>: Output signal (interleaved if 2 channels). length
+ * is frame_size*channels*sizeof(float)
+ * @param [in] frame_size Number of samples per channel of available space in \a pcm.
+ * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will
+ * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1),
+ * then frame_size needs to be exactly the duration of audio that is missing, otherwise the
+ * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and
+ * FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms.
+ * @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be
+ * decoded. If no such data is available the frame is decoded as if it were lost.
+ * @return Number of decoded samples or @ref opus_errorcodes
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode_float(
+ OpusDecoder *st,
+ const unsigned char *data,
+ opus_int32 len,
+ float *pcm,
+ int frame_size,
+ int decode_fec
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Perform a CTL function on an Opus decoder.
+ *
+ * Generally the request and subsequent arguments are generated
+ * by a convenience macro.
+ * @param st <tt>OpusDecoder*</tt>: Decoder state.
+ * @param request This and all remaining parameters should be replaced by one
+ * of the convenience macros in @ref opus_genericctls or
+ * @ref opus_decoderctls.
+ * @see opus_genericctls
+ * @see opus_decoderctls
+ */
+OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NONNULL(1);
+
+/** Frees an <code>OpusDecoder</code> allocated by opus_decoder_create().
+ * @param[in] st <tt>OpusDecoder*</tt>: State to be freed.
+ */
+OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st);
+
+/** Parse an opus packet into one or more frames.
+ * Opus_decode will perform this operation internally so most applications do
+ * not need to use this function.
+ * This function does not copy the frames, the returned pointers are pointers into
+ * the input packet.
+ * @param [in] data <tt>char*</tt>: Opus packet to be parsed
+ * @param [in] len <tt>opus_int32</tt>: size of data
+ * @param [out] out_toc <tt>char*</tt>: TOC pointer
+ * @param [out] frames <tt>char*[48]</tt> encapsulated frames
+ * @param [out] size <tt>opus_int16[48]</tt> sizes of the encapsulated frames
+ * @param [out] payload_offset <tt>int*</tt>: return the position of the payload within the packet (in bytes)
+ * @return number of frames
+ */
+OPUS_EXPORT int opus_packet_parse(
+ const unsigned char *data,
+ opus_int32 len,
+ unsigned char *out_toc,
+ const unsigned char *frames[48],
+ opus_int16 size[48],
+ int *payload_offset
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Gets the bandwidth of an Opus packet.
+ * @param [in] data <tt>char*</tt>: Opus packet
+ * @retval OPUS_BANDWIDTH_NARROWBAND Narrowband (4kHz bandpass)
+ * @retval OPUS_BANDWIDTH_MEDIUMBAND Mediumband (6kHz bandpass)
+ * @retval OPUS_BANDWIDTH_WIDEBAND Wideband (8kHz bandpass)
+ * @retval OPUS_BANDWIDTH_SUPERWIDEBAND Superwideband (12kHz bandpass)
+ * @retval OPUS_BANDWIDTH_FULLBAND Fullband (20kHz bandpass)
+ * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_bandwidth(const unsigned char *data)
+OPUS_ARG_NONNULL(1);
+
+/** Gets the number of samples per frame from an Opus packet.
+ * @param [in] data <tt>char*</tt>: Opus packet.
+ * This must contain at least one byte of
+ * data.
+ * @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz.
+ * This must be a multiple of 400, or
+ * inaccurate results will be returned.
+ * @return Number of samples per frame.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_samples_per_frame(const unsigned char *data,
+ opus_int32 Fs) OPUS_ARG_NONNULL(1);
+
+/** Gets the number of channels from an Opus packet.
+ * @param [in] data <tt>char*</tt>: Opus packet
+ * @return Number of channels
+ * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_channels(const unsigned char *data)
+OPUS_ARG_NONNULL(1);
+
+/** Gets the number of frames in an Opus packet.
+ * @param [in] packet <tt>char*</tt>: Opus packet
+ * @param [in] len <tt>opus_int32</tt>: Length of packet
+ * @return Number of frames
+ * @retval OPUS_BAD_ARG Insufficient data was passed to the function
+ * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[],
+ opus_int32 len) OPUS_ARG_NONNULL(1);
+
+/** Gets the number of samples of an Opus packet.
+ * @param [in] packet <tt>char*</tt>: Opus packet
+ * @param [in] len <tt>opus_int32</tt>: Length of packet
+ * @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz.
+ * This must be a multiple of 400, or
+ * inaccurate results will be returned.
+ * @return Number of samples
+ * @retval OPUS_BAD_ARG Insufficient data was passed to the function
+ * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[],
+ opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1);
+
+/** Gets the number of samples of an Opus packet.
+ * @param [in] dec <tt>OpusDecoder*</tt>: Decoder state
+ * @param [in] packet <tt>char*</tt>: Opus packet
+ * @param [in] len <tt>opus_int32</tt>: Length of packet
+ * @return Number of samples
+ * @retval OPUS_BAD_ARG Insufficient data was passed to the function
+ * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_nb_samples(const OpusDecoder *dec,
+ const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
+
+/** Applies soft-clipping to bring a float signal within the [-1,1] range. If
+ * the signal is already in that range, nothing is done. If there are values
+ * outside of [-1,1], then the signal is clipped as smoothly as possible to
+ * both fit in the range and avoid creating excessive distortion in the
+ * process.
+ * @param [in,out] pcm <tt>float*</tt>: Input PCM and modified PCM
+ * @param [in] frame_size <tt>int</tt> Number of samples per channel to process
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @param [in,out] softclip_mem <tt>float*</tt>: State memory for the soft clipping process (one float per channel, initialized to zero)
+ */
+OPUS_EXPORT void opus_pcm_soft_clip(float *pcm, int frame_size, int channels, float *softclip_mem);
+
+
+/**@}*/
+
+/** @defgroup opus_repacketizer Repacketizer
+ * @{
+ *
+ * The repacketizer can be used to merge multiple Opus packets into a single
+ * packet or alternatively to split Opus packets that have previously been
+ * merged. Splitting valid Opus packets is always guaranteed to succeed,
+ * whereas merging valid packets only succeeds if all frames have the same
+ * mode, bandwidth, and frame size, and when the total duration of the merged
+ * packet is no more than 120 ms. The 120 ms limit comes from the
+ * specification and limits decoder memory requirements at a point where
+ * framing overhead becomes negligible.
+ *
+ * The repacketizer currently only operates on elementary Opus
+ * streams. It will not manipualte multistream packets successfully, except in
+ * the degenerate case where they consist of data from a single stream.
+ *
+ * The repacketizing process starts with creating a repacketizer state, either
+ * by calling opus_repacketizer_create() or by allocating the memory yourself,
+ * e.g.,
+ * @code
+ * OpusRepacketizer *rp;
+ * rp = (OpusRepacketizer*)malloc(opus_repacketizer_get_size());
+ * if (rp != NULL)
+ * opus_repacketizer_init(rp);
+ * @endcode
+ *
+ * Then the application should submit packets with opus_repacketizer_cat(),
+ * extract new packets with opus_repacketizer_out() or
+ * opus_repacketizer_out_range(), and then reset the state for the next set of
+ * input packets via opus_repacketizer_init().
+ *
+ * For example, to split a sequence of packets into individual frames:
+ * @code
+ * unsigned char *data;
+ * int len;
+ * while (get_next_packet(&data, &len))
+ * {
+ * unsigned char out[1276];
+ * opus_int32 out_len;
+ * int nb_frames;
+ * int err;
+ * int i;
+ * err = opus_repacketizer_cat(rp, data, len);
+ * if (err != OPUS_OK)
+ * {
+ * release_packet(data);
+ * return err;
+ * }
+ * nb_frames = opus_repacketizer_get_nb_frames(rp);
+ * for (i = 0; i < nb_frames; i++)
+ * {
+ * out_len = opus_repacketizer_out_range(rp, i, i+1, out, sizeof(out));
+ * if (out_len < 0)
+ * {
+ * release_packet(data);
+ * return (int)out_len;
+ * }
+ * output_next_packet(out, out_len);
+ * }
+ * opus_repacketizer_init(rp);
+ * release_packet(data);
+ * }
+ * @endcode
+ *
+ * Alternatively, to combine a sequence of frames into packets that each
+ * contain up to <code>TARGET_DURATION_MS</code> milliseconds of data:
+ * @code
+ * // The maximum number of packets with duration TARGET_DURATION_MS occurs
+ * // when the frame size is 2.5 ms, for a total of (TARGET_DURATION_MS*2/5)
+ * // packets.
+ * unsigned char *data[(TARGET_DURATION_MS*2/5)+1];
+ * opus_int32 len[(TARGET_DURATION_MS*2/5)+1];
+ * int nb_packets;
+ * unsigned char out[1277*(TARGET_DURATION_MS*2/2)];
+ * opus_int32 out_len;
+ * int prev_toc;
+ * nb_packets = 0;
+ * while (get_next_packet(data+nb_packets, len+nb_packets))
+ * {
+ * int nb_frames;
+ * int err;
+ * nb_frames = opus_packet_get_nb_frames(data[nb_packets], len[nb_packets]);
+ * if (nb_frames < 1)
+ * {
+ * release_packets(data, nb_packets+1);
+ * return nb_frames;
+ * }
+ * nb_frames += opus_repacketizer_get_nb_frames(rp);
+ * // If adding the next packet would exceed our target, or it has an
+ * // incompatible TOC sequence, output the packets we already have before
+ * // submitting it.
+ * // N.B., The nb_packets > 0 check ensures we've submitted at least one
+ * // packet since the last call to opus_repacketizer_init(). Otherwise a
+ * // single packet longer than TARGET_DURATION_MS would cause us to try to
+ * // output an (invalid) empty packet. It also ensures that prev_toc has
+ * // been set to a valid value. Additionally, len[nb_packets] > 0 is
+ * // guaranteed by the call to opus_packet_get_nb_frames() above, so the
+ * // reference to data[nb_packets][0] should be valid.
+ * if (nb_packets > 0 && (
+ * ((prev_toc & 0xFC) != (data[nb_packets][0] & 0xFC)) ||
+ * opus_packet_get_samples_per_frame(data[nb_packets], 48000)*nb_frames >
+ * TARGET_DURATION_MS*48))
+ * {
+ * out_len = opus_repacketizer_out(rp, out, sizeof(out));
+ * if (out_len < 0)
+ * {
+ * release_packets(data, nb_packets+1);
+ * return (int)out_len;
+ * }
+ * output_next_packet(out, out_len);
+ * opus_repacketizer_init(rp);
+ * release_packets(data, nb_packets);
+ * data[0] = data[nb_packets];
+ * len[0] = len[nb_packets];
+ * nb_packets = 0;
+ * }
+ * err = opus_repacketizer_cat(rp, data[nb_packets], len[nb_packets]);
+ * if (err != OPUS_OK)
+ * {
+ * release_packets(data, nb_packets+1);
+ * return err;
+ * }
+ * prev_toc = data[nb_packets][0];
+ * nb_packets++;
+ * }
+ * // Output the final, partial packet.
+ * if (nb_packets > 0)
+ * {
+ * out_len = opus_repacketizer_out(rp, out, sizeof(out));
+ * release_packets(data, nb_packets);
+ * if (out_len < 0)
+ * return (int)out_len;
+ * output_next_packet(out, out_len);
+ * }
+ * @endcode
+ *
+ * An alternate way of merging packets is to simply call opus_repacketizer_cat()
+ * unconditionally until it fails. At that point, the merged packet can be
+ * obtained with opus_repacketizer_out() and the input packet for which
+ * opus_repacketizer_cat() needs to be re-added to a newly reinitialized
+ * repacketizer state.
+ */
+
+typedef struct OpusRepacketizer OpusRepacketizer;
+
+/** Gets the size of an <code>OpusRepacketizer</code> structure.
+ * @return The size in bytes.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_size(void);
+
+/** (Re)initializes a previously allocated repacketizer state.
+ * The state must be at least the size returned by opus_repacketizer_get_size().
+ * This can be used for applications which use their own allocator instead of
+ * malloc().
+ * It must also be called to reset the queue of packets waiting to be
+ * repacketized, which is necessary if the maximum packet duration of 120 ms
+ * is reached or if you wish to submit packets with a different Opus
+ * configuration (coding mode, audio bandwidth, frame size, or channel count).
+ * Failure to do so will prevent a new packet from being added with
+ * opus_repacketizer_cat().
+ * @see opus_repacketizer_create
+ * @see opus_repacketizer_get_size
+ * @see opus_repacketizer_cat
+ * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state to
+ * (re)initialize.
+ * @return A pointer to the same repacketizer state that was passed in.
+ */
+OPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1);
+
+/** Allocates memory and initializes the new repacketizer with
+ * opus_repacketizer_init().
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusRepacketizer *opus_repacketizer_create(void);
+
+/** Frees an <code>OpusRepacketizer</code> allocated by
+ * opus_repacketizer_create().
+ * @param[in] rp <tt>OpusRepacketizer*</tt>: State to be freed.
+ */
+OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp);
+
+/** Add a packet to the current repacketizer state.
+ * This packet must match the configuration of any packets already submitted
+ * for repacketization since the last call to opus_repacketizer_init().
+ * This means that it must have the same coding mode, audio bandwidth, frame
+ * size, and channel count.
+ * This can be checked in advance by examining the top 6 bits of the first
+ * byte of the packet, and ensuring they match the top 6 bits of the first
+ * byte of any previously submitted packet.
+ * The total duration of audio in the repacketizer state also must not exceed
+ * 120 ms, the maximum duration of a single packet, after adding this packet.
+ *
+ * The contents of the current repacketizer state can be extracted into new
+ * packets using opus_repacketizer_out() or opus_repacketizer_out_range().
+ *
+ * In order to add a packet with a different configuration or to add more
+ * audio beyond 120 ms, you must clear the repacketizer state by calling
+ * opus_repacketizer_init().
+ * If a packet is too large to add to the current repacketizer state, no part
+ * of it is added, even if it contains multiple frames, some of which might
+ * fit.
+ * If you wish to be able to add parts of such packets, you should first use
+ * another repacketizer to split the packet into pieces and add them
+ * individually.
+ * @see opus_repacketizer_out_range
+ * @see opus_repacketizer_out
+ * @see opus_repacketizer_init
+ * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state to which to
+ * add the packet.
+ * @param[in] data <tt>const unsigned char*</tt>: The packet data.
+ * The application must ensure
+ * this pointer remains valid
+ * until the next call to
+ * opus_repacketizer_init() or
+ * opus_repacketizer_destroy().
+ * @param len <tt>opus_int32</tt>: The number of bytes in the packet data.
+ * @return An error code indicating whether or not the operation succeeded.
+ * @retval #OPUS_OK The packet's contents have been added to the repacketizer
+ * state.
+ * @retval #OPUS_INVALID_PACKET The packet did not have a valid TOC sequence,
+ * the packet's TOC sequence was not compatible
+ * with previously submitted packets (because
+ * the coding mode, audio bandwidth, frame size,
+ * or channel count did not match), or adding
+ * this packet would increase the total amount of
+ * audio stored in the repacketizer state to more
+ * than 120 ms.
+ */
+OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data,
+ opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
+
+
+/** Construct a new packet from data previously submitted to the repacketizer
+ * state via opus_repacketizer_cat().
+ * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state from which to
+ * construct the new packet.
+ * @param begin <tt>int</tt>: The index of the first frame in the current
+ * repacketizer state to include in the output.
+ * @param end <tt>int</tt>: One past the index of the last frame in the
+ * current repacketizer state to include in the
+ * output.
+ * @param[out] data <tt>const unsigned char*</tt>: The buffer in which to
+ * store the output packet.
+ * @param maxlen <tt>opus_int32</tt>: The maximum number of bytes to store in
+ * the output buffer. In order to guarantee
+ * success, this should be at least
+ * <code>1276</code> for a single frame,
+ * or for multiple frames,
+ * <code>1277*(end-begin)</code>.
+ * However, <code>1*(end-begin)</code> plus
+ * the size of all packet data submitted to
+ * the repacketizer since the last call to
+ * opus_repacketizer_init() or
+ * opus_repacketizer_create() is also
+ * sufficient, and possibly much smaller.
+ * @return The total size of the output packet on success, or an error code
+ * on failure.
+ * @retval #OPUS_BAD_ARG <code>[begin,end)</code> was an invalid range of
+ * frames (begin < 0, begin >= end, or end >
+ * opus_repacketizer_get_nb_frames()).
+ * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the
+ * complete output packet.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp,
+ int begin, int end, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Return the total number of frames contained in packet data submitted to
+ * the repacketizer state so far via opus_repacketizer_cat() since the last
+ * call to opus_repacketizer_init() or opus_repacketizer_create().
+ * This defines the valid range of packets that can be extracted with
+ * opus_repacketizer_out_range() or opus_repacketizer_out().
+ * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state containing the
+ * frames.
+ * @return The total number of frames contained in the packet data submitted
+ * to the repacketizer state.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(
+ OpusRepacketizer *rp) OPUS_ARG_NONNULL(1);
+
+/** Construct a new packet from data previously submitted to the repacketizer
+ * state via opus_repacketizer_cat().
+ * This is a convenience routine that return all the data submitted so far
+ * in a single packet.
+ * It is equivalent to calling
+ * @code
+ * opus_repacketizer_out_range(rp, 0, opus_repacketizer_get_nb_frames(rp),
+ * data, maxlen)
+ * @endcode
+ * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state from which to
+ * construct the new packet.
+ * @param[out] data <tt>const unsigned char*</tt>: The buffer in which to
+ * store the output packet.
+ * @param maxlen <tt>opus_int32</tt>: The maximum number of bytes to store in
+ * the output buffer. In order to guarantee
+ * success, this should be at least
+ * <code>1277*opus_repacketizer_get_nb_frames(rp)</code>.
+ * However,
+ * <code>1*opus_repacketizer_get_nb_frames(rp)</code>
+ * plus the size of all packet data
+ * submitted to the repacketizer since the
+ * last call to opus_repacketizer_init() or
+ * opus_repacketizer_create() is also
+ * sufficient, and possibly much smaller.
+ * @return The total size of the output packet on success, or an error code
+ * on failure.
+ * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the
+ * complete output packet.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp,
+ unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1);
+
+/** Pads a given Opus packet to a larger size (possibly changing the TOC sequence).
+ * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
+ * packet to pad.
+ * @param len <tt>opus_int32</tt>: The size of the packet.
+ * This must be at least 1.
+ * @param new_len <tt>opus_int32</tt>: The desired size of the packet after padding.
+ * This must be at least as large as len.
+ * @return an error code
+ * @retval #OPUS_OK \a on success.
+ * @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len.
+ * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
+ */
+OPUS_EXPORT int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len);
+
+/** Remove all padding from a given Opus packet and rewrite the TOC sequence to
+ * minimize space usage.
+ * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
+ * packet to strip.
+ * @param len <tt>opus_int32</tt>: The size of the packet.
+ * This must be at least 1.
+ * @return The new size of the output packet on success, or an error code
+ * on failure.
+ * @retval #OPUS_BAD_ARG \a len was less than 1.
+ * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_packet_unpad(unsigned char *data,
+ opus_int32 len);
+
+/** Pads a given Opus multi-stream packet to a larger size (possibly changing the TOC sequence).
+ * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
+ * packet to pad.
+ * @param len <tt>opus_int32</tt>: The size of the packet.
+ * This must be at least 1.
+ * @param new_len <tt>opus_int32</tt>: The desired size of the packet after padding.
+ * This must be at least 1.
+ * @param nb_streams <tt>opus_int32</tt>: The number of streams (not channels) in the packet.
+ * This must be at least as large as len.
+ * @return an error code
+ * @retval #OPUS_OK \a on success.
+ * @retval #OPUS_BAD_ARG \a len was less than 1.
+ * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
+ */
+OPUS_EXPORT int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len,
+ int nb_streams);
+
+/** Remove all padding from a given Opus multi-stream packet and rewrite the TOC sequence to
+ * minimize space usage.
+ * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
+ * packet to strip.
+ * @param len <tt>opus_int32</tt>: The size of the packet.
+ * This must be at least 1.
+ * @param nb_streams <tt>opus_int32</tt>: The number of streams (not channels) in the packet.
+ * This must be at least 1.
+ * @return The new size of the output packet on success, or an error code
+ * on failure.
+ * @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len.
+ * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_packet_unpad(unsigned char *data,
+ opus_int32 len, int nb_streams);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPUS_H */
diff --git a/inc/rcu/opus_inc/opus_custom.h b/inc/rcu/opus_inc/opus_custom.h
new file mode 100644
index 0000000..642c5f5
--- /dev/null
+++ b/inc/rcu/opus_inc/opus_custom.h
@@ -0,0 +1,345 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Copyright (c) 2008-2012 Gregory Maxwell
+ Written by Jean-Marc Valin and Gregory Maxwell */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ @file opus_custom.h
+ @brief Opus-Custom reference implementation API
+ */
+
+#ifndef OPUS_CUSTOM_H
+#define OPUS_CUSTOM_H
+
+#include "opus_defines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef CUSTOM_MODES
+# define OPUS_CUSTOM_EXPORT OPUS_EXPORT
+# define OPUS_CUSTOM_EXPORT_STATIC OPUS_EXPORT
+#else
+# define OPUS_CUSTOM_EXPORT
+# ifdef OPUS_BUILD
+# define OPUS_CUSTOM_EXPORT_STATIC static OPUS_INLINE
+# else
+# define OPUS_CUSTOM_EXPORT_STATIC
+# endif
+#endif
+
+/** @defgroup opus_custom Opus Custom
+ * @{
+ * Opus Custom is an optional part of the Opus specification and
+ * reference implementation which uses a distinct API from the regular
+ * API and supports frame sizes that are not normally supported.\ Use
+ * of Opus Custom is discouraged for all but very special applications
+ * for which a frame size different from 2.5, 5, 10, or 20 ms is needed
+ * (for either complexity or latency reasons) and where interoperability
+ * is less important.
+ *
+ * In addition to the interoperability limitations the use of Opus custom
+ * disables a substantial chunk of the codec and generally lowers the
+ * quality available at a given bitrate. Normally when an application needs
+ * a different frame size from the codec it should buffer to match the
+ * sizes but this adds a small amount of delay which may be important
+ * in some very low latency applications. Some transports (especially
+ * constant rate RF transports) may also work best with frames of
+ * particular durations.
+ *
+ * Libopus only supports custom modes if they are enabled at compile time.
+ *
+ * The Opus Custom API is similar to the regular API but the
+ * @ref opus_encoder_create and @ref opus_decoder_create calls take
+ * an additional mode parameter which is a structure produced by
+ * a call to @ref opus_custom_mode_create. Both the encoder and decoder
+ * must create a mode using the same sample rate (fs) and frame size
+ * (frame size) so these parameters must either be signaled out of band
+ * or fixed in a particular implementation.
+ *
+ * Similar to regular Opus the custom modes support on the fly frame size
+ * switching, but the sizes available depend on the particular frame size in
+ * use. For some initial frame sizes on a single on the fly size is available.
+ */
+
+/** Contains the state of an encoder. One encoder state is needed
+ for each stream. It is initialized once at the beginning of the
+ stream. Do *not* re-initialize the state for every frame.
+ @brief Encoder state
+ */
+typedef struct OpusCustomEncoder OpusCustomEncoder;
+
+/** State of the decoder. One decoder state is needed for each stream.
+ It is initialized once at the beginning of the stream. Do *not*
+ re-initialize the state for every frame.
+ @brief Decoder state
+ */
+typedef struct OpusCustomDecoder OpusCustomDecoder;
+
+/** The mode contains all the information necessary to create an
+ encoder. Both the encoder and decoder need to be initialized
+ with exactly the same mode, otherwise the output will be
+ corrupted.
+ @brief Mode configuration
+ */
+typedef struct OpusCustomMode OpusCustomMode;
+
+/** Creates a new mode struct. This will be passed to an encoder or
+ * decoder. The mode MUST NOT BE DESTROYED until the encoders and
+ * decoders that use it are destroyed as well.
+ * @param [in] Fs <tt>int</tt>: Sampling rate (8000 to 96000 Hz)
+ * @param [in] frame_size <tt>int</tt>: Number of samples (per channel) to encode in each
+ * packet (64 - 1024, prime factorization must contain zero or more 2s, 3s, or 5s and no other primes)
+ * @param [out] error <tt>int*</tt>: Returned error code (if NULL, no error will be returned)
+ * @return A newly created mode
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomMode *opus_custom_mode_create(opus_int32 Fs,
+ int frame_size, int *error);
+
+/** Destroys a mode struct. Only call this after all encoders and
+ * decoders using this mode are destroyed as well.
+ * @param [in] mode <tt>OpusCustomMode*</tt>: Mode to be freed.
+ */
+OPUS_CUSTOM_EXPORT void opus_custom_mode_destroy(OpusCustomMode *mode);
+
+
+#if !defined(OPUS_BUILD) || defined(CELT_ENCODER_C)
+
+/* Encoder */
+/** Gets the size of an OpusCustomEncoder structure.
+ * @param [in] mode <tt>OpusCustomMode *</tt>: Mode configuration
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @return size
+ */
+OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_encoder_get_size(
+ const OpusCustomMode *mode,
+ int channels
+) OPUS_ARG_NONNULL(1);
+
+# ifdef CUSTOM_MODES
+/** Initializes a previously allocated encoder state
+ * The memory pointed to by st must be the size returned by opus_custom_encoder_get_size.
+ * This is intended for applications which use their own allocator instead of malloc.
+ * @see opus_custom_encoder_create(),opus_custom_encoder_get_size()
+ * To reset a previously initialized state use the OPUS_RESET_STATE CTL.
+ * @param [in] st <tt>OpusCustomEncoder*</tt>: Encoder state
+ * @param [in] mode <tt>OpusCustomMode *</tt>: Contains all the information about the characteristics of
+ * the stream (must be the same characteristics as used for the
+ * decoder)
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @return OPUS_OK Success or @ref opus_errorcodes
+ */
+OPUS_CUSTOM_EXPORT int opus_custom_encoder_init(
+ OpusCustomEncoder *st,
+ const OpusCustomMode *mode,
+ int channels
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
+# endif
+#endif
+
+
+/** Creates a new encoder state. Each stream needs its own encoder
+ * state (can't be shared across simultaneous streams).
+ * @param [in] mode <tt>OpusCustomMode*</tt>: Contains all the information about the characteristics of
+ * the stream (must be the same characteristics as used for the
+ * decoder)
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @param [out] error <tt>int*</tt>: return an error code
+ * @return Newly created encoder state.
+*/
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomEncoder *opus_custom_encoder_create(
+ const OpusCustomMode *mode,
+ int channels,
+ int *error
+) OPUS_ARG_NONNULL(1);
+
+
+/** Destroys a an encoder state.
+ * @param[in] st <tt>OpusCustomEncoder*</tt>: State to be freed.
+ */
+OPUS_CUSTOM_EXPORT void opus_custom_encoder_destroy(OpusCustomEncoder *st);
+
+/** Encodes a frame of audio.
+ * @param [in] st <tt>OpusCustomEncoder*</tt>: Encoder state
+ * @param [in] pcm <tt>float*</tt>: PCM audio in float format, with a normal range of +/-1.0.
+ * Samples with a range beyond +/-1.0 are supported but will
+ * be clipped by decoders using the integer API and should
+ * only be used if it is known that the far end supports
+ * extended dynamic range. There must be exactly
+ * frame_size samples per channel.
+ * @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal
+ * @param [out] compressed <tt>char *</tt>: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long.
+ * @param [in] maxCompressedBytes <tt>int</tt>: Maximum number of bytes to use for compressing the frame
+ * (can change from one frame to another)
+ * @return Number of bytes written to "compressed".
+ * If negative, an error has occurred (see error codes). It is IMPORTANT that
+ * the length returned be somehow transmitted to the decoder. Otherwise, no
+ * decoding is possible.
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode_float(
+ OpusCustomEncoder *st,
+ const float *pcm,
+ int frame_size,
+ unsigned char *compressed,
+ int maxCompressedBytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Encodes a frame of audio.
+ * @param [in] st <tt>OpusCustomEncoder*</tt>: Encoder state
+ * @param [in] pcm <tt>opus_int16*</tt>: PCM audio in signed 16-bit format (native endian).
+ * There must be exactly frame_size samples per channel.
+ * @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal
+ * @param [out] compressed <tt>char *</tt>: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long.
+ * @param [in] maxCompressedBytes <tt>int</tt>: Maximum number of bytes to use for compressing the frame
+ * (can change from one frame to another)
+ * @return Number of bytes written to "compressed".
+ * If negative, an error has occurred (see error codes). It is IMPORTANT that
+ * the length returned be somehow transmitted to the decoder. Otherwise, no
+ * decoding is possible.
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode(
+ OpusCustomEncoder *st,
+ const opus_int16 *pcm,
+ int frame_size,
+ unsigned char *compressed,
+ int maxCompressedBytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Perform a CTL function on an Opus custom encoder.
+ *
+ * Generally the request and subsequent arguments are generated
+ * by a convenience macro.
+ * @see opus_encoderctls
+ */
+OPUS_CUSTOM_EXPORT int opus_custom_encoder_ctl(OpusCustomEncoder *OPUS_RESTRICT st, int request,
+ ...) OPUS_ARG_NONNULL(1);
+
+
+#if !defined(OPUS_BUILD) || defined(CELT_DECODER_C)
+/* Decoder */
+
+/** Gets the size of an OpusCustomDecoder structure.
+ * @param [in] mode <tt>OpusCustomMode *</tt>: Mode configuration
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @return size
+ */
+OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_decoder_get_size(
+ const OpusCustomMode *mode,
+ int channels
+) OPUS_ARG_NONNULL(1);
+
+/** Initializes a previously allocated decoder state
+ * The memory pointed to by st must be the size returned by opus_custom_decoder_get_size.
+ * This is intended for applications which use their own allocator instead of malloc.
+ * @see opus_custom_decoder_create(),opus_custom_decoder_get_size()
+ * To reset a previously initialized state use the OPUS_RESET_STATE CTL.
+ * @param [in] st <tt>OpusCustomDecoder*</tt>: Decoder state
+ * @param [in] mode <tt>OpusCustomMode *</tt>: Contains all the information about the characteristics of
+ * the stream (must be the same characteristics as used for the
+ * encoder)
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @return OPUS_OK Success or @ref opus_errorcodes
+ */
+OPUS_CUSTOM_EXPORT_STATIC int opus_custom_decoder_init(
+ OpusCustomDecoder *st,
+ const OpusCustomMode *mode,
+ int channels
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
+
+#endif
+
+
+/** Creates a new decoder state. Each stream needs its own decoder state (can't
+ * be shared across simultaneous streams).
+ * @param [in] mode <tt>OpusCustomMode</tt>: Contains all the information about the characteristics of the
+ * stream (must be the same characteristics as used for the encoder)
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @param [out] error <tt>int*</tt>: return an error code
+ * @return Newly created decoder state.
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomDecoder *opus_custom_decoder_create(
+ const OpusCustomMode *mode,
+ int channels,
+ int *error
+) OPUS_ARG_NONNULL(1);
+
+/** Destroys a a decoder state.
+ * @param[in] st <tt>OpusCustomDecoder*</tt>: State to be freed.
+ */
+OPUS_CUSTOM_EXPORT void opus_custom_decoder_destroy(OpusCustomDecoder *st);
+
+/** Decode an opus custom frame with floating point output
+ * @param [in] st <tt>OpusCustomDecoder*</tt>: Decoder state
+ * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
+ * @param [in] len <tt>int</tt>: Number of bytes in payload
+ * @param [out] pcm <tt>float*</tt>: Output signal (interleaved if 2 channels). length
+ * is frame_size*channels*sizeof(float)
+ * @param [in] frame_size Number of samples per channel of available space in *pcm.
+ * @return Number of decoded samples or @ref opus_errorcodes
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode_float(
+ OpusCustomDecoder *st,
+ const unsigned char *data,
+ int len,
+ float *pcm,
+ int frame_size
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Decode an opus custom frame
+ * @param [in] st <tt>OpusCustomDecoder*</tt>: Decoder state
+ * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
+ * @param [in] len <tt>int</tt>: Number of bytes in payload
+ * @param [out] pcm <tt>opus_int16*</tt>: Output signal (interleaved if 2 channels). length
+ * is frame_size*channels*sizeof(opus_int16)
+ * @param [in] frame_size Number of samples per channel of available space in *pcm.
+ * @return Number of decoded samples or @ref opus_errorcodes
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode(
+ OpusCustomDecoder *st,
+ const unsigned char *data,
+ int len,
+ opus_int16 *pcm,
+ int frame_size
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Perform a CTL function on an Opus custom decoder.
+ *
+ * Generally the request and subsequent arguments are generated
+ * by a convenience macro.
+ * @see opus_genericctls
+ */
+OPUS_CUSTOM_EXPORT int opus_custom_decoder_ctl(OpusCustomDecoder *OPUS_RESTRICT st, int request,
+ ...) OPUS_ARG_NONNULL(1);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPUS_CUSTOM_H */
diff --git a/inc/rcu/opus_inc/opus_defines.h b/inc/rcu/opus_inc/opus_defines.h
new file mode 100644
index 0000000..16ef110
--- /dev/null
+++ b/inc/rcu/opus_inc/opus_defines.h
@@ -0,0 +1,753 @@
+/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited
+ Written by Jean-Marc Valin and Koen Vos */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * @file opus_defines.h
+ * @brief Opus reference implementation constants
+ */
+
+#ifndef OPUS_DEFINES_H
+#define OPUS_DEFINES_H
+
+#include "opus_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup opus_errorcodes Error codes
+ * @{
+ */
+/** No error @hideinitializer*/
+#define OPUS_OK 0
+/** One or more invalid/out of range arguments @hideinitializer*/
+#define OPUS_BAD_ARG -1
+/** Not enough bytes allocated in the buffer @hideinitializer*/
+#define OPUS_BUFFER_TOO_SMALL -2
+/** An internal error was detected @hideinitializer*/
+#define OPUS_INTERNAL_ERROR -3
+/** The compressed data passed is corrupted @hideinitializer*/
+#define OPUS_INVALID_PACKET -4
+/** Invalid/unsupported request number @hideinitializer*/
+#define OPUS_UNIMPLEMENTED -5
+/** An encoder or decoder structure is invalid or already freed @hideinitializer*/
+#define OPUS_INVALID_STATE -6
+/** Memory allocation has failed @hideinitializer*/
+#define OPUS_ALLOC_FAIL -7
+/**@}*/
+
+/** @cond OPUS_INTERNAL_DOC */
+/**Export control for opus functions */
+
+#ifndef OPUS_EXPORT
+# if defined(WIN32)
+# if defined(OPUS_BUILD) && defined(DLL_EXPORT)
+# define OPUS_EXPORT __declspec(dllexport)
+# else
+# define OPUS_EXPORT
+# endif
+# elif defined(__GNUC__) && defined(OPUS_BUILD)
+# define OPUS_EXPORT __attribute__ ((visibility ("default")))
+# else
+# define OPUS_EXPORT
+# endif
+#endif
+
+# if !defined(OPUS_GNUC_PREREQ)
+# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
+# define OPUS_GNUC_PREREQ(_maj,_min) \
+ ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))
+# else
+# define OPUS_GNUC_PREREQ(_maj,_min) 0
+# endif
+# endif
+
+#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
+# if OPUS_GNUC_PREREQ(3,0)
+# define OPUS_RESTRICT __restrict__
+# elif (defined(_MSC_VER) && _MSC_VER >= 1400)
+# define OPUS_RESTRICT __restrict
+# else
+# define OPUS_RESTRICT __restrict //ken
+# endif
+#else
+# define OPUS_RESTRICT __restrict
+#endif
+
+#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
+# if OPUS_GNUC_PREREQ(2,7)
+# define OPUS_INLINE __inline__
+# elif (defined(_MSC_VER))
+# define OPUS_INLINE __inline
+# else
+# define OPUS_INLINE __inline
+# endif
+#else
+# define OPUS_INLINE inline
+#endif
+
+/**Warning attributes for opus functions
+ * NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out
+ * some paranoid null checks. */
+#if defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4)
+# define OPUS_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__))
+#else
+# define OPUS_WARN_UNUSED_RESULT
+#endif
+#if !defined(OPUS_BUILD) && defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4)
+# define OPUS_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x)))
+#else
+# define OPUS_ARG_NONNULL(_x)
+#endif
+
+/** These are the actual Encoder CTL ID numbers.
+ * They should not be used directly by applications.
+ * In general, SETs should be even and GETs should be odd.*/
+#define OPUS_SET_APPLICATION_REQUEST 4000
+#define OPUS_GET_APPLICATION_REQUEST 4001
+#define OPUS_SET_BITRATE_REQUEST 4002
+#define OPUS_GET_BITRATE_REQUEST 4003
+#define OPUS_SET_MAX_BANDWIDTH_REQUEST 4004
+#define OPUS_GET_MAX_BANDWIDTH_REQUEST 4005
+#define OPUS_SET_VBR_REQUEST 4006
+#define OPUS_GET_VBR_REQUEST 4007
+#define OPUS_SET_BANDWIDTH_REQUEST 4008
+#define OPUS_GET_BANDWIDTH_REQUEST 4009
+#define OPUS_SET_COMPLEXITY_REQUEST 4010
+#define OPUS_GET_COMPLEXITY_REQUEST 4011
+#define OPUS_SET_INBAND_FEC_REQUEST 4012
+#define OPUS_GET_INBAND_FEC_REQUEST 4013
+#define OPUS_SET_PACKET_LOSS_PERC_REQUEST 4014
+#define OPUS_GET_PACKET_LOSS_PERC_REQUEST 4015
+#define OPUS_SET_DTX_REQUEST 4016
+#define OPUS_GET_DTX_REQUEST 4017
+#define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020
+#define OPUS_GET_VBR_CONSTRAINT_REQUEST 4021
+#define OPUS_SET_FORCE_CHANNELS_REQUEST 4022
+#define OPUS_GET_FORCE_CHANNELS_REQUEST 4023
+#define OPUS_SET_SIGNAL_REQUEST 4024
+#define OPUS_GET_SIGNAL_REQUEST 4025
+#define OPUS_GET_LOOKAHEAD_REQUEST 4027
+/* #define OPUS_RESET_STATE 4028 */
+#define OPUS_GET_SAMPLE_RATE_REQUEST 4029
+#define OPUS_GET_FINAL_RANGE_REQUEST 4031
+#define OPUS_GET_PITCH_REQUEST 4033
+#define OPUS_SET_GAIN_REQUEST 4034
+#define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */
+#define OPUS_SET_LSB_DEPTH_REQUEST 4036
+#define OPUS_GET_LSB_DEPTH_REQUEST 4037
+#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039
+#define OPUS_SET_EXPERT_FRAME_DURATION_REQUEST 4040
+#define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041
+#define OPUS_SET_PREDICTION_DISABLED_REQUEST 4042
+#define OPUS_GET_PREDICTION_DISABLED_REQUEST 4043
+
+/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */
+
+/* Macros to trigger compilation errors when the wrong types are provided to a CTL */
+#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
+#define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr)))
+#define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr)))
+#define __opus_check_val16_ptr(ptr) ((ptr) + ((ptr) - (opus_val16*)(ptr)))
+/** @endcond */
+
+/** @defgroup opus_ctlvalues Pre-defined values for CTL interface
+ * @see opus_genericctls, opus_encoderctls
+ * @{
+ */
+/* Values for the various encoder CTLs */
+#define OPUS_AUTO -1000 /**<Auto/default setting @hideinitializer*/
+#define OPUS_BITRATE_MAX -1 /**<Maximum bitrate @hideinitializer*/
+
+/** Best for most VoIP/videoconference applications where listening quality and intelligibility matter most
+ * @hideinitializer */
+#define OPUS_APPLICATION_VOIP 2048
+/** Best for broadcast/high-fidelity application where the decoded audio should be as close as possible to the input
+ * @hideinitializer */
+#define OPUS_APPLICATION_AUDIO 2049
+/** Only use when lowest-achievable latency is what matters most. Voice-optimized modes cannot be used.
+ * @hideinitializer */
+#define OPUS_APPLICATION_RESTRICTED_LOWDELAY 2051
+
+#define OPUS_SIGNAL_VOICE 3001 /**< Signal being encoded is voice */
+#define OPUS_SIGNAL_MUSIC 3002 /**< Signal being encoded is music */
+#define OPUS_BANDWIDTH_NARROWBAND 1101 /**< 4 kHz bandpass @hideinitializer*/
+#define OPUS_BANDWIDTH_MEDIUMBAND 1102 /**< 6 kHz bandpass @hideinitializer*/
+#define OPUS_BANDWIDTH_WIDEBAND 1103 /**< 8 kHz bandpass @hideinitializer*/
+#define OPUS_BANDWIDTH_SUPERWIDEBAND 1104 /**<12 kHz bandpass @hideinitializer*/
+#define OPUS_BANDWIDTH_FULLBAND 1105 /**<20 kHz bandpass @hideinitializer*/
+
+#define OPUS_FRAMESIZE_ARG 5000 /**< Select frame size from the argument (default) */
+#define OPUS_FRAMESIZE_2_5_MS 5001 /**< Use 2.5 ms frames */
+#define OPUS_FRAMESIZE_5_MS 5002 /**< Use 5 ms frames */
+#define OPUS_FRAMESIZE_10_MS 5003 /**< Use 10 ms frames */
+#define OPUS_FRAMESIZE_20_MS 5004 /**< Use 20 ms frames */
+#define OPUS_FRAMESIZE_40_MS 5005 /**< Use 40 ms frames */
+#define OPUS_FRAMESIZE_60_MS 5006 /**< Use 60 ms frames */
+
+/**@}*/
+
+
+/** @defgroup opus_encoderctls Encoder related CTLs
+ *
+ * These are convenience macros for use with the \c opus_encode_ctl
+ * interface. They are used to generate the appropriate series of
+ * arguments for that call, passing the correct type, size and so
+ * on as expected for each particular request.
+ *
+ * Some usage examples:
+ *
+ * @code
+ * int ret;
+ * ret = opus_encoder_ctl(enc_ctx, OPUS_SET_BANDWIDTH(OPUS_AUTO));
+ * if (ret != OPUS_OK) return ret;
+ *
+ * opus_int32 rate;
+ * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&rate));
+ *
+ * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE);
+ * @endcode
+ *
+ * @see opus_genericctls, opus_encoder
+ * @{
+ */
+
+/** Configures the encoder's computational complexity.
+ * The supported range is 0-10 inclusive with 10 representing the highest complexity.
+ * @see OPUS_GET_COMPLEXITY
+ * @param[in] x <tt>opus_int32</tt>: Allowed values: 0-10, inclusive.
+ *
+ * @hideinitializer */
+#define OPUS_SET_COMPLEXITY(x) OPUS_SET_COMPLEXITY_REQUEST, __opus_check_int(x)
+/** Gets the encoder's complexity configuration.
+ * @see OPUS_SET_COMPLEXITY
+ * @param[out] x <tt>opus_int32 *</tt>: return a value in the range 0-10,
+ * inclusive.
+ * @hideinitializer */
+#define OPUS_GET_COMPLEXITY(x) OPUS_GET_COMPLEXITY_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the bitrate in the encoder.
+ * Rates from 500 to 512000 bits per second are meaningful, as well as the
+ * special values #OPUS_AUTO and #OPUS_BITRATE_MAX.
+ * The value #OPUS_BITRATE_MAX can be used to cause the codec to use as much
+ * rate as it can, which is useful for controlling the rate by adjusting the
+ * output buffer size.
+ * @see OPUS_GET_BITRATE
+ * @param[in] x <tt>opus_int32</tt>: Bitrate in bits per second. The default
+ * is determined based on the number of
+ * channels and the input sampling rate.
+ * @hideinitializer */
+#define OPUS_SET_BITRATE(x) OPUS_SET_BITRATE_REQUEST, __opus_check_int(x)
+/** Gets the encoder's bitrate configuration.
+ * @see OPUS_SET_BITRATE
+ * @param[out] x <tt>opus_int32 *</tt>: return the bitrate in bits per second.
+ * The default is determined based on the
+ * number of channels and the input
+ * sampling rate.
+ * @hideinitializer */
+#define OPUS_GET_BITRATE(x) OPUS_GET_BITRATE_REQUEST, __opus_check_int_ptr(x)
+
+/** Enables or disables variable bitrate (VBR) in the encoder.
+ * The configured bitrate may not be met exactly because frames must
+ * be an integer number of bytes in length.
+ * @see OPUS_GET_VBR
+ * @see OPUS_SET_VBR_CONSTRAINT
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>0</dt><dd>Hard CBR. For LPC/hybrid modes at very low bit-rate, this can
+ * cause noticeable quality degradation.</dd>
+ * <dt>1</dt><dd>VBR (default). The exact type of VBR is controlled by
+ * #OPUS_SET_VBR_CONSTRAINT.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_VBR(x) OPUS_SET_VBR_REQUEST, __opus_check_int(x)
+/** Determine if variable bitrate (VBR) is enabled in the encoder.
+ * @see OPUS_SET_VBR
+ * @see OPUS_GET_VBR_CONSTRAINT
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>0</dt><dd>Hard CBR.</dd>
+ * <dt>1</dt><dd>VBR (default). The exact type of VBR may be retrieved via
+ * #OPUS_GET_VBR_CONSTRAINT.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_VBR(x) OPUS_GET_VBR_REQUEST, __opus_check_int_ptr(x)
+
+/** Enables or disables constrained VBR in the encoder.
+ * This setting is ignored when the encoder is in CBR mode.
+ * @warning Only the MDCT mode of Opus currently heeds the constraint.
+ * Speech mode ignores it completely, hybrid mode may fail to obey it
+ * if the LPC layer uses more bitrate than the constraint would have
+ * permitted.
+ * @see OPUS_GET_VBR_CONSTRAINT
+ * @see OPUS_SET_VBR
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>0</dt><dd>Unconstrained VBR.</dd>
+ * <dt>1</dt><dd>Constrained VBR (default). This creates a maximum of one
+ * frame of buffering delay assuming a transport with a
+ * serialization speed of the nominal bitrate.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x)
+/** Determine if constrained VBR is enabled in the encoder.
+ * @see OPUS_SET_VBR_CONSTRAINT
+ * @see OPUS_GET_VBR
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>0</dt><dd>Unconstrained VBR.</dd>
+ * <dt>1</dt><dd>Constrained VBR (default).</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures mono/stereo forcing in the encoder.
+ * This can force the encoder to produce packets encoded as either mono or
+ * stereo, regardless of the format of the input audio. This is useful when
+ * the caller knows that the input signal is currently a mono source embedded
+ * in a stereo stream.
+ * @see OPUS_GET_FORCE_CHANNELS
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt><dd>Not forced (default)</dd>
+ * <dt>1</dt> <dd>Forced mono</dd>
+ * <dt>2</dt> <dd>Forced stereo</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x)
+/** Gets the encoder's forced channel configuration.
+ * @see OPUS_SET_FORCE_CHANNELS
+ * @param[out] x <tt>opus_int32 *</tt>:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt><dd>Not forced (default)</dd>
+ * <dt>1</dt> <dd>Forced mono</dd>
+ * <dt>2</dt> <dd>Forced stereo</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the maximum bandpass that the encoder will select automatically.
+ * Applications should normally use this instead of #OPUS_SET_BANDWIDTH
+ * (leaving that set to the default, #OPUS_AUTO). This allows the
+ * application to set an upper bound based on the type of input it is
+ * providing, but still gives the encoder the freedom to reduce the bandpass
+ * when the bitrate becomes too low, for better overall quality.
+ * @see OPUS_GET_MAX_BANDWIDTH
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
+ * <dt>OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
+ * <dt>OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
+ * <dt>OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
+ * <dt>OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband (default)</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_MAX_BANDWIDTH(x) OPUS_SET_MAX_BANDWIDTH_REQUEST, __opus_check_int(x)
+
+/** Gets the encoder's configured maximum allowed bandpass.
+ * @see OPUS_SET_MAX_BANDWIDTH
+ * @param[out] x <tt>opus_int32 *</tt>: Allowed values:
+ * <dl>
+ * <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband (default)</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x)
+
+/** Sets the encoder's bandpass to a specific value.
+ * This prevents the encoder from automatically selecting the bandpass based
+ * on the available bitrate. If an application knows the bandpass of the input
+ * audio it is providing, it should normally use #OPUS_SET_MAX_BANDWIDTH
+ * instead, which still gives the encoder the freedom to reduce the bandpass
+ * when the bitrate becomes too low, for better overall quality.
+ * @see OPUS_GET_BANDWIDTH
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
+ * <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __opus_check_int(x)
+
+/** Configures the type of signal being encoded.
+ * This is a hint which helps the encoder's mode selection.
+ * @see OPUS_GET_SIGNAL
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
+ * <dt>#OPUS_SIGNAL_VOICE</dt><dd>Bias thresholds towards choosing LPC or Hybrid modes.</dd>
+ * <dt>#OPUS_SIGNAL_MUSIC</dt><dd>Bias thresholds towards choosing MDCT modes.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured signal type.
+ * @see OPUS_SET_SIGNAL
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
+ * <dt>#OPUS_SIGNAL_VOICE</dt><dd>Bias thresholds towards choosing LPC or Hybrid modes.</dd>
+ * <dt>#OPUS_SIGNAL_MUSIC</dt><dd>Bias thresholds towards choosing MDCT modes.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __opus_check_int_ptr(x)
+
+
+/** Configures the encoder's intended application.
+ * The initial value is a mandatory argument to the encoder_create function.
+ * @see OPUS_GET_APPLICATION
+ * @param[in] x <tt>opus_int32</tt>: return one of the following values:
+ * <dl>
+ * <dt>#OPUS_APPLICATION_VOIP</dt>
+ * <dd>Process signal for improved speech intelligibility.</dd>
+ * <dt>#OPUS_APPLICATION_AUDIO</dt>
+ * <dd>Favor faithfulness to the original input.</dd>
+ * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
+ * <dd>Configure the minimum possible coding delay by disabling certain modes
+ * of operation.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_APPLICATION(x) OPUS_SET_APPLICATION_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured application.
+ * @see OPUS_SET_APPLICATION
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>#OPUS_APPLICATION_VOIP</dt>
+ * <dd>Process signal for improved speech intelligibility.</dd>
+ * <dt>#OPUS_APPLICATION_AUDIO</dt>
+ * <dd>Favor faithfulness to the original input.</dd>
+ * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
+ * <dd>Configure the minimum possible coding delay by disabling certain modes
+ * of operation.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x)
+
+/** Gets the total samples of delay added by the entire codec.
+ * This can be queried by the encoder and then the provided number of samples can be
+ * skipped on from the start of the decoder's output to provide time aligned input
+ * and output. From the perspective of a decoding application the real data begins this many
+ * samples late.
+ *
+ * The decoder contribution to this delay is identical for all decoders, but the
+ * encoder portion of the delay may vary from implementation to implementation,
+ * version to version, or even depend on the encoder's initial configuration.
+ * Applications needing delay compensation should call this CTL rather than
+ * hard-coding a value.
+ * @param[out] x <tt>opus_int32 *</tt>: Number of lookahead samples
+ * @hideinitializer */
+#define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the encoder's use of inband forward error correction (FEC).
+ * @note This is only applicable to the LPC layer
+ * @see OPUS_GET_INBAND_FEC
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>0</dt><dd>Disable inband FEC (default).</dd>
+ * <dt>1</dt><dd>Enable inband FEC.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x)
+/** Gets encoder's configured use of inband forward error correction.
+ * @see OPUS_SET_INBAND_FEC
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>0</dt><dd>Inband FEC disabled (default).</dd>
+ * <dt>1</dt><dd>Inband FEC enabled.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the encoder's expected packet loss percentage.
+ * Higher values trigger progressively more loss resistant behavior in the encoder
+ * at the expense of quality at a given bitrate in the absence of packet loss, but
+ * greater quality under loss.
+ * @see OPUS_GET_PACKET_LOSS_PERC
+ * @param[in] x <tt>opus_int32</tt>: Loss percentage in the range 0-100, inclusive (default: 0).
+ * @hideinitializer */
+#define OPUS_SET_PACKET_LOSS_PERC(x) OPUS_SET_PACKET_LOSS_PERC_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured packet loss percentage.
+ * @see OPUS_SET_PACKET_LOSS_PERC
+ * @param[out] x <tt>opus_int32 *</tt>: return the configured loss percentage
+ * in the range 0-100, inclusive (default: 0).
+ * @hideinitializer */
+#define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the encoder's use of discontinuous transmission (DTX).
+ * @note This is only applicable to the LPC layer
+ * @see OPUS_GET_DTX
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>0</dt><dd>Disable DTX (default).</dd>
+ * <dt>1</dt><dd>Enabled DTX.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __opus_check_int(x)
+/** Gets encoder's configured use of discontinuous transmission.
+ * @see OPUS_SET_DTX
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>0</dt><dd>DTX disabled (default).</dd>
+ * <dt>1</dt><dd>DTX enabled.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x)
+/** Configures the depth of signal being encoded.
+ *
+ * This is a hint which helps the encoder identify silence and near-silence.
+ * It represents the number of significant bits of linear intensity below
+ * which the signal contains ignorable quantization or other noise.
+ *
+ * For example, OPUS_SET_LSB_DEPTH(14) would be an appropriate setting
+ * for G.711 u-law input. OPUS_SET_LSB_DEPTH(16) would be appropriate
+ * for 16-bit linear pcm input with opus_encode_float().
+ *
+ * When using opus_encode() instead of opus_encode_float(), or when libopus
+ * is compiled for fixed-point, the encoder uses the minimum of the value
+ * set here and the value 16.
+ *
+ * @see OPUS_GET_LSB_DEPTH
+ * @param[in] x <tt>opus_int32</tt>: Input precision in bits, between 8 and 24
+ * (default: 24).
+ * @hideinitializer */
+#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured signal depth.
+ * @see OPUS_SET_LSB_DEPTH
+ * @param[out] x <tt>opus_int32 *</tt>: Input precision in bits, between 8 and
+ * 24 (default: 24).
+ * @hideinitializer */
+#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the encoder's use of variable duration frames.
+ * When variable duration is enabled, the encoder is free to use a shorter frame
+ * size than the one requested in the opus_encode*() call.
+ * It is then the user's responsibility
+ * to verify how much audio was encoded by checking the ToC byte of the encoded
+ * packet. The part of the audio that was not encoded needs to be resent to the
+ * encoder for the next call. Do not use this option unless you <b>really</b>
+ * know what you are doing.
+ * @see OPUS_GET_EXPERT_FRAME_DURATION
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd>
+ * <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 5 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_EXPERT_FRAME_DURATION(x) OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured use of variable duration frames.
+ * @see OPUS_SET_EXPERT_FRAME_DURATION
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd>
+ * <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 5 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x)
+
+/** If set to 1, disables almost all use of prediction, making frames almost
+ * completely independent. This reduces quality.
+ * @see OPUS_GET_PREDICTION_DISABLED
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>0</dt><dd>Enable prediction (default).</dd>
+ * <dt>1</dt><dd>Disable prediction.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_PREDICTION_DISABLED(x) OPUS_SET_PREDICTION_DISABLED_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured prediction status.
+ * @see OPUS_SET_PREDICTION_DISABLED
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>0</dt><dd>Prediction enabled (default).</dd>
+ * <dt>1</dt><dd>Prediction disabled.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x)
+
+/**@}*/
+
+/** @defgroup opus_genericctls Generic CTLs
+ *
+ * These macros are used with the \c opus_decoder_ctl and
+ * \c opus_encoder_ctl calls to generate a particular
+ * request.
+ *
+ * When called on an \c OpusDecoder they apply to that
+ * particular decoder instance. When called on an
+ * \c OpusEncoder they apply to the corresponding setting
+ * on that encoder instance, if present.
+ *
+ * Some usage examples:
+ *
+ * @code
+ * int ret;
+ * opus_int32 pitch;
+ * ret = opus_decoder_ctl(dec_ctx, OPUS_GET_PITCH(&pitch));
+ * if (ret == OPUS_OK) return ret;
+ *
+ * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE);
+ * opus_decoder_ctl(dec_ctx, OPUS_RESET_STATE);
+ *
+ * opus_int32 enc_bw, dec_bw;
+ * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&enc_bw));
+ * opus_decoder_ctl(dec_ctx, OPUS_GET_BANDWIDTH(&dec_bw));
+ * if (enc_bw != dec_bw) {
+ * printf("packet bandwidth mismatch!\n");
+ * }
+ * @endcode
+ *
+ * @see opus_encoder, opus_decoder_ctl, opus_encoder_ctl, opus_decoderctls, opus_encoderctls
+ * @{
+ */
+
+/** Resets the codec state to be equivalent to a freshly initialized state.
+ * This should be called when switching streams in order to prevent
+ * the back to back decoding from giving different results from
+ * one at a time decoding.
+ * @hideinitializer */
+#define OPUS_RESET_STATE 4028
+
+/** Gets the final state of the codec's entropy coder.
+ * This is used for testing purposes,
+ * The encoder and decoder state should be identical after coding a payload
+ * (assuming no data corruption or software bugs)
+ *
+ * @param[out] x <tt>opus_uint32 *</tt>: Entropy coder state
+ *
+ * @hideinitializer */
+#define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x)
+
+/** Gets the encoder's configured bandpass or the decoder's last bandpass.
+ * @see OPUS_SET_BANDWIDTH
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
+ * <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x)
+
+/** Gets the sampling rate the encoder or decoder was initialized with.
+ * This simply return the <code>Fs</code> value passed to opus_encoder_init()
+ * or opus_decoder_init().
+ * @param[out] x <tt>opus_int32 *</tt>: Sampling rate of encoder or decoder.
+ * @hideinitializer
+ */
+#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x)
+
+/**@}*/
+
+/** @defgroup opus_decoderctls Decoder related CTLs
+ * @see opus_genericctls, opus_encoderctls, opus_decoder
+ * @{
+ */
+
+/** Configures decoder gain adjustment.
+ * Scales the decoded output by a factor specified in Q8 dB units.
+ * This has a maximum range of -32768 to 32767 inclusive, and return
+ * OPUS_BAD_ARG otherwise. The default is zero indicating no adjustment.
+ * This setting survives decoder reset.
+ *
+ * gain = pow(10, x/(20.0*256))
+ *
+ * @param[in] x <tt>opus_int32</tt>: Amount to scale PCM signal by in Q8 dB units.
+ * @hideinitializer */
+#define OPUS_SET_GAIN(x) OPUS_SET_GAIN_REQUEST, __opus_check_int(x)
+/** Gets the decoder's configured gain adjustment. @see OPUS_SET_GAIN
+ *
+ * @param[out] x <tt>opus_int32 *</tt>: Amount to scale PCM signal by in Q8 dB units.
+ * @hideinitializer */
+#define OPUS_GET_GAIN(x) OPUS_GET_GAIN_REQUEST, __opus_check_int_ptr(x)
+
+/** Gets the duration (in samples) of the last packet successfully decoded or concealed.
+ * @param[out] x <tt>opus_int32 *</tt>: Number of samples (at current sampling rate).
+ * @hideinitializer */
+#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x)
+
+/** Gets the pitch of the last decoded frame, if available.
+ * This can be used for any post-processing algorithm requiring the use of pitch,
+ * e.g. time stretching/shortening. If the last frame was not voiced, or if the
+ * pitch was not coded in the frame, then zero is returned.
+ *
+ * This CTL is only implemented for decoder instances.
+ *
+ * @param[out] x <tt>opus_int32 *</tt>: pitch period at 48 kHz (or 0 if not available)
+ *
+ * @hideinitializer */
+#define OPUS_GET_PITCH(x) OPUS_GET_PITCH_REQUEST, __opus_check_int_ptr(x)
+
+/**@}*/
+
+/** @defgroup opus_libinfo Opus library information functions
+ * @{
+ */
+
+/** Converts an opus error code into a human readable string.
+ *
+ * @param[in] error <tt>int</tt>: Error number
+ * @return Error string
+ */
+OPUS_EXPORT const char *opus_strerror(int error);
+
+/** Gets the libopus version string.
+ *
+ * Applications may look for the substring "-fixed" in the version string to
+ * determine whether they have a fixed-point or floating-point build at
+ * runtime.
+ *
+ * @return Version string
+ */
+OPUS_EXPORT const char *opus_get_version_string(void);
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPUS_DEFINES_H */
diff --git a/inc/rcu/opus_inc/opus_multistream.h b/inc/rcu/opus_inc/opus_multistream.h
new file mode 100644
index 0000000..75f069c
--- /dev/null
+++ b/inc/rcu/opus_inc/opus_multistream.h
@@ -0,0 +1,662 @@
+/* Copyright (c) 2011 Xiph.Org Foundation
+ Written by Jean-Marc Valin */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * @file opus_multistream.h
+ * @brief Opus reference implementation multistream API
+ */
+
+#ifndef OPUS_MULTISTREAM_H
+#define OPUS_MULTISTREAM_H
+
+#include "opus.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @cond OPUS_INTERNAL_DOC */
+
+/** Macros to trigger compilation errors when the wrong types are provided to a
+ * CTL. */
+/**@{*/
+#define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr)))
+#define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr)))
+/**@}*/
+
+/** These are the actual encoder and decoder CTL ID numbers.
+ * They should not be used directly by applications.
+ * In general, SETs should be even and GETs should be odd.*/
+/**@{*/
+#define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120
+#define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122
+/**@}*/
+
+/** @endcond */
+
+/** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs
+ *
+ * These are convenience macros that are specific to the
+ * opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl()
+ * interface.
+ * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and
+ * @ref opus_decoderctls may be applied to a multistream encoder or decoder as
+ * well.
+ * In addition, you may retrieve the encoder or decoder state for an specific
+ * stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or
+ * #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually.
+ */
+/**@{*/
+
+/** Gets the encoder state for an individual stream of a multistream encoder.
+ * @param[in] x <tt>opus_int32</tt>: The index of the stream whose encoder you
+ * wish to retrieve.
+ * This must be non-negative and less than
+ * the <code>streams</code> parameter used
+ * to initialize the encoder.
+ * @param[out] y <tt>OpusEncoder**</tt>: return a pointer to the given
+ * encoder state.
+ * @retval OPUS_BAD_ARG The index of the requested stream was out of range.
+ * @hideinitializer
+ */
+#define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y)
+
+/** Gets the decoder state for an individual stream of a multistream decoder.
+ * @param[in] x <tt>opus_int32</tt>: The index of the stream whose decoder you
+ * wish to retrieve.
+ * This must be non-negative and less than
+ * the <code>streams</code> parameter used
+ * to initialize the decoder.
+ * @param[out] y <tt>OpusDecoder**</tt>: return a pointer to the given
+ * decoder state.
+ * @retval OPUS_BAD_ARG The index of the requested stream was out of range.
+ * @hideinitializer
+ */
+#define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y)
+
+/**@}*/
+
+/** @defgroup opus_multistream Opus Multistream API
+ * @{
+ *
+ * The multistream API allows individual Opus streams to be combined into a
+ * single packet, enabling support for up to 255 channels. Unlike an
+ * elementary Opus stream, the encoder and decoder must negotiate the channel
+ * configuration before the decoder can successfully interpret the data in the
+ * packets produced by the encoder. Some basic information, such as packet
+ * duration, can be computed without any special negotiation.
+ *
+ * The format for multistream Opus packets is defined in
+ * <a href="https://tools.ietf.org/html/rfc7845">RFC 7845</a>
+ * and is based on the self-delimited Opus framing described in Appendix B of
+ * <a href="https://tools.ietf.org/html/rfc6716">RFC 6716</a>.
+ * Normal Opus packets are just a degenerate case of multistream Opus packets,
+ * and can be encoded or decoded with the multistream API by setting
+ * <code>streams</code> to <code>1</code> when initializing the encoder or
+ * decoder.
+ *
+ * Multistream Opus streams can contain up to 255 elementary Opus streams.
+ * These may be either "uncoupled" or "coupled", indicating that the decoder
+ * is configured to decode them to either 1 or 2 channels, respectively.
+ * The streams are ordered so that all coupled streams appear at the
+ * beginning.
+ *
+ * A <code>mapping</code> table defines which decoded channel <code>i</code>
+ * should be used for each input/output (I/O) channel <code>j</code>. This table is
+ * typically provided as an unsigned char array.
+ * Let <code>i = mapping[j]</code> be the index for I/O channel <code>j</code>.
+ * If <code>i < 2*coupled_streams</code>, then I/O channel <code>j</code> is
+ * encoded as the left channel of stream <code>(i/2)</code> if <code>i</code>
+ * is even, or as the right channel of stream <code>(i/2)</code> if
+ * <code>i</code> is odd. Otherwise, I/O channel <code>j</code> is encoded as
+ * mono in stream <code>(i - coupled_streams)</code>, unless it has the special
+ * value 255, in which case it is omitted from the encoding entirely (the
+ * decoder will reproduce it as silence). Each value <code>i</code> must either
+ * be the special value 255 or be less than <code>streams + coupled_streams</code>.
+ *
+ * The output channels specified by the encoder
+ * should use the
+ * <a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-810004.3.9">Vorbis
+ * channel ordering</a>. A decoder may wish to apply an additional permutation
+ * to the mapping the encoder used to achieve a different output channel
+ * order (e.g. for outputing in WAV order).
+ *
+ * Each multistream packet contains an Opus packet for each stream, and all of
+ * the Opus packets in a single multistream packet must have the same
+ * duration. Therefore the duration of a multistream packet can be extracted
+ * from the TOC sequence of the first stream, which is located at the
+ * beginning of the packet, just like an elementary Opus stream:
+ *
+ * @code
+ * int nb_samples;
+ * int nb_frames;
+ * nb_frames = opus_packet_get_nb_frames(data, len);
+ * if (nb_frames < 1)
+ * return nb_frames;
+ * nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames;
+ * @endcode
+ *
+ * The general encoding and decoding process proceeds exactly the same as in
+ * the normal @ref opus_encoder and @ref opus_decoder APIs.
+ * See their documentation for an overview of how to use the corresponding
+ * multistream functions.
+ */
+
+/** Opus multistream encoder state.
+ * This contains the complete state of a multistream Opus encoder.
+ * It is position independent and can be freely copied.
+ * @see opus_multistream_encoder_create
+ * @see opus_multistream_encoder_init
+ */
+typedef struct OpusMSEncoder OpusMSEncoder;
+
+/** Opus multistream decoder state.
+ * This contains the complete state of a multistream Opus decoder.
+ * It is position independent and can be freely copied.
+ * @see opus_multistream_decoder_create
+ * @see opus_multistream_decoder_init
+ */
+typedef struct OpusMSDecoder OpusMSDecoder;
+
+/**\name Multistream encoder functions */
+/**@{*/
+
+/** Gets the size of an OpusMSEncoder structure.
+ * @param streams <tt>int</tt>: The total number of streams to encode from the
+ * input.
+ * This must be no more than 255.
+ * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
+ * to encode.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * encoded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than 255.
+ * @return The size in bytes on success, or a negative error code
+ * (see @ref opus_errorcodes) on error.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size(
+ int streams,
+ int coupled_streams
+);
+
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_surround_encoder_get_size(
+ int channels,
+ int mapping_family
+);
+
+
+/** Allocates and initializes a multistream encoder state.
+ * Call opus_multistream_encoder_destroy() to release
+ * this object when finished.
+ * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param channels <tt>int</tt>: Number of channels in the input signal.
+ * This must be at most 255.
+ * It may be greater than the number of
+ * coded channels (<code>streams +
+ * coupled_streams</code>).
+ * @param streams <tt>int</tt>: The total number of streams to encode from the
+ * input.
+ * This must be no more than the number of channels.
+ * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
+ * to encode.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * encoded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than the number of input channels.
+ * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+ * encoded channels to input channels, as described in
+ * @ref opus_multistream. As an extra constraint, the
+ * multistream encoder does not allow encoding coupled
+ * streams for which one channel is unused since this
+ * is never a good idea.
+ * @param application <tt>int</tt>: The target encoder application.
+ * This must be one of the following:
+ * <dl>
+ * <dt>#OPUS_APPLICATION_VOIP</dt>
+ * <dd>Process signal for improved speech intelligibility.</dd>
+ * <dt>#OPUS_APPLICATION_AUDIO</dt>
+ * <dd>Favor faithfulness to the original input.</dd>
+ * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
+ * <dd>Configure the minimum possible coding delay by disabling certain modes
+ * of operation.</dd>
+ * </dl>
+ * @param[out] error <tt>int *</tt>: return #OPUS_OK on success, or an error
+ * code (see @ref opus_errorcodes) on
+ * failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create(
+ opus_int32 Fs,
+ int channels,
+ int streams,
+ int coupled_streams,
+ const unsigned char *mapping,
+ int application,
+ int *error
+) OPUS_ARG_NONNULL(5);
+
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_surround_encoder_create(
+ opus_int32 Fs,
+ int channels,
+ int mapping_family,
+ int *streams,
+ int *coupled_streams,
+ unsigned char *mapping,
+ int application,
+ int *error
+) OPUS_ARG_NONNULL(5);
+
+/** Initialize a previously allocated multistream encoder state.
+ * The memory pointed to by \a st must be at least the size returned by
+ * opus_multistream_encoder_get_size().
+ * This is intended for applications which use their own allocator instead of
+ * malloc.
+ * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+ * @see opus_multistream_encoder_create
+ * @see opus_multistream_encoder_get_size
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.
+ * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param channels <tt>int</tt>: Number of channels in the input signal.
+ * This must be at most 255.
+ * It may be greater than the number of
+ * coded channels (<code>streams +
+ * coupled_streams</code>).
+ * @param streams <tt>int</tt>: The total number of streams to encode from the
+ * input.
+ * This must be no more than the number of channels.
+ * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
+ * to encode.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * encoded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than the number of input channels.
+ * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+ * encoded channels to input channels, as described in
+ * @ref opus_multistream. As an extra constraint, the
+ * multistream encoder does not allow encoding coupled
+ * streams for which one channel is unused since this
+ * is never a good idea.
+ * @param application <tt>int</tt>: The target encoder application.
+ * This must be one of the following:
+ * <dl>
+ * <dt>#OPUS_APPLICATION_VOIP</dt>
+ * <dd>Process signal for improved speech intelligibility.</dd>
+ * <dt>#OPUS_APPLICATION_AUDIO</dt>
+ * <dd>Favor faithfulness to the original input.</dd>
+ * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
+ * <dd>Configure the minimum possible coding delay by disabling certain modes
+ * of operation.</dd>
+ * </dl>
+ * @return #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
+ * on failure.
+ */
+OPUS_EXPORT int opus_multistream_encoder_init(
+ OpusMSEncoder *st,
+ opus_int32 Fs,
+ int channels,
+ int streams,
+ int coupled_streams,
+ const unsigned char *mapping,
+ int application
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
+
+OPUS_EXPORT int opus_multistream_surround_encoder_init(
+ OpusMSEncoder *st,
+ opus_int32 Fs,
+ int channels,
+ int mapping_family,
+ int *streams,
+ int *coupled_streams,
+ unsigned char *mapping,
+ int application
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
+
+/** Encodes a multistream Opus frame.
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
+ * @param[in] pcm <tt>const opus_int16*</tt>: The input signal as interleaved
+ * samples.
+ * This must contain
+ * <code>frame_size*channels</code>
+ * samples.
+ * @param frame_size <tt>int</tt>: Number of samples per channel in the input
+ * signal.
+ * This must be an Opus frame size for the
+ * encoder's sampling rate.
+ * For example, at 48 kHz the permitted values
+ * are 120, 240, 480, 960, 1920, and 2880.
+ * Passing in a duration of less than 10 ms
+ * (480 samples at 48 kHz) will prevent the
+ * encoder from using the LPC or hybrid modes.
+ * @param[out] data <tt>unsigned char*</tt>: Output payload.
+ * This must contain storage for at
+ * least \a max_data_bytes.
+ * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+ * memory for the output
+ * payload. This may be
+ * used to impose an upper limit on
+ * the instant bitrate, but should
+ * not be used as the only bitrate
+ * control. Use #OPUS_SET_BITRATE to
+ * control the bitrate.
+ * @return The length of the encoded packet (in bytes) on success or a
+ * negative error code (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode(
+ OpusMSEncoder *st,
+ const opus_int16 *pcm,
+ int frame_size,
+ unsigned char *data,
+ opus_int32 max_data_bytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Encodes a multistream Opus frame from floating point input.
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
+ * @param[in] pcm <tt>const float*</tt>: The input signal as interleaved
+ * samples with a normal range of
+ * +/-1.0.
+ * Samples with a range beyond +/-1.0
+ * are supported but will be clipped by
+ * decoders using the integer API and
+ * should only be used if it is known
+ * that the far end supports extended
+ * dynamic range.
+ * This must contain
+ * <code>frame_size*channels</code>
+ * samples.
+ * @param frame_size <tt>int</tt>: Number of samples per channel in the input
+ * signal.
+ * This must be an Opus frame size for the
+ * encoder's sampling rate.
+ * For example, at 48 kHz the permitted values
+ * are 120, 240, 480, 960, 1920, and 2880.
+ * Passing in a duration of less than 10 ms
+ * (480 samples at 48 kHz) will prevent the
+ * encoder from using the LPC or hybrid modes.
+ * @param[out] data <tt>unsigned char*</tt>: Output payload.
+ * This must contain storage for at
+ * least \a max_data_bytes.
+ * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+ * memory for the output
+ * payload. This may be
+ * used to impose an upper limit on
+ * the instant bitrate, but should
+ * not be used as the only bitrate
+ * control. Use #OPUS_SET_BITRATE to
+ * control the bitrate.
+ * @return The length of the encoded packet (in bytes) on success or a
+ * negative error code (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float(
+ OpusMSEncoder *st,
+ const float *pcm,
+ int frame_size,
+ unsigned char *data,
+ opus_int32 max_data_bytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Frees an <code>OpusMSEncoder</code> allocated by
+ * opus_multistream_encoder_create().
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to be freed.
+ */
+OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st);
+
+/** Perform a CTL function on a multistream Opus encoder.
+ *
+ * Generally the request and subsequent arguments are generated by a
+ * convenience macro.
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
+ * @param request This and all remaining parameters should be replaced by one
+ * of the convenience macros in @ref opus_genericctls,
+ * @ref opus_encoderctls, or @ref opus_multistream_ctls.
+ * @see opus_genericctls
+ * @see opus_encoderctls
+ * @see opus_multistream_ctls
+ */
+OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request,
+ ...) OPUS_ARG_NONNULL(1);
+
+/**@}*/
+
+/**\name Multistream decoder functions */
+/**@{*/
+
+/** Gets the size of an <code>OpusMSDecoder</code> structure.
+ * @param streams <tt>int</tt>: The total number of streams coded in the
+ * input.
+ * This must be no more than 255.
+ * @param coupled_streams <tt>int</tt>: Number streams to decode as coupled
+ * (2 channel) streams.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * coded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than 255.
+ * @return The size in bytes on success, or a negative error code
+ * (see @ref opus_errorcodes) on error.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size(
+ int streams,
+ int coupled_streams
+);
+
+/** Allocates and initializes a multistream decoder state.
+ * Call opus_multistream_decoder_destroy() to release
+ * this object when finished.
+ * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param channels <tt>int</tt>: Number of channels to output.
+ * This must be at most 255.
+ * It may be different from the number of coded
+ * channels (<code>streams +
+ * coupled_streams</code>).
+ * @param streams <tt>int</tt>: The total number of streams coded in the
+ * input.
+ * This must be no more than 255.
+ * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
+ * (2 channel) streams.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * coded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than 255.
+ * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+ * coded channels to output channels, as described in
+ * @ref opus_multistream.
+ * @param[out] error <tt>int *</tt>: return #OPUS_OK on success, or an error
+ * code (see @ref opus_errorcodes) on
+ * failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create(
+ opus_int32 Fs,
+ int channels,
+ int streams,
+ int coupled_streams,
+ const unsigned char *mapping,
+ int *error
+) OPUS_ARG_NONNULL(5);
+
+/** Initialize a previously allocated decoder state object.
+ * The memory pointed to by \a st must be at least the size returned by
+ * opus_multistream_encoder_get_size().
+ * This is intended for applications which use their own allocator instead of
+ * malloc.
+ * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+ * @see opus_multistream_decoder_create
+ * @see opus_multistream_deocder_get_size
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.
+ * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param channels <tt>int</tt>: Number of channels to output.
+ * This must be at most 255.
+ * It may be different from the number of coded
+ * channels (<code>streams +
+ * coupled_streams</code>).
+ * @param streams <tt>int</tt>: The total number of streams coded in the
+ * input.
+ * This must be no more than 255.
+ * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
+ * (2 channel) streams.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * coded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than 255.
+ * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+ * coded channels to output channels, as described in
+ * @ref opus_multistream.
+ * @return #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
+ * on failure.
+ */
+OPUS_EXPORT int opus_multistream_decoder_init(
+ OpusMSDecoder *st,
+ opus_int32 Fs,
+ int channels,
+ int streams,
+ int coupled_streams,
+ const unsigned char *mapping
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
+
+/** Decode a multistream Opus packet.
+ * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
+ * @param[in] data <tt>const unsigned char*</tt>: Input payload.
+ * Use a <code>NULL</code>
+ * pointer to indicate packet
+ * loss.
+ * @param len <tt>opus_int32</tt>: Number of bytes in payload.
+ * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
+ * samples.
+ * This must contain room for
+ * <code>frame_size*channels</code>
+ * samples.
+ * @param frame_size <tt>int</tt>: The number of samples per channel of
+ * available space in \a pcm.
+ * If this is less than the maximum packet duration
+ * (120 ms; 5760 for 48kHz), this function will not be capable
+ * of decoding some packets. In the case of PLC (data==NULL)
+ * or FEC (decode_fec=1), then frame_size needs to be exactly
+ * the duration of audio that is missing, otherwise the
+ * decoder will not be in the optimal state to decode the
+ * next incoming packet. For the PLC and FEC cases, frame_size
+ * <b>must</b> be a multiple of 2.5 ms.
+ * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
+ * forward error correction data be decoded.
+ * If no such data is available, the frame is
+ * decoded as if it were lost.
+ * @return Number of samples decoded on success or a negative error code
+ * (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode(
+ OpusMSDecoder *st,
+ const unsigned char *data,
+ opus_int32 len,
+ opus_int16 *pcm,
+ int frame_size,
+ int decode_fec
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Decode a multistream Opus packet with floating point output.
+ * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
+ * @param[in] data <tt>const unsigned char*</tt>: Input payload.
+ * Use a <code>NULL</code>
+ * pointer to indicate packet
+ * loss.
+ * @param len <tt>opus_int32</tt>: Number of bytes in payload.
+ * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
+ * samples.
+ * This must contain room for
+ * <code>frame_size*channels</code>
+ * samples.
+ * @param frame_size <tt>int</tt>: The number of samples per channel of
+ * available space in \a pcm.
+ * If this is less than the maximum packet duration
+ * (120 ms; 5760 for 48kHz), this function will not be capable
+ * of decoding some packets. In the case of PLC (data==NULL)
+ * or FEC (decode_fec=1), then frame_size needs to be exactly
+ * the duration of audio that is missing, otherwise the
+ * decoder will not be in the optimal state to decode the
+ * next incoming packet. For the PLC and FEC cases, frame_size
+ * <b>must</b> be a multiple of 2.5 ms.
+ * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
+ * forward error correction data be decoded.
+ * If no such data is available, the frame is
+ * decoded as if it were lost.
+ * @return Number of samples decoded on success or a negative error code
+ * (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float(
+ OpusMSDecoder *st,
+ const unsigned char *data,
+ opus_int32 len,
+ float *pcm,
+ int frame_size,
+ int decode_fec
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Perform a CTL function on a multistream Opus decoder.
+ *
+ * Generally the request and subsequent arguments are generated by a
+ * convenience macro.
+ * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
+ * @param request This and all remaining parameters should be replaced by one
+ * of the convenience macros in @ref opus_genericctls,
+ * @ref opus_decoderctls, or @ref opus_multistream_ctls.
+ * @see opus_genericctls
+ * @see opus_decoderctls
+ * @see opus_multistream_ctls
+ */
+OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request,
+ ...) OPUS_ARG_NONNULL(1);
+
+/** Frees an <code>OpusMSDecoder</code> allocated by
+ * opus_multistream_decoder_create().
+ * @param st <tt>OpusMSDecoder</tt>: Multistream decoder state to be freed.
+ */
+OPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st);
+
+/**@}*/
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPUS_MULTISTREAM_H */
diff --git a/inc/rcu/opus_inc/opus_types.h b/inc/rcu/opus_inc/opus_types.h
new file mode 100644
index 0000000..85a2ed8
--- /dev/null
+++ b/inc/rcu/opus_inc/opus_types.h
@@ -0,0 +1,159 @@
+/* (C) COPYRIGHT 1994-2002 Xiph.Org Foundation */
+/* Modified by Jean-Marc Valin */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/* opus_types.h based on ogg_types.h from libogg */
+
+/**
+ @file opus_types.h
+ @brief Opus reference implementation types
+*/
+#ifndef OPUS_TYPES_H
+#define OPUS_TYPES_H
+
+/* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */
+#if (defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H))
+#include <stdint.h>
+
+typedef int16_t opus_int16;
+typedef uint16_t opus_uint16;
+typedef int32_t opus_int32;
+typedef uint32_t opus_uint32;
+#elif defined(_WIN32)
+
+# if defined(__CYGWIN__)
+# include <_G_config.h>
+typedef _G_int32_t opus_int32;
+typedef _G_uint32_t opus_uint32;
+typedef _G_int16 opus_int16;
+typedef _G_uint16 opus_uint16;
+# elif defined(__MINGW32__)
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+typedef int opus_int32;
+typedef unsigned int opus_uint32;
+# elif defined(__MWERKS__)
+typedef int opus_int32;
+typedef unsigned int opus_uint32;
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+# else
+/* MSVC/Borland */
+typedef __int32 opus_int32;
+typedef unsigned __int32 opus_uint32;
+typedef __int16 opus_int16;
+typedef unsigned __int16 opus_uint16;
+# endif
+
+#elif defined(__MACOS__)
+
+# include <sys/types.h>
+typedef SInt16 opus_int16;
+typedef UInt16 opus_uint16;
+typedef SInt32 opus_int32;
+typedef UInt32 opus_uint32;
+
+#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
+
+# include <sys/types.h>
+typedef int16_t opus_int16;
+typedef u_int16_t opus_uint16;
+typedef int32_t opus_int32;
+typedef u_int32_t opus_uint32;
+
+#elif defined(__BEOS__)
+
+/* Be */
+# include <inttypes.h>
+typedef int16 opus_int16;
+typedef u_int16 opus_uint16;
+typedef int32_t opus_int32;
+typedef u_int32_t opus_uint32;
+
+#elif defined (__EMX__)
+
+/* OS/2 GCC */
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+typedef int opus_int32;
+typedef unsigned int opus_uint32;
+
+#elif defined (DJGPP)
+
+/* DJGPP */
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+typedef int opus_int32;
+typedef unsigned int opus_uint32;
+
+#elif defined(R5900)
+
+/* PS2 EE */
+typedef int opus_int32;
+typedef unsigned opus_uint32;
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+
+#elif defined(__SYMBIAN32__)
+
+/* Symbian GCC */
+typedef signed short opus_int16;
+typedef unsigned short opus_uint16;
+typedef signed int opus_int32;
+typedef unsigned int opus_uint32;
+
+#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
+
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+typedef long opus_int32;
+typedef unsigned long opus_uint32;
+
+#elif defined(CONFIG_TI_C6X)
+
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+typedef int opus_int32;
+typedef unsigned int opus_uint32;
+
+#else
+
+/* Give up, take a reasonable guess */
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+typedef int opus_int32;
+typedef unsigned int opus_uint32;
+
+#endif
+
+#define opus_int int /* used for counters etc; at least 16 bits */
+#define opus_int64 long long
+#define opus_int8 signed char
+
+#define opus_uint unsigned int /* used for counters etc; at least 16 bits */
+#define opus_uint64 unsigned long long
+#define opus_uint8 unsigned char
+
+#endif /* OPUS_TYPES_H */
diff --git a/inc/rcu/sbc.h b/inc/rcu/sbc.h
new file mode 100644
index 0000000..098fd81
--- /dev/null
+++ b/inc/rcu/sbc.h
@@ -0,0 +1,67 @@
+#ifndef _SBC_H_
+#define _SBC_H_
+
+/* defines */
+#define SBC_SUPPORT_OTHER_MODE 0 //0:just support mono mode
+
+#define SBC_SUCCESS 0
+#define SBC_NOT_ENOUGH_DATA -1
+#define SBC_BUFFER_TOO_SMALL -2
+#define SBC_NO_SYNCBYTE -3
+#define SBC_CHECKSUM_ERROR -4
+
+#define SBC_SYNCBYTE 0x9c
+#define SBC_MAX_SUBBANDS 8
+#if SBC_SUPPORT_OTHER_MODE
+#define SBC_MAX_CHANNELS 2
+#else
+#define SBC_MAX_CHANNELS 1
+#endif
+#define SBC_TERMINATOR -1
+
+/* structs, typedefs */
+#define SBC_FREQU16000 0x0
+#define SBC_FREQU32000 0x1
+#define SBC_FREQU44100 0x2
+#define SBC_FREQU48000 0x3
+typedef unsigned short TSBCSamplingFrequency;
+
+#define SBC_BLOCKS4 0x0
+#define SBC_BLOCKS8 0x1
+#define SBC_BLOCKS12 0x2
+#define SBC_BLOCKS16 0x3
+typedef unsigned short TSBCBlockNumber;
+
+#define SBC_MODE_MONO 0x0
+#if SBC_SUPPORT_OTHER_MODE
+#define SBC_MODE_DUAL 0x1
+#define SBC_MODE_STEREO 0x2
+#define SBC_MODE_JOINT 0x3
+#endif
+typedef unsigned short TSBCChannelMode;
+
+#define SBC_ALLOCLOUDNESS 0x0
+#define SBC_ALLOCSNR 0x1
+typedef unsigned short TSBCAllocMethod;
+
+#define SBC_SUBBANDS4 0x0
+#define SBC_SUBBANDS8 0x1
+typedef unsigned short TSBCSubbandNumber;
+
+typedef struct
+{
+ TSBCSamplingFrequency samplingFrequency;
+ TSBCBlockNumber blockNumber;
+ TSBCChannelMode channelMode;
+ TSBCAllocMethod allocMethod;
+ TSBCSubbandNumber subbandNumber;
+ unsigned char bitpool;
+} T_SBC_PARAMS;
+
+extern T_SBC_PARAMS sbc_enc_params;
+
+void sbc_init_encoder(void);
+int sbc_encode(unsigned char *p_input_buff, int input_size, T_SBC_PARAMS *p_params,
+ unsigned char *p_output_buff, int *p_output_size);
+
+#endif
diff --git a/license b/license
new file mode 100644
index 0000000..67596b0
--- /dev/null
+++ b/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 [yyyy] [name of copyright owner]
+
+ 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. \ No newline at end of file
diff --git a/readme b/readme
index e69de29..dd901f8 100644
--- a/readme
+++ b/readme
@@ -0,0 +1,105 @@
+
+The complete sdk environment includes the following folders:
+(Ultimately, these files need to be placed in a directory, you can create an empty sdk folder and put them in it)
+(1)bin
+(2)board
+(3)doc
+(4)inc
+(5)src
+(6)tool
+(7)license
+(8)readme
+
+========== 1. Instructions for bin image for building the SDK ==========
+
+1.1 Download the bin files from link below:
+
+ link: https://www.realmcu.com/web/Index/a5c3a065-5caf-4918-a810-349efbd8567e
+
+ password: realtek123
+
+ The bin image folder is in folder "Google Ref RTK RCU /bin"
+
+1.2 After downloading, copy the bin folder to the sdk directory
+
+1.3 The bin folder contains the firmware required for burning: configfile, flash map, otaheader, patch, secure boot and upperstack img
+1.3.1 Here is a brief introduction:
+configfile: chip configuration file
+flash map: documents for flash planning
+otaheader: documents for OTA bank planning
+patch: provided by realtek
+secure boot: provided by Realtek requires users to burn the file without switching to Bank
+upperstack img: provided by realtek
+
+
+
+========== 2. Instructions for download tools ==========
+
+2.1 Find the tools from link below:
+
+ link: https://www.realmcu.com/web/Index/a5c3a065-5caf-4918-a810-349efbd8567e
+
+ password: realtek123
+
+ The current version of the tools are in folder "Google Ref RTK RCU /tool", and each tool's User Guide is located in its path
+
+2.2 After downloading, copy the tool folder to the sdk directory
+
+There are four burning tools available:
+2.2.1 BeeMPTool_kits_v1.0.5.8
+2.2.2 mpcli_1.0.4.5_Windows
+2.2.3 mpcli_v1.0.3.8_MAC_OS
+2.2.4 mpcli_v1.0.4.3_Linux
+
+
+
+========== 3. Instructions for compile the project ==========
+
+There are two ways to compile app image:
+3.1 keil:
+3.1.1 open keil project file with the suffix is uvprojx, which is in the path: sdk\board\evb\google_rcu\mdk, and compile in keil
+3.1.2 after compile success, you can find app image bin in the path: sdk\board\evb\google_rcu\mdk\bin
+
+3.2 gcc:
+3.1.1 use cmd in command window: sdk\board\evb\google_rcu\gcc
+3.1.2 input command in cmd window and press enter: mingw32-make
+3.1.3 after compile success, you can find app image bin in the path: sdk\board\evb\google_rcu\gcc\bin
+
+3.3 download
+When burning, the following files need to be burned:
+(1)flash_map.ini (folder: bin/flash_map)
+(2)configfile_xxx.bin (folder: bin/configfile)
+(3)otaheader_xxx.bin (folder: bin/otaheader)
+(4)patch_xxx.bin (folder: bin/patch)
+(5)fsbl_xxx.bin (folder: bin/secure_boot)
+(6)upperstack_xxx.bin (folder: bin/upperstack_img)
+(7)app_xxx.bin (folder: reference to 3.1 and 3.2)
+
+
+
+========== 4. Instructions for debug ==========
+
+ link: https://www.realmcu.com/web/Index/a5c3a065-5caf-4918-a810-349efbd8567e
+
+ password: realtek123
+
+
+ The current version of the tool is in folder "Google Ref RTK RCU /tool"
+
+4.1 Use the tool: DebugAnalyzer-v4.0.0.31.release, which is in folder "Google Ref RTK RCU /tool"
+
+4.2 For specific operating instructions, please refer to Debug Analyzer User Guide
+
+
+
+========== 5. Instructions for doc files about the SDK ==========
+
+5.1 Download the reference doc files from link below:
+
+ link: https://www.realmcu.com/en/Home/Product/28a1b431-5395-4579-9800-35d00166ceb5
+
+
+
+========== 6. Instructions for other ==========
+
+6.1 To be added \ No newline at end of file
diff --git a/src/app/google_rcu/address_module/rcu_link_mgr.c b/src/app/google_rcu/address_module/rcu_link_mgr.c
new file mode 100644
index 0000000..3bf43da
--- /dev/null
+++ b/src/app/google_rcu/address_module/rcu_link_mgr.c
@@ -0,0 +1,171 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file link_mgr.c
+ * @brief Multilink manager functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <rcu_link_mgr.h>
+#include <trace.h>
+#include <string.h>
+#include <ftl.h>
+#include <gap_adv.h>
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+//#if F_BT_LE_USE_STATIC_RANDOM_ADDR
+/** @brief Define start offset of the flash to save static random address. */
+//#define APP_STATIC_RANDOM_ADDR_OFFSET 0
+//#endif
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup SCATTERNET_GAP_MSG
+ * @{
+ */
+//T_APP_LINK app_link_table[APP_MAX_LINKS];
+/** @} */
+/** @addtogroup SCATTERNET_SCAN_MGR
+ * @{
+ */
+T_DEV_INFO dev_list[APP_MAX_DEVICE_INFO];
+uint8_t dev_list_count = 0;
+/** @} */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @addtogroup CENTRAL_SCAN_MGR
+ * @{
+ */
+/**
+ * @brief Add device information to device list.
+ *
+ * @param[in] bd_addr Peer device address.
+ * @param[in] bd_type Peer device address type.
+ * @retval true Success.
+ * @retval false Failed, device list is full.
+ */
+bool link_mgr_add_device(uint8_t *bd_addr, uint8_t bd_type)
+{
+ /* If result count not at max */
+ if (dev_list_count < APP_MAX_DEVICE_INFO)
+ {
+ uint8_t i;
+ /* Check if device is already in device list*/
+ for (i = 0; i < dev_list_count; i++)
+ {
+ if (memcmp(bd_addr, dev_list[i].bd_addr, GAP_BD_ADDR_LEN) == 0)
+ {
+ return true;
+ }
+ }
+
+ /*Add addr to device list list*/
+ memcpy(dev_list[dev_list_count].bd_addr, bd_addr, GAP_BD_ADDR_LEN);
+ dev_list[dev_list_count].bd_type = bd_type;
+
+ /*Increment device list count*/
+ dev_list_count++;
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Clear device list.
+ * @retval None.
+ */
+void link_mgr_clear_device_list(void)
+{
+ dev_list_count = 0;
+}
+/** @} */
+/** @addtogroup SCATTERNET_APP
+ * @{
+ */
+/** @defgroup SCATTERNET_RANDOM Static Random Address Storage
+ * @brief Use @ref F_BT_LE_USE_STATIC_RANDOM_ADDR to open
+ * @{
+ */
+//#if F_BT_LE_USE_STATIC_RANDOM_ADDR
+/**
+ * @brief Save static random address information into flash.
+ * @param[in] p_addr Pointer to the buffer for saving data.
+ * @retval 0 Save success.
+ * @retval other Failed.
+ */
+uint32_t app_save_static_random_address(T_APP_STATIC_RANDOM_ADDR *p_addr)
+{
+ APP_PRINT_INFO0("app_save_static_random_address");
+ return ftl_save(p_addr, APP_STATIC_RANDOM_ADDR_OFFSET, sizeof(T_APP_STATIC_RANDOM_ADDR));
+}
+/**
+ * @brief Load static random address information from storage.
+ * @param[out] p_addr Pointer to the buffer for loading data.
+ * @retval 0 Load success.
+ * @retval other Failed.
+ */
+uint32_t app_load_static_random_address(T_APP_STATIC_RANDOM_ADDR *p_addr)
+{
+ uint32_t result;
+ result = ftl_load(p_addr, APP_STATIC_RANDOM_ADDR_OFFSET,
+ sizeof(T_APP_STATIC_RANDOM_ADDR));
+ APP_PRINT_INFO1("app_load_static_random_address: result 0x%x", result);
+ if (result)
+ {
+ memset(p_addr, 0, sizeof(T_APP_STATIC_RANDOM_ADDR));
+ }
+ return result;
+}
+
+/**
+ * @brief config local static random address.
+ * @param[out] none.
+ * @retval none.
+ */
+void app_static_random_addr_cfg(void)
+{
+ T_APP_STATIC_RANDOM_ADDR random_addr;
+ bool gen_addr = true;
+ uint8_t local_bd_type = GAP_LOCAL_ADDR_LE_RANDOM;
+ if (app_load_static_random_address(&random_addr) == 0)
+ {
+ if (random_addr.is_exist == true)
+ {
+ gen_addr = false;
+ }
+ }
+ if (gen_addr)
+ {
+ if (le_gen_rand_addr(GAP_RAND_ADDR_STATIC, random_addr.bd_addr) == GAP_CAUSE_SUCCESS)
+ {
+ random_addr.is_exist = true;
+ app_save_static_random_address(&random_addr);
+ }
+ }
+ le_cfg_local_identity_address(random_addr.bd_addr, GAP_IDENT_ADDR_RAND);
+ le_set_gap_param(GAP_PARAM_RANDOM_ADDR, 6, random_addr.bd_addr);
+ //only for peripheral,broadcaster
+ le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type);
+ //only for central,observer
+ //le_scan_set_param(GAP_PARAM_SCAN_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type);
+}
+//#endif
+/** @} */
+/** @} */
diff --git a/src/app/google_rcu/address_module/rcu_link_mgr.h b/src/app/google_rcu/address_module/rcu_link_mgr.h
new file mode 100644
index 0000000..b30004d
--- /dev/null
+++ b/src/app/google_rcu/address_module/rcu_link_mgr.h
@@ -0,0 +1,87 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file link_mgr.h
+ * @brief Define multilink manager struct and functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _LINK_MANAGER_H_
+#define _LINK_MANAGER_H_
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <app_msg.h>
+#include <gap_conn_le.h>
+#include <profile_client.h>
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Define device list table size. */
+#define APP_MAX_DEVICE_INFO 6
+
+/** @addtogroup SCATTERNET_GAP_MSG
+ * @{
+ */
+/**
+ * @brief Application Link control block definition.
+ */
+typedef struct
+{
+ T_GAP_CONN_STATE conn_state; /**< Connection state. */
+ T_GAP_REMOTE_ADDR_TYPE bd_type; /**< remote BD type*/
+ uint8_t bd_addr[GAP_BD_ADDR_LEN]; /**< remote BD */
+} T_APP_LINK;
+/** @} */ /* End of group SCATTERNET_GAP_MSG */
+/** @addtogroup SCATTERNET_SCAN_MGR
+ * @{
+ */
+/**
+ * @brief Device list block definition.
+ */
+typedef struct
+{
+ uint8_t bd_addr[GAP_BD_ADDR_LEN]; /**< remote BD */
+ uint8_t bd_type; /**< remote BD type*/
+} T_DEV_INFO;
+/** @} */
+/** @addtogroup SCATTERNET_RANDOM
+ * @{
+ */
+//#if F_BT_LE_USE_STATIC_RANDOM_ADDR
+typedef struct
+{
+ uint8_t is_exist;
+ uint8_t reserved; /**< remote BD type*/
+ uint8_t bd_addr[GAP_BD_ADDR_LEN]; /**< remote BD */
+} T_APP_STATIC_RANDOM_ADDR;
+#endif
+/** @} */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @brief App link table */
+//extern T_APP_LINK app_link_table[APP_MAX_LINKS];
+/** @brief Device list table, used to save discovered device informations. */
+extern T_DEV_INFO dev_list[APP_MAX_DEVICE_INFO];
+/** @brief The number of device informations saved in dev_list. */
+extern uint8_t dev_list_count;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+bool link_mgr_add_device(uint8_t *bd_addr, uint8_t bd_type);
+void link_mgr_clear_device_list(void);
+void app_static_random_addr_cfg(void);
+//#if F_BT_LE_USE_STATIC_RANDOM_ADDR
+uint32_t app_save_static_random_address(T_APP_STATIC_RANDOM_ADDR *p_addr);
+uint32_t app_load_static_random_address(T_APP_STATIC_RANDOM_ADDR *p_addr);
+//#endif
+//#endif
diff --git a/src/app/google_rcu/app_task.c b/src/app/google_rcu/app_task.c
new file mode 100644
index 0000000..b39b8d4
--- /dev/null
+++ b/src/app/google_rcu/app_task.c
@@ -0,0 +1,204 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file app_task.c
+* @brief application task.
+* @details
+* @author barry_bian
+* @date 2020-02-21
+* @version v1.1
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "board.h"
+#include <os_msg.h>
+#include <os_task.h>
+#include <trace.h>
+#include <app_task.h>
+#include <app_msg.h>
+#include <app_task.h>
+#include <rcu_application.h>
+#include "mem_config.h"
+#include "otp_config.h"
+#include "app_section.h"
+#include "rcu_gap_dtm.h"
+#if (AON_WDG_ENABLE == 1)
+#include "rtl876x_aon_wdg.h"
+#endif
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 /* Task priorities. */
+#if (VOICE_ENC_TYPE == SW_OPUS_ENC)
+#if SUPPORT_DUAL_MIC_FEATURE
+#define APP_TASK_STACK_SIZE 512 * 60
+#else
+#define APP_TASK_STACK_SIZE 512 * 40
+#endif
+
+#else
+#define APP_TASK_STACK_SIZE 512 * 4
+#endif
+
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE)
+
+/*============================================================================*
+ * Global Variables
+ *============================================================================*/
+void *app_task_handle;
+void *evt_queue_handle;
+void *io_queue_handle;
+void *dtm_task_handle;
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+static void app_main_task(void *p_param);
+void dtm_task(void *p_param);
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg) DATA_RAM_FUNCTION;
+void app_main_task(void *p_param) DATA_RAM_FUNCTION;
+void dtm_task(void *p_param) DATA_RAM_FUNCTION;
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg) DATA_RAM_FUNCTION;
+void dtm_uart_init(void);
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief handle function of app main task
+ * @param *p_param
+ * @return none
+ * @retval void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+#if (ROM_WATCH_DOG_ENABLE == 1)
+ extern void reset_watch_dog_timer_enable(void);
+ reset_watch_dog_timer_enable();
+#endif
+
+#if (AON_WDG_ENABLE == 1)
+ aon_wdg_init(1, AON_WDG_TIME_OUT_PERIOD_SECOND);
+#endif
+
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ //DBG_DIRECT("***os_msg_recv***");
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief send msg queue to app task.
+ *
+ * @param p_handle The handle to the message queue being peeked.
+ *
+ * @return The status of the message queue peek.
+ * @retval true Message queue was peeked successfully.
+ * @retval false Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/******************************************************************
+ * @brief app_task_init() init app task
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_task_init(void)
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE,
+ APP_TASK_PRIORITY);
+}
+
+/******************************************************************
+ * @brief dtm_task_init() init dtm task
+ * @param none
+ * @return none
+ * @retval void
+ */
+void dtm_task_init(void)
+{
+ os_task_create(&dtm_task_handle, "dtm_task", dtm_task, 0, 512 * 4, 1);
+}
+
+/******************************************************************
+ * @brief handle function of dtm task
+ * @param *p_param
+ * @return none
+ * @retval void
+ */
+void dtm_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ dtm_uart_init();
+
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xffffffff) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ //dtm need not to handle io message
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/app_task.h b/src/app/google_rcu/app_task.h
new file mode 100644
index 0000000..fdf9c97
--- /dev/null
+++ b/src/app/google_rcu/app_task.h
@@ -0,0 +1,24 @@
+
+/*
+ * Routines to access hardware
+ *
+ * Copyright (c) 2018 Realtek Semiconductor Corp.
+ *
+ * This module is a confidential and proprietary property of RealTek and
+ * possession or use of this module requires written permission of RealTek.
+ */
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include "app_msg.h"
+#include "stdbool.h"
+
+extern void *app_task_handle;
+extern void *evt_queue_handle;
+extern void *io_queue_handle;
+
+void app_task_init(void);
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+#endif
+
diff --git a/src/app/google_rcu/bat_module/battery_driver.c b/src/app/google_rcu/bat_module/battery_driver.c
new file mode 100644
index 0000000..9a1ce9d
--- /dev/null
+++ b/src/app/google_rcu/bat_module/battery_driver.c
@@ -0,0 +1,620 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file battery_driver.c
+* @brief rcu vbat adc sample.
+* @details
+* @author chenjie
+* @date 2020-05-11
+* @version v1.1
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <board.h>
+#include <string.h>
+#include <adc_lib.h>
+#include <rtl876x_rcc.h>
+#include <rtl876x_adc.h>
+#include <rtl876x_nvic.h>
+#include <os_timer.h>
+#include <swtimer.h>
+#include <trace.h>
+#include "battery_driver.h"
+#include "bas.h"
+#include "rcu_application.h"
+#include "rcu_gap.h"
+#include "app_task.h"
+#include "app_section.h"
+#if SUPPORT_BAT_LPC_FEATURE
+#include "rtl876x_lpc.h"
+#endif
+#include "rtl876x_rtc.h"
+
+#if SUPPORT_BAT_DETECT_FEATURE
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+static T_BAT_INFO_STRUCT cur_bat_info; /* current battery information */
+#if SUPPORT_BAT_PERIODIC_DETECT_FEATURE
+static TimerHandle_t bat_detect_timer = NULL; /* batttery detect timer */
+#endif
+
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+static uint8_t bat_calculate_bat_level(uint16_t bat_value);
+static uint16_t bat_calibrate_voltage(uint16_t data);
+static void bat_handle_enter_low_power_event(void);
+static void bat_handle_enter_normal_event(void);
+static void bat_handle_key_pressed_event(void);
+
+#if SUPPORT_BAT_LPC_FEATURE
+static void bat_driver_lpc_init(void);
+static void bat_driver_lpc_enter_dlps_config(void);
+static void bat_driver_lpc_exit_dlps_config(void);
+static void bat_lpc_handler(void) DATA_RAM_FUNCTION;
+#endif
+
+#if SUPPORT_BAT_PERIODIC_DETECT_FEATURE
+static void bat_detect_timer_callback(TimerHandle_t pxTimer) DATA_RAM_FUNCTION;
+#endif
+
+void bat_enter_dlps_config(void) DATA_RAM_FUNCTION;
+void bat_exit_dlps_config(void) DATA_RAM_FUNCTION;
+
+/*============================================================================*
+ * Local functions
+ *============================================================================*/
+/******************************************************************
+ * @brief update battery value, level and mode.
+ * @param src_dat - adc sample source data.
+ * @return none
+ * @retval void
+ */
+uint8_t bat_calculate_bat_level(uint16_t bat_value)
+{
+ uint8_t bat_level = 0;
+
+ /*calculate bat level according to bat value*/
+ if (bat_value >= 3100) /* >3.1V, 100% */
+ {
+ bat_level = 100;
+ }
+ else if (bat_value >= 3000) /* 3.1~3.0V, 100%~80% */
+ {
+ bat_level = 80 + (bat_value - 3000) * (100 - 80) / (3100 - 3000);
+ }
+ else if (bat_value >= 2500) /* 3.0~2.5V, 80%~30% */
+ {
+ bat_level = 30 + (bat_value - 2500) * (80 - 30) / (3000 - 2500);
+ }
+ else if (bat_value >= 2200) /* 2.5~2.2V, 30%~15% */
+ {
+ bat_level = 15 + (bat_value - 2200) * (30 - 15) / (2500 - 2200);
+ }
+ else if (bat_value >= 2000) /* 2.2~2.0V, 15%~0% */
+ {
+ bat_level = (bat_value - 2000) * (15 - 0) / (2200 - 2000);
+ }
+ else /* <2.0V, 0% */
+ {
+ bat_level = 0;
+ }
+
+ APP_PRINT_ERROR2("[bat_calculate_bat_level] bat_value is %d, bat_level is %d", bat_value,
+ bat_level);
+
+ return bat_level;
+}
+
+/******************************************************************
+ * @brief calculation battery calibration voltage.
+ * @param data - data read from ADC.
+ * @return uint16_t - ADC voltage whose unit is mv.
+ */
+uint16_t bat_calibrate_voltage(uint16_t data)
+{
+ float adc_voltage = 0;
+ ADC_ErrorStatus error_status = NO_ERROR;
+ if (true == cur_bat_info.is_adc_efuse_existed)
+ {
+ adc_voltage = ADC_GetVoltage(DIVIDE_SINGLE_MODE, (int32_t)data, &error_status);
+ if (error_status < 0)
+ {
+ APP_PRINT_WARN1("ADC parameter or efuse data error %d!", error_status);
+ adc_voltage = (-5283) * (data * data / 100000000.0f) + (3.50388) * data + 93.8;
+ }
+ }
+ else
+ {
+ adc_voltage = (-5283) * (data * data / 100000000.0f) + (3.50388) * data + 93.8;
+ }
+
+ return (uint16_t)adc_voltage;
+}
+
+/******************************************************************
+ * @brief handle enter low power mode event.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void bat_handle_enter_low_power_event(void)
+{
+ /* double check battery mode */
+ if (cur_bat_info.bat_mode == BAT_MODE_POWER_DOWN)
+ {
+ APP_PRINT_INFO0("[bat_handle_enter_low_power_event] Enter low power mode");
+
+ if (RCU_STATUS_ADVERTISING == app_global_data.rcu_status)
+ {
+ rcu_stop_adv(STOP_ADV_REASON_LOWPOWER);
+ }
+ else if ((RCU_STATUS_CONNECTED == app_global_data.rcu_status)
+ || (RCU_STATUS_PAIRED == app_global_data.rcu_status))
+ {
+ rcu_terminate_connection(DISCONN_REASON_LOW_POWER);
+ }
+ else
+ {
+ app_global_data.rcu_status = RCU_STATUS_LOW_POWER;
+ }
+ }
+ else
+ {
+ APP_PRINT_WARN0("[bat_handle_enter_low_power_event] Invalid bat_mode");
+ }
+}
+
+/******************************************************************
+ * @brief handle enter normal mode event.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void bat_handle_enter_normal_event(void)
+{
+ /* double check battery mode */
+ if (cur_bat_info.bat_mode == BAT_MODE_NORMAL)
+ {
+ APP_PRINT_INFO0("[bat_handle_enter_normal_event] Enter normal power mode");
+#if SUPPORT_BAT_LPC_FEATURE
+ bat_driver_lpc_init();
+#endif
+ if (RCU_STATUS_LOW_POWER == app_global_data.rcu_status)
+ {
+ app_global_data.rcu_status = RCU_STATUS_IDLE;
+ }
+ else
+ {
+ APP_PRINT_WARN0("[bat_handle_enter_normal_event] Invalid rcu_status");
+ }
+ }
+ else
+ {
+ APP_PRINT_WARN0("[bat_handle_enter_normal_event] Invalid bat_mode");
+ }
+}
+
+/******************************************************************
+ * @brief handle key pressed event.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void bat_handle_key_pressed_event(void)
+{
+ if (cur_bat_info.bat_mode == BAT_MODE_NORMAL)
+ {
+#if SUPPORT_BAT_KEY_PRESS_DETECT_FEATURE
+ cur_bat_info.bat_detect_index++;
+
+ APP_PRINT_INFO1("[bat_handle_key_pressed_event] bat_detect_index is %d",
+ cur_bat_info.bat_detect_index);
+
+ if (cur_bat_info.bat_detect_index >= BAT_DETECT_TRIGGER_CNT)
+ {
+ cur_bat_info.bat_detect_index = 0;
+ bat_update_battery_info();
+ }
+#endif
+ }
+ else if (cur_bat_info.bat_mode == BAT_MODE_LOW_POWER)
+ {
+ APP_PRINT_INFO0("[bat_handle_key_pressed_event] BAT_MODE_LOW_POWER");
+ bat_update_battery_info();
+ }
+ else if (cur_bat_info.bat_mode == BAT_MODE_POWER_DOWN)
+ {
+ APP_PRINT_INFO0("[bat_handle_key_pressed_event] BAT_MODE_POWER_DOWN");
+ bat_update_battery_info();
+ }
+}
+
+#if SUPPORT_BAT_LPC_FEATURE
+/******************************************************************
+ * @brief Initialize LPC driver.
+ * @param none
+ * @return none
+ */
+void bat_driver_lpc_init(void)
+{
+ LPC_InitTypeDef LPC_InitStruct;
+ LPC_StructInit(&LPC_InitStruct);
+ LPC_InitStruct.LPC_Channel = LPC_CHANNEL_VBAT ;
+ LPC_InitStruct.LPC_Edge = LPC_Vin_Below_Vth ;
+ LPC_InitStruct.LPC_Threshold = BAT_LPC_COMP_VALUE;
+ LPC_Init(&LPC_InitStruct);
+ LPC_Cmd(ENABLE);
+ RamVectorTableUpdate(LPCOMP_VECTORn, bat_lpc_handler);
+
+ LPC_ResetCounter();
+ LPC_SetCompValue(1);
+ LPC_CounterCmd(ENABLE);
+ LPC_ClearINTPendingBit(LPC_INT_LPCOMP_CNT);
+ LPC_INTConfig(LPC_INT_LPCOMP_CNT, ENABLE);
+
+ LPC_INTCmd(ENABLE);
+
+ /* Config LPC interrupt */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = LPCOMP_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/******************************************************************
+ * @brief LPC driver enter dlps config.
+ * @param none
+ * @return none
+ */
+void bat_driver_lpc_enter_dlps_config(void)
+{
+ LPC_Cmd(DISABLE);
+
+ LPC_ClearINTPendingBit(LPC_INT_LPCOMP_CNT);
+ LPC_INTConfig(LPC_INT_LPCOMP_CNT, DISABLE);
+
+ LPC_INTCmd(DISABLE);
+}
+
+/******************************************************************
+ * @brief LPC driver exit dlps config.
+ * @param none
+ * @return none
+ */
+void bat_driver_lpc_exit_dlps_config(void)
+{
+ LPC_Cmd(ENABLE);
+
+ LPC_ResetCounter();
+ LPC_SetCompValue(1);
+ LPC_CounterCmd(ENABLE);
+ LPC_ClearINTPendingBit(LPC_INT_LPCOMP_CNT);
+ LPC_INTConfig(LPC_INT_LPCOMP_CNT, ENABLE);
+
+ LPC_INTCmd(ENABLE);
+}
+
+/******************************************************************
+ * @brief lpc interrupt handler function.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void bat_lpc_handler(void)
+{
+ DBG_DIRECT("[bat_lpc_handler] LPC lower power triggered!");
+
+ /* LPC counter comparator interrupt */
+ if (LPC_GetFlagStatus(LPC_FLAG_LPCOMP_CNT) == SET)
+ {
+ LPC_INTConfig(LPC_INT_LPCOMP_CNT, DISABLE);
+ LPC_INTCmd(DISABLE);
+ DBG_DIRECT("[bat_lpc_handler] LPC lower power CNT triggered!");
+ LPC_ResetCounter();
+
+ LPC_ClearINTPendingBit(LPC_INT_LPCOMP_CNT);
+ WDG_SystemReset(RESET_ALL_EXCEPT_AON, RESET_REASON_LPC_TRIGGER);
+ }
+}
+#endif
+
+#if SUPPORT_BAT_PERIODIC_DETECT_FEATURE
+void bat_detect_timer_callback(TimerHandle_t pxTimer)
+{
+ APP_PRINT_ERROR0("[bat_detect_timer_callback] timeout");
+
+ T_IO_MSG bee_io_msg;
+ bee_io_msg.type = IO_MSG_TYPE_BAT_DETECT;
+ bee_io_msg.subtype = IO_MSG_BAT_DETECT_TIMEOUT;
+ if (false == app_send_msg_to_apptask(&bee_io_msg))
+ {
+ APP_PRINT_WARN0("[bat_detect_timer_callback] Send message failed");
+ }
+
+ os_timer_restart(&bat_detect_timer, BAT_PERIODIC_DETECT_TIMEOUT);
+}
+#endif
+
+/*============================================================================*
+ * Global functions
+ *============================================================================*/
+/******************************************************************
+ * @brief battery module enter DLPS config
+ * @param none
+ * @return none
+ * @retval void
+ */
+void bat_enter_dlps_config(void)
+{
+#if SUPPORT_BAT_LPC_FEATURE
+ bat_driver_lpc_enter_dlps_config();
+#endif
+}
+
+/******************************************************************
+ * @brief battery module exit DLPS config
+ * @param none
+ * @return none
+ * @retval void
+ */
+void bat_exit_dlps_config(void)
+{
+ bat_init_driver();
+
+#if SUPPORT_BAT_LPC_FEATURE
+ bat_driver_lpc_exit_dlps_config();
+#endif
+}
+
+/******************************************************************
+ * @brief Initialize battery module data
+ * @param none
+ * @return none
+ */
+void bat_init_data(void)
+{
+ APP_PRINT_INFO0("[bat_init_data] init data");
+ memset(&cur_bat_info, 0, sizeof(cur_bat_info));
+ cur_bat_info.is_adc_efuse_existed = ADC_CalibrationInit();
+ if (false == cur_bat_info.is_adc_efuse_existed)
+ {
+ APP_PRINT_WARN0("[bat_init_data] Read ADC efuse data error!");
+ }
+}
+
+/******************************************************************
+ * @brief get battery mode.
+ * @param none
+ * @return battery mode
+ */
+T_BAT_MODE bat_get_current_mode(void)
+{
+ return (T_BAT_MODE)cur_bat_info.bat_mode;
+}
+
+/******************************************************************
+ * @brief get battery voltage value.
+ * @param none
+ * @return battery voltage value
+ */
+uint16_t bat_get_current_voltage_value(void)
+{
+ return cur_bat_info.bat_value;
+}
+
+/******************************************************************
+ * @brief get battery voltage level.
+ * @param none
+ * @return battery voltage level
+ */
+uint8_t bat_get_current_voltage_level(void)
+{
+ return cur_bat_info.bat_level;
+}
+
+/******************************************************************
+ * @brief Initialize battery driver.
+ * @param none
+ * @return none
+ */
+void bat_init_driver(void)
+{
+ ADC_DeInit(ADC);
+ RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+
+ ADC_InitTypeDef adcInitStruct;
+ ADC_StructInit(&adcInitStruct);
+
+ for (uint8_t index = 0; index < BAT_ADC_SAMPLE_CNT; index++)
+ {
+ adcInitStruct.ADC_SchIndex[index] = INTERNAL_VBAT_MODE;
+ }
+ adcInitStruct.ADC_Bitmap = (1 << BAT_ADC_SAMPLE_CNT) - 1;
+ adcInitStruct.ADC_SampleTime = 255;
+
+ ADC_Init(ADC, &adcInitStruct);
+
+#if SUPPORT_BAT_PERIODIC_DETECT_FEATURE
+ if (bat_detect_timer == NULL)
+ {
+ APP_PRINT_ERROR0("[bat_init_driver] initialize bat_detect_timer");
+ /* bat_detect_timer is used to update battery info perodically */
+ if (false == os_timer_create(&bat_detect_timer, "bat_detect_timer", 1, \
+ BAT_PERIODIC_DETECT_TIMEOUT, false, bat_detect_timer_callback))
+ {
+ APP_PRINT_ERROR0("[bat_init_driver] timer creat failed!");
+ }
+ else
+ {
+ os_timer_start(&bat_detect_timer);
+ }
+ }
+#endif
+}
+
+/******************************************************************
+ * @brief battery module nvic config
+ * @param none
+ * @return none
+ * @retval void
+ */
+void bat_nvic_config(void)
+{
+#if SUPPORT_BAT_LPC_FEATURE
+ if (BAT_MODE_NORMAL == bat_get_current_mode())
+ {
+ APP_PRINT_INFO0("[bat_nvic_config] Init LPC");
+ bat_driver_lpc_init();
+ }
+ else
+ {
+ APP_PRINT_INFO0("[bat_nvic_config] In low power mode. Don't init LPC");
+ }
+#endif
+}
+
+/******************************************************************
+ * @brief get battery value.
+ * @param p_level
+ * @param p_value
+ * @return T_BAT_STATUS - state
+ */
+T_BAT_STATUS bat_update_battery_info(void)
+{
+ T_BAT_STATUS status = BAT_STATUS_SUCCESS;
+ uint32_t sum = 0;
+ uint16_t adc_arr[BAT_ADC_SAMPLE_CNT];
+ uint16_t min = 0xffff;
+ uint16_t max = 0;
+
+ ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE);
+ ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE);
+
+ uint32_t delay = 0;
+ /* 5000 timeout: 1ms at 40M Clock */
+ while ((ADC_GetINTStatus(ADC, ADC_INT_ONE_SHOT_DONE) != SET)
+ && ((delay++ < 5000)));
+ ADC_ClearINTPendingBit(ADC, ADC_INT_ONE_SHOT_DONE);
+
+ /* get average value after remove minimal and maximal values */
+ for (uint8_t index = 0; index < BAT_ADC_SAMPLE_CNT; index ++)
+ {
+ adc_arr[index] = ADC_ReadRawData(ADC, index);
+
+ sum += adc_arr[index];
+ if (min > adc_arr[index])
+ {
+ min = adc_arr[index];
+ }
+ if (max < adc_arr[index])
+ {
+ max = adc_arr[index];
+ }
+ }
+ sum = (sum - min - max) / (BAT_ADC_SAMPLE_CNT - 2);
+ APP_PRINT_WARN1("[bat_update_battery_info] bat_adc_sample_average_value = %d", sum);
+
+ /* calculate battery voltage value */
+ cur_bat_info.bat_value = (uint16_t)bat_calibrate_voltage(sum);
+
+ /* calculate battery level */
+ cur_bat_info.bat_level = bat_calculate_bat_level(cur_bat_info.bat_value);
+
+ /* update battery mode */
+ if (RCU_STATUS_LOW_POWER != app_global_data.rcu_status)
+ {
+ if (cur_bat_info.bat_value < BAT_ENTER_LOW_POWER_THRESHOLD)
+ {
+ cur_bat_info.bat_mode = BAT_MODE_POWER_DOWN;
+
+ T_IO_MSG bee_io_msg;
+ bee_io_msg.type = IO_MSG_TYPE_BAT_DETECT;
+ bee_io_msg.subtype = IO_MSG_BAT_DETECT_ENTER_LOW_POWER;
+ if (false == app_send_msg_to_apptask(&bee_io_msg))
+ {
+ APP_PRINT_WARN0("[bat_update_battery_info] Send message failed");
+ status = BAT_STATUS_SEND_MSG_FAIL;
+ }
+ }
+ else if (cur_bat_info.bat_value <= BAT_ENTER_NORMAL_MODE_THRESHOLD)
+ {
+ APP_PRINT_WARN0("[bat_update_battery_info] BAT_MODE_LOW_POWER");
+ cur_bat_info.bat_mode = BAT_MODE_LOW_POWER;
+ }
+ else
+ {
+ APP_PRINT_WARN0("[bat_update_battery_info] BAT_MODE_NORMAL");
+ cur_bat_info.bat_mode = BAT_MODE_NORMAL;
+ }
+ }
+ else if (RCU_STATUS_LOW_POWER == app_global_data.rcu_status)
+ {
+ if (cur_bat_info.bat_value > BAT_ENTER_NORMAL_MODE_THRESHOLD)
+ {
+ cur_bat_info.bat_mode = BAT_MODE_NORMAL;
+
+ T_IO_MSG bee_io_msg;
+ bee_io_msg.type = IO_MSG_TYPE_BAT_DETECT;
+ bee_io_msg.subtype = IO_MSG_BAT_DETECT_ENTER_NORMAL_MODE;
+ if (false == app_send_msg_to_apptask(&bee_io_msg))
+ {
+ APP_PRINT_WARN0("[bat_update_battery_info] Send message failed");
+ status = BAT_STATUS_SEND_MSG_FAIL;
+ }
+ }
+ }
+ else
+ {
+ status = BAT_STATUS_FAIL;
+ }
+
+ APP_PRINT_INFO5("[bat_update_battery_info] bat_mode is %d, bat_value is %d, bat_level is %d, status is %d, rcu_status is %d",
+ cur_bat_info.bat_mode, cur_bat_info.bat_value, cur_bat_info.bat_level, status,
+ app_global_data.rcu_status);
+
+ return status;
+}
+
+/******************************************************************
+ * @brief bat message handle.
+ * @param msg_sub_type - the msg type to handle.
+ * @return none
+ * @retval void
+ */
+void bat_msg_handle(uint16_t msg_sub_type)
+{
+ APP_PRINT_ERROR1("[bat_msg_handle] bat_msg_handle, type = %d!", msg_sub_type);
+
+ if (msg_sub_type == IO_MSG_BAT_DETECT_ENTER_LOW_POWER)
+ {
+ bat_handle_enter_low_power_event();
+ }
+ else if (msg_sub_type == IO_MSG_BAT_DETECT_ENTER_NORMAL_MODE)
+ {
+ bat_handle_enter_normal_event();
+ }
+ else if (msg_sub_type == IO_MSG_BAT_DETECT_KEY_PRESSED)
+ {
+ bat_handle_key_pressed_event();
+ }
+ else if (msg_sub_type == IO_MSG_BAT_DETECT_TIMEOUT)
+ {
+ bat_update_battery_info();
+ }
+ else
+ {
+ APP_PRINT_WARN0("[bat_msg_handle] Invalid message type");
+ }
+}
+#endif
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/bat_module/battery_driver.h b/src/app/google_rcu/bat_module/battery_driver.h
new file mode 100644
index 0000000..986be21
--- /dev/null
+++ b/src/app/google_rcu/bat_module/battery_driver.h
@@ -0,0 +1,96 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file battery_driver.h
+* @details
+* @author chenjie_jin
+* @date 2020-05-11
+* @version v1.1
+*********************************************************************************************************
+*/
+
+#ifndef _BAT_DRIVER_H_
+#define _BAT_DRIVER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <board.h>
+
+#if SUPPORT_BAT_DETECT_FEATURE
+/*============================================================================*
+ * Macro Definitions
+ *============================================================================*/
+#define BAT_ADC_SAMPLE_CNT 4 /* battery adc samples counts, ragne 3-16 */
+#if SUPPORT_BAT_KEY_PRESS_DETECT_FEATURE
+#define BAT_DETECT_TRIGGER_CNT 10 /* battery adc detection trigger count */
+#endif
+#if SUPPORT_BAT_PERIODIC_DETECT_FEATURE
+#define BAT_PERIODIC_DETECT_TIMEOUT (600 * 1000) /* timeout in unit 1ms */
+#endif
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef enum
+{
+ BAT_STATUS_SUCCESS = 0,
+ BAT_STATUS_FAIL = 1,
+ BAT_STATUS_PENDING = 2,
+ BAT_STATUS_SEND_MSG_FAIL = 3,
+} T_BAT_STATUS;
+
+typedef enum
+{
+ BAT_MODE_NORMAL = 0, /* battery normal mode */
+ BAT_MODE_POWER_DOWN = 1, /* battery power down mode */
+ BAT_MODE_LOW_POWER = 2, /* battery low power mode: 2V ~ 2.2V */
+} T_BAT_MODE;
+
+typedef enum
+{
+ IO_MSG_BAT_DETECT_ENTER_LOW_POWER = 0, /* enter battery low power mode event */
+ IO_MSG_BAT_DETECT_ENTER_NORMAL_MODE = 1, /* enter battery low power mode event */
+ IO_MSG_BAT_DETECT_LPC = 2, /* LPC trigger event */
+ IO_MSG_BAT_DETECT_KEY_PRESSED = 3, /* key pressed battery event */
+ IO_MSG_BAT_DETECT_TIMEOUT = 4, /* battery timeout event */
+} T_IO_MSG_BAT_DETECT;
+
+typedef struct
+{
+ bool is_adc_efuse_existed; /* to indicate whether adc efuse data is right or not */
+ T_BAT_MODE bat_mode; /* current battery mode */
+ uint8_t bat_detect_index; /* current battery detect index */
+ uint8_t bat_level; /* battery level, range 0-100 */
+ uint16_t bat_value; /* battery value in uint mV */
+} T_BAT_INFO_STRUCT;
+
+/*============================================================================*
+ * Interface Functions
+ *============================================================================*/
+void bat_init_data(void);
+T_BAT_MODE bat_get_current_mode(void);
+uint16_t bat_get_current_voltage_value(void);
+uint8_t bat_get_current_voltage_level(void);
+void bat_init_driver(void);
+void bat_nvic_config(void);
+T_BAT_STATUS bat_update_battery_info(void);
+void bat_msg_handle(uint16_t msg_sub_type);
+void bat_enter_dlps_config(void);
+void bat_exit_dlps_config(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/bibuffer.c b/src/app/google_rcu/bibuffer.c
new file mode 100644
index 0000000..07fe767
--- /dev/null
+++ b/src/app/google_rcu/bibuffer.c
@@ -0,0 +1,94 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file bibuffer.c
+* @brief double buffer data struct.
+* @details
+* @author elliot_chen
+* @date 2017-06-05
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "bibuffer.h"
+
+/* Globals -------------------------------------------------------------------*/
+//RAM_BUFFERON_BSS_SECTION BiBuf_TypeDef BiBuf __attribute__((used));
+BiBuf_TypeDef BiBuf;
+
+/**
+ * @brief Initializes double buffer to their default reset values.
+ * @param None.
+ * @retval None
+ */
+void BiBuffer_Init(void)
+{
+ memset(&BiBuf, 0, sizeof(BiBuf_TypeDef));
+ BiBuffer_SetBuf0Status(READ_DONE);
+ BiBuffer_SetBuf1Status(READ_DONE);
+}
+
+/**
+ * @brief Get buffer address.
+ * @param None.
+ * @retval buffer address.
+ */
+uint32_t BiBuffer_GetBuf0Addr(void)
+{
+ return (uint32_t)BiBuf.buf0;
+}
+
+/**
+ * @brief Set buffer status.
+ * @param None.
+ * @retval None.
+ */
+void BiBuffer_SetBuf0Status(BUF_STATUS status)
+{
+ BiBuf.buf0_stat = status;
+}
+
+/**
+ * @brief Get buffer status.
+ * @param None.
+ * @retval None.
+ */
+BUF_STATUS BiBuffer_GetBuf0Status(void)
+{
+ return BiBuf.buf0_stat;
+}
+
+/**
+ * @brief Get buffer address.
+ * @param None.
+ * @retval buffer address.
+ */
+uint32_t BiBuffer_GetBuf1Addr(void)
+{
+ return (uint32_t)BiBuf.buf1;
+}
+
+/**
+ * @brief Set buffer status.
+ * @param None.
+ * @retval None.
+ */
+void BiBuffer_SetBuf1Status(BUF_STATUS status)
+{
+ BiBuf.buf1_stat = status;
+}
+
+/**
+ * @brief Get buffer status.
+ * @param None.
+ * @retval None.
+ */
+BUF_STATUS BiBuffer_GetBuf1Status(void)
+{
+ return BiBuf.buf1_stat;
+}
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/bibuffer.h b/src/app/google_rcu/bibuffer.h
new file mode 100644
index 0000000..2854f4b
--- /dev/null
+++ b/src/app/google_rcu/bibuffer.h
@@ -0,0 +1,83 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file bibuffer.h
+* @brief header file of double buffer data struct.
+* @details
+* @author elliot chen
+* @date 2017-06-05
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __BI_BUFFER_H
+#define __BI_BUFFER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "string.h"
+#include "trace.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/**
+ * @brief Enable print log or not
+ */
+
+#define PRINT_BI_BUFFER_LOG
+#ifdef PRINT_BI_BUFFER_LOG
+#define BI_BUFFER(MODULE, LEVEL, pFormat, para_num,...) DBG_BUFFER_##LEVEL(MODULE, pFormat, para_num, ##__VA_ARGS__)
+#else
+#define BI_BUFFER(MODULE, LEVEL, pFormat, para_num,...) ((void)0)
+#endif
+
+/**
+ * @brief Configure double buffer parameters
+ */
+
+#define BI_BUFFER_MAX_SIZE (512)
+
+/**
+ * @brief double buffer status
+ */
+
+typedef enum
+{
+ READ_DONE = 0,
+ READING = 1,
+ WRITING = 2,
+ WRITE_DONE = 3,
+} BUF_STATUS;
+
+/**
+ * @brief Loop queue data struct
+ */
+
+typedef struct
+{
+ volatile BUF_STATUS buf0_stat;
+ volatile BUF_STATUS buf1_stat;
+ uint8_t buf0[BI_BUFFER_MAX_SIZE];
+ uint8_t buf1[BI_BUFFER_MAX_SIZE];
+} BiBuf_TypeDef;
+
+void BiBuffer_Init(void);
+uint32_t BiBuffer_GetBuf0Addr(void);
+void BiBuffer_SetBuf0Status(BUF_STATUS status);
+BUF_STATUS BiBuffer_GetBuf0Status(void);
+uint32_t BiBuffer_GetBuf1Addr(void);
+void BiBuffer_SetBuf1Status(BUF_STATUS status);
+BUF_STATUS BiBuffer_GetBuf1Status(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__BI_BUFFER_H */
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/buzzer_module/buzzer_driver.c b/src/app/google_rcu/buzzer_module/buzzer_driver.c
new file mode 100644
index 0000000..91e6d17
--- /dev/null
+++ b/src/app/google_rcu/buzzer_module/buzzer_driver.c
@@ -0,0 +1,247 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file buzzer_driver.c
+* @brief This is the entry of user code which the buzzer module resides in.
+* @details
+* @author chenjie
+* @date 2021-10-14
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <board.h>
+#include <string.h>
+#include <trace.h>
+#include <os_msg.h>
+#include <app_msg.h>
+#include <os_timer.h>
+#include <buzzer_driver.h>
+#include <rtl876x_rcc.h>
+#include <swtimer.h>
+#include <rtl876x_pinmux.h>
+#include <rtl876x_nvic.h>
+#include <app_task.h>
+#include "rtl876x_tim.h"
+#include <rcu_application.h>
+
+#if SUPPORT_BUZZER_FEATURE
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+
+/*============================================================================*
+* Global Variables
+*============================================================================*/
+T_BUZZER_LOCAL_DATA buzzer_local_data;
+
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+static bool buzzer_get_pwm_count(uint32_t period_in_us, uint32_t duty_cycle,
+ uint32_t *p_pwm_high_cnt, uint32_t *p_pwm_low_cnt);
+
+/*============================================================================*
+* External Functions
+*============================================================================*/
+
+
+/*============================================================================*
+* Local Functions
+*============================================================================*/
+/******************************************************************
+ * @fn buzzer_init_driver
+ * @brief buzzer module initial
+ */
+static void buzzer_init_driver(uint16_t frequency, uint8_t duty_cycle)
+{
+ RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+
+ TIM_TimeBaseInitTypeDef TIM_InitStruct;
+ uint32_t period;
+ uint32_t cur_pwm_high_cnt = 0;
+ uint32_t cur_pwm_low_cnt = 0;
+ period = (uint32_t)(1000000 / frequency);
+
+ if (false == buzzer_get_pwm_count(period, (uint32_t)duty_cycle,
+ &cur_pwm_high_cnt, &cur_pwm_low_cnt))
+ {
+ cur_pwm_high_cnt = PWM_HIGH_COUNT;
+ cur_pwm_low_cnt = PWM_LOW_COUNT;
+ }
+
+ TIM_StructInit(&TIM_InitStruct);
+ TIM_InitStruct.TIM_PWM_En = PWM_ENABLE;
+ TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ TIM_InitStruct.TIM_PWM_High_Count = cur_pwm_high_cnt;
+ TIM_InitStruct.TIM_PWM_Low_Count = cur_pwm_low_cnt;
+ TIM_InitStruct.PWM_Deazone_Size = 0;
+ TIM_InitStruct.PWMDeadZone_En = DEADZONE_DISABLE; //enable to use pwn p/n output
+ TIM_TimeBaseInit(PWM_TIMER_NUM, &TIM_InitStruct);
+
+ TIM_Cmd(PWM_TIMER_NUM, ENABLE);
+}
+
+/******************************************************************
+ * @fn buzzer_deinit_driver
+ * @brief buzzer module de-initial
+ */
+static void buzzer_deinit_driver(void)
+{
+ TIM_Cmd(PWM_TIMER_NUM, DISABLE);
+}
+
+/*============================================================================*
+* Global Functions
+*============================================================================*/
+/**
+* @fn buzzer_init_data
+* @brief Initialize buzzer driver data
+*/
+void buzzer_init_data(void)
+{
+ APP_PRINT_INFO0("[buzzer_init_data] init data");
+ memset(&buzzer_local_data, 0, sizeof(buzzer_local_data));
+ buzzer_local_data.is_allowed_to_enter_dlps = true;
+ buzzer_local_data.current_peirod_in_us = PWM_PERIOD;
+ buzzer_local_data.duty_cycle = PWM_DUTY_CYCLE;
+ buzzer_local_data.freq = PWM_FREQUENCY;
+}
+
+/******************************************************************
+ * @brief buzzer pinmux config
+ */
+void buzzer_pinmux_config(void)
+{
+ Pinmux_Config(BUZZER_PWM_OUTPUT_PIN, PWM_OUT_PIN_PINMUX);
+}
+
+/******************************************************************
+ * @brief buzzer init pad config
+ */
+void buzzer_init_pad_config(void)
+{
+ Pad_Config(BUZZER_PWM_OUTPUT_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+}
+
+/******************************************************************
+ * @brief buzzer deinit pad config
+ */
+void buzzer_deinit_pad_config(void)
+{
+ Pad_Config(BUZZER_PWM_OUTPUT_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_DOWN, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+}
+
+/******************************************************************
+ * @brief buzzer check DLPS config
+ */
+bool buzzer_check_dlps_allowed(void)
+{
+ return buzzer_local_data.is_allowed_to_enter_dlps;
+}
+
+/******************************************************************
+ * @brief buzzer start pwm output
+ */
+void buzzer_start_pwm_output(uint16_t frequency, uint8_t duty_cycle)
+{
+ APP_PRINT_INFO2("[buzzer_start_pwm_output] start PWM output!, frequency = %d duty_cycle = %d",
+ frequency, duty_cycle);
+
+ if (buzzer_local_data.is_working == false)
+ {
+ buzzer_init_data();
+ buzzer_init_pad_config();
+ buzzer_pinmux_config();
+ buzzer_init_driver(frequency, duty_cycle);
+ }
+
+ buzzer_local_data.is_allowed_to_enter_dlps = false;
+ buzzer_local_data.is_working = true;
+}
+
+/******************************************************************
+ * @brief buzzer stop pwm output
+ */
+void buzzer_stop_pwm_output(void)
+{
+ APP_PRINT_INFO0("[buzzer_stop_pwm_output] stop PWM output!");
+ if (buzzer_local_data.is_working == true)
+ {
+ buzzer_deinit_driver();
+ buzzer_deinit_pad_config();
+ buzzer_local_data.is_working = false;
+ buzzer_local_data.is_allowed_to_enter_dlps = true;
+ }
+}
+
+/******************************************************************
+ * @brief buzzer get pwm count
+ */
+bool buzzer_get_pwm_count(uint32_t period_in_us, uint32_t duty_cycle, uint32_t *p_pwm_high_cnt,
+ uint32_t *p_pwm_low_cnt)
+{
+ if ((period_in_us == 0)
+ || (duty_cycle > 100))
+ {
+ return false;
+ }
+
+ *p_pwm_high_cnt = (((period_in_us) * (duty_cycle * 40) / 100) - 1);
+ *p_pwm_low_cnt = (((period_in_us) * ((100 - duty_cycle) * 40) / 100) - 1);
+
+ return true;
+}
+
+/******************************************************************
+ * @brief buzzer set frequency
+ */
+void buzzer_set_frequency(uint16_t frequency)
+{
+ buzzer_local_data.freq = frequency;
+}
+
+/******************************************************************
+ * @brief buzzer set duty cycle
+ */
+void buzzer_set_duty_cycle(uint8_t duty_cycle)
+{
+ buzzer_local_data.duty_cycle = duty_cycle;
+}
+
+/******************************************************************
+ * @brief buzzer get frequency
+ */
+uint16_t buzzer_get_frequency(void)
+{
+ return buzzer_local_data.freq;
+}
+
+/******************************************************************
+ * @brief buzzer get duty cycle
+ */
+uint8_t buzzer_get_duty_cycle(void)
+{
+ return buzzer_local_data.duty_cycle;
+}
+
+/******************************************************************
+ * @brief buzzer is working check
+ */
+bool buzzer_is_working_check(void)
+{
+ return buzzer_local_data.is_working;
+}
+
+#endif
diff --git a/src/app/google_rcu/buzzer_module/buzzer_driver.h b/src/app/google_rcu/buzzer_module/buzzer_driver.h
new file mode 100644
index 0000000..09220f9
--- /dev/null
+++ b/src/app/google_rcu/buzzer_module/buzzer_driver.h
@@ -0,0 +1,86 @@
+
+/*
+ * Routines to access hardware
+ *
+ * Copyright (c) 2018 Realtek Semiconductor Corp.
+ *
+ * This module is a confidential and proprietary property of RealTek and
+ * possession or use of this module requires written permission of RealTek.
+ */
+#ifndef _BUZZER_DRIVER_H_
+#define _BUZZER_DRIVER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdint.h>
+#include <stdbool.h>
+#include <swtimer.h>
+#include <rtl876x.h>
+#include <board.h>
+
+#if SUPPORT_BUZZER_FEATURE
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define PWM_TIMER_NUM TIM4
+#define PWM_OUT_PIN_PINMUX TIM_PWM4
+
+/* Config PWM_PERIOD and PWM_DUTY_CYCLE */
+#define PWM_FREQUENCY 1000 //uint:hz
+#define PWM_PERIOD 1000 //uint:us
+#define PWM_DUTY_CYCLE 50 //uint:percent
+#define PWM_HIGH_COUNT (((PWM_PERIOD)*((PWM_DUTY_CYCLE*40)/100))-1) //PWM CLOCK = 40000000
+#define PWM_LOW_COUNT (((PWM_PERIOD)*(((100-PWM_DUTY_CYCLE)*40)/100))-1)
+
+#define BUZZER_PWM_STOP_TIMEOUT 1 /* 1ms */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/**
+ * @brief Buzzer global data struct definition.
+ */
+typedef struct
+{
+ bool is_allowed_to_enter_dlps; /* to indicate whether to allow to enter dlps or not */
+ bool is_working; /* to indicate whether buzzer driver is working or not */
+ uint32_t current_peirod_in_us; /* to indicate the current PWM period in us */
+ uint16_t freq; /* to indicate the frequency */
+ uint8_t duty_cycle; /* to indicate the duty_cycle */
+} T_BUZZER_LOCAL_DATA;
+
+/*============================================================================*
+* Export Global Variables
+*============================================================================*/
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void buzzer_init_data(void);
+void buzzer_pinmux_config(void);
+void buzzer_deinit_pad_config(void);
+void buzzer_init_pad_config(void);
+bool buzzer_check_dlps_allowed(void);
+void buzzer_start_pwm_output(uint16_t frequency, uint8_t duty_cycle);
+void buzzer_stop_pwm_output(void);
+void buzzer_set_frequency(uint16_t frequency);
+void buzzer_set_duty_cycle(uint8_t duty_cycle);
+uint16_t buzzer_get_frequency(void);
+uint8_t buzzer_get_duty_cycle(void);
+bool buzzer_is_working_check(void);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/app/google_rcu/buzzer_module/fms_service_handle.c b/src/app/google_rcu/buzzer_module/fms_service_handle.c
new file mode 100644
index 0000000..b7b6641
--- /dev/null
+++ b/src/app/google_rcu/buzzer_module/fms_service_handle.c
@@ -0,0 +1,403 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file fms_service_handle.c
+* @brief This is the entry of user code which the FMS service handle module resides in.
+* @details
+* @author chenjie jin
+* @date 2022-05-31
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include "board.h"
+#include "fms_service_handle.h"
+#include "fms.h"
+#include "trace.h"
+#include "profile_server.h"
+#include "rcu_application.h"
+#include "os_timer.h"
+#include "swtimer.h"
+#include "os_mem.h"
+#include "app_task.h"
+#include "buzzer_driver.h"
+#include "app_section.h"
+#include "key_handle.h"
+#include "rcu_gap.h"
+
+#if SUPPORT_BUZZER_FEATURE
+
+/*============================================================================*
+ * Static Variables
+ *============================================================================*/
+static TimerHandle_t Fms_Periodical_Conn_Timer = NULL;
+static bool Fms_Handle_Notify_Flag = false;
+static uint16_t Fms_Current_Mode = FMS_CTL_MODE_ALERT;
+
+/*============================================================================*
+ * Global Variables
+ *============================================================================*/
+
+
+/*============================================================================*
+ * Static Functions
+ *============================================================================*/
+static T_APP_RESULT fms_handle_write_control_char(T_FMS_WRITE_MSG *p_write);
+static T_APP_RESULT fms_handle_write_data_char(T_FMS_WRITE_MSG *p_write);
+
+static T_APP_RESULT fms_handle_write_char_cb(T_FMS_WRITE_MSG *p_write);
+static T_APP_RESULT fms_handle_read_char_cb(uint8_t read_value_index);
+static T_APP_RESULT fms_handle_indication_notification_char_cb(uint8_t
+ notification_indification_index);
+
+static void fms_periodical_conn_callback(TimerHandle_t p_timer) DATA_RAM_FUNCTION;
+/******************************************************************
+ * @fn fms_handle_write_char_cb
+ * @brief FMS service handle write char callback.
+ * @param p_write - pointer to write data
+ * @return T_APP_RESULT
+ */
+T_APP_RESULT fms_handle_write_char_cb(T_FMS_WRITE_MSG *p_write)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ uint8_t write_type = p_write->write_type;
+ APP_PRINT_INFO1("[fms_handle_write_char_cb] write_type is %d", write_type);
+
+ switch (write_type)
+ {
+ case FMS_WRITE_CHAR_CONTROL:
+ {
+ fms_handle_write_control_char(p_write);
+ }
+ break;
+ case FMS_WRITE_CHAR_DATA:
+ {
+ fms_handle_write_data_char(p_write);
+ }
+ break;
+ default:
+ cb_result = APP_RESULT_APP_ERR;
+ break;
+ }
+
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn fms_handle_read_char_cb
+ * @brief FMS service handle read char callback.
+ * @param read_value_index - read value index
+ * @return T_APP_RESULT
+ */
+T_APP_RESULT fms_handle_read_char_cb(uint8_t read_value_index)
+{
+ T_APP_RESULT cb_result = APP_RESULT_APP_ERR;
+
+ APP_PRINT_INFO1("[fms_handle_read_char_cb] read_value_index is %d", read_value_index);
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn fms_handle_indication_notification_char_cb
+ * @brief FMS service handle indication notification char callback.
+ * @param notification_indification_index - notification or indication index
+ * @return T_APP_RESULT
+ */
+T_APP_RESULT fms_handle_indication_notification_char_cb(uint8_t
+ notification_indification_index)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ APP_PRINT_INFO1("[fms_handle_indication_notification_char_cb] notification_indification_index is %d",
+ notification_indification_index);
+
+ if (notification_indification_index == FMS_DATA_NOTIFY_ENABLE)
+ {
+ Fms_Handle_Notify_Flag = true;
+ }
+ else if (notification_indification_index == FMS_DATA_NOTIFY_DISABLE)
+ {
+ Fms_Handle_Notify_Flag = false;
+ }
+
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn fms_handle_write_control_char
+ * @brief FMS service handle write GATT_SVC_IR_PROG_CONTROL_INDEX callback.
+ * @param p_write - pointer to write data
+ * @return T_APP_RESULT
+ */
+T_APP_RESULT fms_handle_write_control_char(T_FMS_WRITE_MSG *p_write)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ uint16_t data_len = p_write->write_parameter.report_data.len;
+ uint8_t *p_data = p_write->write_parameter.report_data.report;
+
+ if (data_len == FMS_WRITE_CHAR_CONTROL_LEN)
+ {
+ LE_ARRAY_TO_UINT16(Fms_Current_Mode, p_data);
+ cb_result = APP_RESULT_SUCCESS;
+ }
+ else
+ {
+ cb_result = APP_RESULT_APP_ERR;
+ }
+
+ APP_PRINT_INFO2("[fms_handle_write_control_char] cb_result = %d, Fms_Current_Mode = 0x%04X",
+ cb_result, Fms_Current_Mode);
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn fms_handle_write_data_char
+ * @brief FMS service handle write GATT_SVC_IR_KEY_ID_INDEX callback.
+ * @param p_write - pointer to write data
+ * @return T_APP_RESULT
+ */
+T_APP_RESULT fms_handle_write_data_char(T_FMS_WRITE_MSG *p_write)
+{
+ uint16_t status = FMS_STATUS_OK;
+ uint16_t error_code = FMS_ERROR_NO_ERR;
+ uint16_t cmd_type;
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ uint16_t data_len = p_write->write_parameter.report_data.len;
+ uint8_t *p_data = p_write->write_parameter.report_data.report;
+
+ if (Fms_Current_Mode == FMS_CTL_MODE_ALERT)
+ {
+ if (data_len >= 2)
+ {
+ LE_ARRAY_TO_UINT16(cmd_type, p_data);
+
+ APP_PRINT_INFO1("[fms_handle_write_data_char] FMS_CTL_MODE_ALERT cmd_type = 0x%04X", cmd_type);
+
+ if (cmd_type == FMS_DATA_STOP_ALERT)
+ {
+ /* stop alert */
+ buzzer_stop_pwm_output();
+ }
+ else if (cmd_type == FMS_DATA_ALERT_LEVEL_LOW)
+ {
+ /* low level alert */
+ buzzer_start_pwm_output(1000, 25);
+ }
+ else if (cmd_type == FMS_DATA_ALERT_LEVEL_MEDIUM)
+ {
+ /* medium level alert */
+ buzzer_start_pwm_output(1000, 50);
+ }
+ else if (cmd_type == FMS_DATA_ALERT_LEVEL_HIGH)
+ {
+ /* high level alert */
+ buzzer_start_pwm_output(1000, 75);
+ }
+ else
+ {
+ status = FMS_STATUS_ERROR;
+ error_code = FMS_ERROR_UNKNOWN_CMD;
+ }
+ }
+ else
+ {
+ status = FMS_STATUS_ERROR;
+ error_code = FMS_ERROR_UNKNOWN_CMD;
+ }
+ }
+ else
+ {
+ status = FMS_STATUS_ERROR;
+ error_code = FMS_ERROR_MODE_DISABLED;
+ }
+
+ fms_handle_notify_status(status, error_code);
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @brief FMS periodical connection timer callback
+ *
+ * fms_periodical_conn_callback is used to start advertising after timeout
+ *
+ * @param p_timer - timer handler
+ * @return none
+ * @retval void
+ */
+void fms_periodical_conn_callback(TimerHandle_t p_timer)
+{
+ if (app_global_data.is_link_key_existed == true)
+ {
+ if (app_global_data.rcu_status == RCU_STATUS_IDLE)
+ {
+ app_global_data.wakeup_key_index = KEY_ID_NONE;
+ rcu_start_adv(ADV_UNDIRECT_WAKEUP);
+ }
+ else
+ {
+ os_timer_start(&Fms_Periodical_Conn_Timer);
+ }
+ }
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @fn fms_handle_init_data
+ * @brief Initialize FMS handler data.
+ * @param void
+ * @return void
+ */
+void fms_handle_init_data(void)
+{
+ APP_PRINT_INFO0("[fms_handle_init_data] init data");
+
+ Fms_Handle_Notify_Flag = false;
+ Fms_Current_Mode = FMS_CTL_MODE_ALERT;
+}
+
+/******************************************************************
+ * @fn fms_handle_srv_cb
+ * @brief FMS service callbacks are handled in this function.
+ * @param p_data - pointer to callback data
+ * @return T_APP_RESULT
+ */
+T_APP_RESULT fms_handle_srv_cb(T_FMS_CALLBACK_DATA *p_data)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ APP_PRINT_INFO1("[fms_handle_srv_cb] msg_type: %d", p_data->msg_type);
+
+ switch (p_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ cb_result = fms_handle_read_char_cb(p_data->msg_data.read_value_index);
+ break;
+
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ cb_result = fms_handle_write_char_cb(&p_data->msg_data.write_msg);
+ break;
+
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ cb_result = fms_handle_indication_notification_char_cb(
+ p_data->msg_data.notification_indification_index);
+ break;
+
+ default:
+ APP_PRINT_INFO1("[fms_handle_srv_cb] unknown msg_type: %d", p_data->msg_type);
+ cb_result = APP_RESULT_APP_ERR;
+ break;
+ }
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn fms_handle_disconnect_event
+ * @brief Handle disconnect event.
+ * @param void
+ * @return void
+ */
+void fms_handle_disconnect_event(void)
+{
+ Fms_Handle_Notify_Flag = false;
+
+ APP_PRINT_INFO2("[fms_handle_disconnect_event] en_find_me = %d, find_me_wakeup_timeout = %d",
+ app_global_data.en_find_me, app_global_data.find_me_wakeup_timeout);
+
+ /* check and start periodical connention timer */
+ if ((app_global_data.en_find_me == 1)
+ && (app_global_data.find_me_wakeup_timeout >= MIN_FMS_PERIODICAL_CONN_TIMEOUT)
+ && (app_global_data.find_me_wakeup_timeout <= MAX_FMS_PERIODICAL_CONN_TIMEOUT))
+ {
+ os_timer_restart(&Fms_Periodical_Conn_Timer, app_global_data.find_me_wakeup_timeout * 60 * 1000);
+ }
+}
+
+/******************************************************************
+ * @fn fms_handle_connect_event
+ * @brief Handle connect event.
+ * @param void
+ * @return void
+ */
+void fms_handle_connect_event(void)
+{
+ APP_PRINT_INFO0("[fms_handle_connect_event] connection");
+ os_timer_stop(&Fms_Periodical_Conn_Timer);
+}
+
+/******************************************************************
+ * @fn fms_handle_get_current_mode
+ * @brief Get current FMS mode.
+ * @param void
+ * @return uint16_t - current mode
+ */
+uint16_t fms_handle_get_current_mode(void)
+{
+ return Fms_Current_Mode;
+}
+
+/******************************************************************
+ * @fn fms_handle_notify_status
+ * @brief FMS notify status.
+ * @param status, error_code
+ * @return bool - true or false
+ */
+bool fms_handle_notify_status(uint16_t status, uint16_t error_code)
+{
+ bool result = true;
+ uint8_t notify_data[4];
+
+ LE_UINT16_TO_ARRAY(&notify_data[0], status);
+ LE_UINT16_TO_ARRAY(&notify_data[2], error_code);
+
+ if ((app_global_data.rcu_status == RCU_STATUS_PAIRED)
+ && (Fms_Handle_Notify_Flag == true))
+ {
+ result = server_send_data(0, app_global_data.fms_srv_id, GATT_SVC_FMS_DATA_INDEX, notify_data,
+ sizeof(notify_data), GATT_PDU_TYPE_NOTIFICATION);
+ }
+ else
+ {
+ result = false;
+ }
+
+ APP_PRINT_INFO3("[fms_handle_notify_status] result = %d, status = 0x%04X, error_code = 0x%04X",
+ result, status, error_code);
+
+ return result;
+}
+
+/******************************************************************
+ * @brief key handler init timer
+ * @param none
+ * @return none
+ * @retval void
+ */
+void fms_handle_init_timer(void)
+{
+ APP_PRINT_INFO0("[fms_handle_init_timer] init timer");
+
+ /* fms_periodical_conn_callback is used to start advertising after timeout */
+ if (false == os_timer_create(&Fms_Periodical_Conn_Timer, "Fms_Periodical_Conn_Timer", 1, \
+ (DEFAULT_FMS_PERIODICAL_CONN_TIMEOUT * 60 * 1000), false, fms_periodical_conn_callback))
+ {
+ APP_PRINT_ERROR0("[fms_handle_init_timer] Fms_Periodical_Conn_Timer creat failed!");
+ }
+}
+
+#endif
diff --git a/src/app/google_rcu/buzzer_module/fms_service_handle.h b/src/app/google_rcu/buzzer_module/fms_service_handle.h
new file mode 100644
index 0000000..7c17163
--- /dev/null
+++ b/src/app/google_rcu/buzzer_module/fms_service_handle.h
@@ -0,0 +1,57 @@
+/*
+ * Routines to access hardware
+ *
+ * Copyright (c) 2019 Realtek Semiconductor Corp.
+ *
+ * This module is a confidential and proprietary property of RealTek and
+ * possession or use of this module requires written permission of RealTek.
+ */
+
+#ifndef _FMS_HANDLE_H_
+#define _FMS_HANDLE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "fms.h"
+#include "profile_server.h"
+#include "swtimer.h"
+#include "frm_define.h"
+
+/*============================================================================*
+ * Macro Definitions
+ *============================================================================*/
+#define DEFAULT_FMS_PERIODICAL_CONN_TIMEOUT 60 /* 60 minutes */
+#define MIN_FMS_PERIODICAL_CONN_TIMEOUT 0x0005 /* uint: minute */
+#define MAX_FMS_PERIODICAL_CONN_TIMEOUT 0x05A0 /* uint: minute */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+
+/*============================================================================*
+* Export Global Variables
+*============================================================================*/
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void fms_handle_init_data(void);
+T_APP_RESULT fms_handle_srv_cb(T_FMS_CALLBACK_DATA *p_data);
+uint16_t fms_handle_get_current_mode(void);
+void fms_handle_disconnect_event(void);
+void fms_handle_connect_event(void);
+bool fms_handle_notify_status(uint16_t status, uint16_t error_code);
+void fms_handle_init_timer(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/app/google_rcu/dtm_module/rcu_dtm_app.c b/src/app/google_rcu/dtm_module/rcu_dtm_app.c
new file mode 100644
index 0000000..0363f9d
--- /dev/null
+++ b/src/app/google_rcu/dtm_module/rcu_dtm_app.c
@@ -0,0 +1,473 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file dtm_app.c
+* @brief direct test mode implementation.
+* @details
+* @author jeff
+* @date 2016-12-01
+* @version v1.0
+*
+*/
+
+#include "rtl876x_nvic.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_uart.h"
+#include "rcu_gap_dtm.h"
+#include "trace.h"
+#include "board.h"
+#include "rtl876x_gpio.h"
+/** @defgroup DTM_APP Direct Test Mode Application
+ * @brief This file handles commands from 8852B and return with events.
+ * @{
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief Uart initialization
+ * @return void
+ */
+void dtm_uart_init(void)
+{
+ Pinmux_Config(DATA_UART_TX_PIN, UART0_TX);
+ Pinmux_Config(DATA_UART_RX_PIN, UART0_RX);
+
+ Pad_Config(DATA_UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(DATA_UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ UART_InitTypeDef uartInitStruct;
+ UART_StructInit(&uartInitStruct);
+
+ uartInitStruct.rxTriggerLevel = 14;
+ UART_Init(UART0, &uartInitStruct);
+
+ UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+
+ NVIC_InitTypeDef nvic_init_struct;
+ nvic_init_struct.NVIC_IRQChannel = UART0_IRQn;
+ nvic_init_struct.NVIC_IRQChannelCmd = ENABLE;
+ nvic_init_struct.NVIC_IRQChannelPriority = 5;
+ NVIC_Init(&nvic_init_struct);
+
+ return;
+}
+
+/**
+ * @brief Send event to 8852B
+ * @param event events to send
+ * @return void
+ */
+void dtm_uart_send_bytes(uint16_t event)
+{
+ uint8_t uartdata[2] = {0};
+ uartdata[0] = (event & 0xff00) >> 8;
+ uartdata[1] = event & 0xff;
+ uint8_t *p_ch = uartdata;
+
+ uint8_t i = 0;
+ for (i = 0; i < 2; i++)
+ {
+ while (UART_GetFlagState(UART0, UART_FLAG_THR_EMPTY) != SET)
+ {
+ ;
+ }
+ UART_SendData(UART0, p_ch++, 1);
+ }
+}
+
+/**
+ * @brief handle test command from 8852B, then invoke gap api to start test procedure.
+ * @param[in] command commands from 8852B.
+ * @return void
+ */
+void dtm_test_req(uint16_t command)
+{
+ uint8_t contrl = 0;
+ uint8_t param = 0;
+ uint8_t tx_chann = 0;
+ uint8_t rx_chann = 0;
+ uint8_t data_len = 0;
+ uint8_t pkt_pl = 0;
+ uint8_t cmd = (command & 0xc000) >> 14;
+ uint16_t event = 0;
+
+ //the upper 2 bits of the data length for any Transmitter or Receiver commands following
+ static uint8_t up_2_bits = 0;
+ //physical to use
+ static uint8_t phy = 1;
+ //modulation index to use
+ static uint8_t mod_idx = 0;
+ //local supported features
+ static uint8_t lcl_feats[GAP_LE_SUPPORTED_FEATURES_LEN] = {0};
+
+ switch (cmd)
+ {
+ case 0:
+ contrl = (command & 0x3f00) >> 8;
+ param = (command & 0xfc) >> 2;
+
+ switch (contrl)
+ {
+ case 0:
+ if (param == 0)
+ {
+ up_2_bits = 0;
+ phy = 1;
+ mod_idx = 0;
+ }
+ else
+ {
+ event |= 1;
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ case 1:
+ if (param <= 3)
+ {
+ up_2_bits = param;
+ }
+ else
+ {
+ event |= 1;
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ case 2:
+ if (param >= 1 && param <= 4)
+ {
+ phy = (param == 4) ? 3 : param;
+ }
+ else
+ {
+ event |= 1;
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ case 3:
+ if (param == 0 || param == 1)
+ {
+ mod_idx = param;
+ }
+ else
+ {
+ event |= 1;
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ case 4:
+ if (param == 0)
+ {
+ le_get_gap_param(GAP_PARAM_LOCAL_FEATURES, lcl_feats);
+ if (lcl_feats[0] & 0x20)
+ {
+ event |= 0x0002;
+ }
+ if (lcl_feats[1] & 0x01)
+ {
+ event |= 0x0004;
+ }
+ if (lcl_feats[1] & 0x02)
+ {
+ event |= 0x0008;
+ }
+ APP_PRINT_INFO1("dtm_test_req: lcl_feats 0x%x", event);
+ }
+ else
+ {
+ event |= 1;
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ case 5:
+ /*
+ 8852B do not send these commands
+ 0x00 Read supportedMaxTxOctets
+ 0x01 Read supportedMaxTxTime
+ 0x02 Read supportedMaxRxOctets
+ 0x03 Read supportedMaxRxTime
+ */
+ break;
+ default:
+ break;
+ }
+ APP_PRINT_INFO3("dtm_test_req: up_2_bits 0x%x, phy 0x%x, mod_idx 0x%x", up_2_bits, phy, mod_idx);
+ break;
+
+ case 1:
+ rx_chann = (command & 0x3f00) >> 8;
+ APP_PRINT_INFO3("dtm_test_req: rx_channel 0x%x, phy 0x%x, mod_idx 0x%x", rx_chann, phy, mod_idx);
+#if F_BT_LE_5_0_DTM_SUPPORT
+ if (le_dtm_enhanced_receiver_test(rx_chann, phy, mod_idx) != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR0("dtm_test_req: le_dtm_enhanced_receiver_test fail");
+ }
+#else
+ if (le_dtm_receiver_test(rx_chann) != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR0("dtm_test_req: le_dtm_receiver_test fail");
+ }
+#endif
+ break;
+
+ case 2:
+ tx_chann = (command & 0x3f00) >> 8;
+ data_len = up_2_bits << 6 | (command & 0xfc) >> 2;
+ pkt_pl = command & 0x03;
+ if (pkt_pl == 3)
+ {
+ pkt_pl = 4;
+ }
+ APP_PRINT_INFO4("dtm_test_req: tx_channel 0x%x, data_len 0x%x, pkt_pl 0x%x, phy 0x%x", tx_chann,
+ data_len, pkt_pl, phy);
+#if F_BT_LE_5_0_DTM_SUPPORT
+ if (le_dtm_enhanced_transmitter_test(tx_chann, data_len, pkt_pl, phy) != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR0("dtm_test_req: le_dtm_enhanced_transmitter_test fail");
+ }
+#else
+ if (le_dtm_transmitter_test(tx_chann, data_len, pkt_pl) != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR0("dtm_test_req: le_dtm_transmitter_test fail");
+ }
+#endif
+ break;
+
+ case 3:
+ contrl = (command & 0x3f00) >> 8;
+ param = (command & 0xfc) >> 2;
+ if (contrl == 0 && param == 0)
+ {
+ APP_PRINT_INFO0("dtm_test_req: le test end");
+ if (le_dtm_test_end() != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR0("dtm_test_req: le_test_end fail");
+ }
+ }
+ break;
+ }
+}
+
+
+/**
+ * @brief Receive command from 8852B
+ * @return void
+ */
+void UART0_Handler(void)
+{
+ uint8_t uartdata[2] = {0, 0};
+ uint8_t *p = uartdata;
+ uint16_t command = 0;
+ uint32_t int_status = 0;
+ int_status = UART_GetIID(UART0);
+
+ UART_INTConfig(UART0, UART_INT_RD_AVA | UART_INT_LINE_STS, DISABLE);
+
+ switch (int_status)
+ {
+ case UART_INT_ID_TX_EMPTY:
+ break;
+
+ case UART_INT_ID_RX_LEVEL_REACH:
+
+ case UART_INT_ID_RX_TMEOUT:
+ while (UART_GetFlagState(UART0, UART_FLAG_RX_DATA_RDY) == SET)
+ {
+ UART_ReceiveData(UART0, p++, 1);
+ if (p - uartdata > 2)
+ {
+ break;
+ }
+ }
+ command = (uartdata[0] << 8) | uartdata[1];
+ APP_PRINT_INFO1("FORM 8852B: 0x%x", command);
+ dtm_test_req(command);
+ break;
+
+ case UART_INT_ID_LINE_STATUS:
+ break;
+
+ default:
+ break;
+ }
+
+ UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+ return;
+}
+
+/**
+ * @brief function equal to UART0_Handler(void), avoid conflict with system-uart0-interrupt
+ * @return void
+ */
+void dtm_interrupt(void)
+{
+ uint8_t uartdata[2] = {0, 0};
+ uint8_t *p = uartdata;
+ uint16_t command = 0;
+ uint32_t int_status = 0;
+ int_status = UART_GetIID(UART0);
+
+ UART_INTConfig(UART0, UART_INT_RD_AVA | UART_INT_LINE_STS, DISABLE);
+
+ switch (int_status)
+ {
+ case UART_INT_ID_TX_EMPTY:
+ break;
+
+ case UART_INT_ID_RX_LEVEL_REACH:
+
+ case UART_INT_ID_RX_TMEOUT:
+ while (UART_GetFlagState(UART0, UART_FLAG_RX_DATA_RDY) == SET)
+ {
+ UART_ReceiveData(UART0, p++, 1);
+ if (p - uartdata > 2)
+ {
+ break;
+ }
+ }
+ command = (uartdata[0] << 8) | uartdata[1];
+ APP_PRINT_INFO1("FORM 8852B: 0x%x", command);
+ dtm_test_req(command);
+ break;
+
+ case UART_INT_ID_LINE_STATUS:
+ break;
+
+ default:
+ break;
+ }
+
+ UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+ return;
+}
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type
+ * @param[in] p_cb_data point to callback data
+ * @retval result
+ */
+T_APP_RESULT dtm_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+ uint16_t status = 0;
+ uint16_t event = 0;
+ APP_PRINT_INFO1("dtm_gap_callback: cb_type %d", cb_type);
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DTM_RECEIVER_TEST:
+#if F_BT_LE_5_0_DTM_SUPPORT
+ case GAP_MSG_LE_DTM_ENHANCED_RECEIVER_TEST:
+#endif
+ status = p_data->le_cause.cause;
+ if (status == 0)
+ {
+ APP_PRINT_INFO2("dtm_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("dtm_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+
+ case GAP_MSG_LE_DTM_TRANSMITTER_TEST:
+#if F_BT_LE_5_0_DTM_SUPPORT
+ case GAP_MSG_LE_DTM_ENHANCED_TRANSMITTER_TEST:
+#endif
+ status = p_data->le_cause.cause;
+ if (status == 0)
+ {
+ APP_PRINT_INFO2("dtm_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("dtm_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+
+ case GAP_MSG_LE_DTM_TEST_END:
+ status = p_data->p_le_dtm_test_end_rsp->cause;
+ if (status == 0)
+ {
+ event |= 1 << 15;
+ event |= p_data->p_le_dtm_test_end_rsp->num_pkts;
+ APP_PRINT_INFO2("dtm_gap_callback: event 0x%x, packet count 0x%x", (event & 0x8000) >> 15,
+ event & 0x7fff);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("dtm_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ }
+
+ return result;
+}
+
+/******************************************************************
+ * @brief config dtm MODE_PIN PAD
+ * @param none
+ * @return none
+ * @retval void
+ */
+void gpio_dtm_pad_config(void)
+{
+ Pad_Config(MODE_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
+}
+
+/******************************************************************
+ * @brief config dtm MODE_PIN pinmux
+ * @param none
+ * @return none
+ * @retval void
+ */
+void gpio_dtm_pinmux_config(void)
+{
+ Pinmux_Config(MODE_PIN, DWGPIO);
+}
+
+/******************************************************************
+ * @brief init dtm MODE_PIN
+ * @param none
+ * @return none
+ * @retval void
+ */
+void dtm_gpio_init(void)
+{
+ /* Enable GPIO and hardware timer's clock */
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+
+ /* Initialize GPIO29 P4_1*/
+ GPIO_InitTypeDef GPIO_Param;
+ GPIO_StructInit(&GPIO_Param);
+ GPIO_Param.GPIO_Pin = GPIO_GetPin(MODE_PIN);
+ GPIO_Param.GPIO_Mode = GPIO_Mode_IN;
+ GPIO_Param.GPIO_ITCmd = DISABLE;
+ GPIO_Param.GPIO_ITTrigger = GPIO_INT_Trigger_EDGE;
+ GPIO_Param.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW;
+ GPIO_Param.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_ENABLE;
+ GPIO_Param.GPIO_DebounceTime = 20;
+ GPIO_Init(&GPIO_Param);
+
+ /* Enable interrupt */
+ GPIO_INTConfig(GPIO_GetPin(MODE_PIN), ENABLE);
+ GPIO_MaskINTConfig(GPIO_GetPin(MODE_PIN), DISABLE);
+
+}
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/app/google_rcu/dtm_module/rcu_gap_dtm.h b/src/app/google_rcu/dtm_module/rcu_gap_dtm.h
new file mode 100644
index 0000000..f92d837
--- /dev/null
+++ b/src/app/google_rcu/dtm_module/rcu_gap_dtm.h
@@ -0,0 +1,563 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gap_dtm.h
+ * @brief
+ * @details
+ * @author jeff_zheng
+ * @date 2017-08-02
+ * @version v1.0
+ ******************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ ******************************************************************************
+ */
+/* Define to prevent recursive inclusion **/
+#ifndef GAP_DTM_H
+#define GAP_DTM_H
+
+#include "upperstack_config.h"
+#include "gap_le.h"
+#include <gap_le_types.h>
+
+void dtm_interrupt(void);
+void dtm_uart_init(void);
+T_APP_RESULT dtm_gap_callback(uint8_t cb_type, void *p_cb_data);
+#if F_BT_LE_4_0_DTM_SUPPORT
+/** @addtogroup GAP_LE_DTM GAP LE Direct Test Mode Module
+ * @brief GAP LE Direct Test Mode Module
+ * @{
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup GAP_LE_DTM_Exported_Types GAP LE DTM Exported Types
+ * @brief
+ * @{
+ */
+typedef enum
+{
+ GAP_DTM_MODULATION_INDEX_STANDARD = 0x00, /**< Assume transmitter will have a standard modulation index. */
+ GAP_DTM_MODULATION_INDEX_STABLE = 0x01, /**< Assume transmitter will have a stable modulation index. */
+} T_GAP_DTM_MODULATION_INDEX_TYPE;
+
+typedef enum
+{
+ GAP_DTM_PACKET_PAYLOAD_PRBS9 = 0x00, /**< PRBS9 sequence '11111111100000111101' (in transmission order). */
+ GAP_DTM_PACKET_PAYLOAD_1100 = 0x01, /**< Repeated '11110000' (in transmission order) sequence. */
+ GAP_DTM_PACKET_PAYLOAD_10 = 0x02, /**< Repeated '10101010' (in transmission order) sequence. */
+ GAP_DTM_PACKET_PAYLOAD_PRBS15 = 0x03, /**< PRBS15 sequence. */
+ GAP_DTM_PACKET_PAYLOAD_ALL1 = 0x04, /**< Repeated '11111111' (in transmission order) sequence. . */
+ GAP_DTM_PACKET_PAYLOAD_ALL0 = 0x05, /**< Repeated '00000000' (in transmission order) sequence. . */
+ GAP_DTM_PACKET_PAYLOAD_0011 = 0x06, /**< Repeated '00001111' (in transmission order) sequence. . */
+ GAP_DTM_PACKET_PAYLOAD_01 = 0x07 /**< Repeated '01010101' (in transmission order) sequence. . */
+} T_GAP_DTM_PACKET_PAYLOAD_TYPE;
+
+typedef enum
+{
+ GAP_DTM_PHYS_1M = 0x01, /**< LE PHY 1M used. */
+ GAP_DTM_PHYS_2M = 0x02, /**< LE PHY 2M used. */
+ GAP_DTM_PHYS_CODED_S8 = 0x03, /**< LE Coded PHY with S=8 data coding. */
+ GAP_DTM_PHYS_CODED_S2 = 0x04, /**< LE Coded PHY with S=2 data coding. */
+} T_GAP_DTM_PHYS_TYPE;
+
+/** End of GAP_LE_DTM_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/** @defgroup GAP_LE_DTM_Exported_Functions GAP LE Direct Test Mode Exported Functions
+ * @brief GAP LE Direct Test Mode Exported Functions
+ * @{
+ */
+
+/**
+* @brief Start a test where the DUT receives test reference packets at a fixed interval.
+ The tester generates the test reference packets.
+*
+* @param[in] rx_chann - channel to receive packets.
+*
+* @retval GAP_CAUSE_SUCCESS: Operation success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ rx_chann = (command & 0x3f00) >> 8;
+ le_dtm_receiver_test_req(rx_chann);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_DTM_RECEIVER_TEST:
+ status = p_data->p_le_receive_test_rsp->cause;
+ if (status == 0)
+ {
+ APP_PRINT_INFO2("dtm_event_trace: ev = 0x%x, st = 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("dtm_evt_trace: EV = 0x%x, st = 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_dtm_receiver_test(uint8_t rx_chann);
+
+/**
+* @brief Start a test where the DUT generates test reference packets at a fixed interval.
+ The Controller shall transmit at maximum power.
+*
+* @param[in] tx_chann - channel to transmit packets.
+* @param[in] data_len - length in bytes of payload data in each packet.
+* @param[in] pkt_pl - the value of packet payload.
+*
+* @retval GAP_CAUSE_SUCCESS: Operation success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ tx_chann = (command & 0x3f00) >> 8;
+ data_len = up_2_bits << 6 | (command & 0xfc) >> 2;
+ pkt_pl = command & 0x03;
+ le_dtm_transmitter_test(tx_chann, data_len, pkt_pl);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_DTM_TRANSMITTER_TEST:
+ status = p_data->le_cause.cause;
+ if (status == 0)
+ {
+ APP_PRINT_INFO2("dtm_evt_trace: ev = 0x%x, st = 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("dtm_evt_trace: st = 0x%x, st = 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+
+T_GAP_CAUSE le_dtm_transmitter_test(uint8_t tx_chann, uint8_t data_len, uint8_t pkt_pl);
+
+/**
+* @brief Stop any test which is in progress.
+*
+* @retval GAP_CAUSE_SUCCESS: Operation success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ ...
+ le_dtm_test_end();
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_DTM_TEST_END:
+ status = p_data->p_le_dtm_test_end_rsp->cause;
+ if (status == 0)
+ {
+ event |= 1 << 15;
+ event |= p_data->p_le_dtm_test_end_rsp->num_pkts;
+ APP_PRINT_INFO2("dtm_evt_trace: ev = 0x%x, packet count = 0x%x", (event & 0x8000) >> 15,
+ event & 0x7fff);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("dtm_evt_trace: ev = 0x%x, st = 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ }
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_dtm_test_end(void);
+
+#if F_BT_LE_5_0_DTM_SUPPORT
+/**
+* @brief Start a test where the DUT receives test reference packets at a fixed interval.
+*
+* @param[in] rx_chann - channel to receive packets.
+* @param[in] phy - physical to receive packets.
+* @param[in] mod_idx - modulation index to receive packets.
+*
+* @retval GAP_CAUSE_SUCCESS: Operation success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ static uint8_t phy = 1;
+ static uint8_t mod_idx = 0;
+ rx_chann = (command & 0x3f00) >> 8;
+#if F_BT_LE_5_0_SUPPORT
+ if (le_dtm_enhanced_receiver_test(rx_chann, phy, mod_idx) != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR0("dtm_test_req: le_dtm_enhanced_receiver_test fail");
+ }
+#endif
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+#if F_BT_LE_5_0_SUPPORT
+ case GAP_MSG_LE_DTM_ENHANCED_RECEIVER_TEST:
+#endif
+ status = p_data->le_cause.cause;
+ if (status == 0)
+ {
+ APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_dtm_enhanced_receiver_test(uint8_t rx_chann, uint8_t phy, uint8_t mod_idx);
+
+/**
+* @brief Start a test where the DUT generates test reference packets at a fixed interval.
+*
+* @param[in] tx_chann - Channel to transmit packets.
+* @param[in] data_len - Length in bytes of payload data in each packet.
+* @param[in] pkt_pl - the value of packet payload.
+* @param[in] phy - physical to transmit packets.
+*
+* @retval GAP_CAUSE_SUCCESS: Operation success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ static uint8_t phy = 1;
+ tx_chann = (command & 0x3f00) >> 8;
+ data_len = up_2_bits << 6 | (command & 0xfc) >> 2;
+ pkt_pl = command & 0x03;;
+#if F_BT_LE_5_0_SUPPORT
+ if (le_dtm_enhanced_transmitter_test(tx_chann, data_len, pkt_pl, phy) != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR0("dtm_test_req: le_dtm_enhanced_transmitter_test fail");
+ }
+#endif
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+#if F_BT_LE_5_0_SUPPORT
+ case GAP_MSG_LE_DTM_ENHANCED_TRANSMITTER_TEST:
+#endif
+ status = p_data->le_cause.cause;
+ if (status == 0)
+ {
+ APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+
+ ...
+ }
+ * \endcode
+ */
+
+T_GAP_CAUSE le_dtm_enhanced_transmitter_test(uint8_t tx_chann, uint8_t data_len, uint8_t pkt_pl,
+ uint8_t phy);
+#endif
+
+#if F_BT_LE_5_1_DTM_SUPPORT
+/**
+* @brief Start a test where the DUT receives test reference packets at a fixed interval.
+*
+* @param[in] rx_chann - channel to receive packets.
+ Range: 0x00 to 0x27.
+* @param[in] phy - physical to receive packets: @ref T_GAP_PHYS_TYPE.
+* @param[in] modulation_index - modulation index to receive packets: @ref T_GAP_DTM_MODULATION_INDEX_TYPE.
+* @param[in] expected_cte_length - the expected length of the Constant Tone Extensions in received
+ test reference packets.
+ Range: 0x00 (No Constant Tone Extension expected (default)) or 0x02 to 0x14.
+ Units: 8 us.
+* @param[in] expected_cte_type - the expected type of the Constant Tone Extensions in received
+ test reference packets: @ref T_GAP_CTE_TYPE.
+* @param[in] slot_durations - modulation index to receive packets and shall be ignored when expected_cte_type
+ is not set to GAP_CTE_TYPE_AOA: @ref T_GAP_SLOT_DUATIONS_TYPE.
+* @param[in] switching_pattern_length - the number of Antenna IDs in the pattern and shall be ignored when
+ expected_cte_type is not set to GAP_CTE_TYPE_AOA.
+ Range: 0x02 to max_switching_pattern_length supported by controller
+ max_switching_pattern_length shall be less than or equal to 0x4B.
+* @param[in] p_antenna_ids - Antenna ID in the pattern and shall be ignored when expected_cte_type
+ is not set to GAP_CTE_TYPE_AOA.
+*
+* @retval GAP_CAUSE_SUCCESS: Send request success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ uint8_t rx_channel = 0;
+ T_GAP_PHYS_TYPE phy = GAP_PHYS_1M;
+ T_GAP_DTM_MODULATION_INDEX_TYPE modulation_index = GAP_DTM_MODULATION_INDEX_STANDARD;
+ uint8_t expected_cte_length = 2;
+ T_GAP_CTE_TYPE expected_cte_type = GAP_CTE_TYPE_AOA;
+ T_GAP_SLOT_DUATIONS_TYPE slot_durations = GAP_SLOT_DURATIONS_SWITCH_SAMPLE_1US;
+ uint8_t switching_pattern_length = 2;
+ uint8_t p_antenna_ids[2] = {0, 1};
+
+ le_dtm_receiver_test_v3(rx_channel, phy, modulation_index, expected_cte_length,
+ expected_cte_type, slot_durations,
+ switching_pattern_length, p_antenna_ids);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_DTM_RECEIVER_TEST_V3:
+ APP_PRINT_INFO1("GAP_MSG_LE_DTM_RECEIVER_TEST_V3: cause 0x%x",
+ p_data->le_cause.cause);
+ break;
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_dtm_receiver_test_v3(uint8_t rx_channel, T_GAP_PHYS_TYPE phy,
+ T_GAP_DTM_MODULATION_INDEX_TYPE modulation_index,
+ uint8_t expected_cte_length, T_GAP_CTE_TYPE expected_cte_type,
+ T_GAP_SLOT_DUATIONS_TYPE slot_durations,
+ uint8_t switching_pattern_length, uint8_t *p_antenna_ids);
+
+/**
+* @brief Start a test where the DUT transmits test reference packets at a fixed interval.
+*
+* @param[in] tx_channel - channel to transmit packets.
+ Range: 0x00 to 0x27.
+* @param[in] test_data_length - length in bytes of payload data in each packet.
+ Range: 0x00 to 0xFF.
+* @param[in] packet_payload - contents of the payload of the test reference packets:
+* @ref T_GAP_DTM_PACKET_PAYLOAD_TYPE.
+* @param[in] phy - physical to transmit packets: @ref T_GAP_DTM_PHYS_TYPE.
+* @param[in] cte_length - the length of the Constant Tone Extension in the test reference packets.
+ Range: 0x00 (Do not transmit a Constant Tone Extension) or 0x02 to 0x14.
+ Units: 8 us.
+* @param[in] cte_type - the type of the Constant Tone Extension in the test reference packets.
+ @ref T_GAP_CTE_TYPE.
+* @param[in] switching_pattern_length - the number of Antenna IDs in the pattern and shall be ignored when
+ cte_type is set to GAP_CTE_TYPE_AOA.
+ Range: 0x02 to max_switching_pattern_length supported by controller
+ max_switching_pattern_length shall be less than or equal to 0x4B.
+* @param[in] p_antenna_ids - Antenna ID in the pattern and shall be ignored when expected_cte_type
+* is set to GAP_CTE_TYPE_AOA.
+*
+* @retval GAP_CAUSE_SUCCESS: Send request success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ uint8_t tx_channel = 0;
+ uint8_t test_data_length = 2;
+ T_GAP_DTM_PACKET_PAYLOAD_TYPE packet_payload = GAP_DTM_PACKET_PAYLOAD_PRBS9;
+ T_GAP_DTM_PHYS_TYPE phy = GAP_DTM_PHYS_1M;
+ uint8_t cte_length = 2;
+ T_GAP_CTE_TYPE cte_type = GAP_CTE_TYPE_AOD_2US_SLOT;
+ uint8_t switching_pattern_length = 2;
+ uint8_t p_antenna_ids[2] = {0, 1};
+
+ le_dtm_transmitter_test_v3(tx_channel, test_data_length,
+ packet_payload, phy, cte_length, cte_type,
+ switching_pattern_length, p_antenna_ids);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_DTM_TRANSMITTER_TEST_V3:
+ APP_PRINT_INFO1("GAP_MSG_LE_DTM_TRANSMITTER_TEST_V3: cause 0x%x",
+ p_data->le_cause.cause);
+ break;
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_dtm_transmitter_test_v3(uint8_t tx_channel, uint8_t test_data_length,
+ T_GAP_DTM_PACKET_PAYLOAD_TYPE packet_payload, T_GAP_DTM_PHYS_TYPE phy,
+ uint8_t cte_length, T_GAP_CTE_TYPE cte_type,
+ uint8_t switching_pattern_length, uint8_t *p_antenna_ids);
+#endif
+
+#if F_BT_LE_5_2_DTM_SUPPORT
+/**
+* @brief Start a test where the DUT transmits test reference packets at a fixed interval.
+*
+* @param[in] tx_channel - channel to transmit packets.
+ N = (F-2402) / 2
+ Range: 0x00 to 0x27
+ Frequency Range: 2402 MHz to 2480 MHz.
+* @param[in] test_data_length - length in bytes of payload data in each packet.
+ Range: 0x00 to 0xFF.
+* @param[in] packet_payload - contents of the payload of the test reference packets:
+* @ref T_GAP_DTM_PACKET_PAYLOAD_TYPE.
+* @param[in] phy - physical to transmit packets: @ref T_GAP_DTM_PHYS_TYPE.
+* @param[in] cte_length - the length of the Constant Tone Extension in the test reference packets.
+ 0x00: Do not transmit a Constant Tone Extension
+ 0x02 to 0x14: Length of the Constant Tone Extension in 8 us units.
+* @param[in] cte_type - the type of the Constant Tone Extension in the test reference packets.
+ @ref T_GAP_CTE_TYPE.
+* @param[in] switching_pattern_length - the number of Antenna IDs in the pattern and shall be ignored when
+ cte_type is set to GAP_CTE_TYPE_AOA.
+ Range: 0x02 to max_switching_pattern_length supported by controller
+ max_switching_pattern_length shall be less than or equal to 0x4B.
+* @param[in] p_antenna_ids - Antenna ID in the pattern and shall be ignored when expected_cte_type
+* is set to GAP_CTE_TYPE_AOA.
+* @param[in] tx_power_level - set transmitter to the specified or the nearest transmit power level.
+ Range: -127 to +20.
+ Units: dBm.
+ Note: 0x7E Set transmitter to minimum transmit power level.
+ 0x7F Set transmitter to maximum transmit power level.
+*
+* @retval GAP_CAUSE_SUCCESS: Send request success.
+* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void dtm_test_req(uint16_t command)
+ {
+ uint8_t tx_channel = 0;
+ uint8_t test_data_length = 2;
+ T_GAP_DTM_PACKET_PAYLOAD_TYPE packet_payload = GAP_DTM_PACKET_PAYLOAD_PRBS9;
+ T_GAP_DTM_PHYS_TYPE phy = GAP_DTM_PHYS_1M;
+ uint8_t cte_length = 2;
+ T_GAP_CTE_TYPE cte_type = GAP_CTE_TYPE_AOD_2US_SLOT;
+ uint8_t switching_pattern_length = 2;
+ uint8_t p_antenna_ids[2] = {0, 1};
+ int8_t tx_power_level = 0x10;
+
+ le_dtm_transmitter_test_v3(tx_channel, test_data_length,
+ packet_payload, phy, cte_length, cte_type,
+ switching_pattern_length, p_antenna_ids, tx_power_level);
+ }
+
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ uint16_t status = 0;
+ uint16_t event = 0;
+ switch (cb_type)
+ {
+ ...
+ case GAP_MSG_LE_DTM_TRANSMITTER_TEST_V4:
+ APP_PRINT_INFO1("GAP_MSG_LE_DTM_TRANSMITTER_TEST_V4: cause 0x%x",
+ p_data->le_cause.cause);
+ break;
+ ...
+ }
+ * \endcode
+ */
+T_GAP_CAUSE le_dtm_transmitter_test_v4(uint8_t tx_channel, uint8_t test_data_length,
+ T_GAP_DTM_PACKET_PAYLOAD_TYPE packet_payload, T_GAP_DTM_PHYS_TYPE phy,
+ uint8_t cte_length, T_GAP_CTE_TYPE cte_type,
+ uint8_t switching_pattern_length, uint8_t *p_antenna_ids, int8_t tx_power_level);
+#endif
+/** End of GAP_LE_DTM_Exported_Functions
+ * @}
+ */
+
+/** End of GAP_LE_DTM
+ * @}
+ */
+#endif
+
+#endif /* GAP_DTM_H */
diff --git a/src/app/google_rcu/frm_vpk/frm_define.h b/src/app/google_rcu/frm_vpk/frm_define.h
new file mode 100644
index 0000000..7262142
--- /dev/null
+++ b/src/app/google_rcu/frm_vpk/frm_define.h
@@ -0,0 +1,58 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file frm_define.h
+* @brief header file of framework defines.
+* @details
+* @author chenjie_jin
+* @date 2022-03-09
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+
+#ifndef _FRM_DEFINE_H_
+#define _FRM_DEFINE_H_
+
+#include "otp_config.h"
+#include "flash_map.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _attribute_data_retention_
+
+/* exact-width signed integer types */
+typedef signed char s8;
+typedef signed short int s16;
+typedef signed int s32;
+
+/* exact-width unsigned integer types */
+typedef unsigned char u8;
+typedef unsigned short int u16;
+typedef unsigned int u32;
+
+
+#define U16_HI(a) (((a) >> 8) & 0xFF)
+#define U16_LO(a) ((a) & 0xFF)
+
+#define FLASH_SECTOR_SIZE (4*1024)
+#define FLASH_BLOCK_SIZE (64*1024)
+
+#define APP_CUSTOM_ADDR (BKP_DATA1_ADDR + FLASH_SECTOR_SIZE * 0)
+#define APP_FMS_WAKEUP_INTERVAL (APP_CUSTOM_ADDR + 0xF9)
+#define APP_EN_FIND_ME (APP_CUSTOM_ADDR + 0xFB)
+#define APP_EN_RPA (APP_CUSTOM_ADDR + 0xFC)
+#define APP_EN_BLE_FEATURE (APP_CUSTOM_ADDR + 0xFD)
+#define APP_EN_GOOGLE_WAKEUPPACK (APP_CUSTOM_ADDR + 0xFE)
+#define APP_EN_CACHEKEY (APP_CUSTOM_ADDR + 0xFF)
+#define APP_NEC_IR_CODE_TABLE (BKP_DATA1_ADDR + FLASH_SECTOR_SIZE * 1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FRM_DEFINE_H_ */
+
diff --git a/src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_hal_sflash.c b/src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_hal_sflash.c
new file mode 100644
index 0000000..00f0b86
--- /dev/null
+++ b/src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_hal_sflash.c
@@ -0,0 +1,109 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2021, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file frm_vpk_hal_sflash.c
+* @brief frm vpk flash API implementation
+* @details
+* @author chenjie
+* @date 2021-01-09
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "frm_vpk_hal_sflash.h"
+#include "flash_device.h"
+#include "frm_vpk_log.h"
+#include "dfu_flash.h"
+
+/*============================================================================*
+ * Macro Definitions
+ *============================================================================*/
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+
+/*============================================================================*
+ * Global functions
+ *============================================================================*/
+/**
+ * @brief This function reads the content from a page to the buf.
+ * @param[in] addr - the start address of the page.
+ * @param[in] len - the length(in byte) of content needs to read out from the page.
+ * @param[out] buf - the start address of the buffer.
+ * @return none.
+ * @note Attention: Before calling the FLASH function, please check the power supply voltage of the chip.
+ * Only if the detected voltage is greater than the safe voltage value, the FLASH function can be called.
+ * Taking into account the factors such as power supply fluctuations, the safe voltage value needs to be greater
+ * than the minimum chip operating voltage. For the specific value, please make a reasonable setting according
+ * to the specific application and hardware circuit.
+ *
+ * Risk description: When the chip power supply voltage is relatively low, due to the unstable power supply,
+ * there may be a risk of error in the operation of the flash (especially for the write and erase operations.
+ * If an abnormality occurs, the firmware and user data may be rewritten, resulting in the final Product failure)
+ */
+void frm_vpk_flash_read_page(unsigned long addr, unsigned long len, unsigned char *buf)
+{
+ bool result = false;
+ result = flash_read_locked((addr | FLASH_OFFSET_TO_NO_CACHE), len, buf);
+ frm_vpk_print("[frm_vpk_flash_read_page]: addr=%x, len=%d, result=%d(1:success)", addr, len,
+ result);
+}
+
+/**
+ * @brief This function writes the buffer's content to the flash.
+ * @param[in] addr - the start address of the area.
+ * @param[in] len - the length(in byte) of content needs to write into the flash.
+ * @param[in] buf - the start address of the content needs to write into.
+ * @return none.
+ * @note the function support cross-page writing,which means the len of buf can bigger than 256.
+ *
+ * Attention: Before calling the FLASH function, please check the power supply voltage of the chip.
+ * Only if the detected voltage is greater than the safe voltage value, the FLASH function can be called.
+ * Taking into account the factors such as power supply fluctuations, the safe voltage value needs to be greater
+ * than the minimum chip operating voltage. For the specific value, please make a reasonable setting according
+ * to the specific application and hardware circuit.
+ *
+ * Risk description: When the chip power supply voltage is relatively low, due to the unstable power supply,
+ * there may be a risk of error in the operation of the flash (especially for the write and erase operations.
+ * If an abnormality occurs, the firmware and user data may be rewritten, resulting in the final Product failure)
+ */
+void frm_vpk_flash_write_page(unsigned long addr, unsigned long len, unsigned char *buf)
+{
+ bool result = false;
+
+ unlock_flash_bp_all();
+ result = flash_write_locked((addr | FLASH_OFFSET_TO_NO_CACHE), len, buf);
+ lock_flash_bp();
+
+ frm_vpk_print("[frm_vpk_flash_write_page]: addr=%x, len=%d, result=%d(1:success)", addr, len,
+ result);
+}
+
+/**
+ * @brief This function serves to erase a sector.
+ * @param[in] addr - the start address of the sector needs to erase.
+ * @return none.
+ * @note Attention: Before calling the FLASH function, please check the power supply voltage of the chip.
+ * Only if the detected voltage is greater than the safe voltage value, the FLASH function can be called.
+ * Taking into account the factors such as power supply fluctuations, the safe voltage value needs to be greater
+ * than the minimum chip operating voltage. For the specific value, please make a reasonable setting according
+ * to the specific application and hardware circuit.
+ *
+ * Risk description: When the chip power supply voltage is relatively low, due to the unstable power supply,
+ * there may be a risk of error in the operation of the flash (especially for the write and erase operations.
+ * If an abnormality occurs, the firmware and user data may be rewritten, resulting in the final Product failure)
+ */
+void frm_vpk_flash_erase_sector(unsigned long addr)
+{
+ bool result = false;
+ result = flash_erase_locked(FLASH_ERASE_SECTOR, addr);
+ frm_vpk_print("[frm_vpk_flash_erase_sector]: addr=%x, result=%d(1:success)", addr, result);
+}
+
+/******************* (C) COPYRIGHT 2021 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_hal_sflash.h b/src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_hal_sflash.h
new file mode 100644
index 0000000..c53fc8e
--- /dev/null
+++ b/src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_hal_sflash.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020, Amazon.
+ */
+
+/** @file
+*
+* List of parameters and defined functions needed to access the
+* Serial Flash interface driver.
+*
+*/
+
+#ifndef __FRM_VPK_SFLASH_H__
+#define __FRM_VPK_SFLASH_H__
+
+void frm_vpk_flash_read_page(unsigned long addr, unsigned long len, unsigned char *buf);
+void frm_vpk_flash_write_page(unsigned long addr, unsigned long len, unsigned char *buf);
+void frm_vpk_flash_erase_sector(unsigned long addr);
+
+#endif // __FRM_VPK_SFLASH_H__
diff --git a/src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_log.c b/src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_log.c
new file mode 100644
index 0000000..22c1f78
--- /dev/null
+++ b/src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_log.c
@@ -0,0 +1,65 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2021, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file frm_vpk_log.c
+* @brief frm vpk log API implementation
+* @details
+* @author chenjie
+* @date 2021-01-20
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdio.h>
+#include <stdarg.h>
+#include "frm_vpk_log.h"
+#include "trace.h"
+#include "app_section.h"
+
+
+/*============================================================================*
+ * Macro Definitions
+ *============================================================================*/
+#define MAX_LOG_MESSAGE_LEN 120
+
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+int frm_vpk_print(char *fmt, ...) DATA_RAM_FUNCTION;
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+
+/*============================================================================*
+ * Global functions
+ *============================================================================*/
+/**
+ * @brief API implements the console log printing.
+ *
+ */
+int frm_vpk_print(char *fmt, ...)
+{
+#if 0
+ APP_PRINT_INFO1("[frm_vpk_print] fmt is %s", TRACE_STRING(fmt));
+#endif
+
+ int ret_value;
+ char print_str[MAX_LOG_MESSAGE_LEN];
+ va_list args;
+ va_start(args, fmt);
+
+ ret_value = vsprintf(print_str, (const char *)fmt, args);
+ APP_PRINT_INFO1("%s", TRACE_STRING(print_str));
+
+ va_end(args);
+
+ return ret_value;
+}
+
+/******************* (C) COPYRIGHT 2021 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_log.h b/src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_log.h
new file mode 100644
index 0000000..9f4b18b
--- /dev/null
+++ b/src/app/google_rcu/frm_vpk/frm_vpk_api/frm_vpk_log.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2020, Amazon.
+ */
+
+/** @file
+*
+* List of parameters and defined functions needed to access the
+* log service.
+*
+*/
+#ifndef _FRM_VPK_LOG_H_
+#define _FRM_VPK_LOG_H_
+
+/**
+ * @brief API implements the console log printing.
+ *
+ */
+int frm_vpk_print(char *fmt, ...);
+
+#endif /* _FRM_VPK_LOG_H_ */
diff --git a/src/app/google_rcu/frm_vpk/src/app_custom.c b/src/app/google_rcu/frm_vpk/src/app_custom.c
new file mode 100644
index 0000000..39a1d4f
--- /dev/null
+++ b/src/app/google_rcu/frm_vpk/src/app_custom.c
@@ -0,0 +1,596 @@
+/******************************************************************************
+ * @file app_custom.c
+ *
+ * @brief for TLSR chips
+ *
+ * @author public@telink-semi.com;
+ * @date Sep. 30, 2010
+ *
+ * @attention
+ *
+ * Copyright (C) 2019-2020 Telink Semiconductor (Shanghai) Co., Ltd.
+ *
+ * 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.
+ *
+ *****************************************************************************/
+#include "board.h"
+#include "string.h"
+#include "app_custom.h"
+#include "frm_vpk_log.h"
+#include "frm_vpk_hal_sflash.h"
+#include "key_handle.h"
+#include "rcu_application.h"
+
+const u8 *pREMOTE_G10 = (u8 *)("RemoteG10");
+const u8 *pREMOTE_G20 = (u8 *)("RemoteG20");
+
+#define LAYOUT_MASK_BIT0 0X01
+#define LAYOUT_MASK_BIT1 0X02
+#define LAYOUT_MASK_BIT2 0X04
+#define LAYOUT_MASK_BIT5 0X20
+
+
+void app_custom_ui_layout(u8 ui_layout)
+{
+ uint8_t row_id;
+ uint8_t col_id;
+
+ frm_vpk_print("ui_layout=%x\r\n", ui_layout);
+ if ((ui_layout == 0xff) || (ui_layout == 0))
+ {
+ return;
+ }
+ if (app_global_data.device_type == REMOTE_G10)
+ {
+ if ((ui_layout & LAYOUT_MASK_BIT0))
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G10[0] / KEYPAD_MAX_COLUMN_SIZE_G10;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G10[0] % KEYPAD_MAX_COLUMN_SIZE_G10;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Dashboard;
+ Ir_Override_Table_Index_G10[Ir_Table_Correspend_Index_G10[0]] = KEY_ID_Dashboard;
+ }
+ else
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G10[0] / KEYPAD_MAX_COLUMN_SIZE_G10;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G10[0] % KEYPAD_MAX_COLUMN_SIZE_G10;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Settings;
+ Ir_Override_Table_Index_G10[Ir_Table_Correspend_Index_G10[0]] = KEY_ID_Settings;
+ }
+
+ if ((ui_layout & LAYOUT_MASK_BIT1))
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G10[1] / KEYPAD_MAX_COLUMN_SIZE_G10;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G10[1] % KEYPAD_MAX_COLUMN_SIZE_G10;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Live;
+ Ir_Override_Table_Index_G10[Ir_Table_Correspend_Index_G10[1]] = KEY_ID_Live;
+ }
+ else
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G10[1] / KEYPAD_MAX_COLUMN_SIZE_G10;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G10[1] % KEYPAD_MAX_COLUMN_SIZE_G10;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Guide;
+ Ir_Override_Table_Index_G10[Ir_Table_Correspend_Index_G10[1]] = KEY_ID_Guide;
+ }
+
+ if ((ui_layout & 0x18) == 0x08)
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G10[2] / KEYPAD_MAX_COLUMN_SIZE_G10;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G10[2] % KEYPAD_MAX_COLUMN_SIZE_G10;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Profile;
+ Ir_Override_Table_Index_G10[Ir_Table_Correspend_Index_G10[2]] = KEY_ID_Profile;
+ }
+ else if ((ui_layout & 0x18) == 0x10)
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G10[2] / KEYPAD_MAX_COLUMN_SIZE_G10;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G10[2] % KEYPAD_MAX_COLUMN_SIZE_G10;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_AllApps;
+ Ir_Override_Table_Index_G10[Ir_Table_Correspend_Index_G10[2]] = KEY_ID_AllApps;
+ }
+ }
+ else
+ {
+ if ((ui_layout & LAYOUT_MASK_BIT0))
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[0] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[0] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Dashboard;
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[0]] = KEY_ID_Dashboard;
+ }
+ else
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[0] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[0] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Settings;
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[0]] = KEY_ID_Settings;
+ }
+
+ if ((ui_layout & LAYOUT_MASK_BIT1))
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[1] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[1] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Live;
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[1]] = KEY_ID_Live;
+ }
+ else
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[1] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[1] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Guide;
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[1]] = KEY_ID_Guide;
+ }
+
+ if ((ui_layout & LAYOUT_MASK_BIT2))
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[2] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[2] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_TEXT;
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[2]] = KEY_ID_TEXT;
+ }
+ else
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[2] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[2] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Subtitles;
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[2]] = KEY_ID_Subtitles;
+ }
+
+ if ((ui_layout & 0x18) == 0x08)
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[3] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[3] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Profile;
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[3]] = KEY_ID_Profile;
+ }
+ else if ((ui_layout & 0x18) == 0x10)
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[3] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[3] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_AllApps;
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[3]] = KEY_ID_AllApps;
+ }
+
+ if ((ui_layout & LAYOUT_MASK_BIT5))
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[4] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[4] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_FastRewind;
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[5] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[5] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Record;
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[6] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[6] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_PlayPause;
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[7] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[7] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_FastForward;
+
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[4]] = KEY_ID_FastRewind;
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[5]] = KEY_ID_Record;
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[6]] = KEY_ID_PlayPause;
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[7]] = KEY_ID_FastForward;
+ }
+ else
+ {
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[4] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[4] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Red;
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[5] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[5] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Green;
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[6] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[6] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Yellow;
+ row_id = Kb_Map_devicelayout_Correspend_Index_G20[7] / KEYPAD_MAX_COLUMN_SIZE_G20;
+ col_id = Kb_Map_devicelayout_Correspend_Index_G20[7] % KEYPAD_MAX_COLUMN_SIZE_G20;
+ key_handle_global_data.cur_key_mapping_table[row_id][col_id] = KEY_ID_Blue;
+
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[4]] = KEY_ID_Red;
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[5]] = KEY_ID_Green;
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[6]] = KEY_ID_Yellow;
+ Ir_Override_Table_Index_G20[Ir_Table_Correspend_Index_G20[7]] = KEY_ID_Blue;
+ }
+ }
+}
+
+void app_custom_set_new_ir_table(void)
+{
+ IR_KEY_CODE ir_key_code;
+ u8 dat[192];
+ u8 i;
+ u8 total_loop_cnt;
+ uint8_t *p_index_table;
+
+ if (app_global_data.device_type == REMOTE_G10)
+ {
+ total_loop_cnt = 24;
+ p_index_table = Ir_Override_Table_Index_G10;
+ }
+ else if (app_global_data.device_type == REMOTE_G20)
+ {
+ total_loop_cnt = 48;
+ p_index_table = Ir_Override_Table_Index_G20;
+ }
+ else
+ {
+ total_loop_cnt = 24;
+ p_index_table = Ir_Override_Table_Index_G10;
+ }
+
+ frm_vpk_flash_read_page(APP_NEC_IR_CODE_TABLE, 48 * 4, dat);
+
+ for (i = 0; i < total_loop_cnt; i++)
+ {
+ if ((dat[i * 4 + 2] != 0xff) && (p_index_table[i] != KEY_ID_NONE))
+ {
+ ir_key_code.ir_data =
+ key_handle_global_data.cur_key_code_table[p_index_table[i]].ir_key_code.ir_data;
+
+ ir_key_code.ir_cmd1 = dat[i * 4 + 2];
+ if (dat[i * 4 + 3] != 0xff)
+ {
+ ir_key_code.ir_cmd2 = dat[i * 4 + 3];
+ }
+ else
+ {
+ ir_key_code.ir_cmd2 = ~ir_key_code.ir_cmd1;
+ }
+
+ if (dat[i * 4] != 0xff)
+ {
+ ir_key_code.ir_addr1 = dat[i * 4];
+ if (dat[i * 4 + 1] != 0xff)
+ {
+ ir_key_code.ir_addr2 = dat[i * 4 + 1];
+ }
+ else
+ {
+ ir_key_code.ir_addr2 = ~ir_key_code.ir_addr1;
+ }
+ }
+
+ key_handle_global_data.cur_key_code_table[p_index_table[i]].ir_key_code.ir_data =
+ ir_key_code.ir_data;
+ }
+ }
+}
+
+void app_custom_param_init(u8 device_layout)
+{
+ if (app_global_data.device_type == REMOTE_G10)
+ {
+ key_handle_global_data.keyscan_row_size = KEYPAD_MAX_ROW_SIZE_G10;
+ key_handle_global_data.keyscan_column_size = KEYPAD_MAX_COLUMN_SIZE_G10;
+ memcpy(key_handle_global_data.cur_key_mapping_table, KEY_MAPPING_TABLE_G10,
+ sizeof(KEY_MAPPING_TABLE_G10));
+ }
+ else if (app_global_data.device_type == REMOTE_G20)
+ {
+ key_handle_global_data.keyscan_row_size = KEYPAD_MAX_ROW_SIZE_G20;
+ key_handle_global_data.keyscan_column_size = KEYPAD_MAX_COLUMN_SIZE_G20;
+ memcpy(key_handle_global_data.cur_key_mapping_table, KEY_MAPPING_TABLE_G20,
+ sizeof(KEY_MAPPING_TABLE_G20));
+ }
+ app_custom_ui_layout(device_layout);
+ app_custom_set_new_ir_table();
+}
+
+void app_custom_wakeup_key_load(u16 mask1, u16 mask2)
+{
+ u8 j = 0, i;
+ u8 wakeupkey_num = 0;
+ u8 *p_kb_map;
+
+ if ((mask1 != 0xffff) && (mask2 != 0xffff) && ((mask1 & mask2) == 0))
+ {
+ if (app_global_data.device_type == REMOTE_G10)
+ {
+ wakeupkey_num = APP_CUSTOM_WAKEUPKEY_NUM - 4;
+ p_kb_map = (u8 *)Wakeup_Map_Correspend_Index_G10;
+ }
+ else
+ {
+ wakeupkey_num = APP_CUSTOM_WAKEUPKEY_NUM;
+ p_kb_map = (u8 *)Wakeup_Map_Correspend_Index_G20;
+ }
+ for (i = 0; i < wakeupkey_num; i++)
+ {
+ if (mask1 & 0x01)
+ {
+ app_global_data.wakeup_key1[j] = p_kb_map[i];
+ j++;
+ }
+ mask1 = mask1 >> 1;
+ }
+ j = 0;
+ for (i = 0; i < wakeupkey_num; i++)
+ {
+ if (mask2 & 0x01)
+ {
+ app_global_data.wakeup_key2[j] = p_kb_map[i];
+ j++;
+ }
+ mask2 = mask2 >> 1;
+ }
+ }
+}
+
+void app_custom_init(void)
+{
+ u8 buffer[128];
+ u8 addr_pos = 0;
+// u8 *pREMOTE_B046 = (u8 *)("RemoteB046");
+
+ frm_vpk_flash_read_page(APP_CUSTOM_ADDR, 128, buffer);
+
+ if (buffer[0] == 0xff)
+ {
+ app_global_data.device_ui_layout_type = 0;
+ frm_vpk_print("default custom info\r\n");
+ app_global_data.device_type = REMOTE_G20;
+ app_global_data.device_name_len = 10;
+ memcpy(app_global_data.device_name, pREMOTE_G20, 10);
+ app_custom_param_init(app_global_data.device_ui_layout_type);
+ app_global_data.fw_version[3] = (app_global_data.device_type) + 0x30;
+ app_global_data.fw_version[4] = 0x30;
+ app_global_data.fw_version[5] = 0x30;
+ app_global_data.wakeup_adv_format = WAKEUP_FORMAT_GOOGLE_ONLY;
+ return;
+ }
+ else
+ {
+ memcpy(app_global_data.pnp_id, &buffer[1], 7);
+ app_global_data.device_name_len = buffer[8];
+ app_global_data.device_type = buffer[0];
+ if ((app_global_data.device_type != REMOTE_G10) && (app_global_data.device_type != REMOTE_G20))
+ {
+ app_global_data.device_ui_layout_type = 0;
+ app_global_data.device_type = REMOTE_G20;
+ app_global_data.device_name_len = 10;
+ memcpy(app_global_data.device_name, pREMOTE_G20, 10);
+ app_custom_param_init(app_global_data.device_ui_layout_type);
+ app_global_data.fw_version[3] = (app_global_data.device_type) + 0x30;
+ app_global_data.fw_version[4] = 0x30;
+ app_global_data.fw_version[5] = 0x30;
+ app_global_data.wakeup_adv_format = WAKEUP_FORMAT_GOOGLE_ONLY;
+ return;
+ }
+ if (app_global_data.device_name_len > 16)
+ {
+ memcpy(app_global_data.device_name, &buffer[9], 16);
+ }
+ else
+ {
+ memcpy(app_global_data.device_name, &buffer[9], app_global_data.device_name_len);
+ }
+
+ addr_pos = 9 + app_global_data.device_name_len;
+ app_global_data.device_ui_layout_type = buffer[addr_pos];
+ addr_pos = addr_pos + 1;
+
+ //wakeup key
+ app_global_data.wakeupkey1_mask = (u16)(((u16)buffer[addr_pos] << 8) | ((u16)buffer[addr_pos + 1]));
+ app_global_data.wakeupkey2_mask = (u16)(((u16)buffer[addr_pos + 2] << 8) | ((
+ u16)buffer[addr_pos + 3]));
+ frm_vpk_print("wakeupkey1_mask=%x,wakeupkey2_mask=%x\r\n", app_global_data.wakeupkey1_mask,
+ app_global_data.wakeupkey2_mask);
+ app_custom_wakeup_key_load(app_global_data.wakeupkey1_mask, app_global_data.wakeupkey2_mask);
+ addr_pos += 4;
+
+ if (app_global_data.device_name_len > 16)
+ {
+ app_global_data.device_name_len = 16;
+ }
+ }
+ app_custom_param_init(app_global_data.device_ui_layout_type);
+ app_global_data.fw_version[3] = (app_global_data.device_type) + 0x30;
+
+ uint8_t base_val;
+ uint8_t char_val;
+
+ char_val = app_global_data.device_ui_layout_type >> 4;
+ base_val = (char_val > 9) ? ('A' - 10) : 0x30;
+ app_global_data.fw_version[4] = char_val + base_val;
+
+ char_val = app_global_data.device_ui_layout_type & 0x0F;
+ base_val = (char_val > 9) ? ('A' - 10) : 0x30;
+ app_global_data.fw_version[5] = char_val + base_val;
+
+ /* read APP_CUSTOM_ADDR+0xF9 and set 16 bit wakeup_interval value */
+ u8 buffer_wakeup_interval[2] = {0, 0};
+ frm_vpk_flash_read_page(APP_FMS_WAKEUP_INTERVAL, 2, buffer_wakeup_interval);
+ BE_ARRAY_TO_UINT16(app_global_data.find_me_wakeup_timeout, buffer_wakeup_interval);
+
+ /* read APP_CUSTOM_ADDR+0xFB and set en_find_me value */
+ u8 buffer_find_me[1] = {0};
+ frm_vpk_flash_read_page(APP_EN_FIND_ME, 1, buffer_find_me);
+ if (buffer_find_me[0] == 0)
+ {
+ app_global_data.en_find_me = 1; //enable find me
+ }
+ if (buffer_find_me[0] == 0xFF)
+ {
+ app_global_data.en_find_me = 0; //default:disable find me
+ }
+
+ /* read APP_CUSTOM_ADDR+0xFC and set en_rpa value */
+ u8 buffer_rpa[1] = {0};
+ frm_vpk_flash_read_page(APP_EN_RPA, 1, buffer_rpa);
+ if (buffer_rpa[0] == 0)
+ {
+ app_global_data.en_rpa = 1; //enable RPA
+ }
+ else if (buffer_rpa[0] == 0xFF)
+ {
+ app_global_data.en_rpa = 0; //default:disable RPA
+ }
+
+ /* read APP_CUSTOM_ADDR+0xFD and set en_ble_feature value */
+ u8 buffer_ble_feature[1] = {0};
+ frm_vpk_flash_read_page(APP_EN_BLE_FEATURE, 1, buffer_ble_feature);
+ if (buffer_ble_feature[0] == 0xFF)
+ {
+ app_global_data.en_ble_feature = 1; //default:enable BLE
+ }
+ else if (buffer_ble_feature[0] == 0)
+ {
+ app_global_data.en_ble_feature = 0; //disable BLE, only use IR
+ }
+
+ /* read APP_CUSTOM_ADDR+0xFE and set en_google_wakeuppack value */
+ u8 buffer_wakeuppack[1] = {0};
+ frm_vpk_flash_read_page(APP_EN_GOOGLE_WAKEUPPACK, 1, buffer_wakeuppack);
+ if (buffer_wakeuppack[0] == 0xFF)
+ {
+ app_global_data.en_google_wakeuppack = 1; //default:hybrid wakeup format
+ }
+ if (buffer_wakeuppack[0] == 0)
+ {
+ app_global_data.en_google_wakeuppack = 0; //customized wakeup format
+ }
+
+ /* read APP_CUSTOM_ADDR+0xFF and set en_powerkey_cache value */
+ u8 buffer_cachekey[1] = {0};
+ frm_vpk_flash_read_page(APP_EN_CACHEKEY, 1, buffer_cachekey);
+ if (buffer_cachekey[0] == 0xFF)
+ {
+ app_global_data.en_powerkey_cache = 1; //default:cache power key
+ }
+ if (buffer_cachekey[0] == 0)
+ {
+ app_global_data.en_powerkey_cache = 0; //not cache power key
+ }
+
+ if ((buffer[addr_pos] == 0) || (buffer[addr_pos] > 31))
+ {
+ app_global_data.wakeup_adv_format = WAKEUP_FORMAT_GOOGLE_ONLY;
+ }
+ else
+ {
+ if (app_global_data.en_google_wakeuppack == 0)
+ {
+ app_global_data.wakeup_adv_format = WAKEUP_FORMAT_CUSTOM_ONLY;
+ }
+ else
+ {
+ app_global_data.wakeup_adv_format = WAKEUP_FORMAT_CUSTOM_AND_GOOGLE;
+ }
+
+ memcpy(app_global_data.wakeup_adv_custom_data, &buffer[addr_pos], MAX_WAKE_CUSTOM_DATA_LEN);
+ }
+}
+
+u8 app_custom_is_wakeup_key(u8 keyid)
+{
+ u8 i;
+
+ for (i = 0; i < APP_CUSTOM_WAKEUPKEY_NUM; i++)
+ {
+ if ((keyid == app_global_data.wakeup_key1[i]) || (keyid == app_global_data.wakeup_key2[i]))
+ {
+ frm_vpk_print("wakeup_key =%x\r\n", keyid);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+u8 app_custom_is_enable_wakeup_key(void)
+{
+ if ((app_global_data.wakeupkey1_mask != 0xffff) && (app_global_data.wakeupkey2_mask != 0xffff) &&
+ ((app_global_data.wakeupkey1_mask & app_global_data.wakeupkey2_mask) == 0))
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+u8 app_custom_wakeupkey_packet_index(u8 keyid)
+{
+ u8 i;
+
+ for (i = 0; i < APP_CUSTOM_WAKEUPKEY_NUM; i++)
+ {
+ if (keyid == app_global_data.wakeup_key1[i])
+ {
+ return 1;
+ }
+ else if (keyid == app_global_data.wakeup_key2[i])
+ {
+ return 2;
+ }
+ }
+ return 2;
+}
+
+void app_custom_test(void)
+{
+ u8 buffer[65] = {/* device type */0x02,
+ /* PnP Id */ 0x02, 0x8a, 0x24, 0x66, 0x82, 0x01, 0x00,
+ /* device name and length */ 0x09, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x47, 0x32, 0x30,
+ /* ui layout */ 0x00,
+ /* wake up key */ 0x00, 0x04, 0x00, 0x70,
+ /* wake up adv */ 0x08, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ frm_vpk_flash_erase_sector(APP_CUSTOM_ADDR);
+ frm_vpk_flash_write_page(APP_CUSTOM_ADDR, sizeof(buffer), buffer);
+
+ u8 buffer2[2] = {0x00, 0x05};
+ frm_vpk_flash_write_page(APP_FMS_WAKEUP_INTERVAL, 2, buffer2);
+
+ buffer2[0] = 1;
+ frm_vpk_flash_write_page(APP_EN_FIND_ME, 1, buffer2);
+
+ buffer2[0] = 0;
+ frm_vpk_flash_write_page(APP_EN_GOOGLE_WAKEUPPACK, 1, buffer2);
+ frm_vpk_flash_write_page(APP_EN_BLE_FEATURE, 1, buffer2); //test:write 0 to APP_EN_BLE_FEATURE
+
+ u8 buffer_ir_table[48 * 4];
+ u8 override_index;
+ u8 data_buf[4] = {0xFF, 0xFF, 0xFF, 0xFF};
+ memset(buffer_ir_table, 0xFF, sizeof(buffer_ir_table));
+
+ /* override up with case 1 */
+ override_index = 30;
+ data_buf[0] = 0xFF;
+ data_buf[1] = 0xFF;
+ data_buf[2] = 0x33;
+ data_buf[3] = 0xFF;
+ memcpy(buffer_ir_table + 4 * override_index, data_buf, 4);
+ /* override down with case 2 */
+ override_index = 7;
+ data_buf[0] = 0x11;
+ data_buf[1] = 0xFF;
+ data_buf[2] = 0x33;
+ data_buf[3] = 0xFF;
+ memcpy(buffer_ir_table + 4 * override_index, data_buf, 4);
+ /* override left with case 3 */
+ override_index = 36;
+ data_buf[0] = 0x11;
+ data_buf[1] = 0x22;
+ data_buf[2] = 0x33;
+ data_buf[3] = 0xFF;
+ memcpy(buffer_ir_table + 4 * override_index, data_buf, 4);
+ /* override right with case 4 */
+ override_index = 1;
+ data_buf[0] = 0x11;
+ data_buf[1] = 0x22;
+ data_buf[2] = 0x33;
+ data_buf[3] = 0x44;
+ memcpy(buffer_ir_table + 4 * override_index, data_buf, 4);
+
+ frm_vpk_flash_erase_sector(APP_NEC_IR_CODE_TABLE);
+ frm_vpk_flash_write_page(APP_NEC_IR_CODE_TABLE, sizeof(buffer_ir_table), buffer_ir_table);
+}
diff --git a/src/app/google_rcu/frm_vpk/src/app_custom.h b/src/app/google_rcu/frm_vpk/src/app_custom.h
new file mode 100644
index 0000000..707b6cc
--- /dev/null
+++ b/src/app/google_rcu/frm_vpk/src/app_custom.h
@@ -0,0 +1,46 @@
+/******************************************************************************
+ * @file app_custom.h
+ *
+ * @brief for TLSR chips
+ *
+ * @author public@telink-semi.com;
+ * @date Sep. 30, 2010
+ *
+ * @attention
+ *
+ * Copyright (C) 2019-2020 Telink Semiconductor (Shanghai) Co., Ltd.
+ *
+ * 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 APP_CUSTOM_H_
+#define APP_CUSTOM_H_
+
+#include "frm_define.h"
+
+extern const unsigned char Kb_Map_Normal[8][3];
+extern u8 nec_ir_addr1_table[48];
+extern u8 nec_ir_addr2_table[48];
+extern u8 nec_ir_cmd1_table[48];
+extern u8 nec_ir_cmd2_table[48];
+
+extern void app_custom_init(void);
+extern u8 app_custom_get_drive_len(void);
+extern void app_custom_param_init(u8 device_layout);
+extern u8 app_custom_is_enable_wakeup_key(void);
+extern u8 app_custom_wakeupkey_packet_index(u8 keyid);
+extern u8 app_custom_is_wakeup_key(u8 keyid);
+extern void app_custom_test(void);
+
+#endif
diff --git a/src/app/google_rcu/frm_vpk/src/app_flash_write.c b/src/app/google_rcu/frm_vpk/src/app_flash_write.c
new file mode 100644
index 0000000..6ab40c9
--- /dev/null
+++ b/src/app/google_rcu/frm_vpk/src/app_flash_write.c
@@ -0,0 +1,277 @@
+/******************************************************************************
+ * @file app_info.c
+ *
+ * @brief for TLSR chips
+ *
+ * @author public@telink-semi.com;
+ * @date Sep. 30, 2010
+ *
+ * @attention
+ *
+ * Copyright (C) 2019-2020 Telink Semiconductor (Shanghai) Co., Ltd.
+ *
+ * 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.
+ *
+ *****************************************************************************/
+
+#include "string.h"
+#include "app_flash_write.h"
+#include "frm_vpk_hal_sflash.h"
+
+
+_attribute_data_retention_ u8 flag_ccc_data = 0;
+_attribute_data_retention_ u8 peer_mac[6] = {0};
+
+
+
+/**********************************************************
+ **** operate flash function
+ **********************************************************/
+
+/**
+ * @brief This function can make more effective use of flash.
+ * @param[in] addr the start address of the page
+ * @param[in] Number of sectors used to save this data type
+ * @param[in] Space occupied by a piece of data.Less than 256��
+ * @return -1:No data found,others:address offset
+ */
+s16 bsearch_without_recursion(unsigned long addr, u8 used_sector, u8 used_block)
+{
+ s16 low = 0, high = (4 * 1024 / used_block) * used_sector - 1;
+ u8 rbuf[2];
+ u8 cmp1[] = {U16_LO(FLASH_FLAG), U16_HI(FLASH_FLAG)}; //{0xa5,0xff};
+ u8 cmp2[] = {0x00, 0x00};
+ u8 cmp3[] = {0xff, 0xff};
+ while (low <= high)
+ {
+ //DEBUG("low: %d high: %d\n",low,high);
+ s16 mid = (low + high) / 2;
+
+ frm_vpk_flash_read_page(addr + mid * used_block, 2, rbuf);
+ //frm_vpk_print("bsearchWithoutRecursion tmp:");
+ //arrayPrint(tmp,2);
+ //frm_vpk_print("\n:");
+ if (!memcmp(rbuf, cmp3, 2)) { high = mid - 1; }
+ else if (!memcmp(rbuf, cmp2, 2)) { low = mid + 1; }
+ else if (!memcmp(rbuf, cmp1, 2)) { return mid; } //return mid*used_block;
+ else { return -1; }
+ }
+ return -1;
+}
+
+/**
+ * @brief This function can make more effective use of flash.
+ * @param[in] addr the start address of the page
+ * @param[in] Number of sectors used to save this data type
+ * @param[in] Space occupied by a piece of data.Less than 256��
+ * @param[in] len the length(in byte) of content needs to read out from the page
+ * @param[out] buf the start address of the buffer
+ * @return 0:Success,1:flash is empty,2:sector data error
+ */
+u8 flash_pos_info(unsigned long addr, u8 used_sector, u8 used_block)
+{
+ u8 ret = 0;
+ u8 begin_data[2]; //beginning of sector data.byte 0,1 is 1st sector data,byte 2,3 is 2nd sector data.
+
+ s16 high = (4 * 1024 / used_block) * used_sector - 1;
+
+ //Read the beginning and end data of the 1st sector
+ frm_vpk_flash_read_page(addr, 2, begin_data);
+ //flash_read_page(addr, 2, end_data);
+
+ u8 allff[2] = {0xff, 0xff};
+
+ /**** start check flash ****/
+
+ if (!memcmp(begin_data, allff, 2))
+ {
+ //beginning of 1st sector data(2byte) is all 0xff.
+ //Indicates whether the RCU is brand new or factory set
+ ret = 1; //return 1; //No data in flash
+ }
+ else
+ {
+
+ //search data in flash
+ s16 offset = bsearch_without_recursion(addr, used_sector, used_block);
+ //frm_vpk_print("offset=%x \r\n", (u16)offset);
+ if (offset == -1)
+ {
+
+ ret = 2; //return 2; //sector data error
+ }
+ else
+ {
+ if (offset > (high / 10 * 9))
+ {
+ return 3;
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief This function can make more effective use of flash.
+ * @param[in] addr the start address of the page
+ * @param[in] Number of sectors used to save this data type
+ * @param[in] Space occupied by a piece of data.Less than 256��
+ * @param[in] len the length(in byte) of content needs to read out from the page
+ * @param[out] buf the start address of the buffer
+ * @return 0:Success,1:flash is empty,2:sector data error
+ */
+u8 flash_read_info(unsigned long addr, u8 used_sector, u8 used_block, unsigned long len, u8 *rbuf)
+{
+ u8 ret = 0;
+ u8 begin_data[2]; //beginning of sector data.byte 0,1 is 1st sector data,byte 2,3 is 2nd sector data.
+ //Read the beginning and end data of the 1st sector
+ frm_vpk_flash_read_page(addr, 2, begin_data);
+ //flash_read_page(addr, 2, end_data);
+
+ u8 allff[2] = {0xff, 0xff};
+
+ /**** start check flash ****/
+
+ if (!memcmp(begin_data, allff, 2))
+ {
+ //beginning of 1st sector data(2byte) is all 0xff.
+ //Indicates whether the RCU is brand new or factory set
+ ret = 1; //return 1; //No data in flash
+ }
+ else
+ {
+
+ //search data in flash
+ s16 offset = bsearch_without_recursion(addr, used_sector, used_block);
+
+ if (offset == -1)
+ {
+
+ ret = 2; //return 2; //sector data error
+ }
+ else
+ {
+
+ frm_vpk_flash_read_page(addr + offset * used_block, len, rbuf);
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * @brief This function can make more effective use of flash.
+ * @param[in] addr the start address of the page
+ * @param[in] Number of sectors used to save this data type
+ * @param[in] Space occupied by a piece of data.Less than 256��
+ * @param[in] len the length(in byte) of content needs to read out from the page
+ * @param[out] buf the start address of the buffer
+ * @return 0:Success,1:flash is empty,2:sector data error,3:read data error
+ */
+u8 flash_write_info(unsigned long addr, u8 used_sector, u8 used_block, unsigned long len, u8 *wbuf)
+{
+
+ u8 ret = 0;
+ u8 begin_data[2]; //beginning of sector data.byte 0,1 is 1st sector data,byte 2,3 is 2nd sector data.
+ //u8 end_data[4]; //end of sector data.byte 0,1 is 1st sector data,byte 2,3 is 2nd sector data.
+
+ //Read the beginning and end data of the 1st sector
+ frm_vpk_flash_read_page(addr, 2, begin_data);
+ //flash_read_page(addr, 2, end_data);
+
+ u8 allff[2] = {0xff, 0xff};
+
+ /**** start check flash ****/
+
+ if (!memcmp(begin_data, allff, 2))
+ {
+ //beginning of 1st sector data(2byte) is all 0xff.
+ //Indicates whether the RCU is brand new or factory set
+ ret = 1; //No data in flash
+ }
+ else
+ {
+
+ //search data in flash
+ s16 offset = bsearch_without_recursion(addr, used_sector, used_block);
+
+ if (offset == -1)
+ {
+
+ ret = 2; //sector data error
+ }
+ else
+ {
+ u8 clr[2] = {0};
+ frm_vpk_flash_write_page(addr + offset * used_block, 2, clr);
+
+ //if(offset + 1 >= 4*1024*used_sector/used_block) offtset = -1; //2nd sector is full.so set offset to beginning of 1st sector
+ //write data to flash
+ frm_vpk_flash_write_page(addr + (offset + 1)*used_block, len, wbuf);
+ //Confirm that writing data is correct
+ //u8 temp[256] = {0};
+ u8 temp[16] = {0};
+ frm_vpk_flash_read_page(addr + (offset + 1)*used_block, len, temp);
+ if (memcmp(wbuf, temp, len)) { ret = 3; } //The data written and read does not match
+ }
+ }
+
+ switch (ret)
+ {
+ case 3:
+ case 2:
+ break;
+ case 1:
+ {
+ frm_vpk_flash_write_page(addr, len, wbuf);
+ break;
+ }
+ case 0:
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+void flash_check_area(unsigned long addr, u8 used_sector, u8 used_block, unsigned long len)
+{
+
+
+ u8 begin_data[2]; //beginning of sector data.byte 0,1 is 1st sector data,byte 2,3 is 2nd sector data.
+ u8 allff[2] = {0xff, 0xff};
+ //Read the beginning and end data of the 1st sector
+ frm_vpk_flash_read_page(addr, 2, begin_data);
+
+ if (!memcmp(begin_data, allff, 2))
+ {
+ //beginning of 1st sector data(2byte) is all 0xff.
+ //Indicates whether the RCU is brand new or factory set
+ return;
+ }
+
+
+ s16 offset = bsearch_without_recursion(addr, used_sector, used_block);
+ if (offset == -1)
+ {
+ //sector data error
+ for (u8 i = 0; i < used_sector; i++)
+ {
+ frm_vpk_flash_erase_sector(addr + i * 0x1000);
+ }
+ return;
+ }
+}
+
diff --git a/src/app/google_rcu/frm_vpk/src/app_flash_write.h b/src/app/google_rcu/frm_vpk/src/app_flash_write.h
new file mode 100644
index 0000000..8890622
--- /dev/null
+++ b/src/app/google_rcu/frm_vpk/src/app_flash_write.h
@@ -0,0 +1,62 @@
+/******************************************************************************
+ * @file app_info.h
+ *
+ * @brief for TLSR chips
+ *
+ * @author public@telink-semi.com;
+ * @date Sep. 30, 2010
+ *
+ * @attention
+ *
+ * Copyright (C) 2019-2020 Telink Semiconductor (Shanghai) Co., Ltd.
+ *
+ * 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 APP_INFO_H_
+#define APP_INFO_H_
+
+#include "frm_define.h"
+
+///////////////////////
+#define FLASH_FLAG 0xFFA5
+
+
+#define IR_FLASH_LENGTH 0x500 //(256*5)
+
+//ccc data flag
+#define FLAG_GOOGLE_RX_CCC BIT(0)
+#define FLAG_GOOGLE_CTL_CCC BIT(1)
+
+extern u8 flag_ccc_data;
+extern u8 peer_mac[6];
+void write_ccc_info(u8 *ccc);
+u8 read_ccc_info(u8 *ccc);
+void init_ccc_value(void);
+
+u8 flash_write_info(unsigned long addr, u8 used_sector, u8 used_block, unsigned long len, u8 *wbuf);
+u8 flash_read_info(unsigned long addr, u8 used_sector, u8 used_block, unsigned long len, u8 *rbuf);
+void flash_check_area(unsigned long addr, u8 used_sector, u8 used_block, unsigned long len);
+extern void init_peer_mac(void);
+extern u8 is_peer_mac_flash_info_full(void);
+extern void write_peer_mac_info(u8 *mac);
+extern void write_wakeup_keyindex_info(u8 index);
+extern u8 read_wakeup_keyindex_info(u8 *index);
+extern u8 is_wakeup_keyindex_flash_info_full(void);
+extern void init_wakeup_keyindex(void);
+extern u8 init_ir_key_event_notify(void);
+extern u8 is_ir_key_event_notify_flash_info_full(void);
+extern void write_ir_key_event_notify(u8 index);
+
+#endif /* APP_INFO_H_ */
diff --git a/src/app/google_rcu/ir_module/ir_protocol_nec.c b/src/app/google_rcu/ir_module/ir_protocol_nec.c
new file mode 100644
index 0000000..b3b16a6
--- /dev/null
+++ b/src/app/google_rcu/ir_module/ir_protocol_nec.c
@@ -0,0 +1,485 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_protocol_nec.c
+* @brief This file provides IR encode handler of NEC protocol.
+* @details
+* @author barry_bian
+* @date 2020-02-28
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "board.h"
+#include "stdint.h"
+#include "trace.h"
+#include "ir_protocol_nec.h"
+#include "ir_send_driver.h"
+#include "key_handle.h"
+
+#if SUPPORT_IR_TX_FEATURE
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define abd_f(a,b) (a>b) ? (a-b):(b-a) ;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+const T_IR_NEC_SPEC NEC_SPEC =
+{
+ 2, // header_len;
+ {PULSE_HIGH | 9000, PULSE_LOW | (4500 - 26) }, //uint32_t HeaderContext[NEC_MAX_HEADDER_LEN];
+ {PULSE_HIGH | 560, PULSE_LOW | (560 - 26) }, //Log0[NEC_MAX_LOG_WAVFORM_SIZE];
+ {PULSE_HIGH | 560, PULSE_LOW | (1690 - 26) }, //Log1[NEC_MAX_LOG_WAVFORM_SIZE];
+ PULSE_HIGH | 560,
+ 560,
+ 4
+};
+
+const T_IR_NEC_REPEAT_CODE_SPEC NEC_REPEAT_CODE_SPEC =
+{
+ 3, /* length of repeat code */
+ {PULSE_HIGH | 9000, PULSE_LOW | 2250, PULSE_HIGH | 560}, /* Buffer of repeat code: high 9ms, low 2.25ms, high 560us */
+};
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief hl_time2_tx_buf_countng
+ * @param uint32_t log_context
+ * @param float base_time
+ * @return result
+ * @retval uint32_t
+ */
+static uint32_t hl_time2_tx_buf_count(uint32_t log_context, float base_time)
+{
+ return ((log_context & 0x80000000) | (uint32_t)((log_context & 0x7FFFFFFF) / base_time));
+}
+
+/******************************************************************
+ * @brief bit_n
+ * @param uint32_t a
+ * @param uint32_t b
+ * @return result
+ * @retval uint8_t
+ */
+static uint8_t bit_n(uint32_t a, uint32_t b)
+{
+ return ((a >> b) & 0x01);
+}
+
+/******************************************************************
+ * @brief ir_protocol_nec_command_set_tx_buf
+ * @param T_IR_NEC_BUF *p_ir_data_buf
+ * @param T_IR_NEC_SPEC p_spec
+ * @return result
+ * @retval T_IRDA_RET
+ */
+static T_IRDA_RET ir_protocol_nec_command_set_tx_buf(T_IR_NEC_BUF *p_ir_data_buf,
+ T_IR_NEC_SPEC *p_spec)
+{
+ int i = 0, n = 0;
+ float base_time = 1000000 / (float)p_ir_data_buf->carrier_frequency_hz;
+ uint16_t buf_len = 0;
+
+ uint32_t Log1[NEC_MAX_LOG_WAVFORM_SIZE];
+ uint32_t Log0[NEC_MAX_LOG_WAVFORM_SIZE];
+ uint8_t Code = 0;
+
+ if (p_ir_data_buf->carrier_frequency_hz == 0)
+ {
+ return IRDA_ERROR;
+ }
+
+ for (i = 0; i < NEC_MAX_LOG_WAVFORM_SIZE; i++)
+ {
+ Log1[i] = hl_time2_tx_buf_count(p_spec->log1_context[i],
+ base_time); // (p_spec->log1_context[i] &0x80000000 )| ((p_spec->Log1_Time[i]&0x7FFFFFFF) / base_time);
+ Log0[i] = hl_time2_tx_buf_count(p_spec->log0_context[i],
+ base_time); //(p_spec->log0_context[i] &0x80000000 )| ((p_spec->Log0_Time[i]&0x7FFFFFFF) / base_time);
+
+ }
+
+ /* header */
+ for (i = 0; i < p_spec->header_len; i++)
+ {
+ p_ir_data_buf->p_buf[i] = hl_time2_tx_buf_count(p_spec->header_context[i], base_time);
+ }
+
+ buf_len = p_spec->header_len;
+ for (i = 0; i < p_ir_data_buf->code_len; i++)
+ {
+ Code = p_ir_data_buf->code[i];
+ for (n = 0; n < 8; n++)
+ {
+ /* Change encoding bit order */
+ if (bit_n(Code, n) == 0x01) //if (bit_n(Code,7-n)== 0x01)
+ {
+ /* log 1 */
+ p_ir_data_buf->p_buf[buf_len] = Log1[0];
+ p_ir_data_buf->p_buf[buf_len + 1] = Log1[1];
+ }
+ else
+ {
+ /* log 0 */
+ p_ir_data_buf->p_buf[buf_len] = Log0[0];
+ p_ir_data_buf->p_buf[buf_len + 1] = Log0[1];
+ }
+ buf_len += NEC_MAX_LOG_WAVFORM_SIZE;
+ }
+ }
+
+ /* Stop */
+ if (p_spec->stop_context != 0x0000)
+ {
+ p_ir_data_buf->p_buf[buf_len] = hl_time2_tx_buf_count(p_spec->stop_context, base_time);
+ buf_len += 1;
+ }
+ p_ir_data_buf->buf_len = buf_len;
+
+ return IRDA_SUCCEED;
+}
+
+#if IR_NEC_DECODE
+/******************************************************************
+ * @brief hl_wave
+ * @param a
+ * @return result
+ * @retval uint32_t
+ */
+static uint32_t hl_wave(uint32_t a)
+{
+ return ((a & 0x80000000) >> 15);
+}
+
+/******************************************************************
+ * @brief tx_buf_count2_time
+ * @param uint32_t a
+ * @param float base_time
+ * @return result
+ * @retval float
+ */
+static float tx_buf_count2_time(uint32_t a, float base_time)
+{
+ return ((a & 0x7FFFFFFF) * base_time);
+}
+
+/******************************************************************
+ * @brief ir_protocol_invse_pulse1
+ * @param buf
+ * @param length
+ * @return result
+ * @retval T_IRDA_RET
+ */
+static T_IRDA_RET ir_protocol_invse_pulse1(uint32_t *buf, uint16_t length)
+{
+ uint16_t i = 0;
+
+ for (i = 0; i < length; i++)
+ {
+ if (buf[i] > PULSE_HIGH)
+ {
+ buf[i] = buf[i] & (~PULSE_HIGH);
+ }
+ else
+ {
+ buf[i] = buf[i] | PULSE_HIGH;
+ }
+ }
+ return IRDA_SUCCEED;
+}
+
+/******************************************************************
+ * @brief ir_protocol_rx_buf_log_data_check
+ * @param uint32_t *buf
+ * @param uint32_t *p_log
+ * @param uint16_t log_wav_form_len
+ * @param uint32_t base_time
+ * @param uint32_t dif_base
+ * @param uint32_t dif_base_time
+ * @return result
+ * @retval T_IRDA_RET
+ */
+static T_IRDA_RET ir_protocol_rx_buf_log_data_check(uint32_t *buf,
+ uint32_t *p_log,
+ uint16_t log_wav_form_len,
+ float base_time,
+ float dif_base,
+ float dif_base_time)
+{
+ float time1 = 0, time2 = 0;
+ uint16_t i = 0;
+ uint16_t buf_value;
+ float dif = 0;
+ float temp = 0;
+ for (i = 0; i < log_wav_form_len; i++)
+ {
+ buf_value = buf[i];
+
+ /* check H_L */
+ if (hl_wave(buf_value) != hl_wave(p_log[i]))
+ {
+ return IRDA_ERROR;
+ }
+ /* Check Time */
+ time1 = tx_buf_count2_time(buf_value, base_time);
+ time2 = p_log[i] & 0x7FFFFFFF;
+
+ dif = (time2 / dif_base) * dif_base_time;
+
+ temp = abd_f(time1, time2);
+ if (temp > dif)
+ {
+ return IRDA_ERROR;
+ }
+ }
+
+ return IRDA_SUCCEED;
+}
+
+/******************************************************************
+ * @brief ir_protocol_rx_buf_log_data_check
+ * @param T_IR_NEC_BUF *p_ir_data_buf
+ * @param T_IR_NEC_SPEC *p_spec
+ * @return result
+ * @retval T_IRDA_RET
+ */
+static T_IRDA_RET ir_protocol_nec_set_rx_buf(T_IR_NEC_BUF *p_ir_data_buf, T_IR_NEC_SPEC *p_spec)
+{
+ float base_time = 0;
+ float dif_base_time = 0;
+ float dif = 0;
+ uint32_t buf_count = 0;
+ float temp = 0;
+ float time1, time2;
+ uint8_t bit_num = 0;
+ uint8_t byte_num = 0;
+ uint8_t data;
+ uint8_t bit_type = 0;
+ uint16_t buf_len = 0;
+
+ if (p_ir_data_buf->carrier_frequency_hz == 0)
+ {
+ return IRDA_ERROR;
+ }
+
+ if (ir_protocol_invse_pulse1(p_ir_data_buf->p_buf, p_ir_data_buf->buf_len) != 0)
+ {
+ return IRDA_ERROR;
+ }
+
+ base_time = 1000000 / p_ir_data_buf->carrier_frequency_hz;
+
+ if (p_spec->dif_divisor == 0)
+ {
+ p_spec->dif_divisor = 1;
+ }
+
+ dif_base_time = p_spec->dif_base / p_spec->dif_divisor;
+
+ if (p_spec->stop_context != 0x0000)
+ {
+ buf_len = p_ir_data_buf->buf_len -= 2;
+ }
+ else
+ {
+ buf_len = p_ir_data_buf->buf_len - 1;
+ }
+
+ /* Check header */
+ while (buf_count < p_spec->header_len)
+ {
+ if (hl_wave(p_ir_data_buf->p_buf[buf_count]) != hl_wave(p_ir_data_buf->p_buf[buf_count]))
+ {
+ return IRDA_HEADER_ERROR;
+ }
+
+ time1 = tx_buf_count2_time(p_ir_data_buf->p_buf[buf_count], base_time);
+ time2 = p_spec->header_context[buf_count] & 0x7FFFFFFF;
+
+ dif = time2 / (p_spec->dif_base) * dif_base_time;
+
+ temp = abd_f(time1, time2);
+
+ if (temp > dif)
+ {
+ return IRDA_HEADER_ERROR;
+ }
+ buf_count++;
+ }
+
+ bit_num = 0;
+ byte_num = 0;
+ data = 0;
+
+ while (buf_count < buf_len)
+ {
+ /* check log 0 */
+ if (ir_protocol_rx_buf_log_data_check(&p_ir_data_buf->p_buf[buf_count],
+ p_spec->log0_context,
+ NEC_MAX_LOG_WAVFORM_SIZE,
+ base_time,
+ p_spec->dif_base,
+ dif_base_time) == 0)
+ {
+ bit_type = LOG_LOW;
+ buf_count += NEC_MAX_LOG_WAVFORM_SIZE;
+ }
+ else if (ir_protocol_rx_buf_log_data_check(&p_ir_data_buf->p_buf[buf_count],
+ p_spec->log1_context,
+ NEC_MAX_LOG_WAVFORM_SIZE,
+ base_time,
+ p_spec->dif_base,
+ dif_base_time) == 0)
+ {
+ bit_type = LOG_HIGH;
+ buf_count += NEC_MAX_LOG_WAVFORM_SIZE;
+ }
+ else
+ {
+ return IRDA_DATA_ERROR;
+ }
+ /* Change data's bit order */
+ data |= (bit_type << bit_num);
+ bit_num++;
+#ifdef DBG_ON
+ DBGPRINTF("(%d/%d) data = %x --> %d \n", bit_num, byte_num, data, bit_type);
+#endif
+ if (bit_num >= 8)
+ {
+ p_ir_data_buf->code[byte_num] = data;
+ byte_num++;
+ bit_num = 0;
+ data = 0;
+ p_ir_data_buf->code_len = byte_num;
+
+ }
+ }
+ return IRDA_SUCCEED;
+}
+#endif /*endif @IR_NEC_DECODE*/
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+
+/******************************************************************
+ * @brief encode ir command data with NEC protocol
+ * @param uint8_t ir_key_command
+ * @param T_IR_SEND_PARA *p_ir_send_parameters
+ * @return result
+ * @retval T_IRDA_RET
+ */
+T_IRDA_RET ir_protocol_nec_command_encode(IR_KEY_CODE ir_key_code,
+ T_IR_SEND_PARA *p_ir_send_parameters)
+{
+ T_IRDA_RET ret = IRDA_SUCCEED;
+
+ p_ir_send_parameters->carrier_frequency_hz = NEC_SEND_FREQUENCY;
+ p_ir_send_parameters->duty_cycle = IR_DUTY_CYCLE;
+ p_ir_send_parameters->ir_seq_timeout_ms_1 = NEC_IR_COMMAND_PERIOD;
+ /* set p_ir_send_buf and ir_seq_len_1 */
+ T_IR_NEC_BUF nec_data_buf;
+
+ nec_data_buf.carrier_frequency_hz = NEC_SEND_FREQUENCY; /* 38kHz */
+ nec_data_buf.code_len = NEC_CODE_LEN; /* 4 */
+ nec_data_buf.code[0] = ir_key_code.ir_addr1;
+ nec_data_buf.code[1] = ir_key_code.ir_addr2;
+ nec_data_buf.code[2] = ir_key_code.ir_cmd1;
+ nec_data_buf.code[3] = ir_key_code.ir_cmd2;
+ nec_data_buf.p_buf = p_ir_send_parameters->ir_seq_buf_1;
+
+ ret = ir_protocol_nec_command_set_tx_buf(&nec_data_buf, (T_IR_NEC_SPEC *)&NEC_SPEC);
+ p_ir_send_parameters->ir_seq_len_1 = nec_data_buf.buf_len;
+#ifdef DBG_ON
+ APP_PRINT_INFO0("=========== NEC Tx buf===========================\n");
+ APP_PRINT_INFO2("address = 0x%x command = 0x%x \n", nec_address, ir_key_command);
+ APP_PRINT_INFO1("buf_len= 0x%x\n", nec_data_buf->buf_len);
+
+ for (uint8_t i = 0; i < nec_data_buf->buf_len; i++)
+ {
+ if (i % 8 == 0)
+ {
+ APP_PRINT_INFO0("\n");
+ }
+ APP_PRINT_INFO1("%x,", nec_data_buf->p_buf[i]);
+
+ }
+ APP_PRINT_INFO0("\n");
+ APP_PRINT_INFO1("============= ret = %d===============\n", ret);
+#endif
+
+ return ret;
+}
+
+/******************************************************************
+ * @brief encode ir repeat code data with NEC protocol
+ * @param T_IR_SEND_PARA *p_ir_send_parameters
+ * @return result
+ * @retval T_IRDA_RET
+ */
+T_IRDA_RET ir_protocol_nec_repeat_code_encode(T_IR_SEND_PARA *p_ir_send_parameters)
+{
+ T_IRDA_RET ret = IRDA_SUCCEED;
+
+ if (p_ir_send_parameters->carrier_frequency_hz < 5000 ||
+ p_ir_send_parameters->carrier_frequency_hz > 2000000)
+ {
+ ret = IRDA_ERROR;
+ return ret;
+ }
+ uint16_t index = 0;
+ p_ir_send_parameters->ir_seq_timeout_ms_2 = NEC_IR_REPEAT_CODE_PERIOD;
+ p_ir_send_parameters->ir_seq_len_2 = NEC_REPEAT_CODE_SPEC.repeat_code_len;
+ /* Encode repeat code */
+ for (index = 0; index < p_ir_send_parameters->ir_seq_len_2; index++)
+ {
+ p_ir_send_parameters->ir_seq_buf_2[index] = ir_send_convert_to_carrier_cycle(
+ NEC_REPEAT_CODE_SPEC.repeat_code_buf[index],
+ p_ir_send_parameters->carrier_frequency_hz);
+ }
+
+ return ret;
+}
+
+#if IR_NEC_DECODE
+/******************************************************************
+ * @brief decode ir data with NEC protocol
+ * @param uint8_t *address
+ * @param uint8_t *command
+ * @param T_IR_NEC_BUF *p_ir_data
+ * @return result
+ * @retval T_IRDA_RET
+ */
+T_IRDA_RET ir_protocol_nec_decode(uint8_t *address, uint8_t *command, T_IR_NEC_BUF *p_ir_data)
+{
+ T_IRDA_RET ret = IRDA_SUCCEED;
+ p_ir_data->code_len = 0;
+ p_ir_data->code[0] = 0;
+ p_ir_data->code[1] = 0;
+ p_ir_data->code[2] = 0;
+ p_ir_data->code[3] = 0;
+
+ ret = ir_protocol_nec_set_rx_buf(p_ir_data, (T_IR_NEC_SPEC *)&NEC_SPEC);
+
+ *address = p_ir_data->code[0];
+ *command = p_ir_data->code[2];
+
+#ifdef DBG_ON
+ DBGPRINTF("=========== NEC Rx Code===========================\n");
+ DBGPRINTF("address = 0x%x command = 0x%x \n", *address, *command);
+ DBGPRINTF("\n");
+#endif
+ return ret;
+}
+#endif /*endif @IR_NEC_DECODE*/
+
+#endif /*endif @SUPPORT_IR_TX_FEATURE*/
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/ir_module/ir_protocol_nec.h b/src/app/google_rcu/ir_module/ir_protocol_nec.h
new file mode 100644
index 0000000..49a8e13
--- /dev/null
+++ b/src/app/google_rcu/ir_module/ir_protocol_nec.h
@@ -0,0 +1,63 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ir_nec_protocol.h
+* @brief
+* @details
+* @author barry_bian
+* @date 2020-02-26
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef _IR_NEC_PROTOCOL_H_
+#define _IR_NEC_PROTOCOL_H_
+
+#include "stdint.h"
+#include "ir_send_driver.h"
+#include "key_handle.h"
+
+#define IR_NEC_DECODE 0
+
+#define NEC_SEND_FREQUENCY 38000 /*38KHz*/
+#define NEC_ADDRESS 0x88
+#define NEC_CODE_LEN 4
+#define NEC_MAX_HEADDER_LEN 16
+#define NEC_MAX_LOG_WAVFORM_SIZE 2
+#define NEC_MAX_CODE_SIZE 12
+#define NEC_MAX_REPETA_CODE_SIZE 3
+#define NEC_IR_COMMAND_PERIOD 108 /*ms*/
+#define NEC_IR_REPEAT_CODE_PERIOD 108 /*ms*/
+
+typedef struct
+{
+ uint16_t header_len;
+ uint32_t header_context[NEC_MAX_HEADDER_LEN];
+ uint32_t log0_context[NEC_MAX_LOG_WAVFORM_SIZE];
+ uint32_t log1_context[NEC_MAX_LOG_WAVFORM_SIZE];
+ uint32_t stop_context;
+ uint32_t dif_base;
+ uint32_t dif_divisor;
+} T_IR_NEC_SPEC;
+
+typedef struct
+{
+ uint32_t repeat_code_len;
+ uint32_t repeat_code_buf[NEC_MAX_REPETA_CODE_SIZE];
+} T_IR_NEC_REPEAT_CODE_SPEC;
+
+typedef struct
+{
+ float carrier_frequency_hz;
+ uint8_t code[NEC_MAX_CODE_SIZE];
+ uint8_t code_len;
+ uint16_t buf_len;
+ uint32_t *p_buf;
+} T_IR_NEC_BUF;
+
+T_IRDA_RET ir_protocol_nec_command_encode(IR_KEY_CODE ir_key_command,
+ T_IR_SEND_PARA *p_ir_send_parameters);
+T_IRDA_RET ir_protocol_nec_repeat_code_encode(T_IR_SEND_PARA *p_ir_send_parameters);
+
+#endif
diff --git a/src/app/google_rcu/ir_module/ir_send_driver.c b/src/app/google_rcu/ir_module/ir_send_driver.c
new file mode 100644
index 0000000..8190b7f
--- /dev/null
+++ b/src/app/google_rcu/ir_module/ir_send_driver.c
@@ -0,0 +1,541 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_send_app.c
+* @brief This file provides IR sending data handler by interrupt.
+* @details Application users can use the global functions to send IR data.
+* @author barry_bian
+* @date 2020-02-26
+* @version v1.1
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "string.h"
+#include "board.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_rtc.h"
+#include "rtl876x_ir.h"
+#include "trace.h"
+#include "app_task.h"
+#include "app_section.h"
+#include "ir_send_driver.h"
+#include "rtl876x_gdma.h"
+#include "rtc_driver.h"
+#include "key_handle.h"
+
+#if SUPPORT_IR_TX_FEATURE
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+static T_IR_SEND_STRUCT ir_send_struct;
+
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+static void ir_send_pad_and_pinmux_init(void);
+static void ir_send_driver_init(void);
+static void ir_driver_tx_gdma_deinit(void);
+static void ir_driver_tx_gdma_init(uint32_t source_addr, uint32_t buffer_size);
+
+static void ir_send_int_handler(void) DATA_RAM_FUNCTION;
+static void ir_send_rtc_handler(void) DATA_RAM_FUNCTION;
+
+void ir_tx_gdma_handler(void) DATA_RAM_FUNCTION;
+bool ir_send_check_dlps(void) DATA_RAM_FUNCTION;
+void ir_send_enter_dlps_config(void) DATA_RAM_FUNCTION;
+void ir_send_exit_dlps_config(void) DATA_RAM_FUNCTION;
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+
+/******************************************************************
+ * @brief initialization of pinmux settings and pad settings.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void ir_send_pad_and_pinmux_init(void)
+{
+ Pad_Config(IR_SEND_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
+ Pinmux_Config(IR_SEND_PIN, IRDA_TX);
+}
+
+/******************************************************************
+ * @brief Initialize IR send peripheral.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void ir_send_driver_init(void)
+{
+ /* Enable IR clock */
+ RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, DISABLE);
+ RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, ENABLE);
+
+ /* Initialize IR */
+ IR_InitTypeDef IR_InitStruct;
+ IR_StructInit(&IR_InitStruct);
+ IR_InitStruct.IR_Freq = ir_send_struct.p_ir_send_data->carrier_frequency_hz;
+ IR_InitStruct.IR_DutyCycle = ir_send_struct.p_ir_send_data->duty_cycle;
+ IR_InitStruct.IR_Mode = IR_MODE_TX;
+ IR_InitStruct.IR_TxInverse = IR_TX_DATA_NORMAL;
+ IR_InitStruct.IR_TxFIFOThrLevel = IR_TX_FIFO_THR_LEVEL;
+ IR_InitStruct.IR_TxDmaEn = ENABLE;
+ IR_InitStruct.IR_TxWaterLevel = 28;
+ IR_Init(&IR_InitStruct);
+
+ /*must disable IR TX first*/
+ IR_Cmd(IR_MODE_TX, DISABLE);
+
+ /* Configure NVIC */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = IR_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 2;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ /* Modify IR interrupt handle */
+ RamVectorTableUpdate(IR_VECTORn, ir_send_int_handler);
+}
+
+/******************************************************************
+ * @brief Initialize GDMA peripheral for IR TX.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void ir_driver_tx_gdma_init(uint32_t source_addr, uint32_t buffer_size)
+{
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+ GDMA_InitTypeDef GDMA_InitStruct;
+
+ /*--------------GDMA init-----------------------------*/
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = IR_TX_GDMA_Channel_num;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&IR->TX_FIFO);
+ GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_IR_TX;
+ GDMA_InitStruct.GDMA_BufferSize = buffer_size + 1;
+ GDMA_InitStruct.GDMA_SourceAddr = source_addr;
+ GDMA_Init(IR_TX_GDMA_CHANNEL, &GDMA_InitStruct);
+ GDMA_INTConfig(IR_TX_GDMA_Channel_num, GDMA_INT_Transfer, ENABLE);
+
+ /*-----------------GDMA IRQ init-------------------*/
+ NVIC_InitTypeDef nvic_init_struct;
+ nvic_init_struct.NVIC_IRQChannel = IR_TX_GDMA_Channel_IRQn;
+ nvic_init_struct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ nvic_init_struct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&nvic_init_struct);
+}
+
+/******************************************************************
+ * @brief Deinitialize GDMA peripheral for IR TX.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void ir_driver_tx_gdma_deinit(void)
+{
+ GDMA_Cmd(IR_TX_GDMA_Channel_num, DISABLE);
+}
+
+/******************************************************************
+ * @brief IR interrupt handler function for IR sending.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void ir_send_int_handler(void)
+{
+ /* Must Read INT Status first */
+ ITStatus int_status = IR_GetINTStatus(IR_INT_TF_EMPTY);
+
+ /* Mask IR interrupt */
+ IR_MaskINTConfig(IR_INT_TF_EMPTY, ENABLE);
+
+ if (int_status == SET)
+ {
+ APP_PRINT_INFO0("[IR] IR_INT_TF_EMPTY");
+
+ IR_ClearINTPendingBit(IR_INT_TF_EMPTY_CLR);
+
+ if (ir_send_struct.ir_send_state == IR_SEND_CAMMAND)
+ {
+ ir_send_struct.ir_send_state = IR_SEND_CAMMAND_COMPLETE;
+ }
+ else if (ir_send_struct.ir_send_state == IR_SEND_REPEAT_CODE)
+ {
+ ir_send_struct.ir_send_state = IR_SEND_REPEAT_CODE_COMPLETE;
+ }
+ T_IO_MSG bee_io_msg;
+ bee_io_msg.type = IO_MSG_TYPE_IR;
+ bee_io_msg.subtype = IO_MSG_TYPE_IR_SEND_COMPLETE;
+ if (false == app_send_msg_to_apptask(&bee_io_msg))
+ {
+ APP_PRINT_ERROR0("[ir_send_int_handler] Send IO_MSG_TYPE_IR message failed!");
+ }
+ }
+}
+
+/******************************************************************
+ * @brief RTC interrupt handle function for IR sending repeat code.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void ir_send_rtc_handler(void)
+{
+ APP_PRINT_INFO0("[IR] IR Repeat Code RTC Handler.");
+
+ T_IO_MSG bee_io_msg;
+ bee_io_msg.type = IO_MSG_TYPE_IR;
+ bee_io_msg.subtype = IO_MSG_TYPE_IR_START_SEND_REPEAT_CODE;
+ if (false == app_send_msg_to_apptask(&bee_io_msg))
+ {
+ APP_PRINT_ERROR0("[ir_send_rtc_handler] Send IO_MSG_TYPE_IR message failed!");
+ }
+}
+
+/******************************************************************
+ * @brief start function of sending IR sequence 1.
+ * @param none
+ * @return start successfully or not
+ * @retval true or false
+ */
+bool ir_send_start_seq_1(void)
+{
+ if (ir_send_struct.p_ir_send_data->carrier_frequency_hz < 5000 ||
+ ir_send_struct.p_ir_send_data->carrier_frequency_hz > 2000000)
+ {
+ APP_PRINT_INFO0("[IR] ir send command start fail, carrier frequency <5KHz or >2MHz.");
+ return false;
+ }
+ APP_PRINT_INFO0("[IR] ir send start command.");
+
+ /*init gdma*/
+ ir_driver_tx_gdma_init((uint32_t)ir_send_struct.p_ir_send_data->ir_seq_buf_1,
+ ir_send_struct.p_ir_send_data->ir_seq_len_1);
+ /*
+ 1. disable IR TX
+ 2. enable IR_INT_TF_EMPTY
+ 3. enable gdma and IR TX
+ */
+ IR_Cmd(IR_MODE_TX, DISABLE);
+ IR_MaskINTConfig(IR_INT_TF_EMPTY, DISABLE);
+ IR_INTConfig(IR_INT_TF_EMPTY, ENABLE);
+ GDMA_Cmd(IR_TX_GDMA_Channel_num, ENABLE);
+ IR_Cmd(IR_MODE_TX, ENABLE);
+
+ /*enable RTC*/
+ rtc_driver_set_comp_0_params(ir_send_struct.p_ir_send_data->ir_seq_timeout_ms_1,
+ ir_send_rtc_handler);
+
+ ir_send_struct.ir_send_state = IR_SEND_CAMMAND;
+
+ return true;
+}
+
+/******************************************************************
+ * @brief start function of sending IR seq 2.
+ * @param none
+ * @return start successfully or not
+ * @retval true or false
+ */
+bool ir_send_start_seq_2(void)
+{
+ if (ir_send_struct.p_ir_send_data->carrier_frequency_hz < 5000 ||
+ ir_send_struct.p_ir_send_data->carrier_frequency_hz > 2000000)
+ {
+ APP_PRINT_INFO0("[IR] ERR: ir send carrier frequency <5KHz or >2MHz.");
+ return false;
+ }
+
+ if (ir_send_struct.p_ir_send_data->ir_seq_len_2 == 0)
+ {
+ APP_PRINT_INFO0("[IR] ERR: ir send repeat buffer length is 0.");
+ return false;
+ }
+
+ APP_PRINT_INFO0("[IR] ir send start repeat code.");
+ /*init gdma*/
+ ir_driver_tx_gdma_init((uint32_t)ir_send_struct.p_ir_send_data->ir_seq_buf_2,
+ ir_send_struct.p_ir_send_data->ir_seq_len_2);
+ /*
+ 1. disable IR TX
+ 2. enable IR_INT_TF_EMPTY
+ 3. enable gdma and IR TX
+ */
+ IR_Cmd(IR_MODE_TX, DISABLE);
+ IR_MaskINTConfig(IR_INT_TF_EMPTY, DISABLE);
+ IR_INTConfig(IR_INT_TF_EMPTY, ENABLE);
+ GDMA_Cmd(IR_TX_GDMA_Channel_num, ENABLE);
+ IR_Cmd(IR_MODE_TX, ENABLE);
+
+ /*enable RTC*/
+ rtc_driver_set_comp_0_params(ir_send_struct.p_ir_send_data->ir_seq_timeout_ms_2,
+ ir_send_rtc_handler);
+
+ ir_send_struct.ir_send_state = IR_SEND_REPEAT_CODE;
+
+ return true;
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief GDMA interrupt handler function for IR TX.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void ir_tx_gdma_handler(void)
+{
+ APP_PRINT_INFO0("[ir_tx_gdma_handler] GDMA interrupt!");
+ GDMA_ClearINTPendingBit(IR_TX_GDMA_Channel_num, GDMA_INT_Transfer);
+}
+
+/******************************************************************
+ * @brief convert time and frequency to carrier cycle.
+ * @param time - time of waveform.
+ * @param carrier_cycle - cycle of carrier.
+ * @return vaule of data whose unit is cycle of carrier.
+ */
+uint32_t ir_send_convert_to_carrier_cycle(uint32_t time, uint32_t freq)
+{
+ return ((time & PULSE_HIGH) | ((time & IR_DATA_MSK) * freq / 1000000));
+}
+
+/******************************************************************
+ * @brief check if ir send is working.
+ * @param none
+ * @return if ir send is working
+ * @retval true or false
+ */
+bool ir_send_is_working(void)
+{
+ if (ir_send_struct.ir_send_state == IR_SEND_IDLE)
+ {
+ return false;
+ }
+ return true;
+}
+
+/******************************************************************
+ * @brief check ir send if allow enter dlps.
+ * @param none
+ * @return if allow enter dlps
+ * @retval true or false
+ */
+bool ir_send_check_dlps(void)
+{
+ /*ir send in idle or send complete*/
+ if (ir_send_struct.ir_send_state == IR_SEND_IDLE)
+ {
+ return true;
+ }
+
+ /*ir send not in idle and not send completed*/
+ return false;
+}
+
+/******************************************************************
+ * @brief ir send enter DLPS config
+ * @param none
+ * @return none
+ * @retval void
+ */
+void ir_send_enter_dlps_config(void)
+{
+ Pad_Config(IR_SEND_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
+}
+
+/******************************************************************
+ * @brief ir send exit DLPS config
+ * @param none
+ * @return none
+ * @retval void
+ */
+void ir_send_exit_dlps_config(void)
+{
+ Pad_Config(IR_SEND_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
+}
+
+/******************************************************************
+ * @brief get ir send current state
+ * @param none
+ * @return ir send current state
+ * @retval T_IR_SEND_STATE
+ */
+T_IR_SEND_STATE ir_send_get_current_state(void)
+{
+ return ir_send_struct.ir_send_state;
+}
+
+/******************************************************************
+ * @brief Initialize IR send module
+ * @param key_value - pressed key value
+ * @return result of initialization
+ * @retval true or false
+ */
+bool ir_send_module_init(T_IR_SEND_PARA *p_ir_send_para)
+{
+ if (p_ir_send_para == NULL)
+ {
+ APP_PRINT_INFO0("[IR] ir send module init fail, p_ir_send_para is NULL.");
+ return false;
+ }
+ ir_send_struct.p_ir_send_data = p_ir_send_para;
+ if (ir_send_struct.p_ir_send_data->carrier_frequency_hz < 5000 ||
+ ir_send_struct.p_ir_send_data->carrier_frequency_hz > 2000000)
+ {
+ APP_PRINT_INFO0("[IR] ir send module init fail, carrier frequency <5KHz or >2MHz.");
+ return false;
+ }
+ if (ir_send_struct.p_ir_send_data->duty_cycle <= 0)
+ {
+ APP_PRINT_INFO0("[IR] ir send module init fail, duty_cycle is invalid.");
+ return false;
+ }
+ ir_send_pad_and_pinmux_init();
+ ir_send_driver_init();
+
+ APP_PRINT_INFO0("[IR] ir send module init success.");
+ return true;
+}
+
+/******************************************************************
+ * @brief start function of sending IR command.
+ * @param none
+ * @return start successfully or not
+ * @retval true or false
+ */
+bool ir_send_command_start(void)
+{
+ bool result = false;
+ T_IR_SEND_TYPE ir_send_type = (T_IR_SEND_TYPE)ir_send_struct.p_ir_send_data->ir_send_type;
+
+ switch (ir_send_type)
+ {
+ case IR_SEND_TYPE_DISABLE:
+ break;
+
+ case IR_SEND_TYPE_ONE_TIME:
+ case IR_SEND_TYPE_ONE_TIME_PLUS_REP_SEQ:
+ case IR_SEND_TYPE_REPEATED_SEQ:
+ {
+ result = ir_send_start_seq_1();
+ }
+ break;
+
+ case IR_SEND_TYPE_TWO_REP_SEQ:
+ {
+ if (key_handle_get_key_pressed_count() % 2)
+ {
+ result = ir_send_start_seq_1();
+ }
+ else
+ {
+ result = ir_send_start_seq_2();
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ APP_PRINT_INFO2("[ir_send_command_start] type = %d, result = %d", ir_send_type, result);
+
+ return result;
+}
+
+/******************************************************************
+ * @brief start function of sending IR repeat code.
+ * @param none
+ * @return start successfully or not
+ * @retval true or false
+ */
+bool ir_send_repeat_code_start(void)
+{
+ bool result = false;
+ T_IR_SEND_TYPE ir_send_type = (T_IR_SEND_TYPE)ir_send_struct.p_ir_send_data->ir_send_type;
+
+ switch (ir_send_type)
+ {
+ case IR_SEND_TYPE_DISABLE:
+ case IR_SEND_TYPE_ONE_TIME:
+ break;
+
+ case IR_SEND_TYPE_REPEATED_SEQ:
+ {
+ result = ir_send_start_seq_1();
+ }
+ break;
+
+ case IR_SEND_TYPE_ONE_TIME_PLUS_REP_SEQ:
+ {
+ result = ir_send_start_seq_2();
+ }
+ break;
+
+ case IR_SEND_TYPE_TWO_REP_SEQ:
+ {
+ if (key_handle_get_key_pressed_count() % 2)
+ {
+ result = ir_send_start_seq_1();
+ }
+ else
+ {
+ result = ir_send_start_seq_2();
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ APP_PRINT_INFO2("[ir_send_repeat_code_start] type = %d, result = %d", ir_send_type, result);
+
+ return result;
+}
+
+/******************************************************************
+ * @brief exit IR sending.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void ir_send_exit(void)
+{
+ APP_PRINT_INFO0("[IR] ir send exit.");
+
+ rtc_driver_clear_comp_0();
+
+ ir_driver_tx_gdma_deinit();
+
+ IR_DeInit();
+ IR_INTConfig(IR_INT_TF_EMPTY, DISABLE);
+
+ ir_send_struct.ir_send_state = IR_SEND_IDLE;
+}
+
+#endif /*end Micro @SUPPORT_IR_TX_FEATURE*/
+
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/ir_module/ir_send_driver.h b/src/app/google_rcu/ir_module/ir_send_driver.h
new file mode 100644
index 0000000..2e01b9f
--- /dev/null
+++ b/src/app/google_rcu/ir_module/ir_send_driver.h
@@ -0,0 +1,119 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ir_send_driver.h
+* @brief
+* @details
+* @author barry_bian
+* @date 2020-04-08
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __IR_SEND_DRIVER_H_
+#define __IR_SEND_DRIVER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "board.h"
+#include "stdint.h"
+#include "stdbool.h"
+
+/*============================================================================*
+ * IR Send config
+ *============================================================================*/
+#define IR_TX_GDMA_CHANNEL GDMA_Channel1
+#define IR_TX_GDMA_Channel_num 1
+#define IR_TX_GDMA_Channel_IRQn GDMA0_Channel1_IRQn
+#define ir_tx_gdma_handler GDMA0_Channel1_Handler
+
+#define IR_SEND_WAVE_MAX_LEN 200
+#define IR_REPEAT_CODE_MAX_LEN 200
+
+#define IR_DUTY_CYCLE 3
+
+#define PULSE_HIGH ((uint32_t)0x80000000)
+#define PULSE_LOW 0x0
+#define LOG_HIGH 1
+#define LOG_LOW 0
+#define IR_DATA_MSK 0x7fffffffUL
+
+#define IR_TX_FIFO_THR_LEVEL 2
+
+typedef enum
+{
+ IR_SEND_KEY_PRESS,
+ IR_SEND_KEY_RELEASE,
+} T_IR_SEND_KEY_STATE;
+
+typedef enum
+{
+ IR_SEND_IDLE,
+ IR_SEND_CAMMAND,
+ IR_SEND_CAMMAND_COMPLETE,
+ IR_SEND_REPEAT_CODE,
+ IR_SEND_REPEAT_CODE_COMPLETE,
+} T_IR_SEND_STATE;
+
+typedef enum
+{
+ IRDA_ERROR = -1,
+ IRDA_SUCCEED = 0,
+ IRDA_HEADER_ERROR = 1,
+ IRDA_DATA_ERROR
+} T_IRDA_RET;
+
+typedef enum
+{
+ IR_SEND_TYPE_DISABLE = 0,
+ IR_SEND_TYPE_ONE_TIME = 1,
+ IR_SEND_TYPE_REPEATED_SEQ = 2,
+ IR_SEND_TYPE_ONE_TIME_PLUS_REP_SEQ = 3,
+ IR_SEND_TYPE_TWO_REP_SEQ = 4
+} T_IR_SEND_TYPE;
+
+typedef struct
+{
+ uint8_t ir_send_type;
+ float carrier_frequency_hz;
+ float duty_cycle;
+ uint32_t ir_seq_buf_1[IR_SEND_WAVE_MAX_LEN];
+ uint32_t ir_seq_len_1;
+ uint32_t ir_seq_buf_2[IR_SEND_WAVE_MAX_LEN];
+ uint32_t ir_seq_len_2;
+ uint32_t ir_seq_timeout_ms_1;
+ uint32_t ir_seq_timeout_ms_2;
+} T_IR_SEND_PARA;
+
+typedef struct
+{
+ T_IR_SEND_STATE ir_send_state; /*ir send state*/
+ T_IR_SEND_PARA *p_ir_send_data;
+} T_IR_SEND_STRUCT;
+
+
+
+bool ir_send_check_dlps(void);
+bool ir_send_is_working(void);
+void ir_send_enter_dlps_config(void);
+void ir_send_exit_dlps_config(void);
+T_IR_SEND_STATE ir_send_get_current_state(void);
+bool ir_send_module_init(T_IR_SEND_PARA *ir_send_para);
+bool ir_send_command_start(void);
+bool ir_send_repeat_code_start(void);
+bool ir_send_start_seq_2(void);
+void ir_send_exit(void);
+uint32_t ir_send_convert_to_carrier_cycle(uint32_t time, uint32_t freq);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__IR_APP_CONFIG_H_*/
+
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/ir_module/ir_send_handle.c b/src/app/google_rcu/ir_module/ir_send_handle.c
new file mode 100644
index 0000000..dba98d5
--- /dev/null
+++ b/src/app/google_rcu/ir_module/ir_send_handle.c
@@ -0,0 +1,388 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_send_handle.c
+* @brief This file provides IR sending data handler by interrupt.
+* @details Application users can use the global functions to send IR data.
+* @author barry_bian
+* @date 2020-02-26
+* @version v1.1
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "board.h"
+#include "trace.h"
+#include "string.h"
+#include "rtl876x_ir.h"
+#include "app_msg.h"
+#include "ir_protocol_nec.h"
+#include "ir_send_driver.h"
+#include "ir_send_handle.h"
+#include "ir_service_handle.h"
+#include "key_handle.h"
+
+#if SUPPORT_IR_TX_FEATURE
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+static T_IR_SEND_KEY_STATE ir_send_key_state = IR_SEND_KEY_RELEASE;
+static T_IR_SEND_PARA ir_send_parameters;
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/******************************************************************
+* @brief encode ir send command data
+* @param T_IR_PROTOCOL protocol
+* @param uint8_t ir_key_command
+* @param T_IR_SEND_PARA *p_ir_send_parameters
+* @return result
+* @retval T_IRDA_RET
+*/
+static T_IRDA_RET ir_send_command_encode(T_IR_PROTOCOL ir_protocol, IR_KEY_CODE ir_key_code,
+ T_IR_SEND_PARA *p_ir_send_parameters)
+{
+ T_IRDA_RET ret = IRDA_SUCCEED;
+
+ switch (ir_protocol)
+ {
+ case NEC_PROTOCOL:
+ ret = ir_protocol_nec_command_encode(ir_key_code, p_ir_send_parameters);
+ if (ret == IRDA_SUCCEED)
+ {
+ ret = ir_protocol_nec_repeat_code_encode(p_ir_send_parameters);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+/******************************************************************
+* @brief encode ir send repeat code data
+* @param T_IR_PROTOCOL protocol
+* @param uint8_t ir_key_command
+* @param T_IR_SEND_PARA *p_ir_send_parameters
+* @return result
+* @retval T_IRDA_RET
+*/
+T_IRDA_RET ir_send_repeat_code_encode(T_IR_PROTOCOL ir_protocol, IR_KEY_CODE ir_key_code,
+ T_IR_SEND_PARA *p_ir_send_parameters)
+{
+ T_IRDA_RET ret = IRDA_SUCCEED;
+
+ switch (ir_protocol)
+ {
+ case NEC_PROTOCOL:
+ ret = ir_protocol_nec_repeat_code_encode(p_ir_send_parameters);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+/******************************************************************
+* @brief ir_send_raw_encode
+* @param key_index
+* @return result
+* @retval true or false
+*/
+bool ir_send_raw_encode(T_KEY_INDEX_DEF key_index)
+{
+ bool result = false;
+ uint32_t code_size = 0;
+ uint8_t code[MAX_CODE_LENGTH];
+ uint32_t data_index = 0;
+ uint8_t duty_cycle = 0;
+ uint16_t carrier_freq = 0;
+ uint16_t seq_len_1 = 0;
+ uint16_t seq_len_2 = 0;
+ uint16_t repeat_delay;
+ uint16_t on_data_value;
+ uint16_t off_data_value;
+ uint32_t total_cycle_cnt;
+
+ if (true == ir_service_handle_get_key_code_by_key_id((uint8_t)key_index, &code_size, code))
+ {
+ /* get code type */
+ ir_send_parameters.ir_send_type = code[data_index++];
+
+ if (code_size >= 8)
+ {
+ data_index = 1;
+ duty_cycle = code[data_index++];
+ if (duty_cycle == 0)
+ {
+ duty_cycle = 50;
+ }
+ ir_send_parameters.duty_cycle = 100 / (float)duty_cycle;
+
+ carrier_freq = ((uint16_t)code[data_index] << 8) + code[data_index + 1];
+ data_index += 2;
+ if (carrier_freq == 0)
+ {
+ carrier_freq = 380;
+ }
+ ir_send_parameters.carrier_frequency_hz = carrier_freq * 100;
+
+ seq_len_1 = ((uint16_t)code[data_index] << 8) + code[data_index + 1];
+ data_index += 2;
+
+ seq_len_2 = ((uint16_t)code[data_index] << 8) + code[data_index + 1];
+ data_index += 2;
+ repeat_delay = seq_len_2;
+ }
+
+ if ((ir_send_parameters.ir_send_type == IR_SEND_TYPE_ONE_TIME)
+ && (code_size >= seq_len_1 * 4 + 6))
+ {
+ data_index = 6;
+ total_cycle_cnt = 0;
+
+ for (uint8_t loop_index = 0; loop_index < seq_len_1; loop_index++)
+ {
+ on_data_value = ((uint16_t)code[data_index] << 8) + code[data_index + 1];
+ off_data_value = ((uint16_t)code[data_index + 2] << 8) + code[data_index + 3];
+ data_index += 4;
+ total_cycle_cnt += on_data_value + off_data_value;
+
+ ir_send_parameters.ir_seq_buf_1[2 * loop_index] = on_data_value | PULSE_HIGH;
+ ir_send_parameters.ir_seq_buf_1[2 * loop_index + 1] = off_data_value;
+ }
+ ir_send_parameters.ir_seq_len_1 = seq_len_1 * 2;
+ if (carrier_freq != 0)
+ {
+ ir_send_parameters.ir_seq_timeout_ms_1 = (total_cycle_cnt * 10 + (carrier_freq >> 1)) /
+ carrier_freq;
+ }
+ result = true;
+ }
+ else if ((ir_send_parameters.ir_send_type == IR_SEND_TYPE_REPEATED_SEQ)
+ && (code_size >= seq_len_1 * 4 + 8))
+ {
+ data_index = 8;
+ total_cycle_cnt = 0;
+
+ for (uint8_t loop_index = 0; loop_index < seq_len_1; loop_index++)
+ {
+ on_data_value = ((uint16_t)code[data_index] << 8) + code[data_index + 1];
+ off_data_value = ((uint16_t)code[data_index + 2] << 8) + code[data_index + 3];
+ data_index += 4;
+ total_cycle_cnt += on_data_value + off_data_value;
+
+ ir_send_parameters.ir_seq_buf_1[2 * loop_index] = on_data_value | PULSE_HIGH;
+ ir_send_parameters.ir_seq_buf_1[2 * loop_index + 1] = off_data_value;
+ }
+ ir_send_parameters.ir_seq_len_1 = seq_len_1 * 2;
+ ir_send_parameters.ir_seq_timeout_ms_1 = (repeat_delay * 10 + (carrier_freq >> 1)) / carrier_freq;
+
+ result = true;
+ }
+ else if ((ir_send_parameters.ir_send_type == IR_SEND_TYPE_ONE_TIME_PLUS_REP_SEQ)
+ || (ir_send_parameters.ir_send_type == IR_SEND_TYPE_TWO_REP_SEQ))
+ {
+ if (code_size >= seq_len_1 * 4 + seq_len_2 * 4 + 8)
+ {
+ data_index = 8;
+
+ total_cycle_cnt = 0;
+ for (uint8_t loop_index = 0; loop_index < seq_len_1; loop_index++)
+ {
+ on_data_value = ((uint16_t)code[data_index] << 8) + code[data_index + 1];
+ off_data_value = ((uint16_t)code[data_index + 2] << 8) + code[data_index + 3];
+ data_index += 4;
+ total_cycle_cnt += on_data_value + off_data_value;
+
+ ir_send_parameters.ir_seq_buf_1[2 * loop_index] = on_data_value | PULSE_HIGH;
+ ir_send_parameters.ir_seq_buf_1[2 * loop_index + 1] = off_data_value;
+ }
+ ir_send_parameters.ir_seq_len_1 = seq_len_1 * 2;
+ ir_send_parameters.ir_seq_timeout_ms_1 = (total_cycle_cnt * 10 + (carrier_freq >> 1)) /
+ carrier_freq;
+
+ total_cycle_cnt = 0;
+ for (uint8_t loop_index = 0; loop_index < seq_len_2; loop_index++)
+ {
+ on_data_value = ((uint16_t)code[data_index] << 8) + code[data_index + 1];
+ off_data_value = ((uint16_t)code[data_index + 2] << 8) + code[data_index + 3];
+ data_index += 4;
+ total_cycle_cnt += on_data_value + off_data_value;
+
+ ir_send_parameters.ir_seq_buf_2[2 * loop_index] = on_data_value | PULSE_HIGH;
+ ir_send_parameters.ir_seq_buf_2[2 * loop_index + 1] = off_data_value;
+ }
+ ir_send_parameters.ir_seq_len_2 = seq_len_2 * 2;
+ ir_send_parameters.ir_seq_timeout_ms_2 = (total_cycle_cnt * 10 + (carrier_freq >> 1)) /
+ carrier_freq;
+
+ result = true;
+ }
+ }
+ }
+ else
+ {
+ APP_PRINT_WARN0("[ir_send_key_press_handle] Failed to get key code");
+ }
+
+ APP_PRINT_INFO4("[ir_send_raw_encode] carrier_freq = %d, duty_cycle = %d, seq_len_1 = %d, seq_len_2 = %d",
+ carrier_freq, duty_cycle, seq_len_1, seq_len_2);
+ APP_PRINT_INFO4("[ir_send_raw_encode] key_index = %d, result = %d, ir_send_type = %d, code_size = %d",
+ key_index,
+ result, ir_send_parameters.ir_send_type, code_size);
+
+ return result;
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief IR app send message process.
+ * @param msg_sub_type - message subtype
+ * @return none
+ * @retval void
+ */
+void ir_send_msg_proc(uint16_t msg_sub_type)
+{
+ APP_PRINT_INFO2("[ir_send_msg_proc] msg_sub_type is %d, ir_send_get_current_state is %d",
+ msg_sub_type, ir_send_get_current_state());
+
+ if (ir_send_key_state == IR_SEND_KEY_RELEASE)
+ {
+ ir_send_exit();
+ return;
+ }
+
+ if (msg_sub_type == IO_MSG_TYPE_IR_START_SEND_REPEAT_CODE)
+ {
+ if (ir_send_get_current_state() == IR_SEND_CAMMAND_COMPLETE ||
+ ir_send_get_current_state() == IR_SEND_REPEAT_CODE_COMPLETE)
+ {
+ if (false == ir_send_repeat_code_start())
+ {
+ ir_send_exit();
+ }
+ }
+ else
+ {
+ ir_send_exit();
+ }
+ }
+}
+
+/******************************************************************
+ * @brief Application code for IR send key press handle.
+ * @param T_KEY_INDEX_DEF ir_send_key_index
+ * @return none
+ * @retval void
+ */
+void ir_send_key_press_handle(T_KEY_INDEX_DEF ir_key_index, T_IR_PROTOCOL ir_protocol)
+{
+ bool result = false;
+ ir_send_key_state = IR_SEND_KEY_PRESS;
+
+ memset(&ir_send_parameters, 0, sizeof(T_IR_SEND_PARA));
+
+ if (ir_protocol == NEC_PROTOCOL)
+ {
+ IR_KEY_CODE ir_code = key_handle_get_ir_key_code_by_index(ir_key_index);
+ ir_send_command_encode(NEC_PROTOCOL, ir_code, &ir_send_parameters);
+ ir_send_parameters.ir_send_type = IR_SEND_TYPE_ONE_TIME_PLUS_REP_SEQ;
+ result = true;
+ }
+ else if (ir_protocol == RAW_PROTOCOL)
+ {
+ result = ir_send_raw_encode(ir_key_index);
+ }
+ else
+ {
+ APP_PRINT_WARN1("[ir_send_key_press_handle] Unknown ir_protocol is %d", ir_protocol);
+ result = false;
+ }
+
+
+ if ((result == true)
+ && (true == ir_send_module_init(&ir_send_parameters)))
+ {
+ result = ir_send_command_start();
+ }
+
+ APP_PRINT_INFO2("[IR] ir send key press, ir_protocol is %d, result is %d", ir_protocol, result);
+}
+
+/******************************************************************
+ * @brief Application code for IR send data one time handle.
+ * @param T_KEY_INDEX_DEF ir_send_key_index
+ * @return none
+ * @retval void
+ */
+void ir_send_data_one_time_handle(T_KEY_INDEX_DEF ir_key_index, T_IR_PROTOCOL ir_protocol)
+{
+ bool result = false;
+ ir_send_key_state = IR_SEND_KEY_PRESS;
+
+ memset(&ir_send_parameters, 0, sizeof(T_IR_SEND_PARA));
+
+ if (ir_protocol == NEC_PROTOCOL)
+ {
+ IR_KEY_CODE ir_code = key_handle_get_ir_key_code_by_index(ir_key_index);
+ ir_send_command_encode(NEC_PROTOCOL, ir_code, &ir_send_parameters);
+ ir_send_parameters.ir_send_type = IR_SEND_TYPE_ONE_TIME;
+ result = true;
+ }
+ else if (ir_protocol == RAW_PROTOCOL)
+ {
+ result = ir_send_raw_encode(ir_key_index);
+ }
+ else
+ {
+ APP_PRINT_WARN1("[ir_send_data_one_time_handle] Unknown ir_protocol is %d", ir_protocol);
+ result = false;
+ }
+
+
+ if ((result == true)
+ && (true == ir_send_module_init(&ir_send_parameters)))
+ {
+ result = ir_send_command_start();
+ }
+
+ APP_PRINT_INFO2("[IR] ir_send_data_one_time, ir_protocol is %d, result is %d", ir_protocol, result);
+}
+/******************************************************************
+ * @brief Application code for IR send key release handle.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void ir_send_key_release_handle(void)
+{
+ APP_PRINT_INFO0("[IR] ir send key release.");
+ ir_send_key_state = IR_SEND_KEY_RELEASE;
+
+ if (ir_send_is_working() == false)
+ {
+ return;
+ }
+
+ if (ir_send_get_current_state() != IR_SEND_CAMMAND &&
+ ir_send_get_current_state() != IR_SEND_REPEAT_CODE)
+ {
+ ir_send_exit();
+ }
+}
+
+#endif /*end Micro @SUPPORT_IR_TX_FEATURE*/
+
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/ir_module/ir_send_handle.h b/src/app/google_rcu/ir_module/ir_send_handle.h
new file mode 100644
index 0000000..8d127a9
--- /dev/null
+++ b/src/app/google_rcu/ir_module/ir_send_handle.h
@@ -0,0 +1,46 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ir_send_handle.h
+* @brief
+* @details
+* @author barry_bian
+* @date 2020-04-08
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __IR_SEND_HANDLE_H_
+#define __IR_SEND_HANDLE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "board.h"
+#include "stdint.h"
+#include "stdbool.h"
+#include "ir_send_driver.h"
+#include "key_handle.h"
+
+typedef enum
+{
+ NEC_PROTOCOL = 0,
+ RAW_PROTOCOL = 1,
+} T_IR_PROTOCOL;
+
+void ir_send_msg_proc(uint16_t msg_sub_type);
+void ir_send_key_press_handle(T_KEY_INDEX_DEF ir_key_index, T_IR_PROTOCOL ir_protocol);
+void ir_send_data_one_time_handle(T_KEY_INDEX_DEF ir_key_index, T_IR_PROTOCOL ir_protocol);
+void ir_send_key_release_handle(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__IR_APP_CONFIG_H_*/
+
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/ir_module/ir_service_handle.c b/src/app/google_rcu/ir_module/ir_service_handle.c
new file mode 100644
index 0000000..f1e2174
--- /dev/null
+++ b/src/app/google_rcu/ir_module/ir_service_handle.c
@@ -0,0 +1,851 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_service_handle.c
+* @brief This is the entry of user code which the IR service handle module resides in.
+* @details
+* @author chenjie jin
+* @date 2022-03-22
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include "board.h"
+#include "ir_service_handle.h"
+#include "ir_service.h"
+#include "trace.h"
+#include "profile_server.h"
+#include "rcu_application.h"
+#include "flash_map.h"
+#include "os_timer.h"
+#include "swtimer.h"
+#include "os_mem.h"
+#include "ftl.h"
+#include "flash_device.h"
+#include "key_handle.h"
+#include "app_task.h"
+
+#if FEAUTRE_SUPPORT_IR_OVER_BLE
+
+/*============================================================================*
+ * Static Variables
+ *============================================================================*/
+static uint32_t IR_Table_FTL_Addr_Info[MAX_PROG_KEY_COUNT] =
+{FTL_IR_TABLE_SEC_0_ADDR, FTL_IR_TABLE_SEC_1_ADDR, FTL_IR_TABLE_SEC_2_ADDR, FTL_IR_TABLE_SEC_3_ADDR, FTL_IR_TABLE_SEC_4_ADDR};
+
+static TimerHandle_t ir_programing_timer;
+
+_attribute_data_retention_ app_nec_ir_table_sts nec_ir_table_start = APP_NEC_IR_TABLE_END;
+
+//keyid: receive from the host. button_idx: Corresponding to the key index in the memory ir_table[].rcu_key_id:The actual keyid corresponding to the board
+const key_button_pair_t key_button_map_g10[MAX_PROG_KEY_COUNT] =
+{
+ {0x0018, KEY_ID_VolUp},
+ {0x0019, KEY_ID_VolDown},
+ {0x00A4, KEY_ID_Mute},
+ {0x001A, KEY_ID_Power},
+ {0x00B2, KEY_ID_Input}
+};
+
+//keyid: receive from the host. button_idx: Corresponding to the key index in the memory ir_table[].rcu_key_id:The actual keyid corresponding to the board
+const key_button_pair_t key_button_map_g20[MAX_PROG_KEY_COUNT] =
+{
+ {0x0018, KEY_ID_VolUp},
+ {0x0019, KEY_ID_VolDown},
+ {0x00A4, KEY_ID_Mute},
+ {0x001A, KEY_ID_Power},
+ {0x00B2, KEY_ID_Input}
+};
+
+static _attribute_data_retention_ key_code_t ir_table[MAX_PROG_KEY_COUNT] = {{0}, {0}, {0}, {0}, {0}};
+
+/*============================================================================*
+ * Global Variables
+ *============================================================================*/
+T_IR_SVC_HANDLE_GLOBAL_DATA ir_svc_handle_global_data;
+
+/*============================================================================*
+ * Static Functions
+ *============================================================================*/
+static T_APP_RESULT ir_service_handle_write_prog_control_char(T_IR_WRITE_MSG *p_write);
+static T_APP_RESULT ir_service_handle_write_key_id_char(T_IR_WRITE_MSG *p_write);
+static T_APP_RESULT ir_service_handle_write_code_char(T_IR_WRITE_MSG *p_write);
+static T_APP_RESULT ir_service_handle_write_suppress_char(T_IR_WRITE_MSG *p_write);
+
+static T_APP_RESULT ir_service_handle_write_char_cb(T_IR_WRITE_MSG *p_write);
+static T_APP_RESULT ir_service_handle_read_char_cb(uint8_t read_value_index);
+static T_APP_RESULT ir_service_handle_indication_notification_char_cb(uint8_t
+ notification_indification_index);
+
+static void ir_service_handle_activate_ir_table(void);
+static void ir_service_handle_back_up_ftl_table(void);
+static void ir_service_handle_restore_ir_table_from_ftl(void);
+static bool ir_service_handle_ir_table_add_item(uint16_t atv_key_code, uint16_t data_len,
+ uint8_t *p_data);
+
+/******************************************************************
+ * @fn ir_service_handle_write_char_cb
+ * @brief IR service handle write char callback.
+ * @param p_write - pointer to write data
+ * @return T_APP_RESULT
+ */
+T_APP_RESULT ir_service_handle_write_char_cb(T_IR_WRITE_MSG *p_write)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ uint8_t write_type = p_write->write_type;
+ APP_PRINT_INFO1("[ir_service_handle_write_char_cb] write_type is %d", write_type);
+
+ switch (write_type)
+ {
+ case IR_WRITE_PROG_CONTROL:
+ {
+ ir_service_handle_write_prog_control_char(p_write);
+ }
+ break;
+ case IR_WRITE_KEY_ID:
+ {
+ ir_service_handle_write_key_id_char(p_write);
+ }
+ break;
+ case IR_WRITE_CODE:
+ {
+ ir_service_handle_write_code_char(p_write);
+ }
+ break;
+ case IR_WRITE_SUPPRESS:
+ {
+ ir_service_handle_write_suppress_char(p_write);
+ }
+ break;
+ default:
+ cb_result = APP_RESULT_APP_ERR;
+ break;
+ }
+
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn ir_service_handle_read_char_cb
+ * @brief IR service handle read char callback.
+ * @param read_value_index - read value index
+ * @return T_APP_RESULT
+ */
+T_APP_RESULT ir_service_handle_read_char_cb(uint8_t read_value_index)
+{
+ T_APP_RESULT cb_result = APP_RESULT_APP_ERR;
+
+ APP_PRINT_INFO1("[ir_service_handle_read_char_cb] read_value_index is %d", read_value_index);
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn ir_service_handle_indication_notification_char_cb
+ * @brief IR service handle indication notification char callback.
+ * @param notification_indification_index - notification or indication index
+ * @return T_APP_RESULT
+ */
+T_APP_RESULT ir_service_handle_indication_notification_char_cb(uint8_t
+ notification_indification_index)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ APP_PRINT_INFO1("[ir_service_handle_indication_notification_char_cb] notification_indification_index is %d",
+ notification_indification_index);
+
+ if (notification_indification_index == IR_KEY_EVNET_NOTIFY_ENABLE)
+ {
+ ir_svc_handle_global_data.key_notification_flag = 1;
+ }
+ else if (notification_indification_index == IR_KEY_EVNET_NOTIFY_DISABLE)
+ {
+ ir_svc_handle_global_data.key_notification_flag = 0;
+ }
+
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn ir_service_handle_write_prog_control_char
+ * @brief IR service handle write GATT_SVC_IR_PROG_CONTROL_INDEX callback.
+ * @param p_write - pointer to write data
+ * @return T_APP_RESULT
+ */
+T_APP_RESULT ir_service_handle_write_prog_control_char(T_IR_WRITE_MSG *p_write)
+{
+ uint32_t error_code = 0;
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+ uint16_t data_len = p_write->write_parameter.report_data.len;
+ uint8_t *p_data = p_write->write_parameter.report_data.report;
+
+ if (data_len == 1)
+ {
+ ir_svc_handle_global_data.programming_start = *p_data;
+ if (ir_svc_handle_global_data.programming_start == 1)
+ {
+ app_set_latency_status(LATENCY_IR_BLE_PROC_BIT, LANTENCY_OFF);
+ ir_svc_handle_global_data.programmed_key_count = 0;
+ ir_svc_handle_global_data.current_programming_key_id = INVALID_ATV_KEY_CODE;
+ ir_service_handle_reset_ir_table();
+
+ if (ir_programing_timer)
+ {
+ os_timer_restart(&ir_programing_timer, PROGRAMMING_TIMEOUT);
+ }
+ }
+ else
+ {
+ APP_PRINT_INFO1("[ir_service_handle_write_prog_control_char] ir table programming end, key_count = %d",
+ ir_svc_handle_global_data.programmed_key_count);
+
+ app_set_latency_status(LATENCY_IR_BLE_PROC_BIT, LANTENCY_ON);
+ if (ir_svc_handle_global_data.programmed_key_count > 0)
+ {
+ ir_service_handle_activate_ir_table();
+
+ /* send message to APP task for FTL back-up */
+ T_IO_MSG app_msg;
+ app_msg.type = IO_MSG_TYPE_IR_FLASH;
+ if (false == app_send_msg_to_apptask(&app_msg))
+ {
+ APP_PRINT_INFO0("[ir_service_handle_write_prog_control_char] send IO_MSG_IR_FLASH_SAVE failed");
+ cb_result = APP_RESULT_APP_ERR;
+ }
+ }
+
+ if (ir_programing_timer)
+ {
+ os_timer_stop(&ir_programing_timer);
+ }
+ }
+ }
+ else
+ {
+ cb_result = APP_RESULT_APP_ERR;
+ }
+
+ APP_PRINT_INFO3("[ir_service_handle_write_prog_control_char] data_len is %d, result is %d, error_code is %d",
+ data_len, cb_result, error_code);
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn ir_service_handle_write_key_id_char
+ * @brief IR service handle write GATT_SVC_IR_KEY_ID_INDEX callback.
+ * @param p_write - pointer to write data
+ * @return T_APP_RESULT
+ */
+T_APP_RESULT ir_service_handle_write_key_id_char(T_IR_WRITE_MSG *p_write)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+ uint16_t data_len = p_write->write_parameter.report_data.len;
+ uint8_t *p_data = p_write->write_parameter.report_data.report;
+
+ if ((ir_svc_handle_global_data.programming_start == 1) && (data_len == 2))
+ {
+ ir_svc_handle_global_data.current_programming_key_id = ((uint16_t)p_data[0] << 8) + p_data[1];
+
+ if (ir_programing_timer)
+ {
+ os_timer_restart(&ir_programing_timer, PROGRAMMING_TIMEOUT);
+ }
+ }
+ else
+ {
+ cb_result = APP_RESULT_APP_ERR;
+ }
+
+ APP_PRINT_INFO3("[ir_service_handle_write_key_id_char] data_len is %d, result is %d, atv_key_code is %d",
+ data_len, cb_result, ir_svc_handle_global_data.current_programming_key_id);
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn ir_service_handle_write_code_char
+ * @brief IR service handle write GATT_SVC_IR_CODE_INDEX callback.
+ * @param p_write - pointer to write data
+ * @return T_APP_RESULT
+ */
+T_APP_RESULT ir_service_handle_write_code_char(T_IR_WRITE_MSG *p_write)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+ uint16_t data_len = p_write->write_parameter.report_data.len;
+ uint8_t *p_data = p_write->write_parameter.report_data.report;
+
+ if ((ir_svc_handle_global_data.programming_start == 1) && (data_len > 0))
+ {
+ if (ir_svc_handle_global_data.current_programming_key_id != INVALID_ATV_KEY_CODE)
+ {
+ if (true == ir_service_handle_ir_table_add_item(
+ ir_svc_handle_global_data.current_programming_key_id, data_len, p_data))
+ {
+ cb_result = APP_RESULT_SUCCESS;
+ }
+ else
+ {
+ cb_result = APP_RESULT_APP_ERR;
+ }
+
+ ir_svc_handle_global_data.current_programming_key_id = INVALID_ATV_KEY_CODE;
+ }
+ else
+ {
+ cb_result = APP_RESULT_APP_ERR;
+ }
+
+ if (ir_programing_timer)
+ {
+ os_timer_restart(&ir_programing_timer, PROGRAMMING_TIMEOUT);
+ }
+ }
+ else
+ {
+ cb_result = APP_RESULT_APP_ERR;
+ }
+
+ APP_PRINT_INFO2("[ir_service_handle_write_code_char] data_len is %d, result is %d",
+ data_len, cb_result);
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn ir_service_handle_write_suppress_char
+ * @brief IR service handle write GATT_SVC_IR_SUPPRESS_INDEX callback.
+ * @param p_write - pointer to write data
+ * @return T_APP_RESULT
+ */
+T_APP_RESULT ir_service_handle_write_suppress_char(T_IR_WRITE_MSG *p_write)
+{
+ uint32_t error_code = 0;
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+ uint16_t data_len = p_write->write_parameter.report_data.len;
+ uint8_t *p_data = p_write->write_parameter.report_data.report;
+
+ if (data_len == 2)
+ {
+ ir_svc_handle_global_data.current_programming_key_id = ((uint16_t)p_data[0] << 8) + p_data[1];
+
+ uint8_t index = ir_service_handle_get_item_id_from_atv_id(
+ ir_svc_handle_global_data.current_programming_key_id);
+
+ if (index < MAX_PROG_KEY_COUNT)
+ {
+ if (ir_svc_handle_global_data.ir_suppress_table[index])
+ {
+ ir_svc_handle_global_data.ir_suppress_table[index] = 0;
+ }
+ else
+ {
+ ir_svc_handle_global_data.ir_suppress_table[index] = 1;
+ }
+ }
+ ir_svc_handle_global_data.current_programming_key_id = INVALID_ATV_KEY_CODE;
+ }
+ else
+ {
+ cb_result = APP_RESULT_APP_ERR;
+ }
+
+ APP_PRINT_INFO3("[ir_service_handle_write_suppress_char] data_len is %d, result is %d, error_code is %d",
+ data_len, cb_result, error_code);
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @brief ir programming timer callback
+ *
+ * ir_programming_timeoutcb is used to handle ir programming
+ *
+ * @param p_timer - timer handler
+ * @return none
+ * @retval void
+ */
+void ir_programming_timeoutcb(TimerHandle_t p_timer)
+{
+ APP_PRINT_INFO0("[ir_programming_timeoutcb] timeout");
+
+ ir_svc_handle_global_data.programming_start = 0;
+
+ if (app_global_data.rcu_status == RCU_STATUS_PAIRED)
+ {
+ app_set_latency_status(LATENCY_IR_BLE_PROC_BIT, LANTENCY_ON);
+ }
+}
+
+/******************************************************************
+ * @fn ir_service_handle_reset_ir_table
+ * @brief Initialize ir programming table data.
+ * @param void
+ * @return void
+ */
+void ir_service_handle_reset_ir_table(void)
+{
+ APP_PRINT_INFO0("[ir_service_handle_reset_ir_table] reset IR table");
+
+ memset(ir_table, 0, sizeof(key_code_t) * MAX_PROG_KEY_COUNT);
+ for (uint8_t index = 0; index < MAX_PROG_KEY_COUNT; index++)
+ {
+ ir_table[index].atv_key_code = INVALID_ATV_KEY_CODE;
+ key_handle_restore_key_type_id(ir_svc_handle_global_data.p_key_button_pair_table[index].rcu_key_id);
+ }
+
+ ir_service_handle_invalid_ftl_table();
+}
+
+/******************************************************************
+ * @fn ir_service_handle_active_ir_table
+ * @brief Activate ir programming table data.
+ * @param void
+ * @return void
+ */
+void ir_service_handle_activate_ir_table(void)
+{
+ APP_PRINT_INFO0("[ir_service_handle_activate_ir_table] Activate IR table");
+
+ for (uint8_t index = 0; index < MAX_PROG_KEY_COUNT; index++)
+ {
+ if (ir_table[index].atv_key_code != INVALID_ATV_KEY_CODE)
+ {
+ key_handle_set_key_type_prog_by_id(
+ ir_svc_handle_global_data.p_key_button_pair_table[index].rcu_key_id);
+ }
+ }
+}
+
+/******************************************************************
+ * @fn ir_service_handle_active_ir_table
+ * @brief Activate ir programming table data.
+ * @param void
+ * @return void
+ */
+bool ir_service_handle_ir_table_add_item(uint16_t atv_key_code, uint16_t data_len, uint8_t *p_data)
+{
+ bool result = true;
+
+ uint8_t table_item_id = ir_service_handle_get_item_id_from_atv_id(atv_key_code);
+
+ if ((table_item_id < MAX_PROG_KEY_COUNT)
+ && (ir_svc_handle_global_data.programmed_key_count < MAX_PROG_KEY_COUNT)
+ && (data_len <= MAX_CODE_LENGTH))
+ {
+ ir_table[ir_svc_handle_global_data.programmed_key_count].code_size = data_len;
+ memcpy(ir_table[ir_svc_handle_global_data.programmed_key_count].code, p_data, data_len);
+ ir_table[ir_svc_handle_global_data.programmed_key_count].rcu_key_id =
+ ir_svc_handle_global_data.p_key_button_pair_table[table_item_id].rcu_key_id;
+ ir_table[ir_svc_handle_global_data.programmed_key_count].atv_key_code = atv_key_code;
+ ir_svc_handle_global_data.programmed_key_count++;
+
+ result = true;
+ }
+ else
+ {
+ result = false;
+ }
+
+ APP_PRINT_INFO3("[ir_service_handle_ir_table_add_item] result = %d, atv_key_code = 0x%004X, programmed_key_count = %d",
+ result, atv_key_code, ir_svc_handle_global_data.programmed_key_count);
+
+ return result;
+}
+
+/******************************************************************
+ * @fn ir_service_handle_invalid_ftl_table
+ * @brief Invalid ir table in FTL.
+ * @param void
+ * @return void
+ */
+void ir_service_handle_invalid_ftl_table(void)
+{
+ for (uint8_t index = 0; index < MAX_PROG_KEY_COUNT; index++)
+ {
+ /* check FTL IR table header */
+ ir_table_ftl_hd_t item_hd;
+ memset(&item_hd, 0xFF, sizeof(item_hd));
+
+ if (0 == ftl_load(&item_hd, IR_Table_FTL_Addr_Info[index], sizeof(item_hd)))
+ {
+ if (item_hd.header == APP_IR_DATA_HEAD)
+ {
+ memset(&item_hd, 0xFF, sizeof(item_hd));
+ if (0 != ftl_save(&item_hd, IR_Table_FTL_Addr_Info[index], sizeof(item_hd)))
+ {
+ APP_PRINT_WARN0("[ir_service_handle_invalid_ftl_table] ftl_save failed");
+ }
+ }
+ }
+ }
+}
+
+/******************************************************************
+ * @fn ir_service_handle_back_up_ftl_table
+ * @brief Back up ir table into FTL.
+ * @param void
+ * @return void
+ */
+void ir_service_handle_back_up_ftl_table(void)
+{
+ for (uint8_t index = 0; index < MAX_PROG_KEY_COUNT; index++)
+ {
+ uint16_t save_data_len = 0;
+ bool result = false;
+
+ if (ir_table[index].atv_key_code != INVALID_ATV_KEY_CODE)
+ {
+ save_data_len = ir_table[index].code_size + 8;
+ if (save_data_len & 0x0003)
+ {
+ /* 4-bytes alignment adjustment */
+ save_data_len = (save_data_len + 4) & 0xFFFC;
+ }
+
+ if (save_data_len <= FTL_IR_TABLE_ITEM_MAX_LEN - FTL_IR_TABLE_ITEM_HEADER_LEN)
+ {
+ if (0 == ftl_save(&ir_table[index], IR_Table_FTL_Addr_Info[index] + FTL_IR_TABLE_ITEM_HEADER_LEN,
+ save_data_len))
+ {
+ ir_table_ftl_hd_t ftl_hd_data;
+ ftl_hd_data.header = APP_IR_DATA_HEAD;
+ ftl_hd_data.data_len = save_data_len;
+
+ if (0 == ftl_save(&ftl_hd_data, IR_Table_FTL_Addr_Info[index], FTL_IR_TABLE_ITEM_HEADER_LEN))
+ {
+ result = true;
+ APP_PRINT_INFO2("[ir_service_handle_back_up_ftl_table] Save successful %d, %04X", index,
+ ir_table[index].atv_key_code);
+ }
+ }
+ }
+ else
+ {
+ result = false;
+ }
+ }
+
+ APP_PRINT_INFO3("[ir_service_handle_back_up_ftl_table] result = %d, atv_key_code = 0x%04X, data_len = %d",
+ result, ir_table[index].atv_key_code, save_data_len);
+ }
+
+}
+
+/******************************************************************
+ * @fn ir_service_handle_restore_ir_table_from_ftl
+ * @brief Restore ir table from FTL data.
+ * @param void
+ * @return void
+ */
+void ir_service_handle_restore_ir_table_from_ftl(void)
+{
+ uint32_t ftl_res = 0;
+ ir_table_ftl_hd_t ftl_hd_data;
+
+ for (uint8_t index = 0; index < MAX_PROG_KEY_COUNT; index++)
+ {
+ bool result = false;
+
+ memset(&ftl_hd_data, 0, sizeof(ftl_hd_data));
+ ftl_res = ftl_load(&ftl_hd_data, IR_Table_FTL_Addr_Info[index], FTL_IR_TABLE_ITEM_HEADER_LEN);
+ if (0 == ftl_res)
+ {
+ if ((ftl_hd_data.header == APP_IR_DATA_HEAD) &&
+ (ftl_hd_data.data_len <= FTL_IR_TABLE_ITEM_MAX_LEN - FTL_IR_TABLE_ITEM_HEADER_LEN))
+ {
+ ftl_res = ftl_load(&ir_table[index], IR_Table_FTL_Addr_Info[index] + FTL_IR_TABLE_ITEM_HEADER_LEN,
+ 8);
+ if (0 == ftl_res)
+ {
+ uint16_t load_size = ir_table[index].code_size;
+ if (load_size & 0x0003)
+ {
+ /* 4-bytes alignment adjustment */
+ load_size = (load_size + 4) & 0xFFFC;
+ }
+
+ if ((load_size > 0) && (load_size <= MAX_CODE_LENGTH))
+ {
+ ftl_res = ftl_load(&ir_table[index].code,
+ IR_Table_FTL_Addr_Info[index] + FTL_IR_TABLE_ITEM_HEADER_LEN + 8, load_size);
+ if (0 == ftl_res)
+ {
+ result = true;
+ }
+ else
+ {
+ APP_PRINT_WARN2("[ir_service_handle_restore_ir_table_from_ftl] ftl_load failed_2, addr = 0x%X, len = %d",
+ IR_Table_FTL_Addr_Info[index], load_size);
+ }
+ }
+ }
+ else
+ {
+ APP_PRINT_WARN1("[ir_service_handle_restore_ir_table_from_ftl] ftl_load failed, addr = 0x%X",
+ IR_Table_FTL_Addr_Info[index]);
+ }
+ }
+ else
+ {
+ APP_PRINT_WARN2("[ir_service_handle_restore_ir_table_from_ftl] Invalid header or length, 0x%04X, %d",
+ ftl_hd_data.header, ftl_hd_data.data_len);
+ }
+ }
+
+ if (result == false)
+ {
+ ir_table[index].atv_key_code = INVALID_ATV_KEY_CODE;
+ }
+
+ APP_PRINT_INFO3("[ir_service_handle_restore_ir_table_from_ftl] index = %d, result = %d, ftl_res = %d",
+ index,
+ result, ftl_res);
+ }
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @fn ir_service_handle_init_data
+ * @brief Initialize key programming handler data.
+ * @param void
+ * @return void
+ */
+void ir_service_handle_init_data(void)
+{
+ APP_PRINT_INFO0("[ir_service_handle_init_data] init data");
+
+ memset(&ir_svc_handle_global_data, 0, sizeof(ir_svc_handle_global_data));
+ ir_svc_handle_global_data.current_programming_key_id = INVALID_ATV_KEY_CODE;
+ for (uint8_t index = 0; index < MAX_PROG_KEY_COUNT; index++)
+ {
+ ir_svc_handle_global_data.ir_suppress_table[index] = INVALID_ATV_KEY_CODE;
+ }
+
+ if (app_global_data.device_type == REMOTE_G10)
+ {
+ ir_svc_handle_global_data.p_key_button_pair_table = key_button_map_g10;
+ }
+ else
+ {
+ ir_svc_handle_global_data.p_key_button_pair_table = key_button_map_g20;
+ }
+
+ ir_service_handle_restore_ir_table_from_ftl();
+ ir_service_handle_activate_ir_table();
+
+ if (ir_programing_timer == NULL)
+ {
+ if (false == os_timer_create(&ir_programing_timer, "ir_programing_timer", 1,
+ PROGRAMMING_TIMEOUT, false, ir_programming_timeoutcb))
+ {
+ APP_PRINT_INFO0("[ir_service_handle_init_data] create ir_programing_timer failed!");
+ }
+ }
+}
+
+/******************************************************************
+ * @fn ir_service_handle_get_item_id_from_atv_id
+ * @brief Get table_item_id from atv_key_code
+ * @param atv_key_code
+ * @return table_item_id
+ */
+uint8_t ir_service_handle_get_item_id_from_atv_id(uint16_t atv_key_code)
+{
+ uint8_t table_item_id = INVALID_TABLE_ITEM_ID;
+
+ for (uint8_t index = 0; index < MAX_PROG_KEY_COUNT; index++)
+ {
+ if (atv_key_code == ir_svc_handle_global_data.p_key_button_pair_table[index].atv_key_code)
+ {
+ table_item_id = index;
+ }
+ }
+
+ return table_item_id;
+}
+
+/******************************************************************
+ * @fn ir_service_handle_get_item_id_from_key_id
+ * @brief Get table_item_id from rcu_key_id
+ * @param atv_key_code
+ * @return table_item_id
+ */
+uint8_t ir_service_handle_get_item_id_from_key_id(uint16_t rcu_key_id)
+{
+ uint8_t table_item_id = INVALID_TABLE_ITEM_ID;
+
+ for (uint8_t index = 0; index < MAX_PROG_KEY_COUNT; index++)
+ {
+ if (rcu_key_id == ir_svc_handle_global_data.p_key_button_pair_table[index].rcu_key_id)
+ {
+ table_item_id = index;
+ }
+ }
+
+ return table_item_id;
+}
+
+/******************************************************************
+ * @fn ir_service_handle_srv_cb
+ * @brief IR service callbacks are handled in this function.
+ * @param p_data - pointer to callback data
+ * @return T_APP_RESULT
+ */
+T_APP_RESULT ir_service_handle_srv_cb(T_IR_CALLBACK_DATA *p_data)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ APP_PRINT_INFO1("[ir_service_handle_srv_cb] msg_type: %d", p_data->msg_type);
+
+ switch (p_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ cb_result = ir_service_handle_read_char_cb(p_data->msg_data.read_value_index);
+ break;
+
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ cb_result = ir_service_handle_write_char_cb(&p_data->msg_data.write_msg);
+ break;
+
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ cb_result = ir_service_handle_indication_notification_char_cb(
+ p_data->msg_data.notification_indification_index);
+ break;
+
+ default:
+ APP_PRINT_INFO1("[ir_service_handle_srv_cb] unknown msg_type: %d", p_data->msg_type);
+ cb_result = APP_RESULT_APP_ERR;
+ break;
+ }
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn ir_service_handle_disconnect_event
+ * @brief Handle disconnect event.
+ * @param void
+ * @return void
+ */
+void ir_service_handle_disconnect_event(void)
+{
+ APP_PRINT_INFO0("[ir_service_handle_disconnect_event] disconnection");
+
+ for (uint8_t index = 0; index < MAX_PROG_KEY_COUNT; index++)
+ {
+ ir_svc_handle_global_data.ir_suppress_table[index] = INVALID_ATV_KEY_CODE;
+ }
+}
+
+/******************************************************************
+ * @fn ir_service_handle_flash_save_event
+ * @brief Handle flash save event.
+ * @param void
+ * @return void
+ */
+void ir_service_handle_flash_save_event(void)
+{
+ ir_service_handle_back_up_ftl_table();
+}
+
+/******************************************************************
+ * @fn ir_service_handle_is_key_suppressed
+ * @brief Chech whether key is suppressed or not
+ * @param bool
+ * @return true or false
+ */
+bool ir_service_handle_is_key_suppressed(uint8_t key_id)
+{
+ bool result = false;
+ uint8_t table_item_id = ir_service_handle_get_item_id_from_key_id(key_id);
+ uint16_t atv_key_code =
+ ir_svc_handle_global_data.p_key_button_pair_table[table_item_id].atv_key_code;
+
+ for (uint8_t index = 0; index < MAX_PROG_KEY_COUNT; index++)
+ {
+ if (atv_key_code == ir_svc_handle_global_data.ir_suppress_table[index])
+ {
+ result = true;
+ break;
+ }
+ }
+
+ APP_PRINT_INFO2("[ir_service_handle_is_key_suppressed] key id = %d, result = %d", key_id, result);
+
+ return result;
+}
+
+/******************************************************************
+ * @fn ir_service_handle_is_key_suppressed
+ * @brief Chech whether key is suppressed or not
+ * @param bool
+ * @return true or false
+ */
+bool ir_service_handle_get_key_code_by_key_id(uint8_t key_id, uint32_t *p_code_size,
+ uint8_t *p_key_code)
+{
+ bool result = false;
+
+ for (uint8_t index = 0; index < MAX_PROG_KEY_COUNT; index++)
+ {
+ if ((ir_table[index].atv_key_code != INVALID_ATV_KEY_CODE)
+ && (ir_table[index].rcu_key_id == key_id)
+ && (ir_table[index].code_size > 0)
+ && (ir_table[index].code_size < MAX_CODE_LENGTH))
+ {
+ *p_code_size = ir_table[index].code_size;
+ memcpy(p_key_code, ir_table[index].code, *p_code_size);
+ result = true;
+ break;
+ }
+ }
+
+ APP_PRINT_INFO2("[ir_service_handle_get_key_code_by_key_id] key id = %d, result = %d", key_id,
+ result);
+
+ return result;
+}
+
+/******************************************************************
+ * @fn ir_service_handle_notify_ir_key_event
+ * @brief Notify IR key event
+ * @param key_id - key index
+ * @param action_type - key action type
+ * @return true or false
+ */
+bool ir_service_handle_notify_ir_key_event(uint8_t key_id, uint8_t action_type)
+{
+ bool result = false;
+ uint8_t data[3];
+
+ uint8_t item_id = ir_service_handle_get_item_id_from_key_id(key_id);
+ if ((INVALID_TABLE_ITEM_ID != item_id)
+ && ((action_type == KEY_ACTION_DOWN) || (action_type == KEY_ACTION_UP)))
+ {
+ uint16_t atv_key_code = ir_svc_handle_global_data.p_key_button_pair_table[item_id].atv_key_code;
+
+ data[0] = action_type;
+ data[1] = (uint8_t)(atv_key_code >> 8);
+ data[2] = (uint8_t)atv_key_code;
+
+ result = server_send_data(0, app_global_data.ir_srv_id, GATT_SVC_IR_KEY_EVENT_INDEX, data,
+ sizeof(data), GATT_PDU_TYPE_NOTIFICATION);
+ }
+
+ APP_PRINT_INFO3("[ir_service_handle_notify_ir_key_event] key_id = %d, action_type = %d, result = %d",
+ key_id, action_type, result);
+ return result;
+}
+
+#endif
diff --git a/src/app/google_rcu/ir_module/ir_service_handle.h b/src/app/google_rcu/ir_module/ir_service_handle.h
new file mode 100644
index 0000000..57d2779
--- /dev/null
+++ b/src/app/google_rcu/ir_module/ir_service_handle.h
@@ -0,0 +1,130 @@
+/*
+ * Routines to access hardware
+ *
+ * Copyright (c) 2019 Realtek Semiconductor Corp.
+ *
+ * This module is a confidential and proprietary property of RealTek and
+ * possession or use of this module requires written permission of RealTek.
+ */
+
+#ifndef _IR_SERVICE_HANDLE_H_
+#define _IR_SERVICE_HANDLE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "ir_service.h"
+#include "profile_server.h"
+#include "swtimer.h"
+#include "flash_map.h"
+#include "frm_define.h"
+
+/*============================================================================*
+ * Macro Definitions
+ *============================================================================*/
+//programming timeout 30s
+#define PROGRAMMING_TIMEOUT 30000
+
+#define INVALID_ATV_KEY_CODE 0xFF00
+#define MAX_CODE_LENGTH 500 /* The maximum number of ir codes for each key. */
+#define MAX_PROG_KEY_COUNT 5 /* The maximum number of key for ir programming.*/
+
+#define INVALID_TABLE_ITEM_ID 0xFF
+#define KEY_IDX_NULL 0xff
+
+#define APP_IR_CMD_OTA_NEC_IR_TABLE_PREPARE 0xEF00
+#define APP_IR_CMD_OTA_NEC_IR_TABLE_START 0xEF01
+#define APP_IR_CMD_OTA_NEC_IR_TABLE_END 0xEF02
+
+#define APP_IR_DATA_HEAD 0xA55A
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+typedef struct
+{
+ u16 atv_key_code; //Key ID, comes from ATV (host keyid)
+ u16 rcu_key_id; //button index, based on enum in firmware
+ u32 code_size;
+ u8 code[MAX_CODE_LENGTH];
+} key_code_t;
+
+typedef struct
+{
+ uint16_t header;
+ uint16_t data_len;
+} ir_table_ftl_hd_t;
+
+typedef struct
+{
+ u32 release_timer;
+ u32 repeat_delay;
+} ir_repeat_delay_t;
+
+typedef struct
+{
+ u8 programming_start;
+ u8 programmed_key_count;
+ u8 key_notification_flag;
+ u16 current_programming_key_id;
+} ir_programming_key_t;
+
+typedef struct
+{
+ u16 atv_key_code;
+ u8 rcu_key_id;
+} key_button_pair_t;
+
+typedef enum
+{
+ APP_NEC_IR_TABLE_PREPARE = 1,
+ APP_NEC_IR_TABLE_PREPARE_END,
+ APP_NEC_IR_TABLE_START,
+ APP_NEC_IR_TABLE_WRITEFAIL,
+ APP_NEC_IR_TABLE_END
+} app_nec_ir_table_sts;
+
+/**
+ * @brief ir service handle global data struct definition.
+ */
+typedef struct
+{
+ u8 programming_start;
+ u8 programmed_key_count;
+ u8 key_notification_flag;
+ u16 current_programming_key_id;
+ const key_button_pair_t *p_key_button_pair_table;
+ u16 ir_suppress_table[MAX_PROG_KEY_COUNT];
+} T_IR_SVC_HANDLE_GLOBAL_DATA;
+
+/*============================================================================*
+* Export Global Variables
+*============================================================================*/
+extern T_IR_SVC_HANDLE_GLOBAL_DATA ir_svc_handle_global_data;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void ir_service_handle_init_data(void);
+T_APP_RESULT ir_service_handle_srv_cb(T_IR_CALLBACK_DATA *p_data);
+void ir_table_init(void);
+void ir_service_handle_flash_save_event(void);
+void ir_service_handle_disconnect_event(void);
+uint8_t ir_service_handle_get_item_id_from_key_id(uint16_t rcu_key_id);
+uint8_t ir_service_handle_get_item_id_from_atv_id(uint16_t atv_key_code);
+bool ir_service_handle_is_key_suppressed(uint8_t key_id);
+bool ir_service_handle_get_key_code_by_key_id(uint8_t key_id, uint32_t *p_code_size,
+ uint8_t *p_key_code);
+bool ir_service_handle_notify_ir_key_event(uint8_t key_id, uint8_t action_type);
+void ir_service_handle_invalid_ftl_table(void);
+void ir_service_handle_reset_ir_table(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/app/google_rcu/key_module/key_handle.c b/src/app/google_rcu/key_module/key_handle.c
new file mode 100644
index 0000000..00bf25e
--- /dev/null
+++ b/src/app/google_rcu/key_module/key_handle.c
@@ -0,0 +1,1527 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file key_handle.c
+* @brief This is the entry of user code which the key handle module resides in.
+* @details
+* @author chenjie jin
+* @date 2020-02-25
+* @version v1.1
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include "board.h"
+#include "key_handle.h"
+#include <trace.h>
+#include "profile_server.h"
+#include "hids_rmc.h"
+#include "rcu_application.h"
+#include "os_timer.h"
+#include "swtimer.h"
+#include "voice.h"
+#include "voice_driver.h"
+#include "rcu_gap.h"
+#include "gap_storage_le.h"
+#include "rtl876x_wdg.h"
+#include "rtl876x_keyscan.h"
+#include "gap_bond_le.h"
+#include "battery_driver.h"
+#include "led_driver.h"
+#include <app_section.h>
+#if SUPPORT_IR_TX_FEATURE
+#include "ir_send_handle.h"
+#include "ir_service_handle.h"
+#endif
+#if FEATURE_SUPPORT_MP_TEST_MODE
+#include "mp_test.h"
+#endif
+#include "atvv_service.h"
+#include "app_custom.h"
+#if SUPPORT_BUZZER_FEATURE
+#include "buzzer_driver.h"
+#include "fms_service_handle.h"
+#endif
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+#define MAX_KEY_PRESS_CACHE_FIFO_CNT 22
+
+static uint8_t Key_Press_Cache_FIFO[MAX_KEY_PRESS_CACHE_FIFO_CNT];
+static uint8_t current_cache_fifo_items_cnt = 0;
+static uint8_t cache_fifo_output_cnt = 0;
+
+/*============================================================================*
+ * Global Variables
+ *============================================================================*/
+/* Key Mapping Table Definition, need to align with hardware key matrix */
+const T_KEY_INDEX_DEF KEY_MAPPING_TABLE_G10[KEYPAD_MAX_ROW_SIZE_G10][KEYPAD_MAX_COLUMN_SIZE_G10] =
+{
+ {KEY_ID_Power, KEY_ID_Input, KEY_ID_Bookmark, KEY_ID_Assistant, KEY_ID_Settings, KEY_ID_APP03, KEY_ID_NONE},
+ {KEY_ID_DPadCenter, KEY_ID_DPadUp, KEY_ID_DPadDown, KEY_ID_DPadLeft, KEY_ID_DPadRight, KEY_ID_APP04, KEY_ID_NONE},
+ {KEY_ID_Back, KEY_ID_Home, KEY_ID_Guide, KEY_ID_VolDown, KEY_ID_VolDown, KEY_ID_NONE, KEY_ID_NONE},
+ {KEY_ID_Mute, KEY_ID_ChannelUp, KEY_ID_ChannelDown, KEY_ID_Youtube, KEY_ID_Netflix, KEY_ID_NONE, KEY_ID_NONE},
+};
+/* settings, guide, bookmark index in KEY_MAPPING_TABLE_G10 */
+const uint8_t Kb_Map_devicelayout_Correspend_Index_G10[] = {4, 16, 2};
+const uint8_t Wakeup_Map_Correspend_Index_G10[] =
+{
+ KEY_ID_Assistant, KEY_ID_Home, KEY_ID_Power, KEY_ID_Input, KEY_ID_Youtube, KEY_ID_Netflix, KEY_ID_APP03, KEY_ID_APP04
+};
+uint8_t Ir_Override_Table_Index_G10[24] =
+{
+ KEY_ID_Power, KEY_ID_DPadRight, KEY_ID_VolDown, KEY_ID_Input, KEY_ID_DPadDown, KEY_ID_ChannelDown,
+ KEY_ID_Bookmark, KEY_ID_Back, KEY_ID_Youtube, KEY_ID_Assistant, KEY_ID_Home, KEY_ID_Netflix,
+ KEY_ID_Settings, KEY_ID_Guide, KEY_ID_APP03, KEY_ID_DPadUp, KEY_ID_VolUp, KEY_ID_APP04,
+ KEY_ID_DPadLeft, KEY_ID_ChannelUp, KEY_ID_NONE, KEY_ID_DPadCenter, KEY_ID_Mute, KEY_ID_NONE,
+};
+/* settings, guide, bookmark index in Ir_Override_Table_Index_G10 */
+const uint8_t Ir_Table_Correspend_Index_G10[] = {12, 13, 6};
+
+/* Key Mapping Table Definition, need to align with hardware key matrix */
+const T_KEY_INDEX_DEF KEY_MAPPING_TABLE_G20[KEYPAD_MAX_ROW_SIZE_G20][KEYPAD_MAX_COLUMN_SIZE_G20] =
+{
+ {KEY_ID_Power, KEY_ID_5, KEY_ID_0, KEY_ID_Bookmark, KEY_ID_DPadRight, KEY_ID_Mute, KEY_ID_APP03},
+ {KEY_ID_Input, KEY_ID_6, KEY_ID_Info, KEY_ID_Assistant, KEY_ID_DPadDown, KEY_ID_ChannelUp, KEY_ID_APP04},
+ {KEY_ID_1, KEY_ID_7, KEY_ID_Red, KEY_ID_Settings, KEY_ID_Back, KEY_ID_VolDown, KEY_ID_NONE},
+ {KEY_ID_2, KEY_ID_8, KEY_ID_Green, KEY_ID_DPadUp, KEY_ID_Home, KEY_ID_ChannelDown, KEY_ID_NONE},
+ {KEY_ID_3, KEY_ID_9, KEY_ID_Yellow, KEY_ID_DPadLeft, KEY_ID_Guide, KEY_ID_Youtube, KEY_ID_NONE},
+ {KEY_ID_4, KEY_ID_Subtitles, KEY_ID_Blue, KEY_ID_DPadCenter, KEY_ID_VolUp, KEY_ID_Netflix, KEY_ID_NONE},
+};
+/* settings, guide, subtitle, bookmark, red, green, yellow, blue index in KEY_MAPPING_TABLE_G20 */
+const uint8_t Kb_Map_devicelayout_Correspend_Index_G20[] = {18, 32, 36, 3, 16, 23, 30, 37};
+const uint8_t Wakeup_Map_Correspend_Index_G20[] =
+{
+ KEY_ID_Assistant, KEY_ID_Home, KEY_ID_Power, KEY_ID_Input, KEY_ID_Youtube, KEY_ID_Netflix, KEY_ID_APP03, KEY_ID_APP04, KEY_ID_Blue,
+ KEY_ID_Green, KEY_ID_Red, KEY_ID_Yellow
+};
+uint8_t Ir_Override_Table_Index_G20[48] =
+{
+ KEY_ID_Power, KEY_ID_DPadRight, KEY_ID_VolDown, KEY_ID_Info, KEY_ID_4, KEY_ID_Green,
+ KEY_ID_Input, KEY_ID_DPadDown, KEY_ID_ChannelDown, KEY_ID_0, KEY_ID_3, KEY_ID_Red,
+ KEY_ID_Bookmark, KEY_ID_Back, KEY_ID_Youtube, KEY_ID_Subtitles, KEY_ID_2, KEY_ID_6,
+ KEY_ID_Assistant, KEY_ID_Home, KEY_ID_Netflix, KEY_ID_9, KEY_ID_1, KEY_ID_5,
+ KEY_ID_Settings, KEY_ID_Guide, KEY_ID_APP03, KEY_ID_8, KEY_ID_Blue, KEY_ID_NONE,
+ KEY_ID_DPadUp, KEY_ID_VolUp, KEY_ID_APP04, KEY_ID_7, KEY_ID_Yellow, KEY_ID_NONE,
+ KEY_ID_DPadLeft, KEY_ID_ChannelUp, KEY_ID_NONE, KEY_ID_NONE, KEY_ID_NONE, KEY_ID_NONE,
+ KEY_ID_NONE, KEY_ID_NONE, KEY_ID_NONE, KEY_ID_NONE, KEY_ID_NONE, KEY_ID_NONE,
+};
+/* settings, guide, subtitle, bookmark, red, green, yellow, blue index in Ir_Override_Table_Index_G20 */
+const uint8_t Ir_Table_Correspend_Index_G20[] = {24, 25, 15, 12, 11, 5, 34, 28};
+
+
+/* BLE HID code table definition */
+const T_KEY_CODE_DEF KEY_CODE_TABLE[KEY_CODE_TABLE_SIZE] =
+{
+ /* key_type, hid_usage_page, hid_usage_id, ir_key_code */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_POWER,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_POWER, .ir_cmd2 = ~IR_POWER}
+ }, /* KEY_ID_Power */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_RIGHT,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_RIGHT, .ir_cmd2 = ~IR_RIGHT}
+ }, /* KEY_ID_DPadRight */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_KEYBOARD_PAGE, G00GLE_VK_VOLUMEDOWN,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_VOL_DN, .ir_cmd2 = ~IR_VOL_DN}
+ }, /* KEY_ID_VolDown */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_INFO,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_INFO, .ir_cmd2 = ~IR_INFO}
+ }, /* KEY_ID_Info */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_KEYBOARD_PAGE, G00GLE_VK_4,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_VK_4, .ir_cmd2 = ~IR_VK_4}
+ }, /* KEY_ID_4 */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_GREEN,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_GREEN, .ir_cmd2 = ~IR_GREEN}
+ }, /* KEY_ID_Green */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_INPUT,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_INPUT, .ir_cmd2 = ~IR_INPUT}
+ }, /* KEY_ID_Input */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_DN,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_DN, .ir_cmd2 = ~IR_DN}
+ }, /* KEY_ID_DPadDown */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_CHN_DN,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_CHN_DN, .ir_cmd2 = ~IR_CHN_DN}
+ }, /* KEY_ID_ChannelDown */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_KEYBOARD_PAGE, G00GLE_VK_0,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_VK_0, .ir_cmd2 = ~IR_VK_0}
+ }, /* KEY_ID_0 */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_KEYBOARD_PAGE, G00GLE_VK_3,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_VK_3, .ir_cmd2 = ~IR_VK_3}
+ }, /* KEY_ID_3 */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_RED,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_RED, .ir_cmd2 = ~IR_RED}
+ }, /* KEY_ID_Red */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_BOOKMARK,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_BOOKMARK, .ir_cmd2 = ~IR_BOOKMARK}
+ }, /* KEY_ID_Bookmark */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_BACK,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_BACK, .ir_cmd2 = ~IR_BACK}
+ }, /* KEY_ID_Back */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_YOUTUBE,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_YOUTUBE, .ir_cmd2 = ~IR_YOUTUBE}
+ }, /* KEY_ID_Youtube */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_SUBTITLE,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_SUBTITLE, .ir_cmd2 = ~IR_SUBTITLE}
+ }, /* KEY_ID_Subtitles */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_KEYBOARD_PAGE, G00GLE_VK_2,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_VK_2, .ir_cmd2 = ~IR_VK_2}
+ }, /* KEY_ID_2 */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_KEYBOARD_PAGE, G00GLE_VK_6,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_VK_6, .ir_cmd2 = ~IR_VK_6}
+ }, /* KEY_ID_6 */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_ASSIST,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_ASSIST, .ir_cmd2 = ~IR_ASSIST}
+ }, /* KEY_ID_Assistant */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_HOME,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_HOME, .ir_cmd2 = ~IR_HOME}
+ }, /* KEY_ID_Home */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_NETFLIX,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_NETFLIX, .ir_cmd2 = ~IR_NETFLIX}
+ }, /* KEY_ID_Netflix */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_KEYBOARD_PAGE, G00GLE_VK_9,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_VK_9, .ir_cmd2 = ~IR_VK_9}
+ }, /* KEY_ID_9 */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_KEYBOARD_PAGE, G00GLE_VK_1,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_VK_1, .ir_cmd2 = ~IR_VK_1}
+ }, /* KEY_ID_1 */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_KEYBOARD_PAGE, G00GLE_VK_5,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_VK_5, .ir_cmd2 = ~IR_VK_5}
+ }, /* KEY_ID_5 */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_DASHBOARD,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_DASHBOARD, .ir_cmd2 = ~IR_DASHBOARD}
+ }, /* KEY_ID_Dashboard */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_GUIDE,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_GUIDE, .ir_cmd2 = ~IR_GUIDE}
+ }, /* KEY_ID_Guide */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_APP03,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_APP03, .ir_cmd2 = ~IR_APP03}
+ }, /* KEY_ID_APP03 */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_KEYBOARD_PAGE, G00GLE_VK_8,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_VK_8, .ir_cmd2 = ~IR_VK_8}
+ }, /* KEY_ID_8 */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_BLUE,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_BLUE, .ir_cmd2 = ~IR_BLUE}
+ }, /* KEY_ID_Blue */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_ALLAPPS,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_ALLAPPS, .ir_cmd2 = ~IR_ALLAPPS}
+ }, /* KEY_ID_AllApps */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_UP,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_UP, .ir_cmd2 = ~IR_UP}
+ }, /* KEY_ID_DPadUp */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_KEYBOARD_PAGE, G00GLE_VK_VOLUMEUP,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_VOL_UP, .ir_cmd2 = ~IR_VOL_UP}
+ }, /* KEY_ID_VolUp */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_APP04,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_APP04, .ir_cmd2 = ~IR_APP04}
+ }, /* KEY_ID_APP04 */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_KEYBOARD_PAGE, G00GLE_VK_7,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_VK_7, .ir_cmd2 = ~IR_VK_7}
+ }, /* KEY_ID_APP04 */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_YELLOW,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_YELLOW, .ir_cmd2 = ~IR_YELLOW}
+ }, /* KEY_ID_Yellow */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_PROFILE,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_USERPROFILE, .ir_cmd2 = ~IR_USERPROFILE}
+ }, /* KEY_ID_Profile */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_LEFT,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_LEFT, .ir_cmd2 = ~IR_LEFT}
+ }, /* KEY_ID_DPadLeft */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_CHN_UP,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_CHN_UP, .ir_cmd2 = ~IR_CHN_UP}
+ }, /* KEY_ID_ChannelUp */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_SETTINGS,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_SETTINGS, .ir_cmd2 = ~IR_SETTINGS}
+ }, /* KEY_ID_Settings */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_LIVETV,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_LIVETV, .ir_cmd2 = ~IR_LIVETV}
+ }, /* KEY_ID_Live */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_VOL_MUTE,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_MUTE, .ir_cmd2 = ~IR_MUTE}
+ }, /* KEY_ID_Mute */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_FASTREWIND,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_FASTREWIND, .ir_cmd2 = ~IR_FASTREWIND}
+ }, /* KEY_ID_FastRewind */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_CENTER,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_CENTER, .ir_cmd2 = ~IR_CENTER}
+ }, /* KEY_ID_DPadCenter */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_RECORD,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_RECORD, .ir_cmd2 = ~IR_RECORD}
+ }, /* KEY_ID_Record */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_PLAYPAUSE,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_PLAYPAUSE, .ir_cmd2 = ~IR_PLAYPAUSE}
+ }, /* KEY_ID_PlayPause */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_FASTFORWARD,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_FASTFORWARD, .ir_cmd2 = ~IR_FASTFORWARD}
+ }, /* KEY_ID_FastForward */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_MKEY_TELETEXT,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_TELETEXT, .ir_cmd2 = ~IR_TELETEXT}
+ }, /* KEY_ID_TEXT */
+ {
+ KEY_TYPE_IR_ONLY, HID_UNDEFINED_PAGE, 0,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_BUGREPORT, .ir_cmd2 = (uint8_t)~IR_BUGREPORT}
+ }, /* KEY_ID_BugReport */
+ {
+ KEY_TYPE_BLE_AND_IR, HID_CONSUMER_PAGE, G00GLE_SHORTCUT,
+ {.ir_addr1 = DEFAULT_IR_NEC_ADDR_1, .ir_addr2 = DEFAULT_IR_NEC_ADDR_2, .ir_cmd1 = IR_SHORTCUT, .ir_cmd2 = (uint8_t)~IR_SHORTCUT}
+ }, /* KEY_ID_SHORTCUT */
+
+ {
+ KEY_TYPE_NONE, HID_UNDEFINED_PAGE, 0,
+ {.ir_addr1 = 0, .ir_addr2 = 0, .ir_cmd1 = 0, .ir_cmd2 = ~0}
+ }, /* KEY_ID_NONE */
+};
+
+T_KEY_HANDLE_GLOBAL_DATA key_handle_global_data; /* Value to indicate the reconnection key data */
+TimerHandle_t combine_keys_detection_timer;
+TimerHandle_t notify_key_data_after_reconn_timer;
+#if FEATURE_SUPPORT_KEY_LONG_PRESS_PROTECT
+TimerHandle_t long_press_key_detect_timer;
+#endif
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+static bool key_handle_check_navy_key(T_KEYSCAN_DATA keyscan_data);
+static bool key_handle_prepare_hid_usage_buffer(T_KEY_INDEX_DEF key_index,
+ T_KEY_HID_USAGES_BUFFER *p_buf);
+static bool key_handle_notify_hid_usage_buffer(T_KEY_HID_USAGES_BUFFER *p_cur_buf,
+ T_KEY_HID_USAGES_BUFFER *p_prev_buf);
+static void key_handle_one_key_scenario(T_KEY_INDEX_DEF key_index);
+static bool key_handle_detect_special_keys(T_KEYSCAN_FIFO_DATA *p_keyscan_fifo_data);
+static void key_handle_process_repairing_event(void);
+static void key_handle_process_factory_reset_event(void);
+
+static void key_handle_comb_keys_timer_cb(TimerHandle_t p_timer) DATA_RAM_FUNCTION;
+static void notify_key_data_timer_cb(TimerHandle_t p_timer) DATA_RAM_FUNCTION;
+
+static void key_handle_inqueue_key_pressed_cache_fifo(uint8_t key_index);
+static uint8_t key_handle_dequeue_key_pressed_cache_fifo(void);
+
+
+#if FEATURE_SUPPORT_KEY_LONG_PRESS_PROTECT
+static void long_press_key_detect_timer_cb(TimerHandle_t p_timer) DATA_RAM_FUNCTION;
+#endif
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief handle key prepare hid usage buffer
+ * @param p_cur_buf - point of current hid usage buffer
+ * @param p_prev_buf - point of previous hid usage buffer
+ * @return bool - true or false
+ * @retval void
+ */
+bool key_handle_prepare_hid_usage_buffer(T_KEY_INDEX_DEF key_index, T_KEY_HID_USAGES_BUFFER *p_buf)
+{
+ bool result = false;
+ uint8_t buffer_index;
+ uint8_t hid_usage_page = key_handle_get_hid_usage_page_by_index(key_index);
+ uint16_t hid_usage_id = key_handle_get_hid_usage_id_by_index(key_index);
+ T_KEY_TYPE_DEF key_type = key_handle_get_key_type_by_index(key_index);
+
+ if ((KEY_TYPE_BLE_ONLY == key_type)
+ || (KEY_TYPE_BLE_AND_IR == key_type)
+ || (KEY_TYPE_BLE_OR_IR == key_type)
+ || (KEY_TYPE_IR_PROGRAMMED == key_type))
+ {
+ if (HID_KEYBOARD_PAGE == hid_usage_page)
+ {
+ if (p_buf->keyboard_usage_cnt < MAX_HID_KEYBOARD_USAGE_CNT)
+ {
+ /* start from keyboard_usage_buffer[2] to keep same behavior as Bee1 and Bee2 */
+ buffer_index = (p_buf->keyboard_usage_cnt + 2) % MAX_HID_KEYBOARD_USAGE_CNT;
+ p_buf->keyboard_usage_buffer[buffer_index] = (uint8_t)hid_usage_id;
+ p_buf->keyboard_usage_cnt += 1;
+
+ result = true;
+ }
+ else
+ {
+ APP_PRINT_WARN0("[key_handle_prepare_hid_usage_buffer] keyboard_usage_buffer is full");
+ result = false;
+ }
+ }
+ else if (HID_CONSUMER_PAGE == hid_usage_page)
+ {
+ if (p_buf->consumer_usage_cnt < MAX_HID_CONSUMER_USAGE_CNT)
+ {
+ buffer_index = p_buf->consumer_usage_cnt;
+ p_buf->consumer_usage_buffer[buffer_index] = hid_usage_id;
+ p_buf->consumer_usage_cnt += 1;
+
+ result = true;
+ }
+ else
+ {
+ APP_PRINT_WARN0("[key_handle_prepare_hid_usage_buffer] keyboard_usage_buf is full");
+ result = false;
+ }
+ }
+ }
+
+ APP_PRINT_INFO2("[key_handle_prepare_hid_usage_buffer] key_index is %d, result is %d", key_index,
+ result);
+
+ return result;
+}
+
+/******************************************************************
+ * @brief handle key notify hid usage buffer
+ * @param p_cur_buf - point of current hid usage buffer
+ * @param p_prev_buf - point of previous hid usage buffer
+ * @return bool - true or false
+ * @retval void
+ */
+bool key_handle_notify_hid_usage_buffer(T_KEY_HID_USAGES_BUFFER *p_cur_buf,
+ T_KEY_HID_USAGES_BUFFER *p_prev_buf)
+{
+ bool result = false;
+
+ /* check parameters and status */
+ if ((p_cur_buf == NULL) || (p_prev_buf == NULL))
+ {
+ APP_PRINT_WARN0("[key_handle_notify_hid_usage_buffer] Invalid parameters");
+ return false;
+ }
+ if (app_global_data.rcu_status != RCU_STATUS_PAIRED)
+ {
+ APP_PRINT_WARN1("[key_handle_notify_hid_usage_buffer] Invalid RCU Status %d",
+ app_global_data.rcu_status);
+ return false;
+ }
+
+ /* check whether notification is needed or not */
+ if ((true == app_global_data.is_keyboard_notify_en) &&
+ (0 != memcmp(p_cur_buf->keyboard_usage_buffer, p_prev_buf->keyboard_usage_buffer,
+ sizeof(p_cur_buf->keyboard_usage_buffer))))
+ {
+ result = server_send_data(0, app_global_data.hid_srv_id, GATT_SRV_HID_KB_INPUT_INDEX,
+ p_cur_buf->keyboard_usage_buffer, sizeof(p_cur_buf->keyboard_usage_buffer),
+ GATT_PDU_TYPE_NOTIFICATION);
+ if (result)
+ {
+ APP_PRINT_INFO1("[key_handle_notify_hid_usage_buffer] send keyboard_usage_buffer: 0x %b",
+ TRACE_BINARY(sizeof(p_cur_buf->keyboard_usage_buffer), p_cur_buf->keyboard_usage_buffer));
+ }
+ }
+
+ if ((true == app_global_data.is_mm_keyboard_notify_en) &&
+ (0 != memcmp(p_cur_buf->consumer_usage_buffer, p_prev_buf->consumer_usage_buffer,
+ sizeof(p_cur_buf->consumer_usage_buffer))))
+ {
+ result = server_send_data(0, app_global_data.hid_srv_id, GATT_SRV_HID_MM_KB_INPUT_INDEX,
+ (uint8_t *)p_cur_buf->consumer_usage_buffer, sizeof(p_cur_buf->consumer_usage_buffer),
+ GATT_PDU_TYPE_NOTIFICATION);
+ if (result)
+ {
+ APP_PRINT_INFO1("[key_handle_notify_hid_usage_buffer] send consumer_usage_buffer: 0x %b",
+ TRACE_BINARY(sizeof(p_cur_buf->consumer_usage_buffer), p_cur_buf->consumer_usage_buffer));
+ }
+ }
+
+ return result;
+}
+
+/******************************************************************
+ * @brief rest key pressed cache FIFO
+ * @param void
+ * @return none
+ * @retval void
+ */
+void key_handle_reset_key_pressed_cache_fifo(void)
+{
+ APP_PRINT_INFO0("[key_handle_reset_key_pressed_cache_queue] reset queue");
+ memset(Key_Press_Cache_FIFO, (uint8_t)KEY_ID_NONE, sizeof(Key_Press_Cache_FIFO));
+ current_cache_fifo_items_cnt = 0;
+ cache_fifo_output_cnt = 0;
+}
+
+/******************************************************************
+ * @brief inqueue key pressed cache FIFO
+ * @param key_index - pressed key index
+ * @return none
+ * @retval void
+ */
+void key_handle_inqueue_key_pressed_cache_fifo(uint8_t key_index)
+{
+ bool result = false;
+
+ if ((key_index < KEY_ID_NONE)
+ && (current_cache_fifo_items_cnt < MAX_KEY_PRESS_CACHE_FIFO_CNT))
+ {
+ if ((key_index == KEY_ID_Power) &&
+ (false == app_global_data.en_powerkey_cache))
+ {
+ result = false;
+ }
+ else
+ {
+ bool is_exist_flag = false;
+ /* check whether key is exist or not */
+ for (uint8_t index = 0; index < current_cache_fifo_items_cnt; index++)
+ {
+ if (key_index == Key_Press_Cache_FIFO[index])
+ {
+ is_exist_flag = true;
+ break;
+ }
+ }
+
+ if (false == is_exist_flag)
+ {
+ Key_Press_Cache_FIFO[current_cache_fifo_items_cnt++] = key_index;
+ }
+ }
+ }
+
+ APP_PRINT_INFO3("[key_handle_inqueue_key_pressed_cache_fifo] result = %d, key_index = %d, cnt = %d",
+ result, key_index, current_cache_fifo_items_cnt);
+}
+
+/******************************************************************
+ * @brief dequeue key pressed cache FIFO
+ * @param void
+ * @return uint8_t
+ * @retval void
+ */
+uint8_t key_handle_dequeue_key_pressed_cache_fifo(void)
+{
+ uint8_t key_index = KEY_ID_NONE;
+
+ if (cache_fifo_output_cnt < current_cache_fifo_items_cnt)
+ {
+ key_index = Key_Press_Cache_FIFO[cache_fifo_output_cnt++];
+ }
+
+ APP_PRINT_INFO2("[key_handle_dequeue_key_pressed_cache_fifo] key_index = %d, cache_fifo_output_cnt = %d",
+ key_index, cache_fifo_output_cnt);
+
+ return key_index;
+}
+
+/******************************************************************
+ * @brief handle one key pressed scenario
+ * @param key_index - pressed key index
+ * @return none
+ * @retval void
+ */
+void key_handle_one_key_scenario(T_KEY_INDEX_DEF key_index)
+{
+ T_KEY_TYPE_DEF key_type = key_handle_get_key_type_by_index(key_index);
+
+ APP_PRINT_INFO3("[key_handle_one_key_scenario] key_index = %d, key_type = %d, rcu_status = %d",
+ key_index, key_type, app_global_data.rcu_status);
+ if (key_index == KEY_ID_Back)
+ {
+ if (app_global_data.is_allow_to_factory_reset_for_back_key == 1)
+ {
+ APP_PRINT_INFO0("[key_handle_one_key_scenario] Back key pressed when HW reset and ready to factory reset.");
+ key_handle_process_factory_reset_event();
+ }
+ }
+ if (app_global_data.rcu_status == RCU_STATUS_PAIRED)
+ {
+ if (key_handle_global_data.prev_keyscan_fifo_data.len == 1)
+ {
+ /* key change within one keyscan interval */
+ key_handle_release_event();
+ }
+
+ if (key_index == KEY_ID_Assistant)
+ {
+ voice_handle_mic_key_pressed();
+ }
+ else
+ {
+ if (key_type == KEY_TYPE_IR_PROGRAMMED)
+ {
+ if (true == ir_service_handle_is_key_suppressed(key_index))
+ {
+ key_handle_notify_hid_key_event_by_index(key_index);
+ LED_BLINK(LED_TYPE_BLINK_KEY_PRESS_BLE, 1);
+ }
+ else
+ {
+ ir_send_key_press_handle(key_index, RAW_PROTOCOL);
+ ir_service_handle_notify_ir_key_event(key_index, KEY_ACTION_DOWN);
+ key_handle_global_data.ir_prog_key_down_id = key_index;
+ LED_BLINK(LED_TYPE_BLINK_KEY_PRESS_PROG, 1);
+ }
+ }
+ else if (cache_fifo_output_cnt < current_cache_fifo_items_cnt)
+ {
+ /* cache key if pending key queue is not empty */
+ key_handle_inqueue_key_pressed_cache_fifo(key_index);
+ }
+ else
+ {
+ key_handle_notify_hid_key_event_by_index(key_index);
+ LED_BLINK(LED_TYPE_BLINK_KEY_PRESS_BLE, 1);
+ }
+
+ if (key_index == KEY_ID_DPadCenter)
+ {
+ voice_handle_atv_dpad_select();
+ }
+ }
+ }
+ else
+ {
+ if ((app_global_data.rcu_status == RCU_STATUS_ADVERTISING)
+ && (app_global_data.adv_type == ADV_UNDIRECT_PAIRING)
+ && (key_index == KEY_ID_Back))
+ {
+ APP_PRINT_INFO0("[key_handle_one_key_scenario] Back key pressed, stop pairing adv.");
+ rcu_stop_adv(STOP_ADV_REASON_BACKKEY);
+ LED_BLINK_EXIT(LED_TYPE_BLINK_PAIR_ADV);
+ }
+
+ /* check whether wake up adv is triggered or not */
+ if (true == app_global_data.is_link_key_existed)
+ {
+ if (true == app_custom_is_wakeup_key(key_index))
+ {
+ if (app_global_data.rcu_status == RCU_STATUS_IDLE)
+ {
+ app_global_data.wakeup_key_index = key_index;
+ app_global_data.wakeup_key_count++;
+ app_save_wakeup_key_cnt(app_global_data.wakeup_key_count);
+ rcu_start_adv(ADV_UNDIRECT_WAKEUP);
+ }
+ else if (app_global_data.rcu_status == RCU_STATUS_ADVERTISING)
+ {
+ if ((app_global_data.adv_type == ADV_DIRECT_LDC)
+ || (app_global_data.adv_type == ADV_DIRECT_HDC)
+ || (app_global_data.adv_type == ADV_UNDIRECT_RECONNECT))
+ {
+ app_global_data.wakeup_key_index = key_index;
+ app_global_data.wakeup_key_count++;
+ app_save_wakeup_key_cnt(app_global_data.wakeup_key_count);
+ rcu_stop_adv(STOP_ADV_REASON_WAKEUPKEY);
+ }
+ }
+ }
+ else
+ {
+ if (app_global_data.rcu_status == RCU_STATUS_IDLE)
+ {
+ rcu_start_adv(ADV_DIRECT_LDC);
+ }
+ else if (app_global_data.rcu_status == RCU_STATUS_ADVERTISING)
+ {
+ if ((app_global_data.adv_type == ADV_DIRECT_LDC)
+ || (app_global_data.adv_type == ADV_UNDIRECT_RECONNECT)
+ || (app_global_data.adv_type == ADV_DIRECT_LDC_LT))
+ {
+ rcu_stop_adv(STOP_ADV_REASON_RESTART_RECONNECT_ADV);
+ }
+ }
+ }
+ }
+
+ if ((key_index == KEY_ID_DPadCenter)
+ || (key_index == KEY_ID_Back))
+ {
+ APP_PRINT_INFO0("[key_handle_one_key_scenario] delay IR post");
+ key_handle_global_data.combine_keys_status = IR_DELAY_TX_KEYS_BIT_MASK;
+ os_timer_restart(&combine_keys_detection_timer, IR_DELAY_TX_TIMEOUT);
+ }
+ else
+ {
+ if (key_type == KEY_TYPE_IR_PROGRAMMED)
+ {
+ ir_send_key_press_handle(key_index, RAW_PROTOCOL);
+ LED_BLINK(LED_TYPE_BLINK_KEY_PRESS_PROG, 1);
+ }
+ else if ((key_type == KEY_TYPE_IR_ONLY)
+ || (key_type == KEY_TYPE_BLE_AND_IR)
+ || (key_type == KEY_TYPE_BLE_OR_IR))
+ {
+ ir_send_key_press_handle(key_index, NEC_PROTOCOL);
+ LED_BLINK(LED_TYPE_BLINK_KEY_PRESS_IR, 1);
+ }
+
+ if ((key_type == KEY_TYPE_BLE_ONLY)
+ || (key_type == KEY_TYPE_BLE_AND_IR)
+ || (key_type == KEY_TYPE_IR_PROGRAMMED))
+ {
+ if (true == app_global_data.is_link_key_existed)
+ {
+ key_handle_inqueue_key_pressed_cache_fifo(key_index);
+ }
+ }
+ }
+ }
+}
+
+/******************************************************************
+ * @brief key handle process repairing event
+ * @param none
+ * @return none
+ */
+void key_handle_process_repairing_event(void)
+{
+ key_handle_reset_key_pressed_cache_fifo();
+
+#if FEAUTRE_SUPPORT_IR_OVER_BLE
+ ir_service_handle_reset_ir_table();
+#endif
+
+ app_global_data.pair_failed_retry_cnt = 0;
+ switch (app_global_data.rcu_status)
+ {
+ case RCU_STATUS_IDLE:
+ {
+ rcu_start_adv(ADV_UNDIRECT_PAIRING);
+ }
+ break;
+ case RCU_STATUS_ADVERTISING:
+ {
+ if (app_global_data.adv_type == ADV_UNDIRECT_PAIRING)
+ {
+ if (true == app_global_data.is_link_key_existed)
+ {
+ os_timer_restart(&adv_timer, ADV_UNDIRECT_REPAIRING_TIMEOUT);
+ }
+ else
+ {
+ os_timer_restart(&adv_timer, ADV_UNDIRECT_PAIRING_TIMEOUT);
+ }
+ }
+ else
+ {
+ os_timer_stop(&adv_timer);
+ rcu_stop_adv(STOP_ADV_REASON_PAIRING);
+ }
+ }
+ break;
+ case RCU_STATUS_PAIRED:
+ {
+ rcu_terminate_connection(DISCONN_REASON_PAIRING);
+ }
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+}
+
+/******************************************************************
+ * @brief key handle process factory reset event
+ * @param none
+ * @return none
+ */
+void key_handle_process_factory_reset_event(void)
+{
+ if (bat_get_current_mode() == BAT_MODE_LOW_POWER)
+ {
+ APP_PRINT_INFO0("LOW POWER INDICATION: CAN NOT ENTER FACTORY RESET");
+ return;
+ }
+ bool result = true;
+
+#if FEATURE_SUPPORT_MP_TEST_MODE
+ if (true == mp_test_is_test_mode_flag_en())
+ {
+ result = mp_test_disable_test_mode_flag();
+ }
+#endif
+
+ /* reset FTL section */
+ if (app_global_data.is_link_key_existed)
+ {
+ app_global_data.is_link_key_existed = false;
+ le_bond_clear_all_keys();
+ }
+
+#if FEAUTRE_SUPPORT_IR_OVER_BLE
+ ir_service_handle_invalid_ftl_table();
+#endif
+
+ app_global_data.wakeup_key_count = 0;
+ app_save_wakeup_key_cnt(app_global_data.wakeup_key_count);
+
+#if SUPPORT_LED_INDICATION_FEATURE
+ if (result)
+ {
+ LED_BLINK(LED_TYPE_BLINK_CONFIRMATION, 2);
+ }
+ else
+ {
+ LED_BLINK(LED_TYPE_BLINK_ERROR, 4);
+ }
+#endif
+ os_timer_restart(&system_rest_timer, SYSTEM_RESET_TIMEOUT);;
+}
+
+/******************************************************************
+ * @brief key handle process shortcut event
+ * @param none
+ * @return none
+ */
+void key_handle_process_access_shortcut_event(void)
+{
+#if SUPPORT_LED_INDICATION_FEATURE
+ LED_BLINK(LED_TYPE_BLINK_CONFIRMATION, 2);
+#endif
+ if (app_global_data.rcu_status == RCU_STATUS_PAIRED)
+ {
+ APP_PRINT_INFO0("shortcut_event: in BLE");
+ }
+ else
+ {
+ APP_PRINT_INFO0("shortcut_event: in IR");
+ ir_send_data_one_time_handle(KEY_ID_SHORTCUT, NEC_PROTOCOL);
+ }
+}
+/******************************************************************
+ * @brief key handle process bug report event
+ * @param none
+ * @return none
+ */
+void key_handle_process_bug_report_event(void)
+{
+#if SUPPORT_IR_TX_FEATURE
+ if (app_global_data.rcu_status != RCU_STATUS_PAIRED &&
+ app_global_data.rcu_status != RCU_STATUS_CONNECTED)
+ {
+ ir_send_data_one_time_handle(KEY_ID_BugReport, NEC_PROTOCOL);
+ }
+#endif
+
+#if SUPPORT_LED_INDICATION_FEATURE
+ LED_BLINK(LED_TYPE_BLINK_CONFIRMATION, 2);
+#endif
+}
+
+/******************************************************************
+ * @brief key handle process ir delay tx event
+ * @param none
+ * @return none
+ */
+void key_handle_process_ir_delay_tx_event(void)
+{
+ if ((keyscan_global_data.cur_fifo_data.len == 1)
+ && (app_global_data.rcu_status != RCU_STATUS_PAIRED))
+ {
+ T_KEYSCAN_DATA keyscan_data = keyscan_global_data.cur_fifo_data.key[0];
+ T_KEY_INDEX_DEF key_index =
+ key_handle_global_data.cur_key_mapping_table[keyscan_data.row][keyscan_data.column];
+
+ if ((key_index == KEY_ID_DPadCenter)
+ || (key_index == KEY_ID_Back))
+ {
+ ir_send_key_press_handle(key_index, NEC_PROTOCOL);
+ LED_BLINK(LED_TYPE_BLINK_KEY_PRESS_IR, 1);
+
+ if (true == app_global_data.is_link_key_existed)
+ {
+ key_handle_inqueue_key_pressed_cache_fifo(key_index);
+ }
+ }
+ }
+}
+
+/******************************************************************
+ * @brief key handle detect combine keys
+ * @param p_keyscan_fifo_data - the point of keyscan fifo data
+ * @return bool - true or false
+ * @retval void
+ */
+bool key_handle_detect_special_keys(T_KEYSCAN_FIFO_DATA *p_keyscan_fifo_data)
+{
+ bool result = false;
+ uint32_t timeout_ms = COMBINE_KEYS_DETECT_TIMEOUT;
+
+ if ((p_keyscan_fifo_data->len == 2)
+ && (true == key_handle_is_key_index_in_fifo(KEY_ID_Home, p_keyscan_fifo_data))
+ && (true == key_handle_is_key_index_in_fifo(KEY_ID_Back, p_keyscan_fifo_data)))
+ {
+ key_handle_global_data.combine_keys_status = PAIRING_COMBINE_KEYS_BIT_MASK;
+ LED_BLINK(LED_TYPE_BLINK_COMB_KEY_PRESS, 0);
+ }
+ else if ((p_keyscan_fifo_data->len == 2)
+ && (true == key_handle_is_key_index_in_fifo(KEY_ID_DPadCenter, p_keyscan_fifo_data))
+ && (true == key_handle_is_key_index_in_fifo(KEY_ID_Mute, p_keyscan_fifo_data)))
+ {
+ key_handle_global_data.combine_keys_status = FACTORY_RESET_COMBINE_KEYS_BIT_MASK;
+ /* update timeout period */
+ timeout_ms = FACTORY_RESET_KEYS_DETECT_TIMEOUT;
+ LED_BLINK(LED_TYPE_BLINK_COMB_KEY_PRESS, 0);
+ }
+ else if ((p_keyscan_fifo_data->len == 2)
+ && (true == key_handle_is_key_index_in_fifo(KEY_ID_DPadCenter, p_keyscan_fifo_data))
+ && (true == key_handle_is_key_index_in_fifo(KEY_ID_Back, p_keyscan_fifo_data)))
+ {
+ key_handle_global_data.combine_keys_status = BUG_REPORT_COMBINE_KEYS_BIT_MASK;
+
+ /* update timeout period */
+ timeout_ms = BUG_REPOERT_DETECT_TIMEOUT;
+ LED_BLINK(LED_TYPE_BLINK_COMB_KEY_PRESS, 0);
+ if (app_global_data.rcu_status == RCU_STATUS_PAIRED)
+ {
+ app_global_data.allow_to_send_two_ble_key_value = true;
+ }
+ }
+ else if ((p_keyscan_fifo_data->len == 2)
+ && (true == key_handle_is_key_index_in_fifo(KEY_ID_DPadDown, p_keyscan_fifo_data))
+ && (true == key_handle_is_key_index_in_fifo(KEY_ID_Back, p_keyscan_fifo_data)))
+ {
+ key_handle_global_data.combine_keys_status = ACCESS_SHORTCUT_COMBINE_KEYS_BIT_MASK;
+ /* update timeout period */
+ timeout_ms = ACCESS_SHORTCUT_DETECT_TIMEOUT;
+ LED_BLINK(LED_TYPE_BLINK_COMB_KEY_PRESS, 0);
+ if (app_global_data.rcu_status == RCU_STATUS_PAIRED)
+ {
+ app_global_data.allow_to_send_two_ble_key_value = true;
+ }
+ }
+ else if ((p_keyscan_fifo_data->len == 2)
+ && (true == key_handle_check_navy_key(p_keyscan_fifo_data->key[0]))
+ && (true == key_handle_check_navy_key(p_keyscan_fifo_data->key[1])))
+ {
+ if (app_global_data.rcu_status == RCU_STATUS_PAIRED)
+ {
+ APP_PRINT_INFO0("in BLE mode:[key_handle_check_navy_key] 2 keys are all navi keys");
+ app_global_data.allow_to_send_two_ble_key_value = true;
+ }
+ else
+ {
+ APP_PRINT_INFO0("in IR mode:[key_handle_check_navy_key] 2 keys are all navi keys, force len to 1!");
+ p_keyscan_fifo_data->len = 1;
+ }
+ }
+
+ APP_PRINT_INFO1("[key_handle_detect_special_keys] combine_keys_status is 0x%04X",
+ key_handle_global_data.combine_keys_status);
+ if (key_handle_global_data.combine_keys_status != INVALID_COMBINE_KEYS_BIT_MASK)
+ {
+ result = true;
+ /* start combine keys dectecion timer */
+ os_timer_restart(&combine_keys_detection_timer, timeout_ms);
+ }
+
+ return result;
+}
+
+/******************************************************************
+ * @brief key handle combine keys detected timer callback
+ * @param p_timer - point of timer
+ * @return none
+ * @retval void
+ * @note do NOT execute time consumption functions in timer callback
+ */
+void key_handle_comb_keys_timer_cb(TimerHandle_t p_timer)
+{
+ /* check combine keys status */
+ APP_PRINT_INFO1("[key_handle_comb_keys_timer_cb] combine_keys_status is 0x%04X",
+ key_handle_global_data.combine_keys_status);
+
+ LED_BLINK_EXIT(LED_TYPE_BLINK_COMB_KEY_PRESS);
+
+ if (PAIRING_COMBINE_KEYS_BIT_MASK == key_handle_global_data.combine_keys_status)
+ {
+ key_handle_process_repairing_event();
+ }
+ else if (FACTORY_RESET_COMBINE_KEYS_BIT_MASK == key_handle_global_data.combine_keys_status)
+ {
+ key_handle_process_factory_reset_event();
+ }
+ else if (BUG_REPORT_COMBINE_KEYS_BIT_MASK == key_handle_global_data.combine_keys_status)
+ {
+ key_handle_process_bug_report_event();
+ }
+ else if (ACCESS_SHORTCUT_COMBINE_KEYS_BIT_MASK == key_handle_global_data.combine_keys_status)
+ {
+ key_handle_process_access_shortcut_event();
+ }
+ else if (IR_DELAY_TX_KEYS_BIT_MASK == key_handle_global_data.combine_keys_status)
+ {
+ key_handle_process_ir_delay_tx_event();
+ }
+
+#if FEATURE_SUPPORT_MP_TEST_MODE
+ mp_test_handle_comb_keys_timer_cb(key_handle_global_data.combine_keys_status);
+#endif
+}
+
+/******************************************************************
+ * @brief notify key data after reconn timer callback
+ * @param p_timer - point of timer
+ * @return none
+ * @retval void
+ * @note do NOT execute time consumption functions in timer callback
+ */
+void notify_key_data_timer_cb(TimerHandle_t p_timer)
+{
+ APP_PRINT_INFO2("[notify_key_data_timer_cb] rcu_status is %d, cached fifo length is %d",
+ app_global_data.rcu_status, current_cache_fifo_items_cnt);
+
+ if ((app_global_data.rcu_status == RCU_STATUS_PAIRED) &&
+ (cache_fifo_output_cnt < current_cache_fifo_items_cnt))
+ {
+ uint8_t key_index = key_handle_dequeue_key_pressed_cache_fifo();
+
+ if (key_index == KEY_ID_NONE)
+ {
+ key_handle_reset_key_pressed_cache_fifo();
+ }
+ else
+ {
+ if (KEY_TYPE_IR_PROGRAMMED == key_handle_get_key_type_by_index((T_KEY_INDEX_DEF) key_index))
+ {
+ if (false == ir_service_handle_is_key_suppressed(key_index))
+ {
+ ir_service_handle_notify_ir_key_event(key_index, KEY_ACTION_DOWN);
+ ir_service_handle_notify_ir_key_event(key_index, KEY_ACTION_UP);
+ }
+ else
+ {
+ key_handle_notify_hid_key_event_by_index((T_KEY_INDEX_DEF)key_index);
+ key_handle_notify_hid_release_event();
+ }
+ }
+ else
+ {
+ key_handle_notify_hid_key_event_by_index((T_KEY_INDEX_DEF)key_index);
+ key_handle_notify_hid_release_event();
+ }
+
+ os_timer_restart(&notify_key_data_after_reconn_timer, NOTIFY_KEY_DATA_INTERVAL_TIMEOUT);
+ }
+ }
+ else
+ {
+ key_handle_reset_key_pressed_cache_fifo();
+ }
+}
+
+/******************************************************************
+ * @brief long press key detect timer callback
+ * @param p_timer - point of timer
+ * @return none
+ * @retval void
+ */
+void long_press_key_detect_timer_cb(TimerHandle_t p_timer)
+{
+ APP_PRINT_INFO0("[long_press_key_detect_timer_cb] detect key long pressed event");
+ key_handle_release_event();
+ key_handle_global_data.is_key_long_pressed = true;
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief Get key type by key index
+ * @param key_index - key index
+ * @return T_KEY_TYPE_DEF - key type
+ * @retval void
+ */
+T_KEY_TYPE_DEF key_handle_get_key_type_by_index(T_KEY_INDEX_DEF key_index)
+{
+ return key_handle_global_data.cur_key_code_table[key_index].key_type;
+}
+
+/******************************************************************
+ * @brief Get IR key code by key index
+ * @param key_index - key index
+ * @return uint8_t - ir key code
+ * @retval void
+ */
+IR_KEY_CODE key_handle_get_ir_key_code_by_index(T_KEY_INDEX_DEF key_index)
+{
+ return key_handle_global_data.cur_key_code_table[key_index].ir_key_code;
+}
+
+/******************************************************************
+ * @brief Get HID usage page by key index
+ * @param key_index - key index
+ * @return uint8_t - hid usage page
+ * @retval void
+ */
+uint8_t key_handle_get_hid_usage_page_by_index(T_KEY_INDEX_DEF key_index)
+{
+ return key_handle_global_data.cur_key_code_table[key_index].hid_usage_page;
+}
+
+/******************************************************************
+ * @brief Get HID usage id by key index
+ * @param key_index - key index
+ * @return uint16_t - hid usage id
+ * @retval void
+ */
+uint16_t key_handle_get_hid_usage_id_by_index(T_KEY_INDEX_DEF key_index)
+{
+ return key_handle_global_data.cur_key_code_table[key_index].hid_usage_id;
+}
+
+/******************************************************************
+ * @brief Initialize key handle data
+ * @param dev_type - device type
+ * @return none
+ * @retval void
+ */
+void key_handle_init_data(void)
+{
+ APP_PRINT_INFO0("[key_handle_init_data] init data");
+ memset(&key_handle_global_data, 0, sizeof(key_handle_global_data));
+
+ /* set default keyscan parameters */
+ key_handle_global_data.keyscan_row_size = KEYPAD_MAX_ROW_SIZE_G10;
+ key_handle_global_data.keyscan_column_size = KEYPAD_MAX_COLUMN_SIZE_G10;
+ key_handle_global_data.ir_prog_key_down_id = KEY_ID_NONE;
+ memcpy(key_handle_global_data.cur_key_mapping_table, KEY_MAPPING_TABLE_G10,
+ sizeof(KEY_MAPPING_TABLE_G10));
+ memcpy(key_handle_global_data.cur_key_code_table, KEY_CODE_TABLE, sizeof(KEY_CODE_TABLE));
+
+ key_handle_reset_key_pressed_cache_fifo();
+}
+
+/******************************************************************
+ * @brief Set key typte to KEY_TYPE_IR_PROGRAMMED by key_id
+ * @param key_id - key id
+ * @return none
+ * @retval void
+ */
+void key_handle_set_key_type_prog_by_id(uint8_t key_id)
+{
+ APP_PRINT_INFO1("[key_handle_set_key_type_prog_by_id] key_id = %d", key_id);
+ key_handle_global_data.cur_key_code_table[key_id].key_type = KEY_TYPE_IR_PROGRAMMED;
+}
+
+/******************************************************************
+ * @brief Restore key typte by key_id
+ * @param key_id - key id
+ * @return none
+ * @retval void
+ */
+void key_handle_restore_key_type_id(uint8_t key_id)
+{
+ APP_PRINT_INFO1("[key_handle_restore_key_type_id] key_id = %d", key_id);
+ key_handle_global_data.cur_key_code_table[key_id].key_type = KEY_CODE_TABLE[key_id].key_type;
+}
+
+/******************************************************************
+ * @brief key handler init timer
+ * @param none
+ * @return none
+ * @retval void
+ */
+void key_handle_init_timer(void)
+{
+ APP_PRINT_INFO0("[key_handle_init_timer] init timer");
+ /* combine_keys_detection_timer is used to detect combine keys after timeout */
+ if (false == os_timer_create(&combine_keys_detection_timer, "combine_keys_detection_timer", 1, \
+ COMBINE_KEYS_DETECT_TIMEOUT, false, key_handle_comb_keys_timer_cb))
+ {
+ APP_PRINT_ERROR0("[key_handle_init_timer] combine_keys_detection_timer creat failed!");
+ }
+
+ /* notify_key_data_after_reconn_timer is used to notify key data after timeout */
+ if (false == os_timer_create(&notify_key_data_after_reconn_timer,
+ "notify_key_data_after_reconn_timer", 1, \
+ NOTIFY_KEY_DATA_TIMEOUT, false, notify_key_data_timer_cb))
+ {
+ APP_PRINT_ERROR0("[key_handle_init_timer] notify_key_data_after_reconn_timer creat failed!");
+ }
+#if FEATURE_SUPPORT_KEY_LONG_PRESS_PROTECT
+ if (false == os_timer_create(&long_press_key_detect_timer, "long_press_key_detect_timer", 1, \
+ LONG_PRESS_KEY_DETECT_TIMEOUT, false, long_press_key_detect_timer_cb))
+ {
+ APP_PRINT_ERROR0("[key_handle_init_timer] long_press_key_detect_timer creat failed!");
+ }
+#endif
+}
+
+/******************************************************************
+ * @brief key handle check specific key index is in keyscan FIFO or not
+ * @param key_index - key index
+ * @param p_keyscan_fifo_data - the point of keyscan fifo data
+ * @return bool - true or false
+ * @retval void
+ */
+bool key_handle_is_key_index_in_fifo(T_KEY_INDEX_DEF key_index,
+ T_KEYSCAN_FIFO_DATA *p_keyscan_fifo_data)
+{
+ for (uint32_t loop_index = 0; loop_index < p_keyscan_fifo_data->len; loop_index++)
+ {
+ if (key_index ==
+ key_handle_global_data.cur_key_mapping_table[p_keyscan_fifo_data->key[loop_index].row][p_keyscan_fifo_data->key[loop_index].column])
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/******************************************************************
+ * @brief key handle check specific key index is in navi key or not
+ * @param key_index - key index
+ * @return bool - true or false
+ * @retval void
+ */
+bool key_handle_check_navy_key(T_KEYSCAN_DATA keyscan_data)
+{
+ T_KEY_INDEX_DEF key_index =
+ key_handle_global_data.cur_key_mapping_table[keyscan_data.row][keyscan_data.column];
+
+ if ((key_index == KEY_ID_DPadUp) || (key_index == KEY_ID_DPadDown) ||
+ (key_index == KEY_ID_DPadLeft) || (key_index == KEY_ID_DPadRight))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+/******************************************************************
+ * @brief key handle notify hid key event by index
+ * @param key_index - index of key
+ * @return bool - true of false
+ * @retval none
+ */
+bool key_handle_notify_hid_key_event_by_index(T_KEY_INDEX_DEF key_index)
+{
+ bool result = false;
+
+ memset(&key_handle_global_data.current_hid_usage_buf, 0, sizeof(T_KEY_HID_USAGES_BUFFER));
+
+ if (true == key_handle_prepare_hid_usage_buffer(key_index,
+ &key_handle_global_data.current_hid_usage_buf))
+ {
+ if (true == key_handle_notify_hid_usage_buffer(&key_handle_global_data.current_hid_usage_buf,
+ &key_handle_global_data.prev_hid_usage_buf))
+ {
+ memcpy(&key_handle_global_data.prev_hid_usage_buf, &key_handle_global_data.current_hid_usage_buf,
+ sizeof(T_KEY_HID_USAGES_BUFFER));
+ result = true;
+
+ if (ATVV_VERSION_0_4 == atvv_global_data.app_support_version)
+ {
+ if (key_index == KEY_ID_DPadCenter)
+ {
+ bool notify_result = false;
+ memset(atvv_global_data.char_ctl_data_buff, 0, ATVV_CHAR_CTL_DATA_LEN);
+ atvv_global_data.char_ctl_data_buff[0] = ATV_CTL_OPCODE_DPAD_SELECT;
+
+ notify_result = server_send_data(0, app_global_data.atvv_srv_id, GATT_SVC_ATVV_CHAR_CTL_VALUE_INDEX,
+ atvv_global_data.char_ctl_data_buff, 1, GATT_PDU_TYPE_NOTIFICATION);
+ if (notify_result == false)
+ {
+ APP_PRINT_WARN0("[key_handle_notify_hid_key_event_by_index] ATV_CTL_OPCODE_DPAD_SELECT notify failed!");
+ }
+ else
+ {
+ APP_PRINT_INFO0("[key_handle_notify_hid_key_event_by_index] ATV_CTL_OPCODE_DPAD_SELECT notify success!");
+ }
+ }
+ }
+ }
+ }
+
+ APP_PRINT_INFO2("[key_handle_notify_hid_key_event_by_index] key_index is %d, result = %d",
+ key_index, result);
+
+ return result;
+}
+
+/******************************************************************
+ * @brief key handle notify hid key event by keyscan fifo
+ * @param p_keyscan_fifo_data - point of keyscan fifo data
+ * @return bool - true of false
+ * @retval none
+ */
+bool key_handle_notify_hid_key_event_by_fifo(T_KEYSCAN_FIFO_DATA *p_keyscan_fifo_data)
+{
+ bool result = false;
+ T_KEY_INDEX_DEF key_index;
+ T_KEY_TYPE_DEF key_type;
+
+ memset(&key_handle_global_data.current_hid_usage_buf, 0, sizeof(T_KEY_HID_USAGES_BUFFER));
+
+ for (uint8_t loop_index = 0; loop_index < p_keyscan_fifo_data->len; loop_index++)
+ {
+ key_index =
+ key_handle_global_data.cur_key_mapping_table[p_keyscan_fifo_data->key[loop_index].row][p_keyscan_fifo_data->key[loop_index].column];
+ key_type = key_handle_global_data.cur_key_code_table[key_index].key_type;
+
+ if ((key_type == KEY_TYPE_BLE_ONLY)
+ || (key_type == KEY_TYPE_BLE_AND_IR)
+ || (key_type == KEY_TYPE_BLE_OR_IR))
+ {
+ if (true == key_handle_prepare_hid_usage_buffer(key_index,
+ &key_handle_global_data.current_hid_usage_buf))
+ {
+ /* get invalid hid usage */
+ result = true;
+ }
+ }
+ }
+
+ if (true == result)
+ {
+ if (true == key_handle_notify_hid_usage_buffer(&key_handle_global_data.current_hid_usage_buf,
+ &key_handle_global_data.prev_hid_usage_buf))
+ {
+ memcpy(&key_handle_global_data.prev_hid_usage_buf, &key_handle_global_data.current_hid_usage_buf,
+ sizeof(T_KEY_HID_USAGES_BUFFER));
+ result = true;
+ }
+ else
+ {
+ result = false;
+ }
+ }
+
+ APP_PRINT_INFO2("[key_handle_notify_hid_key_event_by_fifo] len is %d, result = %d",
+ p_keyscan_fifo_data->len, result);
+
+ return result;
+}
+
+/******************************************************************
+ * @brief key handle notify hid release event
+ * @param void
+ * @return bool - true of false
+ * @retval none
+ */
+bool key_handle_notify_hid_release_event(void)
+{
+ bool result = false;
+
+ memset(&key_handle_global_data.current_hid_usage_buf, 0, sizeof(T_KEY_HID_USAGES_BUFFER));
+
+ if (true == key_handle_notify_hid_usage_buffer(&key_handle_global_data.current_hid_usage_buf,
+ &key_handle_global_data.prev_hid_usage_buf))
+ {
+ memcpy(&key_handle_global_data.prev_hid_usage_buf, &key_handle_global_data.current_hid_usage_buf,
+ sizeof(T_KEY_HID_USAGES_BUFFER));
+ result = true;
+ }
+
+ return result;
+}
+
+/******************************************************************
+ * @brief handle key pressed event
+ * @param p_keyscan_fifo_data - point of keyscan FIFO data
+ * @return none
+ * @retval void
+ */
+void key_handle_pressed_event(T_KEYSCAN_FIFO_DATA *p_keyscan_fifo_data)
+{
+ key_handle_global_data.key_pressed_count++;
+
+ T_KEYSCAN_FIFO_DATA keyscan_fifo_data;
+ memcpy(&keyscan_fifo_data, p_keyscan_fifo_data, sizeof(T_KEYSCAN_FIFO_DATA));
+ APP_PRINT_INFO2("[key_handle_pressed_event] keyscan FIFO length is %d, prev length is %d",
+ keyscan_fifo_data.len, key_handle_global_data.prev_keyscan_fifo_data.len);
+ for (uint8_t index = 0; index < (keyscan_fifo_data.len); index++)
+ {
+ APP_PRINT_INFO4("[key_handle_pressed_event] keyscan data[%d]: row - %d, column - %d, value - %d", \
+ index, keyscan_fifo_data.key[index].row, keyscan_fifo_data.key[index].column,
+ key_handle_global_data.cur_key_mapping_table[keyscan_fifo_data.key[index].row][keyscan_fifo_data.key[index].column]);
+ }
+
+#if SUPPORT_IR_TX_FEATURE
+ if (true == ir_send_is_working())
+ {
+ ir_send_key_release_handle();
+ }
+#endif
+
+#if SUPPORT_VOICE_FEATURE
+ if (true == voice_driver_global_data.is_voice_driver_working)
+ {
+ voice_handle_mic_key_released();
+ }
+#endif
+
+#if SUPPORT_BUZZER_FEATURE
+ if (true == buzzer_is_working_check())
+ {
+ buzzer_stop_pwm_output();
+ fms_handle_notify_status(FMS_STATUS_OK, FMS_ERROR_NO_ERR);
+ }
+#endif
+
+#if SUPPORT_BAT_DETECT_FEATURE
+ bat_msg_handle(IO_MSG_BAT_DETECT_KEY_PRESSED);
+
+ if (bat_get_current_mode() == BAT_MODE_LOW_POWER)
+ {
+ APP_PRINT_INFO0("LOW POWER LED INDICATION");
+ LED_BLINK(LED_TYPE_BLINK_TEST_RED, 5);
+ }
+
+ if (BAT_MODE_POWER_DOWN == bat_get_current_mode())
+ {
+ return;
+ }
+#endif
+
+#if FEATURE_SUPPORT_KEY_LONG_PRESS_PROTECT
+ os_timer_start(&long_press_key_detect_timer);
+#endif
+
+ /* detect special combine keys scenario */
+ key_handle_detect_special_keys(&keyscan_fifo_data);
+
+ if (keyscan_fifo_data.len == 0)
+ {
+ APP_PRINT_WARN0("[key_handle_pressed_event] FIFO length is 0!");
+ key_handle_release_event();
+ }
+ else if (keyscan_fifo_data.len == 1)
+ {
+ if (key_handle_global_data.prev_keyscan_fifo_data.len == 0)
+ {
+ T_KEY_INDEX_DEF key_index_1 =
+ key_handle_global_data.cur_key_mapping_table[keyscan_fifo_data.key[0].row][keyscan_fifo_data.key[0].column];
+
+ key_handle_one_key_scenario(key_index_1);
+ }
+ }
+ else
+ {
+ /* multiple keys event senario */
+#if FEATURE_SUPPORT_REPORT_MULTIPLE_HID_KEY_CODES
+ if (app_global_data.rcu_status == RCU_STATUS_PAIRED)
+ {
+ if (app_global_data.allow_to_send_two_ble_key_value == true)
+ {
+ APP_PRINT_INFO0("key_handle_notify_hid_key_event_by_fifo:allow to send two ble keys");
+ app_global_data.allow_to_send_two_ble_key_value = false;
+ key_handle_notify_hid_key_event_by_fifo(&keyscan_fifo_data);
+ }
+ }
+#else
+ if (app_global_data.rcu_status == RCU_STATUS_PAIRED)
+ {
+ key_handle_notify_hid_release_event();
+ }
+#endif
+ }
+
+ memcpy(&key_handle_global_data.prev_keyscan_fifo_data, &keyscan_fifo_data,
+ sizeof(T_KEYSCAN_FIFO_DATA));
+}
+
+/******************************************************************
+ * @brief handle key release event
+ * @param none
+ * @return none
+ * @retval void
+ */
+void key_handle_release_event(void)
+{
+ APP_PRINT_INFO0("[key_handle_release_event] key release event");
+
+ memset(&key_handle_global_data.prev_keyscan_fifo_data, 0, sizeof(T_KEYSCAN_FIFO_DATA));
+
+#if FEATURE_SUPPORT_KEY_LONG_PRESS_PROTECT
+ os_timer_stop(&long_press_key_detect_timer);
+ key_handle_global_data.is_key_long_pressed = false;
+#endif
+
+#if SUPPORT_IR_TX_FEATURE
+ if (true == ir_send_is_working())
+ {
+ ir_send_key_release_handle();
+ }
+#endif
+
+#if SUPPORT_VOICE_FEATURE
+ if (voice_driver_global_data.is_voice_driver_working == true)
+ {
+ voice_handle_mic_key_released();
+ }
+ else
+#endif
+ if (app_global_data.rcu_status == RCU_STATUS_PAIRED)
+ {
+ if (key_handle_global_data.ir_prog_key_down_id != KEY_ID_NONE)
+ {
+ ir_service_handle_notify_ir_key_event(key_handle_global_data.ir_prog_key_down_id, KEY_ACTION_UP);
+ key_handle_global_data.ir_prog_key_down_id = KEY_ID_NONE;
+ }
+
+ key_handle_notify_hid_release_event();
+ }
+}
+
+/******************************************************************
+ * @brief handle key release event
+ * @param none
+ * @return none
+ * @retval void
+ */
+void key_handle_disconnect_event(void)
+{
+ key_handle_reset_key_pressed_cache_fifo();
+}
+
+/******************************************************************
+ * @brief Get key pressed count
+ * @param none
+ * @return uint32_t
+ * @retval key_pressed_count
+ */
+uint32_t key_handle_get_key_pressed_count(void)
+{
+ return key_handle_global_data.key_pressed_count;
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/key_module/key_handle.h b/src/app/google_rcu/key_module/key_handle.h
new file mode 100644
index 0000000..0af07d1
--- /dev/null
+++ b/src/app/google_rcu/key_module/key_handle.h
@@ -0,0 +1,359 @@
+/*****************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file key_handle.h
+ * @brief This file contains all the constants and functions prototypes for key handle.
+ * @details
+ * @author barry_bian
+ * @date 2020-02-25
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#ifndef _KEY_HANDLE_H_
+#define _KEY_HANDLE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdint.h>
+#include <stdbool.h>
+#include <keyscan_driver.h>
+
+/*============================================================================*
+ * Macro Definitions
+ *============================================================================*/
+/* define the bit mask of combine keys */
+#define INVALID_COMBINE_KEYS_BIT_MASK 0x0000
+#define PAIRING_COMBINE_KEYS_BIT_MASK 0x0001
+#define IR_LEARNING_COMBINE_KEYS_BIT_MASK 0x0002
+#define HCI_UART_TEST_COMBINE_KEYS_BIT_MASK 0x0004
+#define DATA_UART_TEST_COMBINE_KEYS_BIT_MASK 0x0008
+#define SINGLE_TONE_TEST_COMBINE_KEYS_BIT_MASK 0x0010
+#define FAST_PAIR_1_COMBINE_KEYS_BIT_MASK 0x0020
+#define FAST_PAIR_2_COMBINE_KEYS_BIT_MASK 0x0040
+#define FAST_PAIR_3_COMBINE_KEYS_BIT_MASK 0x0080
+#define FAST_PAIR_4_COMBINE_KEYS_BIT_MASK 0x0100
+#define FAST_PAIR_5_COMBINE_KEYS_BIT_MASK 0x0200
+#define BUG_REPORT_COMBINE_KEYS_BIT_MASK 0x0400
+#define ACCESS_SHORTCUT_COMBINE_KEYS_BIT_MASK 0x0800
+#define FACTORY_RESET_COMBINE_KEYS_BIT_MASK 0x1000
+#define IR_DELAY_TX_KEYS_BIT_MASK 0x2000
+
+#define COMBINE_KEYS_DETECT_TIMEOUT 4000 /* 4 sec */
+#define COMBINE_KEYS_TEST_DETECT_TIMEOUT 2000 /* 2 sec */
+#define FACTORY_RESET_KEYS_DETECT_TIMEOUT 4000 /* 4 sec */
+#define BUG_REPOERT_DETECT_TIMEOUT 1000 /* 1 sec */
+#define ACCESS_SHORTCUT_DETECT_TIMEOUT 1000 /* 1 sec */
+#define NOTIFY_KEY_DATA_TIMEOUT 100 /* 100 ms */
+#define NOTIFY_KEY_DATA_INTERVAL_TIMEOUT 20 /* 20 ms */
+#define IR_DELAY_TX_TIMEOUT 100 /* 100 ms */
+#define LONG_PRESS_KEY_DETECT_TIMEOUT 30000 /* 30 sec */
+
+#define MAX_HID_KEYBOARD_USAGE_CNT 8
+#define MAX_HID_CONSUMER_USAGE_CNT 3
+
+#define DEFAULT_IR_NEC_ADDR_1 0x88
+#define DEFAULT_IR_NEC_ADDR_2 0x77
+
+#define IR_VK_1 0x01
+#define IR_VK_2 0x02
+#define IR_VK_3 0x03
+#define IR_VK_4 0x04
+#define IR_VK_5 0x05
+#define IR_VK_6 0x06
+#define IR_VK_7 0x07
+#define IR_VK_8 0x08
+#define IR_VK_9 0x09
+#define IR_VK_0 0x0A
+#define IR_SETTINGS 0x0F
+#define IR_DASHBOARD 0x10
+#define IR_UP 0x15
+#define IR_DN 0x16
+#define IR_LEFT 0x17
+#define IR_RIGHT 0x18
+#define IR_CENTER 0x19
+#define IR_POWER 0x21
+#define IR_VOL_UP 0x23
+#define IR_VOL_DN 0x24
+#define IR_MUTE 0x25
+#define IR_INFO 0x29
+#define IR_GUIDE 0x32
+#define IR_CHN_UP 0x33
+#define IR_CHN_DN 0x34
+#define IR_ASSIST 0x46
+#define IR_HOME 0x47
+#define IR_BACK 0x48
+#define IR_YELLOW 0x49
+#define IR_GREEN 0x4a
+#define IR_RED 0x4b
+#define IR_BLUE 0x4c
+#define IR_FASTREWIND 0x51
+#define IR_PLAYPAUSE 0x52
+#define IR_FASTFORWARD 0x53
+#define IR_RECORD 0x54
+#define IR_ALLAPPS 0x57
+#define IR_SUBTITLE 0x58
+#define IR_USERPROFILE 0x59
+#define IR_INPUT 0x60
+#define IR_LIVETV 0x61
+#define IR_NETFLIX 0x63
+#define IR_YOUTUBE 0x64
+#define IR_APP03 0x67
+#define IR_APP04 0x68
+#define IR_BOOKMARK 0x74
+#define IR_TELETEXT 0x75
+#define IR_BUGREPORT 0x96
+#define T_VK_CH_UP 0xd0
+#define T_VK_CH_DN 0xd1
+#define IR_SHORTCUT 0xD0
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef enum
+{
+ KEY_ACTION_DOWN = 0,
+ KEY_ACTION_UP = 1,
+} T_KEY_ACTION_TYPE;
+
+/* define the key index */
+typedef enum
+{
+ KEY_ID_Power = 0,
+ KEY_ID_DPadRight = 1,
+ KEY_ID_VolDown = 2,
+ KEY_ID_Info = 3,
+ KEY_ID_4 = 4,
+ KEY_ID_Green = 5,
+ KEY_ID_Input = 6,
+ KEY_ID_DPadDown = 7,
+ KEY_ID_ChannelDown = 8,
+ KEY_ID_0 = 9,
+ KEY_ID_3 = 10,
+ KEY_ID_Red = 11,
+ KEY_ID_Bookmark = 12,
+ KEY_ID_Back = 13,
+ KEY_ID_Youtube = 14,
+ KEY_ID_Subtitles = 15,
+ KEY_ID_2 = 16,
+ KEY_ID_6 = 17,
+ KEY_ID_Assistant = 18,
+ KEY_ID_Home = 19,
+ KEY_ID_Netflix = 20,
+ KEY_ID_9 = 21,
+ KEY_ID_1 = 22,
+ KEY_ID_5 = 23,
+ KEY_ID_Dashboard = 24,
+ KEY_ID_Guide = 25,
+ KEY_ID_APP03 = 26,
+ KEY_ID_8 = 27,
+ KEY_ID_Blue = 28,
+ KEY_ID_AllApps = 29,
+ KEY_ID_DPadUp = 30,
+ KEY_ID_VolUp = 31,
+ KEY_ID_APP04 = 32,
+ KEY_ID_7 = 33,
+ KEY_ID_Yellow = 34,
+ KEY_ID_Profile = 35,
+ KEY_ID_DPadLeft = 36,
+ KEY_ID_ChannelUp = 37,
+ KEY_ID_Settings = 38,
+ KEY_ID_Live = 39,
+ KEY_ID_Mute = 40,
+ KEY_ID_FastRewind = 41,
+ KEY_ID_DPadCenter = 42,
+ KEY_ID_Record = 43,
+ KEY_ID_PlayPause = 44,
+ KEY_ID_FastForward = 45,
+ KEY_ID_TEXT = 46,
+ KEY_ID_BugReport = 47,
+ KEY_ID_SHORTCUT = 48,
+ KEY_ID_NONE = 49,
+
+ KEY_INDEX_ENUM_GUAID = 50,
+
+} T_KEY_INDEX_DEF;
+
+/* define the key types */
+typedef enum
+{
+ KEY_TYPE_NONE = 0x00, /* none key type */
+ KEY_TYPE_BLE_ONLY = 0x01, /* only BLE key type */
+ KEY_TYPE_IR_ONLY = 0x02, /* only IR key type */
+ KEY_TYPE_BLE_AND_IR = 0x03, /* BLE and IR key type */
+ KEY_TYPE_BLE_OR_IR = 0x04, /* BLE or IR key type */
+ KEY_TYPE_IR_PROGRAMMED = 0x05, /* programmed IR key type */
+} T_KEY_TYPE_DEF;
+
+/* define the HID usage pages */
+typedef enum
+{
+ HID_UNDEFINED_PAGE = 0x00,
+ HID_KEYBOARD_PAGE = 0x07,
+ HID_CONSUMER_PAGE = 0x0C,
+} T_HID_USAGE_PAGES_DEF;
+
+// media key, consumer key
+//reference: <<HID Usage Tables>> Consumer Page(0x0C)
+typedef enum
+{
+ G00GLE_VK_1 = 0x1e,
+ G00GLE_VK_2 = 0x1f,
+ G00GLE_VK_3 = 0x20,
+ G00GLE_VK_4 = 0x21,
+ G00GLE_VK_5 = 0x22,
+ G00GLE_VK_6 = 0x23,
+ G00GLE_VK_7 = 0x24,
+ G00GLE_VK_8 = 0x25,
+ G00GLE_VK_9 = 0x26,
+ G00GLE_VK_0 = 0x27,
+ G00GLE_VK_VOLUMEUP = 0x80,
+ G00GLE_VK_VOLUMEDOWN = 0x81,
+ G00GLE_SHORTCUT = 0xD0,
+
+//device_layout
+ G00GLE_MKEY_NOTIFICATION = 0x009f,
+ G00GLE_MKEY_LIVETV = 0x0089,
+ G00GLE_MKEY_TELETEXT = 0x0185,
+ G00GLE_MKEY_USERPROFILE = 0x0229,
+ G00GLE_MKEY_ALLAPPS = 0x01A2,
+ G00GLE_MKEY_FASTREWIND = 0x00B4,
+ G00GLE_MKEY_RECORD = 0x00CE,
+ G00GLE_MKEY_PLAYPAUSE = 0x00CD,
+ G00GLE_MKEY_FASTFORWARD = 0x00B3,
+
+//g20
+ G00GLE_MKEY_INFO = 0x01BD,
+ G00GLE_MKEY_SUBTITLE = 0x0061,
+ G00GLE_MKEY_RED = 0x0069,
+ G00GLE_MKEY_GREEN = 0x006A,
+ G00GLE_MKEY_YELLOW = 0x006c,
+ G00GLE_MKEY_BLUE = 0x006b,
+//g10
+ G00GLE_MKEY_YOUTUBE = 0x0077,
+ G00GLE_MKEY_NETFLIX = 0x0078,
+ G00GLE_MKEY_APP03 = 0x0079,
+ G00GLE_MKEY_APP04 = 0x007A,
+ G00GLE_MKEY_UP = 0x0042,
+ G00GLE_MKEY_DN = 0x0043,
+ G00GLE_MKEY_LEFT = 0x0044,
+ G00GLE_MKEY_RIGHT = 0x0045,
+ G00GLE_MKEY_CENTER = 0x0041,
+ G00GLE_MKEY_HOME = 0x0223,
+ G00GLE_MKEY_BACK = 0x0224,
+ G00GLE_MKEY_POWER = 0x0030,
+ G00GLE_MKEY_VOL_MUTE = 0X00E2,
+ G00GLE_MKEY_CHN_UP = 0x009C,
+ G00GLE_MKEY_CHN_DN = 0x009D,
+ G00GLE_MKEY_GUIDE = 0x008D,
+ G00GLE_MKEY_BOOKMARK = 0x022a,
+ G00GLE_MKEY_ASSIST = 0x0221,
+ G00GLE_MKEY_INPUT = 0x01bb,
+ G00GLE_MKEY_SETTINGS = 0x0096,
+ G00GLE_MKEY_DASHBOARD = 0x009F,
+ G00GLE_MKEY_PROFILE = 0x0229,
+} google_media_key_t;
+
+/* define the key code table size, the value should modify according to KEY_CODE_TABLE */
+#define KEY_CODE_TABLE_SIZE KEY_INDEX_ENUM_GUAID
+
+typedef union ir_key_code
+{
+ uint32_t ir_data;
+ struct
+ {
+ uint8_t ir_addr1;
+ uint8_t ir_addr2;
+ uint8_t ir_cmd1;
+ uint8_t ir_cmd2;
+ };
+} IR_KEY_CODE;
+
+
+/* define the struct of key code */
+typedef struct
+{
+ T_KEY_TYPE_DEF key_type;
+ uint8_t hid_usage_page;
+ uint16_t hid_usage_id;
+ IR_KEY_CODE ir_key_code;
+} T_KEY_CODE_DEF;
+
+typedef struct
+{
+ uint8_t keyboard_usage_cnt;
+ uint8_t keyboard_usage_buffer[MAX_HID_KEYBOARD_USAGE_CNT];
+ uint8_t consumer_usage_cnt;
+ uint16_t consumer_usage_buffer[MAX_HID_CONSUMER_USAGE_CNT];
+} T_KEY_HID_USAGES_BUFFER;
+
+/* Key global parameters' struct */
+typedef struct
+{
+ bool is_key_long_pressed; /* to indicate whether key is long pressed */
+ uint8_t keyscan_row_size; /* to indicate the row size of keyscan */
+ uint8_t keyscan_column_size; /* to indicate the column size of keyscan */
+ uint32_t combine_keys_status; /* to indicate the status of combined keys */
+ uint32_t key_pressed_count; /* to indicate the count of key pressed */
+ uint8_t ir_prog_key_down_id; /* to indicate the index of IR programmed key down event */
+ T_KEY_HID_USAGES_BUFFER current_hid_usage_buf; /* to indicate the current key HID usage buffer */
+ T_KEY_HID_USAGES_BUFFER prev_hid_usage_buf; /* to indicate the preivous key HID usage buffer */
+ T_KEYSCAN_FIFO_DATA prev_keyscan_fifo_data; /* to indicateh the previous keyscan fifo data */
+ T_KEY_INDEX_DEF
+ cur_key_mapping_table[KEYPAD_MAX_ROW_SIZE][KEYPAD_MAX_COLUMN_SIZE]; /* to indicate the key mapping table */
+ T_KEY_CODE_DEF cur_key_code_table[KEY_CODE_TABLE_SIZE]; /* to indicate current key code table */
+} T_KEY_HANDLE_GLOBAL_DATA;
+
+/*============================================================================*
+* Export Global Variables
+*============================================================================*/
+extern const uint8_t Wakeup_Map_Correspend_Index_G10[];
+extern const uint8_t Kb_Map_devicelayout_Correspend_Index_G10[];
+extern const uint8_t Wakeup_Map_Correspend_Index_G20[];
+extern const uint8_t Kb_Map_devicelayout_Correspend_Index_G20[];
+extern uint8_t Ir_Override_Table_Index_G10[];
+extern uint8_t Ir_Override_Table_Index_G20[];
+extern const uint8_t Ir_Table_Correspend_Index_G10[];
+extern const uint8_t Ir_Table_Correspend_Index_G20[];
+extern const T_KEY_INDEX_DEF
+KEY_MAPPING_TABLE_G20[KEYPAD_MAX_ROW_SIZE_G20][KEYPAD_MAX_COLUMN_SIZE_G20];
+extern const T_KEY_INDEX_DEF
+KEY_MAPPING_TABLE_G10[KEYPAD_MAX_ROW_SIZE_G10][KEYPAD_MAX_COLUMN_SIZE_G10];
+extern T_KEY_HANDLE_GLOBAL_DATA key_handle_global_data;
+extern TimerHandle_t combine_keys_detection_timer;
+extern TimerHandle_t notify_key_data_after_reconn_timer;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+T_KEY_TYPE_DEF key_handle_get_key_type_by_index(T_KEY_INDEX_DEF key_index);
+IR_KEY_CODE key_handle_get_ir_key_code_by_index(T_KEY_INDEX_DEF key_index);
+uint8_t key_handle_get_hid_usage_page_by_index(T_KEY_INDEX_DEF key_index);
+uint16_t key_handle_get_hid_usage_id_by_index(T_KEY_INDEX_DEF key_index);
+void key_handle_init_data(void);
+void key_handle_pressed_event(T_KEYSCAN_FIFO_DATA *p_keyscan_fifo_data);
+void key_handle_release_event(void);
+bool key_handle_is_key_index_in_fifo(T_KEY_INDEX_DEF key_index,
+ T_KEYSCAN_FIFO_DATA *p_keyscan_fifo_data);
+bool key_handle_notify_hid_key_event_by_index(T_KEY_INDEX_DEF key_index);
+bool key_handle_notify_hid_key_event_by_fifo(T_KEYSCAN_FIFO_DATA *p_keyscan_fifo_data);
+bool key_handle_set_pending_keyscan_fifo_data(T_KEYSCAN_FIFO_DATA *p_data);
+void key_handle_reset_pending_keyscan_fifo_data(void);
+bool key_handle_notify_pending_hid_buffer(void);
+bool key_handle_notify_hid_release_event(void);
+void key_handle_init_timer(void);
+void key_handle_set_key_type_prog_by_id(uint8_t key_id);
+void key_handle_restore_key_type_id(uint8_t key_id);
+void key_handle_disconnect_event(void);
+uint32_t key_handle_get_key_pressed_count(void);
+void key_handle_reset_key_pressed_cache_fifo(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/app/google_rcu/key_module/keyscan_driver.c b/src/app/google_rcu/key_module/keyscan_driver.c
new file mode 100644
index 0000000..5bfa3c5
--- /dev/null
+++ b/src/app/google_rcu/key_module/keyscan_driver.c
@@ -0,0 +1,483 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file keyscan_driver.c
+* @brief keyscan module driver
+* @details
+* @author barry_bian
+* @date 2020-02-25
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <board.h>
+#include <string.h>
+#include <trace.h>
+#include <os_msg.h>
+#include <app_msg.h>
+#include <os_timer.h>
+#include <keyscan_driver.h>
+#include <rtl876x_rcc.h>
+#include <rtl876x_keyscan.h>
+#include <swtimer.h>
+#include <rtl876x_pinmux.h>
+#include <rtl876x_nvic.h>
+#include <app_task.h>
+#include <app_section.h>
+#include "key_handle.h"
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+static TimerHandle_t keyscan_timer;
+static uint8_t KeyScanRowPINs[KEYPAD_MAX_COLUMN_SIZE] = {ROW0, ROW1, ROW2, ROW3, ROW4, ROW5};
+static uint8_t KeyScanColumnPINs[KEYPAD_MAX_COLUMN_SIZE] = {COLUMN0, COLUMN1, COLUMN2, COLUMN3, COLUMN4, COLUMN5, COLUMN6};
+
+/*============================================================================*
+ * Global Variables
+ *============================================================================*/
+T_KEYSCAN_GLOBAL_DATA keyscan_global_data;
+
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+#define keyscan_interrupt_handler Keyscan_Handler
+
+static void keyscan_timer_callback(TimerHandle_t pxTimer) DATA_RAM_FUNCTION;
+static void keyscan_row_pad_config(PAD_Mode AON_PAD_Mode,
+ PAD_PWR_Mode AON_PAD_PwrOn,
+ PAD_Pull_Mode AON_PAD_Pull,
+ PAD_OUTPUT_ENABLE_Mode AON_PAD_E,
+ PAD_OUTPUT_VAL AON_PAD_O) DATA_RAM_FUNCTION;
+static void keyscan_column_pad_config(PAD_Mode AON_PAD_Mode,
+ PAD_PWR_Mode AON_PAD_PwrOn,
+ PAD_Pull_Mode AON_PAD_Pull,
+ PAD_OUTPUT_ENABLE_Mode AON_PAD_E,
+ PAD_OUTPUT_VAL AON_PAD_O) DATA_RAM_FUNCTION;
+
+void keyscan_interrupt_handler(void) DATA_RAM_FUNCTION;
+bool keyscan_check_dlps(void) DATA_RAM_FUNCTION;
+void keyscan_enter_dlps_config(void) DATA_RAM_FUNCTION;
+void keyscan_exit_dlps_config(void) DATA_RAM_FUNCTION;
+void keyscan_init_data(void) DATA_RAM_FUNCTION;
+void keyscan_init_pad_config(void) DATA_RAM_FUNCTION;
+void keyscan_init_driver(uint32_t manual_sel, uint32_t is_debounce) DATA_RAM_FUNCTION;
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief keyscan row pad config
+ * @param AON_PAD_Mode
+ * @param AON_PAD_PwrOn
+ * @param AON_PAD_Pull
+ * @param AON_PAD_E
+ * @param AON_PAD_O
+ * @return none
+ * @retval void
+ */
+static void keyscan_row_pad_config(PAD_Mode AON_PAD_Mode,
+ PAD_PWR_Mode AON_PAD_PwrOn,
+ PAD_Pull_Mode AON_PAD_Pull,
+ PAD_OUTPUT_ENABLE_Mode AON_PAD_E,
+ PAD_OUTPUT_VAL AON_PAD_O)
+{
+ for (uint8_t index = 0; index < key_handle_global_data.keyscan_row_size; index++)
+ {
+ Pad_Config(KeyScanRowPINs[index], AON_PAD_Mode, AON_PAD_PwrOn, AON_PAD_Pull, AON_PAD_E, AON_PAD_O);
+ }
+}
+
+/******************************************************************
+ * @brief keyscan column pad config
+ * @param AON_PAD_Mode
+ * @param AON_PAD_PwrOn
+ * @param AON_PAD_Pull
+ * @param AON_PAD_E
+ * @param AON_PAD_O
+ * @return none
+ * @retval void
+ */
+static void keyscan_column_pad_config(PAD_Mode AON_PAD_Mode,
+ PAD_PWR_Mode AON_PAD_PwrOn,
+ PAD_Pull_Mode AON_PAD_Pull,
+ PAD_OUTPUT_ENABLE_Mode AON_PAD_E,
+ PAD_OUTPUT_VAL AON_PAD_O)
+{
+ for (uint8_t index = 0; index < key_handle_global_data.keyscan_column_size; index++)
+ {
+ Pad_Config(KeyScanColumnPINs[index], AON_PAD_Mode, AON_PAD_PwrOn, AON_PAD_Pull, AON_PAD_E,
+ AON_PAD_O);
+ }
+}
+
+/******************************************************************
+ * @brief keyscan enable wakeup config function
+ * @param none
+ * @return none
+ * @retval void
+ */
+static void keyscan_enable_wakeup_config(void)
+{
+ /* @note: no key is pressed, use PAD wake up function with debounce,
+ but pad debunce time should be smaller than ble connect interval */
+ System_WakeUpDebounceTime(0x08);
+
+ for (uint8_t index = 0; index < key_handle_global_data.keyscan_row_size; index++)
+ {
+ System_WakeUpPinEnable(KeyScanRowPINs[index], PAD_WAKEUP_POL_LOW, PAD_WK_DEBOUNCE_ENABLE);
+ }
+}
+
+/******************************************************************
+ * @brief keyscan disable wakeup config function
+ * @param none
+ * @return none
+ * @retval void
+ */
+static void keyscan_disable_wakeup_config(void)
+{
+ for (uint8_t index = 0; index < key_handle_global_data.keyscan_row_size; index++)
+ {
+ System_WakeUpPinDisable(KeyScanRowPINs[index]);
+ }
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @fn keyscan_init_data
+ * @brief initialize keyscan driver data
+ * @param none
+ * @return none
+ * @retval void
+ */
+void keyscan_init_data(void)
+{
+ KEYSCAN_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[keyscan_init_data] init data", 0);
+ memset(&keyscan_global_data, 0, sizeof(keyscan_global_data));
+ keyscan_global_data.is_allowed_to_enter_dlps = true;
+ keyscan_global_data.is_all_key_released = true;
+}
+
+/******************************************************************
+ * @fn keyscan_init_driver
+ * @brief keyscan module initial
+ * @param uint32_t manual_mode - KeyScan_Manual_Sel_Key or KeyScan_Manual_Sel_Bit
+ * @param uint32_t is_debounce
+ * @return none
+ * @retval void
+ * @note when system in dlsp mode, keyscan debunce time should be smaller
+ * than wake up interval time (like ble interval), which can be modified
+ * through KeyScan_InitStruct.debouncecnt.
+ */
+void keyscan_init_driver(uint32_t manual_sel, uint32_t is_debounce)
+{
+ if (false == keyscan_global_data.is_pinmux_setted)
+ {
+ keyscan_init_pad_config();
+ }
+
+ /* turn on keyscan clock */
+ RCC_PeriphClockCmd(APBPeriph_KEYSCAN, APBPeriph_KEYSCAN_CLOCK, ENABLE);
+
+ KEYSCAN_InitTypeDef KeyScan_InitStruct;
+ KeyScan_StructInit(&KeyScan_InitStruct);
+ KeyScan_InitStruct.colSize = key_handle_global_data.keyscan_column_size;
+ KeyScan_InitStruct.rowSize = key_handle_global_data.keyscan_row_size;
+ KeyScan_InitStruct.scanmode = KeyScan_Manual_Scan_Mode;
+ if (KeyScan_Manual_Scan_Mode == KeyScan_InitStruct.scanmode)
+ {
+ KeyScan_InitStruct.manual_sel = manual_sel;
+ if (manual_sel == KeyScan_Manual_Sel_Bit)
+ {
+ KEYSCAN_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[keyscan_init_driver] KeyScan_Manual_Sel_Bit", 0);
+ }
+ else
+ {
+ KEYSCAN_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[keyscan_init_driver] KeyScan_Manual_Sel_Key", 0);
+ }
+ }
+
+ KeyScan_InitStruct.clockdiv = 0x26; /* 128kHz = 5MHz/(clockdiv+1) */
+ KeyScan_InitStruct.delayclk = 0x0f; /* 8kHz = 5MHz/(clockdiv+1)/(delayclk+1) */
+
+ KeyScan_InitStruct.debounceEn = is_debounce;
+ KeyScan_InitStruct.scantimerEn = KeyScan_ScanInterval_Disable;
+ KeyScan_InitStruct.detecttimerEn = KeyScan_Release_Detect_Disable;
+
+ KeyScan_InitStruct.scanInterval = 0x190; /* 50ms = scanInterval/8kHz */
+ KeyScan_InitStruct.debouncecnt = 0x30; /* 6ms = debouncecnt/8kHz */
+ KeyScan_InitStruct.releasecnt = 0x50; /* 10ms = releasecnt/8kHz */
+ KeyScan_InitStruct.keylimit = KEYSCAN_FIFO_LIMIT;
+
+ KeyScan_Init(KEYSCAN, &KeyScan_InitStruct);
+ KeyScan_INTConfig(KEYSCAN, KEYSCAN_INT_SCAN_END, ENABLE);
+ KeyScan_ClearINTPendingBit(KEYSCAN, KEYSCAN_INT_SCAN_END);
+ KeyScan_INTMask(KEYSCAN, KEYSCAN_INT_SCAN_END, DISABLE); /* Mask keyscan interrupt */
+ KeyScan_Cmd(KEYSCAN, ENABLE);
+}
+
+/******************************************************************
+ * @brief keyscan nvic config
+ * @param none
+ * @return none
+ * @retval void
+ */
+void keyscan_nvic_config(void)
+{
+ NVIC_InitTypeDef NVIC_InitStruct;
+
+ NVIC_InitStruct.NVIC_IRQChannel = KeyScan_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/******************************************************************
+ * @brief keyscan pinmux config
+ * @param none
+ * @return none
+ * @retval void
+ */
+void keyscan_pinmux_config(void)
+{
+ for (uint8_t index = 0; index < key_handle_global_data.keyscan_row_size; index++)
+ {
+ Pinmux_Config(KeyScanRowPINs[index], KEY_ROW_0 + index);
+ }
+
+ for (uint8_t index = 0; index < key_handle_global_data.keyscan_column_size; index++)
+ {
+ Pinmux_Config(KeyScanColumnPINs[index], KEY_COL_0 + index);
+ }
+}
+
+/******************************************************************
+ * @brief keyscan init pad config
+ * @param none
+ * @return none
+ * @retval void
+ */
+void keyscan_init_pad_config(void)
+{
+ keyscan_row_pad_config(PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
+ keyscan_column_pad_config(PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_LOW);
+ keyscan_global_data.is_pinmux_setted = true;
+}
+
+/******************************************************************
+ * @brief keyscan enter DLPS config
+ * @param none
+ * @return none
+ * @retval void
+ */
+void keyscan_enter_dlps_config(void)
+{
+ KEYSCAN_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[keyscan_enter_dlps_config] enter DLPS pad config", 0);
+ keyscan_column_pad_config(PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
+
+ if (keyscan_global_data.is_all_key_released == true)
+ {
+ keyscan_enable_wakeup_config();
+ keyscan_row_pad_config(PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
+ }
+ else
+ {
+ /* any key is pressed, disable key row pins, just wait keyscan sw timer to wake */
+ keyscan_disable_wakeup_config();
+ keyscan_row_pad_config(PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_DOWN, PAD_OUT_DISABLE, PAD_OUT_LOW);
+ }
+
+ keyscan_global_data.is_pinmux_setted = false;
+}
+
+/******************************************************************
+ * @brief keyscan exit DLPS config
+ * @param none
+ * @return none
+ * @retval void
+ */
+void keyscan_exit_dlps_config(void)
+{
+ if (true == keyscan_global_data.is_all_key_released)
+ {
+ KEYSCAN_DBG_BUFFER(MODULE_APP, LEVEL_INFO,
+ "[keyscan_exit_dlps_config] start keyscan if all key released", 0);
+ keyscan_init_pad_config();
+ /*key trigger manual mode init*/
+ keyscan_init_driver(KeyScan_Manual_Sel_Key, KeyScan_Debounce_Enable);
+ }
+
+ keyscan_disable_wakeup_config();
+}
+
+/******************************************************************
+ * @brief keyscan check DLPS callback
+ * @param none
+ * @return bool
+ * @retval true or false
+ */
+bool keyscan_check_dlps(void)
+{
+ return keyscan_global_data.is_allowed_to_enter_dlps;
+}
+
+/******************************************************************
+ * @brief keyscan interrupt handler
+ * @param none
+ * @return none
+ * @retval void
+ */
+void keyscan_interrupt_handler(void)
+{
+ KEYSCAN_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[keyscan_interrupt_handler] interrupt handler", 0);
+
+ T_IO_MSG bee_io_msg;
+ bee_io_msg.type = IO_MSG_TYPE_KEYSCAN;
+
+ if (KeyScan_GetFlagState(KEYSCAN, KEYSCAN_INT_FLAG_SCAN_END) == SET)
+ {
+ KEYSCAN_DBG_BUFFER(MODULE_APP, LEVEL_INFO,
+ "[keyscan_interrupt_handler] KEYSCAN_INT_FLAG_SCAN_END interrupt", 0);
+ keyscan_global_data.is_allowed_to_enter_dlps = true;
+
+ memset(&keyscan_global_data.cur_fifo_data, 0, sizeof(T_KEYSCAN_FIFO_DATA));
+
+ /* read keyscan FIFO data length */
+ keyscan_global_data.cur_fifo_data.len = KeyScan_GetFifoDataNum(KEYSCAN);
+ if (keyscan_global_data.cur_fifo_data.len > KEYSCAN_FIFO_LIMIT)
+ {
+ /* set flag to default status and reinit keyscan module to key trigger manual mode with debounce enabled */
+ keyscan_init_data();
+ keyscan_init_driver(KeyScan_Manual_Sel_Key, KeyScan_Debounce_Enable);
+ return;
+ }
+ else if (keyscan_global_data.cur_fifo_data.len != 0)
+ {
+ keyscan_global_data.is_all_key_released = false;
+
+ /* read keyscan fifo data */
+ KeyScan_Read(KEYSCAN, (uint16_t *) & (keyscan_global_data.cur_fifo_data.key[0]),
+ keyscan_global_data.cur_fifo_data.len);
+
+ KeyScan_INTConfig(KEYSCAN, KEYSCAN_INT_SCAN_END, DISABLE);
+ KeyScan_Cmd(KEYSCAN, DISABLE);
+
+ /* start sw timer to check press status */
+ if (!os_timer_restart(&keyscan_timer, KEYSCAN_SW_INTERVAL))
+ {
+ APP_PRINT_ERROR0("[keyscan_interrupt_handler] restart keyscan_timer failed!");
+ /* set flag to default status and reinit keyscan module to key trigger manual mode with debounce enabled */
+ keyscan_init_data();
+ keyscan_init_driver(KeyScan_Manual_Sel_Key, KeyScan_Debounce_Enable);
+ return;
+ }
+
+ if (false == keyscan_global_data.is_allowed_to_repeat_report)
+ {
+ if (!memcmp(&keyscan_global_data.cur_fifo_data, &keyscan_global_data.pre_fifo_data,
+ sizeof(T_KEYSCAN_FIFO_DATA)))
+ {
+ /* same keyscan FIFO data, just return */
+ return;
+ }
+ else
+ {
+ /* updata previous keyscan FIFO data */
+ memcpy(&keyscan_global_data.pre_fifo_data, &keyscan_global_data.cur_fifo_data,
+ sizeof(T_KEYSCAN_FIFO_DATA));
+ }
+ }
+
+ bee_io_msg.subtype = IO_MSG_KEYSCAN_RX_PKT;
+ bee_io_msg.u.buf = (void *)(&keyscan_global_data.pre_fifo_data);
+ if (false == app_send_msg_to_apptask(&bee_io_msg))
+ {
+ APP_PRINT_ERROR0("[keyscan_interrupt_handler] send IO_MSG_KEYSCAN_RX_PKT message failed!");
+ os_timer_stop(&keyscan_timer);
+ /* set flag to default status and reinit keyscan module to key trigger manual mode with debounce enabled */
+ keyscan_init_data();
+ keyscan_init_driver(KeyScan_Manual_Sel_Key, KeyScan_Debounce_Enable);
+ return;
+ }
+ }
+ else
+ {
+ KEYSCAN_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[keyscan_interrupt_handler] fifo is tempty", 0);
+
+ if (keyscan_global_data.is_all_key_released == false)
+ {
+ KEYSCAN_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[keyscan_interrupt_handler] key release", 0);
+ APP_PRINT_INFO0("[keyscan_interrupt_handler] key release");
+
+ keyscan_global_data.is_all_key_released = true;
+ bee_io_msg.subtype = IO_MSG_KEYSCAN_ALLKEYRELEASE;
+ if (false == app_send_msg_to_apptask(&bee_io_msg))
+ {
+ APP_PRINT_ERROR0("[keyscan_interrupt_handler] Send IO_MSG_KEYSCAN_ALLKEYRELEASE message failed!");
+ /* set flag to default status and reinit keyscan module to key trigger manual mode with debounce enabled */
+ keyscan_init_data();
+ keyscan_init_driver(KeyScan_Manual_Sel_Key, KeyScan_Debounce_Enable);
+ return;
+ }
+ }
+
+ os_timer_stop(&keyscan_timer);
+ /* reinit keyscan module to key trigger manual mode with debounce enabled */
+ memset(&keyscan_global_data.pre_fifo_data, 0, sizeof(T_KEYSCAN_FIFO_DATA));
+ keyscan_init_driver(KeyScan_Manual_Sel_Key, KeyScan_Debounce_Enable);
+ return;
+ }
+ }
+ else
+ {
+ KEYSCAN_DBG_BUFFER(MODULE_APP, LEVEL_WARN,
+ "[keyscan_interrupt_handler] not KEYSCAN_INT_FLAG_SCAN_END or KEYSCAN_INT_FLAG_SCAN_END interrupt",
+ 0);
+ /* set flag to default status and reinit keyscan module to key trigger manual mode with debounce enabled */
+ keyscan_init_data();
+ keyscan_init_driver(KeyScan_Manual_Sel_Key, KeyScan_Debounce_Enable);
+ return;
+ }
+}
+
+/******************************************************************
+ * @brief keyscan init timer
+ * @param none
+ * @return none
+ * @retval void
+ */
+void keyscan_init_timer(void)
+{
+ KEYSCAN_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[keyscan_init_timer] init timer", 0);
+ /*keyscan_timer is used for keyscan dlps*/
+ if (false == os_timer_create(&keyscan_timer, "keyscan_timer", 1, \
+ KEYSCAN_SW_INTERVAL, false, keyscan_timer_callback))
+ {
+ APP_PRINT_ERROR0("[keyscan_init_timer] timer creat failed!");
+ }
+}
+
+/******************************************************************
+ * @brief keyscan timer callback
+ * @param none
+ * @return none
+ * @retval void
+ */
+void keyscan_timer_callback(TimerHandle_t pxTimer)
+{
+ KEYSCAN_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[keyscan_timer_callback] start release timer", 0);
+ keyscan_global_data.is_allowed_to_enter_dlps = false;
+ /* start register trigger manual mode */
+ keyscan_init_driver(KeyScan_Manual_Sel_Bit, KeyScan_Debounce_Disable);
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/key_module/keyscan_driver.h b/src/app/google_rcu/key_module/keyscan_driver.h
new file mode 100644
index 0000000..32c91ed
--- /dev/null
+++ b/src/app/google_rcu/key_module/keyscan_driver.h
@@ -0,0 +1,94 @@
+
+/*
+ * Routines to access hardware
+ *
+ * Copyright (c) 2018 Realtek Semiconductor Corp.
+ *
+ * This module is a confidential and proprietary property of RealTek and
+ * possession or use of this module requires written permission of RealTek.
+ */
+#ifndef _KEYSCAN_DRIVER_H_
+#define _KEYSCAN_DRIVER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdint.h>
+#include <stdbool.h>
+#include <swtimer.h>
+#include <rtl876x.h>
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+//#define KEYSCAN_PRINT_LOG /* Enable print log or not */
+
+#ifdef KEYSCAN_PRINT_LOG
+#define KEYSCAN_DBG_BUFFER(MODULE, LEVEL, fmt, para_num,...) DBG_BUFFER_##LEVEL(TYPE_BEE2, SUBTYPE_FORMAT, MODULE, fmt, para_num, ##__VA_ARGS__)
+#else
+#define KEYSCAN_DBG_BUFFER(MODULE, LEVEL, fmt, para_num,...) ((void)0)
+#endif
+
+#define KEYSCAN_SW_INTERVAL 50 /* 50ms */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint16_t column: 5; /**< Keyscan raw buffer data */
+ uint16_t row: 4; /**< Keyscan raw buffer data */
+ uint16_t reserved: 7;
+} T_KEYSCAN_DATA;
+
+/**
+ * @brief KeyScan FIFO data struct definition.
+ */
+typedef struct
+{
+ uint32_t len; /**< Keyscan state register */
+ T_KEYSCAN_DATA key[8];
+} T_KEYSCAN_FIFO_DATA;
+
+/**
+ * @brief KeyScan global data struct definition.
+ */
+typedef struct
+{
+ bool is_allowed_to_repeat_report; /* to indicate whether to allow to report repeat keyscan data event or not */
+ bool is_allowed_to_enter_dlps; /* to indicate whether to allow to enter dlps or not */
+ bool is_all_key_released; /* to indicate whether all keys are released or not */
+ bool is_pinmux_setted; /* to indicate whether pinmux is setted */
+ T_KEYSCAN_FIFO_DATA pre_fifo_data; /* to indicate the previous keyscan FIFO data */
+ T_KEYSCAN_FIFO_DATA cur_fifo_data; /* to indicate the current keyscan FIFO data */
+} T_KEYSCAN_GLOBAL_DATA;
+
+/*============================================================================*
+* Export Global Variables
+*============================================================================*/
+extern T_KEYSCAN_GLOBAL_DATA keyscan_global_data;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void keyscan_init_data(void);
+void keyscan_init_driver(uint32_t manual_sel, uint32_t is_debounce);
+void keyscan_pinmux_config(void);
+void keyscan_init_pad_config(void);
+void keyscan_nvic_config(void);
+void keyscan_enter_dlps_config(void);
+void keyscan_exit_dlps_config(void);
+bool keyscan_check_dlps(void);
+void keyscan_init_timer(void);
+void keyscan_long_press_handler(uint8_t long_pressed_key_row_pin);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/app/google_rcu/led_module/led_driver.c b/src/app/google_rcu/led_module/led_driver.c
new file mode 100644
index 0000000..00f1822
--- /dev/null
+++ b/src/app/google_rcu/led_module/led_driver.c
@@ -0,0 +1,331 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file led_driver.c
+* @brief this file provides led module function driver for users.
+* @details multi prio, multi event, multi led support.
+* @author Yuyin_zhang
+* @date 2020-03-03
+* @version v1.1
+* @note the more led number and led event, the more time cpu spend on tick handle
+* For example: led_num = 8, led_event_num = 10, max time is 112us.
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "board.h"
+#include "trace.h"
+#include "os_timer.h"
+#include "swtimer.h"
+#include "led_driver.h"
+#include "led_pwm_driver.h"
+#include <app_section.h>
+
+#if SUPPORT_LED_INDICATION_FEATURE
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+static const T_LED_EVENT_STG led_event_arr[LED_TYPE_MAX] =
+{
+ {LED_COLOR_RED, LED_DEFAULT_BRIGHTNESS_DUTY, LED_TYPE_BLINK_ERROR, LED_LOOP_BITS_ERROR, LED_BIT_MAP_ERROR},
+ {LED_COLOR_GREEN, LED_DEFAULT_BRIGHTNESS_DUTY, LED_TYPE_BLINK_KEY_PRESS_BLE, LED_LOOP_BITS_KEY_PRESS_BLE, LED_BIT_MAP_KEY_PRESS_BLE},
+ {LED_COLOR_RED, LED_DEFAULT_BRIGHTNESS_DUTY, LED_TYPE_BLINK_KEY_PRESS_IR, LED_LOOP_BITS_KEY_PRESS_IR, LED_BIT_MAP_KEY_PRESS_IR},
+ {LED_COLOR_ORANGE, LED_DEFAULT_BRIGHTNESS_DUTY, LED_TYPE_BLINK_KEY_PRESS_PROG, LED_LOOP_BITS_KEY_PRESS_PROG, LED_BIT_MAP_KEY_PRESS_PROG},
+ {LED_COLOR_GREEN, LED_DEFAULT_BRIGHTNESS_DUTY, LED_TYPE_BLINK_COMB_KEY_PRESS, LED_LOOP_BITS_COMB_KEY_PRESS, LED_BIT_MAP_COMB_KEY_PRESS},
+ {LED_COLOR_GREEN, LED_DEFAULT_BRIGHTNESS_DUTY, LED_TYPE_BLINK_CONFIRMATION, LED_LOOP_BITS_CONFIRMATION, LED_BIT_MAP_CONFIRMATION},
+ {LED_COLOR_GREEN, LED_DEFAULT_BRIGHTNESS_DUTY, LED_TYPE_BLINK_PAIR_ADV, LED_LOOP_BITS_PAIR_ADV, LED_BIT_MAP_PAIR_ADV},
+ {LED_COLOR_GREEN, LED_DEFAULT_BRIGHTNESS_DUTY, LED_TYPE_BLINK_VOICE_HTT, LED_LOOP_BITS_VOICE_HTT, LED_BIT_MAP_VOICE_HTT},
+ {LED_COLOR_GREEN, LED_DEFAULT_BRIGHTNESS_DUTY, LED_TYPE_BLINK_VOICE_PTT, LED_LOOP_BITS_VOICE_PTT, LED_BIT_MAP_VOICE_PTT},
+ {LED_COLOR_GREEN, LED_DEFAULT_BRIGHTNESS_DUTY, LED_TYPE_BLINK_VOICE_ON_REQUEST, LED_LOOP_BITS_VOICE_ON_REQUEST, LED_BIT_MAP_VOICE_ON_REQUEST},
+ {LED_COLOR_RED, LED_DEFAULT_BRIGHTNESS_DUTY, LED_TYPE_BLINK_TEST_RED, LED_LOOP_BITS_TEST_RED, LED_BIT_MAP_TEST_RED},
+ {LED_COLOR_GREEN, LED_DEFAULT_BRIGHTNESS_DUTY, LED_TYPE_BLINK_TEST_GREEN, LED_LOOP_BITS_TEST_GREEN, LED_BIT_MAP_TEST_GREEN},
+ {LED_COLOR_GREEN, LED_DEFAULT_BRIGHTNESS_DUTY, LED_TYPE_ON, LED_LOOP_BITS_ON, LED_BIT_MAP_ON},
+};
+
+static uint32_t led_global_tick_cnt = 0;
+static T_LED_DATA_STG led_ctrl_data = {0};
+static TimerHandle_t led_ctrl_timer;
+
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+static uint32_t led_get_next_event(const uint32_t bitmap);
+static void led_ctrl_timer_cb(TimerHandle_t pxTimer) DATA_RAM_FUNCTION;
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+uint32_t get_led_brightness_duty(uint8_t led_index, LED_TYPE type)
+{
+ uint32_t led_brightness_duty = LED_DEFAULT_BRIGHTNESS_DUTY;
+ if (led_event_arr[type].led_color == LED_COLOR_ORANGE)
+ {
+ if (led_index == LED_R_INDEX)
+ {
+ led_brightness_duty = LED_DEFAULT_BRIGHTNESS_DUTY;
+ }
+ else if (led_index == LED_G_INDEX)
+ {
+ led_brightness_duty = LED_DEFAULT_BRIGHTNESS_DUTY;
+ }
+ else if (led_index == LED_B_INDEX)
+ {
+ led_brightness_duty = 0;
+ }
+ }
+ else
+ {
+ led_brightness_duty = led_event_arr[type].led_brightness;
+ }
+
+ return led_brightness_duty;
+}
+
+/******************************************************************
+ * @brief get next led blink event.
+ * @param bitmap - led event bit map, indicate which led event bit map to get.
+ * @return return led event index.
+ * @retval uint32_t
+ */
+uint32_t led_get_next_event(uint32_t bitmap)
+{
+ for (uint32_t index = 0; index < LED_TYPE_MAX; index++)
+ {
+ uint32_t bit_mask = 0;
+ bit_mask |= (1 << index);
+ if (bit_mask & bitmap)
+ {
+#if LED_DEBUG
+ APP_PRINT_INFO1("[led_get_next_event] index = %d", index);
+#endif
+ return index;
+ }
+ }
+ return LED_TYPE_MAX;
+}
+
+/******************************************************************
+ * @brief callback led timer timeout.
+ * @param pxTimer.
+ * @return none
+ * @retval void
+ */
+void led_ctrl_timer_cb(TimerHandle_t pxTimer)
+{
+ /* update led blink tick */
+ led_global_tick_cnt++;
+
+ /* get led type */
+ uint32_t type = led_get_next_event(led_ctrl_data.led_map);
+
+ if (type < LED_TYPE_MAX)
+ {
+ /* process current led event */
+ uint32_t map = led_event_arr[type].led_bit_map;
+ uint32_t tick_mask = (1 << (led_global_tick_cnt % led_event_arr[type].led_loop_cnt));
+ LED_COLOR_LIST led_color = led_event_arr[type].led_color;
+
+ for (uint8_t led_index = 0; led_index < LED_NUM_MAX; led_index++)
+ {
+ if (((tick_mask & map)) && (led_color & (1 << led_index)))
+ {
+ uint32_t pwm_high_cnt = 0;
+ uint32_t pwm_low_cnt = 0;
+ uint32_t led_brightness_duty = get_led_brightness_duty(led_index, type);
+#if (LED_ACTIVE_LEVEL == 1)
+ pwm_high_cnt = led_brightness_duty * LED_DUTY_FACTOR;
+ pwm_low_cnt = PWM_MAX_COUNT - pwm_high_cnt;
+#else
+ pwm_high_cnt = PWM_MAX_COUNT - led_brightness_duty * LED_DUTY_FACTOR;
+ pwm_low_cnt = PWM_MAX_COUNT - pwm_high_cnt;
+#endif
+
+ led_module_pwm_start(led_index, pwm_high_cnt, pwm_low_cnt);
+ }
+ else
+ {
+ led_module_pwm_stop(led_index);
+ }
+ }
+
+ /* update led_ctrl_data */
+ for (uint8_t index = 0; index < LED_TYPE_MAX; index++)
+ {
+ /* update led state, when new tick come */
+ if (0 == ((1 << index) & led_ctrl_data.led_map))
+ {
+ continue;
+ }
+
+ if ((led_ctrl_data.led_cnt_arr[index].led_loop_cnt > 0)
+ && (led_ctrl_data.led_cnt_arr[index].cur_tick_cnt == (led_global_tick_cnt %
+ led_event_arr[index].led_loop_cnt)))
+ {
+ led_ctrl_data.led_cnt_arr[index].led_loop_cnt --;
+ if (0 == led_ctrl_data.led_cnt_arr[index].led_loop_cnt)
+ {
+ /* clear event bit */
+ led_ctrl_data.led_map &= ~(1 << index);
+ /* turn off led */
+#ifdef LED_R_PIN
+ led_module_pwm_stop(LED_R_INDEX);
+#endif
+#ifdef LED_G_PIN
+ led_module_pwm_stop(LED_G_INDEX);
+#endif
+#ifdef LED_B_PIN
+ led_module_pwm_stop(LED_B_INDEX);
+#endif
+ }
+ }
+ }
+ }
+
+ if (led_ctrl_data.led_map)
+ {
+ /* led timer restart */
+ os_timer_restart(&led_ctrl_timer, LED_PERIOD);
+ }
+
+#if LED_DEBUG
+ APP_PRINT_INFO3("[led_ctrl_timer_cb] led_global_tick_cnt = %d, type = %d, led_map = 0x%02X",
+ led_global_tick_cnt, type, led_ctrl_data.led_map);
+#endif
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief led module init.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void led_module_init(void)
+{
+ bool retval = false;
+
+ led_pwm_init();
+ led_global_tick_cnt = 0;
+
+ /* create led tick timer */
+ retval = os_timer_create(&led_ctrl_timer, "led_ctrl_timer", 1, LED_PERIOD, false,
+ led_ctrl_timer_cb);
+ if (!retval)
+ {
+ APP_PRINT_INFO1("[Led] led_ctrl_timer ret is %d", retval);
+ }
+}
+
+/******************************************************************
+ * @brief led driver check DLPS callback
+ * @param none
+ * @return bool
+ * @retval true or false
+ */
+bool led_driver_dlps_check(void)
+{
+ return led_pwm_driver_dlps_check();
+}
+
+/******************************************************************
+ * @brief start led event.
+ * @param led_color - led color.
+ * @param type - led type to set.
+ * @param cnt - led blink count.
+ * @return result of starting led.
+ * @retval T_LED_RET_CAUSE
+ */
+T_LED_RET_CAUSE led_blink_start(LED_TYPE type, uint8_t cnt)
+{
+ uint32_t pre_led_map = led_ctrl_data.led_map;
+
+ if (LED_TYPE_MAX <= type)
+ {
+ return LED_ERR_TYPE;
+ }
+
+ if (led_event_arr[type].led_bit_map == LED_BIT_MAP_INVALID)
+ {
+ return LED_ERR_TYPE;
+ }
+
+ /* set led event map flag */
+ led_ctrl_data.led_map |= (1 << type);
+
+ if (cnt > 0)
+ {
+ led_ctrl_data.led_cnt_arr[type].led_loop_cnt = cnt;
+ led_ctrl_data.led_cnt_arr[type].cur_tick_cnt = led_global_tick_cnt %
+ led_event_arr[type].led_loop_cnt;
+ }
+ else
+ {
+ led_ctrl_data.led_cnt_arr[type].led_loop_cnt = 0;
+ led_ctrl_data.led_cnt_arr[type].cur_tick_cnt = 0;
+ }
+
+ /* start led tick */
+ if ((pre_led_map == 0) && (led_ctrl_data.led_map != 0))
+ {
+ led_ctrl_timer_cb(&led_ctrl_timer);
+ }
+
+#if LED_DEBUG
+ APP_PRINT_INFO2("[led_blink_start] type = %d, cnt = %d", type, cnt);
+#endif
+
+ return LED_SUCCESS;
+
+}
+
+/******************************************************************
+ * @brief this function terminate led blink according to the led type.
+ * @param led_color - led color.
+ * @param type - led type to set.
+ * @return result of exiting led.
+ * @retval T_LED_RET_CAUSE
+ */
+T_LED_RET_CAUSE led_blink_exit(LED_TYPE type)
+{
+ if (LED_TYPE_MAX <= type)
+ {
+ return LED_ERR_TYPE;
+ }
+
+ /* stop led */
+ if (led_ctrl_data.led_map & (1 << type))
+ {
+#if LED_DEBUG
+ APP_PRINT_INFO1("[led_blink_exit] type = %d", type);
+#endif
+ /* clear current led type bit */
+ led_ctrl_data.led_map &= ~(1 << type);
+
+ /* check whether need close led timer */
+ if (led_ctrl_data.led_map == 0)
+ {
+ os_timer_stop(&led_ctrl_timer);
+#ifdef LED_R_PIN
+ led_module_pwm_stop(LED_R_INDEX);
+#endif
+#ifdef LED_G_PIN
+ led_module_pwm_stop(LED_G_INDEX);
+#endif
+#ifdef LED_B_PIN
+ led_module_pwm_stop(LED_B_INDEX);
+#endif
+ }
+
+ return LED_SUCCESS;
+ }
+ return LED_SUCCESS;
+}
+
+#endif
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/led_module/led_driver.h b/src/app/google_rcu/led_module/led_driver.h
new file mode 100644
index 0000000..865f931
--- /dev/null
+++ b/src/app/google_rcu/led_module/led_driver.h
@@ -0,0 +1,206 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file led_driver.h
+* @brief
+* @details
+* @author
+* @date 2020-03-04
+* @version v1.0
+* @note
+*********************************************************************************************************
+*/
+#ifndef _LED_H_
+#define _LED_H_
+
+#include "stdint.h"
+#include "board.h"
+
+#if SUPPORT_LED_INDICATION_FEATURE
+/**
+* @brief user guide for led driver
+* The driver support multi prio, multi event, and multi led.
+* If you want to control a led with a event as you designed, there is two way to
+* achieve this, modify the exist event and redefine a new event.
+*
+* The led driver is drived by software timer, the timer period is 50ms by default.
+*
+* #define LED_PERIOD 50 //you a change the value according your requirement
+*
+* For the whole led driver system, there is 5 place you might modify.
+*
+* 1. Define led num and led pin, which is in file board.h;
+* For example, define 2 leds as followed:
+* #define LED_NUM_MAX 0x02
+* #define LED_INDEX(n) (n<<8)
+
+* //uint16_t, first byte led index, last byte led pin
+* #define LED_1 (LED_INDEX(0) | P2_2)
+* #define LED_2 (LED_INDEX(1) | P0_2)
+*
+* 2. Define led type index, which is in file led_driver.h, these types must be
+* defined in sequence.
+* For example,
+* #define LED_TYPE_BLINK_OTA_UPDATE (8)
+*
+* 3. Define led loop bits num, in file led_driver.h
+* //max value 32, min value 1, it indicate that there is how many bits to loop
+* //from LSB
+* #define LED_LOOP_BITS_OTA_UPDATE (15)
+*
+* 4. Define led event bit map, in file led_driver.h
+* // it must be cooperated with led loop bits num
+* #define LED_BIT_MAP_OTA_UPDATE (0x4210)//on 50ms, off 200ms, period 50ms
+*
+* 5. Update led event table, led_event_arr[LED_TYPE_MAX], in file led_driver.c
+* Before you use the event you define ,you need to add led type, led loop bit num,
+* and led event bit map into event table.
+* const T_LED_EVENT_STG led_event_arr[LED_TYPE_MAX] =
+* {
+* ··· ···
+* {LED_TYPE_BLINK_OTA_UPDATE, LED_LOOP_BITS_OTA_UPDATE, LED_BIT_MAP_OTA_UPDATE},
+* };
+*
+* There are three interfaces for Led driver, as follow.
+*
+* void led_module_init(void); // called when system boot;
+* T_LED_RET_CAUSE led_blink_start(uint16_t index, LED_TYPE type, uint8_t cnt);
+* T_LED_RET_CAUSE led_blink_exit(uint16_t index, LED_TYPE type);
+*/
+
+#define LED_DEBUG 0
+/*software timer period*/
+#define LED_PERIOD 50 /*50ms*/
+/*led default duty for brightness*/
+#define LED_DEFAULT_BRIGHTNESS_DUTY LED_DEFAULT_DUTY
+/*led index*/
+#define LED_R_INDEX 0
+#define LED_G_INDEX 1
+#define LED_B_INDEX 2
+
+/*led event types, the less value, the higher prio of the event*/
+typedef uint8_t LED_TYPE;
+
+typedef enum
+{
+ LED_TYPE_BLINK_ERROR,
+ LED_TYPE_BLINK_KEY_PRESS_BLE,
+ LED_TYPE_BLINK_KEY_PRESS_IR,
+ LED_TYPE_BLINK_KEY_PRESS_PROG,
+ LED_TYPE_BLINK_COMB_KEY_PRESS,
+ LED_TYPE_BLINK_CONFIRMATION,
+ LED_TYPE_BLINK_PAIR_ADV,
+ LED_TYPE_BLINK_VOICE_HTT,
+ LED_TYPE_BLINK_VOICE_PTT,
+ LED_TYPE_BLINK_VOICE_ON_REQUEST,
+ LED_TYPE_BLINK_TEST_RED,
+ LED_TYPE_BLINK_TEST_GREEN,
+ LED_TYPE_ON,
+ LED_TYPE_MAX
+} LED_TYPE_ENUM;
+
+/*led loop bit num for each event, max value 32*/
+#define LED_LOOP_BITS_ERROR 2
+#define LED_LOOP_BITS_CONFIRMATION 4
+#define LED_LOOP_BITS_PAIR_ADV 10
+#define LED_LOOP_BITS_VOICE_HTT 32
+#define LED_LOOP_BITS_VOICE_PTT 20
+#define LED_LOOP_BITS_VOICE_ON_REQUEST 32
+#define LED_LOOP_BITS_KEY_PRESS_BLE 4
+#define LED_LOOP_BITS_KEY_PRESS_IR 4
+#define LED_LOOP_BITS_KEY_PRESS_PROG 4
+#define LED_LOOP_BITS_COMB_KEY_PRESS 32
+#define LED_LOOP_BITS_TEST_RED 24
+#define LED_LOOP_BITS_TEST_GREEN 24
+#define LED_LOOP_BITS_ON 32
+
+/*led bit map 32bits, High bits(low priority) --- Low bits(high priority) */
+#define LED_BIT_MAP_ERROR 0x00000002
+#define LED_BIT_MAP_CONFIRMATION 0x0000000C
+#define LED_BIT_MAP_PAIR_ADV 0x0000001f
+#define LED_BIT_MAP_VOICE_HTT 0xffffffff
+#define LED_BIT_MAP_VOICE_PTT 0x000003ff
+#define LED_BIT_MAP_VOICE_ON_REQUEST 0xffffffff
+#define LED_BIT_MAP_KEY_PRESS_BLE 0x0000000C
+#define LED_BIT_MAP_KEY_PRESS_IR 0x0000000C
+#define LED_BIT_MAP_KEY_PRESS_PROG 0x0000000C
+#define LED_BIT_MAP_COMB_KEY_PRESS 0xffffffff
+#define LED_BIT_MAP_TEST_RED 0x000000ff
+#define LED_BIT_MAP_TEST_GREEN 0x0000ff00
+#define LED_BIT_MAP_ON 0xffffffff
+
+#define LED_BIT_MAP_INVALID 0x00000000
+
+
+/* LED Color mask bit*/
+#define LED_MASK_RED 0x01 /**< 0001b(0x01) */
+#define LED_MASK_GREEN 0x02 /**< 0010b(0x02) */
+#define LED_MASK_BLUE 0x04 /**< 0100b(0x04) */
+
+/**
+ * @anchor LED_COLOR_LIST
+ * @name LED color list
+ * LSB 0 : bit for RED LED
+ * LSB 1 : bit for GREEN LED
+ * LSB 2 : bit for BLUE LED
+ * LSB 3 - 7 : May need to control brightness of each LED
+ * @{ */
+typedef enum
+{
+ LED_COLOR_INVALID = 0x00, /**< invalid */
+ LED_COLOR_RED = 0x01, /**< red, 0001b(0x01) */
+ LED_COLOR_GREEN = 0x02, /**< green, 0010b(0x02) */
+ LED_COLOR_YELLOW = 0x03, /**< yellow, 0011b(0x03), sRGB(255,255,0) */
+ LED_COLOR_ORANGE = 0x13, /**< orange, 10011b(0x13), sRGB(255,128,0) */
+ LED_COLOR_MAX_OPTIONS = 0x14, /**< led color value should be less than 0x14 */
+} LED_COLOR_LIST;
+
+typedef struct
+{
+ LED_COLOR_LIST led_color;
+ uint32_t led_brightness;
+ uint8_t led_type_index;
+ uint8_t led_loop_cnt;
+ uint32_t led_bit_map;
+} T_LED_EVENT_STG;
+
+/*struct support for led blink count*/
+typedef struct
+{
+ uint8_t led_loop_cnt;
+ uint8_t cur_tick_cnt;
+} T_LED_CNT_STG;
+
+/*support for each led data*/
+typedef struct
+{
+ T_LED_CNT_STG led_cnt_arr[LED_TYPE_MAX];
+ uint32_t led_map;
+} T_LED_DATA_STG;
+
+/*led return code*/
+typedef enum
+{
+ LED_SUCCESS = 0,
+ LED_ERR_TYPE = 1,
+ LED_ERR_INDEX = 2,
+ LED_ERR_CODE_MAX
+} T_LED_RET_CAUSE;
+
+/*============================================================================*
+ * <Led Module Interface>
+ *============================================================================*/
+void led_module_init(void);
+bool led_driver_dlps_check(void);
+T_LED_RET_CAUSE led_blink_start(LED_TYPE type, uint8_t cnt);
+T_LED_RET_CAUSE led_blink_exit(LED_TYPE type);
+
+#define LED_BLINK(type, n) led_blink_start(type, n)
+#define LED_BLINK_EXIT(type) led_blink_exit(type)
+
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/led_module/led_pwm_driver.c b/src/app/google_rcu/led_module/led_pwm_driver.c
new file mode 100644
index 0000000..644364a
--- /dev/null
+++ b/src/app/google_rcu/led_module/led_pwm_driver.c
@@ -0,0 +1,246 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file led_pwm_driver.c
+* @brief this file provides led module function driver for users.
+* @details multi prio, multi event, multi led support.
+* @author Yuyin_zhang
+* @date 2020-03-03
+* @version v1.1
+* @note the more led number and led event, the more time cpu spend on tick handle
+* For example: led_num = 8, led_event_num = 10, max time is 112us.
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "board.h"
+#include "trace.h"
+#include "rtl876x_gpio.h"
+#include "rtl876x_pinmux.h"
+#include "swtimer.h"
+#include "led_pwm_driver.h"
+#include "rtl876x_tim.h"
+#include "rtl876x_rcc.h"
+#include "rcu_application.h"
+
+#if SUPPORT_LED_INDICATION_FEATURE
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+static uint8_t led_pwm_init_states = 0;
+static uint8_t led_on_off_states = 0;
+
+static const T_LED_PWM_PARAM_DEF led_pwm_list[LED_NUM_MAX] =
+{
+ {LED_R_PIN, TIM_PWM2, TIM2},
+ {LED_G_PIN, TIM_PWM3, TIM3},
+};
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/**
+ * @brief led module update pwm init states.
+ * @param index - led index
+ * @param state - ENABLE or DISABLE
+ * @return uint8_t - led_pwm_init_states
+**/
+static uint8_t led_module_update_pwm_states(uint8_t index, FunctionalState state)
+{
+ if (state == DISABLE)
+ {
+ led_pwm_init_states &= ~(1 << index);
+ }
+ else
+ {
+ led_pwm_init_states |= (1 << index);
+ }
+
+ return led_pwm_init_states;
+}
+
+/**
+ * @brief led module update led on/off states.
+ * @param index - led index
+ * @param state - ENABLE or DISABLE
+ * @return uint8_t - led_on_off_states
+**/
+static uint8_t led_module_update_on_off_states(uint8_t index, FunctionalState state)
+{
+ if (state == DISABLE)
+ {
+ led_on_off_states &= ~(1 << index);
+ }
+ else
+ {
+ led_on_off_states |= (1 << index);
+ }
+
+ return led_on_off_states;
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief led module init.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void led_pwm_init(void)
+{
+ led_pwm_init_states = 0;
+ led_on_off_states = 0;
+
+ led_driver_disable_boost_power();
+
+ for (uint8_t index = 0; index < LED_NUM_MAX; index++)
+ {
+ led_module_pwm_stop(index);
+ }
+}
+
+/******************************************************************
+ * @brief led driver check DLPS callback
+ * @param none
+ * @return bool
+ * @retval true or false
+ */
+bool led_pwm_driver_dlps_check(void)
+{
+ return (led_pwm_init_states == 0);
+}
+
+/******************************************************************
+ * @brief this function enable RGB LED boost power.
+ */
+void led_driver_enable_boost_power(void)
+{
+#if LED_PWM_DEBUG
+ APP_PRINT_INFO0("[led_driver_enable_boost_power] enable LED power pin");
+#endif
+#ifdef LED_EN_PIN
+ Pad_Config(LED_EN_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+#endif
+}
+
+/******************************************************************
+ * @brief this function disable RGB LED boost power.
+ */
+void led_driver_disable_boost_power(void)
+{
+#if LED_PWM_DEBUG
+ APP_PRINT_INFO0("[led_driver_disable_boost_power] disable LED power pin");
+#endif
+#ifdef LED_EN_PIN
+ Pad_Config(LED_EN_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
+#endif
+}
+
+/**
+ * @brief led module PWM start.
+ * @param index - led index
+ * @return void.
+**/
+void led_module_pwm_start(uint8_t index, uint32_t pwm_high_cnt, uint32_t pwm_low_cnt)
+{
+#if LED_PWM_DEBUG
+ APP_PRINT_INFO3("[led_module_pwm_start] index = %d, pwm_high_cnt = 0x%X, pwm_low_cnt = 0x%X",
+ index, pwm_high_cnt, pwm_low_cnt);
+#endif
+
+ if (led_on_off_states == 0)
+ {
+ led_driver_enable_boost_power();
+ }
+ led_module_update_on_off_states(index, ENABLE);
+
+ if (pwm_low_cnt == 0)
+ {
+#if (LED_ACTIVE_LEVEL == 1)
+ Pad_Config(led_pwm_list[index].pin_num, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+#else
+ Pad_Config(led_pwm_list[index].pin_num, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_LOW);
+#endif
+ led_module_update_pwm_states(index, DISABLE);
+ }
+ else if (pwm_high_cnt == 0)
+ {
+#if (LED_ACTIVE_LEVEL == 1)
+ Pad_Config(led_pwm_list[index].pin_num, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_LOW);
+#else
+ Pad_Config(led_pwm_list[index].pin_num, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+#endif
+ led_module_update_pwm_states(index, DISABLE);
+ }
+ else if ((led_pwm_init_states & (0x1 << index)) != 0)
+ {
+ TIM_PWMChangeFreqAndDuty(led_pwm_list[index].timer_num, pwm_high_cnt, pwm_low_cnt);
+ }
+ else
+ {
+ Pad_Config(led_pwm_list[index].pin_num, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE,
+ PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+ Pinmux_Config(led_pwm_list[index].pin_num, led_pwm_list[index].pin_func);
+ RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+
+ TIM_TimeBaseInitTypeDef TIM_InitStruct;
+
+ TIM_StructInit(&TIM_InitStruct);
+ TIM_InitStruct.TIM_PWM_En = PWM_ENABLE;
+ TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ TIM_InitStruct.TIM_PWM_High_Count = pwm_high_cnt;
+ TIM_InitStruct.TIM_PWM_Low_Count = pwm_low_cnt;
+ TIM_InitStruct.PWM_Deazone_Size = 0;
+ TIM_InitStruct.PWMDeadZone_En = DEADZONE_DISABLE; //enable to use pwn p/n output
+ TIM_TimeBaseInit(led_pwm_list[index].timer_num, &TIM_InitStruct);
+
+ TIM_Cmd(led_pwm_list[index].timer_num, ENABLE);
+
+ led_module_update_pwm_states(index, ENABLE);
+ }
+}
+
+/**
+ * @brief led module pwm init.
+ *@param void.
+ * @return void.
+ * @note none.
+**/
+void led_module_pwm_stop(uint8_t index)
+{
+#if LED_PWM_DEBUG
+ APP_PRINT_INFO1("[led_module_pwm_stop] index %d", index);
+#endif
+ TIM_Cmd(led_pwm_list[index].timer_num, DISABLE);
+
+#if (LED_ACTIVE_LEVEL == 1)
+ Pad_Config(led_pwm_list[index].pin_num, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_LOW);
+#else
+ Pad_Config(led_pwm_list[index].pin_num, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+#endif
+ led_module_update_pwm_states(index, DISABLE);
+
+ uint8_t prev_on_off_states = led_on_off_states;
+ led_module_update_on_off_states(index, DISABLE);
+
+ if ((prev_on_off_states != 0) && (led_on_off_states == 0))
+ {
+ led_driver_disable_boost_power();
+ }
+}
+
+#endif
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/led_module/led_pwm_driver.h b/src/app/google_rcu/led_module/led_pwm_driver.h
new file mode 100644
index 0000000..87e26ab
--- /dev/null
+++ b/src/app/google_rcu/led_module/led_pwm_driver.h
@@ -0,0 +1,57 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file led_pwm_driver.h
+* @brief
+* @details
+* @author
+* @date 2020-03-04
+* @version v1.0
+* @note
+*********************************************************************************************************
+*/
+#ifndef _LED_PWM_H_
+#define _LED_PWM_H_
+
+#include "board.h"
+#include "swtimer.h"
+#include "rtl876x_tim.h"
+
+#if SUPPORT_LED_INDICATION_FEATURE
+
+#define LED_PWM_DEBUG 0
+
+#define LED_NUM_MAX 2
+
+#define PWM_INIT_COUNT 0xFF00 //0xF82F
+#define PWM_MAX_COUNT 0xFFFF
+
+#define LED_DEFAULT_DUTY 255 // 255/255 = 100%
+#define LED_DUTY_FACTOR (0x101) //(0xFFFF/0xFF)
+
+#define STOP_MIC_LED_BLINK_TIMEOUT 5000 /* 5 sec */
+
+/* led pwm paramesters struct */
+typedef struct
+{
+ uint8_t pin_num;
+ uint8_t pin_func;
+ TIM_TypeDef *timer_num;
+} T_LED_PWM_PARAM_DEF;
+
+/*============================================================================*
+ * <Led Module Interface>
+ *============================================================================*/
+void led_pwm_init(void);
+bool led_pwm_driver_dlps_check(void);
+void led_module_pwm_start(uint8_t index, uint32_t pwm_high_cnt, uint32_t pwm_low_cnt);
+void led_module_pwm_stop(uint8_t index);
+void led_driver_enable_boost_power(void);
+void led_driver_disable_boost_power(void);
+
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/loop_queue.c b/src/app/google_rcu/loop_queue.c
new file mode 100644
index 0000000..e777bf8
--- /dev/null
+++ b/src/app/google_rcu/loop_queue.c
@@ -0,0 +1,418 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file loop_queue.c
+* @brief This file provides loop queue for user.
+* @details
+* @author barry_bian
+* @date 2020-05-12
+* @version v1.1
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "loop_queue.h"
+#include "app_section.h"
+
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+bool loop_queue_is_full(T_LOOP_QUEUE_DEF *p_queue_struct, uint16_t write_size) DATA_RAM_FUNCTION;
+bool loop_queue_is_empty(T_LOOP_QUEUE_DEF *p_queue_struct) DATA_RAM_FUNCTION;
+uint16_t loop_queue_get_vailid_data_size(T_LOOP_QUEUE_DEF *p_queue_struct) DATA_RAM_FUNCTION;
+uint16_t loop_queue_get_free_data_size(T_LOOP_QUEUE_DEF *p_loop_queue) DATA_RAM_FUNCTION;
+bool loop_queue_write_buf(T_LOOP_QUEUE_DEF *p_queue_struct, T_LOOP_QUEUE_BUF p_buf, uint16_t size,
+ bool is_overflow_data_abandoned) DATA_RAM_FUNCTION;
+bool loop_queue_read_buf(T_LOOP_QUEUE_DEF *p_queue_struct, T_LOOP_QUEUE_BUF p_buf,
+ uint16_t size) DATA_RAM_FUNCTION;
+bool loop_queue_copy_buf(T_LOOP_QUEUE_DEF *p_queue_struct, T_LOOP_QUEUE_BUF p_buf,
+ uint16_t size) DATA_RAM_FUNCTION;
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief Initializes loop queue to their default reset values.
+ * @param buf_max_size - loop queue buffer max size.
+ * @param item_size - queue item size.
+ * @param ram_type - RAM_TYPE_DATA_ON or RAM_TYPE_BUFFER_ON.
+ * @retval void*
+ */
+T_LOOP_QUEUE_DEF *loop_queue_init(uint16_t item_cnt, uint16_t item_size,
+ RAM_TYPE ram_type)
+{
+ if ((item_cnt == 0) && (item_size == 0))
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] buf_max_size is invalid!", 0);
+ return NULL;
+ }
+ if (ram_type != RAM_TYPE_DATA_ON && ram_type != RAM_TYPE_BUFFER_ON)
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] ram type is invalid", 0);
+ return NULL;
+ }
+ T_LOOP_QUEUE_DEF *p_loop_queue = NULL;
+ p_loop_queue = os_mem_alloc(ram_type, sizeof(T_LOOP_QUEUE_DEF));
+ if (p_loop_queue != NULL)
+ {
+ uint32_t buf_max_size = item_cnt * item_size;
+ memset(p_loop_queue, 0, sizeof(T_LOOP_QUEUE_DEF));
+ p_loop_queue->item_size = item_size;
+ p_loop_queue->buf_max_item_num = item_cnt;
+ p_loop_queue->is_over_flow = false;
+ p_loop_queue->p_buf = NULL;
+ p_loop_queue->p_buf = os_mem_alloc(ram_type, buf_max_size);
+ if (p_loop_queue->p_buf != NULL)
+ {
+ memset((uint8_t *)p_loop_queue->p_buf, 0, buf_max_size);
+ }
+ else
+ {
+ os_mem_free(p_loop_queue);
+ p_loop_queue = NULL;
+ }
+ }
+ return p_loop_queue;
+}
+
+/******************************************************************
+ * @brief Deinitializes loop queue
+ * @param p_loop_queue - point to loop queue which needs deinitialization.
+ * @return none
+ * @retval void
+ */
+void loop_queue_deinit(T_LOOP_QUEUE_DEF **p_loop_queue)
+{
+ if (*p_loop_queue != NULL)
+ {
+ if ((*p_loop_queue)->p_buf != NULL)
+ {
+ os_mem_free((*p_loop_queue)->p_buf);
+ (*p_loop_queue)->p_buf = NULL;
+ }
+ os_mem_free((*p_loop_queue));
+ *p_loop_queue = NULL;
+ }
+}
+
+/******************************************************************
+ * @brief Get valid data length of loop queue.
+ * @param p_loop_queue - point to loop queue dta struct.
+ * @return valid data size of loop queue.
+ * @retval uint16_t
+ */
+uint16_t loop_queue_get_vailid_data_size(T_LOOP_QUEUE_DEF *p_loop_queue)
+{
+ if (p_loop_queue == NULL)
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] pointer is invalid!", 0);
+ return 0;
+ }
+
+ if (p_loop_queue->write_index == p_loop_queue->read_index)
+ {
+ if (p_loop_queue->is_over_flow == true)
+ {
+ return (p_loop_queue->item_size * p_loop_queue->buf_max_item_num);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ return (p_loop_queue->item_size * ((p_loop_queue->buf_max_item_num + p_loop_queue->write_index -
+ p_loop_queue->read_index) % p_loop_queue->buf_max_item_num));
+ }
+}
+
+/******************************************************************
+ * @brief Get free data length of loop queue.
+ * @param p_queue_struct - point to loop queue dta struct.
+ * @return free data size of loop queue.
+ * @retval uint16_t
+ */
+uint16_t loop_queue_get_free_data_size(T_LOOP_QUEUE_DEF *p_loop_queue)
+{
+ if (p_loop_queue == NULL)
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] pointer is invalid!", 0);
+ return 0;
+ }
+
+ if (p_loop_queue->write_index == p_loop_queue->read_index)
+ {
+ if (p_loop_queue->is_over_flow == true)
+ {
+ return 0;
+ }
+ else
+ {
+ return (p_loop_queue->item_size * p_loop_queue->buf_max_item_num);
+ }
+ }
+ else
+ {
+ return (p_loop_queue->item_size * ((p_loop_queue->buf_max_item_num - p_loop_queue->write_index +
+ p_loop_queue->read_index) % p_loop_queue->buf_max_item_num));
+ }
+}
+
+/******************************************************************
+ * @brief check loop queue if will full or not.
+ * @param p_loop_queue - point to loop queue dta struct.
+ * @return loop queue is full or not
+ * @retval TRUE - full
+ * @retval FALSE - not full
+ */
+bool loop_queue_is_full(T_LOOP_QUEUE_DEF *p_loop_queue, uint16_t write_size)
+{
+ if (p_loop_queue == NULL)
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] pointer is invalid!", 0);
+ return true;
+ }
+ if (write_size % p_loop_queue->item_size != 0)
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] buf_max_size is invalid!", 0);
+ return true;
+ }
+
+ if (p_loop_queue->is_over_flow == true)
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] Loop Queue is already full!", 0);
+ return true;
+ }
+ else if (write_size >= loop_queue_get_free_data_size(p_loop_queue))
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] Loop Queue will over flow!", 0);
+ return true;
+ }
+
+ return false;
+}
+
+/******************************************************************
+ * @brief check loop queue if empty or not.
+ * @param p_loop_queue - point to loop queue dta struct.
+ * @return loop queue is empty or not
+ * @retval TRUE - empty
+ * @retval FALSE - empty full
+ */
+bool loop_queue_is_empty(T_LOOP_QUEUE_DEF *p_loop_queue)
+{
+ if (p_loop_queue == NULL)
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] pointer is invalid!", 0);
+ return false;
+ }
+
+ if (p_loop_queue->is_over_flow == false && p_loop_queue->write_index == p_loop_queue->read_index)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+/******************************************************************
+ * @brief Write source buffer data to loop queue.
+ * @param p_loop_queue - point to loop queue data struct.
+ * @param p_write_buf - point to write buffer.
+ * @param size - size of data to be written.
+ * @return result
+ * @retval true or false
+ */
+bool loop_queue_write_buf(T_LOOP_QUEUE_DEF *p_loop_queue, T_LOOP_QUEUE_BUF p_write_buf,
+ uint16_t size, bool is_overflow_data_abandoned)
+{
+ uint16_t queue_buf_cur_idx = 0;
+ uint16_t write_buf_cur_idx = 0;
+ uint16_t remain_len = 0;
+ uint16_t write_len = 0;
+ uint16_t data_size = 0;
+
+ /* Check parameters */
+ if (p_write_buf == NULL || p_loop_queue == NULL || p_loop_queue->p_buf == NULL)
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] pointer is invalid!", 0);
+ return false;
+ }
+
+ if (size <= 0 || size % p_loop_queue->item_size != 0)
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] write data size is invalid!", 0);
+ return false;
+ }
+
+ if (!loop_queue_is_full(p_loop_queue, size))
+ {
+ remain_len = size / p_loop_queue->item_size;
+ }
+ else
+ {
+ if (is_overflow_data_abandoned == true)
+ {
+ remain_len = loop_queue_get_free_data_size(p_loop_queue) / p_loop_queue->item_size;
+ }
+ else
+ {
+ remain_len = size / p_loop_queue->item_size;
+ }
+ p_loop_queue->is_over_flow = true;
+ }
+
+ while (remain_len)
+ {
+ if (p_loop_queue->write_index + remain_len <= p_loop_queue->buf_max_item_num)
+ {
+ write_len = remain_len;
+ }
+ else
+ {
+ write_len = p_loop_queue->buf_max_item_num - p_loop_queue->write_index;
+ }
+
+ queue_buf_cur_idx = p_loop_queue->item_size * p_loop_queue->write_index;
+ data_size = p_loop_queue->item_size * write_len;
+ memcpy((uint8_t *)p_loop_queue->p_buf + queue_buf_cur_idx,
+ (uint8_t *)p_write_buf + write_buf_cur_idx, data_size);
+ write_buf_cur_idx += data_size;
+ p_loop_queue->write_index = (p_loop_queue->write_index + write_len) %
+ p_loop_queue->buf_max_item_num;
+ remain_len -= write_len;
+ }
+ return true;
+}
+
+/******************************************************************
+ * @brief Read data from loop queue.
+ * @param p_queue_struct - point to loop queue data struct.
+ * @param p_read_buf - point to read buffer
+ * @param size - size of data to be read.
+ * @return result
+ * @retval true or false
+ */
+bool loop_queue_read_buf(T_LOOP_QUEUE_DEF *p_loop_queue, T_LOOP_QUEUE_BUF p_read_buf,
+ uint16_t size)
+{
+ uint16_t queue_buf_cur_idx = 0;
+ uint16_t read_buf_cur_idx = 0;
+ uint16_t remain_len = 0;
+ uint16_t read_len = 0;
+ uint16_t data_size = 0;
+
+ /* Check parameters */
+ if (p_read_buf == NULL || p_loop_queue == NULL || p_loop_queue->p_buf == NULL)
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] pointer is invalid!", 0);
+ return false;
+ }
+
+ if (size <= 0 || size % p_loop_queue->item_size != 0)
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] read data size is invalid!", 0);
+ return false;
+ }
+
+ if (loop_queue_get_vailid_data_size(p_loop_queue) < size)
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] there is not enough data to read!", 0);
+ return false;
+ }
+
+ remain_len = size / p_loop_queue->item_size;
+
+ while (remain_len)
+ {
+ if (p_loop_queue->read_index + remain_len <= p_loop_queue->buf_max_item_num)
+ {
+ read_len = remain_len;
+ }
+ else
+ {
+ read_len = p_loop_queue->buf_max_item_num - p_loop_queue->read_index;
+ }
+
+ queue_buf_cur_idx = p_loop_queue->item_size * p_loop_queue->read_index;
+ data_size = p_loop_queue->item_size * read_len;
+ memcpy((uint8_t *)p_read_buf + read_buf_cur_idx, (uint8_t *)p_loop_queue->p_buf + queue_buf_cur_idx,
+ data_size);
+ read_buf_cur_idx += data_size;
+ p_loop_queue->read_index = (p_loop_queue->read_index + read_len) % p_loop_queue->buf_max_item_num;
+ remain_len -= read_len;
+ }
+
+ p_loop_queue->is_over_flow = false;
+
+ return true;
+}
+
+/******************************************************************
+ * @brief copy buffer data from loop queue.
+ * @param p_loop_queue - point to loop queue data struct.
+ * @param p_copy_buf - point to copy buffer
+ * @param size - size of data to be copy.
+ * @return result
+ * @retval true or false
+ */
+bool loop_queue_copy_buf(T_LOOP_QUEUE_DEF *p_loop_queue, T_LOOP_QUEUE_BUF p_copy_buf,
+ uint16_t size)
+{
+ uint16_t queue_buf_cur_idx = 0;
+ uint16_t copy_buf_cur_idx = 0;
+ uint16_t remain_len = 0;
+ uint16_t copy_len = 0;
+ uint16_t data_size = 0;
+ uint16_t copy_index = 0;
+
+ /* Check parameters */
+ if (p_copy_buf == NULL || p_loop_queue == NULL || p_loop_queue->p_buf == NULL)
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] pointer is invalid!", 0);
+ return false;
+ }
+
+ if (size <= 0 || size % p_loop_queue->item_size != 0)
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] read data size is invalid!", 0);
+ return false;
+ }
+
+ if (loop_queue_get_vailid_data_size(p_loop_queue) < size)
+ {
+ LOOP_QUEUE_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "[loop queue] there is not enough data to copy!", 0);
+ return false;
+ }
+
+ remain_len = size / p_loop_queue->item_size;
+ copy_index = p_loop_queue->read_index;
+
+ while (remain_len)
+ {
+ if (copy_index + remain_len <= p_loop_queue->buf_max_item_num)
+ {
+ copy_len = remain_len;
+ }
+ else
+ {
+ copy_len = p_loop_queue->buf_max_item_num - copy_index;
+ }
+
+ queue_buf_cur_idx = p_loop_queue->item_size * copy_index;
+ data_size = p_loop_queue->item_size * copy_len;
+ memcpy((uint8_t *)p_copy_buf + copy_buf_cur_idx, (uint8_t *)p_loop_queue->p_buf + queue_buf_cur_idx,
+ data_size);
+ copy_buf_cur_idx += data_size;
+ copy_index = (copy_index + copy_len) % p_loop_queue->buf_max_item_num;
+ remain_len -= copy_len;
+ }
+ return true;
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/loop_queue.h b/src/app/google_rcu/loop_queue.h
new file mode 100644
index 0000000..f228e87
--- /dev/null
+++ b/src/app/google_rcu/loop_queue.h
@@ -0,0 +1,71 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file loop_queue.h
+* @brief
+* @details
+* @author barry_bian
+* @date 2020-04-09
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __LOOP_QUEUE_H
+#define __LOOP_QUEUE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "trace.h"
+#include "string.h"
+#include "os_mem.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+#ifdef PRINT_LOG
+#define LOOP_QUEUE_DBG_BUFFER(module, level, fmt, param_num,...) \
+ DBG_BUFFER_##level(TYPE_BUMBLEBEE3, SUBTYPE_FORMAT, module, fmt, param_num, ##__VA_ARGS__)
+
+#else
+#define LOOP_QUEUE_DBG_BUFFER(MODULE, LEVEL, pFormat, para_num,...) ((void)0)
+#endif
+
+typedef void *T_LOOP_QUEUE_BUF;
+
+/**
+ * @brief Loop queue data struct
+ */
+typedef struct
+{
+ volatile bool is_over_flow; /* loop queue item size */
+ volatile uint16_t item_size; /* buf data type */
+ volatile uint16_t buf_max_item_num; /* Buffer size of loop queue */
+ volatile uint16_t read_index; /* index of read queue */
+ volatile uint16_t write_index; /* index of write queue */
+ volatile T_LOOP_QUEUE_BUF p_buf; /* Buffer for loop queue */
+} T_LOOP_QUEUE_DEF;
+
+
+T_LOOP_QUEUE_DEF *loop_queue_init(uint16_t buf_max_size, uint16_t item_size,
+ RAM_TYPE ram_type);
+void loop_queue_deinit(T_LOOP_QUEUE_DEF **p_loop_queue);
+bool loop_queue_is_full(T_LOOP_QUEUE_DEF *p_queue_struct, uint16_t write_size);
+bool loop_queue_is_empty(T_LOOP_QUEUE_DEF *p_queue_struct);
+uint16_t loop_queue_get_vailid_data_size(T_LOOP_QUEUE_DEF *p_queue_struct);
+uint16_t loop_queue_get_free_data_size(T_LOOP_QUEUE_DEF *p_loop_queue);
+bool loop_queue_write_buf(T_LOOP_QUEUE_DEF *p_queue_struct, T_LOOP_QUEUE_BUF p_buf, uint16_t size,
+ bool is_overflow_data_abandoned);
+bool loop_queue_read_buf(T_LOOP_QUEUE_DEF *p_queue_struct, T_LOOP_QUEUE_BUF p_buf, uint16_t size);
+bool loop_queue_copy_buf(T_LOOP_QUEUE_DEF *p_queue_struct, T_LOOP_QUEUE_BUF p_buf, uint16_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__UART_TRANS_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/main.c b/src/app/google_rcu/main.c
new file mode 100644
index 0000000..ceebaa9
--- /dev/null
+++ b/src/app/google_rcu/main.c
@@ -0,0 +1,606 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief This is the entry of user code which the main function resides in.
+* @details
+* @author chenjie_jin
+* @date 2020-02-21
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdlib.h>
+#include <board.h>
+#include <os_sched.h>
+#include <string.h>
+#include <trace.h>
+#include <gap.h>
+#include <gap_bond_le.h>
+#include <profile_server.h>
+#include <rcu_application.h>
+#include <dlps.h>
+#include <rtl876x_keyscan.h>
+#include <rtl876x_io_dlps.h>
+#include <keyscan_driver.h>
+#include <app_task.h>
+#include <swtimer.h>
+#include <bas.h>
+#include <dis.h>
+#include <hids_rmc.h>
+#include <vendor_service.h>
+#include <ota_service.h>
+#include <rcu_gap.h>
+#include <app_section.h>
+#include <mem_config.h>
+#include <key_handle.h>
+#include <voice_driver.h>
+#include "test_mode.h"
+#include "battery_driver.h"
+#include "led_driver.h"
+#include "ir_service.h"
+#if SUPPORT_SILENT_OTA
+#include <dfu_service.h>
+#endif
+#if SUPPORT_VOICE_FEATURE
+#include <voice.h>
+#endif
+#if SUPPORT_IR_TX_FEATURE
+#include <ir_send_driver.h>
+#endif
+#if MP_TEST_MODE_SUPPORT_SINGLE_TONE_TEST
+#include <single_tone.h>
+#endif
+#if FEATURE_SUPPORT_MP_TEST_MODE
+#include <mp_test.h>
+#include <data_uart_test.h>
+#endif
+#if SCENARIO_SWITCH_EN
+#include <app_section.h>
+#include <overlay_mgr.h>
+#endif
+#include <atvv_service.h>
+#if (AON_WDG_ENABLE == 1)
+#include <rtl876x_aon_wdg.h>
+#endif
+#include <rtc_driver.h>
+#include "app_custom.h"
+#if FEAUTRE_SUPPORT_IR_OVER_BLE
+#include "ir_service_handle.h"
+#endif
+#if SUPPORT_BUZZER_FEATURE
+#include "fms.h"
+#include "fms_service_handle.h"
+#include "buzzer_driver.h"
+#endif
+#include "rtl876x_pinmux.h"
+#include "rcu_gap_dtm.h"
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+static void global_data_init(void);
+static void app_pinmux_config(void);
+static void app_pad_config(void);
+static void board_init(void);
+static void driver_init(void);
+#if DLPS_EN
+static void app_enter_dlps_config(void) DATA_RAM_FUNCTION;
+static void app_exit_dlps_config(void) DATA_RAM_FUNCTION;
+static bool app_dlps_check_cb(void) DATA_RAM_FUNCTION;
+#endif
+static void pwr_mgr_init(void);
+static void task_init(void);
+void dtm_task_init(void);
+static void app_normal_power_on_seq(void);
+
+#define app_system_on_interrupt_handler System_Handler
+void app_system_on_interrupt_handler(void) DATA_RAM_FUNCTION;
+
+void dtm_gpio_init(void);
+void gpio_dtm_pad_config(void);
+void gpio_dtm_pinmux_config(void);
+bool enter_dtm(void);
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+void set_dfu_config()
+{
+#if (OTA_AES_FLAG_EN == 0)
+ OTP->ota_with_encryption_data = 0x0;
+#else
+ OTP->ota_with_encryption_data = 0x1;
+#endif
+
+}
+
+USER_CALL_BACK app_pre_main_cb = set_dfu_config;
+
+/******************************************************************
+ * @brief global_data_init() contains the initialization of global data.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void global_data_init(void)
+{
+ // /* for test only */
+ // app_custom_test();
+
+ app_init_global_data();
+ key_handle_init_data();
+ keyscan_init_data();
+
+ app_custom_init();
+ APP_PRINT_INFO1("[global_data_init] device type = %d", app_global_data.device_type);
+ APP_PRINT_INFO1("[global_data_init] ui layout type = 0x%X", app_global_data.device_ui_layout_type);
+ APP_PRINT_INFO1("[global_data_init] fw version = %b",
+ TRACE_BINARY(sizeof(app_global_data.fw_version), app_global_data.fw_version));
+ APP_PRINT_INFO1("[global_data_init] sw version = %b",
+ TRACE_BINARY(sizeof(app_global_data.sw_version), app_global_data.sw_version));
+ APP_PRINT_INFO1("[global_data_init] PnP ID = %b", TRACE_BINARY(7, app_global_data.pnp_id));
+ APP_PRINT_INFO1("[global_data_init] device name = %b", TRACE_BINARY(app_global_data.device_name_len,
+ app_global_data.device_name));
+ APP_PRINT_INFO1("[global_data_init] en_powerkey_cache = %d", app_global_data.en_powerkey_cache);
+ APP_PRINT_INFO1("[global_data_init] en_google_wakeuppack = %d",
+ app_global_data.en_google_wakeuppack);
+ APP_PRINT_INFO2("[global_data_init] wakeupkey1_mask = 0x%X, %b", app_global_data.wakeupkey1_mask,
+ TRACE_BINARY(APP_CUSTOM_WAKEUPKEY_NUM, app_global_data.wakeup_key1));
+ APP_PRINT_INFO2("[global_data_init] wakeupkey2_mask = 0x%X, %b", app_global_data.wakeupkey2_mask,
+ TRACE_BINARY(APP_CUSTOM_WAKEUPKEY_NUM, app_global_data.wakeup_key2));
+ APP_PRINT_INFO2("[global_data_init] wakeup format = %d, custom data: %b",
+ app_global_data.wakeup_adv_format, TRACE_BINARY(40,
+ app_global_data.wakeup_adv_custom_data));
+ APP_PRINT_INFO1("[global_data_init] Default G20 table: %b", TRACE_BINARY(49,
+ KEY_MAPPING_TABLE_G20));
+ APP_PRINT_INFO1("[global_data_init] Current G20 table: %b", TRACE_BINARY(49,
+ key_handle_global_data.cur_key_mapping_table));
+
+ rcu_update_adv_rsp_data();
+
+#if FEAUTRE_SUPPORT_IR_OVER_BLE
+ ir_service_handle_init_data();
+#endif
+
+#if SUPPORT_VOICE_FEATURE
+ voice_driver_init_data();
+ voice_driver_init_codec_params();
+ voice_handle_atvv_init_data();
+#endif
+#if SUPPORT_BAT_DETECT_FEATURE
+ bat_init_data();
+#endif
+#if FEATURE_SUPPORT_MP_TEST_MODE
+ mp_test_init_data();
+#endif
+
+#if SUPPORT_BUZZER_FEATURE
+ fms_handle_init_data();
+#endif
+}
+
+/******************************************************************
+ * @brief app_pinmux_config() contains the initialization of app pinmux config.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_pinmux_config(void)
+{
+ /*only when in normal mode and fast pair mode, keyscan can be config*/
+ if ((app_global_data.test_mode == NOT_TEST_MODE)
+ || (app_global_data.test_mode == AUTO_PAIR_WITH_FIX_ADDR_MODE))
+ {
+ keyscan_pinmux_config();
+ }
+}
+
+/******************************************************************
+ * @brief init dtm pad and pinmux, and judge if MODE_PIN is low
+ * @param none
+ * @return MODE_PIN state
+ * @retval true MODE_PIN is low
+ * @retval false MODE_PIN is not low
+ */
+bool enter_dtm(void)
+{
+ /*dtm board init*/
+ gpio_dtm_pad_config();
+ gpio_dtm_pinmux_config();
+
+ /*dtm driver init*/
+ dtm_gpio_init();
+
+ if (RESET == GPIO_ReadInputDataBit(GPIO_GetPin(MODE_PIN)))
+ {
+ return true;
+ }
+
+ return false;
+}
+/******************************************************************
+ * @brief app_pad_config() contains the initialization of app pad config.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_pad_config(void)
+{
+ /*only when in normal mode and fast pair mode, keyscan can be config*/
+ if ((app_global_data.test_mode == NOT_TEST_MODE)
+ || (app_global_data.test_mode == AUTO_PAIR_WITH_FIX_ADDR_MODE))
+ {
+ keyscan_init_pad_config();
+ }
+}
+
+/******************************************************************
+ * @brief Board_Init() contains the initialization of pinmux settings and pad settings.
+ *
+ * All the pinmux settings and pad settings shall be initiated in this function.
+ * But if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void board_init(void)
+{
+ app_pinmux_config();
+ app_pad_config();
+}
+
+/******************************************************************
+ * @brief driver_init() contains the initialization of peripherals.
+ *
+ * Both new architecture driver and legacy driver initialization method can be used.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void driver_init(void)
+{
+#if SUPPORT_LED_INDICATION_FEATURE
+ /*led module init*/
+ led_module_init();
+#endif
+
+#if MP_TEST_MODE_SUPPORT_DATA_UART_TEST
+ if (app_global_data.test_mode == DATA_UART_TEST_MODE)
+ {
+ /*data uart mode uart init*/
+ uart_test_init();
+ }
+#endif
+
+#if SUPPORT_BAT_DETECT_FEATURE
+ bat_init_driver();
+#endif
+
+#if SUPPORT_BUZZER_FEATURE
+ buzzer_deinit_pad_config();
+#endif
+}
+
+#if DLPS_EN
+/******************************************************************
+ * @brief this function will be called before enter DLPS
+ *
+ * set PAD and wakeup pin config for enterring DLPS
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_enter_dlps_config(void)
+{
+ if ((app_global_data.test_mode == NOT_TEST_MODE)
+ || (app_global_data.test_mode == AUTO_PAIR_WITH_FIX_ADDR_MODE))
+ {
+ keyscan_enter_dlps_config();
+ }
+#if MP_TEST_MODE_SUPPORT_DATA_UART_TEST
+ else if (app_global_data.test_mode == DATA_UART_TEST_MODE)
+ {
+ uart_test_enter_dlps_config();
+ }
+#endif
+
+#if SUPPORT_BAT_DETECT_FEATURE
+ bat_enter_dlps_config();
+#endif
+
+#if SUPPORT_IR_TX_FEATURE
+ ir_send_enter_dlps_config();
+#endif
+
+#if (AON_WDG_ENABLE == 1)
+ aon_wdg_enable();
+#endif
+}
+
+/******************************************************************
+ * @brief this function will be called after exit DLPS
+ *
+ * set PAD and wakeup pin config for enterring DLPS
+ *
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_exit_dlps_config(void)
+{
+ if ((app_global_data.test_mode == NOT_TEST_MODE)
+ || (app_global_data.test_mode == AUTO_PAIR_WITH_FIX_ADDR_MODE))
+ {
+ keyscan_exit_dlps_config();
+ }
+#if SUPPORT_BAT_DETECT_FEATURE
+ bat_exit_dlps_config();
+#endif
+
+#if SUPPORT_IR_TX_FEATURE
+ ir_send_exit_dlps_config();
+#endif
+
+#if (AON_WDG_ENABLE == 1)
+ aon_wdg_disable();
+#endif
+}
+
+/******************************************************************
+ * @brief app_dlps_check_cb() contains the setting about app dlps callback.
+ * @param none
+ * @retval true able to enter DLPS
+ * @retval false unable to enter DLPS
+ */
+bool app_dlps_check_cb(void)
+{
+ return (
+ keyscan_check_dlps()
+#if SUPPORT_VOICE_FEATURE
+ && voice_driver_dlps_check()
+#endif
+#if SUPPORT_IR_TX_FEATURE
+ && ir_send_check_dlps()
+#endif
+#if MP_TEST_MODE_SUPPORT_DATA_UART_TEST
+ && uart_test_check_dlps()
+#endif
+#if SUPPORT_LED_INDICATION_FEATURE
+ && led_driver_dlps_check()
+#endif
+ );
+}
+#endif
+
+/******************************************************************
+ * @brief pwr_mgr_init() contains the setting about power mode.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void pwr_mgr_init(void)
+{
+#if DLPS_EN
+ if (false == dlps_check_cb_reg(app_dlps_check_cb))
+ {
+ APP_PRINT_ERROR0("Error: dlps_check_cb_reg(app_dlps_check_cb) failed!");
+ }
+ DLPS_IORegUserDlpsEnterCb(app_enter_dlps_config);
+ DLPS_IORegUserDlpsExitCb(app_exit_dlps_config);
+ DLPS_IORegister();
+ lps_mode_set(PLATFORM_DLPS_PFM);
+#endif
+}
+
+/******************************************************************
+ * @brief Add simple profile service and register callbacks
+ * @param none
+ * @return none
+ * @retval void
+ */
+static void app_le_profile_init(void)
+{
+ server_init(9);
+
+ app_global_data.bas_srv_id = bas_add_service((void *)app_profile_callback);
+ app_global_data.dis_srv_id = dis_add_service((void *)app_profile_callback);
+ app_global_data.hid_srv_id = hids_add_service((void *)app_profile_callback);
+ app_global_data.atvv_srv_id = atvv_add_service(app_profile_callback);
+ app_global_data.ir_srv_id = ir_svc_add_service((void *)app_profile_callback);
+ app_global_data.ota_srv_id = ota_add_service((void *)app_profile_callback);
+ app_global_data.dfu_srv_id = dfu_add_service((void *)app_profile_callback);
+ app_global_data.vendor_srv_id = vendor_svc_add_service((void *)app_profile_callback);
+#if SUPPORT_BUZZER_FEATURE
+ if (app_global_data.en_find_me == 1)
+ {
+ app_global_data.fms_srv_id = fms_add_service((void *)app_profile_callback);
+ }
+#endif
+ server_register_app_cb(app_profile_callback);
+}
+
+/******************************************************************
+ * @brief app_system_on_interrupt_handler() contains the handler for System_On interrupt.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_system_on_interrupt_handler(void)
+{
+ APP_PRINT_INFO0("[app_system_on_interrupt_handler] system on interrupt");
+
+ NVIC_DisableIRQ(System_IRQn);
+
+ if (SET == System_DebounceWakeupStatus())
+ {
+ APP_PRINT_INFO0("[app_system_on_interrupt_handler] pad signal wake up");
+ /* pad signal wake up event */
+ keyscan_global_data.is_allowed_to_enter_dlps = false;
+
+ /*manual mode keyscan init*/
+ keyscan_init_driver(KeyScan_Manual_Sel_Bit, KeyScan_Debounce_Disable);
+ }
+ NVIC_ClearPendingIRQ(System_IRQn);
+}
+
+/******************************************************************
+ * @brief task_init() contains the initialization of all the tasks.
+ *
+ * There are four tasks are initiated.
+ * Lowerstack task and upperstack task are used by bluetooth stack.
+ * Application task is task which user application code resides in.
+ * Emergency task is reserved.
+ * @param none
+ * @return none
+ * @retval void
+*/
+void task_init(void)
+{
+ app_task_init();
+}
+
+/******************************************************************
+ * @brief app_normal_power_on_seq() contains the app normal power on sequence.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_normal_power_on_seq(void)
+{
+ board_init();
+ driver_init();
+ le_gap_init(1);
+ rcu_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ sw_timer_init();
+ task_init();
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief app_nvic_config() contains the initialization of app NVIC config.
+ *
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_nvic_config(void)
+{
+ if ((app_global_data.test_mode == NOT_TEST_MODE)
+ || (app_global_data.test_mode == AUTO_PAIR_WITH_FIX_ADDR_MODE))
+ {
+ /*auto mode keyscan init*/
+ keyscan_init_driver(KeyScan_Manual_Sel_Key, KeyScan_Debounce_Enable);
+ keyscan_nvic_config();
+ }
+#if SUPPORT_BAT_DETECT_FEATURE
+ bat_nvic_config();
+#endif
+
+ rtc_driver_init();
+}
+
+/******************************************************************
+ * @brief main() is a start of main codes.
+ * @param none
+ * @retval 0
+ */
+int main(void)
+{
+#if FEAUTRE_SUPPORT_FLASH_2_BIT_MODE
+ if (FLASH_SUCCESS == flash_try_high_speed(FLASH_MODE_2BIT))
+ {
+ APP_PRINT_INFO0("Switch to 2-Bit flash mode");
+ }
+#endif
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ app_global_data.reset_reason = reset_reason_get();
+
+ /* check test mode */
+ app_global_data.test_mode = get_test_mode();
+ reset_test_mode();
+
+ APP_PRINT_INFO1("Test Mode is %d", app_global_data.test_mode);
+
+ switch (app_global_data.test_mode)
+ {
+ case NOT_TEST_MODE:
+ {
+ if (enter_dtm() == true)
+ {
+ /* if MODE_PIN is pull down,RCU enter DTM mode to connect with DTM device */
+ switch_to_test_mode(DIRECT_TEST_MODE);
+ break;
+ }
+
+ APP_PRINT_INFO0("RCU is in NOT_TEST_MODE");
+#if (MP_TEST_MODE_TRIG_SEL & MP_TEST_MODE_TRIG_BY_GPIO)
+ mp_test_check_trig_gpio_status();
+#endif
+ app_normal_power_on_seq();
+ }
+ break;
+
+ case DIRECT_TEST_MODE:
+ {
+ APP_PRINT_INFO0("DUT Mode Start");
+ WDG_Disable(); //avoid conflict with WDG
+ le_register_app_cb(dtm_gap_callback);
+ RamVectorTableUpdate(Uart0_VECTORn, dtm_interrupt); //avoid conflict with system-uart0-interrupt
+ dtm_task_init();
+ }
+ break;
+
+#if MP_TEST_MODE_SUPPORT_SINGLE_TONE_TEST
+ case SINGLE_TONE_MODE:
+ {
+ APP_PRINT_INFO0("RCU is in SINGLE_TONE_MODE");
+ WDG_Disable(); /* Avoid unexpected reboot */
+#if SUPPORT_LED_INDICATION_FEATURE
+ /*led module init*/
+ led_module_init();
+ LED_BLINK(LED_TYPE_BLINK_TEST_RED, 0);
+ LED_BLINK(LED_TYPE_BLINK_TEST_GREEN, 0);
+ LED_BLINK(LED_TYPE_BLINK_TEST_BLUE, 0);
+#endif
+ single_tone_init();
+ }
+ break;
+#endif
+
+#if MP_TEST_MODE_SUPPORT_FAST_PAIR_TEST
+ case AUTO_PAIR_WITH_FIX_ADDR_MODE:
+ {
+ APP_PRINT_INFO0("RCU is in AUTO_PAIR_WITH_FIX_ADDR_MODE");
+ mp_test_load_fp_mac_addr();
+ app_normal_power_on_seq();
+ }
+ break;
+#endif
+
+#if MP_TEST_MODE_SUPPORT_DATA_UART_TEST
+ case DATA_UART_TEST_MODE:
+ {
+ APP_PRINT_INFO0("RCU is in DATA_UART_TEST_MODE");
+ app_normal_power_on_seq();
+ }
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ os_sched_start();
+ return 0;
+}
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/mp_config.c b/src/app/google_rcu/mp_config.c
new file mode 100644
index 0000000..8e981ba
--- /dev/null
+++ b/src/app/google_rcu/mp_config.c
@@ -0,0 +1,343 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file mp_config.c
+* @brief .
+* @details
+* @author ranhui_xia
+* @date 2015-11-15
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#include "rtl876x.h"
+#include "trace.h"
+#include "gap.h"
+#include "board.h"
+#include "mp_config.h"
+#if MP_TEST_SUPPORT
+#include "test_mode.h"
+#endif
+#include "app_section.h"
+#include "gap_storage_le.h"
+#include "mem_types.h"
+#include "ftl.h"
+#include "os_mem.h"
+#include "gap_bond_le.h"
+
+#if MP_TEST_SUPPORT
+
+// the test mode flag of user image
+//[Lory] the flag will be written through MP Tool
+const uint32_t test_mode_flag USER_FLASH_TEST_MODE_FLAG = 0xFFFFFFFF; //TEST_MODE_FLAG_DEFAULT;
+
+void mp_set_local_bt_addr(uint8_t index)
+{
+ uint8_t mp_local_bd[8] = {0};
+
+ switch (index)
+ {
+ case MP_TEST_LINE_1:
+ {
+ //00:e0:4c:23:88:01
+ mp_local_bd[5] = 0x00;
+ mp_local_bd[4] = 0xe0;
+ mp_local_bd[3] = 0x4c;
+ mp_local_bd[2] = 0x23;
+ mp_local_bd[1] = 0x88;
+ mp_local_bd[0] = 0x01;
+ }
+ break;
+
+ case MP_TEST_LINE_2:
+ {
+ //00:e0:4c:23:88:02
+ mp_local_bd[5] = 0x00;
+ mp_local_bd[4] = 0xe0;
+ mp_local_bd[3] = 0x4c;
+ mp_local_bd[2] = 0x23;
+ mp_local_bd[1] = 0x88;
+ mp_local_bd[0] = 0x02;
+ }
+ break;
+ case MP_TEST_LINE_3:
+ {
+ //00:e0:4c:23:88:03
+ mp_local_bd[5] = 0x00;
+ mp_local_bd[4] = 0xe0;
+ mp_local_bd[3] = 0x4c;
+ mp_local_bd[2] = 0x23;
+ mp_local_bd[1] = 0x88;
+ mp_local_bd[0] = 0x03;
+ }
+ break;
+ case MP_TEST_LINE_4:
+ {
+ //00:e0:4c:23:88:04
+ mp_local_bd[5] = 0x00;
+ mp_local_bd[4] = 0xe0;
+ mp_local_bd[3] = 0x4c;
+ mp_local_bd[2] = 0x23;
+ mp_local_bd[1] = 0x88;
+ mp_local_bd[0] = 0x04;
+ }
+ break;
+ case MP_TEST_LINE_5:
+ {
+ //00:e0:4c:23:88:05
+ mp_local_bd[5] = 0x00;
+ mp_local_bd[4] = 0xe0;
+ mp_local_bd[3] = 0x4c;
+ mp_local_bd[2] = 0x23;
+ mp_local_bd[1] = 0x88;
+ mp_local_bd[0] = 0x05;
+ }
+ break;
+ default:
+ break;
+ }
+
+ ftl_save(mp_local_bd, MP_FLASH_PARAMS_LOCAL_BD_ADDR_OFFSET, sizeof(mp_local_bd));
+
+
+}
+
+
+void mp_set_auto_pair_info(uint8_t index)
+{
+ uint8_t ccc_bits_count = 16;
+ T_LE_CCCD *p_cccd_data;
+ T_LE_KEY_TYPE key_type = LE_KEY_UNAUTHEN;
+
+ T_GAP_REMOTE_ADDR_TYPE remote_addr_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t bd_addr[6] = {0};/*remote bd address*/
+ uint8_t ltk_length = 16;/*need to get real num*/
+ uint8_t local_ltk[16];
+ switch (index)
+ {
+ case MP_TEST_LINE_1:
+ {
+ //00:e0:c4:23:99:87
+ bd_addr[5] = 0x00;
+ bd_addr[4] = 0xe0;
+ bd_addr[3] = 0x4c;
+ bd_addr[2] = 0x23;
+ bd_addr[1] = 0x99;
+ bd_addr[0] = 0x87;
+ remote_addr_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+
+ /*link key config*/
+ key_type = LE_KEY_UNAUTHEN;
+ ltk_length = 16;
+ local_ltk[0] = 0xcb;
+ local_ltk[1] = 0x84;
+ local_ltk[2] = 0xaa;
+ local_ltk[3] = 0x4d;
+ local_ltk[4] = 0x66;
+ local_ltk[5] = 0x42;
+ local_ltk[6] = 0xd5;
+ local_ltk[7] = 0xa2;
+ local_ltk[8] = 0x33;
+ local_ltk[9] = 0xa1;
+ local_ltk[10] = 0x6a;
+ local_ltk[11] = 0x51;
+ local_ltk[12] = 0x9a;
+ local_ltk[13] = 0x50;
+ local_ltk[14] = 0xb5;
+ local_ltk[15] = 0xac;
+ }
+ break;
+ case MP_TEST_LINE_2:
+ {
+ //00:e0:c4:23:99:87
+ bd_addr[5] = 0x00;
+ bd_addr[4] = 0xe0;
+ bd_addr[3] = 0x4c;
+ bd_addr[2] = 0x23;
+ bd_addr[1] = 0x99;
+ bd_addr[0] = 0x87;
+ remote_addr_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+
+ /*link key config*/
+ key_type = LE_KEY_UNAUTHEN;
+ ltk_length = 16;
+ local_ltk[0] = 0xcb;
+ local_ltk[1] = 0x84;
+ local_ltk[2] = 0xaa;
+ local_ltk[3] = 0x4d;
+ local_ltk[4] = 0x66;
+ local_ltk[5] = 0x42;
+ local_ltk[6] = 0xd5;
+ local_ltk[7] = 0xa2;
+ local_ltk[8] = 0x33;
+ local_ltk[9] = 0xa1;
+ local_ltk[10] = 0x6a;
+ local_ltk[11] = 0x51;
+ local_ltk[12] = 0x9a;
+ local_ltk[13] = 0x50;
+ local_ltk[14] = 0xb5;
+ local_ltk[15] = 0xac;
+ }
+ break;
+ case MP_TEST_LINE_3:
+ {
+ //00:e0:c4:23:99:87
+ bd_addr[5] = 0x00;
+ bd_addr[4] = 0xe0;
+ bd_addr[3] = 0x4c;
+ bd_addr[2] = 0x23;
+ bd_addr[1] = 0x99;
+ bd_addr[0] = 0x87;
+ remote_addr_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+
+
+ /*link key config*/
+ key_type = LE_KEY_UNAUTHEN;
+ ltk_length = 16;
+ local_ltk[0] = 0xcb;
+ local_ltk[1] = 0x84;
+ local_ltk[2] = 0xaa;
+ local_ltk[3] = 0x4d;
+ local_ltk[4] = 0x66;
+ local_ltk[5] = 0x42;
+ local_ltk[6] = 0xd5;
+ local_ltk[7] = 0xa2;
+ local_ltk[8] = 0x33;
+ local_ltk[9] = 0xa1;
+ local_ltk[10] = 0x6a;
+ local_ltk[11] = 0x51;
+ local_ltk[12] = 0x9a;
+ local_ltk[13] = 0x50;
+ local_ltk[14] = 0xb5;
+ local_ltk[15] = 0xac;
+ }
+ break;
+ case MP_TEST_LINE_4:
+ {
+ //00:e0:c4:23:99:87
+ bd_addr[5] = 0x00;
+ bd_addr[4] = 0xe0;
+ bd_addr[3] = 0x4c;
+ bd_addr[2] = 0x23;
+ bd_addr[1] = 0x99;
+ bd_addr[0] = 0x87;
+ remote_addr_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+
+ /*link key config*/
+ key_type = LE_KEY_UNAUTHEN;
+ ltk_length = 16;
+ local_ltk[0] = 0xcb;
+ local_ltk[1] = 0x84;
+ local_ltk[2] = 0xaa;
+ local_ltk[3] = 0x4d;
+ local_ltk[4] = 0x66;
+ local_ltk[5] = 0x42;
+ local_ltk[6] = 0xd5;
+ local_ltk[7] = 0xa2;
+ local_ltk[8] = 0x33;
+ local_ltk[9] = 0xa1;
+ local_ltk[10] = 0x6a;
+ local_ltk[11] = 0x51;
+ local_ltk[12] = 0x9a;
+ local_ltk[13] = 0x50;
+ local_ltk[14] = 0xb5;
+ local_ltk[15] = 0xac;
+ }
+ break;
+ case MP_TEST_LINE_5:
+ {
+ //00:e0:c4:23:99:87
+ bd_addr[5] = 0x00;
+ bd_addr[4] = 0xe0;
+ bd_addr[3] = 0x4c;
+ bd_addr[2] = 0x23;
+ bd_addr[1] = 0x99;
+ bd_addr[0] = 0x87;
+ remote_addr_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+
+ /*link key config*/
+ key_type = LE_KEY_UNAUTHEN;
+ ltk_length = 16;
+ local_ltk[0] = 0xcb;
+ local_ltk[1] = 0x84;
+ local_ltk[2] = 0xaa;
+ local_ltk[3] = 0x4d;
+ local_ltk[4] = 0x66;
+ local_ltk[5] = 0x42;
+ local_ltk[6] = 0xd5;
+ local_ltk[7] = 0xa2;
+ local_ltk[8] = 0x33;
+ local_ltk[9] = 0xa1;
+ local_ltk[10] = 0x6a;
+ local_ltk[11] = 0x51;
+ local_ltk[12] = 0x9a;
+ local_ltk[13] = 0x50;
+ local_ltk[14] = 0xb5;
+ local_ltk[15] = 0xac;
+ }
+ break;
+ default:
+ break;
+ }
+ p_cccd_data = os_mem_alloc(RAM_TYPE_DATA_ON, 4 + ccc_bits_count * 4);
+ p_cccd_data->data_length = 0x14;
+ p_cccd_data->data[0] = 0x4F;
+ p_cccd_data->data[1] = 0x00;
+ p_cccd_data->data[2] = 0x01;
+ p_cccd_data->data[3] = 0x00;
+ p_cccd_data->data[4] = 0x33;
+ p_cccd_data->data[5] = 0x00;
+ p_cccd_data->data[6] = 0x01;
+ p_cccd_data->data[7] = 0x00;
+ p_cccd_data->data[8] = 0x3C;
+ p_cccd_data->data[9] = 0x00;
+ p_cccd_data->data[10] = 0x01;
+ p_cccd_data->data[11] = 0x00;
+ p_cccd_data->data[12] = 0x43;
+ p_cccd_data->data[13] = 0x00;
+ p_cccd_data->data[14] = 0x01;
+ p_cccd_data->data[15] = 0x00;
+ p_cccd_data->data[16] = 0x47;
+ p_cccd_data->data[17] = 0x00;
+ p_cccd_data->data[18] = 0x01;
+ p_cccd_data->data[19] = 0x00;
+
+ /*set mp auto pair device info*/
+ if (le_gen_bond_dev(bd_addr, remote_addr_type, GAP_LOCAL_ADDR_LE_PUBLIC,
+ ltk_length, local_ltk, key_type, p_cccd_data))
+ {
+ APP_PRINT_INFO0("[MP] Generate bond device success.");
+ }
+ else
+ {
+ APP_PRINT_INFO0("[MP] Err: Generate bond device failed!");
+ }
+
+ os_mem_free(p_cccd_data);
+}
+
+bool mp_pair_info_remove(void)
+{
+ bool bRet = true;
+
+ le_bond_clear_all_keys();
+
+ if (0 < le_get_bond_dev_num())
+ {
+ APP_PRINT_INFO0("[MP] Fail, pair information still exist.");
+ bRet = false;
+ }
+ else
+ {
+ APP_PRINT_INFO0("[MP] Success, pair information removed.");
+ TestModeFlagDisable();
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+#endif
+
+
diff --git a/src/app/google_rcu/mp_config.h b/src/app/google_rcu/mp_config.h
new file mode 100644
index 0000000..fe914ae
--- /dev/null
+++ b/src/app/google_rcu/mp_config.h
@@ -0,0 +1,41 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file mp_config.h
+* @brief .
+* @details
+* @author ranhui_xia
+* @date 2015-11-15
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef _MP_CONFIG_H
+#define _MP_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MP_TEST_LINE_1 1
+#define MP_TEST_LINE_2 2
+#define MP_TEST_LINE_3 3
+#define MP_TEST_LINE_4 4
+#define MP_TEST_LINE_5 5
+
+#define MP_FLASH_PARAMS_OFFSET 0
+#define MP_FLASH_PARAMS_LOCAL_BD_ADDR_OFFSET (MP_FLASH_PARAMS_OFFSET)
+
+void mp_set_local_bt_addr(uint8_t index);
+void mp_set_auto_pair_info(uint8_t index);
+bool mp_pair_info_remove(void);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PROFILE_INIT_H */
diff --git a/src/app/google_rcu/opus/config.h b/src/app/google_rcu/opus/config.h
new file mode 100644
index 0000000..d94c7a0
--- /dev/null
+++ b/src/app/google_rcu/opus/config.h
@@ -0,0 +1,64 @@
+/***********************************************************************
+Copyright (c) 2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Internet Society, IETF or IETF Trust, nor the
+names of specific contributors, may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#define USE_ALLOCA 1
+
+/* Comment out the next line for floating-point code */
+#define FIXED_POINT 1
+
+#define OPUS_BUILD 1
+
+#if defined(_M_IX86) || defined(_M_X64)
+/* Can always compile SSE intrinsics (no special compiler flags necessary) */
+#define OPUS_X86_MAY_HAVE_SSE
+#define OPUS_X86_MAY_HAVE_SSE2
+#define OPUS_X86_MAY_HAVE_SSE4_1
+
+/* Presume SSE functions, if compiled to use SSE/SSE2/AVX (note that AMD64 implies SSE2, and AVX
+ implies SSE4.1) */
+#if defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1)) || defined(__AVX__)
+#define OPUS_X86_PRESUME_SSE 1
+#endif
+#if defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__AVX__)
+#define OPUS_X86_PRESUME_SSE2 1
+#endif
+#if defined(__AVX__)
+#define OPUS_X86_PRESUME_SSE4_1 1
+#endif
+
+#if !defined(OPUS_X86_PRESUME_SSE4_1) || !defined(OPUS_X86_PRESUME_SSE2) || !defined(OPUS_X86_PRESUME_SSE)
+#define OPUS_HAVE_RTCD 1
+#endif
+
+#endif
+
+//#include "version.h"
+
+#endif /* CONFIG_H */
diff --git a/src/app/google_rcu/opus/opus.h b/src/app/google_rcu/opus/opus.h
new file mode 100644
index 0000000..933eb78
--- /dev/null
+++ b/src/app/google_rcu/opus/opus.h
@@ -0,0 +1,994 @@
+/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited
+ Written by Jean-Marc Valin and Koen Vos */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * @file opus.h
+ * @brief Opus reference implementation API
+ */
+
+#ifndef OPUS_H
+#define OPUS_H
+
+#include "opus_types.h"
+#include "opus_defines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @mainpage Opus
+ *
+ * The Opus codec is designed for interactive speech and audio transmission over the Internet.
+ * It is designed by the IETF Codec Working Group and incorporates technology from
+ * Skype's SILK codec and Xiph.Org's CELT codec.
+ *
+ * The Opus codec is designed to handle a wide range of interactive audio applications,
+ * including Voice over IP, videoconferencing, in-game chat, and even remote live music
+ * performances. It can scale from low bit-rate narrowband speech to very high quality
+ * stereo music. Its main features are:
+
+ * @li Sampling rates from 8 to 48 kHz
+ * @li Bit-rates from 6 kb/s to 510 kb/s
+ * @li Support for both constant bit-rate (CBR) and variable bit-rate (VBR)
+ * @li Audio bandwidth from narrowband to full-band
+ * @li Support for speech and music
+ * @li Support for mono and stereo
+ * @li Support for multichannel (up to 255 channels)
+ * @li Frame sizes from 2.5 ms to 60 ms
+ * @li Good loss robustness and packet loss concealment (PLC)
+ * @li Floating point and fixed-point implementation
+ *
+ * Documentation sections:
+ * @li @ref opus_encoder
+ * @li @ref opus_decoder
+ * @li @ref opus_repacketizer
+ * @li @ref opus_multistream
+ * @li @ref opus_libinfo
+ * @li @ref opus_custom
+ */
+
+/** @defgroup opus_encoder Opus Encoder
+ * @{
+ *
+ * @brief This page describes the process and functions used to encode Opus.
+ *
+ * Since Opus is a stateful codec, the encoding process starts with creating an encoder
+ * state. This can be done with:
+ *
+ * @code
+ * int error;
+ * OpusEncoder *enc;
+ * enc = opus_encoder_create(Fs, channels, application, &error);
+ * @endcode
+ *
+ * From this point, @c enc can be used for encoding an audio stream. An encoder state
+ * @b must @b not be used for more than one stream at the same time. Similarly, the encoder
+ * state @b must @b not be re-initialized for each frame.
+ *
+ * While opus_encoder_create() allocates memory for the state, it's also possible
+ * to initialize pre-allocated memory:
+ *
+ * @code
+ * int size;
+ * int error;
+ * OpusEncoder *enc;
+ * size = opus_encoder_get_size(channels);
+ * enc = malloc(size);
+ * error = opus_encoder_init(enc, Fs, channels, application);
+ * @endcode
+ *
+ * where opus_encoder_get_size() return the required size for the encoder state. Note that
+ * future versions of this code may change the size, so no assuptions should be made about it.
+ *
+ * The encoder state is always continuous in memory and only a shallow copy is sufficient
+ * to copy it (e.g. memcpy())
+ *
+ * It is possible to change some of the encoder's settings using the opus_encoder_ctl()
+ * interface. All these settings already default to the recommended value, so they should
+ * only be changed when necessary. The most common settings one may want to change are:
+ *
+ * @code
+ * opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate));
+ * opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
+ * opus_encoder_ctl(enc, OPUS_SET_SIGNAL(signal_type));
+ * @endcode
+ *
+ * where
+ *
+ * @arg bitrate is in bits per second (b/s)
+ * @arg complexity is a value from 1 to 10, where 1 is the lowest complexity and 10 is the highest
+ * @arg signal_type is either OPUS_AUTO (default), OPUS_SIGNAL_VOICE, or OPUS_SIGNAL_MUSIC
+ *
+ * See @ref opus_encoderctls and @ref opus_genericctls for a complete list of parameters that can be set or queried. Most parameters can be set or changed at any time during a stream.
+ *
+ * To encode a frame, opus_encode() or opus_encode_float() must be called with exactly one frame (2.5, 5, 10, 20, 40 or 60 ms) of audio data:
+ * @code
+ * len = opus_encode(enc, audio_frame, frame_size, packet, max_packet);
+ * @endcode
+ *
+ * where
+ * <ul>
+ * <li>audio_frame is the audio data in opus_int16 (or float for opus_encode_float())</li>
+ * <li>frame_size is the duration of the frame in samples (per channel)</li>
+ * <li>packet is the byte array to which the compressed data is written</li>
+ * <li>max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended).
+ * Do not use max_packet to control VBR target bitrate, instead use the #OPUS_SET_BITRATE CTL.</li>
+ * </ul>
+ *
+ * opus_encode() and opus_encode_float() return the number of bytes actually written to the packet.
+ * The return value <b>can be negative</b>, which indicates that an error has occurred. If the return value
+ * is 2 bytes or less, then the packet does not need to be transmitted (DTX).
+ *
+ * Once the encoder state if no longer needed, it can be destroyed with
+ *
+ * @code
+ * opus_encoder_destroy(enc);
+ * @endcode
+ *
+ * If the encoder was created with opus_encoder_init() rather than opus_encoder_create(),
+ * then no action is required aside from potentially freeing the memory that was manually
+ * allocated for it (calling free(enc) for the example above)
+ *
+ */
+
+/** Opus encoder state.
+ * This contains the complete state of an Opus encoder.
+ * It is position independent and can be freely copied.
+ * @see opus_encoder_create,opus_encoder_init
+ */
+typedef struct OpusEncoder OpusEncoder;
+
+/** Gets the size of an <code>OpusEncoder</code> structure.
+ * @param[in] channels <tt>int</tt>: Number of channels.
+ * This must be 1 or 2.
+ * @return The size in bytes.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels);
+
+/**
+ */
+
+/** Allocates and initializes an encoder state.
+ * There are three coding modes:
+ *
+ * @ref OPUS_APPLICATION_VOIP gives best quality at a given bitrate for voice
+ * signals. It enhances the input signal by high-pass filtering and
+ * emphasizing formants and harmonics. Optionally it includes in-band
+ * forward error correction to protect against packet loss. Use this
+ * mode for typical VoIP applications. Because of the enhancement,
+ * even at high bitrates the output may sound different from the input.
+ *
+ * @ref OPUS_APPLICATION_AUDIO gives best quality at a given bitrate for most
+ * non-voice signals like music. Use this mode for music and mixed
+ * (music/voice) content, broadcast, and applications requiring less
+ * than 15 ms of coding delay.
+ *
+ * @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY configures low-delay mode that
+ * disables the speech-optimized mode in exchange for slightly reduced delay.
+ * This mode can only be set on an newly initialized or freshly reset encoder
+ * because it changes the codec delay.
+ *
+ * This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution).
+ * @param [in] Fs <tt>opus_int32</tt>: Sampling rate of input signal (Hz)
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) in input signal
+ * @param [in] application <tt>int</tt>: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY)
+ * @param [out] error <tt>int*</tt>: @ref opus_errorcodes
+ * @note Regardless of the sampling rate and number channels selected, the Opus encoder
+ * can switch to a lower audio bandwidth or number of channels if the bitrate
+ * selected is too low. This also means that it is safe to always use 48 kHz stereo input
+ * and let the encoder optimize the encoding.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create(
+ opus_int32 Fs,
+ int channels,
+ int application,
+ int *error
+);
+
+/** Initializes a previously allocated encoder state
+ * The memory pointed to by st must be at least the size returned by opus_encoder_get_size().
+ * This is intended for applications which use their own allocator instead of malloc.
+ * @see opus_encoder_create(),opus_encoder_get_size()
+ * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+ * @param [in] st <tt>OpusEncoder*</tt>: Encoder state
+ * @param [in] Fs <tt>opus_int32</tt>: Sampling rate of input signal (Hz)
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) in input signal
+ * @param [in] application <tt>int</tt>: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY)
+ * @retval #OPUS_OK Success or @ref opus_errorcodes
+ */
+OPUS_EXPORT int opus_encoder_init(
+ OpusEncoder *st,
+ opus_int32 Fs,
+ int channels,
+ int application
+) OPUS_ARG_NONNULL(1);
+
+/** Encodes an Opus frame.
+ * @param [in] st <tt>OpusEncoder*</tt>: Encoder state
+ * @param [in] pcm <tt>opus_int16*</tt>: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16)
+ * @param [in] frame_size <tt>int</tt>: Number of samples per channel in the
+ * input signal.
+ * This must be an Opus frame size for
+ * the encoder's sampling rate.
+ * For example, at 48 kHz the permitted
+ * values are 120, 240, 480, 960, 1920,
+ * and 2880.
+ * Passing in a duration of less than
+ * 10 ms (480 samples at 48 kHz) will
+ * prevent the encoder from using the LPC
+ * or hybrid modes.
+ * @param [out] data <tt>unsigned char*</tt>: Output payload.
+ * This must contain storage for at
+ * least \a max_data_bytes.
+ * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+ * memory for the output
+ * payload. This may be
+ * used to impose an upper limit on
+ * the instant bitrate, but should
+ * not be used as the only bitrate
+ * control. Use #OPUS_SET_BITRATE to
+ * control the bitrate.
+ * @return The length of the encoded packet (in bytes) on success or a
+ * negative error code (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode(
+ OpusEncoder *st,
+ const opus_int16 *pcm,
+ int frame_size,
+ unsigned char *data,
+ opus_int32 max_data_bytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Encodes an Opus frame from floating point input.
+ * @param [in] st <tt>OpusEncoder*</tt>: Encoder state
+ * @param [in] pcm <tt>float*</tt>: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0.
+ * Samples with a range beyond +/-1.0 are supported but will
+ * be clipped by decoders using the integer API and should
+ * only be used if it is known that the far end supports
+ * extended dynamic range.
+ * length is frame_size*channels*sizeof(float)
+ * @param [in] frame_size <tt>int</tt>: Number of samples per channel in the
+ * input signal.
+ * This must be an Opus frame size for
+ * the encoder's sampling rate.
+ * For example, at 48 kHz the permitted
+ * values are 120, 240, 480, 960, 1920,
+ * and 2880.
+ * Passing in a duration of less than
+ * 10 ms (480 samples at 48 kHz) will
+ * prevent the encoder from using the LPC
+ * or hybrid modes.
+ * @param [out] data <tt>unsigned char*</tt>: Output payload.
+ * This must contain storage for at
+ * least \a max_data_bytes.
+ * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+ * memory for the output
+ * payload. This may be
+ * used to impose an upper limit on
+ * the instant bitrate, but should
+ * not be used as the only bitrate
+ * control. Use #OPUS_SET_BITRATE to
+ * control the bitrate.
+ * @return The length of the encoded packet (in bytes) on success or a
+ * negative error code (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float(
+ OpusEncoder *st,
+ const float *pcm,
+ int frame_size,
+ unsigned char *data,
+ opus_int32 max_data_bytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Frees an <code>OpusEncoder</code> allocated by opus_encoder_create().
+ * @param[in] st <tt>OpusEncoder*</tt>: State to be freed.
+ */
+OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st);
+
+/** Perform a CTL function on an Opus encoder.
+ *
+ * Generally the request and subsequent arguments are generated
+ * by a convenience macro.
+ * @param st <tt>OpusEncoder*</tt>: Encoder state.
+ * @param request This and all remaining parameters should be replaced by one
+ * of the convenience macros in @ref opus_genericctls or
+ * @ref opus_encoderctls.
+ * @see opus_genericctls
+ * @see opus_encoderctls
+ */
+OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);
+/**@}*/
+
+/** @defgroup opus_decoder Opus Decoder
+ * @{
+ *
+ * @brief This page describes the process and functions used to decode Opus.
+ *
+ * The decoding process also starts with creating a decoder
+ * state. This can be done with:
+ * @code
+ * int error;
+ * OpusDecoder *dec;
+ * dec = opus_decoder_create(Fs, channels, &error);
+ * @endcode
+ * where
+ * @li Fs is the sampling rate and must be 8000, 12000, 16000, 24000, or 48000
+ * @li channels is the number of channels (1 or 2)
+ * @li error will hold the error code in case of failure (or #OPUS_OK on success)
+ * @li the return value is a newly created decoder state to be used for decoding
+ *
+ * While opus_decoder_create() allocates memory for the state, it's also possible
+ * to initialize pre-allocated memory:
+ * @code
+ * int size;
+ * int error;
+ * OpusDecoder *dec;
+ * size = opus_decoder_get_size(channels);
+ * dec = malloc(size);
+ * error = opus_decoder_init(dec, Fs, channels);
+ * @endcode
+ * where opus_decoder_get_size() return the required size for the decoder state. Note that
+ * future versions of this code may change the size, so no assuptions should be made about it.
+ *
+ * The decoder state is always continuous in memory and only a shallow copy is sufficient
+ * to copy it (e.g. memcpy())
+ *
+ * To decode a frame, opus_decode() or opus_decode_float() must be called with a packet of compressed audio data:
+ * @code
+ * frame_size = opus_decode(dec, packet, len, decoded, max_size, 0);
+ * @endcode
+ * where
+ *
+ * @li packet is the byte array containing the compressed data
+ * @li len is the exact number of bytes contained in the packet
+ * @li decoded is the decoded audio data in opus_int16 (or float for opus_decode_float())
+ * @li max_size is the max duration of the frame in samples (per channel) that can fit into the decoded_frame array
+ *
+ * opus_decode() and opus_decode_float() return the number of samples (per channel) decoded from the packet.
+ * If that value is negative, then an error has occurred. This can occur if the packet is corrupted or if the audio
+ * buffer is too small to hold the decoded audio.
+ *
+ * Opus is a stateful codec with overlapping blocks and as a result Opus
+ * packets are not coded independently of each other. Packets must be
+ * passed into the decoder serially and in the correct order for a correct
+ * decode. Lost packets can be replaced with loss concealment by calling
+ * the decoder with a null pointer and zero length for the missing packet.
+ *
+ * A single codec state may only be accessed from a single thread at
+ * a time and any required locking must be performed by the caller. Separate
+ * streams must be decoded with separate decoder states and can be decoded
+ * in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK
+ * defined.
+ *
+ */
+
+/** Opus decoder state.
+ * This contains the complete state of an Opus decoder.
+ * It is position independent and can be freely copied.
+ * @see opus_decoder_create,opus_decoder_init
+ */
+typedef struct OpusDecoder OpusDecoder;
+
+/** Gets the size of an <code>OpusDecoder</code> structure.
+ * @param [in] channels <tt>int</tt>: Number of channels.
+ * This must be 1 or 2.
+ * @return The size in bytes.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_size(int channels);
+
+/** Allocates and initializes a decoder state.
+ * @param [in] Fs <tt>opus_int32</tt>: Sample rate to decode at (Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) to decode
+ * @param [out] error <tt>int*</tt>: #OPUS_OK Success or @ref opus_errorcodes
+ *
+ * Internally Opus stores data at 48000 Hz, so that should be the default
+ * value for Fs. However, the decoder can efficiently decode to buffers
+ * at 8, 12, 16, and 24 kHz so if for some reason the caller cannot use
+ * data at the full sample rate, or knows the compressed data doesn't
+ * use the full frequency range, it can request decoding at a reduced
+ * rate. Likewise, the decoder is capable of filling in either mono or
+ * interleaved stereo pcm buffers, at the caller's request.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusDecoder *opus_decoder_create(
+ opus_int32 Fs,
+ int channels,
+ int *error
+);
+
+/** Initializes a previously allocated decoder state.
+ * The state must be at least the size returned by opus_decoder_get_size().
+ * This is intended for applications which use their own allocator instead of malloc. @see opus_decoder_create,opus_decoder_get_size
+ * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+ * @param [in] st <tt>OpusDecoder*</tt>: Decoder state.
+ * @param [in] Fs <tt>opus_int32</tt>: Sampling rate to decode to (Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) to decode
+ * @retval #OPUS_OK Success or @ref opus_errorcodes
+ */
+OPUS_EXPORT int opus_decoder_init(
+ OpusDecoder *st,
+ opus_int32 Fs,
+ int channels
+) OPUS_ARG_NONNULL(1);
+
+/** Decode an Opus packet.
+ * @param [in] st <tt>OpusDecoder*</tt>: Decoder state
+ * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
+ * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload*
+ * @param [out] pcm <tt>opus_int16*</tt>: Output signal (interleaved if 2 channels). length
+ * is frame_size*channels*sizeof(opus_int16)
+ * @param [in] frame_size Number of samples per channel of available space in \a pcm.
+ * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will
+ * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1),
+ * then frame_size needs to be exactly the duration of audio that is missing, otherwise the
+ * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and
+ * FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms.
+ * @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be
+ * decoded. If no such data is available, the frame is decoded as if it were lost.
+ * @return Number of decoded samples or @ref opus_errorcodes
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode(
+ OpusDecoder *st,
+ const unsigned char *data,
+ opus_int32 len,
+ opus_int16 *pcm,
+ int frame_size,
+ int decode_fec
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Decode an Opus packet with floating point output.
+ * @param [in] st <tt>OpusDecoder*</tt>: Decoder state
+ * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
+ * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload
+ * @param [out] pcm <tt>float*</tt>: Output signal (interleaved if 2 channels). length
+ * is frame_size*channels*sizeof(float)
+ * @param [in] frame_size Number of samples per channel of available space in \a pcm.
+ * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will
+ * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1),
+ * then frame_size needs to be exactly the duration of audio that is missing, otherwise the
+ * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and
+ * FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms.
+ * @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be
+ * decoded. If no such data is available the frame is decoded as if it were lost.
+ * @return Number of decoded samples or @ref opus_errorcodes
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode_float(
+ OpusDecoder *st,
+ const unsigned char *data,
+ opus_int32 len,
+ float *pcm,
+ int frame_size,
+ int decode_fec
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Perform a CTL function on an Opus decoder.
+ *
+ * Generally the request and subsequent arguments are generated
+ * by a convenience macro.
+ * @param st <tt>OpusDecoder*</tt>: Decoder state.
+ * @param request This and all remaining parameters should be replaced by one
+ * of the convenience macros in @ref opus_genericctls or
+ * @ref opus_decoderctls.
+ * @see opus_genericctls
+ * @see opus_decoderctls
+ */
+OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NONNULL(1);
+
+/** Frees an <code>OpusDecoder</code> allocated by opus_decoder_create().
+ * @param[in] st <tt>OpusDecoder*</tt>: State to be freed.
+ */
+OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st);
+
+/** Parse an opus packet into one or more frames.
+ * Opus_decode will perform this operation internally so most applications do
+ * not need to use this function.
+ * This function does not copy the frames, the returned pointers are pointers into
+ * the input packet.
+ * @param [in] data <tt>char*</tt>: Opus packet to be parsed
+ * @param [in] len <tt>opus_int32</tt>: size of data
+ * @param [out] out_toc <tt>char*</tt>: TOC pointer
+ * @param [out] frames <tt>char*[48]</tt> encapsulated frames
+ * @param [out] size <tt>opus_int16[48]</tt> sizes of the encapsulated frames
+ * @param [out] payload_offset <tt>int*</tt>: return the position of the payload within the packet (in bytes)
+ * @return number of frames
+ */
+OPUS_EXPORT int opus_packet_parse(
+ const unsigned char *data,
+ opus_int32 len,
+ unsigned char *out_toc,
+ const unsigned char *frames[48],
+ opus_int16 size[48],
+ int *payload_offset
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Gets the bandwidth of an Opus packet.
+ * @param [in] data <tt>char*</tt>: Opus packet
+ * @retval OPUS_BANDWIDTH_NARROWBAND Narrowband (4kHz bandpass)
+ * @retval OPUS_BANDWIDTH_MEDIUMBAND Mediumband (6kHz bandpass)
+ * @retval OPUS_BANDWIDTH_WIDEBAND Wideband (8kHz bandpass)
+ * @retval OPUS_BANDWIDTH_SUPERWIDEBAND Superwideband (12kHz bandpass)
+ * @retval OPUS_BANDWIDTH_FULLBAND Fullband (20kHz bandpass)
+ * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_bandwidth(const unsigned char *data)
+OPUS_ARG_NONNULL(1);
+
+/** Gets the number of samples per frame from an Opus packet.
+ * @param [in] data <tt>char*</tt>: Opus packet.
+ * This must contain at least one byte of
+ * data.
+ * @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz.
+ * This must be a multiple of 400, or
+ * inaccurate results will be returned.
+ * @return Number of samples per frame.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_samples_per_frame(const unsigned char *data,
+ opus_int32 Fs) OPUS_ARG_NONNULL(1);
+
+/** Gets the number of channels from an Opus packet.
+ * @param [in] data <tt>char*</tt>: Opus packet
+ * @return Number of channels
+ * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_channels(const unsigned char *data)
+OPUS_ARG_NONNULL(1);
+
+/** Gets the number of frames in an Opus packet.
+ * @param [in] packet <tt>char*</tt>: Opus packet
+ * @param [in] len <tt>opus_int32</tt>: Length of packet
+ * @return Number of frames
+ * @retval OPUS_BAD_ARG Insufficient data was passed to the function
+ * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[],
+ opus_int32 len) OPUS_ARG_NONNULL(1);
+
+/** Gets the number of samples of an Opus packet.
+ * @param [in] packet <tt>char*</tt>: Opus packet
+ * @param [in] len <tt>opus_int32</tt>: Length of packet
+ * @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz.
+ * This must be a multiple of 400, or
+ * inaccurate results will be returned.
+ * @return Number of samples
+ * @retval OPUS_BAD_ARG Insufficient data was passed to the function
+ * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[],
+ opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1);
+
+/** Gets the number of samples of an Opus packet.
+ * @param [in] dec <tt>OpusDecoder*</tt>: Decoder state
+ * @param [in] packet <tt>char*</tt>: Opus packet
+ * @param [in] len <tt>opus_int32</tt>: Length of packet
+ * @return Number of samples
+ * @retval OPUS_BAD_ARG Insufficient data was passed to the function
+ * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_nb_samples(const OpusDecoder *dec,
+ const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
+
+/** Applies soft-clipping to bring a float signal within the [-1,1] range. If
+ * the signal is already in that range, nothing is done. If there are values
+ * outside of [-1,1], then the signal is clipped as smoothly as possible to
+ * both fit in the range and avoid creating excessive distortion in the
+ * process.
+ * @param [in,out] pcm <tt>float*</tt>: Input PCM and modified PCM
+ * @param [in] frame_size <tt>int</tt> Number of samples per channel to process
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @param [in,out] softclip_mem <tt>float*</tt>: State memory for the soft clipping process (one float per channel, initialized to zero)
+ */
+OPUS_EXPORT void opus_pcm_soft_clip(float *pcm, int frame_size, int channels, float *softclip_mem);
+
+
+/**@}*/
+
+/** @defgroup opus_repacketizer Repacketizer
+ * @{
+ *
+ * The repacketizer can be used to merge multiple Opus packets into a single
+ * packet or alternatively to split Opus packets that have previously been
+ * merged. Splitting valid Opus packets is always guaranteed to succeed,
+ * whereas merging valid packets only succeeds if all frames have the same
+ * mode, bandwidth, and frame size, and when the total duration of the merged
+ * packet is no more than 120 ms. The 120 ms limit comes from the
+ * specification and limits decoder memory requirements at a point where
+ * framing overhead becomes negligible.
+ *
+ * The repacketizer currently only operates on elementary Opus
+ * streams. It will not manipualte multistream packets successfully, except in
+ * the degenerate case where they consist of data from a single stream.
+ *
+ * The repacketizing process starts with creating a repacketizer state, either
+ * by calling opus_repacketizer_create() or by allocating the memory yourself,
+ * e.g.,
+ * @code
+ * OpusRepacketizer *rp;
+ * rp = (OpusRepacketizer*)malloc(opus_repacketizer_get_size());
+ * if (rp != NULL)
+ * opus_repacketizer_init(rp);
+ * @endcode
+ *
+ * Then the application should submit packets with opus_repacketizer_cat(),
+ * extract new packets with opus_repacketizer_out() or
+ * opus_repacketizer_out_range(), and then reset the state for the next set of
+ * input packets via opus_repacketizer_init().
+ *
+ * For example, to split a sequence of packets into individual frames:
+ * @code
+ * unsigned char *data;
+ * int len;
+ * while (get_next_packet(&data, &len))
+ * {
+ * unsigned char out[1276];
+ * opus_int32 out_len;
+ * int nb_frames;
+ * int err;
+ * int i;
+ * err = opus_repacketizer_cat(rp, data, len);
+ * if (err != OPUS_OK)
+ * {
+ * release_packet(data);
+ * return err;
+ * }
+ * nb_frames = opus_repacketizer_get_nb_frames(rp);
+ * for (i = 0; i < nb_frames; i++)
+ * {
+ * out_len = opus_repacketizer_out_range(rp, i, i+1, out, sizeof(out));
+ * if (out_len < 0)
+ * {
+ * release_packet(data);
+ * return (int)out_len;
+ * }
+ * output_next_packet(out, out_len);
+ * }
+ * opus_repacketizer_init(rp);
+ * release_packet(data);
+ * }
+ * @endcode
+ *
+ * Alternatively, to combine a sequence of frames into packets that each
+ * contain up to <code>TARGET_DURATION_MS</code> milliseconds of data:
+ * @code
+ * // The maximum number of packets with duration TARGET_DURATION_MS occurs
+ * // when the frame size is 2.5 ms, for a total of (TARGET_DURATION_MS*2/5)
+ * // packets.
+ * unsigned char *data[(TARGET_DURATION_MS*2/5)+1];
+ * opus_int32 len[(TARGET_DURATION_MS*2/5)+1];
+ * int nb_packets;
+ * unsigned char out[1277*(TARGET_DURATION_MS*2/2)];
+ * opus_int32 out_len;
+ * int prev_toc;
+ * nb_packets = 0;
+ * while (get_next_packet(data+nb_packets, len+nb_packets))
+ * {
+ * int nb_frames;
+ * int err;
+ * nb_frames = opus_packet_get_nb_frames(data[nb_packets], len[nb_packets]);
+ * if (nb_frames < 1)
+ * {
+ * release_packets(data, nb_packets+1);
+ * return nb_frames;
+ * }
+ * nb_frames += opus_repacketizer_get_nb_frames(rp);
+ * // If adding the next packet would exceed our target, or it has an
+ * // incompatible TOC sequence, output the packets we already have before
+ * // submitting it.
+ * // N.B., The nb_packets > 0 check ensures we've submitted at least one
+ * // packet since the last call to opus_repacketizer_init(). Otherwise a
+ * // single packet longer than TARGET_DURATION_MS would cause us to try to
+ * // output an (invalid) empty packet. It also ensures that prev_toc has
+ * // been set to a valid value. Additionally, len[nb_packets] > 0 is
+ * // guaranteed by the call to opus_packet_get_nb_frames() above, so the
+ * // reference to data[nb_packets][0] should be valid.
+ * if (nb_packets > 0 && (
+ * ((prev_toc & 0xFC) != (data[nb_packets][0] & 0xFC)) ||
+ * opus_packet_get_samples_per_frame(data[nb_packets], 48000)*nb_frames >
+ * TARGET_DURATION_MS*48))
+ * {
+ * out_len = opus_repacketizer_out(rp, out, sizeof(out));
+ * if (out_len < 0)
+ * {
+ * release_packets(data, nb_packets+1);
+ * return (int)out_len;
+ * }
+ * output_next_packet(out, out_len);
+ * opus_repacketizer_init(rp);
+ * release_packets(data, nb_packets);
+ * data[0] = data[nb_packets];
+ * len[0] = len[nb_packets];
+ * nb_packets = 0;
+ * }
+ * err = opus_repacketizer_cat(rp, data[nb_packets], len[nb_packets]);
+ * if (err != OPUS_OK)
+ * {
+ * release_packets(data, nb_packets+1);
+ * return err;
+ * }
+ * prev_toc = data[nb_packets][0];
+ * nb_packets++;
+ * }
+ * // Output the final, partial packet.
+ * if (nb_packets > 0)
+ * {
+ * out_len = opus_repacketizer_out(rp, out, sizeof(out));
+ * release_packets(data, nb_packets);
+ * if (out_len < 0)
+ * return (int)out_len;
+ * output_next_packet(out, out_len);
+ * }
+ * @endcode
+ *
+ * An alternate way of merging packets is to simply call opus_repacketizer_cat()
+ * unconditionally until it fails. At that point, the merged packet can be
+ * obtained with opus_repacketizer_out() and the input packet for which
+ * opus_repacketizer_cat() needs to be re-added to a newly reinitialized
+ * repacketizer state.
+ */
+
+typedef struct OpusRepacketizer OpusRepacketizer;
+
+/** Gets the size of an <code>OpusRepacketizer</code> structure.
+ * @return The size in bytes.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_size(void);
+
+/** (Re)initializes a previously allocated repacketizer state.
+ * The state must be at least the size returned by opus_repacketizer_get_size().
+ * This can be used for applications which use their own allocator instead of
+ * malloc().
+ * It must also be called to reset the queue of packets waiting to be
+ * repacketized, which is necessary if the maximum packet duration of 120 ms
+ * is reached or if you wish to submit packets with a different Opus
+ * configuration (coding mode, audio bandwidth, frame size, or channel count).
+ * Failure to do so will prevent a new packet from being added with
+ * opus_repacketizer_cat().
+ * @see opus_repacketizer_create
+ * @see opus_repacketizer_get_size
+ * @see opus_repacketizer_cat
+ * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state to
+ * (re)initialize.
+ * @return A pointer to the same repacketizer state that was passed in.
+ */
+OPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1);
+
+/** Allocates memory and initializes the new repacketizer with
+ * opus_repacketizer_init().
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusRepacketizer *opus_repacketizer_create(void);
+
+/** Frees an <code>OpusRepacketizer</code> allocated by
+ * opus_repacketizer_create().
+ * @param[in] rp <tt>OpusRepacketizer*</tt>: State to be freed.
+ */
+OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp);
+
+/** Add a packet to the current repacketizer state.
+ * This packet must match the configuration of any packets already submitted
+ * for repacketization since the last call to opus_repacketizer_init().
+ * This means that it must have the same coding mode, audio bandwidth, frame
+ * size, and channel count.
+ * This can be checked in advance by examining the top 6 bits of the first
+ * byte of the packet, and ensuring they match the top 6 bits of the first
+ * byte of any previously submitted packet.
+ * The total duration of audio in the repacketizer state also must not exceed
+ * 120 ms, the maximum duration of a single packet, after adding this packet.
+ *
+ * The contents of the current repacketizer state can be extracted into new
+ * packets using opus_repacketizer_out() or opus_repacketizer_out_range().
+ *
+ * In order to add a packet with a different configuration or to add more
+ * audio beyond 120 ms, you must clear the repacketizer state by calling
+ * opus_repacketizer_init().
+ * If a packet is too large to add to the current repacketizer state, no part
+ * of it is added, even if it contains multiple frames, some of which might
+ * fit.
+ * If you wish to be able to add parts of such packets, you should first use
+ * another repacketizer to split the packet into pieces and add them
+ * individually.
+ * @see opus_repacketizer_out_range
+ * @see opus_repacketizer_out
+ * @see opus_repacketizer_init
+ * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state to which to
+ * add the packet.
+ * @param[in] data <tt>const unsigned char*</tt>: The packet data.
+ * The application must ensure
+ * this pointer remains valid
+ * until the next call to
+ * opus_repacketizer_init() or
+ * opus_repacketizer_destroy().
+ * @param len <tt>opus_int32</tt>: The number of bytes in the packet data.
+ * @return An error code indicating whether or not the operation succeeded.
+ * @retval #OPUS_OK The packet's contents have been added to the repacketizer
+ * state.
+ * @retval #OPUS_INVALID_PACKET The packet did not have a valid TOC sequence,
+ * the packet's TOC sequence was not compatible
+ * with previously submitted packets (because
+ * the coding mode, audio bandwidth, frame size,
+ * or channel count did not match), or adding
+ * this packet would increase the total amount of
+ * audio stored in the repacketizer state to more
+ * than 120 ms.
+ */
+OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data,
+ opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
+
+
+/** Construct a new packet from data previously submitted to the repacketizer
+ * state via opus_repacketizer_cat().
+ * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state from which to
+ * construct the new packet.
+ * @param begin <tt>int</tt>: The index of the first frame in the current
+ * repacketizer state to include in the output.
+ * @param end <tt>int</tt>: One past the index of the last frame in the
+ * current repacketizer state to include in the
+ * output.
+ * @param[out] data <tt>const unsigned char*</tt>: The buffer in which to
+ * store the output packet.
+ * @param maxlen <tt>opus_int32</tt>: The maximum number of bytes to store in
+ * the output buffer. In order to guarantee
+ * success, this should be at least
+ * <code>1276</code> for a single frame,
+ * or for multiple frames,
+ * <code>1277*(end-begin)</code>.
+ * However, <code>1*(end-begin)</code> plus
+ * the size of all packet data submitted to
+ * the repacketizer since the last call to
+ * opus_repacketizer_init() or
+ * opus_repacketizer_create() is also
+ * sufficient, and possibly much smaller.
+ * @return The total size of the output packet on success, or an error code
+ * on failure.
+ * @retval #OPUS_BAD_ARG <code>[begin,end)</code> was an invalid range of
+ * frames (begin < 0, begin >= end, or end >
+ * opus_repacketizer_get_nb_frames()).
+ * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the
+ * complete output packet.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp,
+ int begin, int end, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Return the total number of frames contained in packet data submitted to
+ * the repacketizer state so far via opus_repacketizer_cat() since the last
+ * call to opus_repacketizer_init() or opus_repacketizer_create().
+ * This defines the valid range of packets that can be extracted with
+ * opus_repacketizer_out_range() or opus_repacketizer_out().
+ * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state containing the
+ * frames.
+ * @return The total number of frames contained in the packet data submitted
+ * to the repacketizer state.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(
+ OpusRepacketizer *rp) OPUS_ARG_NONNULL(1);
+
+/** Construct a new packet from data previously submitted to the repacketizer
+ * state via opus_repacketizer_cat().
+ * This is a convenience routine that return all the data submitted so far
+ * in a single packet.
+ * It is equivalent to calling
+ * @code
+ * opus_repacketizer_out_range(rp, 0, opus_repacketizer_get_nb_frames(rp),
+ * data, maxlen)
+ * @endcode
+ * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state from which to
+ * construct the new packet.
+ * @param[out] data <tt>const unsigned char*</tt>: The buffer in which to
+ * store the output packet.
+ * @param maxlen <tt>opus_int32</tt>: The maximum number of bytes to store in
+ * the output buffer. In order to guarantee
+ * success, this should be at least
+ * <code>1277*opus_repacketizer_get_nb_frames(rp)</code>.
+ * However,
+ * <code>1*opus_repacketizer_get_nb_frames(rp)</code>
+ * plus the size of all packet data
+ * submitted to the repacketizer since the
+ * last call to opus_repacketizer_init() or
+ * opus_repacketizer_create() is also
+ * sufficient, and possibly much smaller.
+ * @return The total size of the output packet on success, or an error code
+ * on failure.
+ * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the
+ * complete output packet.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp,
+ unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1);
+
+/** Pads a given Opus packet to a larger size (possibly changing the TOC sequence).
+ * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
+ * packet to pad.
+ * @param len <tt>opus_int32</tt>: The size of the packet.
+ * This must be at least 1.
+ * @param new_len <tt>opus_int32</tt>: The desired size of the packet after padding.
+ * This must be at least as large as len.
+ * @return an error code
+ * @retval #OPUS_OK \a on success.
+ * @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len.
+ * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
+ */
+OPUS_EXPORT int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len);
+
+/** Remove all padding from a given Opus packet and rewrite the TOC sequence to
+ * minimize space usage.
+ * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
+ * packet to strip.
+ * @param len <tt>opus_int32</tt>: The size of the packet.
+ * This must be at least 1.
+ * @return The new size of the output packet on success, or an error code
+ * on failure.
+ * @retval #OPUS_BAD_ARG \a len was less than 1.
+ * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_packet_unpad(unsigned char *data,
+ opus_int32 len);
+
+/** Pads a given Opus multi-stream packet to a larger size (possibly changing the TOC sequence).
+ * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
+ * packet to pad.
+ * @param len <tt>opus_int32</tt>: The size of the packet.
+ * This must be at least 1.
+ * @param new_len <tt>opus_int32</tt>: The desired size of the packet after padding.
+ * This must be at least 1.
+ * @param nb_streams <tt>opus_int32</tt>: The number of streams (not channels) in the packet.
+ * This must be at least as large as len.
+ * @return an error code
+ * @retval #OPUS_OK \a on success.
+ * @retval #OPUS_BAD_ARG \a len was less than 1.
+ * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
+ */
+OPUS_EXPORT int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len,
+ int nb_streams);
+
+/** Remove all padding from a given Opus multi-stream packet and rewrite the TOC sequence to
+ * minimize space usage.
+ * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
+ * packet to strip.
+ * @param len <tt>opus_int32</tt>: The size of the packet.
+ * This must be at least 1.
+ * @param nb_streams <tt>opus_int32</tt>: The number of streams (not channels) in the packet.
+ * This must be at least 1.
+ * @return The new size of the output packet on success, or an error code
+ * on failure.
+ * @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len.
+ * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_packet_unpad(unsigned char *data,
+ opus_int32 len, int nb_streams);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPUS_H */
diff --git a/src/app/google_rcu/opus/opus_custom.h b/src/app/google_rcu/opus/opus_custom.h
new file mode 100644
index 0000000..206261f
--- /dev/null
+++ b/src/app/google_rcu/opus/opus_custom.h
@@ -0,0 +1,345 @@
+/* Copyright (c) 2007-2008 CSIRO
+ Copyright (c) 2007-2009 Xiph.Org Foundation
+ Copyright (c) 2008-2012 Gregory Maxwell
+ Written by Jean-Marc Valin and Gregory Maxwell */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ @file opus_custom.h
+ @brief Opus-Custom reference implementation API
+ */
+
+#ifndef OPUS_CUSTOM_H
+#define OPUS_CUSTOM_H
+
+#include "opus_defines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef CUSTOM_MODES
+# define OPUS_CUSTOM_EXPORT OPUS_EXPORT
+# define OPUS_CUSTOM_EXPORT_STATIC OPUS_EXPORT
+#else
+# define OPUS_CUSTOM_EXPORT
+# ifdef OPUS_BUILD
+# define OPUS_CUSTOM_EXPORT_STATIC static OPUS_INLINE
+# else
+# define OPUS_CUSTOM_EXPORT_STATIC
+# endif
+#endif
+
+/** @defgroup opus_custom Opus Custom
+ * @{
+ * Opus Custom is an optional part of the Opus specification and
+ * reference implementation which uses a distinct API from the regular
+ * API and supports frame sizes that are not normally supported.\ Use
+ * of Opus Custom is discouraged for all but very special applications
+ * for which a frame size different from 2.5, 5, 10, or 20 ms is needed
+ * (for either complexity or latency reasons) and where interoperability
+ * is less important.
+ *
+ * In addition to the interoperability limitations the use of Opus custom
+ * disables a substantial chunk of the codec and generally lowers the
+ * quality available at a given bitrate. Normally when an application needs
+ * a different frame size from the codec it should buffer to match the
+ * sizes but this adds a small amount of delay which may be important
+ * in some very low latency applications. Some transports (especially
+ * constant rate RF transports) may also work best with frames of
+ * particular durations.
+ *
+ * Libopus only supports custom modes if they are enabled at compile time.
+ *
+ * The Opus Custom API is similar to the regular API but the
+ * @ref opus_encoder_create and @ref opus_decoder_create calls take
+ * an additional mode parameter which is a structure produced by
+ * a call to @ref opus_custom_mode_create. Both the encoder and decoder
+ * must create a mode using the same sample rate (fs) and frame size
+ * (frame size) so these parameters must either be signaled out of band
+ * or fixed in a particular implementation.
+ *
+ * Similar to regular Opus the custom modes support on the fly frame size
+ * switching, but the sizes available depend on the particular frame size in
+ * use. For some initial frame sizes on a single on the fly size is available.
+ */
+
+/** Contains the state of an encoder. One encoder state is needed
+ for each stream. It is initialized once at the beginning of the
+ stream. Do *not* re-initialize the state for every frame.
+ @brief Encoder state
+ */
+typedef struct OpusCustomEncoder OpusCustomEncoder;
+
+/** State of the decoder. One decoder state is needed for each stream.
+ It is initialized once at the beginning of the stream. Do *not*
+ re-initialize the state for every frame.
+ @brief Decoder state
+ */
+typedef struct OpusCustomDecoder OpusCustomDecoder;
+
+/** The mode contains all the information necessary to create an
+ encoder. Both the encoder and decoder need to be initialized
+ with exactly the same mode, otherwise the output will be
+ corrupted.
+ @brief Mode configuration
+ */
+typedef struct OpusCustomMode OpusCustomMode;
+
+/** Creates a new mode struct. This will be passed to an encoder or
+ * decoder. The mode MUST NOT BE DESTROYED until the encoders and
+ * decoders that use it are destroyed as well.
+ * @param [in] Fs <tt>int</tt>: Sampling rate (8000 to 96000 Hz)
+ * @param [in] frame_size <tt>int</tt>: Number of samples (per channel) to encode in each
+ * packet (64 - 1024, prime factorization must contain zero or more 2s, 3s, or 5s and no other primes)
+ * @param [out] error <tt>int*</tt>: Returned error code (if NULL, no error will be returned)
+ * @return A newly created mode
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomMode *opus_custom_mode_create(opus_int32 Fs,
+ int frame_size, int *error);
+
+/** Destroys a mode struct. Only call this after all encoders and
+ * decoders using this mode are destroyed as well.
+ * @param [in] mode <tt>OpusCustomMode*</tt>: Mode to be freed.
+ */
+OPUS_CUSTOM_EXPORT void opus_custom_mode_destroy(OpusCustomMode *mode);
+
+
+#if !defined(OPUS_BUILD) || defined(CELT_ENCODER_C)
+
+/* Encoder */
+/** Gets the size of an OpusCustomEncoder structure.
+ * @param [in] mode <tt>OpusCustomMode *</tt>: Mode configuration
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @return size
+ */
+OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_encoder_get_size(
+ const OpusCustomMode *mode,
+ int channels
+) OPUS_ARG_NONNULL(1);
+
+# ifdef CUSTOM_MODES
+/** Initializes a previously allocated encoder state
+ * The memory pointed to by st must be the size returned by opus_custom_encoder_get_size.
+ * This is intended for applications which use their own allocator instead of malloc.
+ * @see opus_custom_encoder_create(),opus_custom_encoder_get_size()
+ * To reset a previously initialized state use the OPUS_RESET_STATE CTL.
+ * @param [in] st <tt>OpusCustomEncoder*</tt>: Encoder state
+ * @param [in] mode <tt>OpusCustomMode *</tt>: Contains all the information about the characteristics of
+ * the stream (must be the same characteristics as used for the
+ * decoder)
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @return OPUS_OK Success or @ref opus_errorcodes
+ */
+OPUS_CUSTOM_EXPORT int opus_custom_encoder_init(
+ OpusCustomEncoder *st,
+ const OpusCustomMode *mode,
+ int channels
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
+# endif
+#endif
+
+
+/** Creates a new encoder state. Each stream needs its own encoder
+ * state (can't be shared across simultaneous streams).
+ * @param [in] mode <tt>OpusCustomMode*</tt>: Contains all the information about the characteristics of
+ * the stream (must be the same characteristics as used for the
+ * decoder)
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @param [out] error <tt>int*</tt>: return an error code
+ * @return Newly created encoder state.
+*/
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomEncoder *opus_custom_encoder_create(
+ const OpusCustomMode *mode,
+ int channels,
+ int *error
+) OPUS_ARG_NONNULL(1);
+
+
+/** Destroys a an encoder state.
+ * @param[in] st <tt>OpusCustomEncoder*</tt>: State to be freed.
+ */
+OPUS_CUSTOM_EXPORT void opus_custom_encoder_destroy(OpusCustomEncoder *st);
+
+/** Encodes a frame of audio.
+ * @param [in] st <tt>OpusCustomEncoder*</tt>: Encoder state
+ * @param [in] pcm <tt>float*</tt>: PCM audio in float format, with a normal range of +/-1.0.
+ * Samples with a range beyond +/-1.0 are supported but will
+ * be clipped by decoders using the integer API and should
+ * only be used if it is known that the far end supports
+ * extended dynamic range. There must be exactly
+ * frame_size samples per channel.
+ * @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal
+ * @param [out] compressed <tt>char *</tt>: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long.
+ * @param [in] maxCompressedBytes <tt>int</tt>: Maximum number of bytes to use for compressing the frame
+ * (can change from one frame to another)
+ * @return Number of bytes written to "compressed".
+ * If negative, an error has occurred (see error codes). It is IMPORTANT that
+ * the length returned be somehow transmitted to the decoder. Otherwise, no
+ * decoding is possible.
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode_float(
+ OpusCustomEncoder *st,
+ const float *pcm,
+ int frame_size,
+ unsigned char *compressed,
+ int maxCompressedBytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Encodes a frame of audio.
+ * @param [in] st <tt>OpusCustomEncoder*</tt>: Encoder state
+ * @param [in] pcm <tt>opus_int16*</tt>: PCM audio in signed 16-bit format (native endian).
+ * There must be exactly frame_size samples per channel.
+ * @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal
+ * @param [out] compressed <tt>char *</tt>: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long.
+ * @param [in] maxCompressedBytes <tt>int</tt>: Maximum number of bytes to use for compressing the frame
+ * (can change from one frame to another)
+ * @return Number of bytes written to "compressed".
+ * If negative, an error has occurred (see error codes). It is IMPORTANT that
+ * the length returned be somehow transmitted to the decoder. Otherwise, no
+ * decoding is possible.
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode(
+ OpusCustomEncoder *st,
+ const opus_int16 *pcm,
+ int frame_size,
+ unsigned char *compressed,
+ int maxCompressedBytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Perform a CTL function on an Opus custom encoder.
+ *
+ * Generally the request and subsequent arguments are generated
+ * by a convenience macro.
+ * @see opus_encoderctls
+ */
+OPUS_CUSTOM_EXPORT int opus_custom_encoder_ctl(OpusCustomEncoder *OPUS_RESTRICT st, int request,
+ ...) OPUS_ARG_NONNULL(1);
+
+
+#if !defined(OPUS_BUILD) || defined(CELT_DECODER_C)
+/* Decoder */
+
+/** Gets the size of an OpusCustomDecoder structure.
+ * @param [in] mode <tt>OpusCustomMode *</tt>: Mode configuration
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @return size
+ */
+OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_decoder_get_size(
+ const OpusCustomMode *mode,
+ int channels
+) OPUS_ARG_NONNULL(1);
+
+/** Initializes a previously allocated decoder state
+ * The memory pointed to by st must be the size returned by opus_custom_decoder_get_size.
+ * This is intended for applications which use their own allocator instead of malloc.
+ * @see opus_custom_decoder_create(),opus_custom_decoder_get_size()
+ * To reset a previously initialized state use the OPUS_RESET_STATE CTL.
+ * @param [in] st <tt>OpusCustomDecoder*</tt>: Decoder state
+ * @param [in] mode <tt>OpusCustomMode *</tt>: Contains all the information about the characteristics of
+ * the stream (must be the same characteristics as used for the
+ * encoder)
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @return OPUS_OK Success or @ref opus_errorcodes
+ */
+OPUS_CUSTOM_EXPORT_STATIC int opus_custom_decoder_init(
+ OpusCustomDecoder *st,
+ const OpusCustomMode *mode,
+ int channels
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
+
+#endif
+
+
+/** Creates a new decoder state. Each stream needs its own decoder state (can't
+ * be shared across simultaneous streams).
+ * @param [in] mode <tt>OpusCustomMode</tt>: Contains all the information about the characteristics of the
+ * stream (must be the same characteristics as used for the encoder)
+ * @param [in] channels <tt>int</tt>: Number of channels
+ * @param [out] error <tt>int*</tt>: return an error code
+ * @return Newly created decoder state.
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomDecoder *opus_custom_decoder_create(
+ const OpusCustomMode *mode,
+ int channels,
+ int *error
+) OPUS_ARG_NONNULL(1);
+
+/** Destroys a decoder state.
+ * @param[in] st <tt>OpusCustomDecoder*</tt>: State to be freed.
+ */
+OPUS_CUSTOM_EXPORT void opus_custom_decoder_destroy(OpusCustomDecoder *st);
+
+/** Decode an opus custom frame with floating point output
+ * @param [in] st <tt>OpusCustomDecoder*</tt>: Decoder state
+ * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
+ * @param [in] len <tt>int</tt>: Number of bytes in payload
+ * @param [out] pcm <tt>float*</tt>: Output signal (interleaved if 2 channels). length
+ * is frame_size*channels*sizeof(float)
+ * @param [in] frame_size Number of samples per channel of available space in *pcm.
+ * @return Number of decoded samples or @ref opus_errorcodes
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode_float(
+ OpusCustomDecoder *st,
+ const unsigned char *data,
+ int len,
+ float *pcm,
+ int frame_size
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Decode an opus custom frame
+ * @param [in] st <tt>OpusCustomDecoder*</tt>: Decoder state
+ * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
+ * @param [in] len <tt>int</tt>: Number of bytes in payload
+ * @param [out] pcm <tt>opus_int16*</tt>: Output signal (interleaved if 2 channels). length
+ * is frame_size*channels*sizeof(opus_int16)
+ * @param [in] frame_size Number of samples per channel of available space in *pcm.
+ * @return Number of decoded samples or @ref opus_errorcodes
+ */
+OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode(
+ OpusCustomDecoder *st,
+ const unsigned char *data,
+ int len,
+ opus_int16 *pcm,
+ int frame_size
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Perform a CTL function on an Opus custom decoder.
+ *
+ * Generally the request and subsequent arguments are generated
+ * by a convenience macro.
+ * @see opus_genericctls
+ */
+OPUS_CUSTOM_EXPORT int opus_custom_decoder_ctl(OpusCustomDecoder *OPUS_RESTRICT st, int request,
+ ...) OPUS_ARG_NONNULL(1);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPUS_CUSTOM_H */
diff --git a/src/app/google_rcu/opus/opus_defines.h b/src/app/google_rcu/opus/opus_defines.h
new file mode 100644
index 0000000..16ef110
--- /dev/null
+++ b/src/app/google_rcu/opus/opus_defines.h
@@ -0,0 +1,753 @@
+/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited
+ Written by Jean-Marc Valin and Koen Vos */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * @file opus_defines.h
+ * @brief Opus reference implementation constants
+ */
+
+#ifndef OPUS_DEFINES_H
+#define OPUS_DEFINES_H
+
+#include "opus_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup opus_errorcodes Error codes
+ * @{
+ */
+/** No error @hideinitializer*/
+#define OPUS_OK 0
+/** One or more invalid/out of range arguments @hideinitializer*/
+#define OPUS_BAD_ARG -1
+/** Not enough bytes allocated in the buffer @hideinitializer*/
+#define OPUS_BUFFER_TOO_SMALL -2
+/** An internal error was detected @hideinitializer*/
+#define OPUS_INTERNAL_ERROR -3
+/** The compressed data passed is corrupted @hideinitializer*/
+#define OPUS_INVALID_PACKET -4
+/** Invalid/unsupported request number @hideinitializer*/
+#define OPUS_UNIMPLEMENTED -5
+/** An encoder or decoder structure is invalid or already freed @hideinitializer*/
+#define OPUS_INVALID_STATE -6
+/** Memory allocation has failed @hideinitializer*/
+#define OPUS_ALLOC_FAIL -7
+/**@}*/
+
+/** @cond OPUS_INTERNAL_DOC */
+/**Export control for opus functions */
+
+#ifndef OPUS_EXPORT
+# if defined(WIN32)
+# if defined(OPUS_BUILD) && defined(DLL_EXPORT)
+# define OPUS_EXPORT __declspec(dllexport)
+# else
+# define OPUS_EXPORT
+# endif
+# elif defined(__GNUC__) && defined(OPUS_BUILD)
+# define OPUS_EXPORT __attribute__ ((visibility ("default")))
+# else
+# define OPUS_EXPORT
+# endif
+#endif
+
+# if !defined(OPUS_GNUC_PREREQ)
+# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
+# define OPUS_GNUC_PREREQ(_maj,_min) \
+ ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))
+# else
+# define OPUS_GNUC_PREREQ(_maj,_min) 0
+# endif
+# endif
+
+#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
+# if OPUS_GNUC_PREREQ(3,0)
+# define OPUS_RESTRICT __restrict__
+# elif (defined(_MSC_VER) && _MSC_VER >= 1400)
+# define OPUS_RESTRICT __restrict
+# else
+# define OPUS_RESTRICT __restrict //ken
+# endif
+#else
+# define OPUS_RESTRICT __restrict
+#endif
+
+#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
+# if OPUS_GNUC_PREREQ(2,7)
+# define OPUS_INLINE __inline__
+# elif (defined(_MSC_VER))
+# define OPUS_INLINE __inline
+# else
+# define OPUS_INLINE __inline
+# endif
+#else
+# define OPUS_INLINE inline
+#endif
+
+/**Warning attributes for opus functions
+ * NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out
+ * some paranoid null checks. */
+#if defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4)
+# define OPUS_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__))
+#else
+# define OPUS_WARN_UNUSED_RESULT
+#endif
+#if !defined(OPUS_BUILD) && defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4)
+# define OPUS_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x)))
+#else
+# define OPUS_ARG_NONNULL(_x)
+#endif
+
+/** These are the actual Encoder CTL ID numbers.
+ * They should not be used directly by applications.
+ * In general, SETs should be even and GETs should be odd.*/
+#define OPUS_SET_APPLICATION_REQUEST 4000
+#define OPUS_GET_APPLICATION_REQUEST 4001
+#define OPUS_SET_BITRATE_REQUEST 4002
+#define OPUS_GET_BITRATE_REQUEST 4003
+#define OPUS_SET_MAX_BANDWIDTH_REQUEST 4004
+#define OPUS_GET_MAX_BANDWIDTH_REQUEST 4005
+#define OPUS_SET_VBR_REQUEST 4006
+#define OPUS_GET_VBR_REQUEST 4007
+#define OPUS_SET_BANDWIDTH_REQUEST 4008
+#define OPUS_GET_BANDWIDTH_REQUEST 4009
+#define OPUS_SET_COMPLEXITY_REQUEST 4010
+#define OPUS_GET_COMPLEXITY_REQUEST 4011
+#define OPUS_SET_INBAND_FEC_REQUEST 4012
+#define OPUS_GET_INBAND_FEC_REQUEST 4013
+#define OPUS_SET_PACKET_LOSS_PERC_REQUEST 4014
+#define OPUS_GET_PACKET_LOSS_PERC_REQUEST 4015
+#define OPUS_SET_DTX_REQUEST 4016
+#define OPUS_GET_DTX_REQUEST 4017
+#define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020
+#define OPUS_GET_VBR_CONSTRAINT_REQUEST 4021
+#define OPUS_SET_FORCE_CHANNELS_REQUEST 4022
+#define OPUS_GET_FORCE_CHANNELS_REQUEST 4023
+#define OPUS_SET_SIGNAL_REQUEST 4024
+#define OPUS_GET_SIGNAL_REQUEST 4025
+#define OPUS_GET_LOOKAHEAD_REQUEST 4027
+/* #define OPUS_RESET_STATE 4028 */
+#define OPUS_GET_SAMPLE_RATE_REQUEST 4029
+#define OPUS_GET_FINAL_RANGE_REQUEST 4031
+#define OPUS_GET_PITCH_REQUEST 4033
+#define OPUS_SET_GAIN_REQUEST 4034
+#define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */
+#define OPUS_SET_LSB_DEPTH_REQUEST 4036
+#define OPUS_GET_LSB_DEPTH_REQUEST 4037
+#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039
+#define OPUS_SET_EXPERT_FRAME_DURATION_REQUEST 4040
+#define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041
+#define OPUS_SET_PREDICTION_DISABLED_REQUEST 4042
+#define OPUS_GET_PREDICTION_DISABLED_REQUEST 4043
+
+/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */
+
+/* Macros to trigger compilation errors when the wrong types are provided to a CTL */
+#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
+#define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr)))
+#define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr)))
+#define __opus_check_val16_ptr(ptr) ((ptr) + ((ptr) - (opus_val16*)(ptr)))
+/** @endcond */
+
+/** @defgroup opus_ctlvalues Pre-defined values for CTL interface
+ * @see opus_genericctls, opus_encoderctls
+ * @{
+ */
+/* Values for the various encoder CTLs */
+#define OPUS_AUTO -1000 /**<Auto/default setting @hideinitializer*/
+#define OPUS_BITRATE_MAX -1 /**<Maximum bitrate @hideinitializer*/
+
+/** Best for most VoIP/videoconference applications where listening quality and intelligibility matter most
+ * @hideinitializer */
+#define OPUS_APPLICATION_VOIP 2048
+/** Best for broadcast/high-fidelity application where the decoded audio should be as close as possible to the input
+ * @hideinitializer */
+#define OPUS_APPLICATION_AUDIO 2049
+/** Only use when lowest-achievable latency is what matters most. Voice-optimized modes cannot be used.
+ * @hideinitializer */
+#define OPUS_APPLICATION_RESTRICTED_LOWDELAY 2051
+
+#define OPUS_SIGNAL_VOICE 3001 /**< Signal being encoded is voice */
+#define OPUS_SIGNAL_MUSIC 3002 /**< Signal being encoded is music */
+#define OPUS_BANDWIDTH_NARROWBAND 1101 /**< 4 kHz bandpass @hideinitializer*/
+#define OPUS_BANDWIDTH_MEDIUMBAND 1102 /**< 6 kHz bandpass @hideinitializer*/
+#define OPUS_BANDWIDTH_WIDEBAND 1103 /**< 8 kHz bandpass @hideinitializer*/
+#define OPUS_BANDWIDTH_SUPERWIDEBAND 1104 /**<12 kHz bandpass @hideinitializer*/
+#define OPUS_BANDWIDTH_FULLBAND 1105 /**<20 kHz bandpass @hideinitializer*/
+
+#define OPUS_FRAMESIZE_ARG 5000 /**< Select frame size from the argument (default) */
+#define OPUS_FRAMESIZE_2_5_MS 5001 /**< Use 2.5 ms frames */
+#define OPUS_FRAMESIZE_5_MS 5002 /**< Use 5 ms frames */
+#define OPUS_FRAMESIZE_10_MS 5003 /**< Use 10 ms frames */
+#define OPUS_FRAMESIZE_20_MS 5004 /**< Use 20 ms frames */
+#define OPUS_FRAMESIZE_40_MS 5005 /**< Use 40 ms frames */
+#define OPUS_FRAMESIZE_60_MS 5006 /**< Use 60 ms frames */
+
+/**@}*/
+
+
+/** @defgroup opus_encoderctls Encoder related CTLs
+ *
+ * These are convenience macros for use with the \c opus_encode_ctl
+ * interface. They are used to generate the appropriate series of
+ * arguments for that call, passing the correct type, size and so
+ * on as expected for each particular request.
+ *
+ * Some usage examples:
+ *
+ * @code
+ * int ret;
+ * ret = opus_encoder_ctl(enc_ctx, OPUS_SET_BANDWIDTH(OPUS_AUTO));
+ * if (ret != OPUS_OK) return ret;
+ *
+ * opus_int32 rate;
+ * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&rate));
+ *
+ * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE);
+ * @endcode
+ *
+ * @see opus_genericctls, opus_encoder
+ * @{
+ */
+
+/** Configures the encoder's computational complexity.
+ * The supported range is 0-10 inclusive with 10 representing the highest complexity.
+ * @see OPUS_GET_COMPLEXITY
+ * @param[in] x <tt>opus_int32</tt>: Allowed values: 0-10, inclusive.
+ *
+ * @hideinitializer */
+#define OPUS_SET_COMPLEXITY(x) OPUS_SET_COMPLEXITY_REQUEST, __opus_check_int(x)
+/** Gets the encoder's complexity configuration.
+ * @see OPUS_SET_COMPLEXITY
+ * @param[out] x <tt>opus_int32 *</tt>: return a value in the range 0-10,
+ * inclusive.
+ * @hideinitializer */
+#define OPUS_GET_COMPLEXITY(x) OPUS_GET_COMPLEXITY_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the bitrate in the encoder.
+ * Rates from 500 to 512000 bits per second are meaningful, as well as the
+ * special values #OPUS_AUTO and #OPUS_BITRATE_MAX.
+ * The value #OPUS_BITRATE_MAX can be used to cause the codec to use as much
+ * rate as it can, which is useful for controlling the rate by adjusting the
+ * output buffer size.
+ * @see OPUS_GET_BITRATE
+ * @param[in] x <tt>opus_int32</tt>: Bitrate in bits per second. The default
+ * is determined based on the number of
+ * channels and the input sampling rate.
+ * @hideinitializer */
+#define OPUS_SET_BITRATE(x) OPUS_SET_BITRATE_REQUEST, __opus_check_int(x)
+/** Gets the encoder's bitrate configuration.
+ * @see OPUS_SET_BITRATE
+ * @param[out] x <tt>opus_int32 *</tt>: return the bitrate in bits per second.
+ * The default is determined based on the
+ * number of channels and the input
+ * sampling rate.
+ * @hideinitializer */
+#define OPUS_GET_BITRATE(x) OPUS_GET_BITRATE_REQUEST, __opus_check_int_ptr(x)
+
+/** Enables or disables variable bitrate (VBR) in the encoder.
+ * The configured bitrate may not be met exactly because frames must
+ * be an integer number of bytes in length.
+ * @see OPUS_GET_VBR
+ * @see OPUS_SET_VBR_CONSTRAINT
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>0</dt><dd>Hard CBR. For LPC/hybrid modes at very low bit-rate, this can
+ * cause noticeable quality degradation.</dd>
+ * <dt>1</dt><dd>VBR (default). The exact type of VBR is controlled by
+ * #OPUS_SET_VBR_CONSTRAINT.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_VBR(x) OPUS_SET_VBR_REQUEST, __opus_check_int(x)
+/** Determine if variable bitrate (VBR) is enabled in the encoder.
+ * @see OPUS_SET_VBR
+ * @see OPUS_GET_VBR_CONSTRAINT
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>0</dt><dd>Hard CBR.</dd>
+ * <dt>1</dt><dd>VBR (default). The exact type of VBR may be retrieved via
+ * #OPUS_GET_VBR_CONSTRAINT.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_VBR(x) OPUS_GET_VBR_REQUEST, __opus_check_int_ptr(x)
+
+/** Enables or disables constrained VBR in the encoder.
+ * This setting is ignored when the encoder is in CBR mode.
+ * @warning Only the MDCT mode of Opus currently heeds the constraint.
+ * Speech mode ignores it completely, hybrid mode may fail to obey it
+ * if the LPC layer uses more bitrate than the constraint would have
+ * permitted.
+ * @see OPUS_GET_VBR_CONSTRAINT
+ * @see OPUS_SET_VBR
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>0</dt><dd>Unconstrained VBR.</dd>
+ * <dt>1</dt><dd>Constrained VBR (default). This creates a maximum of one
+ * frame of buffering delay assuming a transport with a
+ * serialization speed of the nominal bitrate.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x)
+/** Determine if constrained VBR is enabled in the encoder.
+ * @see OPUS_SET_VBR_CONSTRAINT
+ * @see OPUS_GET_VBR
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>0</dt><dd>Unconstrained VBR.</dd>
+ * <dt>1</dt><dd>Constrained VBR (default).</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures mono/stereo forcing in the encoder.
+ * This can force the encoder to produce packets encoded as either mono or
+ * stereo, regardless of the format of the input audio. This is useful when
+ * the caller knows that the input signal is currently a mono source embedded
+ * in a stereo stream.
+ * @see OPUS_GET_FORCE_CHANNELS
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt><dd>Not forced (default)</dd>
+ * <dt>1</dt> <dd>Forced mono</dd>
+ * <dt>2</dt> <dd>Forced stereo</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x)
+/** Gets the encoder's forced channel configuration.
+ * @see OPUS_SET_FORCE_CHANNELS
+ * @param[out] x <tt>opus_int32 *</tt>:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt><dd>Not forced (default)</dd>
+ * <dt>1</dt> <dd>Forced mono</dd>
+ * <dt>2</dt> <dd>Forced stereo</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the maximum bandpass that the encoder will select automatically.
+ * Applications should normally use this instead of #OPUS_SET_BANDWIDTH
+ * (leaving that set to the default, #OPUS_AUTO). This allows the
+ * application to set an upper bound based on the type of input it is
+ * providing, but still gives the encoder the freedom to reduce the bandpass
+ * when the bitrate becomes too low, for better overall quality.
+ * @see OPUS_GET_MAX_BANDWIDTH
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
+ * <dt>OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
+ * <dt>OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
+ * <dt>OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
+ * <dt>OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband (default)</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_MAX_BANDWIDTH(x) OPUS_SET_MAX_BANDWIDTH_REQUEST, __opus_check_int(x)
+
+/** Gets the encoder's configured maximum allowed bandpass.
+ * @see OPUS_SET_MAX_BANDWIDTH
+ * @param[out] x <tt>opus_int32 *</tt>: Allowed values:
+ * <dl>
+ * <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband (default)</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x)
+
+/** Sets the encoder's bandpass to a specific value.
+ * This prevents the encoder from automatically selecting the bandpass based
+ * on the available bitrate. If an application knows the bandpass of the input
+ * audio it is providing, it should normally use #OPUS_SET_MAX_BANDWIDTH
+ * instead, which still gives the encoder the freedom to reduce the bandpass
+ * when the bitrate becomes too low, for better overall quality.
+ * @see OPUS_GET_BANDWIDTH
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
+ * <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __opus_check_int(x)
+
+/** Configures the type of signal being encoded.
+ * This is a hint which helps the encoder's mode selection.
+ * @see OPUS_GET_SIGNAL
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
+ * <dt>#OPUS_SIGNAL_VOICE</dt><dd>Bias thresholds towards choosing LPC or Hybrid modes.</dd>
+ * <dt>#OPUS_SIGNAL_MUSIC</dt><dd>Bias thresholds towards choosing MDCT modes.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured signal type.
+ * @see OPUS_SET_SIGNAL
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
+ * <dt>#OPUS_SIGNAL_VOICE</dt><dd>Bias thresholds towards choosing LPC or Hybrid modes.</dd>
+ * <dt>#OPUS_SIGNAL_MUSIC</dt><dd>Bias thresholds towards choosing MDCT modes.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __opus_check_int_ptr(x)
+
+
+/** Configures the encoder's intended application.
+ * The initial value is a mandatory argument to the encoder_create function.
+ * @see OPUS_GET_APPLICATION
+ * @param[in] x <tt>opus_int32</tt>: return one of the following values:
+ * <dl>
+ * <dt>#OPUS_APPLICATION_VOIP</dt>
+ * <dd>Process signal for improved speech intelligibility.</dd>
+ * <dt>#OPUS_APPLICATION_AUDIO</dt>
+ * <dd>Favor faithfulness to the original input.</dd>
+ * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
+ * <dd>Configure the minimum possible coding delay by disabling certain modes
+ * of operation.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_APPLICATION(x) OPUS_SET_APPLICATION_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured application.
+ * @see OPUS_SET_APPLICATION
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>#OPUS_APPLICATION_VOIP</dt>
+ * <dd>Process signal for improved speech intelligibility.</dd>
+ * <dt>#OPUS_APPLICATION_AUDIO</dt>
+ * <dd>Favor faithfulness to the original input.</dd>
+ * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
+ * <dd>Configure the minimum possible coding delay by disabling certain modes
+ * of operation.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x)
+
+/** Gets the total samples of delay added by the entire codec.
+ * This can be queried by the encoder and then the provided number of samples can be
+ * skipped on from the start of the decoder's output to provide time aligned input
+ * and output. From the perspective of a decoding application the real data begins this many
+ * samples late.
+ *
+ * The decoder contribution to this delay is identical for all decoders, but the
+ * encoder portion of the delay may vary from implementation to implementation,
+ * version to version, or even depend on the encoder's initial configuration.
+ * Applications needing delay compensation should call this CTL rather than
+ * hard-coding a value.
+ * @param[out] x <tt>opus_int32 *</tt>: Number of lookahead samples
+ * @hideinitializer */
+#define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the encoder's use of inband forward error correction (FEC).
+ * @note This is only applicable to the LPC layer
+ * @see OPUS_GET_INBAND_FEC
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>0</dt><dd>Disable inband FEC (default).</dd>
+ * <dt>1</dt><dd>Enable inband FEC.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x)
+/** Gets encoder's configured use of inband forward error correction.
+ * @see OPUS_SET_INBAND_FEC
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>0</dt><dd>Inband FEC disabled (default).</dd>
+ * <dt>1</dt><dd>Inband FEC enabled.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the encoder's expected packet loss percentage.
+ * Higher values trigger progressively more loss resistant behavior in the encoder
+ * at the expense of quality at a given bitrate in the absence of packet loss, but
+ * greater quality under loss.
+ * @see OPUS_GET_PACKET_LOSS_PERC
+ * @param[in] x <tt>opus_int32</tt>: Loss percentage in the range 0-100, inclusive (default: 0).
+ * @hideinitializer */
+#define OPUS_SET_PACKET_LOSS_PERC(x) OPUS_SET_PACKET_LOSS_PERC_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured packet loss percentage.
+ * @see OPUS_SET_PACKET_LOSS_PERC
+ * @param[out] x <tt>opus_int32 *</tt>: return the configured loss percentage
+ * in the range 0-100, inclusive (default: 0).
+ * @hideinitializer */
+#define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the encoder's use of discontinuous transmission (DTX).
+ * @note This is only applicable to the LPC layer
+ * @see OPUS_GET_DTX
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>0</dt><dd>Disable DTX (default).</dd>
+ * <dt>1</dt><dd>Enabled DTX.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __opus_check_int(x)
+/** Gets encoder's configured use of discontinuous transmission.
+ * @see OPUS_SET_DTX
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>0</dt><dd>DTX disabled (default).</dd>
+ * <dt>1</dt><dd>DTX enabled.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x)
+/** Configures the depth of signal being encoded.
+ *
+ * This is a hint which helps the encoder identify silence and near-silence.
+ * It represents the number of significant bits of linear intensity below
+ * which the signal contains ignorable quantization or other noise.
+ *
+ * For example, OPUS_SET_LSB_DEPTH(14) would be an appropriate setting
+ * for G.711 u-law input. OPUS_SET_LSB_DEPTH(16) would be appropriate
+ * for 16-bit linear pcm input with opus_encode_float().
+ *
+ * When using opus_encode() instead of opus_encode_float(), or when libopus
+ * is compiled for fixed-point, the encoder uses the minimum of the value
+ * set here and the value 16.
+ *
+ * @see OPUS_GET_LSB_DEPTH
+ * @param[in] x <tt>opus_int32</tt>: Input precision in bits, between 8 and 24
+ * (default: 24).
+ * @hideinitializer */
+#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured signal depth.
+ * @see OPUS_SET_LSB_DEPTH
+ * @param[out] x <tt>opus_int32 *</tt>: Input precision in bits, between 8 and
+ * 24 (default: 24).
+ * @hideinitializer */
+#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x)
+
+/** Configures the encoder's use of variable duration frames.
+ * When variable duration is enabled, the encoder is free to use a shorter frame
+ * size than the one requested in the opus_encode*() call.
+ * It is then the user's responsibility
+ * to verify how much audio was encoded by checking the ToC byte of the encoded
+ * packet. The part of the audio that was not encoded needs to be resent to the
+ * encoder for the next call. Do not use this option unless you <b>really</b>
+ * know what you are doing.
+ * @see OPUS_GET_EXPERT_FRAME_DURATION
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd>
+ * <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 5 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_EXPERT_FRAME_DURATION(x) OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured use of variable duration frames.
+ * @see OPUS_SET_EXPERT_FRAME_DURATION
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd>
+ * <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 5 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x)
+
+/** If set to 1, disables almost all use of prediction, making frames almost
+ * completely independent. This reduces quality.
+ * @see OPUS_GET_PREDICTION_DISABLED
+ * @param[in] x <tt>opus_int32</tt>: Allowed values:
+ * <dl>
+ * <dt>0</dt><dd>Enable prediction (default).</dd>
+ * <dt>1</dt><dd>Disable prediction.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_SET_PREDICTION_DISABLED(x) OPUS_SET_PREDICTION_DISABLED_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured prediction status.
+ * @see OPUS_SET_PREDICTION_DISABLED
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>0</dt><dd>Prediction enabled (default).</dd>
+ * <dt>1</dt><dd>Prediction disabled.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x)
+
+/**@}*/
+
+/** @defgroup opus_genericctls Generic CTLs
+ *
+ * These macros are used with the \c opus_decoder_ctl and
+ * \c opus_encoder_ctl calls to generate a particular
+ * request.
+ *
+ * When called on an \c OpusDecoder they apply to that
+ * particular decoder instance. When called on an
+ * \c OpusEncoder they apply to the corresponding setting
+ * on that encoder instance, if present.
+ *
+ * Some usage examples:
+ *
+ * @code
+ * int ret;
+ * opus_int32 pitch;
+ * ret = opus_decoder_ctl(dec_ctx, OPUS_GET_PITCH(&pitch));
+ * if (ret == OPUS_OK) return ret;
+ *
+ * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE);
+ * opus_decoder_ctl(dec_ctx, OPUS_RESET_STATE);
+ *
+ * opus_int32 enc_bw, dec_bw;
+ * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&enc_bw));
+ * opus_decoder_ctl(dec_ctx, OPUS_GET_BANDWIDTH(&dec_bw));
+ * if (enc_bw != dec_bw) {
+ * printf("packet bandwidth mismatch!\n");
+ * }
+ * @endcode
+ *
+ * @see opus_encoder, opus_decoder_ctl, opus_encoder_ctl, opus_decoderctls, opus_encoderctls
+ * @{
+ */
+
+/** Resets the codec state to be equivalent to a freshly initialized state.
+ * This should be called when switching streams in order to prevent
+ * the back to back decoding from giving different results from
+ * one at a time decoding.
+ * @hideinitializer */
+#define OPUS_RESET_STATE 4028
+
+/** Gets the final state of the codec's entropy coder.
+ * This is used for testing purposes,
+ * The encoder and decoder state should be identical after coding a payload
+ * (assuming no data corruption or software bugs)
+ *
+ * @param[out] x <tt>opus_uint32 *</tt>: Entropy coder state
+ *
+ * @hideinitializer */
+#define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x)
+
+/** Gets the encoder's configured bandpass or the decoder's last bandpass.
+ * @see OPUS_SET_BANDWIDTH
+ * @param[out] x <tt>opus_int32 *</tt>: return one of the following values:
+ * <dl>
+ * <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
+ * <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
+ * <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x)
+
+/** Gets the sampling rate the encoder or decoder was initialized with.
+ * This simply return the <code>Fs</code> value passed to opus_encoder_init()
+ * or opus_decoder_init().
+ * @param[out] x <tt>opus_int32 *</tt>: Sampling rate of encoder or decoder.
+ * @hideinitializer
+ */
+#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x)
+
+/**@}*/
+
+/** @defgroup opus_decoderctls Decoder related CTLs
+ * @see opus_genericctls, opus_encoderctls, opus_decoder
+ * @{
+ */
+
+/** Configures decoder gain adjustment.
+ * Scales the decoded output by a factor specified in Q8 dB units.
+ * This has a maximum range of -32768 to 32767 inclusive, and return
+ * OPUS_BAD_ARG otherwise. The default is zero indicating no adjustment.
+ * This setting survives decoder reset.
+ *
+ * gain = pow(10, x/(20.0*256))
+ *
+ * @param[in] x <tt>opus_int32</tt>: Amount to scale PCM signal by in Q8 dB units.
+ * @hideinitializer */
+#define OPUS_SET_GAIN(x) OPUS_SET_GAIN_REQUEST, __opus_check_int(x)
+/** Gets the decoder's configured gain adjustment. @see OPUS_SET_GAIN
+ *
+ * @param[out] x <tt>opus_int32 *</tt>: Amount to scale PCM signal by in Q8 dB units.
+ * @hideinitializer */
+#define OPUS_GET_GAIN(x) OPUS_GET_GAIN_REQUEST, __opus_check_int_ptr(x)
+
+/** Gets the duration (in samples) of the last packet successfully decoded or concealed.
+ * @param[out] x <tt>opus_int32 *</tt>: Number of samples (at current sampling rate).
+ * @hideinitializer */
+#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x)
+
+/** Gets the pitch of the last decoded frame, if available.
+ * This can be used for any post-processing algorithm requiring the use of pitch,
+ * e.g. time stretching/shortening. If the last frame was not voiced, or if the
+ * pitch was not coded in the frame, then zero is returned.
+ *
+ * This CTL is only implemented for decoder instances.
+ *
+ * @param[out] x <tt>opus_int32 *</tt>: pitch period at 48 kHz (or 0 if not available)
+ *
+ * @hideinitializer */
+#define OPUS_GET_PITCH(x) OPUS_GET_PITCH_REQUEST, __opus_check_int_ptr(x)
+
+/**@}*/
+
+/** @defgroup opus_libinfo Opus library information functions
+ * @{
+ */
+
+/** Converts an opus error code into a human readable string.
+ *
+ * @param[in] error <tt>int</tt>: Error number
+ * @return Error string
+ */
+OPUS_EXPORT const char *opus_strerror(int error);
+
+/** Gets the libopus version string.
+ *
+ * Applications may look for the substring "-fixed" in the version string to
+ * determine whether they have a fixed-point or floating-point build at
+ * runtime.
+ *
+ * @return Version string
+ */
+OPUS_EXPORT const char *opus_get_version_string(void);
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPUS_DEFINES_H */
diff --git a/src/app/google_rcu/opus/opus_multistream.h b/src/app/google_rcu/opus/opus_multistream.h
new file mode 100644
index 0000000..75f069c
--- /dev/null
+++ b/src/app/google_rcu/opus/opus_multistream.h
@@ -0,0 +1,662 @@
+/* Copyright (c) 2011 Xiph.Org Foundation
+ Written by Jean-Marc Valin */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * @file opus_multistream.h
+ * @brief Opus reference implementation multistream API
+ */
+
+#ifndef OPUS_MULTISTREAM_H
+#define OPUS_MULTISTREAM_H
+
+#include "opus.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @cond OPUS_INTERNAL_DOC */
+
+/** Macros to trigger compilation errors when the wrong types are provided to a
+ * CTL. */
+/**@{*/
+#define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr)))
+#define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr)))
+/**@}*/
+
+/** These are the actual encoder and decoder CTL ID numbers.
+ * They should not be used directly by applications.
+ * In general, SETs should be even and GETs should be odd.*/
+/**@{*/
+#define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120
+#define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122
+/**@}*/
+
+/** @endcond */
+
+/** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs
+ *
+ * These are convenience macros that are specific to the
+ * opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl()
+ * interface.
+ * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and
+ * @ref opus_decoderctls may be applied to a multistream encoder or decoder as
+ * well.
+ * In addition, you may retrieve the encoder or decoder state for an specific
+ * stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or
+ * #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually.
+ */
+/**@{*/
+
+/** Gets the encoder state for an individual stream of a multistream encoder.
+ * @param[in] x <tt>opus_int32</tt>: The index of the stream whose encoder you
+ * wish to retrieve.
+ * This must be non-negative and less than
+ * the <code>streams</code> parameter used
+ * to initialize the encoder.
+ * @param[out] y <tt>OpusEncoder**</tt>: return a pointer to the given
+ * encoder state.
+ * @retval OPUS_BAD_ARG The index of the requested stream was out of range.
+ * @hideinitializer
+ */
+#define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y)
+
+/** Gets the decoder state for an individual stream of a multistream decoder.
+ * @param[in] x <tt>opus_int32</tt>: The index of the stream whose decoder you
+ * wish to retrieve.
+ * This must be non-negative and less than
+ * the <code>streams</code> parameter used
+ * to initialize the decoder.
+ * @param[out] y <tt>OpusDecoder**</tt>: return a pointer to the given
+ * decoder state.
+ * @retval OPUS_BAD_ARG The index of the requested stream was out of range.
+ * @hideinitializer
+ */
+#define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y)
+
+/**@}*/
+
+/** @defgroup opus_multistream Opus Multistream API
+ * @{
+ *
+ * The multistream API allows individual Opus streams to be combined into a
+ * single packet, enabling support for up to 255 channels. Unlike an
+ * elementary Opus stream, the encoder and decoder must negotiate the channel
+ * configuration before the decoder can successfully interpret the data in the
+ * packets produced by the encoder. Some basic information, such as packet
+ * duration, can be computed without any special negotiation.
+ *
+ * The format for multistream Opus packets is defined in
+ * <a href="https://tools.ietf.org/html/rfc7845">RFC 7845</a>
+ * and is based on the self-delimited Opus framing described in Appendix B of
+ * <a href="https://tools.ietf.org/html/rfc6716">RFC 6716</a>.
+ * Normal Opus packets are just a degenerate case of multistream Opus packets,
+ * and can be encoded or decoded with the multistream API by setting
+ * <code>streams</code> to <code>1</code> when initializing the encoder or
+ * decoder.
+ *
+ * Multistream Opus streams can contain up to 255 elementary Opus streams.
+ * These may be either "uncoupled" or "coupled", indicating that the decoder
+ * is configured to decode them to either 1 or 2 channels, respectively.
+ * The streams are ordered so that all coupled streams appear at the
+ * beginning.
+ *
+ * A <code>mapping</code> table defines which decoded channel <code>i</code>
+ * should be used for each input/output (I/O) channel <code>j</code>. This table is
+ * typically provided as an unsigned char array.
+ * Let <code>i = mapping[j]</code> be the index for I/O channel <code>j</code>.
+ * If <code>i < 2*coupled_streams</code>, then I/O channel <code>j</code> is
+ * encoded as the left channel of stream <code>(i/2)</code> if <code>i</code>
+ * is even, or as the right channel of stream <code>(i/2)</code> if
+ * <code>i</code> is odd. Otherwise, I/O channel <code>j</code> is encoded as
+ * mono in stream <code>(i - coupled_streams)</code>, unless it has the special
+ * value 255, in which case it is omitted from the encoding entirely (the
+ * decoder will reproduce it as silence). Each value <code>i</code> must either
+ * be the special value 255 or be less than <code>streams + coupled_streams</code>.
+ *
+ * The output channels specified by the encoder
+ * should use the
+ * <a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-810004.3.9">Vorbis
+ * channel ordering</a>. A decoder may wish to apply an additional permutation
+ * to the mapping the encoder used to achieve a different output channel
+ * order (e.g. for outputing in WAV order).
+ *
+ * Each multistream packet contains an Opus packet for each stream, and all of
+ * the Opus packets in a single multistream packet must have the same
+ * duration. Therefore the duration of a multistream packet can be extracted
+ * from the TOC sequence of the first stream, which is located at the
+ * beginning of the packet, just like an elementary Opus stream:
+ *
+ * @code
+ * int nb_samples;
+ * int nb_frames;
+ * nb_frames = opus_packet_get_nb_frames(data, len);
+ * if (nb_frames < 1)
+ * return nb_frames;
+ * nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames;
+ * @endcode
+ *
+ * The general encoding and decoding process proceeds exactly the same as in
+ * the normal @ref opus_encoder and @ref opus_decoder APIs.
+ * See their documentation for an overview of how to use the corresponding
+ * multistream functions.
+ */
+
+/** Opus multistream encoder state.
+ * This contains the complete state of a multistream Opus encoder.
+ * It is position independent and can be freely copied.
+ * @see opus_multistream_encoder_create
+ * @see opus_multistream_encoder_init
+ */
+typedef struct OpusMSEncoder OpusMSEncoder;
+
+/** Opus multistream decoder state.
+ * This contains the complete state of a multistream Opus decoder.
+ * It is position independent and can be freely copied.
+ * @see opus_multistream_decoder_create
+ * @see opus_multistream_decoder_init
+ */
+typedef struct OpusMSDecoder OpusMSDecoder;
+
+/**\name Multistream encoder functions */
+/**@{*/
+
+/** Gets the size of an OpusMSEncoder structure.
+ * @param streams <tt>int</tt>: The total number of streams to encode from the
+ * input.
+ * This must be no more than 255.
+ * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
+ * to encode.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * encoded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than 255.
+ * @return The size in bytes on success, or a negative error code
+ * (see @ref opus_errorcodes) on error.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size(
+ int streams,
+ int coupled_streams
+);
+
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_surround_encoder_get_size(
+ int channels,
+ int mapping_family
+);
+
+
+/** Allocates and initializes a multistream encoder state.
+ * Call opus_multistream_encoder_destroy() to release
+ * this object when finished.
+ * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param channels <tt>int</tt>: Number of channels in the input signal.
+ * This must be at most 255.
+ * It may be greater than the number of
+ * coded channels (<code>streams +
+ * coupled_streams</code>).
+ * @param streams <tt>int</tt>: The total number of streams to encode from the
+ * input.
+ * This must be no more than the number of channels.
+ * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
+ * to encode.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * encoded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than the number of input channels.
+ * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+ * encoded channels to input channels, as described in
+ * @ref opus_multistream. As an extra constraint, the
+ * multistream encoder does not allow encoding coupled
+ * streams for which one channel is unused since this
+ * is never a good idea.
+ * @param application <tt>int</tt>: The target encoder application.
+ * This must be one of the following:
+ * <dl>
+ * <dt>#OPUS_APPLICATION_VOIP</dt>
+ * <dd>Process signal for improved speech intelligibility.</dd>
+ * <dt>#OPUS_APPLICATION_AUDIO</dt>
+ * <dd>Favor faithfulness to the original input.</dd>
+ * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
+ * <dd>Configure the minimum possible coding delay by disabling certain modes
+ * of operation.</dd>
+ * </dl>
+ * @param[out] error <tt>int *</tt>: return #OPUS_OK on success, or an error
+ * code (see @ref opus_errorcodes) on
+ * failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create(
+ opus_int32 Fs,
+ int channels,
+ int streams,
+ int coupled_streams,
+ const unsigned char *mapping,
+ int application,
+ int *error
+) OPUS_ARG_NONNULL(5);
+
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_surround_encoder_create(
+ opus_int32 Fs,
+ int channels,
+ int mapping_family,
+ int *streams,
+ int *coupled_streams,
+ unsigned char *mapping,
+ int application,
+ int *error
+) OPUS_ARG_NONNULL(5);
+
+/** Initialize a previously allocated multistream encoder state.
+ * The memory pointed to by \a st must be at least the size returned by
+ * opus_multistream_encoder_get_size().
+ * This is intended for applications which use their own allocator instead of
+ * malloc.
+ * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+ * @see opus_multistream_encoder_create
+ * @see opus_multistream_encoder_get_size
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.
+ * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param channels <tt>int</tt>: Number of channels in the input signal.
+ * This must be at most 255.
+ * It may be greater than the number of
+ * coded channels (<code>streams +
+ * coupled_streams</code>).
+ * @param streams <tt>int</tt>: The total number of streams to encode from the
+ * input.
+ * This must be no more than the number of channels.
+ * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
+ * to encode.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * encoded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than the number of input channels.
+ * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+ * encoded channels to input channels, as described in
+ * @ref opus_multistream. As an extra constraint, the
+ * multistream encoder does not allow encoding coupled
+ * streams for which one channel is unused since this
+ * is never a good idea.
+ * @param application <tt>int</tt>: The target encoder application.
+ * This must be one of the following:
+ * <dl>
+ * <dt>#OPUS_APPLICATION_VOIP</dt>
+ * <dd>Process signal for improved speech intelligibility.</dd>
+ * <dt>#OPUS_APPLICATION_AUDIO</dt>
+ * <dd>Favor faithfulness to the original input.</dd>
+ * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
+ * <dd>Configure the minimum possible coding delay by disabling certain modes
+ * of operation.</dd>
+ * </dl>
+ * @return #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
+ * on failure.
+ */
+OPUS_EXPORT int opus_multistream_encoder_init(
+ OpusMSEncoder *st,
+ opus_int32 Fs,
+ int channels,
+ int streams,
+ int coupled_streams,
+ const unsigned char *mapping,
+ int application
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
+
+OPUS_EXPORT int opus_multistream_surround_encoder_init(
+ OpusMSEncoder *st,
+ opus_int32 Fs,
+ int channels,
+ int mapping_family,
+ int *streams,
+ int *coupled_streams,
+ unsigned char *mapping,
+ int application
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
+
+/** Encodes a multistream Opus frame.
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
+ * @param[in] pcm <tt>const opus_int16*</tt>: The input signal as interleaved
+ * samples.
+ * This must contain
+ * <code>frame_size*channels</code>
+ * samples.
+ * @param frame_size <tt>int</tt>: Number of samples per channel in the input
+ * signal.
+ * This must be an Opus frame size for the
+ * encoder's sampling rate.
+ * For example, at 48 kHz the permitted values
+ * are 120, 240, 480, 960, 1920, and 2880.
+ * Passing in a duration of less than 10 ms
+ * (480 samples at 48 kHz) will prevent the
+ * encoder from using the LPC or hybrid modes.
+ * @param[out] data <tt>unsigned char*</tt>: Output payload.
+ * This must contain storage for at
+ * least \a max_data_bytes.
+ * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+ * memory for the output
+ * payload. This may be
+ * used to impose an upper limit on
+ * the instant bitrate, but should
+ * not be used as the only bitrate
+ * control. Use #OPUS_SET_BITRATE to
+ * control the bitrate.
+ * @return The length of the encoded packet (in bytes) on success or a
+ * negative error code (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode(
+ OpusMSEncoder *st,
+ const opus_int16 *pcm,
+ int frame_size,
+ unsigned char *data,
+ opus_int32 max_data_bytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Encodes a multistream Opus frame from floating point input.
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
+ * @param[in] pcm <tt>const float*</tt>: The input signal as interleaved
+ * samples with a normal range of
+ * +/-1.0.
+ * Samples with a range beyond +/-1.0
+ * are supported but will be clipped by
+ * decoders using the integer API and
+ * should only be used if it is known
+ * that the far end supports extended
+ * dynamic range.
+ * This must contain
+ * <code>frame_size*channels</code>
+ * samples.
+ * @param frame_size <tt>int</tt>: Number of samples per channel in the input
+ * signal.
+ * This must be an Opus frame size for the
+ * encoder's sampling rate.
+ * For example, at 48 kHz the permitted values
+ * are 120, 240, 480, 960, 1920, and 2880.
+ * Passing in a duration of less than 10 ms
+ * (480 samples at 48 kHz) will prevent the
+ * encoder from using the LPC or hybrid modes.
+ * @param[out] data <tt>unsigned char*</tt>: Output payload.
+ * This must contain storage for at
+ * least \a max_data_bytes.
+ * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+ * memory for the output
+ * payload. This may be
+ * used to impose an upper limit on
+ * the instant bitrate, but should
+ * not be used as the only bitrate
+ * control. Use #OPUS_SET_BITRATE to
+ * control the bitrate.
+ * @return The length of the encoded packet (in bytes) on success or a
+ * negative error code (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float(
+ OpusMSEncoder *st,
+ const float *pcm,
+ int frame_size,
+ unsigned char *data,
+ opus_int32 max_data_bytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+/** Frees an <code>OpusMSEncoder</code> allocated by
+ * opus_multistream_encoder_create().
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to be freed.
+ */
+OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st);
+
+/** Perform a CTL function on a multistream Opus encoder.
+ *
+ * Generally the request and subsequent arguments are generated by a
+ * convenience macro.
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
+ * @param request This and all remaining parameters should be replaced by one
+ * of the convenience macros in @ref opus_genericctls,
+ * @ref opus_encoderctls, or @ref opus_multistream_ctls.
+ * @see opus_genericctls
+ * @see opus_encoderctls
+ * @see opus_multistream_ctls
+ */
+OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request,
+ ...) OPUS_ARG_NONNULL(1);
+
+/**@}*/
+
+/**\name Multistream decoder functions */
+/**@{*/
+
+/** Gets the size of an <code>OpusMSDecoder</code> structure.
+ * @param streams <tt>int</tt>: The total number of streams coded in the
+ * input.
+ * This must be no more than 255.
+ * @param coupled_streams <tt>int</tt>: Number streams to decode as coupled
+ * (2 channel) streams.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * coded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than 255.
+ * @return The size in bytes on success, or a negative error code
+ * (see @ref opus_errorcodes) on error.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size(
+ int streams,
+ int coupled_streams
+);
+
+/** Allocates and initializes a multistream decoder state.
+ * Call opus_multistream_decoder_destroy() to release
+ * this object when finished.
+ * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param channels <tt>int</tt>: Number of channels to output.
+ * This must be at most 255.
+ * It may be different from the number of coded
+ * channels (<code>streams +
+ * coupled_streams</code>).
+ * @param streams <tt>int</tt>: The total number of streams coded in the
+ * input.
+ * This must be no more than 255.
+ * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
+ * (2 channel) streams.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * coded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than 255.
+ * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+ * coded channels to output channels, as described in
+ * @ref opus_multistream.
+ * @param[out] error <tt>int *</tt>: return #OPUS_OK on success, or an error
+ * code (see @ref opus_errorcodes) on
+ * failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create(
+ opus_int32 Fs,
+ int channels,
+ int streams,
+ int coupled_streams,
+ const unsigned char *mapping,
+ int *error
+) OPUS_ARG_NONNULL(5);
+
+/** Initialize a previously allocated decoder state object.
+ * The memory pointed to by \a st must be at least the size returned by
+ * opus_multistream_encoder_get_size().
+ * This is intended for applications which use their own allocator instead of
+ * malloc.
+ * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+ * @see opus_multistream_decoder_create
+ * @see opus_multistream_deocder_get_size
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.
+ * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
+ * This must be one of 8000, 12000, 16000,
+ * 24000, or 48000.
+ * @param channels <tt>int</tt>: Number of channels to output.
+ * This must be at most 255.
+ * It may be different from the number of coded
+ * channels (<code>streams +
+ * coupled_streams</code>).
+ * @param streams <tt>int</tt>: The total number of streams coded in the
+ * input.
+ * This must be no more than 255.
+ * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
+ * (2 channel) streams.
+ * This must be no larger than the total
+ * number of streams.
+ * Additionally, The total number of
+ * coded channels (<code>streams +
+ * coupled_streams</code>) must be no
+ * more than 255.
+ * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+ * coded channels to output channels, as described in
+ * @ref opus_multistream.
+ * @return #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
+ * on failure.
+ */
+OPUS_EXPORT int opus_multistream_decoder_init(
+ OpusMSDecoder *st,
+ opus_int32 Fs,
+ int channels,
+ int streams,
+ int coupled_streams,
+ const unsigned char *mapping
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
+
+/** Decode a multistream Opus packet.
+ * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
+ * @param[in] data <tt>const unsigned char*</tt>: Input payload.
+ * Use a <code>NULL</code>
+ * pointer to indicate packet
+ * loss.
+ * @param len <tt>opus_int32</tt>: Number of bytes in payload.
+ * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
+ * samples.
+ * This must contain room for
+ * <code>frame_size*channels</code>
+ * samples.
+ * @param frame_size <tt>int</tt>: The number of samples per channel of
+ * available space in \a pcm.
+ * If this is less than the maximum packet duration
+ * (120 ms; 5760 for 48kHz), this function will not be capable
+ * of decoding some packets. In the case of PLC (data==NULL)
+ * or FEC (decode_fec=1), then frame_size needs to be exactly
+ * the duration of audio that is missing, otherwise the
+ * decoder will not be in the optimal state to decode the
+ * next incoming packet. For the PLC and FEC cases, frame_size
+ * <b>must</b> be a multiple of 2.5 ms.
+ * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
+ * forward error correction data be decoded.
+ * If no such data is available, the frame is
+ * decoded as if it were lost.
+ * @return Number of samples decoded on success or a negative error code
+ * (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode(
+ OpusMSDecoder *st,
+ const unsigned char *data,
+ opus_int32 len,
+ opus_int16 *pcm,
+ int frame_size,
+ int decode_fec
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Decode a multistream Opus packet with floating point output.
+ * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
+ * @param[in] data <tt>const unsigned char*</tt>: Input payload.
+ * Use a <code>NULL</code>
+ * pointer to indicate packet
+ * loss.
+ * @param len <tt>opus_int32</tt>: Number of bytes in payload.
+ * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
+ * samples.
+ * This must contain room for
+ * <code>frame_size*channels</code>
+ * samples.
+ * @param frame_size <tt>int</tt>: The number of samples per channel of
+ * available space in \a pcm.
+ * If this is less than the maximum packet duration
+ * (120 ms; 5760 for 48kHz), this function will not be capable
+ * of decoding some packets. In the case of PLC (data==NULL)
+ * or FEC (decode_fec=1), then frame_size needs to be exactly
+ * the duration of audio that is missing, otherwise the
+ * decoder will not be in the optimal state to decode the
+ * next incoming packet. For the PLC and FEC cases, frame_size
+ * <b>must</b> be a multiple of 2.5 ms.
+ * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
+ * forward error correction data be decoded.
+ * If no such data is available, the frame is
+ * decoded as if it were lost.
+ * @return Number of samples decoded on success or a negative error code
+ * (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float(
+ OpusMSDecoder *st,
+ const unsigned char *data,
+ opus_int32 len,
+ float *pcm,
+ int frame_size,
+ int decode_fec
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Perform a CTL function on a multistream Opus decoder.
+ *
+ * Generally the request and subsequent arguments are generated by a
+ * convenience macro.
+ * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
+ * @param request This and all remaining parameters should be replaced by one
+ * of the convenience macros in @ref opus_genericctls,
+ * @ref opus_decoderctls, or @ref opus_multistream_ctls.
+ * @see opus_genericctls
+ * @see opus_decoderctls
+ * @see opus_multistream_ctls
+ */
+OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request,
+ ...) OPUS_ARG_NONNULL(1);
+
+/** Frees an <code>OpusMSDecoder</code> allocated by
+ * opus_multistream_decoder_create().
+ * @param st <tt>OpusMSDecoder</tt>: Multistream decoder state to be freed.
+ */
+OPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st);
+
+/**@}*/
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPUS_MULTISTREAM_H */
diff --git a/src/app/google_rcu/opus/opus_types.h b/src/app/google_rcu/opus/opus_types.h
new file mode 100644
index 0000000..85a2ed8
--- /dev/null
+++ b/src/app/google_rcu/opus/opus_types.h
@@ -0,0 +1,159 @@
+/* (C) COPYRIGHT 1994-2002 Xiph.Org Foundation */
+/* Modified by Jean-Marc Valin */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/* opus_types.h based on ogg_types.h from libogg */
+
+/**
+ @file opus_types.h
+ @brief Opus reference implementation types
+*/
+#ifndef OPUS_TYPES_H
+#define OPUS_TYPES_H
+
+/* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */
+#if (defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H))
+#include <stdint.h>
+
+typedef int16_t opus_int16;
+typedef uint16_t opus_uint16;
+typedef int32_t opus_int32;
+typedef uint32_t opus_uint32;
+#elif defined(_WIN32)
+
+# if defined(__CYGWIN__)
+# include <_G_config.h>
+typedef _G_int32_t opus_int32;
+typedef _G_uint32_t opus_uint32;
+typedef _G_int16 opus_int16;
+typedef _G_uint16 opus_uint16;
+# elif defined(__MINGW32__)
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+typedef int opus_int32;
+typedef unsigned int opus_uint32;
+# elif defined(__MWERKS__)
+typedef int opus_int32;
+typedef unsigned int opus_uint32;
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+# else
+/* MSVC/Borland */
+typedef __int32 opus_int32;
+typedef unsigned __int32 opus_uint32;
+typedef __int16 opus_int16;
+typedef unsigned __int16 opus_uint16;
+# endif
+
+#elif defined(__MACOS__)
+
+# include <sys/types.h>
+typedef SInt16 opus_int16;
+typedef UInt16 opus_uint16;
+typedef SInt32 opus_int32;
+typedef UInt32 opus_uint32;
+
+#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
+
+# include <sys/types.h>
+typedef int16_t opus_int16;
+typedef u_int16_t opus_uint16;
+typedef int32_t opus_int32;
+typedef u_int32_t opus_uint32;
+
+#elif defined(__BEOS__)
+
+/* Be */
+# include <inttypes.h>
+typedef int16 opus_int16;
+typedef u_int16 opus_uint16;
+typedef int32_t opus_int32;
+typedef u_int32_t opus_uint32;
+
+#elif defined (__EMX__)
+
+/* OS/2 GCC */
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+typedef int opus_int32;
+typedef unsigned int opus_uint32;
+
+#elif defined (DJGPP)
+
+/* DJGPP */
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+typedef int opus_int32;
+typedef unsigned int opus_uint32;
+
+#elif defined(R5900)
+
+/* PS2 EE */
+typedef int opus_int32;
+typedef unsigned opus_uint32;
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+
+#elif defined(__SYMBIAN32__)
+
+/* Symbian GCC */
+typedef signed short opus_int16;
+typedef unsigned short opus_uint16;
+typedef signed int opus_int32;
+typedef unsigned int opus_uint32;
+
+#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
+
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+typedef long opus_int32;
+typedef unsigned long opus_uint32;
+
+#elif defined(CONFIG_TI_C6X)
+
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+typedef int opus_int32;
+typedef unsigned int opus_uint32;
+
+#else
+
+/* Give up, take a reasonable guess */
+typedef short opus_int16;
+typedef unsigned short opus_uint16;
+typedef int opus_int32;
+typedef unsigned int opus_uint32;
+
+#endif
+
+#define opus_int int /* used for counters etc; at least 16 bits */
+#define opus_int64 long long
+#define opus_int8 signed char
+
+#define opus_uint unsigned int /* used for counters etc; at least 16 bits */
+#define opus_uint64 unsigned long long
+#define opus_uint8 unsigned char
+
+#endif /* OPUS_TYPES_H */
diff --git a/src/app/google_rcu/profile_module/dfu_api.h b/src/app/google_rcu/profile_module/dfu_api.h
new file mode 100644
index 0000000..467abcb
--- /dev/null
+++ b/src/app/google_rcu/profile_module/dfu_api.h
@@ -0,0 +1,183 @@
+/**
+************************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+************************************************************************************************************
+* @file dfu_api.h
+* @brief APIs to implement device firmware update.
+* @details OTA is used to update device firmware via bluetooth.
+* @author ranhui
+* @date 2015-10-29
+* @version v1.0
+*************************************************************************************************************
+*/
+
+#ifndef _DFU_API_H_
+#define _DFU_API_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#include "string.h"
+#include "patch_header_check.h"
+#include "sha256.h"
+
+#define MAJOR_IMG_VER(p) (p & 0xf)
+#define MINOR_IMG_VER(p) ((p & 0xff0) >> 4)
+#define REVISION_IMG_VER(p) ((p & 0x07fff000) >> 12)
+#define RESERVE_IMG_VER(p) ((p & 0xf8000000) >> 27)
+
+/*convert T_IMAGE_VERSION to little endian uint32_t value, so that compare version value directly */
+#define IMAGE_VERSION_TO_LE_UINT32(ver) (((ver & 0xf) << 28 )\
+ + (((ver & 0xff0) >> 4) << 20)\
+ + (((ver & 0x07fff000) >> 12) << 5)\
+ + ((ver & 0xf8000000) >> 27))
+
+
+/* dfu service uuid */
+#define GATT_UUID128_DFU_SERVICE 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0x87, 0x62, 0x00, 0x00
+#define GATT_UUID128_DFU_DATA 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0x87, 0x63, 0x00, 0x00
+#define GATT_UUID128_DFU_CONTROL_POINT 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0x87, 0x64, 0x00, 0x00
+
+/*length of each control point procedure*/
+#define DFU_LENGTH_START_DFU (1+12+4)/*4 bytes is padding for encrypt*/
+#define DFU_LENGTH_RECEIVE_FW_IMAGE_INFO (1+2+4) //img_id + cur_offset
+#define DFU_LENGTH_VALID_FW (1+2) //img_id
+#define DFU_LENGTH_ACTIVE_IMAGE_RESET (1)
+#define DFU_LENGTH_ACTIVE_IMAGE_RESET_TO_OTA_MODE (1+1) //uint8_t reset_mode, 1: reset to ota mode
+#define DFU_LENGTH_SYSTEM_RESET (1)
+#define DFU_LENGTH_REPORT_TARGET_INFO (1+2) //img_id
+#define DFU_LENGTH_CONN_PARA_TO_UPDATE_REQ (1+2+2+2+2) //conn_interval_min,conn_interval_max,conn_latency,superv_tout
+#define DFU_LENGTH_BUFFER_CHECK_EN (1)
+#define DFU_LENGTH_REPORT_BUFFER_CRC (1+2+2) //buf_size, buf_crc
+#define DFU_LENGTH_HANDSHAKE (1+16) //handshake
+#define DFU_LENGTH_MAX DFU_LENGTH_START_DFU
+
+/*length of notification*/
+#define DFU_NOTIFY_LENGTH_ARV 3 //others opcode notification length
+#define DFU_NOTIFY_LENGTH_START_DFU (DFU_NOTIFY_LENGTH_ARV)
+#define DFU_NOTIFY_LENGTH_VALID_FW (DFU_NOTIFY_LENGTH_ARV)
+#define DFU_NOTIFY_LENGTH_CONN_PARA_UPDATE_REQ (DFU_NOTIFY_LENGTH_ARV)
+#define DFU_NOTIFY_LENGTH_REPORT_TARGET_INFO (DFU_NOTIFY_LENGTH_ARV+4+4) //img_ver, cur_offset
+#define DFU_NOTIFY_LENGTH_BUFFER_CHECK_EN (DFU_NOTIFY_LENGTH_ARV+2+2) //buf_size, mtu_size
+#define DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC (DFU_NOTIFY_LENGTH_ARV+4) //cur_offset
+#define DFU_NOTIFY_LENGTH_RECEIVE_IC_TYPE (DFU_NOTIFY_LENGTH_ARV+1) //ic_type
+#define DFU_NOTIFY_LENGTH_HANDSHAKE (DFU_NOTIFY_LENGTH_ARV+16) //handshake
+/*max length*/
+#define DFU_NOTIFY_LENGTH_MAX DFU_NOTIFY_LENGTH_HANDSHAKE
+
+
+/** @defgroup DFU_Client_Exported_Types Exported Types
+ * @{
+ */
+
+typedef union
+{
+ uint8_t value;
+ struct
+ {
+ uint8_t buf_check_en: 1; // 1:support, 0:don't support
+ uint8_t aesflg: 1; // 1:aes encrypt when ota, 0:not encrypt
+ uint8_t aesmode: 1; // 1:all data is encrypted, 0:only encrypt 16byte
+ uint8_t copy_img: 1; //1:support ,0:don't support
+ uint8_t multi_img: 1; //1:support(update multi img at a time) ,0:don't support(one img at a time)
+ uint8_t rsvd: 3;
+ } mode_flag;
+} T_OTA_MODE;
+
+
+/*each control point procedure,can't modify exist value*/
+typedef enum
+{
+ DFU_OPCODE_MIN = 0x00, /*control point opcode min*/
+ DFU_OPCODE_START_DFU = 0x01,
+ DFU_OPCODE_RECEIVE_FW_IMAGE_INFO = 0x02,
+ DFU_OPCODE_VALID_FW = 0x03,
+ DFU_OPCODE_ACTIVE_IMAGE_RESET = 0x04,
+ DFU_OPCODE_SYSTEM_RESET = 0x05,
+ DFU_OPCODE_REPORT_TARGET_INFO = 0x06,
+ DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ = 0x07,
+ DFU_OPCODE_PKT_RX_NOTIFICATION_VOICE = 0x08,
+ DFU_OPCODE_BUFFER_CHECK_EN = 0x09,
+ DFU_OPCODE_REPORT_BUFFER_CRC = 0x0a,
+ DFU_OPCODE_RECEIVE_IC_TYPE = 0x0b,
+ DFU_OPCODE_COPY_IMG = 0x0c,
+ DFU_OPCODE_CHECK_IMAGE_VER = 0x0d,
+ DFU_OPCODE_HANDSHAKE = 0x0e,
+ DFU_OPCODE_MAX = 0x0f, /*control point opcode max*/
+ DFU_OPCODE_NOTIFICATION = 0x10, /*notification opcode,fixed*/
+} T_DFU_CP_OPCODE;
+
+/*dfu error code*/
+typedef enum
+{
+ DFU_ARV_SUCCESS = 0x01,
+ DFU_ARV_FAIL_INVALID_PARAMETER = 0x02,
+ DFU_ARV_FAIL_OPERATION = 0x03,
+ DFU_ARV_FAIL_DATA_SIZE_EXCEEDS_LIMIT = 0x04,
+ DFU_ARV_FAIL_CRC_ERROR = 0x05,
+ DFU_ARV_FAIL_LENGTH_ERROR = 0x06,
+ DFU_ARV_FAIL_PROG_ERROR = 0x07,
+ DFU_ARV_FAIL_ERASE_ERROR = 0x08,
+ DFU_ARV_FAIL_SYS_VERSION_ERROR = 0x09,
+} T_DFU_ARV_ERROR_CODE;
+
+
+/** @defgroup DFU_API DFU API Sets
+ * @brief API sets for device firmware update implementation
+ * @{
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup DFU_API_Exported_Functions DFU API Sets Exported Functions
+ * @{
+ */
+bool dfu_reset(uint16_t image_id);
+
+/**
+ * @brief set specified image valid bit..
+ * @param p_header specified image.
+ * @return true if ready bit sets to 0, false otherwise
+*/
+extern void dfu_set_ready(T_IMG_CTRL_HEADER_FORMAT *p_header);
+
+extern void dfu_set_obsolete(T_IMG_CTRL_HEADER_FORMAT *p_header);
+
+/**
+ * @brief dump image header for debug.
+*/
+extern void dfu_dump_header(T_IMG_HEADER_FORMAT *p_header);
+
+extern uint16_t dfu_process_crc(uint16_t fcs, uint8_t *buf, uint32_t buf_max_size, uint8_t *pdata,
+ size_t data_len);
+
+extern void dfu_process_sha256(SHA256_CTX *ctx, uint8_t *buf, uint32_t buf_max_size, uint8_t *pdata,
+ size_t data_len);
+
+
+static inline uint32_t get_image_version_le_value_from_start_addr(uint32_t start_addr)
+{
+ uint32_t img_ver = 0;
+ T_IMG_HEADER_FORMAT *p_header = (T_IMG_HEADER_FORMAT *)start_addr;
+ if (p_header)
+ {
+ img_ver = (p_header->git_ver.ver_info.sub_version._version_major << 28)
+ + (p_header->git_ver.ver_info.sub_version._version_minor << 20)
+ + (p_header->git_ver.ver_info.sub_version._version_revision << 5)
+ + p_header->git_ver.ver_info.sub_version._version_reserve;
+ }
+ return img_ver;
+}
+
+
+/** @} */ /* End of group DFU_API_Exported_Functions */
+/** @} */ /* End of group DFU_API */
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif
+
diff --git a/src/app/google_rcu/profile_module/dfu_service.c b/src/app/google_rcu/profile_module/dfu_service.c
new file mode 100644
index 0000000..ce807a5
--- /dev/null
+++ b/src/app/google_rcu/profile_module/dfu_service.c
@@ -0,0 +1,1188 @@
+#include <string.h>
+#include "gatt.h"
+#include "gap_conn_le.h"
+#include "patch_header_check.h"
+#include "rtl876x_wdg.h"
+#include "flash_device.h"
+#include "dfu_flash.h"
+#include "dfu_api.h"
+#include "dfu_service.h"
+#include "otp.h"
+#include "trace.h"
+#include "board.h"
+#include "rtl876x_hw_aes.h"
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+
+//#define CAL_OFFSET(type, member) ((size_t)(&((type *)0)->member))
+
+/*============================================================================*
+ * External Variables
+ *============================================================================*/
+extern bool aes256_ecb_encrypt_msb2lsb(uint8_t plaintext[16], const uint8_t key[32],
+ uint8_t *encrypted);
+
+T_DFU_PARA g_dfu_para;
+uint8_t *p_ota_temp_buffer_head;
+uint16_t g_ota_tmp_buf_used_size;
+uint8_t temp_image_num = 0;
+T_TEMP_IMAGE_INFO temp_image_info[IMAGE_MAX - SecureBoot];
+
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+uint8_t ota_temp_buffer_head[DFU_TEMP_BUFFER_SIZE];
+static bool buffer_check_en = false;
+static uint32_t dfu_resend_offset = 0;
+static T_SERVER_ID dfu_service_id;
+
+P_FUN_SERVER_GENERAL_CB pfn_dfu_service_cb = NULL;
+
+const uint8_t SILENCE_GATT_UUID128_DFU_SERVICE[16] = {GATT_UUID128_DFU_SERVICE};
+
+T_ATTRIB_APPL gatt_dfu_service_table[] =
+{
+
+ /*-------------------------- DFU Service ---------------------------*/
+ /* <<Primary Service>>, .. */
+ {
+ (ATTRIB_FLAG_VOID | ATTRIB_FLAG_LE), /* flags */
+ {
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE), /* type_value */
+ },
+ UUID_128BIT_SIZE, /* bValueLen */
+ (void *)SILENCE_GATT_UUID128_DFU_SERVICE, /* p_value_context */
+ GATT_PERM_READ /* permissions */
+ },
+
+
+
+ /* <<Characteristic>>, .. */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP/* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ /*--- DFU packet characteristic value ---*/
+ {
+ ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */
+ { /* type_value */
+ GATT_UUID128_DFU_DATA
+ },
+ 0, /* bValueLen */
+ NULL,
+#if DFU_SERVER_REQUIRE_AUTH
+ GATT_PERM_WRITE_AUTHEN_MITM_REQ /* permissions */
+#else
+ GATT_PERM_WRITE /* permissions */
+#endif
+ },
+ /* <<Characteristic>>, .. */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_WRITE | /* characteristic properties */
+ GATT_CHAR_PROP_NOTIFY)
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ /*--- DFU Control Point value ---*/
+ {
+ ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */
+ { /* type_value */
+ GATT_UUID128_DFU_CONTROL_POINT
+ },
+ 0, /* bValueLen */
+ NULL,
+#if DFU_SERVER_REQUIRE_AUTH
+ GATT_PERM_WRITE_AUTHEN_MITM_REQ /* permissions */
+#else
+ GATT_PERM_WRITE /* permissions */
+#endif
+ },
+ /* client characteristic configuration */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* flags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+#if DFU_SERVER_REQUIRE_AUTH
+ (GATT_PERM_READ | GATT_PERM_WRITE_AUTHEN_MITM_REQ) /* permissions */
+#else
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */
+#endif
+ }
+
+};
+
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+static void buf_swap(uint8_t *dst, const uint8_t *src, uint16_t len)
+{
+ int i;
+ if (dst == NULL || src == NULL)
+ {
+ return;
+ }
+
+ for (i = 0; i < len; i++)
+ {
+ dst[len - 1 - i] = src[i];
+ }
+}
+
+/**
+ * @brief DFU encrypt handshake data.
+*/
+void dfu_encrypt_handshake_data(uint8_t data[16])
+{
+ uint8_t data_tmp[16] = {0};
+ buf_swap(data_tmp, data, 16);
+ aes256_ecb_encrypt_msb2lsb(data_tmp, (uint8_t *)OTP->aes_key, data_tmp);
+ buf_swap(data, data_tmp, 16);
+}
+
+/**
+ * @brief dfu_buffer_check_process
+ *
+ * @param buffer_check_size size for buffer check.
+ * @param buffer_crc calced buffer crc value.
+ * @return None
+*/
+void dfu_buffer_check_process(uint8_t conn_id, uint16_t buffer_check_size, uint16_t buffer_crc)
+{
+ uint8_t notif_data[DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC] = {0};
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_REPORT_BUFFER_CRC;
+
+ T_DFU_CALLBACK_DATA callback_data;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_attrib_index = INDEX_DFU_CONTROL_POINT_CHAR_VALUE;
+
+ if (buffer_check_size > DFU_TEMP_BUFFER_SIZE)
+ {
+ //invalid para
+ DFU_PRINT_ERROR3("<==dfu_buffer_check_process: invalid buffer_check_size=%d(>%d), cur_offset=%d",
+ buffer_check_size, DFU_TEMP_BUFFER_SIZE, g_dfu_para.cur_offset);
+ g_ota_tmp_buf_used_size = 0;
+ notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER;
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+
+ if (g_ota_tmp_buf_used_size == buffer_check_size ||
+ g_dfu_para.cur_offset + g_ota_tmp_buf_used_size == g_dfu_para.image_total_length)
+ {
+ if (dfu_check_buf_crc(p_ota_temp_buffer_head, g_ota_tmp_buf_used_size, buffer_crc))
+ {
+ //crc error
+ DFU_PRINT_ERROR1("<==dfu_buffer_check_process: Buf CRC Error! cur_offset=%d",
+ g_dfu_para.cur_offset);
+ g_ota_tmp_buf_used_size = 0;
+ notif_data[2] = DFU_ARV_FAIL_CRC_ERROR;
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+
+ else //crc ok
+ {
+ //1. devrypt data
+ if (OTP->ota_with_encryption_data)
+ {
+ dfu_hw_aes_decrypt_image(p_ota_temp_buffer_head, p_ota_temp_buffer_head, g_ota_tmp_buf_used_size);
+ }
+ //2. write flash
+ uint32_t result = dfu_update(g_dfu_para.ctrl_header.image_id,
+ g_dfu_para.cur_offset + temp_image_info[temp_image_num].image_offset,
+ g_ota_tmp_buf_used_size, (uint32_t *)p_ota_temp_buffer_head, false);
+
+ if (result == 0)
+ {
+ uint32_t updated_success_len = g_ota_tmp_buf_used_size;
+ callback_data.msg_data.write.opcode = DFU_WRITE_DOING;
+ callback_data.msg_data.write.length = 4;
+ callback_data.msg_data.write.p_value = (uint8_t *)&updated_success_len;
+ if (pfn_dfu_service_cb)
+ {
+ T_APP_RESULT w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ g_dfu_para.cur_offset += g_ota_tmp_buf_used_size;
+
+ if ((g_dfu_para.cur_offset - dfu_resend_offset) >= FMC_SEC_SECTION_LEN)
+ {
+ dfu_resend_offset += FMC_SEC_SECTION_LEN;
+ }
+ g_ota_tmp_buf_used_size = 0;
+ DFU_PRINT_INFO2("<==dfu_buffer_check_process: dfu_update Success! cur_offset=%d, dfu_resend_offset=%d",
+ g_dfu_para.cur_offset, dfu_resend_offset);
+ notif_data[2] = DFU_ARV_SUCCESS; //valid
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+ else
+ {
+ DFU_PRINT_ERROR1("<==dfu_buffer_check_process: dfu_update Fail result=%d", result);
+
+ result = dfu_flash_erase_sector_with_retry(g_dfu_para.ctrl_header.image_id, dfu_resend_offset);
+ if (result)
+ {
+ //erase fail
+ g_ota_tmp_buf_used_size = 0;
+ g_dfu_para.cur_offset = dfu_resend_offset;
+ DFU_PRINT_ERROR1("<==dfu_buffer_check_process: erase flash fail 3 times! cur_offset=%d",
+ g_dfu_para.cur_offset);
+
+ notif_data[2] = DFU_ARV_FAIL_ERASE_ERROR;
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+
+ if ((g_dfu_para.cur_offset - dfu_resend_offset) > FMC_SEC_SECTION_LEN) //need erase two sector
+ {
+ DFU_PRINT_INFO0("<==dfu_buffer_check_process:Need erase two sectors");
+ result = dfu_flash_erase_sector_with_retry(g_dfu_para.ctrl_header.image_id,
+ dfu_resend_offset + FMC_SEC_SECTION_LEN);
+ if (result)
+ {
+ //erase fail
+ g_ota_tmp_buf_used_size = 0;
+ g_dfu_para.cur_offset = dfu_resend_offset;
+ DFU_PRINT_ERROR1("<==dfu_buffer_check_process: erase flash fail 3 times! cur_offset=%d",
+ g_dfu_para.cur_offset);
+
+ notif_data[2] = DFU_ARV_FAIL_ERASE_ERROR;
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+
+ }
+ //erase ok
+ g_ota_tmp_buf_used_size = 0;
+ g_dfu_para.cur_offset = dfu_resend_offset;
+ DFU_PRINT_INFO1("<==dfu_buffer_check_process: erase ok! cur_offset=%d", g_dfu_para.cur_offset);
+ notif_data[2] = DFU_ARV_FAIL_PROG_ERROR;
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+ }
+ }
+ else
+ {
+ DFU_PRINT_ERROR4("<==dfu_buffer_check_process: Error buffer_check_size=%d,buf_used_size=%d,cur_offset=%d,image_total_length=%d",
+ buffer_check_size, g_ota_tmp_buf_used_size,
+ g_dfu_para.cur_offset, g_dfu_para.image_total_length);
+ //flush buffer.
+ g_ota_tmp_buf_used_size = 0;
+ notif_data[2] = DFU_ARV_FAIL_LENGTH_ERROR;
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+}
+
+void dfu_notify_conn_para_update_req(uint8_t conn_id, T_DFU_ARV_ERROR_CODE error_code)
+{
+ if (g_dfu_para.dfu_conn_para_update_in_progress == true)
+ {
+ g_dfu_para.dfu_conn_para_update_in_progress = false;
+ uint8_t notif_data[3] = {0};
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ;
+ notif_data[2] = error_code;
+
+ DFU_PRINT_INFO1("<==dfu_notify_conn_para_update_req error_code=0x%x", error_code);
+ /* Connection Param Update rejected, we should notify the fail result to remote device. */
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_CONN_PARA_UPDATE_REQ, GATT_PDU_TYPE_NOTIFICATION);
+ }
+}
+
+void dfu_service_handle_valid_fw(uint8_t conn_id)
+{
+ uint8_t notif_data[DFU_NOTIFY_LENGTH_VALID_FW] = {0};
+ bool check_result = false;
+ bool is_enable_bank_switch = is_ota_support_bank_switch();
+
+ if (is_enable_bank_switch)
+ {
+ check_result = dfu_check_checksum(g_dfu_para.ctrl_header.image_id, 0);
+ }
+ else
+ {
+ check_result = dfu_check_checksum(temp_image_info[temp_image_num].image_id,
+ temp_image_info[temp_image_num].image_offset);
+ }
+ DFU_PRINT_INFO1("dfu_service_handle_valid_fw: check_result=%d (1: Success, 0: Fail)", check_result);
+
+ if (check_result)
+ {
+ if (!is_enable_bank_switch)
+ {
+ temp_image_num ++;
+ DFU_PRINT_INFO1("DFU_OPCODE_VALID_FW: temp_image_num=%d ", temp_image_num);
+ }
+
+ notif_data[2] = DFU_ARV_SUCCESS;
+ }
+ else
+ {
+ notif_data[2] = DFU_ARV_FAIL_CRC_ERROR;
+ }
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_VALID_FW;
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_VALID_FW, GATT_PDU_TYPE_NOTIFICATION);
+}
+
+
+void dfu_service_handle_active_image(void)
+{
+ if (!is_ota_support_bank_switch())
+ {
+ uint32_t base_addr = 0;
+ T_IMG_CTRL_HEADER_FORMAT *p_header = NULL;
+ if (IMAGE_USER_DATA == g_dfu_para.ctrl_header.image_id)
+ {
+ /* because flash_get_bank_addr(FLASH_BKP_DATA1) is not located flash block protect range, needn't unlock bp */
+ base_addr = flash_get_bank_addr(FLASH_BKP_DATA1) | FLASH_OFFSET_TO_NO_CACHE;
+ }
+ else
+ {
+ /* check OTA temp or running bank to see if received image is OK.*/
+ base_addr = get_temp_ota_bank_addr_by_img_id((T_IMG_ID)g_dfu_para.ctrl_header.image_id);
+ }
+
+ for (uint8_t i = 0; i < temp_image_num; i++)
+ {
+ p_header = (T_IMG_CTRL_HEADER_FORMAT *)(base_addr + temp_image_info[i].image_offset);
+ dfu_set_image_ready(p_header);
+ }
+ }
+
+}
+
+/**
+ * @brief dfu_service_handle_control_point_req
+ *
+ * @param length control point cmd length.
+ * @param p_value control point cmd address..
+ * @return None
+*/
+void dfu_service_handle_control_point_req(uint8_t conn_id, uint16_t length,
+ uint8_t *p_value)
+{
+ T_APP_RESULT w_cause = APP_RESULT_SUCCESS;
+ T_DFU_CTRL_POINT dfu_control_point;
+ uint8_t *p = p_value + 1;
+ uint8_t notif_data[DFU_NOTIFY_LENGTH_MAX] = {0};
+
+ T_DFU_CALLBACK_DATA callback_data;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_attrib_index = INDEX_DFU_CONTROL_POINT_CHAR_VALUE;
+
+ dfu_control_point.opcode = *p_value;
+ DFU_PRINT_TRACE2("==>dfu_service_handle_control_point_req: opcode=0x%x, length=%d",
+ dfu_control_point.opcode, length);
+
+ if (dfu_control_point.opcode >= DFU_OPCODE_MAX || dfu_control_point.opcode <= DFU_OPCODE_MIN)
+ {
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = dfu_control_point.opcode;
+ notif_data[2] = 0xff;
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_START_DFU, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+
+ switch (dfu_control_point.opcode)
+ {
+ case DFU_OPCODE_START_DFU: //0x01
+ if (length == DFU_LENGTH_START_DFU)/*4 bytes is padding for encrypt*/
+ {
+ if (OTP->ota_with_encryption_data)
+ {
+ DFU_PRINT_INFO1("ctrl header before decryped=%b", TRACE_BINARY(16, p));
+ dfu_hw_aes_decrypt_image(p, p, 16);
+ DFU_PRINT_INFO1("ctrl header after decryped=%b", TRACE_BINARY(16, p));
+ }
+
+ dfu_control_point.start_dfu.ic_type = (*p);
+ p += 1;
+ dfu_control_point.start_dfu.secure_version = (*p);
+ p += 1;
+ LE_ARRAY_TO_UINT16(dfu_control_point.start_dfu.ctrl_flag.value, p);
+ p += 2;
+ LE_ARRAY_TO_UINT16(dfu_control_point.start_dfu.image_id, p);
+ p += 2;
+ LE_ARRAY_TO_UINT16(dfu_control_point.start_dfu.crc16, p);
+ p += 2;
+ LE_ARRAY_TO_UINT32(dfu_control_point.start_dfu.payload_len, p);
+
+ DFU_PRINT_INFO6("DFU_OPCODE_START_DFU: ic_type=0x%x, secure_version=0x%x, ctrl_flag.value=0x%x, image_id=0x%x,crc16=0x%x, payload_len=%d",
+ dfu_control_point.start_dfu.ic_type,
+ dfu_control_point.start_dfu.secure_version,
+ dfu_control_point.start_dfu.ctrl_flag.value,
+ dfu_control_point.start_dfu.image_id,
+ dfu_control_point.start_dfu.crc16,
+ dfu_control_point.start_dfu.payload_len
+ );
+ g_dfu_para.ctrl_header.ic_type = dfu_control_point.start_dfu.ic_type;
+ g_dfu_para.ctrl_header.ctrl_flag.value = dfu_control_point.start_dfu.ctrl_flag.value;
+ g_dfu_para.ctrl_header.image_id = dfu_control_point.start_dfu.image_id;
+ g_dfu_para.ctrl_header.crc16 = dfu_control_point.start_dfu.crc16;
+ g_dfu_para.ctrl_header.payload_len = dfu_control_point.start_dfu.payload_len;
+ g_dfu_para.image_total_length = g_dfu_para.ctrl_header.payload_len + IMG_HEADER_SIZE;
+
+ /*check if start dfu fields are valid*/
+ if (g_dfu_para.ctrl_header.ic_type == DEFINED_IC_TYPE)
+ {
+ if (((g_dfu_para.ctrl_header.image_id >= OTA) && (g_dfu_para.ctrl_header.image_id < IMAGE_MAX))
+ || (g_dfu_para.ctrl_header.image_id == IMAGE_USER_DATA))
+ {
+ /*disable bank switch, need record temp image info*/
+ if (!is_ota_support_bank_switch())
+ {
+ temp_image_info[temp_image_num].image_id = (T_IMG_ID)g_dfu_para.ctrl_header.image_id;
+// temp_image_info[temp_image_num].image_size = UP_ALIGN(g_dfu_para.image_total_length, FMC_SEC_SECTION_LEN);
+ temp_image_info[temp_image_num].image_size = g_dfu_para.image_total_length;
+ if (temp_image_num == 0)
+ {
+ temp_image_info[temp_image_num].image_offset = 0;
+ }
+ else
+ {
+ temp_image_info[temp_image_num].image_offset = temp_image_info[temp_image_num - 1].image_offset +
+ temp_image_info[temp_image_num - 1].image_size;
+ }
+ }
+ DFU_PRINT_INFO4("DFU_OPCODE_START_DFU: image_num=%d, image_id=0x%x, image_size=0x%x, image_offset=0x%x",
+ temp_image_num, temp_image_info[temp_image_num].image_id,
+ temp_image_info[temp_image_num].image_size, temp_image_info[temp_image_num].image_offset);
+
+ callback_data.msg_data.write.opcode = DFU_WRITE_START;
+ callback_data.msg_data.write.length = DFU_HEADER_SIZE;
+ callback_data.msg_data.write.p_value = (uint8_t *)&g_dfu_para.ctrl_header;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ uint32_t result = dfu_update(g_dfu_para.ctrl_header.image_id,
+ 0 + temp_image_info[temp_image_num].image_offset, DFU_HEADER_SIZE,
+ (uint32_t *)&g_dfu_para.ctrl_header, true);
+ if (result)
+ {
+ DBG_DIRECT("DFU_OPCODE_START_DFU: dfu_update fail=%d", result);
+ T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_UPDATE_FLASH;
+ callback_data.msg_data.write.opcode = DFU_WRITE_FAIL;
+ callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON);
+ callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ dfu_fw_reboot(false);
+ }
+ else
+ {
+ g_dfu_para.cur_offset += DFU_HEADER_SIZE;
+ DFU_PRINT_INFO0("DFU_OPCODE_START_DFU: start success!");
+
+ uint32_t updated_success_len = DFU_HEADER_SIZE;
+ callback_data.msg_data.write.opcode = DFU_WRITE_DOING;
+ callback_data.msg_data.write.length = 4;
+ callback_data.msg_data.write.p_value = (uint8_t *)&updated_success_len;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_START_DFU;
+ notif_data[2] = DFU_ARV_SUCCESS;
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_START_DFU, GATT_PDU_TYPE_NOTIFICATION);
+ }
+
+
+ }
+ else
+ {
+ DFU_PRINT_ERROR1("DFU_OPCODE_START_DFU: image id=0x%x Error!", g_dfu_para.ctrl_header.image_id);
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_START_DFU;
+ notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER;
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_START_DFU, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+ }
+ else
+ {
+ DFU_PRINT_ERROR1("DFU_OPCODE_START_DFU: ic type=0x%x Error!", g_dfu_para.ctrl_header.ic_type);
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_START_DFU;
+ notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER;
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_START_DFU, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+ }
+ break;
+
+ case DFU_OPCODE_RECEIVE_FW_IMAGE_INFO://0x02
+ if (length == DFU_LENGTH_RECEIVE_FW_IMAGE_INFO)
+ {
+ LE_ARRAY_TO_UINT16(g_dfu_para.ctrl_header.image_id, p);
+ p += 2;
+ LE_ARRAY_TO_UINT32(g_dfu_para.cur_offset, p);
+ if ((g_dfu_para.cur_offset == 0) || (g_dfu_para.cur_offset == DFU_HEADER_SIZE))
+ {
+ g_ota_tmp_buf_used_size = 0;
+ dfu_resend_offset = 0;
+ }
+ DFU_PRINT_INFO3("DFU_OPCODE_RECEIVE_FW_IMAGE_INFO: image_id=0x%x, cur_offset=%d, g_ota_tmp_buf_used_size=%d",
+ g_dfu_para.ctrl_header.image_id, g_dfu_para.cur_offset, g_ota_tmp_buf_used_size);
+ }
+ else
+ {
+ DFU_PRINT_ERROR1("DFU_OPCODE_RECEIVE_FW_IMAGE_INFO: length=%d Error!", length);
+ }
+ break;
+
+ case DFU_OPCODE_VALID_FW://0x03
+
+ if (length == DFU_LENGTH_VALID_FW)
+ {
+ LE_ARRAY_TO_UINT16(g_dfu_para.ctrl_header.image_id, p);
+ DFU_PRINT_TRACE1("DFU_OPCODE_VALID_FW: image_id=0x%x", g_dfu_para.ctrl_header.image_id);
+
+ /*if ota large img, need modify wdg timeout period*/
+ if (OTP->wdgEnableInRom && g_dfu_para.image_total_length > 0x100000)
+ {
+ /*1M and less---4s, 2M and less---8s,..., 8M and less---32s*/
+ uint32_t img_align_len = ((g_dfu_para.image_total_length + (0x100000 - 1)) & (~(0x100000 - 1)));
+ uint8_t wdg_period_4s = (img_align_len / 0x100000);
+ uint16_t div_factor = (32 * wdg_period_4s - 1);
+ DFU_PRINT_TRACE2("DFU_OPCODE_VALID_FW: Change WDG Period to %ds, div_factor=%d", wdg_period_4s << 2,
+ div_factor);
+ WDG_Config(div_factor, 15, RESET_ALL); //31 - 4s, 63 - 8s
+ }
+ /*It is not recommended to do things that take a long time in upperstack task cb.
+ So dfu service cb need send msg to app task to handle checksum image if support silent ota.
+ While app task must handle IO_MSG_TYPE_DFU_VALID_FW by calling dfu_service_handle_valid_fw.
+ */
+ }
+ else
+ {
+ DFU_PRINT_ERROR1("DFU_OPCODE_VALID_FW: length=%d Error!", length);
+ }
+ break;
+
+ case DFU_OPCODE_ACTIVE_IMAGE_RESET://0x04
+ {
+ /*when disable bank switch, need set image ready*/
+ dfu_service_handle_active_image();
+
+ /*notify bootloader to reset and use new image*/
+ DFU_PRINT_INFO0("DFU_OPCODE_ACTIVE_IMAGE_RESET");
+ callback_data.msg_data.write.opcode = DFU_WRITE_END;
+ callback_data.msg_data.write.length = DFU_HEADER_SIZE;
+ callback_data.msg_data.write.p_value = (uint8_t *)&g_dfu_para.ctrl_header;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ if (!is_ota_support_bank_switch())
+ {
+ /*note: must unlock flash bp for ota copy before reset when not support bank switch*/
+ unlock_flash_bp_all();
+ }
+ }
+ break;
+
+ case DFU_OPCODE_SYSTEM_RESET://0x05
+ {
+ /*whatever cause ota fail, client will send this cmd to reset device*/
+ DBG_DIRECT("DFU_OPCODE_SYSTEM_RESET");
+
+ /*if select not active image by Phone even if image transport successful. Not for single bank user data*/
+ if (g_dfu_para.ctrl_header.image_id >= OTA && g_dfu_para.ctrl_header.image_id < IMAGE_MAX)
+ {
+
+ uint32_t temp_addr = get_temp_ota_bank_addr_by_img_id((T_IMG_ID)g_dfu_para.ctrl_header.image_id);
+
+ T_IMG_CTRL_HEADER_FORMAT *p_temp_header = (T_IMG_CTRL_HEADER_FORMAT *)temp_addr;
+ if (p_temp_header && !p_temp_header->ctrl_flag.flag_value.not_ready)
+ {
+ flash_erase_locked(FLASH_ERASE_SECTOR, temp_addr);
+ }
+ }
+
+ T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_SYSTEM_RESET_CMD;
+ callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON);
+ callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason;
+ callback_data.msg_data.write.opcode = DFU_WRITE_FAIL;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ dfu_fw_reboot(false);
+ }
+ break;
+
+ case DFU_OPCODE_REPORT_TARGET_INFO://0x06
+ if (length == DFU_LENGTH_REPORT_TARGET_INFO)
+ {
+ LE_ARRAY_TO_UINT16(g_dfu_para.ctrl_header.image_id, p);
+ dfu_report_target_fw_info(g_dfu_para.ctrl_header.image_id, &g_dfu_para.origin_image_version,
+ (uint32_t *)&g_dfu_para.cur_offset);
+ g_dfu_para.cur_offset = 0;
+ DFU_PRINT_INFO3("DFU_OPCODE_REPORT_TARGET_INFO: image_id=0x%x,origin_image_ver=0x%x, cur_offset=%d",
+ g_dfu_para.ctrl_header.image_id, g_dfu_para.origin_image_version, g_dfu_para.cur_offset);
+
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_REPORT_TARGET_INFO;
+ notif_data[2] = DFU_ARV_SUCCESS;
+
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.origin_image_version);
+ LE_UINT32_TO_ARRAY(&notif_data[7], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_TARGET_INFO, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ else
+ {
+ DFU_PRINT_ERROR1("DFU_OPCODE_REPORT_TARGET_INFO: length=%d Error!", length);
+ }
+ break;
+
+ case DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ://0x07
+ {
+ /* no need to update connection parameters */
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ;
+ notif_data[2] = DFU_ARV_FAIL_OPERATION;
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_ARV, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ break;
+
+ case DFU_OPCODE_BUFFER_CHECK_EN: //0x09
+ {
+ le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &g_dfu_para.mtu_size, conn_id);
+ DFU_PRINT_TRACE2("DFU_OPCODE_BUFFER_CHECK_EN: mtu_size=%d, max_bufffer_size=%d",
+ g_dfu_para.mtu_size,
+ DFU_TEMP_BUFFER_SIZE);
+
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_BUFFER_CHECK_EN;
+#if (DFU_BUFFER_CHECK_ENABLE == 1)
+ buffer_check_en = true;
+ notif_data[2] = DFU_ARV_SUCCESS;
+#else
+ buffer_check_en = false;
+ notif_data[2] = DFU_ARV_FAIL_OPERATION;
+#endif
+ LE_UINT16_TO_ARRAY(&notif_data[3], DFU_TEMP_BUFFER_SIZE);
+ LE_UINT16_TO_ARRAY(&notif_data[5], g_dfu_para.mtu_size);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_BUFFER_CHECK_EN, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ break;
+
+ case DFU_OPCODE_REPORT_BUFFER_CRC: //0x0a
+ {
+ uint16_t mBufSize;
+ uint16_t mCrcVal;
+ LE_ARRAY_TO_UINT16(mBufSize, p);
+ p += 2;
+ LE_ARRAY_TO_UINT16(mCrcVal, p);
+ DFU_PRINT_INFO2("DFU_OPCODE_REPORT_BUFFER_CRC: mBufSize=0x%x, mCrcVal=0x%x", mBufSize, mCrcVal);
+ dfu_buffer_check_process(conn_id, mBufSize, mCrcVal);
+ }
+ break;
+
+ case DFU_OPCODE_RECEIVE_IC_TYPE://0x0b
+ {
+ uint8_t ic_type = 0; //0 means invalid ic type
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_RECEIVE_IC_TYPE;
+ if (dfu_report_target_ic_type(OTA, &ic_type))
+ {
+ notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER;
+ notif_data[3] = ic_type;
+ }
+ else
+ {
+ notif_data[2] = DFU_ARV_SUCCESS;
+ notif_data[3] = ic_type;
+ }
+ DFU_PRINT_INFO1("DFU_OPCODE_RECEIVE_IC_TYPE: ic_type=0x%x", ic_type);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_RECEIVE_IC_TYPE, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ break;
+
+#if (ENABLE_BANK_SWITCH_COPY_APP_DATA == 1)
+ case DFU_OPCODE_COPY_IMG://0x0c
+ {
+ uint32_t dlAddress, dlSize;
+ LE_ARRAY_TO_UINT16(g_dfu_para.ctrl_header.image_id, p);
+ p += 2;
+ LE_ARRAY_TO_UINT32(dlAddress, p);
+ p += 4;
+ LE_ARRAY_TO_UINT32(dlSize, p);
+ DFU_PRINT_TRACE2("DFU_OPCODE_COPY_IMG: dlAddress=0x%x,dlSize=0x%x", dlAddress,
+ dlSize);
+
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_COPY_IMG;
+
+ if (dfu_copy_img(g_dfu_para.ctrl_header.image_id, dlAddress, dlSize))
+ {
+ notif_data[2] = DFU_ARV_SUCCESS;
+ }
+ else
+ {
+ notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER;
+ }
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_ARV, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ break;
+#endif //end ENABLE_BANK_SWITCH_COPY_APP_DATA
+
+ case DFU_OPCODE_HANDSHAKE://0x0e
+ {
+ if (length == DFU_LENGTH_HANDSHAKE)
+ {
+ DFU_PRINT_INFO0("DFU_OPCODE_HANDSHAKE");
+
+ uint8_t handshake_data[16];
+ memcpy(handshake_data, p_value + 1, 16);
+
+ /* decrypt data */
+ if (OTP->ota_with_encryption_data)
+ {
+ dfu_hw_aes_decrypt_image(handshake_data, handshake_data, 16);
+ }
+
+ /* increase data value */
+ for (uint8_t index = 0; index < 16; index++)
+ {
+ handshake_data[index] += 1;
+ }
+
+ /* encrypt data */
+ if (OTP->ota_with_encryption_data)
+ {
+ dfu_encrypt_handshake_data(handshake_data);
+ }
+
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_HANDSHAKE;
+ notif_data[2] = DFU_ARV_SUCCESS;
+ memcpy(&notif_data[3], handshake_data, 16);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_HANDSHAKE, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ else
+ {
+ DFU_PRINT_ERROR1("DFU_OPCODE_HANDSHAKE: length=%d Error!", length);
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_HANDSHAKE;
+ notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER;
+ memset(&notif_data[3], 0, 16);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_HANDSHAKE, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ }
+ break;
+
+ default:
+ {
+ DFU_PRINT_TRACE1("dfu_service_handle_control_point_req: Unknown Opcode=0x%x",
+ dfu_control_point.opcode);
+ }
+ break;
+ }
+}
+
+
+/**
+ * @brief dfu_service_handle_packet_req
+ *
+ * @param length data reviewed length.
+ * @param p_value data receive point address.
+ * @return None
+*/
+void dfu_service_handle_packet_req(uint8_t conn_id, uint16_t length, uint8_t *p_value)
+{
+ T_APP_RESULT w_cause = APP_RESULT_SUCCESS;
+ T_DFU_CALLBACK_DATA callback_data;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_attrib_index = INDEX_DFU_PACKET_VALUE;
+ callback_data.msg_data.write.length = length;
+ callback_data.msg_data.write.p_value = p_value;
+
+ DFU_PRINT_INFO4("dfu_service_handle_packet_req: length=%d, cur_offset=%d, g_ota_tmp_buf_used_size=%d, image_total_length=%d",
+ length, g_dfu_para.cur_offset,
+ g_ota_tmp_buf_used_size, g_dfu_para.image_total_length);
+
+ if (buffer_check_en == true)
+ {
+ /*to avoid memory overflow*/
+ if (g_ota_tmp_buf_used_size + length > DFU_TEMP_BUFFER_SIZE)
+ {
+ DFU_PRINT_ERROR3("<==dfu_service_handle_packet_req: Buf overflow! ota_tmp_buf_used_size=%d,length=%d, max_buffer_size=%d",
+ g_ota_tmp_buf_used_size, length, DFU_TEMP_BUFFER_SIZE);
+
+ T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_EXCEED_MAX_BUFFER_SIZE;
+ callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON);
+ callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason;
+ callback_data.msg_data.write.opcode = DFU_WRITE_FAIL;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ dfu_fw_reboot(false);
+ }
+ else
+ {
+ memcpy(p_ota_temp_buffer_head + g_ota_tmp_buf_used_size, p_value, length);
+ g_ota_tmp_buf_used_size += length;
+ }
+ }
+ else
+ {
+ /*when disable buffer check, Default client send 20bytes per packet*/
+ uint32_t max_buffer_size = DFU_TEMP_BUFFER_SIZE - (DFU_TEMP_BUFFER_SIZE % 20);
+ /*0.check memcpy buffer boundary*/
+ if (g_ota_tmp_buf_used_size + length > max_buffer_size)
+ {
+ DBG_DIRECT("<==dfu_service_handle_packet_req: Buf overflow! ota_tmp_buf_used_size=%d,length=%d, max_buffer_size=%d",
+ g_ota_tmp_buf_used_size, length, max_buffer_size);
+
+ T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_EXCEED_MAX_BUFFER_SIZE;
+ callback_data.msg_data.write.opcode = DFU_WRITE_FAIL;
+ callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON);
+ callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ dfu_fw_reboot(false);
+ }
+
+ /*0.check total length*/
+ if (g_dfu_para.cur_offset + g_ota_tmp_buf_used_size + length > g_dfu_para.image_total_length)
+ {
+ DFU_PRINT_ERROR1("<==dfu_service_handle_packet_req: received data total length beyond image_total_length(%d bytes)",
+ g_dfu_para.image_total_length);
+
+ T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_EXCEED_IMG_TOTAL_LEN;
+ callback_data.msg_data.write.opcode = DFU_WRITE_FAIL;
+ callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON);
+ callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ dfu_fw_reboot(false);
+ }
+
+ /*start handle received data*/
+ //1. deceypt data
+ if (OTP->ota_with_encryption_data)
+ {
+ dfu_hw_aes_decrypt_image(p_value, p_value, length);
+ }
+
+ //2. copy received data to buffer
+ memcpy(p_ota_temp_buffer_head + g_ota_tmp_buf_used_size, p_value, length);
+ g_ota_tmp_buf_used_size += length;
+
+ //3. write to flash
+ if (g_ota_tmp_buf_used_size == max_buffer_size ||
+ g_dfu_para.cur_offset + g_ota_tmp_buf_used_size == g_dfu_para.image_total_length)
+ {
+ uint32_t result = dfu_update(g_dfu_para.ctrl_header.image_id,
+ g_dfu_para.cur_offset + temp_image_info[temp_image_num].image_offset,
+ g_ota_tmp_buf_used_size,
+ (uint32_t *)p_ota_temp_buffer_head, false);
+ if (result)
+ {
+ DBG_DIRECT("Buffer check disable: dfu_update fail=%d", result);
+
+ /*eflash write fail, we should restart ota procedure.*/
+ T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_UPDATE_FLASH;
+ callback_data.msg_data.write.opcode = DFU_WRITE_FAIL;
+ callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON);
+ callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ dfu_fw_reboot(false);
+ }
+ else
+ {
+ uint32_t updated_success_len = g_ota_tmp_buf_used_size;
+ callback_data.msg_data.write.opcode = DFU_WRITE_DOING;
+ callback_data.msg_data.write.length = 4;
+ callback_data.msg_data.write.p_value = (uint8_t *)&updated_success_len;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ /*update varibals value*/
+ g_dfu_para.cur_offset += g_ota_tmp_buf_used_size;
+ g_ota_tmp_buf_used_size = 0;
+ }
+ }
+ }
+
+}
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param ServiceID ServiceID to be written.
+ * @param iAttribIndex Attribute index of characteristic.
+ * @param wLength length of value to be written.
+ * @param pValue value to be written.
+ * @return Profile procedure result
+*/
+T_APP_RESULT dfu_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT w_cause = APP_RESULT_SUCCESS;
+ T_DFU_CALLBACK_DATA callback_data;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_attrib_index = attrib_index;
+ callback_data.msg_data.write.length = length;
+ callback_data.msg_data.write.p_value = p_value;
+
+ /* Notify Application. */
+ callback_data.msg_data.write.opcode = DFU_WRITE_ATTR_ENTER;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return w_cause;
+ }
+ }
+
+ if (attrib_index == INDEX_DFU_CONTROL_POINT_CHAR_VALUE)
+ {
+ dfu_service_handle_control_point_req(conn_id, length, p_value);
+ }
+ else if (attrib_index == INDEX_DFU_PACKET_VALUE)
+ {
+ dfu_service_handle_packet_req(conn_id, length, p_value);
+ }
+ else
+ {
+ DFU_PRINT_INFO1("dfu_attr_write_cb fail! attrib_index=%d", attrib_index);
+ w_cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+
+ /* Notify Application. */
+ callback_data.msg_data.write.opcode = DFU_WRITE_ATTR_EXIT;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return w_cause;
+ }
+ }
+
+ return w_cause;
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param ServiceId Service ID.
+ * @param Index Attribute index of characteristic data.
+ * @param wCCCBits CCCD bits from stack.
+ * @return None
+*/
+void dfu_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ T_DFU_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.conn_id = conn_id;
+ bool b_handle = true;
+ DFU_PRINT_INFO2("dfu_cccd_update_cb: index=%d, ccc_bits=0x%x", index, ccc_bits);
+ switch (index)
+ {
+ case INDEX_DFU_CHAR_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ // Enable Notification
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = DFU_NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = DFU_NOTIFY_DISABLE;
+ }
+ break;
+ }
+ default:
+ {
+ b_handle = false;
+ break;
+ }
+
+ }
+ /* Notify Application. */
+ if (pfn_dfu_service_cb && (b_handle == true))
+ {
+ T_APP_RESULT update_cause = pfn_dfu_service_cb(service_id, (void *)&callback_data);
+ if (update_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ return;
+}
+
+/**
+ * @brief OTA ble Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS DfuServiceCBs =
+{
+ NULL, // Read callback function pointer
+ dfu_attr_write_cb, // Write callback function pointer
+ dfu_cccd_update_cb // CCCD update callback function pointer
+};
+
+/**
+ * @brief add OTA ble service to application.
+ *
+ * @param pFunc pointer of app callback function called by profile.
+ * @return service ID auto generated by profile layer.
+ * @retval ServiceId
+*/
+uint8_t dfu_add_service(void *pFunc)
+{
+ if (false == server_add_service(&dfu_service_id,
+ (uint8_t *)gatt_dfu_service_table,
+ sizeof(gatt_dfu_service_table),
+ DfuServiceCBs))
+ {
+ DFU_PRINT_ERROR1("dfu_add_service: service_id=%d", dfu_service_id);
+ dfu_service_id = 0xff;
+ return dfu_service_id;
+ }
+ pfn_dfu_service_cb = (P_FUN_SERVER_GENERAL_CB)pFunc;
+ p_ota_temp_buffer_head = ota_temp_buffer_head;
+
+ return dfu_service_id;
+}
+
+
diff --git a/src/app/google_rcu/profile_module/dfu_service.h b/src/app/google_rcu/profile_module/dfu_service.h
new file mode 100644
index 0000000..a5af29f
--- /dev/null
+++ b/src/app/google_rcu/profile_module/dfu_service.h
@@ -0,0 +1,117 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file dfu_service.h
+* @brief
+* @details
+* @author ken_mei
+* @date 02-09-2016
+* @version v1.0.0
+******************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2015 Realtek Semiconductor Corporation</center></h2>
+******************************************************************************
+*/
+
+#ifndef _DFU_SERVICE_H_
+#define _DFU_SERVICE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "profile_server.h"
+#include "patch_header_check.h"
+#include "dfu_api.h"
+
+#define DFU_NOTIFY_ENABLE 1
+#define DFU_NOTIFY_DISABLE 2
+
+/*attribut index*/
+#define INDEX_DFU_PACKET_VALUE 0x02
+#define INDEX_DFU_CONTROL_POINT_CHAR_VALUE 0x04
+#define INDEX_DFU_CHAR_CCCD_INDEX 0x05
+
+
+
+typedef struct _T_DFU_CTRL_POINT
+{
+ uint8_t opcode;
+ T_IMG_CTRL_HEADER_FORMAT start_dfu; /* start dfu trans first 12 bytes ctrl header*/
+} T_DFU_CTRL_POINT, * P_DFU_CTRL_POINT;
+
+typedef struct
+{
+ T_IMG_CTRL_HEADER_FORMAT ctrl_header;
+ uint32_t image_total_length;
+ uint32_t origin_image_version;
+ uint32_t cur_offset;
+ uint8_t mtu_size;
+ bool dfu_conn_para_update_in_progress;
+ uint16_t dfu_conn_interval;
+ uint16_t dfu_conn_lantency;
+} T_DFU_PARA;
+
+typedef struct
+{
+ T_IMG_ID image_id;
+ uint32_t image_size;
+ uint32_t image_offset;
+} T_TEMP_IMAGE_INFO;
+
+typedef enum
+{
+ DFU_FAIL_UPDATE_FLASH,
+ DFU_FAIL_SYSTEM_RESET_CMD,
+ DFU_FAIL_EXCEED_MAX_BUFFER_SIZE,
+ DFU_FAIL_EXCEED_IMG_TOTAL_LEN,
+
+} T_DFU_FAIL_REASON;
+
+typedef enum
+{
+ DFU_WRITE_ATTR_ENTER,
+ DFU_WRITE_ATTR_EXIT,
+ DFU_WRITE_START,
+ DFU_WRITE_DOING,
+ DFU_WRITE_END,
+ DFU_WRITE_FAIL,
+} T_DFU_WRITE_OPCODE;
+
+
+typedef struct
+{
+ uint8_t opcode;
+ uint8_t write_attrib_index;
+ uint16_t length;
+ uint8_t *p_value;
+} T_DFU_WRITE_MSG;
+
+typedef union _TDFU_UPSTREAM_MSG_DATA
+{
+ uint8_t notification_indification_index;
+ T_DFU_WRITE_MSG write;
+} T_DFU_UPSTREAM_MSG_DATA;
+
+/** Dfu service data to inform application */
+typedef struct _TDFU_CALLBACK_DATA
+{
+ uint8_t conn_id;
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_DFU_UPSTREAM_MSG_DATA msg_data;
+} T_DFU_CALLBACK_DATA;
+
+extern uint8_t *p_ota_temp_buffer_head;
+extern uint16_t g_ota_tmp_buf_used_size;
+extern T_DFU_PARA g_dfu_para;
+
+extern void dfu_notify_conn_para_update_req(uint8_t conn_id, T_DFU_ARV_ERROR_CODE error_code);
+extern void dfu_service_handle_valid_fw(uint8_t conn_id);
+extern uint8_t dfu_add_service(void *pFunc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/app/google_rcu/profile_module/fms.c b/src/app/google_rcu/profile_module/fms.c
new file mode 100644
index 0000000..b2ac182
--- /dev/null
+++ b/src/app/google_rcu/profile_module/fms.c
@@ -0,0 +1,292 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file fms.c
+* @brief Find Me service source file.
+* @details Interfaces to access Find Me service.
+* @author Chenjie jin
+* @date 2022-05-31
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#include "board.h"
+#include "string.h"
+#include "trace.h"
+#include "gatt.h"
+#include "profile_server.h"
+#include "fms.h"
+#include "fms_service_handle.h"
+#include "gap.h"
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+static uint16_t Fms_Ctl_mode;
+static P_FUN_SERVER_GENERAL_CB pfn_fms_cb = NULL;
+static const uint8_t GATT_UUID_FMS_SERVICE[16] = {GATT_UUID128_FMS_SERVICE};
+
+/********************************************************************************************************
+* global variables
+********************************************************************************************************/
+/**< @brief profile/service definition.
+* here is an example of fms service table
+* including Write
+*/
+const T_ATTRIB_APPL fms_svc_attr_tbl[] =
+{
+ /*--------------------------FMS Service ---------------------------*/
+ /* <<Primary Service>>, .. 0*/
+ {
+ (ATTRIB_FLAG_VOID | ATTRIB_FLAG_LE), /* wFlags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ },
+ UUID_128BIT_SIZE, /* bValueLen */
+ (void *)GATT_UUID_FMS_SERVICE, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic>> 1 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* FMS Control 2 */
+ {
+ ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* wFlags */
+ { /* type_value */
+ GATT_UUID128_FMS_CONTROL
+ },
+ 0, /* variable size */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ },
+
+ /* <<Characteristic>> 3 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* FMS Data 4 */
+ {
+ ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* wFlags */
+ { /* type_value */
+ GATT_UUID128_FMS_DATA
+ },
+ 0, /* variable size */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ },
+
+ /* client characteristic configuration 5 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* flags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */
+ }
+};
+
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param conn_id Connection ID.
+ * @param service_id ServiceID to be read.
+ * @param attrib_index Attribute index of getting characteristic data.
+ * @param offset Offset of characteritic to be read.
+ * @param p_length Length of getting characteristic data.
+ * @param pp_value Pointer to pointer of characteristic value to be read.
+ * @return T_APP_RESULT
+*/
+T_APP_RESULT fms_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ *p_length = 0;
+
+ PROFILE_PRINT_INFO2("fms_attr_read_cb attrib_index = %d offset %x", attrib_index, offset);
+
+ switch (attrib_index)
+ {
+ case GATT_SVC_FMS_CONTROL_INDEX:
+ {
+ /* update Fms_Ctl_mode */
+ Fms_Ctl_mode = fms_handle_get_current_mode();
+
+ *pp_value = (uint8_t *)&Fms_Ctl_mode;
+ *p_length = 2;
+ }
+ break;
+
+ default:
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+ }
+
+ return cause;
+}
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param ServiceID ServiceID to be written.
+ * @param iAttribIndex Attribute index of characteristic.
+ * @param wLength length of value to be written.
+ * @param pValue value to be written.
+ * @return Profile procedure result
+*/
+T_APP_RESULT fms_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ bool handle = true;
+ T_FMS_CALLBACK_DATA callback_data;
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+
+ APP_PRINT_INFO1("[fms_attr_write_cb] attrib_index is %d", attrib_index);
+
+ if (GATT_SVC_FMS_CONTROL_INDEX == attrib_index)
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write_msg.write_type = FMS_WRITE_CHAR_CONTROL;
+ callback_data.msg_data.write_msg.write_parameter.report_data.len = length;
+ callback_data.msg_data.write_msg.write_parameter.report_data.report = p_value;
+ }
+ else if (GATT_SVC_FMS_DATA_INDEX == attrib_index)
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write_msg.write_type = FMS_WRITE_CHAR_DATA;
+ callback_data.msg_data.write_msg.write_parameter.report_data.len = length;
+ callback_data.msg_data.write_msg.write_parameter.report_data.report = p_value;
+ }
+
+ if ((pfn_fms_cb) && (handle == true))
+ {
+ pfn_fms_cb(service_id, (void *)&callback_data);
+ }
+
+ return cause;
+
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param ServiceId Service ID.
+ * @param Index Attribute index of characteristic data.
+ * @param wCCCBits CCCD bits from stack.
+ * @return None
+*/
+void fms_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index,
+ uint16_t ccc_bits)
+{
+ bool handle = true;
+ T_FMS_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+
+ APP_PRINT_INFO2("[fms_cccd_update_cb] index = %d, ccc_bits %x", index, ccc_bits);
+ switch (index)
+ {
+ case GATT_SVC_FMS_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = FMS_DATA_NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = FMS_DATA_NOTIFY_DISABLE;
+ }
+ break;
+ }
+ default:
+ {
+ handle = false;
+ break;
+ }
+ }
+
+ if (pfn_fms_cb && (handle == true))
+ {
+ /* Notify Application */
+ pfn_fms_cb(service_id, (void *)&callback_data);
+ }
+
+ return;
+}
+
+/**
+ * @brief FMS Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS fms_cbs =
+{
+ fms_attr_read_cb, // Read callback function pointer
+ fms_attr_write_cb, // Write callback function pointer
+ fms_cccd_update_cb // CCCD update callback function pointer
+};
+
+/**
+ * @brief Add FMS service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ bas_id = fms_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+uint8_t fms_add_service(void *p_func)
+{
+ uint8_t service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)fms_svc_attr_tbl,
+ sizeof(fms_svc_attr_tbl),
+ fms_cbs))
+ {
+ APP_PRINT_INFO1("fms_add_service: service_id %d", service_id);
+ service_id = 0xff;
+ return service_id;
+ }
+ pfn_fms_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
diff --git a/src/app/google_rcu/profile_module/fms.h b/src/app/google_rcu/profile_module/fms.h
new file mode 100644
index 0000000..63587e7
--- /dev/null
+++ b/src/app/google_rcu/profile_module/fms.h
@@ -0,0 +1,103 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file fms.h
+ * @brief Head file for using Find me Service.
+ * @details Find Me service data structs and external functions declaration.
+ * @author Chenjie Jin
+ * @date 2022-05-31
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#ifndef _FMS_H_
+#define _FMS_H_
+
+#include "profile_server.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/** @brief Demo Profile service related UUIDs. */
+#define GATT_UUID128_FMS_SERVICE 0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0x01, 0x00, 0x02, 0x18
+#define GATT_UUID128_FMS_CONTROL 0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0x02, 0x00, 0x02, 0x18
+#define GATT_UUID128_FMS_DATA 0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0x03, 0x00, 0x02, 0x18
+
+
+/** @brief Index of each characteristic in Demo Profile service database. */
+#define GATT_SVC_FMS_CONTROL_INDEX 2
+#define GATT_SVC_FMS_DATA_INDEX 4
+#define GATT_SVC_FMS_CCCD_INDEX 5
+
+/** @brief fms service write event */
+#define FMS_WRITE_CHAR_CONTROL 1
+#define FMS_WRITE_CHAR_DATA 2
+
+/** @brief fms service write event length*/
+#define FMS_WRITE_CHAR_CONTROL_LEN 2
+
+/** @brief fms service notification flag */
+#define FMS_DATA_NOTIFY_ENABLE 1
+#define FMS_DATA_NOTIFY_DISABLE 2
+
+/** @brief FMS_CTL_MODE */
+#define FMS_CTL_MODE_DISABLE_ALL 0x0000 /* disable all features */
+#define FMS_CTL_MODE_ALERT 0xE100 /* ready for Find me */
+
+/** @brief FMS_DATA_EVNET */
+#define FMS_DATA_STOP_ALERT 0x0000 /* disable buzzer */
+#define FMS_DATA_ALERT_LEVEL_LOW 0xE101 /* run the buzzer at low vol. */
+#define FMS_DATA_ALERT_LEVEL_MEDIUM 0xE102 /* run the buzzer at medium vol. */
+#define FMS_DATA_ALERT_LEVEL_HIGH 0xE103 /* run the buzzer at high vol. */
+
+/** @brief status or error type */
+#define FMS_STATUS_OK 0xE180
+#define FMS_STATUS_ERROR 0x0F00
+
+#define FMS_ERROR_NO_ERR 0x0000
+#define FMS_ERROR_MODE_DISABLED 0x0F01
+#define FMS_ERROR_UNKNOWN_CMD 0x0F02
+
+/** Message content */
+typedef union
+{
+ struct
+ {
+ uint16_t len;
+ uint8_t *report;
+ } report_data;
+} T_FMS_WRITE_PARAMETER;
+
+/** @struct T_FMS_WRITE_MSG
+ * @brief write message
+ */
+typedef struct
+{
+ uint8_t write_type; /**< ref: @ref IR_Write_Info */
+ T_FMS_WRITE_PARAMETER write_parameter;
+} T_FMS_WRITE_MSG;
+
+typedef union _FMS_UPSTREAM_MSG_DATA
+{
+ uint8_t read_value_index;
+ uint8_t notification_indification_index;
+ T_FMS_WRITE_MSG write_msg;
+} T_FMS_UPSTREAM_MSG_DATA;
+
+/** FMS service data to inform application */
+typedef struct _T_FMS_CALLBACK_DATA
+{
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_FMS_UPSTREAM_MSG_DATA msg_data;
+} T_FMS_CALLBACK_DATA;
+
+uint8_t fms_add_service(void *pFunc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/app/google_rcu/profile_module/hids_rmc.c b/src/app/google_rcu/profile_module/hids_rmc.c
new file mode 100644
index 0000000..7f03a45
--- /dev/null
+++ b/src/app/google_rcu/profile_module/hids_rmc.c
@@ -0,0 +1,670 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file hids_rmc.c
+* @brief Remote control HID service source file.
+* @details Interfaces to access HIDS service.
+* @author
+* @date
+* @version v1.0
+*********************************************************************************************************
+*/
+#include "profile_server.h"
+#include "hids_rmc.h"
+#include <string.h>
+#include <trace.h>
+#include "board.h"
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+static P_FUN_SERVER_GENERAL_CB pfn_hids_cb = NULL;
+
+static const uint8_t hids_report_descriptor[] =
+{
+ 0x05, 0x01, /* Usage Page(Generic Desktop) */
+ 0x09, 0x06, /* Usage (Keyboard) */
+ 0xa1, 0x01, /* Collection Application */
+
+ 0x05, 0x07, /* Usage Page (Keyboard) */
+ 0x09, 0x06, /* Usage (Keyboard) */
+ 0xa1, 0x01, /* Collection Application */
+ 0x85, HIDS_KB_REPORT_ID, /* Report Id */
+ 0x95, 0x08, /* Report Count */
+ 0x75, 0x08, /* Report Size */
+ 0x15, 0x00, /* Logical Minimum */
+ 0x25, 0xff, /* Logical Maximum */
+ 0x19, 0x00, /* Usage Minimum */
+ 0x29, 0xff, /* Usage Maximum */
+ 0x81, 0x00, /* Input */
+ 0xc0, /* End Collection */
+
+ 0x05, 0x0c, /* USAGE_PAGE (Consumer) */
+ 0x09, 0x01, /* USAGE (Consumer Control) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ 0x85, HIDS_MM_KB_REPORT_ID, /* REPORT_ID (4) */
+ 0x95, 0x03, /* report count */
+ 0x75, 0x10, /* report size */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x26, 0x9C, 0x02, /* LOGICAL_MAXIMUM (1) */
+ 0x19, 0x00, /* Usage Minimum */
+ 0x2A, 0x9C, 0x02, /* Usage Maximum */
+ 0x81, 0x00, /* INPUT (Data,Var,Abs) */
+ 0xc0, /* END_COLLECTION */
+
+ 0xc0 /* End Collection */
+};
+
+static uint8_t hids_protocol_mode = REPORT_PROCOCOL_MODE;
+static uint8_t hids_suspand_mode = 0;
+static HID_INFO_ATTRB hids_info = {0, 0, 0x0100};
+static uint8_t *p_report_data = NULL;
+static uint16_t RmcDataLen = 0;
+
+
+const T_ATTRIB_APPL hids_attr_table[] =
+{
+ /*--------------------------HID Service ---------------------------*/
+ /* <<Primary Service>> 0 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_HID), /* service UUID */
+ HI_WORD(GATT_UUID_HID)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* p_value_context */
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* <<characteristic>> 1 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* HID Information characteristic 2 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_HID_INFO),
+ HI_WORD(GATT_UUID_CHAR_HID_INFO)
+ },
+ 4, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ GATT_PERM_READ_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_READ /* permissions */
+#endif
+ },
+
+ /* <<Characteristic>> 3 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* HID controlPoint characteristic 4 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT),
+ HI_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT)
+ },
+ 1, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* permissions */
+#endif
+ },
+
+ /* <<Characteristic>> 5 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* HID Protocol Mode characteristic 6 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_PROTOCOL_MODE),
+ HI_WORD(GATT_UUID_CHAR_PROTOCOL_MODE)
+ },
+ 1, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* permissions */
+#endif
+ },
+
+ /* <<Characteristic>> 7 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* HID Report Map characteristic 8 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_REPORT_MAP),
+ HI_WORD(GATT_UUID_CHAR_REPORT_MAP)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ GATT_PERM_READ_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_READ /* permissions */
+#endif
+ },
+
+ /* <<Characteristic>> 9 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* Keyboard Input Report characteristic 10 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 8, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* permissions */
+#endif
+ },
+
+ /* client characteristic configuration 11 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* flags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */
+#endif
+ },
+
+ /* Keyboard Input Report reference descriptor 12 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* flags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ HIDS_KB_REPORT_ID, /* client char. config. bit field */
+ 1
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* permissions */
+#endif
+ },
+
+ /* <<Characteristic>> 20 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* HID Report characteristic value, multimedia keyboard Input 21 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 3, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* permissions */
+#endif
+ },
+
+ /* client characteristic configuration 22 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* flags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */
+#endif
+ },
+
+ /* multimedia keyboard Input reference descriptor 23 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* flags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ HIDS_MM_KB_REPORT_ID, /* client char. config. bit field */
+ HID_INPUT_TYPE
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* permissions */
+#endif
+ }
+};
+
+uint16_t hids_attr_tbl_size = sizeof(hids_attr_table);
+
+/**
+ * @brief Set a HID service parameter.
+ *
+ * NOTE: You can call this function with a HID service parameter type and it will set the
+ * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE.
+ *
+ * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t mode = 1;
+ hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode);
+ }
+ * \endcode
+ */
+bool hids_set_parameter(uint8_t param_type, uint8_t length, void *value_ptr)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ case HIDS_PARAM_PROTOCOL_MODE:
+ {
+ hids_protocol_mode = *((uint8_t *)value_ptr);
+ }
+ break;
+ case HIDS_PARAM_SUSPEND_MODE:
+ {
+ hids_suspand_mode = *((uint8_t *)value_ptr);
+ }
+ break;
+ case HIDS_PARAM_HID_INFO:
+ {
+ memcpy((void *)&hids_info, value_ptr, length);
+ }
+ break;
+ case HIDS_PARAM_REPORT:
+ {
+ RmcDataLen = length;
+ p_report_data = value_ptr;
+ }
+ break;
+
+ default:
+ ret = false;
+ break;
+
+ }
+ return ret;
+}
+
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param conn_id Connection ID.
+ * @param service_id ServiceID to be read.
+ * @param attrib_index Attribute index of getting characteristic data.
+ * @param offset Offset of characteritic to be read.
+ * @param p_length Length of getting characteristic data.
+ * @param pp_value Pointer to pointer of characteristic value to be read.
+ * @return T_APP_RESULT
+*/
+T_APP_RESULT hids_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ T_HID_CALLBACK_DATA callback_data;
+ *p_length = 0;
+
+ PROFILE_PRINT_INFO2("hids_attr_read_cb attrib_index = %d offset %x", attrib_index, offset);
+
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ switch (attrib_index)
+ {
+ default:
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+
+ case GATT_SRV_HID_KB_INPUT_INDEX:
+ case GATT_SRV_HID_MM_KB_INPUT_INDEX:
+ {
+ callback_data.msg_data.read_value_index = HIDS_READ_PARAM_REPORT;
+ if (pfn_hids_cb)
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+ *pp_value = p_report_data;
+ *p_length = RmcDataLen;
+ if ((*p_length == 0) || (NULL == p_report_data))
+ {
+ cause = APP_RESULT_APP_ERR;
+ }
+ }
+ break;
+
+ case GATT_SVC_HID_INFO_INDEX:
+ {
+ callback_data.msg_data.read_value_index = HIDS_READ_PARAM_HID_INFO;
+ if (pfn_hids_cb)
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+ *pp_value = (uint8_t *)&hids_info;
+ *p_length = sizeof(hids_info);
+ }
+ break;
+ case GATT_SVC_HID_CONTROL_POINT_INDEX:
+ {
+ callback_data.msg_data.read_value_index = HIDS_READ_PARAM_SUSPEND_MODE;
+ if (pfn_hids_cb)
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+ *pp_value = &hids_suspand_mode;
+ *p_length = 1;
+ }
+ break;
+ case GATT_SVC_HID_PROTOCOL_MODE_INDEX:
+ {
+ callback_data.msg_data.read_value_index = HIDS_READ_PARAM_PROTOCOL_MODE;
+ if (pfn_hids_cb)
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+ *pp_value = &hids_protocol_mode;
+ *p_length = sizeof(hids_protocol_mode);
+ }
+ break;
+ case GATT_SVC_HID_REPORT_MAP_INDEX:
+ {
+ *pp_value = (uint8_t *)hids_report_descriptor;
+ *p_length = sizeof(hids_report_descriptor);
+ }
+ break;
+ }
+
+ return cause;
+}
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID to be written.
+ * @param[in] attrib_index Attribute index of characteristic.
+ * @param[in] write_type Write type.
+ * @param[in] length Length of writing characteristic data.
+ * @param[in] p_value Pointer to characteristic data.
+ * @param[in] p_write_ind_post_proc Function pointer after ias_attr_write_cb.
+ * @return TProfileResult
+*/
+T_APP_RESULT hids_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ T_HID_CALLBACK_DATA callback_data;
+ if (!p_value)
+ {
+ PROFILE_PRINT_ERROR2("hids_attr_write_cb: p_value %p length= 0x%x", p_value, length);
+ cause = APP_RESULT_INVALID_PDU;
+ return cause;
+ }
+
+ switch (attrib_index)
+ {
+ default:
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+ case GATT_SVC_HID_PROTOCOL_MODE_INDEX:
+ {
+ hids_protocol_mode = *p_value;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_type = HID_WRITE_PROTOCOL_MODE;
+ callback_data.msg_data.write.write_parameter.protocol_mode = *p_value;
+
+ cause = APP_RESULT_SUCCESS;
+ APP_PRINT_INFO1("--> host write hids_protocol_mode %d ",
+ hids_protocol_mode);
+ }
+ break;
+ case GATT_SVC_HID_CONTROL_POINT_INDEX:
+ {
+ hids_suspand_mode = *p_value;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_type = HID_WRITE_SUSPEND_MODE;
+ callback_data.msg_data.write.write_parameter.suspend_mode = *p_value;
+
+ cause = APP_RESULT_SUCCESS;
+ APP_PRINT_INFO1("--> host write hids_suspand_mode %d",
+ hids_suspand_mode);
+ }
+ break;
+ case GATT_SRV_HID_KB_INPUT_INDEX:
+ case GATT_SRV_HID_MM_KB_INPUT_INDEX:
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_type = HID_WRITE_INPUT_REPORT;
+ callback_data.msg_data.write.write_parameter.report_data.reportLen = length;
+ callback_data.msg_data.write.write_parameter.report_data.report = p_value;
+ cause = APP_RESULT_SUCCESS;
+ }
+ break;
+ }
+
+ if (pfn_hids_cb && (cause == APP_RESULT_SUCCESS))
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+
+ return cause;
+
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param conn_id Connection ID.
+ * @param service_id Service ID.
+ * @param index Attribute index of characteristic data.
+ * @param ccc_bits CCCD bits from stack.
+ * @return None
+*/
+void hids_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ T_HID_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ bool handle = true;
+
+ PROFILE_PRINT_INFO2("hids_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits);
+ switch (index)
+ {
+ case GATT_SRV_HID_KB_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_KB_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_KB_DISABLE;
+ }
+ }
+ break;
+ case GATT_SRV_HID_MM_KB_INPUT_CCCD_INDEX:
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_MM_KB_ENABLE;
+
+ }
+ else
+ {
+ callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_MM_KB_DISABLE;
+ }
+ break;
+ default:
+ handle = false;
+ break;
+ }
+
+ if (pfn_hids_cb && (handle == true))
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+
+ return;
+}
+
+/**
+ * @brief HID Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS hids_cbs =
+{
+ hids_attr_read_cb, // Read callback function pointer
+ hids_attr_write_cb, // Write callback function pointer
+ hids_cccd_update_cb // Authorization callback function pointer
+};
+
+/**
+ * @brief Add HIDS service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ bas_id = hids_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+uint8_t hids_add_service(void *p_func)
+{
+ uint8_t service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)hids_attr_table,
+ hids_attr_tbl_size,
+ hids_cbs))
+ {
+ APP_PRINT_ERROR1("hids_add_service: ServiceId %d", service_id);
+ service_id = 0xff;
+ }
+
+ pfn_hids_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
diff --git a/src/app/google_rcu/profile_module/hids_rmc.h b/src/app/google_rcu/profile_module/hids_rmc.h
new file mode 100644
index 0000000..1be50c2
--- /dev/null
+++ b/src/app/google_rcu/profile_module/hids_rmc.h
@@ -0,0 +1,227 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hids_rmc.h
+ * @brief Head file for using Human Interface Device Service Remote Controller.
+ * @details HIDS RMC data structs and external functions declaration.
+ * @author Chenjie Jin
+ * @date 2018-5-7
+ * @version v1.1
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _HIDS_RMC_H
+#define _HIDS_RMC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Add Includes here */
+#include "profile_server.h"
+#include "board.h"
+
+/** @defgroup HIDS_RmC HIDS Human Interface Device Service of Remote Controller
+ * @brief Human Interface Device Service Remote Controller
+ * @{
+ */
+
+/** @defgroup HIDS_RmC_Exported_Constants HIDS RmC Exported Constants
+ * @brief macros that other .c files may use all defined here
+ * @{
+ */
+
+/** @brief HIDS Report Id Definition. */
+#define HIDS_KB_REPORT_ID 1
+#define HIDS_MM_KB_REPORT_ID 2
+
+
+/** @defgroup HIDS_RmC_Application_Parameters HIDS RmC Application Parameters
+ * @brief Type of parameters set/got from application.
+ * @{
+ */
+#define HIDS_PARAM_PROTOCOL_MODE 1
+#define HIDS_PARAM_SUSPEND_MODE 2
+#define HIDS_PARAM_HID_INFO 3
+#define HIDS_PARAM_REPORT 4
+/** @} */
+
+///@cond
+/** @brief HIDS_RmC related UUIDs. */
+#define GATT_UUID_HID 0x1812
+#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C
+#define GATT_UUID_CHAR_HID_INFO 0x2A4A
+#define GATT_UUID_CHAR_REPORT 0x2A4D
+#define GATT_UUID_CHAR_REPORT_MAP 0x2A4B
+#define GATT_UUID_CHAR_RECORD_ACCESS_POINT 0x2A52
+#define GATT_UUID_CHAR_PROTOCOL_MODE 0x2A4E
+#define GATT_UUID_CHAR_BOOT_KB_IN_REPORT 0x2A22
+#define GATT_UUID_CHAR_BOOT_KB_OUT_REPORT 0x2A32
+#define GATT_UUID_CHAR_BOOT_MOUSE_IN_REPORT 0x2A33
+#define GATT_UUID_CHAR_REPORT_REFERENCE 0x2908
+#define GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE 0x2907
+
+///@endcond
+
+/** @defgroup HIDS_RmC_Attribute_Index HIDS RmC Attribute Index
+ * @brief Index defines for Characteristic's value in HID Device
+ * @{
+ */
+#define GATT_SRV_HID_INDEX_MAX 23
+#define GATT_SVC_HID_INFO_INDEX (2) /**< @brief Index for HID Information chars's value */
+#define GATT_SVC_HID_CONTROL_POINT_INDEX (4) /**< @brief Index for HID Control Point chars's value */
+#define GATT_SVC_HID_PROTOCOL_MODE_INDEX (6) /**< @brief Index for HID Protocol Mode chars's value */
+#define GATT_SVC_HID_REPORT_MAP_INDEX (8) /**< @brief Index for HID Report Map chars's value */
+
+#define GATT_SRV_HID_KB_INPUT_INDEX (10)
+#define GATT_SRV_HID_KB_CCCD_INDEX (GATT_SRV_HID_KB_INPUT_INDEX + 1)
+
+#define GATT_SRV_HID_MM_KB_INPUT_INDEX (14)
+#define GATT_SRV_HID_MM_KB_INPUT_CCCD_INDEX (GATT_SRV_HID_MM_KB_INPUT_INDEX + 1)
+
+/** @} */
+
+/** @defgroup HIDS_RmC_Upstream_Message HIDS RmC Upstream Message
+ * @brief Upstream message used to inform application.
+ * @{
+ */
+
+/** @defgroup HIDS_RmC_Read_Info HIDS RmC Read Info
+ * @brief Parameter for read characteristic value.
+ * @{
+ */
+#define HIDS_READ_PARAM_PROTOCOL_MODE 1
+#define HIDS_READ_PARAM_SUSPEND_MODE 2
+#define HIDS_READ_PARAM_HID_INFO 3
+#define HIDS_READ_PARAM_REPORT 4
+/** @} */
+
+/** @defgroup HIDS_RmC_Write_Info HIDS RmC Write Info
+ * @brief Parameter for write characteristic value.
+ * @{
+ */
+#define HID_WRITE_PROTOCOL_MODE 1
+#define HID_WRITE_SUSPEND_MODE 2
+#define HID_WRITE_OUTPUT 3
+#define HID_WRITE_INPUT_REPORT 4
+/** @} */
+
+/** @defgroup HIDS_RmC_Notify_Indicate_Info HIDS RmC Notify Indicate Info
+ * @brief Parameter for enable or disable notification or indication.
+ * @{
+ */
+#define HID_NOTIFY_INDICATE_KB_ENABLE 1
+#define HID_NOTIFY_INDICATE_KB_DISABLE 2
+#define HID_NOTIFY_INDICATE_MM_KB_ENABLE 3
+#define HID_NOTIFY_INDICATE_MM_KB_DISABLE 4
+
+/** @} */
+
+/** @} End of HIDS_RmC_Upstream_Message */
+
+/** @} End of HIDS_RmC_Exported_Constants */
+
+/** @defgroup HIDS_RmC_Exported_Types HIDS RmC Exported Types
+ * @brief types that other.c files may use all defined here
+ * @{
+ */
+
+/* Add all public types here */
+
+/** @struct _HID_INFO_ATTRB hids_rmc.h "hids_rmc.h"
+ * @brief type define for value of HID information
+ */
+typedef struct _HID_INFO_ATTRB
+{
+ uint8_t CountryCode;
+ uint8_t bFlags;
+ uint16_t BcdHID;
+} HID_INFO_ATTRB;
+
+/** @brief enum for TProfile_HIDReportType*/
+typedef enum
+{
+ HID_INPUT_TYPE = 1, /**< @enum Input report */
+ HID_OUTPUT_TYPE = 2, /**< @enum Output report */
+ HID_FEATURE_TYPE = 3 /**< @enum Feature report */
+} TProfile_HIDReportType;
+
+/** @struct _TProfile_REPORT_REFE_TABLE hids_rmc.h "hids_rmc.h"
+ * @brief type define for info reference to report data
+ */
+typedef struct _TProfile_REPORT_REFE_TABLE
+{
+ uint8_t report_size; /**< @brief report size according to value of Report Map value, byte */
+ uint8_t report_id; /**< @brief report ID defined in value of Report Map Char, byte */
+ uint8_t report_type; /**< @brief report Type(Input,Output,Feature), ref: @ref TProfile_HIDReportType */
+} TProfile_REPORT_REFE_TABLE;
+
+/** @defgroup HIDS_RmC_Callback_Data HIDS RmC Callback Data
+ * @brief HIDS RmC data struct for notification data to application.
+ * @{
+ */
+
+/** @brief value for HID protocol mode characteristic */
+enum TProfile_HID_PROTOCOL_MODE
+{
+ BOOT_PROTOCOL_MODE = 0, /**< @enum boot protocol mode */
+ REPORT_PROCOCOL_MODE = 1 /**< @enum report protocol mode */
+};
+
+typedef union _THID_WRITE_PARAMETER
+{
+ uint8_t protocol_mode; /**< ref: @ref TProfile_HID_PROTOCOL_MODE */
+ uint8_t suspend_mode;
+ struct
+ {
+ uint8_t reportLen;
+ uint8_t *report;
+ } report_data;
+} THID_WRITE_PARAMETER;
+
+/** @struct _THID_WRITE_MSG hids_rmc.h "hids_rmc.h"
+ * @brief write message
+ */
+typedef struct _THID_WRITE_MSG
+{
+ uint8_t write_type; /**< ref: @ref HIDS_RmC_Write_Info */
+ THID_WRITE_PARAMETER write_parameter;
+} THID_WRITE_MSG;
+
+typedef union _THID_UPSTREAM_MSG_DATA
+{
+ uint8_t notification_indification_index; /**< ref: @ref HIDS_RmC_Notify_Indicate_Info */
+ uint8_t read_value_index; /**< ref: @ref HIDS_RmC_Read_Info */
+ THID_WRITE_MSG write;
+} THID_UPSTREAM_MSG_DATA;
+
+/** @struct _T_HID_CALLBACK_DATA hids_rmc.h "hids_rmc.h"
+ * @brief callback data
+ */
+typedef struct _T_HID_CALLBACK_DATA
+{
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ THID_UPSTREAM_MSG_DATA msg_data;
+} T_HID_CALLBACK_DATA;
+/** @} End of HIDS_RmC_Callback_Data */
+
+/** @} End of HIDS_RmC_Exported_Types */
+
+/** @defgroup HIDS_RmC_Exported_Functions HIDS RmC Exported Functions
+ * @brief functions that other .c files may use all defined here
+ * @{
+ */
+bool hids_set_parameter(uint8_t param_type, uint8_t length, void *value_ptr);
+uint8_t hids_add_service(void *p_func);
+/** @} End of HIDS_RmC_Exported_Functions */
+
+/** @} End of HIDS_RmC */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _HIDS_RMC_H */
diff --git a/src/app/google_rcu/profile_module/ir_service.c b/src/app/google_rcu/profile_module/ir_service.c
new file mode 100644
index 0000000..610f721
--- /dev/null
+++ b/src/app/google_rcu/profile_module/ir_service.c
@@ -0,0 +1,342 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_service.c
+* @brief IR service source file.
+* @details Interfaces to access IR service.
+* @author
+* @date
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#include "board.h"
+#include "string.h"
+#include "trace.h"
+#include "gatt.h"
+#include "profile_server.h"
+#include "ir_service.h"
+#include "gap.h"
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+static P_FUN_SERVER_GENERAL_CB pfn_ir_svc_cb = NULL;
+static const uint8_t GATT_UUID_IR_SERVICE[16] = {GATT_UUID128_IR_SERVICE};
+
+/********************************************************************************************************
+* global variables
+********************************************************************************************************/
+uint8_t ir_svc_handshake_values[16] = {0};
+
+/**< @brief profile/service definition.
+* here is an example of ir service table
+* including Write
+*/
+const T_ATTRIB_APPL ir_svc_attr_tbl[] =
+{
+ /*--------------------------IR Service ---------------------------*/
+ /* <<Primary Service>>, .. 0*/
+ {
+ (ATTRIB_FLAG_VOID | ATTRIB_FLAG_LE), /* wFlags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ },
+ UUID_128BIT_SIZE, /* bValueLen */
+ (void *)GATT_UUID_IR_SERVICE, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic>> 1 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* IR Control 2 */
+ {
+ ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* wFlags */
+ { /* type_value */
+ GATT_UUID128_IR_PROG_CONTROL
+ },
+ 0, /* variable size */
+ NULL,
+ GATT_PERM_WRITE /* wPermissions */
+ },
+
+ /* <<Characteristic>> 3 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* IR Key ID 4 */
+ {
+ ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* wFlags */
+ { /* type_value */
+ GATT_UUID128_IR_KEY_ID
+ },
+ 0, /* variable size */
+ NULL,
+ GATT_PERM_WRITE /* wPermissions */
+ },
+
+ /* <<Characteristic>> 5 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* IR Code 6 */
+ {
+ ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* wFlags */
+ { /* type_value */
+ GATT_UUID128_IR_CODE
+ },
+ 0, /* variable size */
+ NULL,
+ GATT_PERM_WRITE /* wPermissions */
+ },
+
+ /* <<Characteristic>> 7 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* IR Suppress 8 */
+ {
+ ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* wFlags */
+ { /* type_value */
+ GATT_UUID128_IR_SUPPRESS
+ },
+ 0, /* variable size */
+ NULL,
+ GATT_PERM_WRITE /* wPermissions */
+ },
+
+ /* <<Characteristic>> 9 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* IR Key Event 10 */
+ {
+ ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* wFlags */
+ { /* type_value */
+ GATT_UUID128_IR_KEY_EVENT
+ },
+ 0, /* variable size */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* client characteristic configuration 11*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* flags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */
+ }
+};
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param ServiceID ServiceID to be written.
+ * @param iAttribIndex Attribute index of characteristic.
+ * @param wLength length of value to be written.
+ * @param pValue value to be written.
+ * @return Profile procedure result
+*/
+T_APP_RESULT ir_svc_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ bool handle = true;
+ T_IR_CALLBACK_DATA callback_data;
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+
+ APP_PRINT_INFO1("[ir_svc_attr_write_cb] attrib_index is %d", attrib_index);
+
+ if (GATT_SVC_IR_PROG_CONTROL_INDEX == attrib_index)
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write_msg.write_type = IR_WRITE_PROG_CONTROL;
+ callback_data.msg_data.write_msg.write_parameter.report_data.len = length;
+ callback_data.msg_data.write_msg.write_parameter.report_data.report = p_value;
+ }
+ else if (GATT_SVC_IR_KEY_ID_INDEX == attrib_index)
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write_msg.write_type = IR_WRITE_KEY_ID;
+ callback_data.msg_data.write_msg.write_parameter.report_data.len = length;
+ callback_data.msg_data.write_msg.write_parameter.report_data.report = p_value;
+ }
+ else if (GATT_SVC_IR_CODE_INDEX == attrib_index)
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write_msg.write_type = IR_WRITE_CODE;
+ callback_data.msg_data.write_msg.write_parameter.report_data.len = length;
+ callback_data.msg_data.write_msg.write_parameter.report_data.report = p_value;
+ }
+ else if (GATT_SVC_IR_SUPPRESS_INDEX == attrib_index)
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write_msg.write_type = IR_WRITE_SUPPRESS;
+ callback_data.msg_data.write_msg.write_parameter.report_data.len = length;
+ callback_data.msg_data.write_msg.write_parameter.report_data.report = p_value;
+ }
+
+ if ((pfn_ir_svc_cb) && (handle == true))
+ {
+ pfn_ir_svc_cb(service_id, (void *)&callback_data);
+ }
+
+ return cause;
+
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param ServiceId Service ID.
+ * @param Index Attribute index of characteristic data.
+ * @param wCCCBits CCCD bits from stack.
+ * @return None
+*/
+void ir_svc_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index,
+ uint16_t ccc_bits)
+{
+ bool handle = true;
+ T_IR_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+
+ APP_PRINT_INFO2("[ir_svc_cccd_update_cb] index = %d, ccc_bits %x", index, ccc_bits);
+ switch (index)
+ {
+ case GATT_SVC_IR_KEY_EVENT_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = IR_KEY_EVNET_NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = IR_KEY_EVNET_NOTIFY_DISABLE;
+ }
+ break;
+ }
+ default:
+ {
+ handle = false;
+ break;
+ }
+ }
+
+ if (pfn_ir_svc_cb && (handle == true))
+ {
+ /* Notify Application */
+ pfn_ir_svc_cb(service_id, (void *)&callback_data);
+ }
+
+ return;
+}
+
+/**
+ * @brief IR Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS ir_svc_cbs =
+{
+ NULL, // Read callback function pointer
+ ir_svc_attr_write_cb, // Write callback function pointer
+ ir_svc_cccd_update_cb // CCCD update callback function pointer
+};
+
+/**
+ * @brief Add ir service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ bas_id = ir_svc_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+uint8_t ir_svc_add_service(void *p_func)
+{
+ uint8_t service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)ir_svc_attr_tbl,
+ sizeof(ir_svc_attr_tbl),
+ ir_svc_cbs))
+ {
+ APP_PRINT_INFO1("ir_svc_add_service: service_id %d", service_id);
+ service_id = 0xff;
+ return service_id;
+ }
+ pfn_ir_svc_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
diff --git a/src/app/google_rcu/profile_module/ir_service.h b/src/app/google_rcu/profile_module/ir_service.h
new file mode 100644
index 0000000..4770c0f
--- /dev/null
+++ b/src/app/google_rcu/profile_module/ir_service.h
@@ -0,0 +1,101 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ir_service.h
+ * @brief Head file for using IR Service.
+ * @details IR service data structs and external functions declaration.
+ * @author barry_bian
+ * @date 2022-01-11
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#ifndef _IR_SERVICE_H_
+#define _IR_SERVICE_H_
+
+#include "profile_server.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/** @brief Demo Profile service related UUIDs. */
+#define GATT_UUID128_IR_SERVICE 0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0xC0, 0xBF, 0x43, 0xD3
+#define GATT_UUID128_IR_PROG_CONTROL 0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0xC1, 0xBF, 0x43, 0xD3
+#define GATT_UUID128_IR_KEY_ID 0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0xC2, 0xBF, 0x43, 0xD3
+#define GATT_UUID128_IR_CODE 0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0xC3, 0xBF, 0x43, 0xD3
+#define GATT_UUID128_IR_SUPPRESS 0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0xC4, 0xBF, 0x43, 0xD3
+#define GATT_UUID128_IR_KEY_EVENT 0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0xC5, 0xBF, 0x43, 0xD3
+
+/** @brief Index of each characteristic in Demo Profile service database. */
+#define GATT_SVC_IR_PROG_CONTROL_INDEX 2
+#define GATT_SVC_IR_KEY_ID_INDEX 4
+#define GATT_SVC_IR_CODE_INDEX 6
+#define GATT_SVC_IR_SUPPRESS_INDEX 8
+#define GATT_SVC_IR_KEY_EVENT_INDEX 10
+#define GATT_SVC_IR_KEY_EVENT_CCCD_INDEX 11
+
+/** @brief ir service write event */
+#define IR_WRITE_PROG_CONTROL 1
+#define IR_WRITE_KEY_ID 2
+#define IR_WRITE_CODE 3
+#define IR_WRITE_SUPPRESS 4
+
+/** @brief ir service write event length*/
+#define IR_WRITE_PROG_CONTROL_LEN 1
+#define IR_WRITE_KEY_ID_LEN 2
+
+/** @brief ir service notification flag */
+#define IR_KEY_EVNET_NOTIFY_ENABLE 1
+#define IR_KEY_EVNET_NOTIFY_DISABLE 2
+
+/** @brief IR_PROG_CONTROL event */
+#define IR_PROG_CONTROL_START 0x01
+#define IR_PROG_CONTROL_FINISH 0x00
+
+/** @brief IR_KEY_EVNET event */
+#define IR_KEY_UP 0x01
+#define IR_KEY_DOWN 0x00
+
+/** Message content */
+typedef union
+{
+ struct
+ {
+ uint16_t len;
+ uint8_t *report;
+ } report_data;
+} T_IR_WRITE_PARAMETER;
+
+/** @struct T_IR_WRITE_MSG
+ * @brief write message
+ */
+typedef struct
+{
+ uint8_t write_type; /**< ref: @ref IR_Write_Info */
+ T_IR_WRITE_PARAMETER write_parameter;
+} T_IR_WRITE_MSG;
+
+typedef union _IR_UPSTREAM_MSG_DATA
+{
+ uint8_t read_value_index;
+ uint8_t notification_indification_index;
+ T_IR_WRITE_MSG write_msg;
+} T_IR_UPSTREAM_MSG_DATA;
+
+/** IR service data to inform application */
+typedef struct _T_IR_CALLBACK_DATA
+{
+ T_SERVICE_CALLBACK_TYPE msg_type;
+ T_IR_UPSTREAM_MSG_DATA msg_data;
+} T_IR_CALLBACK_DATA;
+
+uint8_t ir_svc_add_service(void *pFunc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/app/google_rcu/profile_module/ota_service.c b/src/app/google_rcu/profile_module/ota_service.c
new file mode 100644
index 0000000..e99e2cb
--- /dev/null
+++ b/src/app/google_rcu/profile_module/ota_service.c
@@ -0,0 +1,842 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ota_service.c
+* @brief
+* @details
+* @author Ken_mei
+* @date 14-May-2018
+* @version v1.0.0
+******************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2015 Realtek Semiconductor Corporation</center></h2>
+******************************************************************************
+*/
+
+#include <string.h>
+#include "gatt.h"
+#include "patch_header_check.h"
+#include "flash_map.h"
+#include "ota_service.h"
+#include "otp.h"
+#include "trace.h"
+#include "board.h"
+#include "rcu_application.h"
+#include "os_timer.h"
+#include "swtimer.h"
+
+/*============================================================================*
+ * Micro
+ *============================================================================*/
+#define SOCV_CFG 0
+#define SYS_CFG 1
+#define OTA_HEADER 2
+#define SECURE_BOOT 3
+#define ROM_PATCH 4
+#define APP_IMG 5
+#define APP_DATA1 6
+#define APP_DATA2 7
+#define APP_DATA3 8
+#define APP_DATA4 9
+#define APP_DATA5 10
+#define APP_DATA6 11
+
+#define IMAGE_NOEXIST 0
+#define IMAGE_LOCATION_BANK0 1
+#define IMAGE_LOCATION_BANK1 2
+#define IMAGE_FIX_BANK_EXIST 3
+
+typedef struct
+{
+ uint8_t image_num;
+ uint16_t image_exist;
+ uint32_t image_indicator;
+} T_OTA_ACTIVE_BANK_IMG_INFO;
+
+/*============================================================================*
+ * External Variables
+ *============================================================================*/
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+/**< Function pointer used to send event to application from BWPS extended profile. */
+P_FUN_SERVER_GENERAL_CB pfn_ota_service_cb = NULL;
+uint8_t mac_addr[6];
+uint32_t patch_version = 0;
+uint32_t patch_ext_version = 0;
+uint32_t app_version = 0;
+#if (SUPPORT_OTA_PROTOCOL_TYPE_CHARACTERISTIC == 1)
+uint16_t protocol_type = 0x0;
+#endif
+static uint32_t image_version[IMAGE_MAX - OTA] = {0};
+T_OTA_ACTIVE_BANK_IMG_INFO ota_active_bank_info;
+
+const uint8_t GATT_UUID_OTA_SERVICE[16] = { 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0xFF, 0xD0, 0x00, 0x00};
+
+/**< @brief profile/service definition.
+* here is an example of OTA service table
+* including Write
+*/
+const T_ATTRIB_APPL gatt_Ota_service_table[] =
+{
+ /*--------------------------OTA Service ---------------------------*/
+ /* <<Primary Service>>, .. 0*/
+ {
+ (ATTRIB_FLAG_VOID | ATTRIB_FLAG_LE), /* wFlags */
+ {
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE), /* bTypeValue */
+ },
+ UUID_128BIT_SIZE, /* bValueLen */
+ (void *)GATT_UUID_OTA_SERVICE, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic1>>, .. 1*/ //----------------------OTA CMD 1
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 2*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_OTA),
+ HI_WORD(GATT_UUID_CHAR_OTA),
+ },
+ 2, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+ },
+
+ /* <<Characteristic2>>, .. 3, MAC Address*/ //------------------------MAC Address 2
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 4*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_MAC),
+ HI_WORD(GATT_UUID_CHAR_MAC),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic3>>, .. 5, Patch version*/ //-------------------------Patch Version 3
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 6*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_PATCH),
+ HI_WORD(GATT_UUID_CHAR_PATCH),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* <<Characteristic4>>, .. 7 App version*/ //-----------------------------APP Version 4
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 8*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_APP_VERSION),
+ HI_WORD(GATT_UUID_CHAR_APP_VERSION),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* <<Characteristic5>>, .. 9 Patch extension version*/ //--------------------Patch Ext Version 5
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 0x0A*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_PATCH_EXTENSION),
+ HI_WORD(GATT_UUID_CHAR_PATCH_EXTENSION),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic6>>, .. 0xB TEST MODE*/ //------------------------MP TEST MODE 6
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 0x0C*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_TEST_MODE),
+ HI_WORD(GATT_UUID_CHAR_TEST_MODE),
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_WRITE /* wPermissions */
+ },
+
+ /* <<Characteristic7>>, .. 0x0D OTA Device info*/ //---------------------------Device info 7
+ {
+ ATTRIB_FLAG_VALUE_INCL,
+ {
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ,
+ },
+ 1,
+ NULL,
+ GATT_PERM_READ
+ },
+ /* OTA Device info characteristic value 0x0E*/
+ {
+ ATTRIB_FLAG_VALUE_APPL,
+ {
+ LO_WORD(GATT_UUID_CHAR_DEVICE_INFO),
+ HI_WORD(GATT_UUID_CHAR_DEVICE_INFO),
+ },
+ 1,
+ (void *)NULL,
+ GATT_PERM_READ
+ },
+ /* <<Characteristic8>>, .. 0x0F OTA IMAGE COUNT TO UPDATE*/ //----------------------NUM OF IMG TO UPDATA 8
+ {
+ ATTRIB_FLAG_VALUE_INCL,
+ {
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE,
+ },
+ 1,
+ NULL,
+ GATT_PERM_READ
+ },
+ /* OTA IMAGE COUNT TO UPDATE characteristic value 0x10*/
+ {
+ ATTRIB_FLAG_VALUE_APPL,
+ {
+ LO_WORD(GATT_UUID_CHAR_IMAGE_COUNT_TO_UPDATE),
+ HI_WORD(GATT_UUID_CHAR_IMAGE_COUNT_TO_UPDATE),
+ },
+ 5,
+ (void *)NULL,
+ GATT_PERM_WRITE
+ },
+
+ /* <<Characteristic9>>, .. 0x11,ota pack img version*/ //-------------------------ota pack image version 9
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 0x12*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_IMAGE_VERSION0),
+ HI_WORD(GATT_UUID_CHAR_IMAGE_VERSION0),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic10>>, .. 0x13,ota pack img version*/ //-------------------------ota pack image version 9
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 0x14*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_IMAGE_VERSION1),
+ HI_WORD(GATT_UUID_CHAR_IMAGE_VERSION1),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic11>>, .. 0x15,ota pack img version*/ //-------------------------ota pack image version 9
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 0x16*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_IMAGE_VERSION2),
+ HI_WORD(GATT_UUID_CHAR_IMAGE_VERSION2),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+#if (SUPPORT_OTA_PROTOCOL_TYPE_CHARACTERISTIC == 1)
+ /* <<Characteristic10>>, .. 0x17,ota pack img version*/ //-------------------------ota pack img version 10
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 0x14*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_PROTOCOL_TYPE),
+ HI_WORD(GATT_UUID_CHAR_PROTOCOL_TYPE),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+#endif
+};
+
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param ServiceID ServiceID to be written.
+ * @param iAttribIndex Attribute index of characteristic.
+ * @param wLength length of value to be written.
+ * @param pValue value to be written.
+ * @return Profile procedure result
+*/
+
+T_APP_RESULT ota_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_OTA_CALLBACK_DATA callback_data;
+ T_APP_RESULT wCause = APP_RESULT_SUCCESS;
+
+ if (BLE_SERVICE_CHAR_OTA_INDEX == attrib_index)
+ {
+ /* Make sure written value size is valid. */
+ if ((length != sizeof(uint8_t)) || (p_value == NULL))
+ {
+ wCause = APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ else
+ {
+ /* Notify Application. */
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.opcode = OTA_WRITE_CHAR_VAL;
+ callback_data.msg_data.write.u.value = p_value[0];
+
+ if (pfn_ota_service_cb)
+ {
+ pfn_ota_service_cb(service_id, (void *)&callback_data);
+ }
+ }
+ }
+ else if (BLE_SERVICE_CHAR_IMAGE_COUNT_INDEX == attrib_index)
+ {
+ /* Make sure written value size is valid. */
+ if ((length != OTA_CHAR_IMAGE_COUNT_LEN) || (p_value == NULL))
+ {
+ wCause = APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ else
+ {
+ /* Notify Application. */
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.opcode = OTA_WRITE_IMAGE_COUNT_VAL;
+ callback_data.msg_data.write.u.update_image_info.image_count = p_value[0];
+ callback_data.msg_data.write.u.update_image_info.update_patch_version = CHAR2SHORT(&p_value[1]);
+ callback_data.msg_data.write.u.update_image_info.update_app_version = CHAR2SHORT(&p_value[3]);
+
+ if (pfn_ota_service_cb)
+ {
+ pfn_ota_service_cb(service_id, (void *)&callback_data);
+ }
+ }
+ }
+ else if (BLE_SERVICE_CHAR_TEST_MODE_INDEX == attrib_index)
+ {
+ /* Make sure written value size is valid. */
+ if ((length != sizeof(uint8_t)) || (p_value == NULL))
+ {
+ wCause = APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ else
+ {
+ /* Notify Application. */
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.opcode = OTA_WRITE_TEST_MODE_CHAR_VAL;
+ callback_data.msg_data.write.u.value = p_value[0];
+
+ if (pfn_ota_service_cb)
+ {
+ pfn_ota_service_cb(service_id, (void *)&callback_data);
+ }
+ }
+ }
+ else
+ {
+ DFU_PRINT_INFO2("==>[OTA]ota_attr_write_cb Error! attrib_index=0x%x, length=%d",
+ attrib_index,
+ length);
+ wCause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ return wCause;
+
+}
+
+/**
+ * @brief get OTA active bank image info
+ * @param[out] p_ota_image_info
+ * image_exist
+ * bit0: ota header, bit: fsbl, bit2: patch ..., bit9: appdata6, bit10: upperstack
+ * img_indicator
+ * Indications for each image version.each indication use 2bit.
+ * 00: image is not existed.
+ * 01: image is existed in bank0,ota should update image for bank1.
+ * 10: image is existed in bank1,ota should update image for bank0.
+ * 11: image is standalone. ota should update image for standalone.
+ *
+ * bit[1:0]: Image 0
+ * bit[2N+1:2N]:Image N
+
+ * Image indicator for bee3 is as below:
+ * Image 0 OTA Header File
+ * Image 1 Secure Boot Loader Image
+ * Image 2 ROM Patch Image
+ * Image 3 APP Image
+ * Image 4 APP Data1 File
+ * Image 5 APP Data2 File
+ * Image 6 APP Data3 File
+ * Image 7 APP Data4 File
+ * Image 8 APP Data5 File
+ * Image 9 APP Data6 File
+ * Image 10 Upperstack image
+*/
+static void get_ota_active_bank_image_info(T_OTA_ACTIVE_BANK_IMG_INFO *p_ota_image_info)
+{
+ uint32_t image_location = IMAGE_NOEXIST;
+ bool enable_bank_switch = is_ota_support_bank_switch();
+ p_ota_image_info->image_num = 0;
+
+ if (enable_bank_switch)
+ {
+ uint32_t ota_bank0_addr = flash_get_bank_addr(FLASH_OTA_BANK_0);
+ if (ota_bank0_addr == get_active_ota_bank_addr())
+ {
+ image_location = IMAGE_LOCATION_BANK0;
+ }
+ else
+ {
+ image_location = IMAGE_LOCATION_BANK1;
+ }
+ }
+ else
+ {
+ image_location = IMAGE_FIX_BANK_EXIST;
+ }
+
+ for (T_IMG_ID image_id = OTA; image_id < IMAGE_MAX; image_id++)
+ {
+ if (0 != get_active_bank_image_size_by_img_id(image_id))
+ {
+ p_ota_image_info->image_num++;
+ p_ota_image_info->image_exist |= BIT(image_id - OTA);
+ p_ota_image_info->image_indicator |= image_location << ((OTA_HEADER + image_id - OTA) * 2);
+ }
+ }
+}
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param ServiceId ServiceID of characteristic data.
+ * @param iAttribIndex Attribute index of getting characteristic data.
+ * @param iOffset Used for Blob Read.
+ * @param piLength length of getting characteristic data.
+ * @param ppValue data got from service.
+ * @return Profile procedure result
+*/
+T_APP_RESULT ota_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT wCause = APP_RESULT_SUCCESS;
+ T_OTA_CALLBACK_DATA callback_data;
+ bool defer_handle = false;
+
+ switch (attrib_index)
+ {
+ default:
+ DFU_PRINT_INFO1("==>ota_attr_read_cb: attrib_index=%d not found!", attrib_index);
+ wCause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+ case BLE_SERVICE_CHAR_MAC_ADDRESS_INDEX:
+ {
+ gap_get_param(GAP_PARAM_BD_ADDR, mac_addr);
+ uint8_t addr[6];
+ for (int i = 0; i < 6; i++)
+ {
+ addr[i] = mac_addr[5 - i];
+ }
+ memcpy(mac_addr, addr, 6);
+ *pp_value = (uint8_t *)mac_addr;
+ *p_length = sizeof(mac_addr);
+ }
+ break;
+ case BLE_SERVICE_CHAR_PATCH_INDEX:
+ {
+ T_IMG_HEADER_FORMAT *p_header;
+ uint32_t addr = get_header_addr_by_img_id(RomPatch);
+ p_header = (T_IMG_HEADER_FORMAT *)addr;
+ patch_version = p_header->git_ver.ver_info.version;
+ DFU_PRINT_INFO2("ota_attr_read_cb: Patch addr=0x%x, version=0x%x", addr, patch_version);
+
+ *pp_value = (uint8_t *)&patch_version;
+ *p_length = sizeof(patch_version);
+ }
+ break;
+
+ case BLE_SERVICE_CHAR_APP_VERSION_INDEX:
+ {
+ T_IMG_HEADER_FORMAT *p_header;
+ uint32_t addr = get_header_addr_by_img_id(AppPatch);
+ p_header = (T_IMG_HEADER_FORMAT *)addr;
+ app_version = p_header->git_ver.ver_info.version;
+ DFU_PRINT_INFO2("ota_attr_read_cb: APP addr=0x%x, version=0x%x", addr, app_version);
+
+ *pp_value = (uint8_t *)&app_version;
+ *p_length = sizeof(app_version);
+ }
+ break;
+
+ case BLE_SERVICE_CHAR_PATCH_EXTENSION_INDEX: //not used in bee2
+ {
+
+ }
+ break;
+ case BLE_SERVICE_CHAR_DEVICE_INFO_INDEX:
+ {
+ static T_DFU_DEVICE_INFO DeviceInfo;
+ T_IMG_HEADER_FORMAT *p_ota_header;
+ uint32_t ota_header_addr = get_header_addr_by_img_id(OTA);
+ p_ota_header = (T_IMG_HEADER_FORMAT *)ota_header_addr;
+ DeviceInfo.ic_type = DEFINED_IC_TYPE;
+ DeviceInfo.ota_version = 0x3;
+ DeviceInfo.secure_version = p_ota_header->ctrl_header.secure_version;
+ DFU_PRINT_INFO3("<==ota_attr_read_cb: ic_type=0x%x, ota_version=0x%x, OTA Header secure_version=0x%x",
+ DeviceInfo.ic_type, DeviceInfo.ota_version, DeviceInfo.secure_version);
+
+ DeviceInfo.ota_mode.mode_flag.buf_check_en = DFU_BUFFER_CHECK_ENABLE;
+ DeviceInfo.max_buffer_size = DFU_TEMP_BUFFER_SIZE;
+ DeviceInfo.ota_mode.mode_flag.aesflg = OTP->ota_with_encryption_data;
+ DeviceInfo.ota_mode.mode_flag.aesmode = 1;
+ DFU_PRINT_INFO4("<==ota_attr_read_cb: bufChkEn=%d, bufsize=0x%x, aesflg=%d, aesmode=%d",
+ DeviceInfo.ota_mode.mode_flag.buf_check_en, DeviceInfo.max_buffer_size,
+ DeviceInfo.ota_mode.mode_flag.aesflg, DeviceInfo.ota_mode.mode_flag.aesmode);
+
+ /* default disable copy app data img when bank switch */
+ DeviceInfo.ota_mode.mode_flag.copy_img = 0;
+
+ /* prepare img_indicator, if modify here need to sync with vaule
+ of BLE_SERVICE_CHAR_IMAGE_VERSION_INDEX */
+ if (is_ota_support_bank_switch())
+ {
+ //dual bank must support multiple image update
+ DeviceInfo.ota_mode.mode_flag.multi_img = 1;
+ uint32_t ota_bank0_addr = flash_get_bank_addr(FLASH_OTA_BANK_0);
+ if (ota_bank0_addr == get_active_ota_bank_addr())
+ {
+ /* meaningful only when multi_img = 1 */
+ DeviceInfo.temp_bank_size = flash_get_bank_size(FLASH_OTA_BANK_1) / FMC_SEC_SECTION_LEN;
+ }
+ else
+ {
+ /* meaningful only when multi_img = 1 */
+ DeviceInfo.temp_bank_size = flash_get_bank_size(FLASH_OTA_BANK_0) / FMC_SEC_SECTION_LEN;
+ }
+ }
+ else
+ {
+#if (SUPPORT_TEMP_COMBINED_OTA == 1)
+ DeviceInfo.ota_mode.mode_flag.multi_img = 1;
+#else
+ DeviceInfo.ota_mode.mode_flag.multi_img = 0;
+#endif
+ /* meaningful only when multi_img = 1 */
+ DeviceInfo.temp_bank_size = flash_get_bank_size(FLASH_OTA_TMP) / FMC_SEC_SECTION_LEN;
+ }
+ /*read flash map info to set image indicator*/
+ get_ota_active_bank_image_info(&ota_active_bank_info);
+ DeviceInfo.img_indicator = ota_active_bank_info.image_indicator;
+
+ DFU_PRINT_INFO4("<==ota_attr_read_cb: copy_img=0x%x, multi_img=0x%x, temp_bank_size=0x%x, img_indicator=0x%x",
+ DeviceInfo.ota_mode.mode_flag.copy_img, DeviceInfo.ota_mode.mode_flag.multi_img,
+ DeviceInfo.temp_bank_size, DeviceInfo.img_indicator);
+
+
+ *pp_value = (uint8_t *)&DeviceInfo;
+ *p_length = sizeof(T_DFU_DEVICE_INFO);
+ }
+ break;
+ case BLE_SERVICE_CHAR_IMAGE_VERSION0_INDEX:
+ {
+ uint8_t index = 0;
+ T_IMAGE_VERSION image_ver;
+
+ if (0 == ota_active_bank_info.image_num)
+ {
+ get_ota_active_bank_image_info(&ota_active_bank_info);
+ }
+ DFU_PRINT_INFO2("image_exist=0x%x(BIT0:OTA, BIT1:patch, ...), image_num=%d",
+ ota_active_bank_info.image_exist, ota_active_bank_info.image_num);
+
+ for (T_IMG_ID image_id = OTA; image_id < IMAGE_MAX; image_id++)
+ {
+ if (ota_active_bank_info.image_exist & BIT(image_id - OTA))
+ {
+ get_active_bank_image_version(image_id, &image_ver);
+ image_version[index] = image_ver.ver_info.version;
+ index ++;
+ DFU_PRINT_INFO2("image:0x%x exist!, version=0x%x",
+ image_id, image_ver.ver_info.version);
+ }
+ }
+
+ *pp_value = (uint8_t *)image_version;
+ if (ota_active_bank_info.image_num > 5)
+ {
+ *p_length = 20;
+ }
+ else
+ {
+ *p_length = 4 * ota_active_bank_info.image_num;
+ }
+ DFU_PRINT_INFO5("Image Version[0-4]: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x",
+ image_version[0], image_version[1], image_version[2], image_version[3], image_version[4]);
+
+ /* Notify Application. */
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = OTA_READ_CHAR_IMAGE_VERSION_INDEX;
+ /*defer processing before ota start*/
+ defer_handle = true;
+ }
+ break;
+ case BLE_SERVICE_CHAR_IMAGE_VERSION1_INDEX:
+ {
+ if (ota_active_bank_info.image_num > 5)
+ {
+ *pp_value = (uint8_t *)&image_version[5];
+ if (ota_active_bank_info.image_num > 10)
+ {
+ *p_length = 20;
+ }
+ else
+ {
+ *p_length = 4 * (ota_active_bank_info.image_num - 5);
+ }
+ DFU_PRINT_INFO5("Image Version[5-9]: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x",
+ image_version[5], image_version[6], image_version[7], image_version[8], image_version[9]);
+ }
+ else
+ {
+ *pp_value = NULL;
+ *p_length = 0;
+ }
+
+ /* Notify Application. */
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = OTA_READ_CHAR_IMAGE_VERSION_INDEX;
+ /*defer processing before ota start*/
+ defer_handle = true;
+ }
+ break;
+ case BLE_SERVICE_CHAR_IMAGE_VERSION2_INDEX:
+ {
+ if (ota_active_bank_info.image_num > 10)
+ {
+ *pp_value = (uint8_t *)&image_version[10];
+ *p_length = 4 * (ota_active_bank_info.image_num - 10);
+ //ota 11 images at most now
+ DFU_PRINT_INFO1("Image Version[10]: 0x%x", image_version[10]);
+ }
+ else
+ {
+ *pp_value = NULL;
+ *p_length = 0;
+ }
+
+ /* Notify Application. */
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = OTA_READ_CHAR_IMAGE_VERSION_INDEX;
+ /*defer processing before ota start*/
+ defer_handle = true;
+ }
+ break;
+#if (SUPPORT_OTA_PROTOCOL_TYPE_CHARACTERISTIC == 1)
+ case BLE_SERVICE_CHAR_PROTOCOL_TYPE_INDEX:
+ {
+ protocol_type = 0x0012;
+ *pp_value = (uint8_t *)&protocol_type;
+ *p_length = sizeof(protocol_type);
+ }
+ break;
+#endif
+ }
+
+ /* Notify Application. */
+ if (pfn_ota_service_cb && (defer_handle == true))
+ {
+ pfn_ota_service_cb(service_id, (void *)&callback_data);
+ }
+
+ if (temp_off_latency_timer != NULL)
+ {
+ /* turn off latency to speed up process */
+ app_set_latency_status(LATENCY_TEMP_OFF_BIT, LANTENCY_OFF);
+ /* start temp_off_latency_timer */
+ os_timer_restart(&temp_off_latency_timer, TEMP_OFF_LANTENCY_TIMEOUT);
+ }
+
+ return (wCause);
+}
+
+
+/**
+ * @brief OTA ble Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS ota_service_cbs =
+{
+ ota_attr_read_cb, // Read callback function pointer
+ ota_attr_write_cb, // Write callback function pointer
+ NULL // CCCD update callback function pointer
+};
+
+/**
+ * @brief add OTA ble service to application.
+ *
+ * @param p_func pointer of app callback function called by profile.
+ * @return service ID auto generated by profile layer.
+ * @retval ServiceId
+*/
+uint8_t ota_add_service(void *p_func)
+{
+ uint8_t service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)gatt_Ota_service_table,
+ sizeof(gatt_Ota_service_table),
+ ota_service_cbs))
+ {
+ DFU_PRINT_ERROR1("<==ota_add_service: service_id=%d", service_id);
+ service_id = 0xff;
+ return service_id;
+ }
+ pfn_ota_service_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
diff --git a/src/app/google_rcu/profile_module/ota_service.h b/src/app/google_rcu/profile_module/ota_service.h
new file mode 100644
index 0000000..9f4e0dc
--- /dev/null
+++ b/src/app/google_rcu/profile_module/ota_service.h
@@ -0,0 +1,142 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ota_service.h
+* @brief
+* @details
+* @author hunter_shuai
+* @date 14-July-2015
+* @version v1.0.0
+******************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2015 Realtek Semiconductor Corporation</center></h2>
+******************************************************************************
+*/
+
+#ifndef _OTA_SERVICE_H_
+#define _OTA_SERVICE_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "profile_server.h"
+#include "dfu_api.h"
+/** @brief Demo Profile service related UUIDs. */
+
+#define GATT_UUID_CHAR_OTA 0xFFD1 //1
+#define GATT_UUID_CHAR_MAC 0xFFD2 //2
+#define GATT_UUID_CHAR_PATCH 0xFFD3 //3
+#define GATT_UUID_CHAR_APP_VERSION 0xFFD4 //4
+#define GATT_UUID_CHAR_PATCH_EXTENSION 0xFFD5 //5
+#define GATT_UUID_CHAR_TEST_MODE 0xFFD8 //6
+
+#define GATT_UUID_CHAR_DEVICE_INFO 0xFFF1 //7
+#define GATT_UUID_CHAR_IMAGE_COUNT_TO_UPDATE 0xFFF2 //8
+#define GATT_UUID_CHAR_IMAGE_VERSION0 0xFFE0 //mandatory when OTA version >= 1
+#define GATT_UUID_CHAR_IMAGE_VERSION1 0xFFE1
+#define GATT_UUID_CHAR_IMAGE_VERSION2 0xFFE2
+#define GATT_UUID_CHAR_PROTOCOL_TYPE 0xFFF3
+
+/** @brief Index of each characteristic in Demo Profile service database. */
+#define BLE_SERVICE_CHAR_OTA_INDEX 0x02 /**< attr write */
+#define BLE_SERVICE_CHAR_MAC_ADDRESS_INDEX 0x04 /**< attr read */
+#define BLE_SERVICE_CHAR_PATCH_INDEX 0x06 /**< attr read */
+#define BLE_SERVICE_CHAR_APP_VERSION_INDEX 0x08 /**< attr read */
+#define BLE_SERVICE_CHAR_PATCH_EXTENSION_INDEX 0x0a /**< attr read */
+#define BLE_SERVICE_CHAR_TEST_MODE_INDEX 0x0c /**< attr write */
+#define BLE_SERVICE_CHAR_DEVICE_INFO_INDEX 0x0e /**< attr read */
+#define BLE_SERVICE_CHAR_IMAGE_COUNT_INDEX 0x10 /**< attr write */
+#define BLE_SERVICE_CHAR_IMAGE_VERSION0_INDEX 0x12 /**< attr read */
+#define BLE_SERVICE_CHAR_IMAGE_VERSION1_INDEX 0x14 /**< attr read */
+#define BLE_SERVICE_CHAR_IMAGE_VERSION2_INDEX 0x16 /**< attr read */
+#define BLE_SERVICE_CHAR_PROTOCOL_TYPE_INDEX 0x18 /**< attr read */
+
+/** @brief OTA Read callback data type definition.*/
+#define OTA_READ_CHAR_MAC_ADDRESS_INDEX 0x01
+#define OTA_READ_CHAR_PATCH_INDEX 0x02
+#define OTA_READ_CHAR_APP_VERSION_INDEX 0x03
+#define OTA_READ_CHAR_PATCH_EXTENSION_INDEX 0x04
+#define OTA_READ_CHAR_DEVICE_INFO_INDEX 0x05
+#define OTA_READ_CHAR_IMAGE_VERSION_INDEX 0x06
+#define OTA_READ_CHAR_PROTOCOL_TYPE_INDEX 0x07
+
+
+/** @brief OTA Write callback data type definition.*/
+#define OTA_WRITE_CHAR_VAL 0x01 /**< switch ota mode write opcode */
+#define OTA_VALUE_ENTER 0x01 /**< switch ota mode write value */
+
+/** @brief OTA Write callback data type definition.*/
+#define OTA_WRITE_TEST_MODE_CHAR_VAL 0x02 /**< test mode write opcode */
+
+/** @brief OTA Write callback data type definition.*/
+#define OTA_WRITE_IMAGE_COUNT_VAL 0x02 /**< image count write opcode */
+#define OTA_VALUE_IMAGE_COUNT_APP_ONLY 0x01
+#define OTA_VALUE_IMAGE_COUNT_PATCH_ONLY 0x02
+#define OTA_VALUE_IMAGE_COUNT_APP_AND_PATCH 0x03
+
+#define OTA_CHAR_IMAGE_COUNT_LEN 5
+
+#define CHAR2SHORT(p) (((*(p)) & 0xff) + ((*((p)+1)) << 8))
+
+typedef struct _T_DFU_DEVICE_INFO
+{
+ uint8_t ic_type;
+ uint8_t ota_version;
+ uint8_t secure_version;
+ T_OTA_MODE ota_mode;
+
+ uint16_t max_buffer_size;
+ uint8_t temp_bank_size; //Unit:4K, 0x00:No Limitation of OTA Temp Buffer Size,Only available when Updating Multi Image at a time is supported.
+ uint8_t rsvd;
+ uint32_t img_indicator;
+
+} T_DFU_DEVICE_INFO, * P_DFU_DEVICE_INFO;
+
+typedef struct _T_OTA_UPDATE_IMAGE_INFO
+{
+ uint8_t image_count;
+ uint16_t update_patch_version;
+ uint16_t update_app_version;
+} T_OTA_UPDATE_IMAGE_INFO;
+
+typedef struct _T_OTA_WRITE_MSG
+{
+ uint8_t opcode;
+ union
+ {
+ uint8_t value;
+ T_OTA_UPDATE_IMAGE_INFO update_image_info;
+ } u;
+} T_OTA_WRITE_MSG;
+
+typedef union _T_OTA_UPSTREAM_MSG_DATA
+{
+ uint8_t notification_indification_index;
+ uint8_t read_value_index;
+ T_OTA_WRITE_MSG write;
+} T_OTA_UPSTREAM_MSG_DATA;
+
+/**
+ * @brief OTA servic data struct for notification data to application.
+ *
+ * OTA service data to inform application.
+*/
+typedef struct _T_OTA_CALLBACK_DATA
+{
+ T_SERVICE_CALLBACK_TYPE msg_type; /**< @brief EventId defined upper */
+ T_OTA_UPSTREAM_MSG_DATA msg_data;
+} T_OTA_CALLBACK_DATA;
+
+
+extern uint8_t ota_add_service(void *pFunc);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/app/google_rcu/rcu_application.c b/src/app/google_rcu/rcu_application.c
new file mode 100644
index 0000000..507d5a3
--- /dev/null
+++ b/src/app/google_rcu/rcu_application.c
@@ -0,0 +1,1722 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file rcu_application.c
+* @brief rcu application implementation
+* @details including callbacks of handle functions for users to implement customization requirements
+* @author barry_bian
+* @date 2020-02-24
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <trace.h>
+#include <string.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include "rcu_gap.h"
+#include <profile_server.h>
+#include <gap_msg.h>
+#include "board.h"
+#include <app_task.h>
+#include <app_msg.h>
+#include <rcu_application.h>
+#include "hids_rmc.h"
+#include "bas.h"
+#include "dis.h"
+#include "key_handle.h"
+#include "os_timer.h"
+#include "swtimer.h"
+#include "voice.h"
+#include "version.h"
+#include "voice_driver.h"
+#include "gap_conn_le.h"
+#include "vendor_service.h"
+#include "ota_service.h"
+#include "rtl876x_wdg.h"
+#include "dfu_api.h"
+#include "ftl.h"
+#include "mp_test.h"
+#include "hids_rmc.h"
+#include "dfu_service.h"
+#include "dfu_flash.h"
+#include "patch_header_check.h"
+#include "gatt_builtin_services.h"
+#include "led_driver.h"
+#include "battery_driver.h"
+#include "app_section.h"
+#include "ir_service.h"
+#include <rcu_link_mgr.h>
+#if SUPPORT_IR_TX_FEATURE
+#include "ir_send_handle.h"
+#endif
+#if FEATURE_SUPPORT_MP_TEST_MODE
+#include "data_uart_test.h"
+#endif
+#include "atvv_service.h"
+#include "frm_define.h"
+#if FEAUTRE_SUPPORT_IR_OVER_BLE
+#include "ir_service_handle.h"
+#endif
+#if SUPPORT_BUZZER_FEATURE
+#include "fms.h"
+#include "fms_service_handle.h"
+#include "buzzer_driver.h"
+#endif
+
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+void app_handle_io_msg(T_IO_MSG io_driver_msg_recv) DATA_RAM_FUNCTION;
+extern T_GAP_CAUSE client_send_exchange_mtu_req(uint8_t conn_id);
+
+/*============================================================================*
+ * Global Variables
+ *============================================================================*/
+const uint8_t Default_PnP_ID[] = {0x02, LO_WORD(VID), HI_WORD(VID), LO_WORD(PID), HI_WORD(PID), 0x01, 0x00};
+const uint8_t Default_FW_Rev [] = {'V', '1', '.', '1', '0', '1'};
+const uint8_t Default_SW_Rev [] = {'V', '1', '.', '0', '2'};
+const uint8_t Default_HW_Rev [] = {'V', '1', '.', '0'};
+const uint8_t Default_Manu_Name [] = {'R', 'e', 'a', 'l', 't', 'e', 'k'};
+
+T_APP_GLOBAL_DATA app_global_data;
+#if FEATURE_SUPPORT_PRIVACY
+T_PRIVACY_STATE app_privacy_state = PRIVACY_STATE_INIT;
+T_PRIVACY_ADDR_RESOLUTION_STATE app_privacy_resolution_state = PRIVACY_ADDR_RESOLUTION_DISABLED;
+#endif
+/*============================================================================*
+ * External Variables
+ *============================================================================*/
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief handler stop adverting reason
+ * @param T_STOP_ADV_REASON reason.
+ * @return none
+ * @retval void
+ */
+static void app_stop_adv_reason_handler(T_STOP_ADV_REASON reason)
+{
+ switch (reason)
+ {
+ case STOP_ADV_REASON_RESTART_RECONNECT_ADV:
+ if ((app_global_data.adv_type == ADV_DIRECT_LDC) || (app_global_data.adv_type == ADV_DIRECT_LDC_LT))
+ {
+ APP_PRINT_INFO0("STOP_ADV_REASON_RESTART_RECONNECT_ADV!");
+ rcu_start_adv(ADV_DIRECT_LDC);
+ }
+ break;
+ case STOP_ADV_REASON_WAKEUPKEY:
+ APP_PRINT_INFO0("STOP_ADV_REASON_WAKEUPKEY!");
+ rcu_start_adv(ADV_UNDIRECT_WAKEUP);
+ break;
+ case STOP_ADV_REASON_BACKKEY:
+ APP_PRINT_INFO0("STOP_ADV_REASON_BACKKEY!");
+ break;
+ case STOP_ADV_REASON_PAIRING:
+ APP_PRINT_INFO0("STOP_ADV_REASON_PAIRING!");
+ rcu_start_adv(ADV_UNDIRECT_PAIRING);
+ break;
+ case STOP_ADV_REASON_TIMEOUT:
+ APP_PRINT_INFO0("STOP_ADV_REASON_TIMEOUT!");
+ if (app_global_data.adv_type == ADV_UNDIRECT_PAIRING)
+ {
+ rcu_start_adv(ADV_UNDIRECT_PAIRING_LT);
+ }
+ else if (app_global_data.adv_type == ADV_UNDIRECT_PAIRING_LT)
+ {
+#if SUPPORT_LED_INDICATION_FEATURE
+ LED_BLINK_EXIT(LED_TYPE_BLINK_PAIR_ADV);
+ LED_BLINK(LED_TYPE_BLINK_ERROR, 4);
+#endif
+ }
+ else if (app_global_data.adv_type == ADV_UNDIRECT_WAKEUP)
+ {
+ rcu_start_adv(ADV_DIRECT_LDC);
+ }
+ else if (app_global_data.adv_type == ADV_DIRECT_LDC)
+ {
+ rcu_start_adv(ADV_DIRECT_LDC_LT);
+ }
+ else if (app_global_data.adv_type == ADV_DIRECT_LDC_LT)
+ {
+ key_handle_reset_key_pressed_cache_fifo();
+ }
+ break;
+ case STOP_ADV_REASON_LOWPOWER:
+ APP_PRINT_INFO0("STOP_ADV_REASON_LOWPOWER!");
+ app_global_data.rcu_status = RCU_STATUS_LOW_POWER;
+ break;
+ case STOP_ADV_REASON_UART_CMD:
+ APP_PRINT_INFO0("STOP_ADV_REASON_UART_CMD!");
+ break;
+ case STOP_ADV_REASON_IDLE:
+ APP_PRINT_INFO0("STOP_ADV_REASON_IDLE!");
+ if (app_global_data.adv_type == ADV_DIRECT_HDC)
+ {
+ APP_PRINT_INFO1("[STOP_ADV_REASON_IDLE] retry cnt is %d", app_global_data.direct_adv_cnt);
+ if (app_global_data.direct_adv_cnt < MAX_DIRECT_ADV_RETRY_CNT)
+ {
+ rcu_start_adv(ADV_DIRECT_HDC);
+ app_global_data.direct_adv_cnt++;
+ return;
+ }
+ else
+ {
+ app_global_data.direct_adv_cnt = 0; /* reset direct_adv_cnt to 0 */
+ }
+
+ key_handle_reset_key_pressed_cache_fifo();
+ }
+ break;
+ default:
+ APP_PRINT_WARN1("Unknown stop_adv_reason: %d", app_global_data.stop_adv_reason);
+ break;
+ }
+}
+
+/******************************************************************
+ * @brief handler disconnect reason
+ * @param T_DISCONN_REASON reason.
+ * @return none
+ * @retval void
+ */
+static void app_disconn_reason_handler(T_DISCONN_REASON reason)
+{
+ switch (reason)
+ {
+ case DISCONN_REASON_PAIRING:
+ APP_PRINT_INFO0("[GAP_CONN_STATE_DISCONNECTED] DISCONN_REASON_PAIRING");
+ rcu_start_adv(ADV_UNDIRECT_PAIRING);
+ break;
+ case DISCONN_REASON_TIMEOUT:
+ APP_PRINT_INFO0("[GAP_CONN_STATE_DISCONNECTED] DISCONN_REASON_TIMEOUT");
+ break;
+ case DISCONN_REASON_PAIR_FAILED:
+ APP_PRINT_INFO0("[GAP_CONN_STATE_DISCONNECTED] DISCONN_REASON_PAIR_FAILED");
+ if (false == app_global_data.is_link_key_existed)
+ {
+ APP_PRINT_INFO1("[GAP_CONN_STATE_DISCONNECTED] DISCONN_REASON_PAIR_FAILED, retry cnt is %d",
+ app_global_data.pair_failed_retry_cnt);
+ if (app_global_data.pair_failed_retry_cnt < MAX_PAIR_FAILED_RETRY_CNT)
+ {
+ app_global_data.pair_failed_retry_cnt++;
+ rcu_start_adv(ADV_UNDIRECT_PAIRING);
+ }
+ }
+ break;
+ case DISCONN_REASON_LOW_POWER:
+ APP_PRINT_INFO0("[GAP_CONN_STATE_DISCONNECTED] DISCONN_REASON_LOW_POWER");
+ app_global_data.rcu_status = RCU_STATUS_LOW_POWER;
+ break;
+ case DISCONN_REASON_UART_CMD:
+ APP_PRINT_INFO0("[GAP_CONN_STATE_DISCONNECTED] DISCONN_REASON_UART_CMD");
+ break;
+#if SUPPORT_NORMAL_OTA
+ case DISCONN_REASON_OTA:
+ APP_PRINT_INFO0("[GAP_CONN_STATE_DISCONNECTED] DISCONN_REASON_OTA");
+ /* switch to OTA and reboot */
+ dfu_switch_to_ota_mode();
+ break;
+#endif
+#if SUPPORT_SILENT_OTA
+ case DISCONN_REASON_SILENT_OTA:
+ dfu_fw_reboot(true);
+ break;
+#endif
+ default:
+ APP_PRINT_WARN1("[GAP_CONN_STATE_DISCONNECTED] unknown reason: %d", app_global_data.disconn_reason);
+ break;
+ }
+}
+
+/******************************************************************
+ * @fn app_general_srv_cb
+ * @brief General service callbacks are handled in this function.
+ * @param p_data - pointer to callback data
+ * @return cb_result
+ * @retval T_APP_RESULT
+ */
+static T_APP_RESULT app_general_srv_cb(T_SERVER_APP_CB_DATA *p_data)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ switch (p_data->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_data->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits = %d",
+ p_data->event_data.send_data_result.conn_id,
+ p_data->event_data.send_data_result.cause,
+ p_data->event_data.send_data_result.service_id,
+ p_data->event_data.send_data_result.attrib_idx,
+ p_data->event_data.send_data_result.credits);
+ if (p_data->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+#if SUPPORT_VOICE_FEATURE
+ if (voice_driver_global_data.is_voice_driver_working)
+ {
+ voice_handle_messages(VOICE_MSG_BT_SEND_COMPLETE, NULL);
+ }
+#endif
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn app_bas_srv_cb
+ * @brief BAS service callbacks are handled in this function.
+ * @param p_data - pointer to callback data
+ * @return cb_result
+ * @retval T_APP_RESULT
+ */
+static T_APP_RESULT app_bas_srv_cb(T_BAS_CALLBACK_DATA *p_data)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ switch (p_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ if (p_data->msg_data.notification_indification_index == BAS_NOTIFY_BATTERY_LEVEL_ENABLE)
+ {
+ APP_PRINT_INFO0("[app_bas_srv_cb] Battery level notification enable");
+ }
+ else if (p_data->msg_data.notification_indification_index ==
+ BAS_NOTIFY_BATTERY_LEVEL_DISABLE)
+ {
+ APP_PRINT_INFO0("[app_bas_srv_cb] Battery level notification disable");
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ uint8_t bat_level = 100;
+#if SUPPORT_BAT_DETECT_FEATURE
+ if (BAT_STATUS_SUCCESS == bat_update_battery_info())
+ {
+ bat_level = bat_get_current_voltage_level();
+ }
+ else
+ {
+ cb_result = APP_RESULT_APP_ERR;
+ }
+#endif
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &bat_level);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn app_dis_srv_cb
+ * @brief DIS service callbacks are handled in this function.
+ * @param p_data - pointer to callback data
+ * @return cb_result
+ * @retval T_APP_RESULT
+ */
+static T_APP_RESULT app_dis_srv_cb(T_DIS_CALLBACK_DATA *p_data)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ switch (p_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_data->msg_data.read_value_index == DIS_READ_MANU_NAME_INDEX)
+ {
+ dis_set_parameter(DIS_PARAM_MANUFACTURER_NAME,
+ sizeof(Default_Manu_Name),
+ (void *)Default_Manu_Name);
+ }
+ else if (p_data->msg_data.read_value_index == DIS_READ_MODEL_NUM_INDEX)
+ {
+ const uint8_t DISModelNumber[] = "Google RCU";
+ dis_set_parameter(DIS_PARAM_MODEL_NUMBER,
+ sizeof(DISModelNumber) - 1,
+ (void *)DISModelNumber);
+ }
+ else if (p_data->msg_data.read_value_index == DIS_READ_SERIAL_NUM_INDEX)
+ {
+ const uint8_t DISSerialNumber[] = "123456";
+ dis_set_parameter(DIS_PARAM_SERIAL_NUMBER,
+ sizeof(DISSerialNumber) - 1,
+ (void *)DISSerialNumber);
+ }
+ else if (p_data->msg_data.read_value_index == DIS_READ_HARDWARE_REV_INDEX)
+ {
+ dis_set_parameter(DIS_PARAM_HARDWARE_REVISION,
+ sizeof(Default_HW_Rev),
+ (void *)Default_HW_Rev);
+ }
+ else if (p_data->msg_data.read_value_index == DIS_READ_FIRMWARE_REV_INDEX)
+ {
+ dis_set_parameter(DIS_PARAM_FIRMWARE_REVISION,
+ sizeof(app_global_data.fw_version),
+ (void *)app_global_data.fw_version);
+ }
+ else if (p_data->msg_data.read_value_index == DIS_READ_SOFTWARE_REV_INDEX)
+ {
+ dis_set_parameter(DIS_PARAM_SOFTWARE_REVISION,
+ sizeof(app_global_data.sw_version),
+ (void *)app_global_data.sw_version);
+ }
+ else if (p_data->msg_data.read_value_index == DIS_READ_SYSTEM_ID_INDEX)
+ {
+ const uint8_t DISSystemID[DIS_SYSTEM_ID_LENGTH] = {0, 1, 2, 0, 0, 3, 4, 5};
+ dis_set_parameter(DIS_PARAM_SYSTEM_ID,
+ sizeof(DISSystemID),
+ (void *)DISSystemID);
+ }
+ else if (p_data->msg_data.read_value_index == DIS_READ_IEEE_CERT_STR_INDEX)
+ {
+ const uint8_t DISIEEEDataList[] = "RTKBeeIEEEDatalist";
+ dis_set_parameter(DIS_PARAM_IEEE_DATA_LIST,
+ sizeof(DISIEEEDataList) - 1,
+ (void *)DISIEEEDataList);
+ }
+ else if (p_data->msg_data.read_value_index == DIS_READ_PNP_ID_INDEX)
+ {
+ dis_set_parameter(DIS_PARAM_PNP_ID,
+ sizeof(app_global_data.pnp_id),
+ app_global_data.pnp_id);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (temp_off_latency_timer != NULL)
+ {
+ /* turn off latency to speed up process */
+ app_set_latency_status(LATENCY_TEMP_OFF_BIT, LANTENCY_OFF);
+ /* start temp_off_latency_timer */
+ os_timer_restart(&temp_off_latency_timer, TEMP_OFF_LANTENCY_TIMEOUT);
+ }
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn app_hid_srv_cb
+ * @brief HID service callbacks are handled in this function.
+ * @param p_data - pointer to callback data
+ * @return cb_result
+ * @retval T_APP_RESULT
+ */
+static T_APP_RESULT app_hid_srv_cb(T_HID_CALLBACK_DATA *p_data)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ APP_PRINT_INFO1("[app_hid_srv_cb] msg_type %d", p_data->msg_type);
+ switch (p_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_data->msg_data.notification_indification_index)
+ {
+ case HID_NOTIFY_INDICATE_KB_ENABLE:
+ APP_PRINT_INFO0("[app_hid_srv_cb] HID_NOTIFY_INDICATE_KB_ENABLE");
+ app_global_data.is_keyboard_notify_en = true;
+ break;
+ case HID_NOTIFY_INDICATE_KB_DISABLE:
+ APP_PRINT_INFO0("[app_hid_srv_cb] HID_NOTIFY_INDICATE_KB_DISABLE");
+ app_global_data.is_keyboard_notify_en = false;
+ break;
+ case HID_NOTIFY_INDICATE_MM_KB_ENABLE:
+ APP_PRINT_INFO0("[app_hid_srv_cb] HID_NOTIFY_INDICATE_MM_KB_ENABLE");
+ app_global_data.is_mm_keyboard_notify_en = true;
+ break;
+ case HID_NOTIFY_INDICATE_MM_KB_DISABLE:
+ APP_PRINT_INFO0("[app_hid_srv_cb] HID_NOTIFY_INDICATE_MM_KB_DISABLE");
+ app_global_data.is_mm_keyboard_notify_en = false;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ APP_PRINT_INFO0("SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE\n");
+ }
+ break;
+ default:
+ break;
+ }
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn app_vendor_srv_cb
+ * @brief Vendor service callbacks are handled in this function.
+ * @param p_data - pointer to callback data
+ * @return cb_result
+ * @retval T_APP_RESULT
+ */
+static T_APP_RESULT app_vendor_srv_cb(T_VENDOR_CALLBACK_DATA *p_data)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ APP_PRINT_INFO1("[app_vendor_srv_cb] msg_type %d", p_data->msg_type);
+ switch (p_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ if (p_data->msg_data.notification_indification_index == VENDOR_NOTIFY_ENABLE)
+ {
+ APP_PRINT_INFO0("[app_vendor_srv_cb] VENDOR_NOTIFY_ENABLE");
+ server_send_data(0, app_global_data.vendor_srv_id,
+ BLE_SERVICE_CHAR_VENDOR_HANDSHAKE_INDEX,
+ (uint8_t *)vendor_svc_handshake_values,
+ 16,
+ GATT_PDU_TYPE_NOTIFICATION);
+ }
+ else if (p_data->msg_data.notification_indification_index == VENDOR_NOTIFY_DISABLE)
+ {
+ APP_PRINT_INFO0("[app_vendor_srv_cb] VENDOR_NOTIFY_DISABLE");
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ if (p_data->msg_data.write_msg.write_type == VENDOR_WRITE_HANDSHAKE)
+ {
+ APP_PRINT_INFO0("[app_vendor_srv_cb] SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE");
+ memcpy(vendor_svc_handshake_values, p_data->msg_data.write_msg.write_parameter.report_data.report,
+ 16);
+ if (!BTIF_VendorGetResponse(vendor_svc_handshake_values, 16))
+ {
+ APP_PRINT_WARN0("[app_vendor_srv_cb] blueAPI_HandShakeGetResponse failed!");
+ cb_result = APP_RESULT_APP_ERR;
+ }
+ }
+#if FEATURE_SUPPORT_MP_TEST_MODE
+ else if (p_data->msg_data.write_msg.write_type == VENDOR_WRITE_TEST_MODE)
+ {
+ mp_test_clear_bond_info();
+
+ if (mp_test_disable_test_mode_flag())
+ {
+ APP_PRINT_INFO0("[app_vendor_srv_cb] disable test mode flag success!");
+
+ /* notify 8-0x00 HID key notification */
+ uint8_t notify_buffer[8];
+ memset(notify_buffer, 0, sizeof(notify_buffer));
+ server_send_data(0, app_global_data.hid_srv_id, GATT_SRV_HID_KB_INPUT_INDEX,
+ notify_buffer, sizeof(notify_buffer), GATT_PDU_TYPE_NOTIFICATION);
+ }
+ else
+ {
+ APP_PRINT_WARN0("[app_vendor_srv_cb] disable test mode flag failed!");
+ cb_result = APP_RESULT_APP_ERR;
+ }
+ }
+#endif
+ else
+ {
+ cb_result = APP_RESULT_APP_ERR;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn app_ota_srv_cb
+ * @brief OTA service callbacks are handled in this function.
+ * @param p_data - pointer to callback data
+ * @return cb_result
+ * @retval T_APP_RESULT
+ */
+static T_APP_RESULT app_ota_srv_cb(T_OTA_CALLBACK_DATA *p_data)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ switch (p_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ if (OTA_WRITE_CHAR_VAL == p_data->msg_data.write.opcode &&
+ OTA_VALUE_ENTER == p_data->msg_data.write.u.value)
+ {
+#if SUPPORT_NORMAL_OTA
+#if SUPPORT_BAT_DETECT_FEATURE
+ bat_update_battery_info();
+ uint16_t bat_value = bat_get_current_voltage_value();
+
+ if (bat_value < BAT_ENTER_OTA_MODE_THRESHOLD)
+ {
+ APP_PRINT_INFO1("[app_ota_srv_cb] Cannot switch into OTA mode, battery voltage is too low %d",
+ bat_value);
+ cb_result = APP_RESULT_APP_ERR;
+ }
+ else
+#endif
+ {
+ APP_PRINT_INFO0("[app_ota_srv_cb] Preparing switch into OTA mode");
+ /* disconnect and prepare to enter OTA mode */
+ rcu_terminate_connection(DISCONN_REASON_OTA);
+ }
+#endif
+ }
+#if FEATURE_SUPPORT_MP_TEST_MODE
+ else if (OTA_WRITE_TEST_MODE_CHAR_VAL == p_data->msg_data.write.opcode)
+ {
+ APP_PRINT_INFO1("[MP] Test mode clear operation action: (%d)\n",
+ p_data->msg_data.write.u.value);
+ if (true == mp_test_clear_bond_info())
+ {
+ APP_PRINT_INFO0("[MP] Exit MP test mode.");
+ uint8_t exitTestModeData[8] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+ exitTestModeData[2] = 0xFF;
+ server_send_data(0, app_global_data.hid_srv_id, GATT_SRV_HID_KB_INPUT_INDEX,
+ exitTestModeData, sizeof(exitTestModeData), GATT_PDU_TYPE_NOTIFICATION);
+ }
+ }
+#endif
+ break;
+
+ default:
+ break;
+ }
+
+ return cb_result;
+}
+
+/******************************************************************
+ * @fn app_dfu_srv_cb
+ * @brief DFU service callbacks are handled in this function.
+ * @param p_data - pointer to callback data
+ * @return cb_result
+ * @retval T_APP_RESULT
+ */
+#if SUPPORT_SILENT_OTA
+static T_APP_RESULT app_dfu_srv_cb(T_DFU_CALLBACK_DATA *p_data)
+{
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ switch (p_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ if (p_data->msg_data.write.opcode == DFU_WRITE_START)
+ {
+ if (p_data->msg_data.write.write_attrib_index == INDEX_DFU_CONTROL_POINT_CHAR_VALUE)
+ {
+#if SUPPORT_BAT_DETECT_FEATURE
+ bat_update_battery_info();
+ if (bat_get_current_voltage_value() < BAT_ENTER_OTA_MODE_THRESHOLD)
+ {
+ APP_PRINT_INFO0("battery voltage value < BAT_ENTER_OTA_MODE_THRESHOLD, can't start OTA");
+ cb_result = APP_RESULT_REJECT;
+ break;
+ }
+#endif
+ app_set_latency_status(LATENCY_DFU_PROC_BIT, LANTENCY_OFF);
+ }
+ }
+ else if (p_data->msg_data.write.opcode == DFU_WRITE_ATTR_EXIT)
+ {
+ if (p_data->msg_data.write.write_attrib_index == INDEX_DFU_CONTROL_POINT_CHAR_VALUE)
+ {
+ uint8_t control_point_opcode = *p_data->msg_data.write.p_value;
+ switch (control_point_opcode)
+ {
+ case DFU_OPCODE_VALID_FW:
+ {
+ T_IO_MSG dfu_valid_fw_msg;
+ dfu_valid_fw_msg.type = IO_MSG_TYPE_DFU_VALID_FW;
+ dfu_valid_fw_msg.u.param = p_data->conn_id;
+ if (app_send_msg_to_apptask(&dfu_valid_fw_msg) == false)
+ {
+ DBG_DIRECT("DFU send Valid FW msg fail!");
+ }
+ }
+ break;
+ case DFU_OPCODE_ACTIVE_IMAGE_RESET:
+ {
+ rcu_terminate_connection(DISCONN_REASON_SILENT_OTA);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else if (p_data->msg_data.write.opcode == DFU_WRITE_ATTR_ENTER)
+ {
+#if FEATURE_SUPPORT_NO_ACTION_DISCONN
+ os_timer_restart(&no_act_disconn_timer, NO_ACTION_DISCON_TIMEOUT);
+#endif
+
+ /*check rcu state*/
+ uint8_t notif_data[9] = {0};
+ uint8_t control_point_opcode = *p_data->msg_data.write.p_value;
+ if (RCU_STATUS_PAIRED != app_global_data.rcu_status)
+ {
+ APP_PRINT_INFO0("[app_dfu_srv_cb] err: rcu is not paired.");
+
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = control_point_opcode;
+ notif_data[2] = DFU_ARV_FAIL_SYS_VERSION_ERROR;
+ server_send_data(0, app_global_data.dfu_srv_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, 3, GATT_PDU_TYPE_NOTIFICATION);
+ cb_result = APP_RESULT_REJECT;
+ }
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ if (p_data->msg_data.notification_indification_index == DFU_NOTIFY_ENABLE)
+ {
+ APP_PRINT_INFO0("dfu notification enable");
+ }
+ else if (p_data->msg_data.notification_indification_index ==
+ DFU_NOTIFY_DISABLE)
+ {
+ APP_PRINT_INFO0("dfu notification disable");
+ }
+ }
+ break;
+ default:
+ break;
+
+ }
+ return cb_result;
+}
+#endif
+
+/******************************************************************
+ * @fn peripheral_HandleBtDevStateChangeEvt
+ * @brief All the gaprole_States_t events are pre-handled in this function.
+ * Then the event handling function shall be called according to the newState.
+ *
+ * @param new_state - new gap state
+ * @param uint16_t cause
+ * @return none
+ * @retval void
+ */
+static void periph_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO4("periph_handle_dev_state_evt: init state %d, adv state %d, conn state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state,
+ new_state.gap_conn_state, cause);
+
+#if FEATURE_SUPPORT_PRIVACY
+ if ((new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ && (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ && (new_state.gap_conn_state == GAP_CONN_DEV_STATE_IDLE))
+ {
+ privacy_handle_resolv_list();
+ }
+#endif
+
+ if (app_global_data.gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+
+ /* set PPCP, otherwise may cause connection update failed case */
+ gaps_set_peripheral_preferred_conn_param(PPCP_CONN_INTERVAL_MIN, PPCP_CONN_INTERVAL_MAX,
+ PPCP_SLAVE_LATENCY, PPCP_SUP_TIMEOUT / 10);
+
+ app_global_data.rcu_status = RCU_STATUS_IDLE;
+
+#if SUPPORT_BAT_DETECT_FEATURE
+ /* update battery after stack ready */
+ bat_update_battery_info();
+#endif
+
+ T_LE_KEY_ENTRY *p_le_key_entry;
+ p_le_key_entry = le_get_high_priority_bond();
+ if ((p_le_key_entry != NULL) && (p_le_key_entry->is_used))
+ {
+ app_global_data.is_link_key_existed = true;
+ /* add paired device in white list */
+ le_modify_white_list(GAP_WHITE_LIST_OP_ADD, p_le_key_entry->remote_bd.addr,
+ (T_GAP_REMOTE_ADDR_TYPE)(p_le_key_entry->remote_bd.remote_bd_type));
+
+ /* attempt to reconnect with master if ont in low power*/
+ if (BAT_MODE_POWER_DOWN != bat_get_current_mode())
+ {
+ rcu_start_adv(ADV_DIRECT_LDC);
+ }
+ }
+ else
+ {
+ app_global_data.is_link_key_existed = false;
+
+ if (app_global_data.reset_reason != RESET_REASON_FACTORY_RESET)
+ {
+ if (BAT_MODE_POWER_DOWN != bat_get_current_mode())
+ {
+ rcu_start_adv(ADV_UNDIRECT_PAIRING);
+ }
+ }
+ }
+
+ app_nvic_config(); /* enable peripheral NVIC after GAP stack ready */
+ if (app_global_data.reset_reason == RESET_REASON_HW)
+ {
+ APP_PRINT_INFO0("start timer for back key when reset");
+ app_global_data.is_allow_to_factory_reset_for_back_key = 1;
+ os_timer_restart(&back_key_pressed_when_HW_reset_timer,
+ CHECK_BACK_KEY_PRESSED_WHEN_HW_RESET_TIMEOUT);
+ }
+ }
+ }
+
+ if (app_global_data.gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ /* sync rcu status to idle */
+ app_global_data.rcu_status = RCU_STATUS_IDLE;
+ os_timer_stop(&adv_timer);
+ os_timer_stop(&adv_change_data_timer);
+
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_STOP)
+ {
+ APP_PRINT_INFO0("Advertisng is stopped by user stop or timeouot");
+ /* check adv stop reason */
+ app_stop_adv_reason_handler(app_global_data.stop_adv_reason);
+ app_global_data.stop_adv_reason = STOP_ADV_REASON_IDLE; /* reset stop_adv_reason */
+ }
+ else if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("Advertisng is stopped for link establishment");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ app_global_data.rcu_status = RCU_STATUS_ADVERTISING;
+ }
+ }
+
+ if (app_global_data.gap_dev_state.gap_conn_state != new_state.gap_conn_state)
+ {
+ APP_PRINT_INFO2("conn state: %d -> %d",
+ app_global_data.gap_dev_state.gap_conn_state,
+ new_state.gap_conn_state);
+ }
+ app_global_data.gap_dev_state = new_state;
+}
+
+/******************************************************************
+ * @fn peripheral_HandleBtDevStateChangeEvt
+ * @brief Handle connection status change event.
+ *
+ * @param uint8_t conn_id
+ * @param T_GAP_CONN_STATE new_state
+ * @param uint16_t disc_cause
+ * @return none
+ * @retval void
+ */
+static void periph_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state,
+ uint16_t disc_cause)
+{
+ APP_PRINT_INFO3("periph_handle_conn_state_evt: conn_id = %d old_state = %d new_state = %d",
+ conn_id, app_global_data.gap_conn_state, new_state);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ app_global_data.rcu_status = RCU_STATUS_IDLE;
+ app_global_data.is_keyboard_notify_en = false;
+ app_global_data.is_mm_keyboard_notify_en = false;
+ app_global_data.is_atv_voice_notify_en = false;
+ LED_BLINK_EXIT(LED_TYPE_BLINK_PAIR_ADV);
+#if FEATURE_SUPPORT_NO_ACTION_DISCONN
+ /* stop no_act_disconn_timer if disconnection detected */
+ os_timer_stop(&no_act_disconn_timer);
+#endif
+ os_timer_stop(&next_state_check_timer); /* ensure pair_fail_disconn_timer is stopped */
+#if FEAUTRE_SUPPORT_IR_OVER_BLE
+ ir_service_handle_disconnect_event();
+#endif
+#if SUPPORT_BUZZER_FEATURE
+ fms_handle_disconnect_event();
+#endif
+ key_handle_disconnect_event();
+#if SUPPORT_VOICE_FEATURE
+ if (voice_driver_global_data.is_voice_driver_working == true)
+ {
+ voice_global_data.is_allowed_to_notify_voice_data = false;
+ voice_handle_stop_mic();
+ }
+#endif
+ if (disc_cause == (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ {
+ APP_PRINT_INFO0("[GAP_CONN_STATE_DISCONNECTED] REMOTE_USER_TERMINATE");
+
+ if (app_global_data.is_link_key_existed == false)
+ {
+ if (app_global_data.pair_failed_retry_cnt < MAX_PAIR_FAILED_RETRY_CNT)
+ {
+ app_global_data.pair_failed_retry_cnt++;
+ rcu_start_adv(ADV_UNDIRECT_PAIRING);
+ }
+ }
+ else
+ {
+ rcu_start_adv(ADV_DIRECT_LDC);
+ }
+ }
+ else if (disc_cause == (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE))
+ {
+ /* handle APP disconection reason */
+ app_disconn_reason_handler(app_global_data.disconn_reason);
+ }
+ else
+ {
+ APP_PRINT_WARN1("[GAP_CONN_STATE_DISCONNECTED] Connection lost: cause 0x%x", disc_cause);
+
+ if (true == app_global_data.is_link_key_existed)
+ {
+ rcu_start_adv(ADV_DIRECT_LDC);
+ }
+ }
+
+ app_global_data.disconn_reason = DISCONN_REASON_IDLE; /* reset disconn_reason */
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ app_global_data.rcu_status = RCU_STATUS_CONNECTED;
+ os_timer_restart(&next_state_check_timer, PAIRING_EXCEPTION_TIMEOUT);
+
+ /* reset latency_status to default after connect */
+ memset(&app_global_data.latency_status, 0, sizeof(app_global_data.latency_status));
+ /* turn off slave latency to speed up pairing process, have to turn on latency later */
+ app_set_latency_status(LATENCY_SYS_UPDATE_BIT, LANTENCY_OFF);
+#if FEATURE_SUPPORT_DATA_LENGTH_EXTENSION
+ uint16_t gap_param_data_len_tx_oct = 251;
+ uint16_t gap_param_data_len_tx_time = 2120; /* tx max time: 2.12ms */
+ le_set_data_len(conn_id, gap_param_data_len_tx_oct, gap_param_data_len_tx_time);
+#endif
+#if SUPPORT_BUZZER_FEATURE
+ fms_handle_connect_event();
+#endif
+ /* print remote device information */
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ uint8_t remote_bd_type;
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ app_global_data.gap_conn_state = new_state;
+}
+
+/******************************************************************
+ * @fn peripheral_HandleBtGapAuthenStateChangeEvt
+ * @brief All the bonding state change events are pre-handled in this function.
+ * Then the event handling function shall be called according to the newState.
+ *
+ * @param uint8_t conn_id
+ * @param T_GAP_CONN_STATE new_state
+ * @param uint16_t cause
+ * @return none
+ * @retval void
+ */
+static void periph_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO1("periph_handle_authen_state_evt:conn_id %d", conn_id);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("GAP_AUTHEN_STATE_STARTED");
+ os_timer_restart(&next_state_check_timer, PAIRING_EXCEPTION_TIMEOUT);
+ /* slave init MTU size exchange process */
+ client_send_exchange_mtu_req(conn_id);
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_INFO0("[GAP_AUTHEN_STATE_COMPLETE] pairing success");
+ app_global_data.is_link_key_existed = true;
+ app_global_data.rcu_status = RCU_STATUS_PAIRED;
+ app_global_data.pair_failed_retry_cnt = 0;
+ app_global_data.updt_conn_params_retry_cnt = 0; /* reset retry cnt */
+
+ os_timer_stop(&next_state_check_timer);
+#if FEATURE_SUPPORT_NO_ACTION_DISCONN
+ os_timer_restart(&no_act_disconn_timer, NO_ACTION_DISCON_TIMEOUT);
+#endif
+
+ if ((app_global_data.adv_type == ADV_DIRECT_HDC)
+ || (app_global_data.adv_type == ADV_UNDIRECT_RECONNECT)
+ || (app_global_data.adv_type == ADV_UNDIRECT_WAKEUP)
+ || (app_global_data.adv_type == ADV_DIRECT_LDC))
+ {
+ os_timer_restart(&notify_key_data_after_reconn_timer, NOTIFY_KEY_DATA_TIMEOUT);
+
+ /* update connection parameter 1s delay */
+ os_timer_restart(&update_conn_params_timer, UPDATE_CONN_PARAMS_SHORT_TIMEOUT);
+ }
+ else
+ {
+ LED_BLINK_EXIT(LED_TYPE_BLINK_PAIR_ADV);
+ LED_BLINK(LED_TYPE_BLINK_CONFIRMATION, 2);
+
+ key_handle_reset_key_pressed_cache_fifo();
+ /* start timer to update connection parameter, postpone with timer to accelate GATT process */
+ os_timer_restart(&update_conn_params_timer, UPDATE_CONN_PARAMS_TIMEOUT);
+ }
+ }
+ else
+ {
+#if SUPPORT_LED_INDICATION_FEATURE
+ LED_BLINK_EXIT(LED_TYPE_BLINK_PAIR_ADV);
+ LED_BLINK(LED_TYPE_BLINK_ERROR, 4);
+#endif
+ if (cause == (SM_ERR | SM_ERR_KEY_SAVE_FAILED))
+ {
+ le_bond_clear_all_keys();
+ }
+
+ else if (cause == (SM_ERR | SM_ERR_LINK_KEY_MISSING))
+ {
+ APP_PRINT_INFO0("G20 - key missing");
+ }
+ APP_PRINT_INFO0("[GAP_AUTHEN_STATE_COMPLETE] pair failed");
+
+ os_timer_restart(&next_state_check_timer, PAIR_FAIL_DISCONN_TIMEOUT);
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_INFO1("GAP_MSG_LE_AUTHEN_STATE_CHANGE:(unknown newstate: %d)", new_state);
+ }
+ break;
+ }
+}
+
+/******************************************************************
+ * @fn peripheral_HandleBtGapConnParaChangeEvt
+ * @brief All the connection parameter update change events are pre-handled in this function.
+ * Then the event handling function shall be called according to the status.
+ *
+ * @param uint8_t conn_id
+ * @param uint8_t status - connection parameter result, 0 - success, otherwise fail.
+ * @param uint16_t cause
+ * @return none
+ * @retval void
+ */
+static void periph_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ /* reset updt_conn_params_retry_cnt */
+ app_global_data.updt_conn_params_retry_cnt = 0;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &app_global_data.conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &app_global_data.conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &app_global_data.conn_supervision_timeout, conn_id);
+
+ APP_PRINT_INFO3("GAP_MSG_LE_CONN_PARAM_UPDATE update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ app_global_data.conn_interval, app_global_data.conn_latency,
+ app_global_data.conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("GAP_MSG_LE_CONN_PARAM_UPDATE failed: cause 0x%x", cause);
+ if (app_global_data.updt_conn_params_retry_cnt < MAX_UPDATE_CONN_PARAMS_RETRY_CNT)
+ {
+ app_global_data.updt_conn_params_retry_cnt++;
+ APP_PRINT_WARN0("[rcu_update_conn_params] GAP_CONN_PARAM_UPDATE_STATUS_FAIL retry");
+ os_timer_restart(&update_conn_params_timer, UPDATE_CONN_PARAMS_TIMEOUT);
+ }
+ else
+ {
+ APP_PRINT_WARN0("[rcu_update_conn_params] GAP_CONN_PARAM_UPDATE_STATUS_FAIL failed");
+ }
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("GAP_CONN_PARAM_UPDATE_STATUS_PENDING");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/******************************************************************
+ * @fn peripheral_HandleBtGapMessage
+ * @brief All the bt gap msg events are pre-handled in this function.
+ * Then the event handling function shall be called according to the subType
+ * of BEE_IO_MSG.
+ *
+ * @param p_gap_msg - pointer to bee io msg
+ * @return none
+ * @retval void
+ */
+static void periph_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("periph_handle_gap_msg subType = %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ periph_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ periph_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ periph_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ periph_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ uint8_t mtu_size = 0;
+ le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size,
+ gap_msg.msg_data.gap_conn_mtu_info.conn_id);
+
+ if (mtu_size >= 23)
+ {
+ /* update mtu size */
+ app_global_data.mtu_size = mtu_size;
+ APP_PRINT_INFO1("[periph_handle_gap_msg] update mtu size to %d", mtu_size);
+ }
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("periph_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+#if !FEATURE_SUPPORT_PRIVACY
+/******************************************************************
+ * @brief handle bond modify message.
+ * @param T_LE_BOND_MODIFY_TYPE type
+ * @param T_LE_KEY_ENTRY *p_entry
+ * @return none
+ * @retval void
+ */
+void app_handle_bond_modify_msg(T_LE_BOND_MODIFY_TYPE type, T_LE_KEY_ENTRY *p_entry)
+{
+ APP_PRINT_INFO1("app_handle_bond_modify_msg GAP_MSG_LE_BOND_MODIFY_INFO:type=0x%x",
+ type);
+
+ switch (type)
+ {
+ case LE_BOND_DELETE:
+ {
+ le_modify_white_list(GAP_WHITE_LIST_OP_REMOVE, p_entry->remote_bd.addr,
+ (T_GAP_REMOTE_ADDR_TYPE)(p_entry->remote_bd.remote_bd_type));
+ }
+ break;
+ case LE_BOND_ADD:
+ {
+ le_modify_white_list(GAP_WHITE_LIST_OP_ADD, p_entry->remote_bd.addr,
+ (T_GAP_REMOTE_ADDR_TYPE)(p_entry->remote_bd.remote_bd_type));
+ }
+ break;
+ case LE_BOND_CLEAR:
+ {
+ le_modify_white_list(GAP_WHITE_LIST_OP_CLEAR, p_entry->remote_bd.addr,
+ (T_GAP_REMOTE_ADDR_TYPE)(p_entry->remote_bd.remote_bd_type));
+ }
+ break;
+ default:
+ break;
+ }
+}
+#endif
+
+/******************************************************************
+ * @brief set or get rcu app latency status.
+ * @param index_bit - module index
+ * @param new_status - LANTENCY_ON or LANTENCY_OFF
+ * @return none
+ * @retval void
+ */
+void app_set_latency_status(T_APP_LATENCY_MASK index_bit, T_LATENCY_STATE new_state)
+{
+ uint8_t retry_cnt = 0;
+ bool latency_update_value = true;
+
+ APP_PRINT_INFO2("[app_set_latency_status] module index = %d, new_state is %d", index_bit,
+ new_state);
+
+ /*0. check new state valid or not */
+ if ((new_state != LANTENCY_ON) && (new_state != LANTENCY_OFF))
+ {
+ APP_PRINT_WARN0("[app_set_latency_status] new_state is invalid");
+ return;
+ }
+
+ /*1. check latency state is updating */
+ if (app_global_data.latency_status.is_updating == true)
+ {
+ APP_PRINT_INFO0("[app_set_latency_status] latency_status is pending!");
+ /* update pending latency status */
+ app_global_data.latency_status.is_pending = true;
+ app_global_data.latency_status.pending_status = new_state;
+ app_global_data.latency_status.pending_index_bit = index_bit;
+ return ;
+ }
+
+ /*2. update latency data value */
+ if (new_state == LANTENCY_OFF)
+ {
+ app_global_data.latency_status.latency_bits_map |= (1 << index_bit);
+ }
+ else
+ {
+ app_global_data.latency_status.latency_bits_map &= ~(1 << index_bit);
+ }
+
+ /*3. check whether need update according to latency value*/
+ if (0 == app_global_data.latency_status.latency_bits_map)
+ {
+ /* need enable latency*/
+ if (LANTENCY_ON == app_global_data.latency_status.cur_status)
+ {
+ APP_PRINT_INFO0("[app_set_latency_status] latency_status is already enabled!");
+ return;
+ }
+ latency_update_value = false;
+ }
+ else
+ {
+ /* need disable latency */
+ if (LANTENCY_OFF == app_global_data.latency_status.cur_status)
+ {
+ APP_PRINT_INFO0("[app_set_latency_status] latency_status is already disabled!");
+ return;
+ }
+ latency_update_value = true;
+ }
+
+ /*4. process latency update*/
+ while (retry_cnt < MAX_ONOFF_LATENCY_SEND_RETRY_CNT)
+ {
+ if (le_disable_slave_latency(0, latency_update_value) == GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_INFO1("[app_set_latency_status] call le_disable_slave_latency successfully, latency bit map: %#x",
+ app_global_data.latency_status.latency_bits_map);
+ app_global_data.latency_status.is_pending = false;
+ app_global_data.latency_status.is_updating = true;
+ app_global_data.latency_status.cur_status = new_state;
+ app_global_data.latency_status.cur_index_bit = index_bit;
+ return;
+ }
+ retry_cnt++;
+ }
+
+ /*5. check update success or not*/
+ if (retry_cnt >= MAX_ONOFF_LATENCY_SEND_RETRY_CNT)
+ {
+ /* all retry failed */
+ APP_PRINT_WARN0("[app_set_latency_status] all retry failed");
+ /* TBD: how to handle this scenario */
+ }
+}
+
+/******************************************************************
+ * @fn app_init_global_data
+ * @brief Initialize global APP data
+ * @param void
+ * @return none
+ * @retval void
+ */
+void app_init_global_data(void)
+{
+ memset(&app_global_data, 0, sizeof(app_global_data));
+ app_global_data.mtu_size = 23;
+ app_global_data.device_type = REMOTE_G20;
+ app_global_data.en_ble_feature = 1;
+ app_global_data.en_powerkey_cache = 1;
+ app_global_data.en_google_wakeuppack = 1;
+ memcpy(app_global_data.pnp_id, Default_PnP_ID, sizeof(Default_PnP_ID));
+ memcpy(app_global_data.fw_version, Default_FW_Rev, sizeof(Default_FW_Rev));
+ app_global_data.fw_version[1] = VERSION_MAJOR + 0x30;
+ memcpy(app_global_data.sw_version, Default_SW_Rev, sizeof(Default_SW_Rev));
+ app_global_data.sw_version[1] = VERSION_MINOR + 0x30;
+ app_global_data.sw_version[3] = VERSION_REVISION + 0x30;
+ app_global_data.sw_version[4] = VERSION_BUILDNUM + 0x30;
+ memset(app_global_data.wakeup_key1, 0xFF, sizeof(app_global_data.wakeup_key1));
+ app_global_data.wakeup_key1[0] = KEY_ID_Power;
+ memset(app_global_data.wakeup_key2, 0xFF, sizeof(app_global_data.wakeup_key2));
+ app_global_data.wakeup_adv_format = WAKEUP_FORMAT_GOOGLE_ONLY;
+ app_load_wakeup_key_cnt(&app_global_data.wakeup_key_count);
+ app_global_data.wakeup_key_index = KEY_ID_NONE;
+}
+
+/******************************************************************
+ * @fn app_handle_io_msg
+ * @brief All the application events are pre-handled in this function.
+ * All the IO MSGs are sent to this function, Then the event handling function
+ * shall be called according to the MSG type.
+ *
+ * @param io_msg - bee io msg data
+ * @return none
+ * @retval void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ APP_PRINT_INFO1("[app_handle_io_msg] msg_type is %d", msg_type);
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ periph_handle_gap_msg(&io_msg);
+ }
+ break;
+ case IO_MSG_TYPE_KEYSCAN:
+ {
+#if FEATURE_SUPPORT_NO_ACTION_DISCONN
+ /* key event to restart no_act_disconn_timer */
+ os_timer_restart(&no_act_disconn_timer, NO_ACTION_DISCON_TIMEOUT);
+#endif
+ if (key_handle_global_data.combine_keys_status != INVALID_COMBINE_KEYS_BIT_MASK)
+ {
+ /* reset combine keys bit mask and timer */
+ key_handle_global_data.combine_keys_status = INVALID_COMBINE_KEYS_BIT_MASK;
+ os_timer_stop(&combine_keys_detection_timer);
+ LED_BLINK_EXIT(LED_TYPE_BLINK_COMB_KEY_PRESS);
+ }
+
+ if (io_msg.subtype == IO_MSG_KEYSCAN_ALLKEYRELEASE)
+ {
+ key_handle_release_event();
+ }
+ else if (io_msg.subtype == IO_MSG_KEYSCAN_RX_PKT)
+ {
+#if FEATURE_SUPPORT_KEY_LONG_PRESS_PROTECT
+ if (false == key_handle_global_data.is_key_long_pressed)
+#endif
+ {
+ key_handle_pressed_event(io_msg.u.buf);
+ }
+ }
+ }
+ break;
+#if SUPPORT_VOICE_FEATURE
+ case IO_MSG_TYPE_GDMA:
+ APP_PRINT_INFO0("[Voice] GDMA Voice data MSG.");
+#if MP_TEST_MODE_SUPPORT_DATA_UART_TEST
+ if (app_global_data.test_mode == DATA_UART_TEST_MODE)
+ {
+ uart_test_handle_gdma_msg(io_msg);
+ }
+ else
+#endif
+ {
+ voice_handle_messages(VOICE_MSG_PERIPHERAL_GDMA, &io_msg);
+ }
+ break;
+#endif
+#if SUPPORT_IR_TX_FEATURE
+ case IO_MSG_TYPE_IR:
+ {
+ ir_send_msg_proc(io_msg.subtype);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_IR_FLASH:
+ {
+ ir_service_handle_flash_save_event();
+ }
+ break;
+#if (FEATURE_SUPPORT_MP_TEST_MODE && MP_TEST_MODE_SUPPORT_DATA_UART_TEST)
+ case IO_MSG_TYPE_UART:
+ {
+ uart_test_handle_uart_msg(io_msg);
+ }
+ break;
+#endif
+#if SUPPORT_BAT_DETECT_FEATURE
+ case IO_MSG_TYPE_BAT_DETECT:
+ {
+ bat_msg_handle(io_msg.subtype);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_RESET_WDG_TIMER:
+ {
+ APP_PRINT_INFO0("[WDG] Watch Dog Rset Timer");
+ WDG_Restart();
+ }
+ break;
+#if SUPPORT_SILENT_OTA
+ case IO_MSG_TYPE_DFU_VALID_FW:
+ {
+ dfu_service_handle_valid_fw(io_msg.u.param);
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+}
+
+/******************************************************************
+ * @fn app_gap_callback
+ * @brief All the application gap events are pre-handled in this function.
+ *
+ * @param cb_type - event type
+ * @param p_cb_data - point to datas
+ * @return result
+ * @retval T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_BOND_MODIFY_INFO:
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x",
+ p_data->p_le_bond_modify_info->type);
+#if FEATURE_SUPPORT_PRIVACY
+ privacy_handle_bond_modify_msg(p_data->p_le_bond_modify_info->type,
+ p_data->p_le_bond_modify_info->p_entry, true);
+#else
+ app_handle_bond_modify_msg(p_data->p_le_bond_modify_info->type,
+ p_data->p_le_bond_modify_info->p_entry);
+#endif
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ case GAP_MSG_LE_DISABLE_SLAVE_LATENCY:
+ APP_PRINT_INFO1("GAP_MSG_LE_DISABLE_SLAVE_LATENCY: cause 0x%x",
+ p_data->p_le_disable_slave_latency_rsp->cause);
+ /* restore is_updating to false */
+ app_global_data.latency_status.is_updating = false;
+ if (p_data->p_le_disable_slave_latency_rsp->cause == GAP_CAUSE_SUCCESS)
+ {
+ app_global_data.latency_status.retry_cnt = 0;
+ /* check if has any pending status */
+ if (app_global_data.latency_status.is_pending == true)
+ {
+ APP_PRINT_INFO0("[app_gap_callback] handle onoff latency pending status");
+ app_set_latency_status(app_global_data.latency_status.pending_index_bit,
+ app_global_data.latency_status.pending_status);
+ }
+ }
+ else
+ {
+ if (app_global_data.latency_status.retry_cnt < MAX_ONOFF_LATENCY_FAILED_RETRY_CNT)
+ {
+ APP_PRINT_WARN0("[app_gap_callback] retry onoff latency");
+ app_global_data.latency_status.retry_cnt++;
+ app_set_latency_status(app_global_data.latency_status.cur_index_bit,
+ app_global_data.latency_status.cur_status);
+ }
+ else
+ {
+ APP_PRINT_ERROR0("[app_gap_callback] OnOff latency failed!");
+ /* TBD: how to handle this scenario */
+ }
+ }
+ break;
+
+ default:
+ APP_PRINT_INFO1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+
+#if FEATURE_SUPPORT_PRIVACY
+/******************************************************************
+ * @fn app_privacy_callback
+ * @brief All the privacy events are pre-handled in this function.
+ *
+ * @param type - event type
+ * @param cb_data - point to datas
+ * @return none
+ * @retval void
+ */
+void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data)
+{
+ APP_PRINT_INFO1("app_privacy_callback: type %d", type);
+ switch (type)
+ {
+ case PRIVACY_STATE_MSGTYPE:
+ app_privacy_state = cb_data.privacy_state;
+ break;
+
+ case PRIVACY_RESOLUTION_STATUS_MSGTYPE:
+ app_privacy_resolution_state = cb_data.resolution_state;
+ break;
+
+ default:
+ break;
+ }
+}
+#endif
+
+/******************************************************************
+ * @fn app_profile_callback
+ * @brief All the bt profile callbacks are handled in this function.
+ * Then the event handling function shall be called according to the serviceID
+ * of BEE_IO_MSG.
+ *
+ * @param service_id - service id of profile
+ * @param p_data - pointer to callback data
+ * @return app_result
+ * @retval T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ app_general_srv_cb((T_SERVER_APP_CB_DATA *)p_data);
+ }
+ else if (service_id == app_global_data.bas_srv_id)
+ {
+ app_result = app_bas_srv_cb((T_BAS_CALLBACK_DATA *)p_data);
+ }
+ else if (service_id == app_global_data.dis_srv_id)
+ {
+ app_result = app_dis_srv_cb((T_DIS_CALLBACK_DATA *)p_data);
+ }
+ else if (service_id == app_global_data.hid_srv_id)
+ {
+ app_result = app_hid_srv_cb((T_HID_CALLBACK_DATA *)p_data);
+ }
+ else if (service_id == app_global_data.ir_srv_id)
+ {
+#if FEAUTRE_SUPPORT_IR_OVER_BLE
+ app_result = ir_service_handle_srv_cb((T_IR_CALLBACK_DATA *)p_data);
+#endif
+ }
+ else if (service_id == app_global_data.vendor_srv_id)
+ {
+ app_result = app_vendor_srv_cb((T_VENDOR_CALLBACK_DATA *)p_data);
+ }
+ else if (service_id == app_global_data.ota_srv_id)
+ {
+ app_result = app_ota_srv_cb((T_OTA_CALLBACK_DATA *)p_data);
+ }
+#if SUPPORT_SILENT_OTA
+ else if (service_id == app_global_data.dfu_srv_id)
+ {
+ app_result = app_dfu_srv_cb((T_DFU_CALLBACK_DATA *)p_data);
+ }
+#endif
+#if SUPPORT_VOICE_FEATURE
+ else if (service_id == app_global_data.atvv_srv_id)
+ {
+ app_result = voice_handle_atvv_srv_cb((T_ATVV_CALLBACK_DATA *)p_data);
+ }
+#endif
+#if SUPPORT_BUZZER_FEATURE
+ else if (service_id == app_global_data.fms_srv_id)
+ {
+ app_result = fms_handle_srv_cb((T_FMS_CALLBACK_DATA *)p_data);
+ }
+#endif
+ return app_result;
+}
+
+/******************************************************************
+ * @fn app_load_wakeup_key_cnt
+ * @brief Load the wakeup key count from FTL
+ *
+ * @param p_count - point of count
+ * @return bool
+ * @retval true or false
+ */
+bool app_load_wakeup_key_cnt(uint32_t *p_count)
+{
+ bool result = false;
+
+ if (0 == ftl_load(p_count, FTL_WAKEUP_KEY_COUNT_ADDR, FTL_WAKEUP_KEY_COUNT_LEN))
+ {
+ result = true;
+ }
+ else
+ {
+ *p_count = 0;
+ result = false;
+ }
+
+ APP_PRINT_INFO2("[app_load_wakeup_key_cnt] count = %d, result = %d", *p_count, result);
+ return result;
+}
+
+/******************************************************************
+ * @fn app_save_wakeup_key_cnt
+ * @brief Load the wakeup key count from FTL
+ *
+ * @param save_count - save count
+ * @return bool
+ * @retval true or false
+ */
+bool app_save_wakeup_key_cnt(uint32_t save_count)
+{
+ bool result = false;
+
+ if (0 == ftl_save(&save_count, FTL_WAKEUP_KEY_COUNT_ADDR, FTL_WAKEUP_KEY_COUNT_LEN))
+ {
+ result = true;
+ }
+ else
+ {
+ result = false;
+ }
+
+ APP_PRINT_INFO2("[app_save_wakeup_key_cnt] count = %d, result = %d", save_count, result);
+ return result;
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/rcu_application.h b/src/app/google_rcu/rcu_application.h
new file mode 100644
index 0000000..cf12f39
--- /dev/null
+++ b/src/app/google_rcu/rcu_application.h
@@ -0,0 +1,253 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file simple_ble_peripheral_application.h
+* @brief simple_ble_peripheral_application
+* @details simple_ble_peripheral_application
+* @author jane
+* @date 2015-12-22
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _PERIPHERAL_APPLICATION__
+#define _PERIPHERAL_APPLICATION__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <board.h>
+#include <app_msg.h>
+#include <gap_le.h>
+#include <profile_server.h>
+#include <gap_msg.h>
+#include <test_mode.h>
+#if FEATURE_SUPPORT_PRIVACY
+#include "privacy_mgnt.h"
+#endif
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/* @note:
+* keyscan debounce time should be smaller than RCU_CONNECT_INTERVAL*1.25ms, in case
+* keyscan can not be used due to keycan initialization when system enter dlps frequently,
+* you ca change keyscan debunce time in function keyscan_init_driver() and keyscan_enter_dlps_config().
+*/
+#define RCU_CONNECT_INTERVAL 8 /* 8 * 1.25ms = 10ms*/
+#define RCU_CONNECT_LATENCY 99
+#define RCU_SUPERVISION_TIMEOUT 4000 /* 4s */
+
+#define PPCP_CONN_INTERVAL_MIN 0x08
+#define PPCP_CONN_INTERVAL_MAX 0x0B
+#define PPCP_SLAVE_LATENCY 0
+#define PPCP_SUP_TIMEOUT 1000
+
+#define MAX_DIRECT_ADV_RETRY_CNT 3 /* max retry count for direct adv */
+#define MAX_ONOFF_LATENCY_SEND_RETRY_CNT 3 /* max retry count for call le_disable_slave_latency */
+#define MAX_ONOFF_LATENCY_FAILED_RETRY_CNT 5 /* max retry count for le_disable_slave_latency failure case */
+#define MAX_UPDATE_CONN_PARAMS_RETRY_CNT 3 /* max retry count for connection parameters update */
+#define MAX_PAIR_FAILED_RETRY_CNT 1 /* max retry count for pair failed scenario */
+
+#define NEW_SET_LATENCY_FUNC /* compile error workaround, todo: refactor rcu_dfu_service */
+
+#define DEV_TYPE_REMOTE_G10 1
+#define DEV_TYPE_REMOTE_G20 2
+
+#define APP_CUSTOM_WAKEUPKEY_NUM 12
+
+#define MAX_WAKE_CUSTOM_DATA_LEN 40
+
+typedef enum
+{
+ ADV_IDLE = 0,
+ ADV_DIRECT_HDC,
+ ADV_DIRECT_LDC,
+ ADV_DIRECT_LDC_LT,//long interval
+ ADV_UNDIRECT_RECONNECT,
+ ADV_UNDIRECT_PAIRING,
+ ADV_UNDIRECT_PAIRING_LT,//long interval
+ ADV_UNDIRECT_WAKEUP,
+} T_ADV_TYPE;
+
+typedef enum
+{
+ WAKEUP_FORMAT_GOOGLE_ONLY = 0,
+ WAKEUP_FORMAT_CUSTOM_AND_GOOGLE = 1,
+ WAKEUP_FORMAT_CUSTOM_ONLY = 2,
+} T_WAKEUP_ADV_FORMAT;
+
+typedef enum
+{
+ STOP_ADV_REASON_IDLE = 0,
+ STOP_ADV_REASON_PAIRING,
+ STOP_ADV_REASON_TIMEOUT,
+ STOP_ADV_REASON_WAKEUPKEY,
+ STOP_ADV_REASON_BACKKEY,
+ STOP_ADV_REASON_LOWPOWER,
+ STOP_ADV_REASON_UART_CMD,
+ STOP_ADV_REASON_RESTART_RECONNECT_ADV,
+} T_STOP_ADV_REASON;
+
+typedef enum
+{
+ DISCONN_REASON_IDLE = 0,
+ DISCONN_REASON_PAIRING,
+ DISCONN_REASON_TIMEOUT,
+ DISCONN_REASON_OTA,
+ DISCONN_REASON_PAIR_FAILED,
+ DISCONN_REASON_LOW_POWER,
+ DISCONN_REASON_UART_CMD,
+ DISCONN_REASON_SILENT_OTA,
+} T_DISCONN_REASON;
+
+typedef enum
+{
+ RCU_STATUS_IDLE = 0, /* RCU idle status */
+ RCU_STATUS_ADVERTISING, /* RCU adversting status */
+ RCU_STATUS_STOP_ADVERTISING, /* temporary status of stop adversting */
+ RCU_STATUS_CONNECTED, /* connect status but not start paring */
+ RCU_STATUS_PAIRED, /* rcu paired success status */
+ RCU_STATUS_DISCONNECTING, /* temporary status of disconnecting */
+ RCU_STATUS_LOW_POWER, /*rcu low power mode*/
+} T_RCU_STATUS;
+
+/**
+ * @brief APP latency state enum definition.
+ */
+typedef enum
+{
+ LANTENCY_ON = 0,
+ LANTENCY_OFF,
+} T_LATENCY_STATE;
+
+typedef enum
+{
+ LATENCY_SYS_UPDATE_BIT = 0,
+ LATENCY_PAIR_PROC_BIT = 1,
+ LATENCY_VOICE_PROC_BIT = 2,
+ LATENCY_DFU_PROC_BIT = 3,
+ LATENCY_IR_BLE_PROC_BIT = 4,
+ LATENCY_TEMP_OFF_BIT = 5,
+ LATENCY_MAX_BIT_NUM,
+} T_APP_LATENCY_MASK;
+
+/**
+ * @brief APP latency status struct definition.
+ */
+typedef struct
+{
+ bool is_updating;
+ bool is_pending;
+ uint8_t retry_cnt;
+ T_APP_LATENCY_MASK cur_index_bit;
+ T_APP_LATENCY_MASK pending_index_bit;
+ T_LATENCY_STATE cur_status;
+ T_LATENCY_STATE pending_status;
+ uint16_t latency_bits_map;
+} T_latency_status;
+
+/**
+ * @brief APP battery status status definition.
+ */
+typedef struct
+{
+ uint16_t voltage_value;
+ uint16_t level_value;
+} T_BATTERY_STATUS;
+
+
+
+/**
+ * @brief APP global data struct definition.
+ */
+typedef struct
+{
+ bool is_link_key_existed; /* to indicate whether link key is existed or not */
+ bool is_keyboard_notify_en; /* to indicate whether keyboard notification is enabled or not */
+ bool is_atv_voice_notify_en; /* to indicate whether voice(attv) notification is enabled or not */
+ bool is_mm_keyboard_notify_en; /* to indicate whether multimediea keyboard notification is enabled or not */
+ uint8_t device_type; /* to indicate the device type */
+ uint8_t device_ui_layout_type; /* to indicate the device ui layout type */
+ uint8_t en_find_me; /* to indicate whether Find Me is enabled or not */
+ uint8_t en_rpa; /* to indicate whether RPA is enabled or not */
+ uint8_t en_ble_feature; /* to indicate whether BLE Feature is enabled or not */
+ uint8_t en_powerkey_cache; /* to indicate whether power key cache is enabled or not */
+ uint8_t en_google_wakeuppack; /* to indicate whether google wakeuppack enabled or not */
+ uint8_t direct_adv_cnt; /* to indicate the count of high duty adv */
+ uint8_t updt_conn_params_retry_cnt; /* to indicate the retry count for connection parameter update */
+ uint8_t mtu_size; /* to indicate the current mtu size */
+ uint8_t pair_failed_retry_cnt; /* to indicate the retry cnt for pair failed scenario */
+ uint16_t find_me_wakeup_timeout; /* to indicate the find me wakeup timeout */
+ uint8_t wakeup_key_index; /* to indicate the wakeup key index */
+ uint32_t wakeup_key_count; /* to indicate the wakeup key count */
+ T_WAKEUP_ADV_FORMAT wakeup_adv_format; /* to indicate the wakeup adv format */
+ T_SW_RESET_REASON reset_reason; /* to indicate the reset reason */
+ uint8_t wakeup_adv_custom_data[MAX_WAKE_CUSTOM_DATA_LEN]; /* to indicate the data buffer of customized wakeup adv */
+ T_SERVER_ID bas_srv_id; /* to indicate the service id for BAS */
+ T_SERVER_ID dis_srv_id; /* to indicate the service id for DIS */
+ T_SERVER_ID hid_srv_id; /* to indicate the service id for HID */
+ T_SERVER_ID ir_srv_id; /* to indicate the service id for IR */
+ T_SERVER_ID vendor_srv_id; /* to indicate the service id for vendor service */
+ T_SERVER_ID ota_srv_id; /* to indicate the service id for OTA service */
+ T_SERVER_ID dfu_srv_id; /* to indicate the service id for DFU service */
+ T_SERVER_ID atvv_srv_id; /* to indicate the service id for ATVV service */
+ T_SERVER_ID voice_srv_id; /* to indicate the service id for voice service */
+ T_SERVER_ID fms_srv_id; /* to indicate the service id for FMS service */
+ T_RCU_STATUS rcu_status; /* to indicate the current status of rcu state machine */
+ T_GAP_DEV_STATE gap_dev_state; /* to indicate the current GAP device state */
+ T_GAP_CONN_STATE gap_conn_state; /* to indicate the current GAP connection state */
+ T_ADV_TYPE adv_type; /* to indicate the current advertising type */
+ T_STOP_ADV_REASON stop_adv_reason; /* to indicate the reason of stop advertising */
+ T_DISCONN_REASON disconn_reason; /* to indicate the reason of disconnec */
+ T_BATTERY_STATUS battery_status; /* to indicate the status of battery information */
+ T_latency_status latency_status; /* to indicate rcu app latency status */
+ T_TEST_MODE test_mode; /* to indicate current test mode */
+ uint16_t conn_interval; /* to indicate rcu connect interval */
+ uint16_t conn_latency; /* to indicate rcu connect latency */
+ uint16_t conn_supervision_timeout; /* to indicate rcu supervision time out */
+ uint16_t wakeupkey1_mask; /* to indicate the wakeup key1 mask */
+ uint16_t wakeupkey2_mask; /* to indicate the wakeup key2 mask */
+ uint8_t wakeup_key1[APP_CUSTOM_WAKEUPKEY_NUM]; /* to indicate the key ids with wakeup */
+ uint8_t wakeup_key2[APP_CUSTOM_WAKEUPKEY_NUM]; /* to indicate the key ids with wakeup */
+ uint8_t pnp_id[7]; /* to indicate the info of PnP Id */
+ uint8_t fw_version[6]; /* to indicate the info of FW version */
+ uint8_t sw_version[5]; /* to indicate the info of SW version */
+ uint8_t device_name_len; /* to indicate the length of device name */
+ uint8_t device_name[20]; /* to indicate the info of device name */
+ uint8_t is_allow_to_factory_reset_for_back_key; /* chaeck if rcu can reset by back key */
+ bool allow_to_send_two_ble_key_value; /*check if allow to send two ble key value */
+} T_APP_GLOBAL_DATA;
+
+extern T_APP_GLOBAL_DATA app_global_data;
+#if FEATURE_SUPPORT_PRIVACY
+extern T_PRIVACY_STATE app_privacy_state;
+extern T_PRIVACY_ADDR_RESOLUTION_STATE app_privacy_resolution_state;
+#endif
+
+#if !FEATURE_SUPPORT_PRIVACY
+void app_handle_bond_modify_msg(T_LE_BOND_MODIFY_TYPE type, T_LE_KEY_ENTRY *p_entry);
+#endif
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+void app_handle_io_msg(T_IO_MSG io_driver_msg_recv);
+void app_set_latency_status(T_APP_LATENCY_MASK index_bit, T_LATENCY_STATE new_state);
+void app_init_global_data(void);
+void app_nvic_config(void);
+#if FEATURE_SUPPORT_PRIVACY
+void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data);
+#endif
+bool app_load_wakeup_key_cnt(uint32_t *p_count);
+bool app_save_wakeup_key_cnt(uint32_t save_count);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/app/google_rcu/rcu_gap.c b/src/app/google_rcu/rcu_gap.c
new file mode 100644
index 0000000..f4417b8
--- /dev/null
+++ b/src/app/google_rcu/rcu_gap.c
@@ -0,0 +1,804 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file rcu_gap.c
+* @brief rcu gap implementation
+* @details including handler for advertising, disconnecting and updating parameters
+* @author barry_bian
+* @date 2020-02-24
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "rtl876x.h"
+#include "gap.h"
+#include "gap_adv.h"
+#include "rcu_gap.h"
+#include "board.h"
+#include "gap_storage_le.h"
+#include "gap_conn_le.h"
+#include "string.h"
+#include <trace.h>
+#include "mem_config.h"
+#include "rcu_application.h"
+#include <gap_bond_le.h>
+#include "os_timer.h"
+#include "swtimer.h"
+#include "led_driver.h"
+#if FEATURE_SUPPORT_PRIVACY
+#include "privacy_mgnt.h"
+#endif
+#include "app_custom.h"
+#include <gap_privacy.h>
+#include "battery_driver.h"
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/* What is the advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320 /* 20ms */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320 /* 30ms */
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+/* GAP - SCAN RSP data (max size = 31 bytes) */
+static uint8_t app_scan_rsp_data_len = 0;
+static uint8_t app_scan_rsp_data[31] = {};
+
+/* Pairing advertisement data (max size = 31 bytes, though this is
+ best kept short to conserve power while advertisting) */
+static uint8_t app_pairing_adv_data_len = 0;
+static uint8_t app_pairing_adv_data[31] = {};
+
+static const uint8_t app_adv_data_fixed_part[] =
+{
+ 0x02, /* length */
+ 0x01, /* type="Flags" */
+ 0x06, /* LE Limited Discoverable Mode, BR/EDR not supported */
+
+ 0x03, /* length */
+ 0x19, /* type="Appearance" */
+ 0x80, 0x01, /* Remote Control */
+
+ 0x05, /* length */
+ 0x02, /* type="incomplete 16-bit UUIDs available" */
+ 0x12, 0x18, /* HID Service */
+ 0x0F, 0x18,
+};
+
+/* GAP - Advertisement data (max size = 31 bytes, though this is
+ best kept short to conserve power while advertisting) */
+static uint8_t google_wake_adv_data[] =
+{
+ 0x0C, /* length */
+ 0x16, /* service data */
+ 0x36, 0xFD, /* Wakeup Packet Service ID */
+ 0x01, /* packet format version */
+ 0x01, /* key index */
+ 0x01, /* key press count */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* master MAC address */
+};
+static uint8_t google_wake_adv_data_len = sizeof(google_wake_adv_data);
+
+static uint8_t custom_wakeup_adv_data[31] = {};
+static uint8_t custom_wakeup_adv_data_len = 0;
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+void app_change_wakeup_adv_data(void)
+{
+ if ((app_global_data.rcu_status == RCU_STATUS_ADVERTISING)
+ && (app_global_data.adv_type == ADV_UNDIRECT_WAKEUP))
+ {
+ le_adv_set_param(GAP_PARAM_ADV_DATA, google_wake_adv_data_len, google_wake_adv_data);
+ le_adv_update_param();
+ }
+}
+
+/******************************************************************
+ * @brief update adv and scan response data
+ * @param void
+ * @retval void
+ */
+void rcu_update_adv_rsp_data(void)
+{
+ /* set to default value */
+ app_scan_rsp_data_len = 0;
+ memset(app_scan_rsp_data, 0, sizeof(app_scan_rsp_data));
+ app_pairing_adv_data_len = 0;
+ memset(app_pairing_adv_data, 0, sizeof(app_pairing_adv_data));
+
+ /* prepare scan response data */
+ app_scan_rsp_data[0] = app_global_data.device_name_len + 1;
+ app_scan_rsp_data[1] = 0x09;
+ memcpy(&app_scan_rsp_data[2], app_global_data.device_name, app_global_data.device_name_len);
+ app_scan_rsp_data_len = app_global_data.device_name_len + 2;
+
+ /* prepare adv data */
+ memcpy(app_pairing_adv_data, app_scan_rsp_data, app_scan_rsp_data_len);
+ memcpy(&app_pairing_adv_data[app_scan_rsp_data_len], app_adv_data_fixed_part,
+ sizeof(app_adv_data_fixed_part));
+ app_pairing_adv_data_len = app_scan_rsp_data_len + sizeof(app_adv_data_fixed_part);
+}
+
+/******************************************************************
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @param none
+ * @return none
+ * @retval void
+ */
+void rcu_le_gap_init(void)
+{
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = {0};
+ memcpy(device_name, app_global_data.device_name, app_global_data.device_name_len);
+
+ uint16_t appearance = GAP_GATT_APPEARANCE_GENERIC_REMOTE_CONTROL;
+
+ //advertising parameters
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MIN;
+
+ //GAP Bond Manager parameters
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+ uint8_t auth_sec_req_enable = false;
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t slave_init_mtu_req = false;
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);//maximum MTU size default is 247
+
+ //Register gap callback
+ le_register_app_cb(app_gap_callback);
+
+#if FEATURE_SUPPORT_PRIVACY
+ privacy_init(app_privacy_callback, true);
+#endif
+
+ //Set RPA parameters
+ if (app_global_data.en_rpa == 1)
+ {
+ uint16_t privacy_timeout = APP_RESOLVED_TIMEOUT;
+ uint8_t gen_auto = 1;
+ uint8_t local_bd_type = GAP_LOCAL_ADDR_LE_RAP_OR_PUBLIC;
+ le_privacy_set_param(GAP_PARAM_PRIVACY_TIMEOUT, sizeof(uint16_t), &privacy_timeout);
+ le_bond_set_param(GAP_PARAM_BOND_GEN_LOCAL_IRK_AUTO, sizeof(gen_auto), &gen_auto);
+ le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type);
+ }
+
+ //Set device name and device appearance
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+
+ //Set advertising parameters
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, app_pairing_adv_data_len, app_pairing_adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, app_scan_rsp_data_len, app_scan_rsp_data);
+
+ // Setup the GAP Bond Manager
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+}
+
+/******************************************************************
+ * @brief start advertising
+ * @param adv_type - indicate to send which type of adv
+ * @return result of starting advertising
+ * @retval true or false
+ */
+bool rcu_start_adv(T_ADV_TYPE adv_type)
+{
+ bool result = false;
+ if (app_global_data.en_ble_feature == 0)
+ {
+ APP_PRINT_INFO0("RCU disable BLE");
+ return result;
+ }
+
+ uint8_t adv_event_type;
+ uint8_t adv_channel_map;
+ uint8_t adv_filter_policy;
+ uint16_t adv_interval_min;
+ uint16_t adv_interval_max;
+ uint16_t local_bd_type;
+ T_LE_KEY_ENTRY *p_le_key_entry = le_get_high_priority_bond();
+
+ /* check current status, only allow to start adv if RCU_STATUS_IDLE */
+ if (app_global_data.rcu_status != RCU_STATUS_IDLE)
+ {
+ APP_PRINT_WARN1("rcu_status %d is not allowed to start adv again!", app_global_data.rcu_status);
+ return false;
+ }
+
+ switch (adv_type)
+ {
+ case ADV_DIRECT_HDC:
+ {
+ adv_event_type = GAP_ADTYPE_ADV_HDC_DIRECT_IND;
+ adv_filter_policy = GAP_ADV_FILTER_ANY;
+ adv_channel_map = GAP_ADVCHAN_ALL;
+
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_event_type), &adv_event_type);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_channel_map), &adv_channel_map);
+
+#if FEATURE_SUPPORT_PRIVACY
+ uint8_t addr_type = p_le_key_entry->remote_bd.addr[5] & RANDOM_ADDR_MASK;
+ if ((p_le_key_entry->remote_bd.remote_bd_type == GAP_REMOTE_ADDR_LE_RANDOM) &&
+ (addr_type == RANDOM_ADDR_MASK_RESOLVABLE))
+ {
+ APP_PRINT_INFO0("[rcu_start_adv] resolvable random addr!");
+ if (app_privacy_resolution_state == PRIVACY_ADDR_RESOLUTION_DISABLED)
+ {
+ privacy_set_addr_resolution(true);
+ }
+
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE,
+ sizeof(p_le_key_entry->resolved_remote_bd.remote_bd_type),
+ &(p_le_key_entry->resolved_remote_bd.remote_bd_type));
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(p_le_key_entry->resolved_remote_bd.addr),
+ p_le_key_entry->resolved_remote_bd.addr);
+ }
+ else
+#endif
+ {
+ APP_PRINT_INFO0("[rcu_start_adv] not resolvable random addr!");
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(p_le_key_entry->remote_bd.remote_bd_type),
+ &(p_le_key_entry->remote_bd.remote_bd_type));
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(p_le_key_entry->remote_bd.addr),
+ p_le_key_entry->remote_bd.addr);
+ }
+
+ if (GAP_CAUSE_SUCCESS == le_adv_start())
+ {
+ APP_PRINT_INFO0("rcu start ADV_DIRECT_HDC success!");
+ app_global_data.rcu_status = RCU_STATUS_ADVERTISING;
+ app_global_data.adv_type = ADV_DIRECT_HDC;
+ result = true;
+ }
+ else
+ {
+ APP_PRINT_WARN0("rcu start ADV_DIRECT_HDC fail!");
+ }
+ }
+ break;
+
+ case ADV_DIRECT_LDC:
+ {
+ adv_event_type = GAP_ADTYPE_ADV_LDC_DIRECT_IND;
+ adv_filter_policy = GAP_ADV_FILTER_ANY;
+ adv_channel_map = GAP_ADVCHAN_ALL;
+ adv_interval_min = 0x20; /* 20ms */
+ adv_interval_max = 0x28; /* 25ms */
+
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_event_type), &adv_event_type);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_channel_map), &adv_channel_map);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_interval_min), &adv_interval_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_interval_max), &adv_interval_max);
+
+#if FEATURE_SUPPORT_PRIVACY
+ uint8_t addr_type = p_le_key_entry->remote_bd.addr[5] & RANDOM_ADDR_MASK;
+ if ((p_le_key_entry->remote_bd.remote_bd_type == GAP_REMOTE_ADDR_LE_RANDOM) &&
+ (addr_type == RANDOM_ADDR_MASK_RESOLVABLE))
+ {
+ APP_PRINT_INFO0("[rcu_start_adv] resolvable random addr!");
+ if (app_privacy_resolution_state == PRIVACY_ADDR_RESOLUTION_DISABLED)
+ {
+ privacy_set_addr_resolution(true);
+ }
+
+ //Set RPA parameters
+ if (app_global_data.en_rpa == 1)
+ {
+ local_bd_type = GAP_LOCAL_ADDR_LE_RAP_OR_PUBLIC;
+ le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type);
+ }
+
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE,
+ sizeof(p_le_key_entry->resolved_remote_bd.remote_bd_type),
+ &(p_le_key_entry->resolved_remote_bd.remote_bd_type));
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(p_le_key_entry->resolved_remote_bd.addr),
+ p_le_key_entry->resolved_remote_bd.addr);
+ }
+ else
+#endif
+ {
+ APP_PRINT_INFO0("[rcu_start_adv] not resolvable random addr!");
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(p_le_key_entry->remote_bd.remote_bd_type),
+ &(p_le_key_entry->remote_bd.remote_bd_type));
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(p_le_key_entry->remote_bd.addr),
+ p_le_key_entry->remote_bd.addr);
+ }
+
+ if (GAP_CAUSE_SUCCESS == le_adv_start())
+ {
+ APP_PRINT_INFO0("rcu start ADV_DIRECT_LDC success!");
+ app_global_data.rcu_status = RCU_STATUS_ADVERTISING;
+ app_global_data.adv_type = ADV_DIRECT_LDC;
+ os_timer_restart(&adv_timer, ADV_UPDATE_INTERVAL_TIMEOUT);
+ result = true;
+ }
+ else
+ {
+ APP_PRINT_WARN0("rcu start ADV_DIRECT_LDC fail!");
+ }
+ }
+ break;
+ case ADV_DIRECT_LDC_LT:
+ {
+ adv_event_type = GAP_ADTYPE_ADV_LDC_DIRECT_IND;
+ adv_filter_policy = GAP_ADV_FILTER_ANY;
+ adv_channel_map = GAP_ADVCHAN_ALL;
+ adv_interval_min = 0x30; /* 30ms */
+ adv_interval_max = 0x35; /* 35ms */
+
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_event_type), &adv_event_type);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_channel_map), &adv_channel_map);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_interval_min), &adv_interval_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_interval_max), &adv_interval_max);
+
+#if FEATURE_SUPPORT_PRIVACY
+ uint8_t addr_type = p_le_key_entry->remote_bd.addr[5] & RANDOM_ADDR_MASK;
+ if ((p_le_key_entry->remote_bd.remote_bd_type == GAP_REMOTE_ADDR_LE_RANDOM) &&
+ (addr_type == RANDOM_ADDR_MASK_RESOLVABLE))
+ {
+ APP_PRINT_INFO0("[rcu_start_adv] resolvable random addr!");
+ if (app_privacy_resolution_state == PRIVACY_ADDR_RESOLUTION_DISABLED)
+ {
+ privacy_set_addr_resolution(true);
+ }
+
+ //Set RPA parameters
+ if (app_global_data.en_rpa == 1)
+ {
+ local_bd_type = GAP_LOCAL_ADDR_LE_RAP_OR_PUBLIC;
+ le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type);
+ }
+
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE,
+ sizeof(p_le_key_entry->resolved_remote_bd.remote_bd_type),
+ &(p_le_key_entry->resolved_remote_bd.remote_bd_type));
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(p_le_key_entry->resolved_remote_bd.addr),
+ p_le_key_entry->resolved_remote_bd.addr);
+ }
+ else
+#endif
+ {
+ APP_PRINT_INFO0("[rcu_start_adv] not resolvable random addr!");
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(p_le_key_entry->remote_bd.remote_bd_type),
+ &(p_le_key_entry->remote_bd.remote_bd_type));
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(p_le_key_entry->remote_bd.addr),
+ p_le_key_entry->remote_bd.addr);
+ }
+
+ if (GAP_CAUSE_SUCCESS == le_adv_start())
+ {
+ APP_PRINT_INFO0("rcu start ADV_DIRECT_LDC_LT success!");
+ app_global_data.rcu_status = RCU_STATUS_ADVERTISING;
+ app_global_data.adv_type = ADV_DIRECT_LDC_LT;
+ os_timer_restart(&adv_timer, ADV_RECONNECT_TIMEOUT - ADV_UPDATE_INTERVAL_TIMEOUT);//90
+ result = true;
+ }
+ else
+ {
+ APP_PRINT_WARN0("rcu start ADV_DIRECT_LDC_LT fail!");
+ }
+ }
+ break;
+ case ADV_UNDIRECT_RECONNECT:
+ {
+#if FEATURE_SUPPORT_PRIVACY
+ uint8_t addr_type = p_le_key_entry->remote_bd.addr[5] & RANDOM_ADDR_MASK;
+ if ((p_le_key_entry->remote_bd.remote_bd_type == GAP_REMOTE_ADDR_LE_RANDOM) &&
+ (addr_type == RANDOM_ADDR_MASK_RESOLVABLE))
+ {
+ APP_PRINT_INFO0("[rcu_start_adv] resolvable random addr!");
+ if (app_privacy_resolution_state == PRIVACY_ADDR_RESOLUTION_DISABLED)
+ {
+ privacy_set_addr_resolution(true);
+ }
+ }
+#endif
+ adv_event_type = GAP_ADTYPE_ADV_IND;
+ adv_channel_map = GAP_ADVCHAN_ALL;
+ adv_filter_policy = GAP_ADV_FILTER_WHITE_LIST_ALL;
+ adv_interval_min = 0x20; /* 20ms */
+ adv_interval_max = 0x20; /* 20ms */
+
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_event_type), &adv_event_type);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_channel_map), &adv_channel_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_interval_min), &adv_interval_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_interval_max), &adv_interval_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, app_pairing_adv_data_len, app_pairing_adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, app_scan_rsp_data_len, app_scan_rsp_data);
+
+ if (GAP_CAUSE_SUCCESS == le_adv_start())
+ {
+ APP_PRINT_INFO0("rcu start ADV_UNDIRECT_RECONNECT success!");
+ app_global_data.rcu_status = RCU_STATUS_ADVERTISING;
+ app_global_data.adv_type = ADV_UNDIRECT_RECONNECT;
+ os_timer_restart(&adv_timer, ADV_RECONNECT_TIMEOUT);
+ result = true;
+ }
+ else
+ {
+ APP_PRINT_WARN0("rcu start ADV_UNDIRECT_RECONNECT fail!");
+ }
+ }
+ break;
+
+ case ADV_UNDIRECT_WAKEUP:
+ {
+ PROFILE_PRINT_INFO1("ADV_UNDIRECT_WAKEUP for wake up master, type is %d",
+ app_global_data.wakeup_adv_format);
+
+ uint8_t peer_mac_addr[6];
+ adv_event_type = GAP_ADTYPE_ADV_IND;
+ adv_channel_map = GAP_ADVCHAN_ALL;
+ adv_filter_policy = GAP_ADV_FILTER_WHITE_LIST_ALL;
+ adv_interval_min = 0x20; /* 20ms */
+ adv_interval_max = 0x30; /* 30ms */
+
+#if FEATURE_SUPPORT_PRIVACY
+ uint8_t addr_type = p_le_key_entry->remote_bd.addr[5] & RANDOM_ADDR_MASK;
+ if ((p_le_key_entry->remote_bd.remote_bd_type == GAP_REMOTE_ADDR_LE_RANDOM) &&
+ (addr_type == RANDOM_ADDR_MASK_RESOLVABLE))
+ {
+ APP_PRINT_INFO0("[rcu_start_adv] resolvable random addr!");
+
+ if (app_privacy_resolution_state == PRIVACY_ADDR_RESOLUTION_DISABLED)
+ {
+ privacy_set_addr_resolution(true);
+ }
+ memcpy(peer_mac_addr, p_le_key_entry->resolved_remote_bd.addr, 6);
+ }
+ else
+#endif
+ {
+ APP_PRINT_INFO0("[rcu_start_adv] not resolvable random addr!");
+ memcpy(peer_mac_addr, p_le_key_entry->remote_bd.addr, 6);
+ }
+
+ /* update wakeup adv data */
+ if ((app_global_data.wakeup_adv_format == WAKEUP_FORMAT_GOOGLE_ONLY)
+ || (app_global_data.wakeup_adv_format == WAKEUP_FORMAT_CUSTOM_AND_GOOGLE))
+ {
+ /* update google_wake_adv_data */
+ google_wake_adv_data[5] = app_custom_wakeupkey_packet_index(app_global_data.wakeup_key_index);
+ google_wake_adv_data[6] = (uint8_t)app_global_data.wakeup_key_count;
+ memcpy(&google_wake_adv_data[7], peer_mac_addr, 6);
+ }
+
+ if ((app_global_data.wakeup_adv_format == WAKEUP_FORMAT_CUSTOM_ONLY)
+ || (app_global_data.wakeup_adv_format == WAKEUP_FORMAT_CUSTOM_AND_GOOGLE))
+ {
+ /* update custom_wakeup_adv_data_len */
+ if ((app_global_data.wakeup_adv_custom_data[0] > 0) &&
+ (app_global_data.wakeup_adv_custom_data[0] <= 31))
+ {
+ custom_wakeup_adv_data_len = app_global_data.wakeup_adv_custom_data[0];
+ memcpy(custom_wakeup_adv_data, &app_global_data.wakeup_adv_custom_data[4],
+ custom_wakeup_adv_data_len);
+
+ uint8_t key_id_pos = app_global_data.wakeup_adv_custom_data[1];
+ if (key_id_pos <= 30)
+ {
+ custom_wakeup_adv_data[key_id_pos] = app_custom_wakeupkey_packet_index(
+ app_global_data.wakeup_key_index);
+ }
+
+ uint8_t key_cnt_pos = app_global_data.wakeup_adv_custom_data[2];
+ if (key_id_pos <= 30)
+ {
+ custom_wakeup_adv_data[key_cnt_pos] = (uint8_t)app_global_data.wakeup_key_count;
+ }
+
+ uint8_t peer_addr_pos = app_global_data.wakeup_adv_custom_data[3];
+ if (peer_addr_pos <= 24)
+ {
+ memcpy(&custom_wakeup_adv_data[peer_addr_pos], peer_mac_addr, 6);
+ }
+ }
+ }
+
+ if (app_global_data.wakeup_adv_format == WAKEUP_FORMAT_GOOGLE_ONLY)
+ {
+ le_adv_set_param(GAP_PARAM_ADV_DATA, google_wake_adv_data_len, google_wake_adv_data);
+ }
+ else if (app_global_data.wakeup_adv_format == WAKEUP_FORMAT_CUSTOM_AND_GOOGLE)
+ {
+ le_adv_set_param(GAP_PARAM_ADV_DATA, custom_wakeup_adv_data_len, custom_wakeup_adv_data);
+ os_timer_restart(&adv_change_data_timer, ADV_CHANGE_DATA_TIMEOUT);
+ }
+ else if (app_global_data.wakeup_adv_format == WAKEUP_FORMAT_CUSTOM_ONLY)
+ {
+ le_adv_set_param(GAP_PARAM_ADV_DATA, custom_wakeup_adv_data_len, custom_wakeup_adv_data);
+ }
+
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_event_type), &adv_event_type);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_channel_map), &adv_channel_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_interval_min), &adv_interval_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_interval_max), &adv_interval_max);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(app_scan_rsp_data), app_scan_rsp_data);
+
+ if (GAP_CAUSE_SUCCESS == le_adv_start())
+ {
+ APP_PRINT_INFO1("rcu start ADV_UNDIRECT_WAKEUP success, wakeup_adv_format is %d",
+ app_global_data.wakeup_adv_format);
+ app_global_data.rcu_status = RCU_STATUS_ADVERTISING;
+ app_global_data.adv_type = ADV_UNDIRECT_WAKEUP;
+ os_timer_restart(&adv_timer, ADV_UNDIRECT_POWER_TIMEOUT);
+ result = true;
+ }
+ else
+ {
+ APP_PRINT_WARN0("rcu start ADV_UNDIRECT_WAKEUP fail!");
+ }
+ }
+ break;
+
+ case ADV_UNDIRECT_PAIRING:
+ {
+ if (bat_get_current_mode() == BAT_MODE_LOW_POWER)
+ {
+ APP_PRINT_INFO0("LOW POWER INDICATION: CAN NOT ENTER PAIRING MODE");
+ return result;
+ }
+
+ PROFILE_PRINT_INFO0("ADV_UNDIRECT_PAIRING for pairing!");
+#if FEATURE_SUPPORT_REMOVE_LINK_KEY_BEFORE_PAIRING
+ if (app_global_data.is_link_key_existed)
+ {
+ app_global_data.is_link_key_existed = false;
+ le_bond_clear_all_keys();
+ }
+#endif
+#if FEATURE_SUPPORT_PRIVACY
+ if (app_privacy_resolution_state == PRIVACY_ADDR_RESOLUTION_ENABLED)
+ {
+ privacy_set_addr_resolution(false);
+ }
+#endif
+ adv_event_type = GAP_ADTYPE_ADV_IND;
+ adv_channel_map = GAP_ADVCHAN_ALL;
+ adv_filter_policy = GAP_ADV_FILTER_ANY;
+ adv_interval_min = 0x20; /* 20ms */
+ adv_interval_max = 0x28; /* 25ms */
+
+ //Set RPA parameters
+ if (app_global_data.en_rpa == 1)
+ {
+ local_bd_type = GAP_LOCAL_ADDR_LE_RAP_OR_PUBLIC;
+ le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type);
+ }
+
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_event_type), &adv_event_type);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_channel_map), &adv_channel_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_interval_min), &adv_interval_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_interval_max), &adv_interval_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, app_pairing_adv_data_len, app_pairing_adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, app_scan_rsp_data_len, app_scan_rsp_data);
+
+ if (GAP_CAUSE_SUCCESS == le_adv_start())
+ {
+ APP_PRINT_INFO0("rcu start ADV_UNDIRECT_PAIRING success!");
+ app_global_data.rcu_status = RCU_STATUS_ADVERTISING;
+ app_global_data.adv_type = ADV_UNDIRECT_PAIRING;
+
+ if (true == app_global_data.is_link_key_existed)
+ {
+ os_timer_restart(&adv_timer, ADV_UPDATE_INTERVAL_TIMEOUT);
+ }
+ else
+ {
+ os_timer_restart(&adv_timer, ADV_UPDATE_INTERVAL_TIMEOUT);
+ }
+#if SUPPORT_LED_INDICATION_FEATURE
+ LED_BLINK(LED_TYPE_BLINK_PAIR_ADV, 0);
+#endif
+ result = true;
+ }
+ else
+ {
+ APP_PRINT_WARN0("rcu start ADV_UNDIRECT_PAIRING fail!");
+ }
+ }
+ break;
+ case ADV_UNDIRECT_PAIRING_LT:
+ {
+ PROFILE_PRINT_INFO0("ADV_UNDIRECT_PAIRING_LT for pairing!");
+#if FEATURE_SUPPORT_REMOVE_LINK_KEY_BEFORE_PAIRING
+ if (app_global_data.is_link_key_existed)
+ {
+ app_global_data.is_link_key_existed = false;
+ le_bond_clear_all_keys();
+ }
+#endif
+#if FEATURE_SUPPORT_PRIVACY
+ if (app_privacy_resolution_state == PRIVACY_ADDR_RESOLUTION_ENABLED)
+ {
+ privacy_set_addr_resolution(false);
+ }
+#endif
+ adv_event_type = GAP_ADTYPE_ADV_IND;
+ adv_channel_map = GAP_ADVCHAN_ALL;
+ adv_filter_policy = GAP_ADV_FILTER_ANY;
+ adv_interval_min = 0x30; /* 30ms */
+ adv_interval_max = 0x35; /* 35ms */
+
+ //Set RPA parameters
+ if (app_global_data.en_rpa == 1)
+ {
+ local_bd_type = GAP_LOCAL_ADDR_LE_RAP_OR_PUBLIC;
+ le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type);
+ }
+
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_event_type), &adv_event_type);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_channel_map), &adv_channel_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_interval_min), &adv_interval_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_interval_max), &adv_interval_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, app_pairing_adv_data_len, app_pairing_adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, app_scan_rsp_data_len, app_scan_rsp_data);
+
+ if (GAP_CAUSE_SUCCESS == le_adv_start())
+ {
+ APP_PRINT_INFO0("rcu start ADV_UNDIRECT_PAIRING_LT success!");
+ app_global_data.rcu_status = RCU_STATUS_ADVERTISING;
+ app_global_data.adv_type = ADV_UNDIRECT_PAIRING_LT;
+
+ if (true == app_global_data.is_link_key_existed)
+ {
+ os_timer_restart(&adv_timer, ADV_UNDIRECT_REPAIRING_TIMEOUT - ADV_UPDATE_INTERVAL_TIMEOUT);
+ }
+ else
+ {
+ os_timer_restart(&adv_timer, ADV_UNDIRECT_PAIRING_TIMEOUT - ADV_UPDATE_INTERVAL_TIMEOUT);
+ }
+
+#if SUPPORT_LED_INDICATION_FEATURE
+ LED_BLINK(LED_TYPE_BLINK_PAIR_ADV, 0);
+#endif
+ result = true;
+ }
+ else
+ {
+ APP_PRINT_WARN0("rcu start ADV_UNDIRECT_PAIRING_LT fail!");
+ }
+ }
+ break;
+ default:
+ /* invalid adv type */
+ APP_PRINT_WARN1("[rcu_start_adv] unknown adv type: %d", adv_type);
+ break;
+ }
+
+ return result;
+}
+
+/******************************************************************
+ * @brief stop advertising
+ * @param stop_adv_reason - indicate to the reason to stop adv
+ * @return result of stoping advertising
+ * @retval true or false
+ */
+bool rcu_stop_adv(T_STOP_ADV_REASON stop_adv_reason)
+{
+ bool result = false;
+ app_global_data.stop_adv_reason = stop_adv_reason;
+
+ if (app_global_data.rcu_status == RCU_STATUS_ADVERTISING)
+ {
+ if (le_adv_stop() == GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_INFO0("[rcu_stop_adv] stop adv command sent successfully");
+ app_global_data.rcu_status = RCU_STATUS_STOP_ADVERTISING;
+ result = true;
+ }
+ else
+ {
+ APP_PRINT_WARN0("[rcu_stop_adv] stop adv command sent failed");
+ }
+ }
+ else
+ {
+ APP_PRINT_WARN1("[rcu_stop_adv] Invalid RCU status: %d", app_global_data.rcu_status);
+ }
+
+ return result;
+}
+
+/******************************************************************
+ * @brief terminate connection
+ * @param disconn_reason - indicate to the reason to terminate connection
+ * @return result of terminating connection
+ * @retval true or false
+ */
+bool rcu_terminate_connection(T_DISCONN_REASON disconn_reason)
+{
+ bool result = false;
+ app_global_data.disconn_reason = disconn_reason;
+
+ if ((app_global_data.rcu_status == RCU_STATUS_CONNECTED)
+ || (app_global_data.rcu_status == RCU_STATUS_PAIRED))
+ {
+ if (le_disconnect(0) == GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_INFO0("[rcu_terminate_connection] terminate command sent successfully");
+ result = true;
+ }
+ else
+ {
+ APP_PRINT_WARN0("[rcu_terminate_connection] terminate command sent failed");
+ }
+ }
+ else
+ {
+ APP_PRINT_WARN1("[rcu_terminate_connection] Invalid RCU status: %d", app_global_data.rcu_status);
+ }
+
+ return result;
+
+}
+
+/******************************************************************
+ * @brief update peripheral connection parameters
+ * @param interval
+ * @param latency
+ * @param timeout
+ * @return none
+ * @retval void
+ */
+void rcu_update_conn_params(uint16_t interval, uint16_t latency, uint16_t timeout)
+{
+ if (GAP_CAUSE_SUCCESS != le_update_conn_param(0, interval, interval, latency, timeout / 10,
+ interval * 2 - 2,
+ interval * 2 - 2))
+ {
+ if (app_global_data.updt_conn_params_retry_cnt < MAX_UPDATE_CONN_PARAMS_RETRY_CNT)
+ {
+ app_global_data.updt_conn_params_retry_cnt++;
+ APP_PRINT_WARN0("[rcu_update_conn_params] send HCI command retry");
+ os_timer_restart(&update_conn_params_timer, UPDATE_CONN_PARAMS_TIMEOUT);
+ }
+ else
+ {
+ APP_PRINT_WARN0("[rcu_update_conn_params] send HCI command failed");
+ }
+ }
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/rcu_gap.h b/src/app/google_rcu/rcu_gap.h
new file mode 100644
index 0000000..7f5856d
--- /dev/null
+++ b/src/app/google_rcu/rcu_gap.h
@@ -0,0 +1,38 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file rcu_gap.h
+* @brief
+* @details
+* @author Chuanguo Xue
+* @date 2020-02-25
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+
+#ifndef _RCU_GAP_H
+#define _RCU_GAP_H
+
+#include <stdint.h>
+#include "rcu_application.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rcu_update_adv_rsp_data(void);
+void rcu_le_gap_init(void);
+bool rcu_start_adv(T_ADV_TYPE adv_type);
+bool rcu_stop_adv(T_STOP_ADV_REASON stop_adv_reason);
+bool rcu_terminate_connection(T_DISCONN_REASON disconn_reason);
+void rcu_update_conn_params(uint16_t interval, uint16_t latency, uint16_t timeout);
+void app_change_wakeup_adv_data(void);
+
+extern bool BTIF_VendorGetResponse(uint8_t *pData, uint8_t len);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PROFILE_INIT_H */
diff --git a/src/app/google_rcu/reset_watch_dog_timer.c b/src/app/google_rcu/reset_watch_dog_timer.c
new file mode 100644
index 0000000..ac4c07c
--- /dev/null
+++ b/src/app/google_rcu/reset_watch_dog_timer.c
@@ -0,0 +1,108 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file reset_watch_dog_timer.c
+* @brief This is the entry of user code which the watch dog module resides in.
+* @details
+* @author barry_bian
+* @date 2020-03-10
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "rtl876x_tim.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_nvic.h"
+#include "app_msg.h"
+#include "app_task.h"
+#include "trace.h"
+#include <app_section.h>
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define TIMER_NUM TIM5
+#define TIMER_IRQN TIMER5_IRQ
+#define WDG_Timer_Handler Timer5_Handler
+#define TIMER_PERIOD (2*1000*1000*40-1) //2s for 40M clock
+
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+static void watch_dog_timer_driver_init(void);
+
+void WDG_Timer_Handler(void) DATA_RAM_FUNCTION;
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief Initialize watch dog timer.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void watch_dog_timer_driver_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+
+ TIM_TimeBaseInitTypeDef TIM_InitStruct;
+ TIM_StructInit(&TIM_InitStruct);
+
+ TIM_InitStruct.TIM_PWM_En = PWM_DISABLE;
+ TIM_InitStruct.TIM_Period = TIMER_PERIOD ;
+ TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ TIM_TimeBaseInit(TIMER_NUM, &TIM_InitStruct);
+
+ /* Enable TIMER IRQ */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = TIMER_IRQN;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ TIM_ClearINT(TIMER_NUM);
+ TIM_INTConfig(TIMER_NUM, ENABLE);
+ TIM_Cmd(TIMER_NUM, ENABLE);
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief enable watch dog timer.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void reset_watch_dog_timer_enable(void)
+{
+ watch_dog_timer_driver_init();
+}
+
+/******************************************************************
+ * @brief watch dog timer handle.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void WDG_Timer_Handler(void)
+{
+ TIM_ClearINT(TIMER_NUM);
+ TIM_Cmd(TIMER_NUM, DISABLE);
+ //send message to app task in which reset the watch dog timer
+ T_IO_MSG bee_io_msg = {0};
+ bee_io_msg.type = IO_MSG_TYPE_RESET_WDG_TIMER;
+ if (false == app_send_msg_to_apptask(&bee_io_msg))
+ {
+ APP_PRINT_ERROR0("[WDG] send IO_MSG_TYPE_RESET_WDG_TIMER message failed!");
+ }
+
+ TIM_Cmd(TIMER_NUM, ENABLE);
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/rtc_module/rtc_driver.c b/src/app/google_rcu/rtc_module/rtc_driver.c
new file mode 100644
index 0000000..55e20d8
--- /dev/null
+++ b/src/app/google_rcu/rtc_module/rtc_driver.c
@@ -0,0 +1,206 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file battery_driver.c
+* @brief rcu vbat adc sample.
+* @details
+* @author chenjie
+* @date 2020-05-11
+* @version v1.1
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "board.h"
+#include "rtl876x_rtc.h"
+#include "rtl876x_nvic.h"
+#include "trace.h"
+#include "rtc_driver.h"
+#include "app_section.h"
+#include "rtl876x_wdg.h"
+#include "stdio.h"
+
+/*============================================================================*
+ * Macro Definitions
+ *============================================================================*/
+/** Prescaler value.
+ * 12 bits prescaler for COUNTER frequency (32768/(PRESCALER+1)).
+ * If use internal 32KHz, (32000/(PRESCALER+1)).
+ * Must be written when RTC 32-bit counter is stopped.
+ */
+#define RTC_PRESCALER_VALUE 31 /* f = 1000Hz */
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+static uint32_t rtc_ovf_cnt = 0;
+static rtc_driver_raw_cb rtc_driver_comp_0_cb = NULL;
+
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+void RTC_Handler(void) DATA_RAM_FUNCTION;
+
+/*============================================================================*
+ * Local functions
+ *============================================================================*/
+
+/*============================================================================*
+ * Global functions
+ *============================================================================*/
+/**
+ * @brief Initialize rtc peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void rtc_driver_init(void)
+{
+ APP_PRINT_INFO0("[driver_rtc_init] init RTC");
+ rtc_ovf_cnt = 0;
+ RTC_DeInit();
+ RTC_SetPrescaler(RTC_PRESCALER_VALUE);
+
+ /* Config RTC interrupt */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ RTC_SystemWakeupConfig(ENABLE);
+ RTC_NvCmd(ENABLE);
+ /* Start RTC */
+ RTC_ResetCounter();
+ RTC_Cmd(ENABLE);
+}
+
+/**
+ * @brief Deinitialize rtc peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void rtc_driver_deinit(void)
+{
+ APP_PRINT_INFO0("[driver_rtc_init] deinit RTC");
+ RTC_DeInit();
+}
+
+/**
+ * @brief Get RTC timestamp in us uint
+ * @param No parameter.
+ * @return uint64_t time in us
+ */
+uint64_t rtc_driver_get_us(void)
+{
+ uint64_t time_in_us;
+
+ time_in_us = (((uint64_t)(1) << 32) * rtc_ovf_cnt + RTC_GetCounter()) * 1000 *
+ (1 + RTC_PRESCALER_VALUE) / 32;
+
+ APP_PRINT_INFO3("[rtc_driver_get_us] %d.%d%d sec", (uint32_t)(time_in_us / 1000000),
+ (uint32_t)((time_in_us % 1000000) / 1000),
+ (uint32_t)(time_in_us % 1000));
+
+ return time_in_us;
+}
+
+/**
+ * @brief Get RTC timestamp in ms uint
+ * @param No parameter.
+ * @return uint64_t time in ms
+ */
+uint64_t rtc_driver_get_ms(void)
+{
+ return (rtc_driver_get_us() / 1000);
+}
+
+/**
+ * @brief Get RTC timestamp in secnods uint
+ * @param No parameter.
+ * @return uint64_t time in ms
+ */
+uint32_t rtc_driver_get_seconds(void)
+{
+ return (rtc_driver_get_us() / 1000000);
+}
+
+/**
+ * @brief Set RTC comp 0 params
+ * @param time_ms - time in ms
+ * @param cb_func - callback function
+ * @return true or false
+ */
+bool rtc_driver_set_comp_0_params(uint32_t time_ms, rtc_driver_raw_cb cb_func)
+{
+ bool result = false;
+ uint32_t comp_value;
+
+ if (time_ms == 0)
+ {
+ result = false;
+ }
+ else
+ {
+ if (cb_func)
+ {
+ rtc_driver_comp_0_cb = cb_func;
+ }
+
+ comp_value = (uint32_t)((uint64_t)(time_ms) * 32 / (1 + RTC_PRESCALER_VALUE));
+ comp_value = ((RTC_GetCounter() + comp_value) & 0xFFFFFFFF);
+ RTC_SetCompValue(RTC_COMP0, comp_value);
+
+ RTC_ClearCompINT(RTC_COMP0);
+ RTC_INTConfig(RTC_INT_COMP0, ENABLE);
+
+ result = true;
+ }
+
+ APP_PRINT_INFO2("[rtc_driver_set_comp_0_params] result = %d, time_ms = %d", result, time_ms);
+
+ return result;
+}
+
+/**
+ * @brief Clear RTC comp 0
+ * @param No parameter.
+ * @return void
+ */
+void rtc_driver_clear_comp_0(void)
+{
+ RTC_INTConfig(RTC_INT_COMP0, DISABLE);
+ RTC_ClearCompINT(RTC_COMP0);
+}
+
+/**
+ * @brief RTC interrupt handle function.
+ * @param None.
+ * @return None.
+ */
+void RTC_Handler(void)
+{
+ /* RTC overflow interrupt handle */
+ if (RTC_GetINTStatus(RTC_INT_OVF) == SET)
+ {
+ APP_PRINT_INFO0("[RTC_Handler] RTC_INT_OVF");
+ rtc_ovf_cnt++;
+ RTC_ClearOverFlowINT();
+ }
+
+ if (RTC_GetINTStatus(RTC_INT_COMP0) == SET)
+ {
+ APP_PRINT_INFO0("[RTC_Handler] RTC_INT_COMP0");
+ rtc_driver_clear_comp_0();
+
+ if (rtc_driver_comp_0_cb)
+ {
+ rtc_driver_comp_0_cb();
+ }
+ }
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/rtc_module/rtc_driver.h b/src/app/google_rcu/rtc_module/rtc_driver.h
new file mode 100644
index 0000000..f864337
--- /dev/null
+++ b/src/app/google_rcu/rtc_module/rtc_driver.h
@@ -0,0 +1,51 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtc_driver.h
+* @details
+* @author chenjie_jin
+* @date 2021-01-09
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef _RTC_DRIVER_H_
+#define _RTC_DRIVER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <board.h>
+
+/*============================================================================*
+ * Macro Definitions
+ *============================================================================*/
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef void (*rtc_driver_raw_cb)(void);
+
+/*============================================================================*
+ * Interface Functions
+ *============================================================================*/
+void rtc_driver_init(void);
+void rtc_driver_deinit(void);
+uint64_t rtc_driver_get_us(void);
+uint64_t rtc_driver_get_ms(void);
+uint32_t rtc_driver_get_seconds(void);
+bool rtc_driver_set_comp_0_params(uint32_t time_ms, rtc_driver_raw_cb cb_func);
+void rtc_driver_clear_comp_0(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/swtimer.c b/src/app/google_rcu/swtimer.c
new file mode 100644
index 0000000..b7d82d8
--- /dev/null
+++ b/src/app/google_rcu/swtimer.c
@@ -0,0 +1,319 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file swtimer.c
+* @brief software timers source file.
+* @details include initialization and callback funcitions of software timers
+* @author
+* @date 2020-02-24
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "os_timer.h"
+#include <trace.h>
+#include "board.h"
+#include "swtimer.h"
+#include "rcu_gap.h"
+#include "rcu_application.h"
+#include "key_handle.h"
+#include "keyscan_driver.h"
+#include "gap_bond_le.h"
+#include "rtl876x_keyscan.h"
+#include "app_section.h"
+#if SUPPORT_VOICE_FEATURE
+#include "voice_driver.h"
+#endif
+#if SUPPORT_BUZZER_FEATURE
+#include "fms_service_handle.h"
+#endif
+
+/*============================================================================*
+ * Global Variables
+ *============================================================================*/
+TimerHandle_t adv_change_data_timer;
+TimerHandle_t adv_timer;
+TimerHandle_t temp_off_latency_timer;
+#if FEATURE_SUPPORT_NO_ACTION_DISCONN
+TimerHandle_t no_act_disconn_timer;
+#endif
+TimerHandle_t update_conn_params_timer;
+TimerHandle_t next_state_check_timer;
+#if (AON_WDG_ENABLE == 1)
+void *aon_watch_dog_wake_up_dlps_timer;
+#define AON_WDG_TIMER_WAKEUP_DLPS_PERIOD ((AON_WDG_TIME_OUT_PERIOD_SECOND - 1) * 1000)
+#endif
+TimerHandle_t system_rest_timer;
+TimerHandle_t back_key_pressed_when_HW_reset_timer;
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+static void adv_timer_callback(TimerHandle_t p_timer) DATA_RAM_FUNCTION;
+static void adv_change_data_timer_callback(TimerHandle_t p_timer) DATA_RAM_FUNCTION;
+static void next_state_timeout_timer_callback(TimerHandle_t p_timer) DATA_RAM_FUNCTION;
+static void update_conn_params_timer_cb(TimerHandle_t p_timer) DATA_RAM_FUNCTION;
+#if FEATURE_SUPPORT_NO_ACTION_DISCONN
+static void no_act_disconn_timer_callback(TimerHandle_t p_timer) DATA_RAM_FUNCTION;
+#endif
+#if (AON_WDG_ENABLE == 1)
+static void aon_watch_dog_wake_up_dlps_callback(TimerHandle_t p_timer) DATA_RAM_FUNCTION;
+#endif
+static void system_reset_timer_callback(TimerHandle_t p_timer) DATA_RAM_FUNCTION;
+static void temp_off_latency_timer_cb(TimerHandle_t p_timer) DATA_RAM_FUNCTION;
+static void back_key_pressed_when_HW_reset_timer_cb(TimerHandle_t p_timer) DATA_RAM_FUNCTION;
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+
+/******************************************************************
+* @brief back_key_pressed_when_HW_reset_timer callback.
+* @param p_timer - point of timer
+* @return none
+* @retval void
+* @note if reset reason is HW and back key is pressed in 50ms, then clean pairing table(inserting battery)
+*/
+void back_key_pressed_when_HW_reset_timer_cb(TimerHandle_t p_timer)
+{
+ APP_PRINT_INFO0("back_key_pressed_when_HW_reset_timer_cb");
+ app_global_data.is_allow_to_factory_reset_for_back_key = 0;
+}
+
+/******************************************************************
+ * @brief turn of slave latency timer callback.
+ * @param p_timer - point of timer
+ * @return none
+ * @retval void
+ * @note do NOT execute time consumption functions in timer callback
+ */
+void temp_off_latency_timer_cb(TimerHandle_t p_timer)
+{
+ if (app_global_data.rcu_status == RCU_STATUS_PAIRED)
+ {
+ app_set_latency_status(LATENCY_TEMP_OFF_BIT, LANTENCY_ON);
+ }
+}
+
+/******************************************************************
+ * @brief advertising timer callback
+ *
+ * adv_timer_callback is used to stop advertising after timeout
+ *
+ * @param p_timer - timer handler
+ * @return none
+ * @retval void
+ */
+void adv_timer_callback(TimerHandle_t p_timer)
+{
+ if (app_global_data.rcu_status == RCU_STATUS_ADVERTISING)
+ {
+ if (app_global_data.adv_type != ADV_DIRECT_HDC)
+ {
+ rcu_stop_adv(STOP_ADV_REASON_TIMEOUT);
+ }
+ }
+}
+
+/******************************************************************
+ * @brief advertising change data timer callback
+ *
+ * adv_change_data_timer_callback is used to change advertising data after timeout
+ *
+ * @param p_timer - timer handler
+ * @return none
+ * @retval void
+ */
+void adv_change_data_timer_callback(TimerHandle_t p_timer)
+{
+ APP_PRINT_INFO0("[adv_change_data_timer_callback] timeout");
+ app_change_wakeup_adv_data();
+}
+
+/******************************************************************
+ * @brief pair failed disconnection timer callback
+ *
+ * pair_fail_disconn_timer_callback is used to disconnect for pair failed
+ *
+ * @param p_timer - timer handler
+ * @return none
+ * @retval void
+ */
+void next_state_timeout_timer_callback(TimerHandle_t p_timer)
+{
+ if (app_global_data.rcu_status == RCU_STATUS_CONNECTED)
+ {
+ APP_PRINT_INFO0("[pair_fail_disconn_timer_callback] timeout");
+ rcu_terminate_connection(DISCONN_REASON_PAIR_FAILED);
+ }
+}
+
+/******************************************************************
+ * @brief update connection parameters timer callback
+ *
+ * update_conn_params_timer is used to update desired connection parameters after timeout
+ *
+ * @param p_timer - timer handler
+ * @return none
+ * @retval void
+ */
+void update_conn_params_timer_cb(TimerHandle_t p_timer)
+{
+ if (app_global_data.rcu_status == RCU_STATUS_PAIRED)
+ {
+#if SUPPORT_VOICE_FEATURE
+ if (voice_driver_global_data.is_voice_driver_working == true)
+ {
+ /* voice module is working, start timer to attempt later */
+ os_timer_restart(&update_conn_params_timer, UPDATE_CONN_PARAMS_TIMEOUT);
+ }
+ else
+#endif
+ {
+ rcu_update_conn_params(RCU_CONNECT_INTERVAL, RCU_CONNECT_LATENCY,
+ RCU_SUPERVISION_TIMEOUT);
+ app_set_latency_status(LATENCY_SYS_UPDATE_BIT, LANTENCY_ON); /* turn on latency */
+ }
+ }
+ else
+ {
+ APP_PRINT_WARN1("[update_conn_params_timer_cb] Invalid rcu status: %d", app_global_data.rcu_status);
+ }
+}
+
+#if FEATURE_SUPPORT_NO_ACTION_DISCONN
+/******************************************************************
+ * @brief no action disconnect timer callback
+ *
+ * no_act_disconn_timer_callback is used to terminate connection after timeout
+ *
+ * @param p_timer - timer handler
+ * @return none
+ * @retval void
+ */
+void no_act_disconn_timer_callback(TimerHandle_t p_timer)
+{
+ if (app_global_data.rcu_status == RCU_STATUS_PAIRED)
+ {
+ APP_PRINT_INFO0("[RCU] Idle No Action Timeout, Disconnect.");
+ rcu_terminate_connection(DISCONN_REASON_TIMEOUT);
+ }
+}
+#endif
+
+#if (AON_WDG_ENABLE == 1)
+void aon_watch_dog_wake_up_dlps_callback(TimerHandle_t pxTimer)
+{
+ APP_PRINT_INFO0("aon_watch_dog_wake_up_dlps_callback timeout!");
+}
+#endif
+
+/******************************************************************
+ * @brief system reset timer callback
+ *
+ * adv_timer_callback is used to stop advertising after timeout
+ *
+ * @param p_timer - timer handler
+ * @return none
+ * @retval void
+ */
+void system_reset_timer_callback(TimerHandle_t p_timer)
+{
+ WDG_SystemReset(RESET_ALL_EXCEPT_AON, RESET_REASON_FACTORY_RESET);
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief software timer init function
+ * @param none
+ * @return none
+ * @retval void
+ */
+void sw_timer_init(void)
+{
+ /* back_key_pressed_when_HW_reset_timer is used to control reset by back key */
+ if (false == os_timer_create(&back_key_pressed_when_HW_reset_timer,
+ "back_key_pressed_when_HW_reset_timer", 1, \
+ CHECK_BACK_KEY_PRESSED_WHEN_HW_RESET_TIMEOUT, false,
+ back_key_pressed_when_HW_reset_timer_cb))
+ {
+ APP_PRINT_INFO0("[sw_timer_init] init back_key_pressed_when_HW_reset_timer failed");
+ }
+
+ /* adv_timer is used to stop advertising after timeout */
+ if (false == os_timer_create(&adv_timer, "adv_timer", 1, \
+ ADV_UNDIRECT_PAIRING_TIMEOUT, false, adv_timer_callback))
+ {
+ APP_PRINT_INFO0("[sw_timer_init] init adv_timer failed");
+ }
+
+ /* adv_change_data_timer is used to change advertising data after timeout */
+ if (false == os_timer_create(&adv_change_data_timer, "adv_change_data_timer", 1, \
+ ADV_CHANGE_DATA_TIMEOUT, false, adv_change_data_timer_callback))
+ {
+ APP_PRINT_INFO0("[sw_timer_init] init adv_change_data_timer failed");
+ }
+
+ /* pair_fail_disconn_timer is used to disconnect for pair failed */
+ if (false == os_timer_create(&next_state_check_timer, "pair_fail_disconn_timer", 1, \
+ PAIR_FAIL_DISCONN_TIMEOUT, false, next_state_timeout_timer_callback))
+ {
+ APP_PRINT_INFO0("[sw_timer_init] init pairing_exception_timer failed");
+ }
+
+#if FEATURE_SUPPORT_NO_ACTION_DISCONN
+ /* no_act_disconn_timer is used to disconnect after timeout if there is on action under connection */
+ if (false == os_timer_create(&no_act_disconn_timer, "no_act_disconn_timer", 1, \
+ NO_ACTION_DISCON_TIMEOUT, false, no_act_disconn_timer_callback))
+ {
+ APP_PRINT_INFO0("[sw_timer_init] init no_act_disconn_timer failed");
+ }
+#endif
+
+#if (AON_WDG_ENABLE == 1)
+ if (false == os_timer_create(&aon_watch_dog_wake_up_dlps_timer, "aon_watch_dog_wake_up_dlps_timer",
+ 1, \
+ AON_WDG_TIMER_WAKEUP_DLPS_PERIOD, true, aon_watch_dog_wake_up_dlps_callback))
+ {
+ APP_PRINT_INFO0("[sw_timer_init] init aon_watch_dog_wake_up_dlps_callback failed");
+ }
+ else
+ {
+ os_timer_start(&aon_watch_dog_wake_up_dlps_timer);
+ APP_PRINT_INFO0("Start aon_watch_dog_wake_up_dlps_callback!");
+ }
+#endif
+
+ /* update_conn_params_timer is used to update desired connection parameters after timeout */
+ if (false == os_timer_create(&update_conn_params_timer, "update_conn_params_timer", 1
+ , UPDATE_CONN_PARAMS_TIMEOUT, false, update_conn_params_timer_cb))
+ {
+ APP_PRINT_INFO0("[sw_timer_init] init update_conn_params_timer failed");
+ }
+
+ if (false == os_timer_create(&system_rest_timer, "system_rest_timer", 1
+ , SYSTEM_RESET_TIMEOUT, false, system_reset_timer_callback))
+ {
+ APP_PRINT_INFO0("[sw_timer_init] init system_rest_timer failed");
+ }
+
+ if (false == os_timer_create(&temp_off_latency_timer, "temp_off_latency_timer", 1
+ , TEMP_OFF_LANTENCY_TIMEOUT, false, temp_off_latency_timer_cb))
+ {
+ APP_PRINT_INFO0("[sw_timer_init] init temp_off_latency_timer failed");
+ }
+
+ keyscan_init_timer();
+
+ key_handle_init_timer();
+
+#if SUPPORT_BUZZER_FEATURE
+ fms_handle_init_timer();
+#endif
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/swtimer.h b/src/app/google_rcu/swtimer.h
new file mode 100644
index 0000000..8e3f84f
--- /dev/null
+++ b/src/app/google_rcu/swtimer.h
@@ -0,0 +1,74 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file swtimer.h
+* @brief header file of software timer implementation
+* @details
+* @author KEN_MEI
+* @date 2017-02-08
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _SWTIMER__
+#define _SWTIMER__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <board.h>
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define ADV_RECONNECT_TIMEOUT 120000 /* 120s */
+#define ADV_UNDIRECT_POWER_TIMEOUT 6000 /* 6s */
+#define ADV_UNDIRECT_PAIRING_TIMEOUT 600000 /* 600s */
+#define ADV_UNDIRECT_REPAIRING_TIMEOUT 120000 /* 120s */
+#define ADV_CHANGE_DATA_TIMEOUT 3000 /* 3s */
+#define PAIRING_EXCEPTION_TIMEOUT 10000 /* 10s */
+#define NO_ACTION_DISCON_TIMEOUT 300000 /* 300s */
+#define UPDATE_CONN_PARAMS_TIMEOUT 12 * 1000 /* 12s */
+#define UPDATE_CONN_PARAMS_SHORT_TIMEOUT 5 * 1000 /* 5s */
+#define DFU_PROCESS_WAIT_TIMEOUT 5000 /* 5s */
+#define PAIR_FAIL_DISCONN_TIMEOUT 2000 /* 2s */
+#define SYSTEM_RESET_TIMEOUT 500 /* 500ms */
+#define TEMP_OFF_LANTENCY_TIMEOUT 500 /* 500ms */
+#define APP_RESOLVED_TIMEOUT 360 /* 360s */
+#define ADV_UPDATE_INTERVAL_TIMEOUT 30000 /* 30s */
+#define CHECK_BACK_KEY_PRESSED_WHEN_HW_RESET_TIMEOUT 50 /* 50ms*/
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef void *TimerHandle_t;
+
+/*============================================================================*
+* Export Global Variables
+*============================================================================*/
+extern TimerHandle_t adv_timer;
+extern TimerHandle_t adv_change_data_timer;
+#if FEATURE_SUPPORT_NO_ACTION_DISCONN
+extern TimerHandle_t no_act_disconn_timer;
+#endif
+extern TimerHandle_t update_conn_params_timer;
+extern TimerHandle_t next_state_check_timer;
+extern TimerHandle_t system_rest_timer;
+extern TimerHandle_t temp_off_latency_timer;
+extern TimerHandle_t back_key_pressed_when_HW_reset_timer;
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void sw_timer_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_SWTIMER__*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/test_module/data_uart_test.c b/src/app/google_rcu/test_module/data_uart_test.c
new file mode 100644
index 0000000..55f9a0f
--- /dev/null
+++ b/src/app/google_rcu/test_module/data_uart_test.c
@@ -0,0 +1,1347 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file data_uart_test.c
+* @brief This file provides data uart test.
+* @details
+* @author chenjie
+* @date 2020-03-03
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "board.h"
+#include <data_uart_test.h>
+#include <version.h>
+#include <patch_header_check.h>
+#include <gap.h>
+#include "rtl876x_rcc.h"
+#include "rtl876x_lib_platform.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_gpio.h"
+#include "mp_test.h"
+#include "rcu_application.h"
+#include "voice.h"
+#include "voice_driver.h"
+#include "rtl876x_uart.h"
+#include "rcu_gap.h"
+#include "gap_bond_le.h"
+#include "os_sched.h"
+#if MP_TEST_MODE_SUPPORT_AUTO_K_RF
+#include "auto_k_rf_bonding_dut.h"
+#include "auto_k_rf.h"
+#endif
+#if MP_TEST_MODE_SUPPORT_DATA_UART_DOWNLOAD
+#include "flash_adv_cfg.h"
+#endif
+#include "app_section.h"
+
+#if MP_TEST_MODE_SUPPORT_DATA_UART_TEST
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define TEST_DEVICE_TYPE 0x31 /* Sbee2 DUT device type */
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+static bool uart_test_is_dlps_allowed = true;
+
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+static void uart_test_get_cmd_func(T_UART_PACKET_DEF *p_data);
+static void uart_test_read_patch_version(void *p_data);
+static void uart_test_read_app_version(void *p_data);
+static void uart_test_read_mac_addr(void *p_data);
+static void uart_test_enter_fast_pair_mode(void *p_data);
+static void uart_test_get_dev_state(void *p_data);
+static void uart_test_voice_test_start(void *p_data);
+static void uart_test_voice_test_stop(void *p_data);
+static void uart_test_set_voice_config(void *p_data);
+static void uart_test_get_voice_config(void *p_data);
+static void uart_test_enter_dlps(void *p_data);
+static void uart_test_start_stop_adv(void *p_data);
+static void uart_test_enter_hci_mode(void *p_data);
+static void uart_test_disable_test_mode_flag(void *p_data);
+static void uart_test_enable_test_mode_flag(void *p_data);
+static void uart_test_erase_pair_info(void *p_data);
+static void uart_test_change_baudrate(void *p_data);
+static void uart_test_direct_k_rf_freq(void *p_data);
+static void uart_test_get_dut_info(void *p_data);
+static void uart_test_auto_k_rf_freq(void *p_data);
+static void uart_test_find_device_type(void *p_data);
+static void uart_test_reboot_device(void *p_data);
+static void uart_test_enter_single_tone(void *p_data);
+static void uart_test_terminate_connect(void *p_data);
+static void uart_test_enter_hci_download_mode(void *p_data);
+#if SUPPORT_CODEC_EQ_CONFIG_FEATURE
+static void uart_test_set_codec_eq_ch0_config(void *p_data);
+static void uart_test_get_codec_eq_ch0_config(void *p_data);
+#endif
+#if SUPPORT_DUAL_MIC_FEATURE
+#if SUPPORT_CODEC_EQ_CONFIG_FEATURE
+static void uart_test_set_codec_eq_ch1_config(void *p_data);
+static void uart_test_get_codec_eq_ch1_config(void *p_data);
+#endif
+#endif
+
+bool uart_test_check_dlps(void) DATA_RAM_FUNCTION;
+void uart_test_enter_dlps_config(void) DATA_RAM_FUNCTION;
+
+/*============================================================================*
+ * Global Variables
+ *============================================================================*/
+/**< Array of all used test function informations */
+const T_UART_TEST_PROTOCOL uart_test_func_map[UART_TEST_SUPPORT_NUM] =
+{
+ /* Opcode, Parameter Length, Function */
+ {READ_PATCH_VERSION_CMD, 0, uart_test_read_patch_version},
+ {READ_APP_VERSION_CMD, 0, uart_test_read_app_version},
+ {READ_MAC_ADDR_CMD, 0, uart_test_read_mac_addr},
+ {ENTER_FAST_PAIR_MODE_CMD, 1, uart_test_enter_fast_pair_mode},
+ {GET_DEVICE_STATE_CMD, 0, uart_test_get_dev_state},
+ {VOICE_TEST_START_CMD, 0, uart_test_voice_test_start},
+ {VOICE_TEST_STOP_CMD, 0, uart_test_voice_test_stop},
+ {SET_VOICE_CONFIG_CMD, 20, uart_test_set_voice_config},
+ {GET_VOICE_CONFIG_CMD, 0, uart_test_get_voice_config},
+ {ENTER_DLPS_TEST_MODE_CMD, 0, uart_test_enter_dlps},
+ {START_STOP_ADV_CMD, 1, uart_test_start_stop_adv},
+ {START_IR_TEST_MODE_CMD, 0, NULL},
+ {ENTER_HCI_TEST_MODE_CMD, 0, uart_test_enter_hci_mode},
+ {DISABLE_TEST_MODE_FLG_CMD, 0, uart_test_disable_test_mode_flag},
+ {ENABLE_TEST_MODE_FLG_CMD, 0, uart_test_enable_test_mode_flag},
+ {ERASE_PAIR_INFO_CMD, 0, uart_test_erase_pair_info},
+ {CHANGE_BAUDRATE_CMD, 1, uart_test_change_baudrate},
+ {DIRECT_K_RF_FREQ_CMD, 2, uart_test_direct_k_rf_freq},
+ {GET_GLODEN_INFO_CMD, 0, NULL},
+ {GET_DUT_INFO_CMD, 32, uart_test_get_dut_info},
+ {VERIFY_DUT_INFO_CMD, 0, NULL},
+ {AUTO_K_RF_FREQ_CMD, 18, uart_test_auto_k_rf_freq},
+ {FIND_DEVICE_TYPE_CMD, 0, uart_test_find_device_type},
+ {REBOOT_DEVICE_CMD, 0, uart_test_reboot_device},
+ {UPDATE_MAC_ADDR_CMD, 0, NULL},
+ {ENTER_SINGLE_TONE_MODE_CMD, 1, uart_test_enter_single_tone},
+ {READ_HARDWARE_VERSION_CMD, 0, NULL},
+ {TERMINATE_CONNECT_CMD, 0, uart_test_terminate_connect},
+ {MANUAL_K_RF_FREQ_CMD, 1, NULL},
+ {ENTER_HCI_DOWNLOAD_MODE_CMD, 0, uart_test_enter_hci_download_mode},
+#if SUPPORT_CODEC_EQ_CONFIG_FEATURE
+ {SET_CODEC_EQ_CH0_CONFIG_CMD, 22, uart_test_set_codec_eq_ch0_config},
+ {GET_CODEC_EQ_CH0_CONFIG_CMD, 1, uart_test_get_codec_eq_ch0_config},
+#else
+ {SET_CODEC_EQ_CH0_CONFIG_CMD, 22, NULL},
+ {GET_CODEC_EQ_CH0_CONFIG_CMD, 1, NULL},
+#endif
+#if SUPPORT_DUAL_MIC_FEATURE
+
+#if SUPPORT_CODEC_EQ_CONFIG_FEATURE
+ {SET_CODEC_EQ_CH1_CONFIG_CMD, 22, uart_test_set_codec_eq_ch1_config},
+ {GET_CODEC_EQ_CH1_CONFIG_CMD, 1, uart_test_get_codec_eq_ch1_config},
+#else
+ {SET_CODEC_EQ_CH1_CONFIG_CMD, 22, NULL},
+ {GET_CODEC_EQ_CH1_CONFIG_CMD, 1, NULL},
+#endif
+#else
+
+ {SET_CODEC_EQ_CH1_CONFIG_CMD, 22, NULL},
+ {GET_CODEC_EQ_CH1_CONFIG_CMD, 1, NULL},
+#endif
+ /* Add more command here,Please store in order according to opcode! */
+};
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief Read patch command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_read_patch_version(void *p_data)
+{
+ uint16_t patch_version = 0;
+ uint8_t patch_version_bytes[2] = {0};
+
+ T_IMG_HEADER_FORMAT *p_header;
+ uint32_t addr = get_header_addr_by_img_id(RomPatch);
+ p_header = (T_IMG_HEADER_FORMAT *)addr;
+
+ if (p_header)
+ {
+ patch_version = p_header->git_ver.ver_info.version;
+ }
+ else
+ {
+ patch_version = 0x00;
+ }
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_read_patch_version] patch version: %d", 1,
+ patch_version);
+
+ patch_version_bytes[0] = (uint8_t)(patch_version & 0x00FF);
+ patch_version_bytes[1] = (uint8_t)(patch_version >> 8);
+
+ /* Response data */
+ data_uart_cmd_response(READ_PATCH_VERSION_CMD, UART_TEST_SUCCESS, patch_version_bytes, 2);
+}
+
+/******************************************************************
+ * @brief Read App command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_read_app_version(void *p_data)
+{
+ uint8_t app_version_bytes[4] = {0};
+ app_version_bytes[0] = (uint8_t)(VERSION_MAJOR);
+ app_version_bytes[1] = (uint8_t)(VERSION_MINOR);
+ app_version_bytes[2] = (uint8_t)(VERSION_REVISION);
+ app_version_bytes[3] = (uint8_t)(VERSION_BUILDNUM);
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_read_app_version] app version: %d.%d.%d.%d", 4,
+ app_version_bytes[0], app_version_bytes[1], app_version_bytes[2], app_version_bytes[3]);
+
+ /* Response data */
+ data_uart_cmd_response(READ_APP_VERSION_CMD, UART_TEST_SUCCESS, app_version_bytes, 4);
+}
+
+/******************************************************************
+ * @brief Read Mac address command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_read_mac_addr(void *p_data)
+{
+ uint8_t mac_addr[6];
+ gap_get_param(GAP_PARAM_BD_ADDR, mac_addr);
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO,
+ "[uart_test_read_mac_addr] MAC Addr: %02X %02X %02X %02X %02X %02X",
+ 6, mac_addr[5], mac_addr[4], mac_addr[3], mac_addr[2], mac_addr[1], mac_addr[0]);
+
+ /* Response data */
+ data_uart_cmd_response(READ_MAC_ADDR_CMD, UART_TEST_SUCCESS, mac_addr, 6);
+}
+
+/******************************************************************
+ * @brief Enter fast pair mode command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_enter_fast_pair_mode(void *p_data)
+{
+ uint8_t mode_index = *((uint8_t *)p_data + 3);
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_enter_fast_pair_mode] mode index is %d", 1,
+ mode_index);
+
+ if (mode_index < FP_MAX_LINE_NUM)
+ {
+ if (mp_test_set_fast_pair_info(mode_index))
+ {
+ DBG_DIRECT("[uart_test_enter_fast_pair_mode] Switch to Fast Pair %d test mode!", (mode_index + 1));
+
+ data_uart_cmd_response(ENTER_FAST_PAIR_MODE_CMD, UART_TEST_SUCCESS, NULL, 0);
+
+ switch_to_test_mode(AUTO_PAIR_WITH_FIX_ADDR_MODE);
+ }
+ }
+
+ data_uart_cmd_response(ENTER_FAST_PAIR_MODE_CMD, UART_TEST_ERROR, NULL, 0);
+}
+
+/******************************************************************
+ * @brief Enter fast pair mode command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_get_dev_state(void *p_data)
+{
+ uint8_t dev_state[1];
+
+ dev_state[0] = app_global_data.rcu_status;
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_get_dev_state] dev_state is %d", 1,
+ dev_state[0]);
+
+ data_uart_cmd_response(GET_DEVICE_STATE_CMD, UART_TEST_SUCCESS, dev_state, 1);
+}
+
+/******************************************************************
+ * @brief Voice test start command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_voice_test_start(void *p_data)
+{
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_voice_test_start] start voice test", 0);
+
+#if SUPPORT_VOICE_FEATURE
+ data_uart_cmd_response(VOICE_TEST_START_CMD, UART_TEST_SUCCESS, NULL, 0);
+ os_delay(50);
+ voice_handle_start_mic();
+#endif
+}
+
+/******************************************************************
+ * @brief Voice test stop command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_voice_test_stop(void *p_data)
+{
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_voice_test_stop] start voice stop", 0);
+
+#if SUPPORT_VOICE_FEATURE
+ voice_handle_stop_mic();
+ os_delay(50);
+ data_uart_cmd_response(VOICE_TEST_STOP_CMD, UART_TEST_SUCCESS, NULL, 0);
+#endif
+}
+
+/******************************************************************
+ * @brief Voice test set voice mic config command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_set_voice_config(void *p_data)
+{
+
+ bool result = true;
+#if SUPPORT_VOICE_FEATURE
+ uint8_t codec_sample_rate = *((uint8_t *)p_data + 3);
+ uint8_t dmic_clock = *((uint8_t *)p_data + 4);
+ uint8_t codec_i2s_format = *((uint8_t *)p_data + 5);
+ uint8_t codec_i2s_data_width = *((uint8_t *)p_data + 6);
+ uint8_t codec_i2s_ch_sequence = *((uint8_t *)p_data + 7);
+ uint8_t mic_bias_voltage = *((uint8_t *)p_data + 8);
+ uint8_t amic_bst_gain = *((uint8_t *)p_data + 9);
+ uint8_t amic_bst_mode = *((uint8_t *)p_data + 10);
+ uint8_t codec_ch0_mute = *((uint8_t *)p_data + 11);
+ uint8_t codec_ch0_mic_type = *((uint8_t *)p_data + 12);
+ uint8_t codec_ch0_dmic_data_latch = *((uint8_t *)p_data + 13);
+ uint8_t codec_ch0_ad_gain = *((uint8_t *)p_data + 14);
+ uint8_t codec_ch0_boost_gain = *((uint8_t *)p_data + 15);
+ uint8_t codec_ch0_zero_det_timeout = *((uint8_t *)p_data + 16);
+ uint8_t codec_ch1_mute = *((uint8_t *)p_data + 17);
+ uint8_t codec_ch1_mic_type = *((uint8_t *)p_data + 18);
+ uint8_t codec_ch1_dmic_data_latch = *((uint8_t *)p_data + 19);
+ uint8_t codec_ch1_ad_gain = *((uint8_t *)p_data + 20);
+ uint8_t codec_ch1_boost_gain = *((uint8_t *)p_data + 21);
+ uint8_t codec_ch1_zero_det_timeout = *((uint8_t *)p_data + 22);
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO,
+ "[uart_test_set_voice0_config] voice config %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
+ 20,
+ codec_sample_rate, dmic_clock, codec_i2s_format, codec_i2s_data_width,
+ codec_i2s_ch_sequence, mic_bias_voltage, amic_bst_gain, amic_bst_mode,
+ codec_ch0_mute, codec_ch0_mic_type, codec_ch0_dmic_data_latch, codec_ch0_ad_gain,
+ codec_ch0_boost_gain, codec_ch0_zero_det_timeout, codec_ch1_mute, codec_ch1_mic_type,
+ codec_ch1_dmic_data_latch, codec_ch1_ad_gain, codec_ch1_boost_gain, codec_ch1_zero_det_timeout);
+ /* check paramster is valid or not */
+ if ((codec_sample_rate > UART_TEST_CODEC_SAMPLE_RATE_ENUM_GUARD)
+ || (dmic_clock > T_UART_TEST_CODEC_DMICCLOCK_ENUM_GUARD)
+ || (mic_bias_voltage > UART_TEST_CODEC_MIC_BIAS_VOL_ENUM_GUARD)
+ || (amic_bst_gain > UART_TEST_CODEC_MICBST_GAIN_ENUM_GUARD)
+ || (codec_ch0_boost_gain > T_UART_TEST_CODEC_CH0_BOOSTGAIN_ENUM_GUARD)
+ || (codec_ch1_boost_gain > T_UART_TEST_CODEC_CH1_BOOSTGAIN_ENUM_GUARD)
+ )
+ {
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_set_voice0_config] parameter invalid!", 0);
+ result = false;
+ }
+ else
+ {
+ switch (codec_sample_rate)
+ {
+ case UART_TEST_CODEC_SAMPLE_RATE_8K:
+ voice_driver_codec_params.codec_sample_rate = SAMPLE_RATE_8KHz;
+ break;
+ case UART_TEST_CODEC_SAMPLE_RATE_16K:
+ voice_driver_codec_params.codec_sample_rate = SAMPLE_RATE_16KHz;
+ break;
+ case UART_TEST_CODEC_SAMPLE_RATE_32K:
+ voice_driver_codec_params.codec_sample_rate = SAMPLE_RATE_32KHz;
+ break;
+ case UART_TEST_CODEC_SAMPLE_RATE_44100:
+ voice_driver_codec_params.codec_sample_rate = SAMPLE_RATE_44100Hz;
+ break;
+ case UART_TEST_CODEC_SAMPLE_RATE_48K:
+ voice_driver_codec_params.codec_sample_rate = SAMPLE_RATE_48KHz;
+ break;
+ }
+ voice_driver_codec_params.dmic_clock = ((uint32_t)(dmic_clock << CODEC_DMIC1_CLK_SEL_POS));
+ voice_driver_codec_params.mic_bias_voltage = ((uint32_t)(mic_bias_voltage <<
+ CODEC_MICBIAS_VSET_POS));
+ voice_driver_codec_params.amic_bst_gain = ((uint32_t)(amic_bst_gain << CODEC_MICBST_GAIN_POS));
+ voice_driver_codec_params.codec_ch0_ad_gain = codec_ch0_ad_gain;
+ voice_driver_codec_params.codec_ch0_boost_gain = ((uint32_t)(codec_ch0_boost_gain <<
+ CODEC_ADC_CH0_BOOST_GAIN_POS));
+#if SUPPORT_DUAL_MIC_FEATURE
+ voice_driver_codec_params.codec_ch1_ad_gain = codec_ch1_ad_gain;
+ voice_driver_codec_params.codec_ch1_boost_gain = ((uint32_t)(codec_ch1_boost_gain <<
+ CODEC_ADC_CH1_BOOST_GAIN_POS));
+#endif
+ }
+#else
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO,
+ "[uart_test_set_voice0_config] voice module disabled", 0);
+
+#endif
+ if (result == true)
+ {
+ data_uart_cmd_response(SET_VOICE_CONFIG_CMD, UART_TEST_SUCCESS, NULL, 0);
+ }
+ else
+ {
+ data_uart_cmd_response(SET_VOICE_CONFIG_CMD, UART_TEST_ERROR, NULL, 0);
+ }
+}
+
+/******************************************************************
+ * @brief Voice test get voice mic0 config command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_get_voice_config(void *p_data)
+{
+ uint8_t voice_params[20] = {0};
+#if SUPPORT_VOICE_FEATURE
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO,
+ "[uart_test_get_voice0_config] codec config %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
+ 20,
+ voice_driver_codec_params.codec_sample_rate,
+ voice_driver_codec_params.dmic_clock,
+ voice_driver_codec_params.codec_i2s_format,
+ voice_driver_codec_params.codec_i2s_data_width,
+ voice_driver_codec_params.codec_i2s_ch_sequence,
+ voice_driver_codec_params.mic_bias_voltage,
+ voice_driver_codec_params.amic_bst_gain,
+ voice_driver_codec_params.amic_bst_mode,
+ voice_driver_codec_params.codec_ch0_mute,
+ voice_driver_codec_params.codec_ch0_mic_type,
+ voice_driver_codec_params.codec_ch0_dmic_data_latch,
+ voice_driver_codec_params.codec_ch0_ad_gain,
+ voice_driver_codec_params.codec_ch0_boost_gain,
+ voice_driver_codec_params.codec_ch0_zero_det_timeout,
+ voice_driver_codec_params.codec_ch1_mute,
+ voice_driver_codec_params.codec_ch1_mic_type,
+ voice_driver_codec_params.codec_ch1_dmic_data_latch,
+ voice_driver_codec_params.codec_ch1_ad_gain,
+ voice_driver_codec_params.codec_ch1_boost_gain,
+ voice_driver_codec_params.codec_ch1_zero_det_timeout
+ );
+
+ switch (voice_driver_codec_params.codec_sample_rate)
+ {
+ case SAMPLE_RATE_8KHz:
+ voice_params[0] = (uint8_t)(UART_TEST_CODEC_SAMPLE_RATE_8K);
+ break;
+ case SAMPLE_RATE_16KHz:
+ voice_params[0] = (uint8_t)(UART_TEST_CODEC_SAMPLE_RATE_16K);
+ break;
+ case SAMPLE_RATE_32KHz:
+ voice_params[0] = (uint8_t)(UART_TEST_CODEC_SAMPLE_RATE_32K);
+ break;
+ case SAMPLE_RATE_44100Hz:
+ voice_params[0] = (uint8_t)(UART_TEST_CODEC_SAMPLE_RATE_44100);
+ break;
+ case SAMPLE_RATE_48KHz:
+ voice_params[0] = (uint8_t)(UART_TEST_CODEC_SAMPLE_RATE_48K);
+ break;
+ }
+
+ voice_params[1] = (uint8_t)(voice_driver_codec_params.dmic_clock >> CODEC_DMIC1_CLK_SEL_POS);
+ voice_params[2] = (uint8_t)(0);
+ voice_params[3] = (uint8_t)(0);
+ voice_params[4] = (uint8_t)(0);
+ voice_params[5] = (uint8_t)(voice_driver_codec_params.mic_bias_voltage >> CODEC_MICBIAS_VSET_POS);
+ voice_params[6] = (uint8_t)(voice_driver_codec_params.amic_bst_gain >> CODEC_MICBST_GAIN_POS);
+ voice_params[7] = (uint8_t)(0);
+ voice_params[8] = (uint8_t)(0);
+ voice_params[9] = (uint8_t)(0);
+ voice_params[10] = (uint8_t)(0);
+ voice_params[11] = (uint8_t)(voice_driver_codec_params.codec_ch0_ad_gain);
+ voice_params[12] = (uint8_t)(voice_driver_codec_params.codec_ch0_boost_gain >>
+ CODEC_ADC_CH0_BOOST_GAIN_POS);
+ voice_params[13] = (uint8_t)(0);
+
+#if SUPPORT_DUAL_MIC_FEATURE
+ voice_params[14] = (uint8_t)(0);
+ voice_params[15] = (uint8_t)(0);
+ voice_params[16] = (uint8_t)(0);
+ voice_params[17] = (uint8_t)(voice_driver_codec_params.codec_ch1_ad_gain);
+ voice_params[18] = (uint8_t)(voice_driver_codec_params.codec_ch1_boost_gain >>
+ CODEC_ADC_CH1_BOOST_GAIN_POS);
+ voice_params[19] = (uint8_t)(0);
+#endif
+
+#else
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_get_voice0_config] voice module disabled", 0);
+#endif
+
+ data_uart_cmd_response(GET_VOICE_CONFIG_CMD, UART_TEST_SUCCESS, voice_params, 20);
+
+}
+
+
+
+/******************************************************************
+ * @brief Enter DLPS command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_enter_dlps(void *p_data)
+{
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_enter_dlps] enter DLPS", 0);
+
+ data_uart_cmd_response(ENTER_DLPS_TEST_MODE_CMD, UART_TEST_SUCCESS, NULL, 0);
+
+ uart_test_is_dlps_allowed = true;
+}
+
+/******************************************************************
+ * @brief Start and stop advertisemnet command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_start_stop_adv(void *p_data)
+{
+ bool result = false;
+ uint8_t cmd_type = *((uint8_t *)p_data + 3);
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_start_stop_adv] cmd_type is %d", 1, cmd_type);
+
+ switch (cmd_type)
+ {
+ case ADV_IDLE:
+ {
+ result = rcu_stop_adv(STOP_ADV_REASON_UART_CMD);
+ }
+ break;
+ case ADV_UNDIRECT_PAIRING:
+ {
+ result = rcu_start_adv(ADV_UNDIRECT_PAIRING);
+ }
+ break;
+ case ADV_DIRECT_HDC:
+ case ADV_UNDIRECT_WAKEUP:
+ {
+ if (app_global_data.is_link_key_existed == true)
+ {
+ result = rcu_start_adv((T_ADV_TYPE)cmd_type);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (result == true)
+ {
+ data_uart_cmd_response(START_STOP_ADV_CMD, UART_TEST_SUCCESS, NULL, 0);
+ }
+ else
+ {
+ data_uart_cmd_response(START_STOP_ADV_CMD, UART_TEST_ERROR, NULL, 0);
+ }
+}
+
+/******************************************************************
+ * @brief Enter HCI uart test mode command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_enter_hci_mode(void *p_data)
+{
+ DBG_DIRECT("[uart_test_enter_hci_mode] Switch to HCI UART test mode!");
+
+ data_uart_cmd_response(ENTER_HCI_TEST_MODE_CMD, UART_TEST_SUCCESS, NULL, 0);
+
+ switch_to_hci_mode();
+}
+
+/******************************************************************
+ * @brief Disable test mode flag command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_disable_test_mode_flag(void *p_data)
+{
+ bool result = false;
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_disable_test_mode_flag] disable test mode flag",
+ 0);
+
+ result = mp_test_disable_test_mode_flag();
+
+ if (result == true)
+ {
+ data_uart_cmd_response(DISABLE_TEST_MODE_FLG_CMD, UART_TEST_SUCCESS, NULL, 0);
+ }
+ else
+ {
+ data_uart_cmd_response(DISABLE_TEST_MODE_FLG_CMD, UART_TEST_ERROR, NULL, 0);
+ }
+}
+
+/******************************************************************
+ * @brief Enable test mode flag command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_enable_test_mode_flag(void *p_data)
+{
+ bool result = false;
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_enable_test_mode_flag] enable test mode flag",
+ 0);
+
+ result = mp_test_enable_test_mode_flag();
+
+ if (result == true)
+ {
+ data_uart_cmd_response(ENABLE_TEST_MODE_FLG_CMD, UART_TEST_SUCCESS, NULL, 0);
+ }
+ else
+ {
+ data_uart_cmd_response(ENABLE_TEST_MODE_FLG_CMD, UART_TEST_ERROR, NULL, 0);
+ }
+}
+
+/******************************************************************
+ * @brief Erase pair info command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_erase_pair_info(void *p_data)
+{
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_erase_pair_info] erase pair info", 0);
+
+ app_global_data.is_link_key_existed = false;
+ le_bond_clear_all_keys();
+
+ if (le_get_bond_dev_num() == 0)
+ {
+ data_uart_cmd_response(ERASE_PAIR_INFO_CMD, UART_TEST_SUCCESS, NULL, 0);
+ }
+ else
+ {
+ data_uart_cmd_response(ERASE_PAIR_INFO_CMD, UART_TEST_ERROR, NULL, 0);
+ }
+}
+
+/******************************************************************
+ * @brief Change baudrate command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_change_baudrate(void *p_data)
+{
+ bool result = false;
+ uint8_t baudrate_index = *((uint8_t *)p_data + 3);
+
+ if ((baudrate_index == CHANGE_BAUDRATE_OPTION_115200) ||
+ (baudrate_index == CHANGE_BAUDRATE_OPTION_1M) ||
+ (baudrate_index == CHANGE_BAUDRATE_OPTION_2M))
+ {
+ result = true;
+ }
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO,
+ "[uart_test_change_baudrate] baudrate_index is %d, result is %d", 2, baudrate_index, result);
+
+ if (result == true)
+ {
+ data_uart_cmd_response(CHANGE_BAUDRATE_CMD, UART_TEST_SUCCESS, NULL, 0);
+ data_uart_init(baudrate_index);
+ }
+ else
+ {
+ data_uart_cmd_response(CHANGE_BAUDRATE_CMD, UART_TEST_ERROR, NULL, 0);
+ }
+}
+
+/******************************************************************
+ * @brief Terminate connection command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_terminate_connect(void *p_data)
+{
+ bool result = false;
+
+ result = rcu_terminate_connection(DISCONN_REASON_UART_CMD);
+
+ if (result == true)
+ {
+ data_uart_cmd_response(TERMINATE_CONNECT_CMD, UART_TEST_SUCCESS, NULL, 0);
+ }
+ else
+ {
+ data_uart_cmd_response(TERMINATE_CONNECT_CMD, UART_TEST_ERROR, NULL, 0);
+ }
+}
+
+/******************************************************************
+ * @brief Enter HCI uart test mode command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_enter_hci_download_mode(void *p_data)
+{
+#if MP_TEST_MODE_SUPPORT_DATA_UART_DOWNLOAD
+ DBG_DIRECT("[uart_test_enter_hci_download_mode] Switch to HCI UART download mode!");
+
+ flash_set_block_protect_locked(0);
+ flash_erase_locked(FLASH_ERASE_SECTOR, get_header_addr_by_img_id(OTA));
+
+ data_uart_cmd_response(ENTER_HCI_DOWNLOAD_MODE_CMD, UART_TEST_SUCCESS, NULL, 0);
+
+ WDG_SystemReset(RESET_ALL, UART_CMD_RESET);
+#else
+ data_uart_cmd_response(ENTER_HCI_DOWNLOAD_MODE_CMD, UART_TEST_ERROR, NULL, 0);
+#endif
+}
+
+#if SUPPORT_CODEC_EQ_CONFIG_FEATURE
+/******************************************************************
+ * @brief Set codec eq ch0 config command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_set_codec_eq_ch0_config(void *p_data)
+{
+ bool result = false;
+ uint8_t eq_channel_index = *((uint8_t *)p_data + 3) - 1;
+ uint8_t eq_status = *((uint8_t *)p_data + 4);
+ uint32_t eq_coef_H0 = (uint32_t)(*((uint8_t *)p_data + 5))
+ + ((uint32_t)(*((uint8_t *)p_data + 6) << 8))
+ + ((uint32_t)(*((uint8_t *)p_data + 7) << 16))
+ + ((uint32_t)(*((uint8_t *)p_data + 8) << 24));
+ uint32_t eq_coef_B1 = (uint32_t)(*((uint8_t *)p_data + 9))
+ + ((uint32_t)(*((uint8_t *)p_data + 10) << 8))
+ + ((uint32_t)(*((uint8_t *)p_data + 11) << 16))
+ + ((uint32_t)(*((uint8_t *)p_data + 12) << 24));
+ uint32_t eq_coef_B2 = (uint32_t)(*((uint8_t *)p_data + 13))
+ + ((uint32_t)(*((uint8_t *)p_data + 14) << 8))
+ + ((uint32_t)(*((uint8_t *)p_data + 15) << 16))
+ + ((uint32_t)(*((uint8_t *)p_data + 16) << 24));
+ uint32_t eq_coef_A1 = (uint32_t)(*((uint8_t *)p_data + 17))
+ + ((uint32_t)(*((uint8_t *)p_data + 18) << 8))
+ + ((uint32_t)(*((uint8_t *)p_data + 19) << 16))
+ + ((uint32_t)(*((uint8_t *)p_data + 20) << 24));
+ uint32_t eq_coef_A2 = (uint32_t)(*((uint8_t *)p_data + 21))
+ + ((uint32_t)(*((uint8_t *)p_data + 22) << 8))
+ + ((uint32_t)(*((uint8_t *)p_data + 23) << 16))
+ + ((uint32_t)(*((uint8_t *)p_data + 24) << 24));
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_set_codec_eq_ch0_config] %d %d %d %d %d %d %d",
+ 7,
+ eq_channel_index, eq_status, eq_coef_H0, eq_coef_B1, eq_coef_B1, eq_coef_A1, eq_coef_A2);
+
+ /* check parmester validation */
+ if ((eq_channel_index >= CODEC_EQ_MAX_NUM)
+ || (eq_status >= UART_TEST_CODEC_EQ_STATUS_ENUM_GUARD))
+ {
+ result = false;
+ }
+ else
+ {
+ if (eq_status == UART_TEST_CODEC_EQ_STATUS_DISABLE)
+ {
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQChCmd = EQ_CH_DISABLE;
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefH0 = 0;
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefB1 = 0;
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefB2 = 0;
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefA1 = 0;
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefA2 = 0;
+ }
+ else if (eq_status == UART_TEST_CODEC_EQ_STATUS_ENABLE)
+ {
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQChCmd = EQ_CH_ENABLE;
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefH0 = eq_coef_H0;
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefB1 = eq_coef_B1;
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefB2 = eq_coef_B2;
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefA1 = eq_coef_A1;
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefA2 = eq_coef_A2;
+ }
+ result = true;
+ }
+
+ if (result == true)
+ {
+ data_uart_cmd_response(SET_CODEC_EQ_CH0_CONFIG_CMD, UART_TEST_SUCCESS, NULL, 0);
+ }
+ else
+ {
+ data_uart_cmd_response(SET_CODEC_EQ_CH0_CONFIG_CMD, UART_TEST_ERROR, NULL, 0);
+ }
+}
+
+/******************************************************************
+ * @brief Get codec eq ch0 config command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_get_codec_eq_ch0_config(void *p_data)
+{
+ uint8_t eq_channel_index = *((uint8_t *)p_data + 3) - 1;
+ uint8_t eq_config_buff[21] = {0};
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_get_codec_eq_ch0_config] %d %d %d %d %d %d %d",
+ 7,
+ eq_channel_index,
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQChCmd,
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefH0,
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefB1,
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefB2,
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefA1,
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefA2
+ );
+
+ if (voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQChCmd == EQ_CH_DISABLE)
+ {
+ eq_config_buff[0] = 0;
+ }
+ else if (voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQChCmd ==
+ EQ_CH_ENABLE)
+ {
+ eq_config_buff[0] = 1;
+ }
+
+ eq_config_buff[1] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefH0);
+ eq_config_buff[2] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefH0 >> 8);
+ eq_config_buff[3] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefH0 >> 16);
+ eq_config_buff[4] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefH0 >> 24);
+
+ eq_config_buff[5] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefB1);
+ eq_config_buff[6] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefB1 >> 8);
+ eq_config_buff[7] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefB1 >> 16);
+ eq_config_buff[8] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefB1 >> 24);
+
+ eq_config_buff[9] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefB2);
+ eq_config_buff[10] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefB2 >> 8);
+ eq_config_buff[11] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefB2 >> 16);
+ eq_config_buff[12] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefB2 >> 24);
+
+ eq_config_buff[13] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefA1);
+ eq_config_buff[14] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefA1 >> 8);
+ eq_config_buff[15] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefA1 >> 16);
+ eq_config_buff[16] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefA1 >> 24);
+
+ eq_config_buff[17] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefA2);
+ eq_config_buff[18] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefA2 >> 8);
+ eq_config_buff[19] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefA2 >> 16);
+ eq_config_buff[20] = (uint8_t)(
+ voice_driver_codec_params.codec_ch0_eq_params[eq_channel_index].CODEC_EQCoefA2 >> 24);
+
+ data_uart_cmd_response(GET_CODEC_EQ_CH0_CONFIG_CMD, UART_TEST_SUCCESS, eq_config_buff, 21);
+}
+
+#if SUPPORT_DUAL_MIC_FEATURE
+/******************************************************************
+ * @brief Set codec eq ch1 config command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_set_codec_eq_ch1_config(void *p_data)
+{
+ bool result = false;
+ uint8_t eq_channel_index = *((uint8_t *)p_data + 3) - 1;
+ uint8_t eq_status = *((uint8_t *)p_data + 4);
+ uint32_t eq_coef_H0 = (uint32_t)(*((uint8_t *)p_data + 5))
+ + ((uint32_t)(*((uint8_t *)p_data + 6) << 8))
+ + ((uint32_t)(*((uint8_t *)p_data + 7) << 16))
+ + ((uint32_t)(*((uint8_t *)p_data + 8) << 24));
+ uint32_t eq_coef_B1 = (uint32_t)(*((uint8_t *)p_data + 9))
+ + ((uint32_t)(*((uint8_t *)p_data + 10) << 8))
+ + ((uint32_t)(*((uint8_t *)p_data + 11) << 16))
+ + ((uint32_t)(*((uint8_t *)p_data + 12) << 24));
+ uint32_t eq_coef_B2 = (uint32_t)(*((uint8_t *)p_data + 13))
+ + ((uint32_t)(*((uint8_t *)p_data + 14) << 8))
+ + ((uint32_t)(*((uint8_t *)p_data + 15) << 16))
+ + ((uint32_t)(*((uint8_t *)p_data + 16) << 24));
+ uint32_t eq_coef_A1 = (uint32_t)(*((uint8_t *)p_data + 17))
+ + ((uint32_t)(*((uint8_t *)p_data + 18) << 8))
+ + ((uint32_t)(*((uint8_t *)p_data + 19) << 16))
+ + ((uint32_t)(*((uint8_t *)p_data + 20) << 24));
+ uint32_t eq_coef_A2 = (uint32_t)(*((uint8_t *)p_data + 21))
+ + ((uint32_t)(*((uint8_t *)p_data + 22) << 8))
+ + ((uint32_t)(*((uint8_t *)p_data + 23) << 16))
+ + ((uint32_t)(*((uint8_t *)p_data + 24) << 24));
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_set_codec_eq1_config] %d %d %d %d %d %d %d", 7,
+ eq_channel_index, eq_status, eq_coef_H0, eq_coef_B1, eq_coef_B1, eq_coef_A1, eq_coef_A2);
+
+ /* check parmester validation */
+ if ((eq_channel_index >= CODEC_EQ_MAX_NUM)
+ || (eq_status >= UART_TEST_CODEC_EQ_STATUS_ENUM_GUARD))
+ {
+ result = false;
+ }
+ else
+ {
+ if (eq_status == UART_TEST_CODEC_EQ_STATUS_DISABLE)
+ {
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQChCmd = EQ_CH_DISABLE;
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefH0 = 0;
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefB1 = 0;
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefB2 = 0;
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefA1 = 0;
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefA2 = 0;
+ }
+ else if (eq_status == UART_TEST_CODEC_EQ_STATUS_ENABLE)
+ {
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQChCmd = EQ_CH_ENABLE;
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefH0 = eq_coef_H0;
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefB1 = eq_coef_B1;
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefB2 = eq_coef_B2;
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefA1 = eq_coef_A1;
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefA2 = eq_coef_A2;
+ }
+ result = true;
+ }
+
+ if (result == true)
+ {
+ data_uart_cmd_response(SET_CODEC_EQ_CH1_CONFIG_CMD, UART_TEST_SUCCESS, NULL, 0);
+ }
+ else
+ {
+ data_uart_cmd_response(SET_CODEC_EQ_CH1_CONFIG_CMD, UART_TEST_ERROR, NULL, 0);
+ }
+}
+
+/******************************************************************
+ * @brief Get codec eq ch1 config command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_get_codec_eq_ch1_config(void *p_data)
+{
+ uint8_t eq_channel_index = *((uint8_t *)p_data + 3) - 1;
+ uint8_t eq_config_buff[21] = {0};
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_get_codec_eq1_config] %d %d %d %d %d %d %d", 7,
+ eq_channel_index,
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQChCmd,
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefH0,
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefB1,
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefB2,
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefA1,
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefA2
+ );
+
+ if (voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQChCmd == EQ_CH_DISABLE)
+ {
+ eq_config_buff[0] = 0;
+ }
+ else if (voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQChCmd ==
+ EQ_CH_ENABLE)
+ {
+ eq_config_buff[0] = 1;
+ }
+
+ eq_config_buff[1] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefH0);
+ eq_config_buff[2] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefH0 >> 8);
+ eq_config_buff[3] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefH0 >> 16);
+ eq_config_buff[4] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefH0 >> 24);
+
+ eq_config_buff[5] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefB1);
+ eq_config_buff[6] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefB1 >> 8);
+ eq_config_buff[7] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefB1 >> 16);
+ eq_config_buff[8] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefB1 >> 24);
+
+ eq_config_buff[9] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefB2);
+ eq_config_buff[10] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefB2 >> 8);
+ eq_config_buff[11] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefB2 >> 16);
+ eq_config_buff[12] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefB2 >> 24);
+
+ eq_config_buff[13] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefA1);
+ eq_config_buff[14] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefA1 >> 8);
+ eq_config_buff[15] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefA1 >> 16);
+ eq_config_buff[16] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefA1 >> 24);
+
+ eq_config_buff[17] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefA2);
+ eq_config_buff[18] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefA2 >> 8);
+ eq_config_buff[19] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefA2 >> 16);
+ eq_config_buff[20] = (uint8_t)(
+ voice_driver_codec_params.codec_ch1_eq_params[eq_channel_index].CODEC_EQCoefA2 >> 24);
+
+ data_uart_cmd_response(GET_CODEC_EQ_CH1_CONFIG_CMD, UART_TEST_SUCCESS, eq_config_buff, 21);
+}
+#endif
+#endif
+
+/******************************************************************
+ * @brief Reboot device command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_reboot_device(void *p_data)
+{
+ DBG_DIRECT("[uart_test_reboot_device] reboot device!");
+
+ data_uart_cmd_response(REBOOT_DEVICE_CMD, UART_TEST_SUCCESS, NULL, 0);
+
+ WDG_SystemReset(RESET_ALL, UART_CMD_RESET);
+}
+
+/******************************************************************
+ * @brief Enter Single Tone test command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_enter_single_tone(void *p_data)
+{
+ DBG_DIRECT("[uart_test_enter_single_tone] Switch to Single Tone test mode!");
+
+ data_uart_cmd_response(ENTER_SINGLE_TONE_MODE_CMD, UART_TEST_SUCCESS, NULL, 0);
+
+ switch_to_test_mode(SINGLE_TONE_MODE);
+}
+
+/******************************************************************
+ * @brief Direct K RF frequency command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_direct_k_rf_freq(void *p_data)
+{
+#if MP_TEST_MODE_SUPPORT_AUTO_K_RF
+ uint8_t cal_xtal_result;
+ uint8_t rx_channel = *((uint8_t *)p_data + 3);
+ uint8_t drift_threshold = *((uint8_t *)p_data + 4);
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO,
+ "[uart_test_direct_k_rf_freq] rx_channel is %d, drift_threshold is %d",
+ 2, rx_channel, drift_threshold);
+
+ if (Auto_K_RF(rx_channel, drift_threshold, &cal_xtal_result))
+ {
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_direct_k_rf_freq] Cal RF freqency failed", 0);
+ data_uart_cmd_response(AUTO_K_RF_FREQ_CMD, UART_TEST_ERROR, NULL, 0);
+ }
+ else
+ {
+ bool write_xtal_ret;
+
+#ifdef WRITE_XTAL_TO_EFUSE
+ write_xtal_ret = WriteXtalToEfuse(cal_xtal_result);
+#else
+ write_xtal_ret = WriteXtalToConfig(cal_xtal_result);
+#endif
+ if (write_xtal_ret == true)
+ {
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_direct_k_rf_freq] Cal RF freqency succeeded",
+ 0);
+ data_uart_cmd_response(DIRECT_K_RF_FREQ_CMD, UART_TEST_SUCCESS, &cal_xtal_result, 1);
+ }
+ else
+ {
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_direct_k_rf_freq] Cal RF freqency failed", 0);
+ data_uart_cmd_response(DIRECT_K_RF_FREQ_CMD, UART_TEST_ERROR, NULL, 0);
+ }
+ }
+#endif
+}
+
+/******************************************************************
+ * @brief uart_test_get_dut_info
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_get_dut_info(void *p_data)
+{
+#if MP_TEST_MODE_SUPPORT_AUTO_K_RF
+ bool result = false;
+ uint8_t golden_info[32];
+ uint8_t dut_info[32];
+
+ memset(dut_info, 0, 32);
+ memcpy(golden_info, (uint8_t *)p_data + 3, 32);
+ result = dut_info_get(golden_info, dut_info);
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO,
+ "[uart_test_get_dut_info] result is %d", 1, result);
+
+ if (result == true)
+ {
+ data_uart_cmd_response(GET_DUT_INFO_CMD, UART_TEST_SUCCESS, dut_info, 32);
+ }
+ else
+ {
+ data_uart_cmd_response(GET_DUT_INFO_CMD, UART_TEST_ERROR, NULL, 0);
+ }
+#else
+ data_uart_cmd_response(GET_DUT_INFO_CMD, UART_TEST_ERROR, NULL, 0);
+#endif
+}
+
+/******************************************************************
+ * @brief Get DUT information command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_auto_k_rf_freq(void *p_data)
+{
+#if MP_TEST_MODE_SUPPORT_AUTO_K_RF
+ bool result = false;
+ uint8_t result_info[16];
+ uint8_t cal_xtal_result;
+
+ uint8_t rx_channel = *((uint8_t *)p_data + 19);
+ uint8_t drift_threshold = *((uint8_t *)p_data + 20);
+
+ memcpy(result_info, (uint8_t *)p_data + 3, 16);
+ result = check_verify_result(result_info);
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO,
+ "[uart_test_auto_k_rf_freq] rx_channel is %d, drift_threshold is %d, check_result is %d",
+ 3, rx_channel, drift_threshold, result);
+
+ if (result == true)
+ {
+ if (Auto_K_RF(rx_channel, drift_threshold, &cal_xtal_result))
+ {
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_auto_k_rf_freq] Cal RF freqency failed", 0);
+ data_uart_cmd_response(AUTO_K_RF_FREQ_CMD, UART_TEST_ERROR, NULL, 0);
+ }
+ else
+ {
+ bool write_xtal_ret;
+
+#ifdef WRITE_XTAL_TO_EFUSE
+ write_xtal_ret = WriteXtalToEfuse(cal_xtal_result);
+#else
+ write_xtal_ret = WriteXtalToConfig(cal_xtal_result);
+#endif
+ if (write_xtal_ret == true)
+ {
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_auto_k_rf_freq] Cal RF freqency succeeded", 0);
+ data_uart_cmd_response(AUTO_K_RF_FREQ_CMD, UART_TEST_SUCCESS, &cal_xtal_result, 1);
+ }
+ else
+ {
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_auto_k_rf_freq] Cal RF freqency failed", 0);
+ data_uart_cmd_response(AUTO_K_RF_FREQ_CMD, UART_TEST_ERROR, NULL, 0);
+ }
+ }
+ }
+ else
+ {
+ data_uart_cmd_response(AUTO_K_RF_FREQ_CMD, UART_TEST_ERROR, NULL, 0);
+ }
+#else
+ data_uart_cmd_response(AUTO_K_RF_FREQ_CMD, UART_TEST_ERROR, NULL, 0);
+#endif
+}
+
+/******************************************************************
+ * @brief Find device type command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void
+ */
+static void uart_test_find_device_type(void *p_data)
+{
+ uint8_t dev_type = TEST_DEVICE_TYPE;
+
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_find_device_type] dev_type is %d", 1,
+ dev_type);
+ data_uart_cmd_response(FIND_DEVICE_TYPE_CMD, UART_TEST_SUCCESS, &dev_type, 1);
+}
+
+/******************************************************************
+ * @brief Get the specified uart command.
+ * @param p_data - point to UART packet struct.
+ * @return none
+ * @retval void.
+ */
+static void uart_test_get_cmd_func(T_UART_PACKET_DEF *p_data)
+{
+ uint16_t opcode = (p_data->uart_buf[2] << 8) + p_data->uart_buf[1];
+
+ UART_DBG_BUFFER(MODULE_UART, LEVEL_INFO, "[uart_test_get_cmd_func] opcode is 0x%04X", 1, opcode);
+
+ /* uart test command */
+ if ((opcode >= UART_FN_BEGIN) && (opcode < UART_FN_END))
+ {
+ if (uart_test_func_map[opcode & UART_FN_MASK].fncb != NULL)
+ {
+ uart_test_func_map[opcode & UART_FN_MASK].fncb(p_data);
+ }
+ else
+ {
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "No uart test cmd function!", 0);
+ }
+ }
+ else
+ {
+ /* Other command */
+ }
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief initialize uart test function.
+ * @return none
+ * @retval void
+ */
+void uart_test_init(void)
+{
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[uart_test_init] initialize uart test mode", 0);
+ data_uart_transport_init();
+ uart_test_is_dlps_allowed = false;
+}
+
+/******************************************************************
+ * @brief Uart Test Check DLPS allowed or not.
+ * @return allow to enter DLPS or not.
+ * @retval true or false.
+ */
+bool uart_test_check_dlps(void)
+{
+ return uart_test_is_dlps_allowed;
+}
+
+/******************************************************************
+ * @brief Uart Test enter DLPS config
+ * @param none
+ * @return none
+ * @retval void
+ */
+void uart_test_enter_dlps_config(void)
+{
+ /*config uart tx/rx pins*/
+ Pad_Config(MP_TEST_UART_TX_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_DOWN, PAD_OUT_ENABLE,
+ PAD_OUT_LOW);
+ Pad_Config(MP_TEST_UART_RX_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_DOWN, PAD_OUT_ENABLE,
+ PAD_OUT_LOW);
+
+ /*config mp check pin*/
+ Pad_Config(MP_TEST_TRIG_PIN_2, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_LOW);
+}
+
+/******************************************************************
+ * @brief handle UART message.
+ * @param io_driver_msg_recv - received io message.
+ * @return none
+ * @retval void
+ */
+void uart_test_handle_uart_msg(T_IO_MSG io_driver_msg_recv)
+{
+ T_UART_PACKET_DEF *pUartTestPacket = (T_UART_PACKET_DEF *)(io_driver_msg_recv.u.buf);
+
+ if (data_uart_packet_decode(pUartTestPacket))
+ {
+ uart_test_get_cmd_func(pUartTestPacket);
+ }
+}
+
+/******************************************************************
+ * @brief handle GDMA message
+ * @param io_driver_msg_recv - received io message.
+ * @return none
+ * @retval void
+ */
+void uart_test_handle_gdma_msg(T_IO_MSG io_driver_msg_recv)
+{
+ uint8_t blk_cnt, remainder;
+ uint8_t *p_buf = io_driver_msg_recv.u.buf;
+
+ blk_cnt = (VOICE_GDMA_FRAME_SIZE) / UART_TX_FIFO_SIZE;
+ remainder = (VOICE_GDMA_FRAME_SIZE) % UART_TX_FIFO_SIZE;
+ /* send voice data through uart */
+ for (int i = 0; i < blk_cnt; i++)
+ {
+ /* 1. max send 16 bytes(Uart tx and rx fifo size is 16) */
+ UART_SendData(UART0, p_buf, 16);
+ /* wait tx fifo empty */
+ while (UART_GetFlagStatus(UART0, UART_FLAG_TX_FIFO_EMPTY) != SET);
+ p_buf += 16;
+ }
+
+ /* send left bytes */
+ UART_SendData(UART0, p_buf, remainder);
+ /* wait tx fifo empty */
+ while (UART_GetFlagStatus(UART0, UART_FLAG_TX_FIFO_EMPTY) != SET);
+}
+
+#endif
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/test_module/data_uart_test.h b/src/app/google_rcu/test_module/data_uart_test.h
new file mode 100644
index 0000000..6cdc24e
--- /dev/null
+++ b/src/app/google_rcu/test_module/data_uart_test.h
@@ -0,0 +1,198 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file rcu_uart_test.h
+* @brief
+* @details
+* @author chenjie jin
+* @date 2018-04-08
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __RCU_UART_TEST_H
+#define __RCU_UART_TEST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "uart_transport.h"
+#include "app_msg.h"
+
+/* Defines ------------------------------------------------------------------ */
+
+/** @brief Number of function used in application.*/
+/* You must modify this value according the function number used in your application. */
+
+#define UART_FN_MASK ((uint16_t)0x00FF)
+
+/* Protocol command defines */
+#define UART_FN_BEGIN ((uint16_t)0x1100)
+
+#define READ_PATCH_VERSION_CMD ((uint16_t)0x1100)
+#define READ_APP_VERSION_CMD ((uint16_t)0x1101)
+#define READ_MAC_ADDR_CMD ((uint16_t)0x1102)
+#define ENTER_FAST_PAIR_MODE_CMD ((uint16_t)0x1103)
+#define GET_DEVICE_STATE_CMD ((uint16_t)0x1104)
+#define VOICE_TEST_START_CMD ((uint16_t)0x1105)
+#define VOICE_TEST_STOP_CMD ((uint16_t)0x1106)
+#define SET_VOICE_CONFIG_CMD ((uint16_t)0x1107)
+#define GET_VOICE_CONFIG_CMD ((uint16_t)0x1108)
+#define ENTER_DLPS_TEST_MODE_CMD ((uint16_t)0x1109)
+#define START_STOP_ADV_CMD ((uint16_t)0x110A)
+#define START_IR_TEST_MODE_CMD ((uint16_t)0x110B)
+#define ENTER_HCI_TEST_MODE_CMD ((uint16_t)0x110C)
+#define DISABLE_TEST_MODE_FLG_CMD ((uint16_t)0x110D)
+#define ENABLE_TEST_MODE_FLG_CMD ((uint16_t)0x110E)
+#define ERASE_PAIR_INFO_CMD ((uint16_t)0x110F)
+#define CHANGE_BAUDRATE_CMD ((uint16_t)0x1110)
+#define DIRECT_K_RF_FREQ_CMD ((uint16_t)0x1111)
+#define GET_GLODEN_INFO_CMD ((uint16_t)0x1112)
+#define GET_DUT_INFO_CMD ((uint16_t)0x1113)
+#define VERIFY_DUT_INFO_CMD ((uint16_t)0x1114)
+#define AUTO_K_RF_FREQ_CMD ((uint16_t)0x1115)
+#define FIND_DEVICE_TYPE_CMD ((uint16_t)0x1116)
+#define REBOOT_DEVICE_CMD ((uint16_t)0x1117)
+#define UPDATE_MAC_ADDR_CMD ((uint16_t)0x1118)
+#define ENTER_SINGLE_TONE_MODE_CMD ((uint16_t)0x1119)
+#define READ_HARDWARE_VERSION_CMD ((uint16_t)0x111A)
+#define TERMINATE_CONNECT_CMD ((uint16_t)0x111B)
+#define MANUAL_K_RF_FREQ_CMD ((uint16_t)0x111C)
+#define ENTER_HCI_DOWNLOAD_MODE_CMD ((uint16_t)0x111D)
+#define SET_CODEC_EQ_CH0_CONFIG_CMD ((uint16_t)0x111E)
+#define GET_CODEC_EQ_CH0_CONFIG_CMD ((uint16_t)0x111F)
+#define SET_CODEC_EQ_CH1_CONFIG_CMD ((uint16_t)0x1120)
+#define GET_CODEC_EQ_CH1_CONFIG_CMD ((uint16_t)0x1121)
+
+#define UART_FN_END ((uint16_t)0x1122)
+
+#define UART_TEST_SUPPORT_NUM (UART_FN_END - UART_FN_BEGIN)
+
+typedef void (*p_uart_test_func)(void *);
+
+typedef struct
+{
+ uint16_t opcode;
+ uint16_t param_len;
+ p_uart_test_func fncb;
+} T_UART_TEST_PROTOCOL;
+
+typedef enum
+{
+ UART_TEST_SUCCESS = 0,
+ UART_TEST_ERROR = 1
+} T_UART_TEST_STATUS;
+
+typedef enum
+{
+ CHANGE_BAUDRATE_OPTION_115200 = 0,
+ CHANGE_BAUDRATE_OPTION_1M = 1,
+ CHANGE_BAUDRATE_OPTION_2M = 2,
+} T_CHANGE_BAUDRATE_OPTION;
+
+typedef enum
+{
+ UART_TEST_CODEC_SAMPLE_RATE_8K = 0,
+ UART_TEST_CODEC_SAMPLE_RATE_16K = 1,
+ UART_TEST_CODEC_SAMPLE_RATE_32K = 2,
+ UART_TEST_CODEC_SAMPLE_RATE_44100 = 3,
+ UART_TEST_CODEC_SAMPLE_RATE_48K = 4,
+ UART_TEST_CODEC_SAMPLE_RATE_ENUM_GUARD,
+} T_UART_TEST_CODEC_SAMPLE_RATE;
+
+typedef enum
+{
+ T_UART_TEST_CODEC_DMICCLOCK_5MHz = 0,
+ T_UART_TEST_CODEC_DMICCLOCK_2500KHz = 1,
+ T_UART_TEST_CODEC_DMICCLOCK_1250KHz = 2,
+ T_UART_TEST_CODEC_DMICCLOCK_625KHz = 3,
+ T_UART_TEST_CODEC_DMICCLOCK_312500Hz = 4,
+ T_UART_TEST_CODEC_DMICCLOCK_ENUM_GUARD,
+} T_UART_TEST_CODEC_DMICCLOCK;
+
+typedef enum
+{
+ UART_TEST_CODEC_MIC_BIAS_VOL_1_507 = 0,
+ UART_TEST_CODEC_MIC_BIAS_VOL_1_62 = 1,
+ UART_TEST_CODEC_MIC_BIAS_VOL_1_705 = 2,
+ UART_TEST_CODEC_MIC_BIAS_VOL_1_8 = 3,
+ UART_TEST_CODEC_MIC_BIAS_VOL_1_906 = 4,
+ UART_TEST_CODEC_MIC_BIAS_VOL_2_025 = 5,
+ UART_TEST_CODEC_MIC_BIAS_VOL_2_16 = 6,
+ UART_TEST_CODEC_MIC_BIAS_VOL_2_314 = 7,
+ UART_TEST_CODEC_MIC_BIAS_VOL_ENUM_GUARD,
+} T_UART_TEST_CODEC_MIC_BIAS_VOL;
+
+typedef enum
+{
+ UART_TEST_CODEC_MICBST_GAIN_0dB = 0,
+ UART_TEST_CODEC_MICBST_GAIN_20dB = 1,
+ UART_TEST_CODEC_MICBST_GAIN_30dB = 2,
+ UART_TEST_CODEC_MICBST_GAIN_40dB = 3,
+ UART_TEST_CODEC_MICBST_GAIN_ENUM_GUARD,
+} T_UART_TEST_CODEC_MICBST_GAIN;
+
+typedef enum
+{
+ UART_TEST_MIC_INPUT_TYPE_DIFF = 0,
+ UART_TEST_MIC_INPUT_TYPE_SINGLE = 1,
+} T_UART_TEST_MIC_INPUT_TYPE;
+
+typedef enum
+{
+ T_UART_TEST_CODEC_CH0_BOOSTGAIN_0dB = 0,
+ T_UART_TEST_CODEC_CH0_BOOSTGAIN_12dB = 1,
+ T_UART_TEST_CODEC_CH0_BOOSTGAIN_24dB = 2,
+ T_UART_TEST_CODEC_CH0_BOOSTGAIN_36dB = 3,
+ T_UART_TEST_CODEC_CH0_BOOSTGAIN_ENUM_GUARD,
+} T_UART_TEST_CODEC_CH0_BOOSTGAIN;
+
+typedef enum
+{
+ T_UART_TEST_CODEC_CH1_BOOSTGAIN_0dB = 0,
+ T_UART_TEST_CODEC_CH1_BOOSTGAIN_12dB = 1,
+ T_UART_TEST_CODEC_CH1_BOOSTGAIN_24dB = 2,
+ T_UART_TEST_CODEC_CH1_BOOSTGAIN_36dB = 3,
+ T_UART_TEST_CODEC_CH1_BOOSTGAIN_ENUM_GUARD,
+} T_UART_TEST_CODEC_CH1_BOOSTGAIN;
+
+
+typedef enum
+{
+ UART_TEST_VOICE_ENC_TYPE_RAW = 0,
+ UART_TEST_VOICE_ENC_TYPE_MSBC = 1,
+ UART_TEST_VOICE_ENC_TYPE_SBC = 2,
+ UART_TEST_VOICE_ENC_TYPE_ADPCM = 3,
+ UART_TEST_VOICE_ENC_TYPE_ENUM_GUARD,
+} T_UART_TEST_VOICE_ENC_TYPE;
+
+
+
+#if SUPPORT_CODEC_EQ_CONFIG_FEATURE
+typedef enum
+{
+ UART_TEST_CODEC_EQ_STATUS_DISABLE = 0,
+ UART_TEST_CODEC_EQ_STATUS_ENABLE = 1,
+ UART_TEST_CODEC_EQ_STATUS_ENUM_GUARD,
+} T_UART_TEST_CODEC_EQ_STATUS;
+#endif
+
+extern const T_UART_TEST_PROTOCOL uart_test_func_map[UART_TEST_SUPPORT_NUM];
+
+void uart_test_init(void);
+bool uart_test_check_dlps(void);
+void uart_test_enter_dlps_config(void);
+void uart_test_handle_uart_msg(T_IO_MSG io_driver_msg_recv);
+void uart_test_handle_gdma_msg(T_IO_MSG io_driver_msg_recv);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__RCU_UART_TEST_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/test_module/mp_test.c b/src/app/google_rcu/test_module/mp_test.c
new file mode 100644
index 0000000..e43cac1
--- /dev/null
+++ b/src/app/google_rcu/test_module/mp_test.c
@@ -0,0 +1,442 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file mp_test.c
+* @brief
+* @details
+* @author chenjie jin
+* @date 2020-03-03
+* @version v2.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "rtl876x.h"
+#include "trace.h"
+#include "gap.h"
+#include "board.h"
+#include "mp_test.h"
+#include "test_mode.h"
+#include "gap_storage_le.h"
+#include "mem_types.h"
+#include "ftl.h"
+#include "os_mem.h"
+#include "gap_bond_le.h"
+#include "key_handle.h"
+#include <rtl876x_rcc.h>
+#include <rtl876x_pinmux.h>
+#include <rtl876x_gpio.h>
+
+#if FEATURE_SUPPORT_MP_TEST_MODE
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+/* Fast Pairing Local Mac Address Config List */
+static const uint8_t mp_fp_local_addr_config_list[FP_MAX_LINE_NUM][FP_MAC_ADDR_LEN] =
+{
+ {0x01, 0x88, 0x23, 0x4c, 0xe0, 0x00},
+ {0x02, 0x88, 0x23, 0x4c, 0xe0, 0x00},
+ {0x03, 0x88, 0x23, 0x4c, 0xe0, 0x00},
+ {0x04, 0x88, 0x23, 0x4c, 0xe0, 0x00},
+ {0x05, 0x88, 0x23, 0x4c, 0xe0, 0x00},
+};
+
+/* Fast Pairing Remote Mac Address Config List */
+static const uint8_t mp_fp_remote_addr_config_list[FP_MAX_LINE_NUM][FP_MAC_ADDR_LEN] =
+{
+ {0x87, 0x99, 0x23, 0x4c, 0xe0, 0x00},
+ {0x87, 0x99, 0x23, 0x4c, 0xe0, 0x00},
+ {0x87, 0x99, 0x23, 0x4c, 0xe0, 0x00},
+ {0x87, 0x99, 0x23, 0x4c, 0xe0, 0x00},
+ {0x87, 0x99, 0x23, 0x4c, 0xe0, 0x00},
+};
+
+/* Fast Pairing Link Key Config List */
+static const uint8_t mp_fp_link_key_config_list[FP_MAX_LINE_NUM][FP_LINK_KEY_LEN] =
+{
+ {0xcb, 0x84, 0xaa, 0x4d, 0x66, 0x42, 0xd5, 0xa2, 0x33, 0xa1, 0x6a, 0x51, 0x9a, 0x50, 0xb5, 0xac},
+ {0xcb, 0x84, 0xaa, 0x4d, 0x66, 0x42, 0xd5, 0xa2, 0x33, 0xa1, 0x6a, 0x51, 0x9a, 0x50, 0xb5, 0xac},
+ {0xcb, 0x84, 0xaa, 0x4d, 0x66, 0x42, 0xd5, 0xa2, 0x33, 0xa1, 0x6a, 0x51, 0x9a, 0x50, 0xb5, 0xac},
+ {0xcb, 0x84, 0xaa, 0x4d, 0x66, 0x42, 0xd5, 0xa2, 0x33, 0xa1, 0x6a, 0x51, 0x9a, 0x50, 0xb5, 0xac},
+ {0xcb, 0x84, 0xaa, 0x4d, 0x66, 0x42, 0xd5, 0xa2, 0x33, 0xa1, 0x6a, 0x51, 0x9a, 0x50, 0xb5, 0xac},
+};
+
+/* Fast Pairing CCCD Information */
+
+static const uint8_t mp_fp_cccd_info[FP_CCCD_DATA_LEN] =
+{
+ 0x04, 0x00, 0x02, 0x00, 0x11, 0x00, 0x01, 0x00,
+ 0x30, 0x00, 0x01, 0x00, 0x34, 0x00, 0x01, 0x00,
+ 0x3b, 0x00, 0x01, 0x00, 0x5f, 0x00, 0x01, 0x00,
+ 0x62, 0x00, 0x01, 0x00, 0x68, 0x00, 0x01, 0x00
+};
+
+uint32_t test_flag_ftl_value = MP_TEST_MODE_FLG_DISABLE_VALUE;
+
+/*============================================================================*
+* Local Functions
+*============================================================================*/
+
+
+/*============================================================================*
+* Global Functions
+*============================================================================*/
+/******************************************************************
+ * @brief MP Test initialize data.
+ * @param void
+ * @return void
+ * @retval none
+ */
+void mp_test_init_data(void)
+{
+ uint32_t ftl_res = 0;
+
+ ftl_res = ftl_load(&test_flag_ftl_value, MP_TEST_FTL_PARAMS_TEST_MODE_FLG_OFFSET,
+ MP_TEST_FTL_PARAMS_TEST_MODE_FLG_LEN);
+
+ if (ftl_res == FTL_READ_ERROR_READ_NOT_FOUND)
+ {
+ APP_PRINT_WARN0("[mp_test_is_test_mode_flag_en] test mode ftl flag is invalid, reset to enabled!");
+ mp_test_enable_test_mode_flag();
+ ftl_load(&test_flag_ftl_value, MP_TEST_FTL_PARAMS_TEST_MODE_FLG_OFFSET,
+ MP_TEST_FTL_PARAMS_TEST_MODE_FLG_LEN);
+ }
+
+ APP_PRINT_INFO2("[mp_test_is_test_mode_flag_en] ftl_res is %d, value is 0x%08X", ftl_res,
+ test_flag_ftl_value);
+}
+
+/******************************************************************
+ * @brief MP Test enable test mode flag.
+ * @param none
+ * @return result
+ * @retval true of false
+ */
+bool mp_test_enable_test_mode_flag(void)
+{
+ uint32_t result = false;
+ test_flag_ftl_value = MP_TEST_MODE_FLG_ENABLE_VALUE;
+
+ result = ftl_save(&test_flag_ftl_value, MP_TEST_FTL_PARAMS_TEST_MODE_FLG_OFFSET,
+ MP_TEST_FTL_PARAMS_TEST_MODE_FLG_LEN);
+
+ return (result == 0);
+}
+
+/******************************************************************
+ * @brief MP Test disable test mode flag.
+ * @param none
+ * @return result
+ * @retval true of false
+ */
+bool mp_test_disable_test_mode_flag(void)
+{
+ uint32_t result = false;
+ test_flag_ftl_value = MP_TEST_MODE_FLG_DISABLE_VALUE;
+
+ result = ftl_save(&test_flag_ftl_value, MP_TEST_FTL_PARAMS_TEST_MODE_FLG_OFFSET,
+ MP_TEST_FTL_PARAMS_TEST_MODE_FLG_LEN);
+
+ return (result == 0);
+}
+
+/******************************************************************
+ * @brief MP Test check if test mode is enabled or not.
+ * @param none
+ * @return result
+ * @retval true of false
+ */
+bool mp_test_is_test_mode_flag_en(void)
+{
+ return (test_flag_ftl_value == MP_TEST_MODE_FLG_ENABLE_VALUE);
+}
+
+/******************************************************************
+ * @brief MP Test Set Fast Pair Info.
+ * @param index
+ * @return result
+ * @retval true of false
+ */
+bool mp_test_set_fast_pair_info(uint8_t index)
+{
+ bool result = false;
+ uint8_t ltk_length;
+ uint8_t mp_local_bd[8] = {0};
+ uint8_t remote_mac_addr[6] = {0};
+ T_LE_KEY_TYPE link_key_type = LE_KEY_UNAUTHEN;
+ uint8_t local_ltk[FP_LINK_KEY_LEN];
+ T_GAP_REMOTE_ADDR_TYPE remote_addr_type;
+ uint8_t ccc_bits_count;
+ T_LE_CCCD *p_cccd_data;
+
+ if (index >= FP_MAX_LINE_NUM)
+ {
+ return false;
+ }
+
+ /* set local bd addr info */
+ memcpy(mp_local_bd, mp_fp_local_addr_config_list[index], FP_MAC_ADDR_LEN);
+ result = ftl_save(mp_local_bd, MP_TEST_FTL_PARAMS_LOCAL_BD_ADDR_OFFSET,
+ MP_TEST_FTL_PARAMS_LOCAL_BD_ADDR_LEN);
+ if (result != 0)
+ {
+ return false; /* ftl save failed */
+ }
+
+ /* set remote mac addr info */
+ remote_addr_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ memcpy(remote_mac_addr, mp_fp_remote_addr_config_list[index], FP_MAC_ADDR_LEN);
+
+ /* set link key info */
+ ltk_length = FP_LINK_KEY_LEN;
+ memcpy(local_ltk, mp_fp_link_key_config_list[index], FP_LINK_KEY_LEN);
+
+ /* set cccd info */
+ ccc_bits_count = FP_CCCD_BITS_CNT;
+ p_cccd_data = os_mem_alloc(RAM_TYPE_DATA_ON, 4 + ccc_bits_count * 4);
+ p_cccd_data->data_length = FP_CCCD_DATA_LEN;
+ memcpy(p_cccd_data->data, mp_fp_cccd_info, FP_CCCD_DATA_LEN);
+
+ /* generate bond dev info */
+ result = le_gen_bond_dev(remote_mac_addr, remote_addr_type, GAP_LOCAL_ADDR_LE_PUBLIC,
+ ltk_length, local_ltk, link_key_type, p_cccd_data);
+
+ os_mem_free(p_cccd_data);
+
+ return result;
+}
+
+/******************************************************************
+ * @brief MP Test load fast pair mac addr.
+ * @param none
+ * @return result
+ * @retval true of false
+ */
+bool mp_test_load_fp_mac_addr(void)
+{
+ bool result = false;
+ uint8_t mp_mac[8] = {0};
+
+ if (0 == ftl_load(mp_mac, MP_TEST_FTL_PARAMS_LOCAL_BD_ADDR_OFFSET, sizeof(mp_mac)))
+ {
+ memcpy((uint8_t *)0x00200197, mp_mac, 6);
+ APP_PRINT_INFO1("[mp_test_load_fp_mac_addr] MP MAC Addr: %b", TRACE_BINARY(6, mp_mac));
+ result = true;
+ }
+ else
+ {
+ APP_PRINT_ERROR0("[mp_test_load_fp_mac_addr] load mp mac addr failed!");
+ result = false;
+ }
+
+ return result;
+}
+
+/******************************************************************
+ * @brief MP Test clear bond information
+ * @param none
+ * @return result
+ * @retval true of false
+ */
+bool mp_test_clear_bond_info(void)
+{
+ bool result = true;
+
+ /* clear all keys */
+ le_bond_clear_all_keys();
+
+ result = (le_get_bond_dev_num() > 0) ? false : true;
+
+ APP_PRINT_INFO1("[mp_test_clear_bond_info] result: %d", result);
+
+ return result;
+}
+
+/******************************************************************
+ * @brief MP Test handle combine keys timer callback
+ * @param combine_status
+ * @return result
+ * @retval true or false
+ */
+bool mp_test_handle_comb_keys_timer_cb(uint32_t combine_status)
+{
+ bool result = true;
+
+ switch (combine_status)
+ {
+#if MP_TEST_MODE_SUPPORT_HCI_UART_TEST
+ case HCI_UART_TEST_COMBINE_KEYS_BIT_MASK:
+ {
+ DBG_DIRECT("[mp_test_handle_comb_keys_timer_cb] Switch to HCI UART test mode!");
+ switch_to_hci_mode();
+ }
+ break;
+#endif
+#if MP_TEST_MODE_SUPPORT_DATA_UART_TEST
+ case DATA_UART_TEST_COMBINE_KEYS_BIT_MASK:
+ {
+ DBG_DIRECT("[mp_test_handle_comb_keys_timer_cb] Switch to Data UART test mode!");
+ switch_to_test_mode(DATA_UART_TEST_MODE);
+ }
+ break;
+#endif
+#if MP_TEST_MODE_SUPPORT_SINGLE_TONE_TEST
+ case SINGLE_TONE_TEST_COMBINE_KEYS_BIT_MASK:
+ {
+ DBG_DIRECT("[mp_test_handle_comb_keys_timer_cb] Switch to Single Tone test mode!");
+ switch_to_test_mode(SINGLE_TONE_MODE);
+ }
+ break;
+#endif
+#if MP_TEST_MODE_SUPPORT_FAST_PAIR_TEST
+ case FAST_PAIR_1_COMBINE_KEYS_BIT_MASK:
+ {
+ if (mp_test_set_fast_pair_info(0) == true)
+ {
+ DBG_DIRECT("[mp_test_handle_comb_keys_timer_cb] Switch to Fast Pair 1 test mode!");
+ switch_to_test_mode(AUTO_PAIR_WITH_FIX_ADDR_MODE);
+ }
+ else
+ {
+ APP_PRINT_ERROR0("[mp_test_handle_comb_keys_timer_cb] Failed to switch to Fast Pair 1 mode!");
+ }
+ }
+ break;
+ case FAST_PAIR_2_COMBINE_KEYS_BIT_MASK:
+ {
+ if (mp_test_set_fast_pair_info(1) == true)
+ {
+ DBG_DIRECT("[mp_test_handle_comb_keys_timer_cb] Switch to Fast Pair 2 test mode!");
+ switch_to_test_mode(AUTO_PAIR_WITH_FIX_ADDR_MODE);
+ }
+ else
+ {
+ APP_PRINT_ERROR0("[mp_test_handle_comb_keys_timer_cb] Failed to switch to Fast Pair 2 mode!");
+ }
+ }
+ break;
+ case FAST_PAIR_3_COMBINE_KEYS_BIT_MASK:
+ {
+ if (mp_test_set_fast_pair_info(2) == true)
+ {
+ DBG_DIRECT("[mp_test_handle_comb_keys_timer_cb] Switch to Fast Pair 3 test mode!");
+ switch_to_test_mode(AUTO_PAIR_WITH_FIX_ADDR_MODE);
+ }
+ else
+ {
+ APP_PRINT_ERROR0("[mp_test_handle_comb_keys_timer_cb] Failed to switch to Fast Pair 3 mode!");
+ }
+ }
+ break;
+ case FAST_PAIR_4_COMBINE_KEYS_BIT_MASK:
+ {
+ if (mp_test_set_fast_pair_info(3) == true)
+ {
+ DBG_DIRECT("[mp_test_handle_comb_keys_timer_cb] Switch to Fast Pair 4 test mode!");
+ switch_to_test_mode(AUTO_PAIR_WITH_FIX_ADDR_MODE);
+ }
+ else
+ {
+ APP_PRINT_ERROR0("[mp_test_handle_comb_keys_timer_cb] Failed to switch to Fast Pair 4 mode!");
+ }
+ }
+ break;
+ case FAST_PAIR_5_COMBINE_KEYS_BIT_MASK:
+ {
+ if (mp_test_set_fast_pair_info(4) == true)
+ {
+ DBG_DIRECT("[mp_test_handle_comb_keys_timer_cb] Switch to Fast Pair 5 test mode!");
+ switch_to_test_mode(AUTO_PAIR_WITH_FIX_ADDR_MODE);
+ }
+ else
+ {
+ APP_PRINT_ERROR0("[mp_test_handle_comb_keys_timer_cb] Failed to switch to Fast Pair 5 mode!");
+ }
+ }
+ break;
+#endif
+ default:
+ {
+ result = false;
+ }
+ break;
+ }
+
+ return result;
+}
+
+#if (MP_TEST_MODE_TRIG_SEL & MP_TEST_MODE_TRIG_BY_GPIO)
+/******************************************************************
+ * @brief Test Mode check trigger GPIO status
+ * @param none
+ * @return none
+ * @retval void
+ */
+void mp_test_check_trig_gpio_status(void)
+{
+ uint8_t gpio_status_1;
+ uint8_t gpio_status_2;
+
+ /* Enable GPIO clock */
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+ /* pinmux configuration */
+ Pinmux_Config(MP_TEST_TRIG_PIN_1, DWGPIO);
+ Pinmux_Config(MP_TEST_TRIG_PIN_2, DWGPIO);
+ /* pad configuration */
+ Pad_Config(MP_TEST_TRIG_PIN_1, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(MP_TEST_TRIG_PIN_2, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+
+ GPIO_InitTypeDef Gpio_Struct;
+ GPIO_StructInit(&Gpio_Struct);
+ Gpio_Struct.GPIO_Pin = GPIO_GetPin(MP_TEST_TRIG_PIN_1) | GPIO_GetPin(MP_TEST_TRIG_PIN_2);
+ Gpio_Struct.GPIO_Mode = GPIO_Mode_IN;
+ Gpio_Struct.GPIO_ITCmd = DISABLE;
+ GPIO_Init(&Gpio_Struct);
+
+ gpio_status_1 = GPIO_ReadInputDataBit(GPIO_GetPin(MP_TEST_TRIG_PIN_1));
+ gpio_status_2 = GPIO_ReadInputDataBit(GPIO_GetPin(MP_TEST_TRIG_PIN_2));
+
+ /* reset pad configuration to save power */
+ Pad_Config(MP_TEST_TRIG_PIN_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_DOWN, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(MP_TEST_TRIG_PIN_2, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_DOWN, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+
+ APP_PRINT_INFO2("[mp_test_check_trig_gpio_status] gpio_status_1 = %d, gpio_status_2 = %d",
+ gpio_status_1, gpio_status_2);
+ if (gpio_status_1 == 0)
+ {
+ DBG_DIRECT("[mp_test_check_trig_gpio_status] Switch to Single Tone test mode!");
+ switch_to_test_mode(SINGLE_TONE_MODE);
+ }
+// if ((gpio_status_1 == 0) && (gpio_status_2 == 0))
+// {
+// DBG_DIRECT("[mp_test_check_trig_gpio_status] Switch to Single Tone test mode!");
+// switch_to_test_mode(SINGLE_TONE_MODE);
+// }
+// else if ((gpio_status_1 == 1) && (gpio_status_2 == 0))
+// {
+// DBG_DIRECT("[mp_test_check_trig_gpio_status] Switch to Data UART test mode!");
+// switch_to_test_mode(DATA_UART_TEST_MODE);
+// }
+// else if ((gpio_status_1 == 0) && (gpio_status_2 == 1))
+// {
+// DBG_DIRECT("[mp_test_check_trig_gpio_status] Switch to HCI UART test mode!");
+// switch_to_hci_mode();
+// }
+// else
+// {
+// /* normal mode */
+// }
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/test_module/mp_test.h b/src/app/google_rcu/test_module/mp_test.h
new file mode 100644
index 0000000..5071f06
--- /dev/null
+++ b/src/app/google_rcu/test_module/mp_test.h
@@ -0,0 +1,53 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file mp_test.h
+* @brief .
+* @details
+* @author ranhui_xia
+* @date 2020-05-14
+* @version v1.1
+*********************************************************************************************************
+*/
+
+#ifndef _MP_CONFIG_H
+#define _MP_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stdbool.h"
+#include "stdint.h"
+#include "key_handle.h"
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define FP_MAX_LINE_NUM 5
+#define FP_MAC_ADDR_LEN 6
+#define FP_LINK_KEY_LEN 16
+#define FP_CCCD_BITS_CNT 36
+#define FP_CCCD_DATA_LEN 32
+
+#define MP_TEST_MODE_FLG_ENABLE_VALUE 0x74657374
+#define MP_TEST_MODE_FLG_DISABLE_VALUE 0x50245150
+
+void mp_test_init_data(void);
+bool mp_test_enable_test_mode_flag(void);
+bool mp_test_disable_test_mode_flag(void);
+bool mp_test_is_test_mode_flag_en(void);
+bool mp_test_set_fast_pair_info(uint8_t index);
+bool mp_test_clear_bond_info(void);
+bool mp_test_handle_comb_keys_timer_cb(uint32_t combine_status);
+#if (MP_TEST_MODE_TRIG_SEL & MP_TEST_MODE_TRIG_BY_GPIO)
+void mp_test_check_trig_gpio_status(void);
+#endif
+bool mp_test_load_fp_mac_addr(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PROFILE_INIT_H */
diff --git a/src/app/google_rcu/test_module/single_tone.c b/src/app/google_rcu/test_module/single_tone.c
new file mode 100644
index 0000000..dedfe77
--- /dev/null
+++ b/src/app/google_rcu/test_module/single_tone.c
@@ -0,0 +1,232 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file single_tone.c
+* @brief single tone test implementation.
+* @details none.
+* @author Chenjie Jin
+* @date 2020-03-03
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "board.h"
+#include "single_tone.h"
+#include "trace.h"
+#include "os_mem.h"
+#include "os_task.h"
+#include "os_sched.h"
+#include "os_timer.h"
+#include "rtl876x_wdg.h"
+#include <app_section.h>
+
+#if MP_TEST_MODE_SUPPORT_SINGLE_TONE_TEST
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/* open EXIT_SINGLE_TONE_TEST_WHEN_TIMEOUT to enable the function of exiting Single Tone Test when Timeout */
+#define EXIT_SINGLE_TONE_TEST_WHEN_TIMEOUT 1
+
+#if EXIT_SINGLE_TONE_TEST_WHEN_TIMEOUT
+#define EXIT_SINGLE_TONE_TIME (8*1000) /* 8s */
+#endif
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+typedef void *TimerHandle_t;
+#if EXIT_SINGLE_TONE_TEST_WHEN_TIMEOUT
+static TimerHandle_t single_tone_exit_timer = NULL;
+#endif
+static bool single_tone_is_sent_start_cmd = false;
+static bool single_tone_is_sent_restart_cmd = false;
+static void *single_tone_task_handle;
+
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+static void single_tone_reset(uint8_t channel_num);
+static void single_tone_start(uint8_t channel_num);
+static bool single_tone_handle_hci_cb(T_SINGLE_TONE_EVT evt, bool status, uint8_t *p_buf,
+ uint32_t len);
+static void single_tone_task(void *p_param);
+#if EXIT_SINGLE_TONE_TEST_WHEN_TIMEOUT
+static void single_tone_exit_timeout_cb(TimerHandle_t p_timer) DATA_RAM_FUNCTION;
+#endif
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief reset singletone.
+ * @param channel_num - channel of singletone.
+ * @return none
+ * @retval void
+ */
+void single_tone_reset(uint8_t channel_num)
+{
+ T_SINGLE_TONE_VEND_CMD_PARAMS *p_vend_cmd_params = os_mem_alloc(RAM_TYPE_DATA_ON,
+ sizeof(T_SINGLE_TONE_VEND_CMD_PARAMS));
+
+ if (p_vend_cmd_params)
+ {
+ APP_PRINT_INFO0("Single Tone Reset Command!");
+
+ p_vend_cmd_params->pkt_type = 1;
+ p_vend_cmd_params->opcode = 0xfc78;
+ p_vend_cmd_params->length = 4;
+ p_vend_cmd_params->start = 0;
+ p_vend_cmd_params->channel = channel_num;
+ p_vend_cmd_params->tx_power = 6;
+ p_vend_cmd_params->is_le = 1;
+
+ hci_if_write((uint8_t *)p_vend_cmd_params, sizeof(T_SINGLE_TONE_VEND_CMD_PARAMS));
+
+ single_tone_is_sent_restart_cmd = true;
+ }
+}
+
+/******************************************************************
+ * @brief start singletone.
+ * @param channel_num - channel of singletone.
+ * @return none
+ * @retval void
+ */
+void single_tone_start(uint8_t channel_num)
+{
+ APP_PRINT_INFO0("Single Tone Start!");
+
+ T_SINGLE_TONE_VEND_CMD_PARAMS *p_vend_cmd_params = os_mem_alloc(RAM_TYPE_DATA_ON,
+ sizeof(T_SINGLE_TONE_VEND_CMD_PARAMS));
+
+ if (p_vend_cmd_params)
+ {
+ p_vend_cmd_params->pkt_type = 1;
+ p_vend_cmd_params->opcode = 0xfc78;
+ p_vend_cmd_params->length = 4;
+ p_vend_cmd_params->start = 1;
+ p_vend_cmd_params->channel = channel_num;
+ /** note:
+ * tx_power config:
+ * 0x10/(-20dBm), 0x60/0dBm, 0xA0/3dBm,
+ * 0xB0/4dBm, 0xE0/7.5dBm(only for rtl876x)
+ */
+ p_vend_cmd_params->tx_power = 0x60;
+ p_vend_cmd_params->is_le = 1;
+
+ hci_if_write((uint8_t *)p_vend_cmd_params, sizeof(T_SINGLE_TONE_VEND_CMD_PARAMS));
+
+ single_tone_is_sent_start_cmd = true;
+ }
+}
+
+/******************************************************************
+ * @brief HCI callback of single tone handler.
+ * @param evt - single tone event
+ * @param status
+ * @param p_buf - point to hci buf
+ * @param len - buf length
+ * @return result
+ * @retval true or false
+ */
+bool single_tone_handle_hci_cb(T_SINGLE_TONE_EVT evt, bool status, uint8_t *p_buf,
+ uint32_t len)
+{
+ bool result = true;
+ uint8_t channel_num = 20; /* 2.442G */
+
+ APP_PRINT_INFO1("[single_tone_handle_hci_cb] evt is %d", evt);
+
+ switch (evt)
+ {
+ case SINGLE_TONE_EVT_OPENED:
+ if (!single_tone_is_sent_restart_cmd)
+ {
+ single_tone_reset(channel_num);
+ }
+ break;
+
+ case SINGLE_TONE_EVT_CLOSED:
+ break;
+
+ case SINGLE_TONE_EVT_DATA_IND:
+ hci_if_confirm(p_buf);
+ if (!single_tone_is_sent_start_cmd)
+ {
+ single_tone_start(channel_num);
+ }
+ break;
+
+ case SINGLE_TONE_EVT_DATA_XMIT:
+ os_mem_free(p_buf);
+ break;
+
+ case SINGLE_TONE_EVT_ERROR:
+ break;
+
+ default:
+ break;
+ }
+ return (result);
+}
+
+/******************************************************************
+ * @brief single tone task
+ * @param p_param
+ * @return none
+ * @retval void
+ */
+void single_tone_task(void *p_param)
+{
+ os_delay(100);
+ hci_if_open(single_tone_handle_hci_cb);
+
+ while (1)
+ {
+ os_delay(1000);
+ }
+}
+
+#if EXIT_SINGLE_TONE_TEST_WHEN_TIMEOUT
+/******************************************************************
+ * @brief single tone exit timer callback
+ * @param p_timer
+ * @return none
+ * @retval void
+ */
+void single_tone_exit_timeout_cb(TimerHandle_t p_timer)
+{
+ WDG_SystemReset(RESET_ALL, SINGLE_TONE_TIMEOUT_RESET);
+}
+#endif
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief single tone module init
+ * @param none
+ * @return none
+ * @retval void
+ */
+void single_tone_init(void)
+{
+ APP_PRINT_INFO0("Single Tone Init");
+
+#if EXIT_SINGLE_TONE_TEST_WHEN_TIMEOUT
+ if (true == os_timer_create(&single_tone_exit_timer, "single_tone_exit_timer", 1,
+ EXIT_SINGLE_TONE_TIME, false, single_tone_exit_timeout_cb))
+ {
+ os_timer_start(&single_tone_exit_timer);
+ }
+#endif
+
+ os_task_create(&single_tone_task_handle, "single_tone", single_tone_task, 0, 512, 1);
+}
+#endif
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/app/google_rcu/test_module/single_tone.h b/src/app/google_rcu/test_module/single_tone.h
new file mode 100644
index 0000000..19747ab
--- /dev/null
+++ b/src/app/google_rcu/test_module/single_tone.h
@@ -0,0 +1,57 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2014, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file single_tone.h
+* @brief single tone test defines.
+* @details none.
+* @author Chenjie Jin
+* @date 2018-05-30
+* @version v2.0
+* *********************************************************************************************************
+*/
+
+#ifndef _BEE_SINGLETONE_H_
+#define _BEE_SINGLETONE_H_
+
+#include "stdbool.h"
+#include "stdint.h"
+
+typedef enum
+{
+ SINGLE_TONE_EVT_OPENED, /* single tone open completed */
+ SINGLE_TONE_EVT_CLOSED, /* single tone close completed */
+ SINGLE_TONE_EVT_DATA_IND, /* single tone rx data indicated */
+ SINGLE_TONE_EVT_DATA_XMIT, /* single tone tx data transmitted */
+ SINGLE_TONE_EVT_ERROR, /* single tone error occurred */
+} T_SINGLE_TONE_EVT;
+
+#pragma pack(1)
+typedef struct
+{
+ uint8_t pkt_type;
+ uint16_t opcode;
+ uint8_t length;
+ uint8_t start;
+ uint8_t channel;
+ uint8_t tx_power;
+ uint8_t is_le;
+} T_SINGLE_TONE_VEND_CMD_PARAMS;
+#pragma pack()
+
+typedef bool (*P_SINGLE_TONE_CALLBACK)(T_SINGLE_TONE_EVT evt, bool status, uint8_t *p_buf,
+ uint32_t len);
+
+extern bool hci_if_open(P_SINGLE_TONE_CALLBACK p_callback);
+
+extern bool hci_if_close(void);
+
+extern bool hci_if_write(uint8_t *p_buf, uint32_t len);
+
+extern bool hci_if_confirm(uint8_t *p_buf);
+
+/* export functions */
+void single_tone_init(void);
+
+#endif /* _BEE_SINGLETONE_H_ */
+
diff --git a/src/app/google_rcu/test_module/uart_transport.c b/src/app/google_rcu/test_module/uart_transport.c
new file mode 100644
index 0000000..736a718
--- /dev/null
+++ b/src/app/google_rcu/test_module/uart_transport.c
@@ -0,0 +1,463 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file uart_transport.c
+* @brief This file provides uart transport layer driver for rcu uart test.
+* @details
+* @author chenjie_jin
+* @date 2020-03-03
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <board.h>
+#include <uart_transport.h>
+#include <data_uart_test.h>
+#include <rtl876x_uart.h>
+#include <rtl876x_pinmux.h>
+#include <rtl876x_rcc.h>
+#include <rtl876x_nvic.h>
+#include <loop_queue.h>
+#include <app_task.h>
+#include <app_section.h>
+
+#if MP_TEST_MODE_SUPPORT_DATA_UART_TEST
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/* Protocol defines ------------------------------------------------------------*/
+/* Protocol header define */
+#define PACKET_HEAD ((uint8_t)0x87)
+#define PACKET_HEAD_LEN ((uint8_t)0x01)
+#define OPCODE_LEN ((uint8_t)0x02)
+#define CRC_DATA_LEN ((uint16_t)0x02)
+/* Configure data uart receive trigger level */
+#define UART_RX_TRIGGER_LEVEL 4
+#define UART_RX_TRIGGER_VALUE 4
+
+#define FAR
+typedef unsigned char UCHAR, BYTE, * PUCHAR, * PBYTE;
+typedef unsigned short WORD, USHORT, * PUSHORT, * PWORD;
+typedef unsigned char FAR *LPBYTE;
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+static T_LOOP_QUEUE_DEF *p_uart_loop_queue = NULL;
+/* UART packet data structure */
+static T_UART_PACKET_DEF uart_packet;
+/* CRC check function */
+extern uint16_t btxfcs(WORD fcs, BYTE FAR *cp, WORD len);
+
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+static void uart_packet_struct_init(T_UART_PACKET_DEF *p_packet);
+static void data_uart_test_interrupt_handler(void);
+
+static void data_uart_test_interrupt_handler(void) DATA_RAM_FUNCTION;
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief Initializes UART packet data structure.
+ * @param p_packet - point to UART packet structure.
+ * @return none
+ * @retval void
+ */
+void uart_packet_struct_init(T_UART_PACKET_DEF *p_packet)
+{
+ /* Initialize UART packet data structure */
+ p_packet->buf_index = 0;
+ p_packet->crc_len = 0;
+ p_packet->payload_len = 0;
+ p_packet->uart_status = WaitHeader;
+}
+
+/******************************************************************
+ * @brief Data UART interrupt handle.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void data_uart_test_interrupt_handler(void)
+{
+ /* read interrupt id */
+ uint32_t int_status = UART_GetIID(UART0);
+
+ UART_DBG_BUFFER(MODULE_UART, LEVEL_INFO, "[data_uart_test_interrupt_handler] int_status = %d", 1,
+ int_status);
+
+ /* disable interrupt */
+ UART_INTConfig(UART0, UART_INT_RD_AVA | UART_INT_RX_LINE_STS, DISABLE);
+
+ if (UART_GetFlagStatus(UART0, UART_FLAG_RX_IDLE) == SET)
+ {
+ //clear Flag
+ UART_INTConfig(UART0, UART_INT_RX_IDLE, DISABLE);
+ /* Send Msg to App task */
+ T_IO_MSG uart_test_msg;
+ uart_test_msg.type = IO_MSG_TYPE_UART;
+ uart_test_msg.subtype = IO_MSG_UART_RX;
+ uart_test_msg.u.buf = (void *)(&uart_packet);
+
+ if (false == app_send_msg_to_apptask(&uart_test_msg))
+ {
+ APP_PRINT_ERROR0("[data_uart_test_interrupt_handler] Send IO_MSG_TYPE_UART message failed!");
+ }
+ //enable idle interrupt again
+ UART_ClearRxFIFO(UART0);
+ UART_INTConfig(UART0, UART_INT_RX_IDLE, ENABLE);
+ }
+
+ switch (int_status)
+ {
+ /* tx fifo empty, not enable */
+ case UART_INT_ID_TX_EMPTY:
+ {
+ /* do nothing */
+ break;
+ }
+
+ /* rx data valiable */
+ case UART_INT_ID_RX_LEVEL_REACH:
+ {
+ uint8_t temp_buf[UART_RX_TRIGGER_VALUE];
+ UART_ReceiveData(UART0, temp_buf, UART_RX_TRIGGER_VALUE);
+ if (!loop_queue_is_full(p_uart_loop_queue, UART_RX_TRIGGER_VALUE))
+ {
+ loop_queue_write_buf(p_uart_loop_queue, temp_buf, UART_RX_TRIGGER_VALUE, true);
+ }
+ break;
+ }
+
+ /* rx time out */
+ case UART_INT_ID_RX_DATA_TIMEOUT:
+ {
+ uint8_t temp_data;
+ while (UART_GetFlagStatus(UART0, UART_FLAG_RX_DATA_AVA) == SET)
+ {
+ UART_ReceiveData(UART0, &temp_data, 1);
+ if (!loop_queue_is_full(p_uart_loop_queue, 1))
+ {
+ loop_queue_write_buf(p_uart_loop_queue, &temp_data, 1, true);
+ }
+ }
+ break;
+ }
+
+ /* receive line status interrupt */
+ case UART_INT_ID_LINE_STATUS:
+ {
+ UART_GetFlagStatus(UART0, UART_FLAG_RX_OVERRUN);
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "line status error!", 0);
+ break;
+ }
+
+ default:
+ break;
+ }
+ /* enable interrupt again */
+ UART_INTConfig(UART0, UART_INT_RD_AVA | UART_INT_RX_LINE_STS, ENABLE);
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief Initializes UART peripheral.
+ * @param buadrate_opt - buadrate value.
+ * @return none
+ * @retval void
+ */
+void data_uart_init(uint8_t buadrate_opt)
+{
+ /* pinmux configuration */
+ UART_DeInit(UART0);
+ Pinmux_Config(MP_TEST_UART_TX_PIN, UART0_TX);
+ Pinmux_Config(MP_TEST_UART_RX_PIN, UART0_RX);
+
+
+ /* pad configuration */
+ Pad_Config(MP_TEST_UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+ Pad_Config(MP_TEST_UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+
+ /* turn on UART clock */
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ /* uart init */
+ UART_InitTypeDef uartInitStruct;
+ UART_StructInit(&uartInitStruct);
+ uartInitStruct.UART_RxThdLevel = UART_RX_TRIGGER_LEVEL;
+
+ if (buadrate_opt == CHANGE_BAUDRATE_OPTION_1M)
+ {
+ /* set baudrate to 1M */
+ uartInitStruct.UART_Div = 4;
+ uartInitStruct.UART_Ovsr = 5;
+ uartInitStruct.UART_OvsrAdj = 0;
+ uartInitStruct.UART_Parity = UART_PARITY_NO_PARTY;
+ }
+ else if (buadrate_opt == CHANGE_BAUDRATE_OPTION_2M)
+ {
+ /* set baudrate to 2M */
+ uartInitStruct.UART_Div = 2;
+ uartInitStruct.UART_Ovsr = 5;
+ uartInitStruct.UART_OvsrAdj = 0;
+ uartInitStruct.UART_Parity = UART_PARITY_NO_PARTY;
+ }
+ else
+ {
+ /* set baudrate to 115200 */
+ uartInitStruct.UART_Div = 20;
+ uartInitStruct.UART_Ovsr = 12;
+ uartInitStruct.UART_OvsrAdj = 0x252;
+ uartInitStruct.UART_Parity = UART_PARITY_NO_PARTY;
+ }
+
+ UART_Init(UART0, &uartInitStruct);
+
+ /* NVIC init */
+ UART_INTConfig(UART0, UART_INT_RD_AVA | UART_INT_RX_LINE_STS | UART_INT_RX_IDLE, ENABLE);
+ NVIC_ClearPendingIRQ(UART0_IRQn);
+
+ /* Enable UART IRQ */
+ NVIC_InitTypeDef nvic_init_struct;
+ nvic_init_struct.NVIC_IRQChannel = UART0_IRQn;
+ nvic_init_struct.NVIC_IRQChannelCmd = ENABLE;
+ nvic_init_struct.NVIC_IRQChannelPriority = 5;
+ NVIC_Init(&nvic_init_struct);
+}
+
+/******************************************************************
+ * @brief Initializes loop queue and UART packet data structure to their default reset values.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void data_uart_transport_init(void)
+{
+ /* Initialize loop queue */
+ if (p_uart_loop_queue == NULL)
+ {
+ p_uart_loop_queue = loop_queue_init(UART_LOOP_QUEUE_MAX_SIZE, sizeof(uint8_t), RAM_TYPE_DATA_ON);
+ }
+
+ /* Initialize UART packet data structure */
+ uart_packet_struct_init(&uart_packet);
+
+ /* Update Data UART interrupt handle */
+ RamVectorTableUpdate(Uart0_VECTORn, data_uart_test_interrupt_handler);
+
+ /* Initialize Data UART peripheral */
+ data_uart_init(CHANGE_BAUDRATE_OPTION_115200);
+}
+
+/******************************************************************
+ * @brief decode uart packet.
+ * @param p_queue_struct - point to loop queue data structure.
+ * @param p_packet - point to UART packet struct.
+ * @return result
+ * @retval true or false
+ */
+static bool uart_packet_decode(T_LOOP_QUEUE_DEF *p_queue_struct, T_UART_PACKET_DEF *p_packet)
+{
+ bool is_paket_complete = false;
+ uint16_t opcode = 0;
+ uint8_t param_len = 0;
+ uint8_t *p_loop_buf = (uint8_t *)p_queue_struct->p_buf;
+
+ UART_DBG_BUFFER(MODULE_UART, LEVEL_INFO, "[uart_packet_decode] decode uart packet", 0);
+ UART_DBG_BUFFER(MODULE_UART, LEVEL_INFO, "[uart_packet_decode] %d %d", 2,
+ p_queue_struct->read_index,
+ p_queue_struct->write_index);
+
+ while (p_queue_struct->read_index != p_queue_struct->write_index)
+ {
+ switch (p_packet->uart_status)
+ {
+ case WaitHeader:
+ {
+ /* Header: one byte */
+ if (p_loop_buf[p_queue_struct->read_index] == PACKET_HEAD)
+ {
+ if (true == loop_queue_read_buf(p_queue_struct, &p_packet->uart_buf[p_packet->buf_index], 1))
+ {
+ p_packet->buf_index++;
+ }
+ p_packet->uart_status = WaitCMD;
+ }
+ else
+ {
+ p_queue_struct->read_index++;
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "Error header = 0x%x!", 1,
+ p_loop_buf[p_queue_struct->read_index]);
+ }
+ break;
+ }
+ case WaitCMD:
+ {
+ while (!loop_queue_is_empty(p_uart_loop_queue))
+ {
+ /* Obtain command field data */
+ if (true == loop_queue_read_buf(p_queue_struct, &p_packet->uart_buf[p_packet->buf_index], 1))
+ {
+ p_packet->buf_index++;
+ }
+
+ /* CMD: two bytes */
+ if (p_packet->buf_index == (PACKET_HEAD_LEN + OPCODE_LEN))
+ {
+ opcode = (p_packet->uart_buf[p_packet->buf_index - 1] << 8) + p_packet->uart_buf[p_packet->buf_index
+ - 2];
+
+ if ((opcode >= UART_FN_BEGIN) && (opcode < UART_FN_END))
+ {
+ param_len = uart_test_func_map[opcode & UART_FN_MASK].param_len;
+ }
+ else
+ {
+ param_len = 0;
+ }
+ p_packet->uart_status = WaitParams;
+ break;
+ }
+ }
+ break;
+ }
+
+ case WaitParams:
+ {
+ /* Obtain parameter field data */
+ if (true == loop_queue_read_buf(p_queue_struct, &p_packet->uart_buf[p_packet->buf_index],
+ param_len))
+ {
+ p_packet->buf_index += param_len;
+ }
+ p_packet->uart_status = WaitCRC;
+ break;
+ }
+
+ case WaitCRC:
+ {
+ uint16_t vailid_data_size = loop_queue_get_vailid_data_size(p_uart_loop_queue);
+ if ((vailid_data_size != 0) && (p_packet->crc_len < CRC_DATA_LEN))
+ {
+ if (vailid_data_size >= CRC_DATA_LEN - p_packet->crc_len)
+ {
+ if (true == loop_queue_read_buf(p_queue_struct, &p_packet->uart_buf[p_packet->buf_index],
+ CRC_DATA_LEN - p_packet->crc_len))
+ {
+ p_packet->buf_index += CRC_DATA_LEN - p_packet->crc_len;
+ }
+ }
+ else
+ {
+ if (true == loop_queue_read_buf(p_queue_struct, &p_packet->uart_buf[p_packet->buf_index],
+ vailid_data_size))
+ {
+ p_packet->buf_index += vailid_data_size;
+ }
+ }
+ }
+
+ /* CRC check */
+ if (btxfcs(0, p_packet->uart_buf,
+ (p_packet->buf_index) - CRC_DATA_LEN) == ((p_packet->uart_buf[p_packet->buf_index
+ - 1] << 8) + p_packet->uart_buf[p_packet->buf_index - 2]))
+ {
+ is_paket_complete = true;
+ }
+ else
+ {
+ /* CRC check error */
+ UART_DBG_BUFFER(MODULE_APP, LEVEL_ERROR, "CRC check Error!", 0);
+ }
+
+ /* Reset decoding status */
+ uart_packet_struct_init(p_packet);
+ return is_paket_complete;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ return is_paket_complete;
+}
+
+/******************************************************************
+ * @brief Response of uart command.
+ * @param opcode
+ * @param status
+ * @param p_payload - point to payload of uart response.
+ * @param payload_length - length of payload.
+ * @return none
+ * @retval void
+ */
+void data_uart_cmd_response(uint16_t opcode, uint8_t status, uint8_t *p_payload,
+ uint32_t payload_length)
+{
+ T_UART_PACKET_DEF response_packet;
+ T_UART_PACKET_DEF *p_resp_packet = &response_packet;
+
+ p_resp_packet->buf_index = 0;
+ p_resp_packet->uart_buf[p_resp_packet->buf_index++] = PACKET_HEAD;
+ p_resp_packet->uart_buf[p_resp_packet->buf_index++] = opcode & 0xff;
+ p_resp_packet->uart_buf[p_resp_packet->buf_index++] = opcode >> 8;
+ p_resp_packet->uart_buf[p_resp_packet->buf_index++] = status;
+ p_resp_packet->uart_buf[p_resp_packet->buf_index++] = payload_length & 0xff;
+ p_resp_packet->uart_buf[p_resp_packet->buf_index++] = payload_length >> 8;
+ p_resp_packet->uart_buf[p_resp_packet->buf_index++] = payload_length >> 16;
+ p_resp_packet->uart_buf[p_resp_packet->buf_index++] = payload_length >> 24;
+
+ while (payload_length--)
+ {
+ p_resp_packet->uart_buf[p_resp_packet->buf_index++] = *p_payload++;
+ }
+
+ /* Add CRC data */
+ uint16_t crc_calc = btxfcs(0, p_resp_packet->uart_buf, p_resp_packet->buf_index);
+ p_resp_packet->uart_buf[p_resp_packet->buf_index++] = (uint8_t)(crc_calc & 0xff);
+ p_resp_packet->uart_buf[p_resp_packet->buf_index++] = (uint8_t)(crc_calc >> 8);
+
+ /* send block bytes(16 bytes) */
+ uint32_t i = 0;
+ for (i = 0; i < (p_resp_packet->buf_index / UART_TX_FIFO_SIZE); i++)
+ {
+ UART_SendData(UART0, &(p_resp_packet->uart_buf[UART_TX_FIFO_SIZE * i]), UART_TX_FIFO_SIZE);
+ /* wait tx fifo empty */
+ while (UART_GetFlagStatus(UART0, UART_FLAG_TX_EMPTY) != SET);
+ }
+
+ /* send left bytes */
+ UART_SendData(UART0, &(p_resp_packet->uart_buf[UART_TX_FIFO_SIZE * i]),
+ p_resp_packet->buf_index % UART_TX_FIFO_SIZE);
+ /* wait tx fifo empty */
+ while (UART_GetFlagStatus(UART0, UART_FLAG_TX_EMPTY) != SET);
+}
+
+/******************************************************************
+ * @brief decode uart packet.
+ * @param p_packet - point to UART packet struct.
+ * @return result
+ * @retval true or false
+ */
+bool data_uart_packet_decode(T_UART_PACKET_DEF *p_packet)
+{
+ return uart_packet_decode(p_uart_loop_queue, p_packet);
+}
+#endif
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/test_module/uart_transport.h b/src/app/google_rcu/test_module/uart_transport.h
new file mode 100644
index 0000000..989016f
--- /dev/null
+++ b/src/app/google_rcu/test_module/uart_transport.h
@@ -0,0 +1,77 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file uart_transport.h
+* @brief
+* @details
+* @author chenjie jin
+* @date 2018-04-08
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __UART_TRANSPORT_H
+#define __UART_TRANSPORT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "board.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include "trace.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/* Enable print log or not */
+#define UART_PRINT_LOG
+
+/* Configure loop queue parameters */
+#define UART_LOOP_QUEUE_MAX_SIZE 512
+
+/* Configure UART packet buffer length */
+#define CMD_SIZE 50
+
+#ifdef UART_PRINT_LOG
+#define UART_DBG_BUFFER(MODULE, LEVEL, fmt, para_num,...) DBG_BUFFER_##LEVEL(TYPE_BEE2, SUBTYPE_FORMAT, MODULE, fmt, para_num, ##__VA_ARGS__)
+#else
+#define UART_DBG_BUFFER(MODULE, LEVEL, fmt, para_num,...) ((void)0)
+#endif
+
+/* Packet decode status */
+typedef enum
+{
+ WaitHeader,
+ WaitCMD,
+ WaitParams,
+ WaitCRC,
+} T_UART_WAIT_STATE;
+
+/* UART packet data structure */
+typedef struct t_uart_packet_def
+{
+ uint8_t uart_buf[CMD_SIZE]; /* command buffer */
+ uint16_t buf_index; /* index of buffer */
+ uint16_t payload_len; /* length of decoder payload */
+ uint16_t crc_len; /* index of CRC */
+ T_UART_WAIT_STATE uart_status; /* status of decoding */
+
+} T_UART_PACKET_DEF;
+
+void data_uart_init(uint8_t buadrate_opt);
+void data_uart_transport_init(void);
+bool data_uart_packet_decode(T_UART_PACKET_DEF *p_packet);
+void data_uart_cmd_response(uint16_t opcode, uint8_t status, uint8_t *p_payload,
+ uint32_t payload_length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__UART_TRANSPORT_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/voice_module/voice.c b/src/app/google_rcu/voice_module/voice.c
new file mode 100644
index 0000000..c9bcc5b
--- /dev/null
+++ b/src/app/google_rcu/voice_module/voice.c
@@ -0,0 +1,1081 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file voice.c
+* @brief This is the entry of user code which the voice module resides in.
+* @details
+* @author
+* @date 2020-03-05
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <trace.h>
+#include <string.h>
+#include <rtl876x_pinmux.h>
+#include "board.h"
+#include "voice.h"
+#include "voice_driver.h"
+#include "profile_server.h"
+#include "profile_server.h"
+#include "app_msg.h"
+#include "rcu_application.h"
+#include <app_section.h>
+#include "swtimer.h"
+#include "key_handle.h"
+#include "os_timer.h"
+#include "loop_queue.h"
+#include "led_driver.h"
+#include "ima_adpcm_enc.h"
+#include "atvv_service.h"
+
+#if SUPPORT_VOICE_FEATURE
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+/* voice_exception_timer is used to detect audio transfer and active remote exception*/
+static TimerHandle_t voice_exception_timer = NULL;
+
+static T_LOOP_QUEUE_DEF *p_voice_queue;
+
+/*============================================================================*
+ * Global Variables
+ *============================================================================*/
+T_VOICE_GLOBAL_DATA voice_global_data;
+
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+static void voice_handle_init_data(void);
+static void voice_handle_init_encode_param(void);
+static void voice_handle_deinit_encode_param(void);
+static bool voice_handle_notify_voice_data(void);
+static void voice_handle_encode_raw_data(uint8_t *p_input_data, int32_t input_size,
+ uint8_t *p_output_data, int32_t *p_output_size);
+static void voice_handle_gdma_event(T_IO_MSG io_driver_msg_recv);
+static void voice_handle_exception_timer_cb(TimerHandle_t p_timer) DATA_RAM_FUNCTION;
+bool voice_handle_start_mic(void);
+void voice_handle_stop_mic(void);
+bool voice_handle_atvv_audio_start(ATV_AUDIO_START_REASON reason);
+bool voice_handle_atvv_audio_stop(ATV_AUDIO_STOP_REASON reason);
+bool voice_handle_atvv_mic_open_error(ATV_MIC_OPEN_ERROR reason);
+void voice_handle_atvv_init_data(void);
+static void voice_handle_atv_audio_sync(uint16_t seq_id, uint16_t val_prev, uint8_t index);
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief Initialize voice handle data.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_handle_init_data(void)
+{
+ APP_PRINT_INFO0("[voice_handle_init_data] init data");
+ memset(&voice_global_data, 0, sizeof(voice_global_data));
+}
+
+/******************************************************************
+ * @brief init voice encode parameters.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_handle_init_encode_param(void)
+{
+ voice_global_data.is_encoder_init = false;
+ memset(&ima_adpcm_global_state, 0, sizeof(ima_adpcm_global_state));
+ voice_global_data.is_encoder_init = true;
+}
+
+/******************************************************************
+ * @brief deinit voice encode parameters.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_handle_deinit_encode_param(void)
+{
+ if (voice_global_data.is_encoder_init == true)
+ {
+ voice_global_data.is_encoder_init = false;
+ }
+}
+
+/******************************************************************
+ * @brief voice handle out queue.
+ * @param none
+ * @return result
+ * @retval true or false
+ */
+bool voice_handle_notify_voice_data(void)
+{
+ bool result = false;
+ uint8_t gap_link_credits = 0;
+ uint8_t reserved_credits = 2;
+
+ if (atvv_global_data.app_support_version == ATVV_VERSION_1_0)
+ {
+ reserved_credits += 1; /* add one more for AUDIO_SYNC notification */
+ }
+
+ le_get_gap_param(GAP_PARAM_LE_REMAIN_CREDITS, &gap_link_credits);
+
+ if (p_voice_queue == NULL)
+ {
+ APP_PRINT_WARN0("[voice_handle_out_queue] Queue buffer is NOT initialiezed!");
+ result = false;
+ }
+ else if (loop_queue_is_empty(p_voice_queue) == true)
+ {
+ APP_PRINT_INFO0("[voice_handle_out_queue] Voice Queue is empty.");
+ result = false;
+ }
+ else if (gap_link_credits <=
+ reserved_credits) /* reserve at least notification FIFO for key event */
+ {
+ APP_PRINT_WARN1("[voice_handle_out_queue] gap_link_credits is not enough is %d!", gap_link_credits);
+ result = false;
+ }
+ else
+ {
+ uint32_t queue_item_cnt = loop_queue_get_vailid_data_size(p_voice_queue) / p_voice_queue->item_size;
+ uint32_t loop_cnt = (queue_item_cnt <= gap_link_credits - reserved_credits) ? queue_item_cnt :
+ (gap_link_credits - reserved_credits);
+
+ APP_PRINT_INFO3("[voice_handle_out_queue] gap_link_credits is %d, queue_item_cnt is %d, loop_cnt is %d",
+ gap_link_credits, queue_item_cnt, loop_cnt);
+
+ while ((loop_cnt > 0) && (loop_queue_is_empty(p_voice_queue) == false))
+ {
+ loop_cnt--;
+ /* attampt to send voice data */
+ uint8_t notify_data_len = p_voice_queue->item_size;
+ uint8_t *p_notify_buffer = os_mem_alloc(RAM_TYPE_DATA_ON, notify_data_len);
+
+ if ((p_notify_buffer != NULL) &&
+ (true == (loop_queue_copy_buf(p_voice_queue, p_notify_buffer, p_voice_queue->item_size))))
+ {
+ if (atvv_global_data.app_support_version == ATVV_VERSION_1_0)
+ {
+ uint16_t seq_id = ((uint16_t)p_notify_buffer[0] << 8) + p_notify_buffer[1];
+ if (seq_id % (VOICE_AUDIO_SYNC_PERIOD + 1) == VOICE_AUDIO_SYNC_PERIOD)
+ {
+ uint16_t val_prev = ((uint16_t)p_notify_buffer[3] << 8) + p_notify_buffer[4];
+ uint8_t frame_index = p_notify_buffer[5];
+ voice_handle_atv_audio_sync(seq_id, val_prev, frame_index);
+ }
+
+ result = server_send_data(0, app_global_data.atvv_srv_id, GATT_SVC_ATVV_CHAR_RX_VALUE_INDEX, \
+ p_notify_buffer + VOICE_FRAME_HEADER_SIZE, notify_data_len - VOICE_FRAME_HEADER_SIZE,
+ GATT_PDU_TYPE_NOTIFICATION);
+ }
+ else
+ {
+ result = server_send_data(0, app_global_data.atvv_srv_id, GATT_SVC_ATVV_CHAR_RX_VALUE_INDEX, \
+ p_notify_buffer, notify_data_len, GATT_PDU_TYPE_NOTIFICATION);
+ }
+
+ if (result == true)
+ {
+ result = loop_queue_read_buf(p_voice_queue, p_notify_buffer, p_voice_queue->item_size);
+ }
+
+ os_mem_free(p_notify_buffer);
+ }
+ else
+ {
+ result = false;
+ }
+ }
+ }
+
+ return result;
+}
+
+/******************************************************************
+ * @brief voice handle encode raw datae.
+ * @param p_input_data - point of input data
+ * @param input_size - input size
+ * @param p_output_data - point of output data
+ * @param p_output_size - point of output size
+ * @return none
+ * @retval void
+ */
+void voice_handle_encode_raw_data(uint8_t *p_input_data, int32_t input_size,
+ uint8_t *p_output_data, int32_t *p_output_size)
+{
+ int32_t tmp_size;
+ p_output_data[0] = (uint8_t)(ima_adpcm_global_state.seq_id >> 8);//cppcheck-suppress [ctuArrayIndex]
+ p_output_data[1] = (uint8_t)(ima_adpcm_global_state.seq_id);
+ ima_adpcm_global_state.seq_id++;
+ p_output_data[2] = 0;
+ p_output_data[3] = (uint8_t)(ima_adpcm_global_state.valprev >> 8);
+ p_output_data[4] = (uint8_t) ima_adpcm_global_state.valprev;
+ p_output_data[5] = ima_adpcm_global_state.index;
+
+ tmp_size = ima_adpcm_encode((void *)p_input_data, &p_output_data[VOICE_FRAME_HEADER_SIZE],
+ VOICE_PCM_FRAME_SIZE / 2,
+ &ima_adpcm_global_state);
+ *p_output_size = tmp_size + VOICE_FRAME_HEADER_SIZE;
+
+ APP_PRINT_INFO1("[voice_handle_encode_raw_data] *p_output_size = %d", *p_output_size);
+}
+
+/******************************************************************
+ * @brief voice handle GDMA evnet.
+ * @param io_driver_msg_recv - gdma message
+ * @return none
+ * @retval void
+ */
+void voice_handle_gdma_event(T_IO_MSG io_driver_msg_recv)
+{
+ if (!voice_driver_global_data.is_voice_driver_working)
+ {
+ return;
+ }
+
+ int32_t output_size = 0;
+ uint8_t encode_output_buffer[p_voice_queue->item_size];
+
+ /* skip first several GMDA interrupts, to wait codec stable */
+ if (voice_global_data.voice_gdma_int_cnt < VOICE_GDMA_INT_SKIP_CNT)
+ {
+ voice_global_data.voice_gdma_int_cnt++;
+ return;
+ }
+
+ if (true == voice_global_data.is_pending_to_stop_recording)
+ {
+ if ((loop_queue_is_empty(p_voice_queue) == true) ||
+ (voice_global_data.is_allowed_to_notify_voice_data == false))
+ {
+ /* voice buffer data has all been sent after voice key up */
+ if (ATV_ASSISTANT_INTERACTION_MODEL_HOLD_TO_TALK == atvv_global_data.assistant_interaction_model)
+ {
+ voice_handle_atvv_audio_stop(ATV_STOP_REASON_HTT);
+ }
+ }
+ else
+ {
+ voice_handle_notify_voice_data();
+ }
+ }
+ else if (voice_global_data.is_encoder_init == true)
+ {
+ /* encode raw data */
+ voice_handle_encode_raw_data(io_driver_msg_recv.u.buf, VOICE_GDMA_FRAME_SIZE, encode_output_buffer,
+ &output_size);
+
+ if (output_size == p_voice_queue->item_size)
+ {
+ /* set is_overflow_data_abandoned to false, to drop oldest data if queue is full */
+ loop_queue_write_buf(p_voice_queue, encode_output_buffer, p_voice_queue->item_size, false);
+
+ if (voice_global_data.is_allowed_to_notify_voice_data == true)
+ {
+ voice_handle_notify_voice_data();
+ }
+ else
+ {
+ APP_PRINT_INFO0("[voice_handle_gdma_event] not allowed to notify voice data");
+ }
+ }
+ else
+ {
+ APP_PRINT_WARN2("[voice_handle_gdma_event] encode failed %d %d", output_size,
+ p_voice_queue->item_size);
+ }
+ }
+ else
+ {
+ APP_PRINT_WARN0("[voice_handle_gdma_event] Encoder is NOT initialized");
+ }
+}
+
+/******************************************************************
+ * @brief voice exception timer callback.
+ * @param p_timer - point of timer
+ * @return none
+ * @retval void
+ * @note do NOT execute time consumption functions in timer callback
+ */
+void voice_handle_exception_timer_cb(TimerHandle_t p_timer)
+{
+ if (voice_driver_global_data.is_voice_driver_working == true)
+ {
+ APP_PRINT_INFO0("[voice_handle_exception_timer_cb] audio transfer timeout");
+ voice_handle_atvv_audio_stop(ATV_STOP_REASON_AUDIO_TRANSFER_TIMEOUT);
+ }
+ else
+ {
+ APP_PRINT_INFO0("[voice_handle_exception_timer_cb] active remote timeout");
+ voice_handle_atvv_mic_open_error(ATV_MIC_OPEN_ERROR_REMOTE_IS_NOT_ACTIVE);
+ app_set_latency_status(LATENCY_VOICE_PROC_BIT, LANTENCY_ON);
+ }
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief voice handle start mic and recording.
+ * @param none
+ * @return result
+ * @retval true or false
+ */
+bool voice_handle_start_mic(void)
+{
+ uint16_t item_size = 0;
+ uint16_t queue_size = 0;
+
+ if (voice_driver_global_data.is_voice_driver_working == true)
+ {
+ APP_PRINT_INFO0("[voice_handle_start_mic] Voice driver is working, start failed!");
+ return false;
+ }
+
+ APP_PRINT_INFO0("[voice_handle_start_mic] start recording!");
+
+ voice_handle_init_data();
+ voice_handle_init_encode_param();
+ item_size = VOICE_REPORT_FRAME_SIZE;
+ if (item_size == 0)
+ {
+ APP_PRINT_WARN0("[voice_handle_start_mic] Invalid item_size!");
+ return false;
+ }
+ queue_size = VOICE_QUEUE_MAX_BUFFER_SIZE / item_size;
+ p_voice_queue = loop_queue_init(queue_size, item_size, RAM_TYPE_DATA_ON);
+
+ voice_driver_init();
+
+ return true;
+}
+
+/******************************************************************
+ * @brief voice handle stop mic and recording.
+ * @param none
+ * @return result
+ * @retval true or false
+ */
+void voice_handle_stop_mic(void)
+{
+ APP_PRINT_INFO0("[voice_handle_stop_mic] stop recording!");
+
+#if SUPPORT_LED_INDICATION_FEATURE
+ if (atvv_global_data.atv_start_reason == ATV_START_REASON_MIC_OPEN_REQUEST)
+ {
+ LED_BLINK_EXIT(LED_TYPE_BLINK_VOICE_ON_REQUEST);
+ }
+ else if (atvv_global_data.atv_start_reason == ATV_START_REASON_HTT)
+ {
+ LED_BLINK_EXIT(LED_TYPE_BLINK_VOICE_HTT);
+ }
+ else if (atvv_global_data.atv_start_reason == ATV_START_REASON_PTT)
+ {
+ LED_BLINK_EXIT(LED_TYPE_BLINK_VOICE_PTT);
+ }
+#endif
+
+ if (voice_exception_timer)
+ {
+ os_timer_stop(&voice_exception_timer);
+ }
+
+ if (voice_driver_global_data.is_voice_driver_working == false)
+ {
+ APP_PRINT_INFO0("[voice_handle_stop_mic] Voice driver is not working, stop failed!");
+ }
+ else
+ {
+ voice_driver_deinit();
+ voice_handle_deinit_encode_param();
+ loop_queue_deinit(&p_voice_queue);
+ }
+}
+
+/******************************************************************
+ * @brief vocie key press msg handle.
+ * @param none
+ * @return result
+ * @retval true or false
+ */
+bool voice_handle_mic_key_pressed(void)
+{
+ bool ret = true;
+
+ if (true == voice_driver_global_data.is_voice_driver_working)
+ {
+ APP_PRINT_WARN0("[voice_handle_mic_key_pressed] Voice driver is Working, start recording failed!");
+ return false;
+ }
+
+ APP_PRINT_INFO1("[voice_handle_mic_key_pressed] assistant_interaction_model is %d",
+ atvv_global_data.assistant_interaction_model);
+
+ if (ATV_ASSISTANT_INTERACTION_MODEL_ON_REQUEST == atvv_global_data.assistant_interaction_model)
+ {
+ /* send ATV_CTL_OPCODE_START_SEARCH */
+ memset(atvv_global_data.char_ctl_data_buff, 0, ATVV_CHAR_CTL_DATA_LEN);
+ atvv_global_data.char_ctl_data_buff[0] = ATV_CTL_OPCODE_START_SEARCH;
+ server_send_data(0, app_global_data.atvv_srv_id, GATT_SVC_ATVV_CHAR_CTL_VALUE_INDEX,
+ atvv_global_data.char_ctl_data_buff, 1, GATT_PDU_TYPE_NOTIFICATION);
+
+ key_handle_notify_hid_key_event_by_index(KEY_ID_Assistant);
+ key_handle_notify_hid_release_event();
+
+ app_set_latency_status(LATENCY_VOICE_PROC_BIT,
+ LANTENCY_OFF); /* off latency to speed up voice process */
+ /* start voice exception timer */
+ if (voice_exception_timer == NULL)
+ {
+ if (true == os_timer_create(&voice_exception_timer, "voice_exception_timer", 1, \
+ VOICE_ACTIVE_REMOTE_TIMEOUT, false, voice_handle_exception_timer_cb))
+ {
+ os_timer_restart(&voice_exception_timer, VOICE_ACTIVE_REMOTE_TIMEOUT);
+ }
+ else
+ {
+ APP_PRINT_ERROR0("[voice_handle_mic_key_pressed] voice_exception_timer creat failed!");
+ }
+ }
+ else
+ {
+ os_timer_restart(&voice_exception_timer, VOICE_ACTIVE_REMOTE_TIMEOUT);
+ }
+ }
+ else if (ATV_ASSISTANT_INTERACTION_MODEL_PRESS_TO_TALK ==
+ atvv_global_data.assistant_interaction_model)
+ {
+ if (app_global_data.is_atv_voice_notify_en == true)
+ {
+ voice_handle_atvv_audio_start(ATV_START_REASON_PTT);
+ }
+ else
+ {
+ voice_handle_atvv_mic_open_error(ATV_MIC_OPEN_ERROR_ATVV_CHAR_AUDIO_IS_DISABLE);
+ ret = false;
+ }
+ }
+ else if (ATV_ASSISTANT_INTERACTION_MODEL_HOLD_TO_TALK ==
+ atvv_global_data.assistant_interaction_model)
+ {
+ if (app_global_data.is_atv_voice_notify_en == true)
+ {
+ voice_handle_atvv_audio_start(ATV_START_REASON_HTT);
+ }
+ else
+ {
+ voice_handle_atvv_mic_open_error(ATV_MIC_OPEN_ERROR_ATVV_CHAR_AUDIO_IS_DISABLE);
+ ret = false;
+ }
+ }
+
+ return ret;
+}
+
+/******************************************************************
+ * @brief vocie key release msg handle.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_handle_mic_key_released(void)
+{
+ if (voice_driver_global_data.is_voice_driver_working == false)
+ {
+ APP_PRINT_WARN0("[voice_handle_mic_key_released] Voice driver is not working!");
+ return;
+ }
+
+ if (ATV_START_REASON_MIC_OPEN_REQUEST ==
+ atvv_global_data.atv_start_reason)
+ {
+ key_handle_notify_hid_release_event();
+ }
+ else if (ATV_START_REASON_HTT ==
+ atvv_global_data.atv_start_reason)
+ {
+ if (loop_queue_is_empty(p_voice_queue) ||
+ (false == voice_global_data.is_allowed_to_notify_voice_data) ||
+ (p_voice_queue == NULL) ||
+ (app_global_data.mtu_size - 3 < p_voice_queue->item_size))
+ {
+ /* stop voice recording immediately */
+ voice_handle_atvv_audio_stop(ATV_STOP_REASON_HTT);
+ }
+ else
+ {
+ /* stop voice in queue, and wait for all buffered voice data send */
+ voice_global_data.is_pending_to_stop_recording = true;
+ }
+ }
+}
+
+/******************************************************************
+ * @brief Initialize atv global data.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_handle_atvv_init_data(void)
+{
+ APP_PRINT_INFO0("[voice_handle_atvv_init_data] init data");
+
+ memset(&atvv_global_data, 0, sizeof(T_ATVV_GLOBAL_DATA));
+ atvv_global_data.atv_start_reason = ATV_START_REASON_INVALID;
+
+#if (ATV_VOICE_VERSION == ATV_VERSION_1_0)
+ atvv_global_data.app_support_version = ATVV_VERSION_1_0;
+#elif (ATV_VOICE_VERSION == ATV_VERSION_0_4)
+ atvv_global_data.app_support_version = ATVV_VERSION_0_4;
+#endif
+
+ atvv_global_data.codec_support = ATTV_CODEC_MASK_8K_ADPCM | ATTV_CODEC_MASK_16K_ADPCM;
+
+#if (ATV_VOICE_INTERACTION_MODEL == ATV_INTERACTION_MODEL_ON_REQUEST)
+ atvv_global_data.assistant_interaction_model = ATV_ASSISTANT_INTERACTION_MODEL_ON_REQUEST;
+#elif (ATV_VOICE_INTERACTION_MODEL == ATV_INTERACTION_MODEL_PRESS_TO_TALK)
+ atvv_global_data.assistant_interaction_model = ATV_ASSISTANT_INTERACTION_MODEL_PRESS_TO_TALK;
+#elif (ATV_VOICE_INTERACTION_MODEL == ATV_INTERACTION_MODEL_HOLD_TO_TALK)
+ atvv_global_data.assistant_interaction_model = ATV_ASSISTANT_INTERACTION_MODEL_HOLD_TO_TALK;
+#endif
+}
+
+/******************************************************************
+ * @brief ATV voice handle start voice and response to master.
+ * @param none
+ * @return result
+ * @retval true or false
+ */
+bool voice_handle_atvv_audio_start(ATV_AUDIO_START_REASON reason)
+{
+ bool result = false;
+ uint8_t stream_id = 0;
+
+ APP_PRINT_INFO1("[voice_handle_atvv_audio_start] ATV_CTL_OPCODE_AUDIO_START, reason is 0x%x",
+ reason);
+
+ atvv_global_data.atv_start_reason = reason;
+
+ voice_handle_start_mic();
+
+ app_set_latency_status(LATENCY_VOICE_PROC_BIT, LANTENCY_OFF);
+ voice_global_data.is_allowed_to_notify_voice_data = true;
+
+ /* send Audio Start Notification */
+ memset(atvv_global_data.char_ctl_data_buff, 0, ATVV_CHAR_CTL_DATA_LEN);
+ atvv_global_data.char_ctl_data_buff[0] = ATV_CTL_OPCODE_AUDIO_START;
+ if (ATVV_VERSION_1_0 == atvv_global_data.app_support_version)
+ {
+ if (reason == ATV_START_REASON_MIC_OPEN_REQUEST)
+ {
+ stream_id = 0x00;
+ }
+ else
+ {
+ atvv_global_data.stream_id = (atvv_global_data.stream_id % 0x80) + 1;
+ stream_id = atvv_global_data.stream_id;
+ }
+ APP_PRINT_INFO1("[voice_handle_atvv_audio_start] rcu stream_id is 0x%x",
+ atvv_global_data.stream_id);
+ atvv_global_data.char_ctl_data_buff[1] = reason;
+ atvv_global_data.char_ctl_data_buff[2] = CODEC_SAMPLE_RATE_SEL;
+ atvv_global_data.char_ctl_data_buff[3] = stream_id;
+
+ atvv_global_data.codec_used = CODEC_SAMPLE_RATE_SEL;
+
+ result = server_send_data(0, app_global_data.atvv_srv_id, GATT_SVC_ATVV_CHAR_CTL_VALUE_INDEX,
+ atvv_global_data.char_ctl_data_buff, 4, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ else
+ {
+ result = server_send_data(0, app_global_data.atvv_srv_id, GATT_SVC_ATVV_CHAR_CTL_VALUE_INDEX,
+ atvv_global_data.char_ctl_data_buff, 1, GATT_PDU_TYPE_NOTIFICATION);
+ }
+
+
+ if (result == false)
+ {
+ APP_PRINT_WARN0("[voice_handle_atvv_audio_start] ATV_CTL_OPCODE_AUDIO_START notify failed!");
+ }
+
+ /* start voice exception timer */
+ if (voice_exception_timer == NULL)
+ {
+ if (true == os_timer_create(&voice_exception_timer, "voice_exception_timer", 1, \
+ VOICE_TRANSFER_TIMEOUT, false, voice_handle_exception_timer_cb))
+ {
+ os_timer_restart(&voice_exception_timer, VOICE_TRANSFER_TIMEOUT);
+ }
+ else
+ {
+ APP_PRINT_ERROR0("[voice_handle_mic_key_pressed] voice_exception_timer creat failed!");
+ }
+ }
+ else
+ {
+ os_timer_restart(&voice_exception_timer, VOICE_TRANSFER_TIMEOUT);
+ }
+#if SUPPORT_LED_INDICATION_FEATURE
+ if (result)
+ {
+ if (reason == ATV_START_REASON_MIC_OPEN_REQUEST)
+ {
+ LED_BLINK(LED_TYPE_BLINK_VOICE_ON_REQUEST, 0);
+ }
+ else if (reason == ATV_START_REASON_HTT)
+ {
+ LED_BLINK(LED_TYPE_BLINK_VOICE_HTT, 0);
+ }
+ else if (reason == ATV_START_REASON_PTT)
+ {
+ LED_BLINK(LED_TYPE_BLINK_VOICE_PTT, 0);
+ }
+ }
+#endif
+ return result;
+}
+
+/******************************************************************
+ * @brief ATV voice handle stop voice and response to master.
+ * @param none
+ * @return result
+ * @retval true or false
+ */
+bool voice_handle_atvv_audio_stop(ATV_AUDIO_STOP_REASON reason)
+{
+ bool notify_result = false;
+ APP_PRINT_INFO1("[voice_handle_atvv_audio_stop] ATV_CTL_OPCODE_AUDIO_STOP, reason is 0x%x", reason);
+ memset(atvv_global_data.char_ctl_data_buff, 0, ATVV_CHAR_CTL_DATA_LEN);
+ atvv_global_data.char_ctl_data_buff[0] = ATV_CTL_OPCODE_AUDIO_STOP;
+ if (ATVV_VERSION_1_0 == atvv_global_data.app_support_version)
+ {
+ atvv_global_data.char_ctl_data_buff[1] = reason;
+
+ notify_result = server_send_data(0, app_global_data.atvv_srv_id, GATT_SVC_ATVV_CHAR_CTL_VALUE_INDEX,
+ atvv_global_data.char_ctl_data_buff, 2, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ else
+ {
+ notify_result = server_send_data(0, app_global_data.atvv_srv_id, GATT_SVC_ATVV_CHAR_CTL_VALUE_INDEX,
+ atvv_global_data.char_ctl_data_buff, 1, GATT_PDU_TYPE_NOTIFICATION);
+ }
+
+ if (notify_result == false)
+ {
+ APP_PRINT_WARN0("[voice_handle_atvv_audio_stop] ATV_CTL_OPCODE_AUDIO_STOP notify failed!");
+ }
+ voice_global_data.is_allowed_to_notify_voice_data = false;
+ voice_handle_stop_mic();
+ app_set_latency_status(LATENCY_VOICE_PROC_BIT, LANTENCY_ON);
+
+ atvv_global_data.atv_start_reason = ATV_START_REASON_INVALID;
+
+ return notify_result;
+}
+
+/******************************************************************
+ * @brief ATV voice handle mic open error and response to master.
+ * @param none
+ * @return result
+ * @retval true or false
+ */
+bool voice_handle_atvv_mic_open_error(ATV_MIC_OPEN_ERROR reason)
+{
+ bool notify_result = false;
+ APP_PRINT_INFO1("[voice_handle_atvv_mic_open_error] MIC Open Error, reason is 0x%x!", reason);
+ memset(atvv_global_data.char_ctl_data_buff, 0, ATVV_CHAR_CTL_DATA_LEN);
+ atvv_global_data.char_ctl_data_buff[0] = ATV_CTL_OPCODE_MIC_OPEN_ERROR;
+ atvv_global_data.char_ctl_data_buff[1] = (uint8_t)(reason >> 8);
+ atvv_global_data.char_ctl_data_buff[2] = (uint8_t)reason;
+ notify_result = server_send_data(0, app_global_data.atvv_srv_id, GATT_SVC_ATVV_CHAR_CTL_VALUE_INDEX,
+ atvv_global_data.char_ctl_data_buff, 3, GATT_PDU_TYPE_NOTIFICATION);
+ if (notify_result == false)
+ {
+ APP_PRINT_WARN0("[voice_handle_atvv_mic_open_error] ATV_CTL_OPCODE_MIC_OPEN_ERROR notify failed!");
+ }
+ return notify_result;
+}
+
+/******************************************************************
+ * @brief send AUDIO_SYNC for ATV
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_handle_atv_audio_sync(uint16_t seq_id, uint16_t val_prev, uint8_t index)
+{
+ APP_PRINT_INFO0("[voice_handle_atv_audio_sync] ATV_CTL_OPCODE_AUDIO_SYNC");
+ memset(atvv_global_data.char_ctl_data_buff, 0, ATVV_CHAR_CTL_DATA_LEN);
+ atvv_global_data.char_ctl_data_buff[0] = ATV_CTL_OPCODE_AUDIO_SYNC;
+ atvv_global_data.char_ctl_data_buff[1] = atvv_global_data.codec_used;
+ atvv_global_data.char_ctl_data_buff[2] = (uint8_t)(seq_id >> 8);
+ atvv_global_data.char_ctl_data_buff[3] = (uint8_t)seq_id;
+ atvv_global_data.char_ctl_data_buff[4] = (uint8_t)(val_prev >> 8);
+ atvv_global_data.char_ctl_data_buff[5] = (uint8_t)val_prev;
+ atvv_global_data.char_ctl_data_buff[6] = index;
+ bool notify_result = server_send_data(0, app_global_data.atvv_srv_id,
+ GATT_SVC_ATVV_CHAR_CTL_VALUE_INDEX,
+ atvv_global_data.char_ctl_data_buff, 7,
+ GATT_PDU_TYPE_NOTIFICATION);
+ if (notify_result == false)
+ {
+ APP_PRINT_WARN0("[voice_handle_atv_audio_sync] ATV_CTL_OPCODE_AUDIO_SYNC notify failed!");
+ }
+}
+
+/******************************************************************
+ * @brief handle DPAD select event
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_handle_atv_dpad_select(void)
+{
+ APP_PRINT_INFO1("[voice_handle_atv_dpad_select] atv version is %d",
+ atvv_global_data.app_support_version);
+
+ if (ATVV_VERSION_0_4 == atvv_global_data.app_support_version)
+ {
+ bool result = false;
+
+ /* send Audio Start Notification */
+ memset(atvv_global_data.char_ctl_data_buff, 0, ATVV_CHAR_CTL_DATA_LEN);
+ atvv_global_data.char_ctl_data_buff[0] = ATV_CTL_OPCODE_AUDIO_START;
+
+ result = server_send_data(0, app_global_data.atvv_srv_id, GATT_SVC_ATVV_CHAR_CTL_VALUE_INDEX,
+ atvv_global_data.char_ctl_data_buff, 1, GATT_PDU_TYPE_NOTIFICATION);
+ if (result == false)
+ {
+ APP_PRINT_WARN0("[voice_handle_atv_dpad_select] ATV_CTL_OPCODE_AUDIO_START notify failed!");
+ }
+ }
+
+ if (temp_off_latency_timer != NULL)
+ {
+ /* turn off latency to speed up voice process */
+ app_set_latency_status(LATENCY_TEMP_OFF_BIT, LANTENCY_OFF);
+ /* start temp_off_latency_timer */
+ os_timer_restart(&temp_off_latency_timer, TEMP_OFF_LANTENCY_TIMEOUT);
+ }
+}
+
+/******************************************************************
+ * @brief voice module msg handle.
+ * @param msg_type - voice message type
+ * @param p_data - point to voice message data
+ * @return result
+ * @retval true or false
+ */
+bool voice_handle_messages(T_VOICE_MSG_TYPE msg_type, void *p_data)
+{
+ bool ret = true;
+
+ APP_PRINT_INFO1("[voice_handle_messages] msg_type is %d", msg_type);
+
+ switch (msg_type)
+ {
+ case VOICE_MSG_PERIPHERAL_GDMA:
+ {
+ voice_handle_gdma_event(*(T_IO_MSG *)p_data);
+ }
+ break;
+ case VOICE_MSG_BT_SEND_COMPLETE:
+ {
+ if (voice_global_data.is_allowed_to_notify_voice_data)
+ {
+ voice_handle_notify_voice_data();
+ }
+ }
+ break;
+
+ default:
+ APP_PRINT_INFO0("[voice_handle_messages] unknown msg type!");
+ ret = false;
+ break;
+ }
+ return ret;
+}
+
+/******************************************************************
+ * @fn voice_handle_atvv_srv_cb
+ * @brief ATV service callbacks are handled in this function.
+ * @param p_data - pointer to callback data
+ * @return cb_result
+ * @retval T_APP_RESULT
+ */
+T_APP_RESULT voice_handle_atvv_srv_cb(T_ATVV_CALLBACK_DATA *p_data)
+{
+ bool notify_result = false;
+ T_APP_RESULT cb_result = APP_RESULT_SUCCESS;
+
+ switch (p_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ /* add user code here */
+ switch (p_data->msg_data.notification_indification_index)
+ {
+ case ATVV_CHAR_RX_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("[voice_handle_atvv_srv_cb] ATVV_CHAR_RX_NOTIFY_ENABLE");
+ app_global_data.is_atv_voice_notify_en = true;
+ break;
+ case ATVV_CHAR_RX_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("[voice_handle_atvv_srv_cb] ATVV_CHAR_RX_NOTIFY_DISABLE");
+ app_global_data.is_atv_voice_notify_en = false;
+ if (ATVV_VERSION_1_0 == atvv_global_data.app_support_version)
+ {
+ if (voice_driver_global_data.is_voice_driver_working == true)
+ {
+ voice_handle_atvv_audio_stop(ATV_STOP_REASON_ATVV_CHAR_AUDIO_DISABLE);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ /* add user code here */
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ uint8_t report_len = p_data->msg_data.write.write_parameter.report_data.len;
+ uint8_t *report_data_ptr = p_data->msg_data.write.write_parameter.report_data.report;
+
+ APP_PRINT_INFO1("[voice_handle_atvv_srv_cb] SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE report_len = %d",
+ report_len);
+
+ if ((report_len > 0) && (report_len <= ATVV_CHAR_WRITE_DATA_LEN))
+ {
+ APP_PRINT_INFO1("[voice_handle_atvv_srv_cb] report data = %b", TRACE_BINARY(report_len,
+ report_data_ptr));
+
+ switch (report_data_ptr[0])
+ {
+ case ATV_TX_OPCODE_GET_CAPS:
+ {
+ /* parse received data */
+ uint8_t parsed_version_major = report_data_ptr[1];
+ uint8_t parsed_version_minor = report_data_ptr[2];
+ uint16_t parsed_codecs = ((uint16_t)report_data_ptr[3] << 8) + report_data_ptr[4];
+
+ APP_PRINT_INFO3("[voice_handle_atvv_srv_cb] ATV_TX_OPCODE_GET_CAPS V%d.%d codec = %d",
+ parsed_version_major, parsed_version_minor, parsed_codecs);
+
+ /* choose atv version */
+ uint8_t app_support_major_version = (uint8_t)(atvv_global_data.app_support_version >> 8);
+ if (app_support_major_version > parsed_version_major)
+ {
+ app_support_major_version = parsed_version_major;
+ if (app_support_major_version == 0)
+ {
+ atvv_global_data.app_support_version = ATVV_VERSION_0_4;
+ }
+ else
+ {
+ atvv_global_data.app_support_version = ATVV_VERSION_1_0;
+ }
+ }
+ APP_PRINT_INFO3("[voice_handle_atvv_srv_cb] APP use ATV version V%d.%d codec = %d",
+ (uint8_t)(atvv_global_data.app_support_version >> 8), (uint8_t)atvv_global_data.app_support_version,
+ atvv_global_data.codec_support);
+
+ /* send response */
+ if (ATVV_VERSION_1_0 == atvv_global_data.app_support_version)
+ {
+#if (ATV_VOICE_INTERACTION_MODEL == ATV_INTERACTION_MODEL_ON_REQUEST)
+ atvv_global_data.assistant_interaction_model = ATV_ASSISTANT_INTERACTION_MODEL_ON_REQUEST;
+#elif (ATV_VOICE_INTERACTION_MODEL == ATV_INTERACTION_MODEL_PRESS_TO_TALK)
+ atvv_global_data.assistant_interaction_model = ATV_ASSISTANT_INTERACTION_MODEL_PRESS_TO_TALK;
+#elif (ATV_VOICE_INTERACTION_MODEL == ATV_INTERACTION_MODEL_HOLD_TO_TALK)
+ atvv_global_data.assistant_interaction_model = ATV_ASSISTANT_INTERACTION_MODEL_HOLD_TO_TALK;
+#endif
+ atvv_global_data.codec_used = ATTV_CODEC_MASK_16K_ADPCM;
+ uint8_t mast_support_assistant_interaction_model = report_data_ptr[5];
+ uint16_t audio_frame_size = VOICE_FRAME_SIZE_AFTER_ENC * VOICE_PCM_FRAME_CNT;
+
+ if (atvv_global_data.assistant_interaction_model > mast_support_assistant_interaction_model)
+ {
+ atvv_global_data.assistant_interaction_model = mast_support_assistant_interaction_model;
+ }
+ APP_PRINT_INFO2("[voice_handle_atvv_srv_cb] assistant_interaction_model-- master support: %d, rcu use: %d",
+ mast_support_assistant_interaction_model, atvv_global_data.assistant_interaction_model);
+
+ memset(atvv_global_data.char_ctl_data_buff, 0, ATVV_CHAR_CTL_DATA_LEN);
+ atvv_global_data.char_ctl_data_buff[0] = ATV_CTL_OPCODE_GET_CAPS_RESP;
+ atvv_global_data.char_ctl_data_buff[1] = (uint8_t)(atvv_global_data.app_support_version >> 8);
+ atvv_global_data.char_ctl_data_buff[2] = (uint8_t)atvv_global_data.app_support_version;
+ atvv_global_data.char_ctl_data_buff[3] = (uint8_t)
+ atvv_global_data.codec_support; /* codecs supported */
+ atvv_global_data.char_ctl_data_buff[4] =
+ atvv_global_data.assistant_interaction_model; /*assistant interaction model*/
+ atvv_global_data.char_ctl_data_buff[5] = (uint8_t)(audio_frame_size >> 8);
+ atvv_global_data.char_ctl_data_buff[6] = (uint8_t) audio_frame_size; /* bytes/audio frame size*/
+ atvv_global_data.char_ctl_data_buff[7] = ATVV_DLE_AND_MTU_UPDATE_DISABLE; /* ectra configuration */
+ atvv_global_data.char_ctl_data_buff[8] = 0x00; /* reserved*/
+ }
+ else if (ATVV_VERSION_0_4 == atvv_global_data.app_support_version)
+ {
+ atvv_global_data.assistant_interaction_model = ATV_ASSISTANT_INTERACTION_MODEL_ON_REQUEST;
+
+ memset(atvv_global_data.char_ctl_data_buff, 0, ATVV_CHAR_CTL_DATA_LEN);
+ atvv_global_data.char_ctl_data_buff[0] = ATV_CTL_OPCODE_GET_CAPS_RESP;
+ atvv_global_data.char_ctl_data_buff[1] = (uint8_t)(atvv_global_data.app_support_version >> 8);
+ atvv_global_data.char_ctl_data_buff[2] = (uint8_t)atvv_global_data.app_support_version;
+ atvv_global_data.char_ctl_data_buff[3] = (uint8_t)(atvv_global_data.codec_support >> 8);
+ atvv_global_data.char_ctl_data_buff[4] = (uint8_t)
+ atvv_global_data.codec_support; /* codec_support */
+ atvv_global_data.char_ctl_data_buff[5] = 0x00;
+ atvv_global_data.char_ctl_data_buff[6] = (uint8_t)VOICE_REPORT_FRAME_SIZE; /* bytes/frame */
+ atvv_global_data.char_ctl_data_buff[7] = 0x00;
+ atvv_global_data.char_ctl_data_buff[8] = 0x14; /* bytes/char */
+ }
+
+ notify_result = server_send_data(0, app_global_data.atvv_srv_id, GATT_SVC_ATVV_CHAR_CTL_VALUE_INDEX,
+ atvv_global_data.char_ctl_data_buff, 9, GATT_PDU_TYPE_NOTIFICATION);
+ if (notify_result == false)
+ {
+ APP_PRINT_WARN0("[voice_handle_atvv_srv_cb] ATV_TX_OPCODE_GET_CAPS notify failed!");
+ }
+ }
+ break;
+
+ case ATV_TX_OPCODE_MIC_OPEN:
+ {
+ APP_PRINT_INFO0("[voice_handle_atvv_srv_cb] ATV_TX_OPCODE_MIC_OPEN");
+ if (ATVV_VERSION_1_0 == atvv_global_data.app_support_version)
+ {
+ if ((atvv_global_data.atv_start_reason != ATV_START_REASON_PTT)
+ && (atvv_global_data.atv_start_reason != ATV_START_REASON_HTT))
+ {
+ if (app_global_data.is_atv_voice_notify_en == true)
+ {
+ atvv_global_data.audio_consumption_mode = report_data_ptr[1];
+ if (voice_driver_global_data.is_voice_driver_working == true)
+ {
+ voice_handle_atvv_audio_stop(ATV_STOP_REASON_AUDIO_START_COMMAND);
+ }
+ voice_handle_atvv_audio_start(ATV_START_REASON_MIC_OPEN_REQUEST);
+ }
+ else
+ {
+ voice_handle_atvv_mic_open_error(ATV_MIC_OPEN_ERROR_ATVV_CHAR_AUDIO_IS_DISABLE);
+ }
+ }
+ else
+ {
+ APP_PRINT_WARN0("[voice_handle_atvv_srv_cb] atv assistant_interaction_model is not ATV_ASSISTANT_INTERACTION_MODEL_ON_REQUEST");
+ voice_handle_atvv_mic_open_error(ATV_MIC_OPEN_ERROR_PTT_HTT_IS_IN_PROGRESS);
+ }
+ }
+ else if (ATVV_VERSION_0_4 == atvv_global_data.app_support_version)
+ {
+ uint16_t parsed_codecs = ((uint16_t)report_data_ptr[1] << 8) + report_data_ptr[2];
+ APP_PRINT_INFO1("[voice_handle_atvv_srv_cb] ATV_TX_OPCODE_MIC_OPEN parsed_codecs = %d",
+ parsed_codecs);
+
+ if ((parsed_codecs & atvv_global_data.codec_support) && app_global_data.is_atv_voice_notify_en)
+ {
+ atvv_global_data.codec_used = parsed_codecs;
+ if (parsed_codecs == ATTV_CODEC_MASK_8K_ADPCM)
+ {
+ voice_driver_codec_params.codec_sample_rate = SAMPLE_RATE_8KHz;
+ }
+ else if (parsed_codecs == ATTV_CODEC_MASK_16K_ADPCM)
+ {
+ voice_driver_codec_params.codec_sample_rate = SAMPLE_RATE_16KHz;
+ }
+ voice_handle_atvv_audio_start(ATV_START_REASON_MIC_OPEN_REQUEST);
+ }
+ else
+ {
+ voice_handle_atvv_mic_open_error(ATV_MIC_OPEN_ERROR_RESERVED);
+ }
+ }
+ }
+ break;
+
+ case ATV_TX_OPCODE_MIC_CLOSE:
+ {
+ APP_PRINT_INFO0("[voice_handle_atvv_srv_cb] ATV_TX_OPCODE_MIC_CLOSE");
+ APP_PRINT_INFO2("[voice_handle_atvv_srv_cb] stream_id-- master: 0x%x, rcu: 0x%x",
+ report_data_ptr[1],
+ atvv_global_data.stream_id);
+ if (ATVV_VERSION_1_0 == atvv_global_data.app_support_version)
+ {
+ if (voice_driver_global_data.is_voice_driver_working == true)
+ {
+ if ((report_data_ptr[1] == 0xff)
+ || ((report_data_ptr[1] == 0)
+ && (atvv_global_data.atv_start_reason == ATV_START_REASON_MIC_OPEN_REQUEST))
+ || ((report_data_ptr[1] == atvv_global_data.stream_id)
+ && (atvv_global_data.atv_start_reason != ATV_START_REASON_MIC_OPEN_REQUEST)))
+ {
+ voice_handle_atvv_audio_stop(ATV_STOP_REASON_MIC_CLOSE_MESSAGE);
+ }
+ }
+ }
+ else if (ATVV_VERSION_0_4 == atvv_global_data.app_support_version)
+ {
+ voice_handle_atvv_audio_stop(ATV_STOP_REASON_MIC_CLOSE_MESSAGE);
+ }
+ }
+ break;
+
+ case ATV_TX_OPCODE_EXTEND:
+ {
+ APP_PRINT_INFO0("[voice_handle_atvv_srv_cb] ATV_TX_OPCODE_EXTEND");
+ APP_PRINT_INFO2("[voice_handle_atvv_srv_cb] stream_id-- master: 0x%x, rcu: 0x%x",
+ report_data_ptr[1],
+ atvv_global_data.stream_id);
+ if (ATVV_VERSION_1_0 == atvv_global_data.app_support_version)
+ {
+ if (voice_driver_global_data.is_voice_driver_working == true)
+ {
+ if ((report_data_ptr[1] == 0xff)
+ || ((report_data_ptr[1] == 0x00) &&
+ (atvv_global_data.atv_start_reason == ATV_START_REASON_MIC_OPEN_REQUEST))
+ || ((report_data_ptr[1] == atvv_global_data.stream_id) &&
+ (atvv_global_data.atv_start_reason != ATV_START_REASON_MIC_OPEN_REQUEST)))
+ {
+ APP_PRINT_INFO0("[voice_handle_atvv_audio_stop] ATV_TX_OPCODE_EXTEND");
+ os_timer_restart(&voice_exception_timer, VOICE_TRANSFER_TIMEOUT);
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return cb_result;
+}
+
+#endif
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/voice_module/voice.h b/src/app/google_rcu/voice_module/voice.h
new file mode 100644
index 0000000..8fbaf7c
--- /dev/null
+++ b/src/app/google_rcu/voice_module/voice.h
@@ -0,0 +1,86 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file voice.h
+* @brief This is the header file of user code which the voice module resides in.
+* @details
+* @author chenjie jin
+* @date 2018-05-03
+* @version v1.1
+*********************************************************************************************************
+*/
+
+#ifndef _VOICE_HANDLE_H_
+#define _VOICE_HANDLE_H_
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "stdint.h"
+#include "os_mem.h"
+#include "rtl876x_gpio.h"
+#include "board.h"
+#include "swtimer.h"
+#include "atvv_service.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define VOICE_QUEUE_MAX_BUFFER_SIZE (6 * 1024) /* unit: Byte */
+#define VOICE_TRANSFER_TIMEOUT 30000 /* 30 sec */
+#define VOICE_ACTIVE_REMOTE_TIMEOUT 60000 /* 60 sec */
+#define VOICE_GDMA_INT_SKIP_CNT 7 /* skip first several GDMA interrupts, to wait codec stable */
+
+#define VOICE_AUDIO_SYNC_PERIOD 20 /* ATV audio sync period in packet munber */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/*voice msg type*/
+typedef enum
+{
+ VOICE_MSG_INVALID = 0,
+ VOICE_MSG_BT_SEND_COMPLETE = 1,
+ VOICE_MSG_BT_WRITE_CMD = 2,
+ VOICE_MSG_PERIPHERAL_GDMA = 3,
+} T_VOICE_MSG_TYPE;
+
+typedef struct
+{
+ bool is_allowed_to_notify_voice_data; /* to indicate whether is allowed to notify voice data or not */
+ bool is_pending_to_stop_recording; /* to indicate whether is pending to stop recording */
+ bool is_encoder_init; /* to indicate whether encoder is initialized or not */
+ uint32_t voice_gdma_int_cnt; /* to indicate the count of voice GDMA interrupt */
+} T_VOICE_GLOBAL_DATA;
+
+/*============================================================================*
+* Export Global Variables
+*============================================================================*/
+extern T_VOICE_GLOBAL_DATA voice_global_data;
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+bool voice_handle_mic_key_pressed(void);
+void voice_handle_mic_key_released(void);
+bool voice_handle_messages(T_VOICE_MSG_TYPE msg_type, void *p_data);
+bool voice_handle_start_mic(void);
+void voice_handle_stop_mic(void);
+bool voice_handle_atvv_audio_start(ATV_AUDIO_START_REASON reason);
+bool voice_handle_atvv_audio_stop(ATV_AUDIO_STOP_REASON reason);
+bool voice_handle_atvv_mic_open_error(ATV_MIC_OPEN_ERROR reason);
+void voice_handle_atvv_init_data(void);
+void voice_handle_atv_dpad_select(void);
+T_APP_RESULT voice_handle_atvv_srv_cb(T_ATVV_CALLBACK_DATA *p_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/app/google_rcu/voice_module/voice_driver.c b/src/app/google_rcu/voice_module/voice_driver.c
new file mode 100644
index 0000000..25f1964
--- /dev/null
+++ b/src/app/google_rcu/voice_module/voice_driver.c
@@ -0,0 +1,555 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file voice_driver.c
+* @brief voice module driver.
+* @details
+* @author
+* @date 2020-03-05
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include "board.h"
+#include <trace.h>
+#include "voice_driver.h"
+#include "rtl876x_gpio.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_gdma.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_codec.h"
+#include "rtl876x_i2s.h"
+#include "app_msg.h"
+#include <app_task.h>
+#include <app_section.h>
+#include "rtl876x_uart.h"
+
+#if SUPPORT_VOICE_FEATURE
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+/* LLI structure for I2S data */
+static GDMA_LLIDef voice_driver_gdma_link_list[2];
+
+/*============================================================================*
+ * External Variables
+ *============================================================================*/
+
+/*============================================================================*
+ * Global Variables
+ *============================================================================*/
+T_VOICE_DRIVER_GLOBAL_DATA voice_driver_global_data;
+T_VOICE_DRIVER_CODEC_PARAMS voice_driver_codec_params;
+
+/*============================================================================*
+ * Functions Declaration
+ *============================================================================*/
+static void voice_driver_init_pad_and_pinmux(void);
+static void voice_driver_init_i2s(void);
+static void voice_driver_deinit_i2s(void);
+static void voice_driver_init_codec(void);
+static void voice_driver_deinit_codec(void);
+static void voice_driver_init_rx_gdma(void);
+static void voice_driver_deinit_rx_gdma(void);
+
+void VOICE_GDMA_Channel_Handler(void) DATA_RAM_FUNCTION;
+bool voice_driver_dlps_check(void) DATA_RAM_FUNCTION;
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief initialization of pinmux settings and pad settings.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_driver_init_pad_and_pinmux(void)
+{
+#if (VOICE_MIC_TYPE == AMIC_TYPE)
+ Pad_Config(AMIC_MIC_N_PIN, PAD_SW_MODE, PAD_NOT_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(AMIC_MIC_P_PIN, PAD_SW_MODE, PAD_NOT_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW);
+#elif (VOICE_MIC_TYPE == DMIC_TYPE)
+ Pad_Config(DMIC_CLK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+ Pad_Config(DMIC_DATA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+
+ Pinmux_Deinit(DMIC_CLK_PIN);
+ Pinmux_Deinit(DMIC_DATA_PIN);
+ Pinmux_Config(DMIC_CLK_PIN, DMIC1_CLK);
+ Pinmux_Config(DMIC_DATA_PIN, DMIC1_DAT);
+#endif
+#if SUPPORT_MIC_BIAS_OUTPUT
+ Pad_Config(H_0, PAD_SW_MODE, PAD_NOT_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW);
+#endif
+}
+
+/******************************************************************
+ * @brief Initialize I2S peripheral.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_driver_init_i2s(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_I2S0, APBPeriph_I2S0_CLOCK, ENABLE);
+
+ I2S_InitTypeDef I2S_InitStruct;
+ I2S_StructInit(&I2S_InitStruct);
+ I2S_InitStruct.I2S_ClockSource = I2S_CLK_40M;
+ I2S_InitStruct.I2S_DataFormat = I2S_Mode;
+ I2S_InitStruct.I2S_DeviceMode = I2S_DeviceMode_Master;
+ I2S_InitStruct.I2S_RxWaterlevel = 0x4;
+
+ /* config I2S clock speed */
+ /* BCLK = 40MHz*(I2S_BClockNi/I2S_BClockMi) = Sample Rate * 64BCLK/sample */
+ if (voice_driver_codec_params.codec_sample_rate == SAMPLE_RATE_8KHz)
+ {
+ I2S_InitStruct.I2S_BClockMi = 0x186A;
+ I2S_InitStruct.I2S_BClockNi = 0x50;
+ }
+ else if (voice_driver_codec_params.codec_sample_rate == SAMPLE_RATE_16KHz)
+ {
+ I2S_InitStruct.I2S_BClockMi = 0x186A;
+ I2S_InitStruct.I2S_BClockNi = 0xA0;
+ }
+ else
+ {
+ APP_PRINT_WARN1("[voice_driver_init_i2s] invalid codec sample rate: %d",
+ voice_driver_codec_params.codec_sample_rate);
+ I2S_InitStruct.I2S_BClockMi = 0x186A;
+ I2S_InitStruct.I2S_BClockNi = 0xA0;
+ }
+
+ /* config I2S channel type */
+ I2S_InitStruct.I2S_ChannelType = I2S_Channel_Mono;
+
+ I2S_Init(I2S0, &I2S_InitStruct);
+ I2S_Cmd(I2S0, I2S_MODE_RX, ENABLE);
+}
+
+/******************************************************************
+ * @brief Deinitialize I2S peripheral.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_driver_deinit_i2s(void)
+{
+ I2S_DeInit(I2S0);
+}
+
+/******************************************************************
+ * @brief Initialize codec peripheral.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_driver_init_codec(void)
+{
+ /* switch power mode */
+ SystemCall(3, 1);
+
+ CODEC_AnalogCircuitInit();
+
+ RCC_PeriphClockCmd(APBPeriph_CODEC, APBPeriph_CODEC_CLOCK, ENABLE);
+
+ CODEC_InitTypeDef CODEC_InitStruct;
+ CODEC_StructInit(&CODEC_InitStruct);
+
+ /* Basic parameters section */
+ CODEC_InitStruct.CODEC_SampleRate = voice_driver_codec_params.codec_sample_rate;
+ CODEC_InitStruct.CODEC_DmicClock = voice_driver_codec_params.dmic_clock;
+ CODEC_InitStruct.CODEC_I2SFormat = voice_driver_codec_params.codec_i2s_format;
+ CODEC_InitStruct.CODEC_I2SDataWidth = voice_driver_codec_params.codec_i2s_data_width;
+ CODEC_InitStruct.CODEC_I2SChSequence = voice_driver_codec_params.codec_i2s_ch_sequence;
+ CODEC_InitStruct.CODEC_MicBIAS = voice_driver_codec_params.mic_bias_voltage;
+ CODEC_InitStruct.CODEC_MicBstGain = voice_driver_codec_params.amic_bst_gain;
+ CODEC_InitStruct.CODEC_MicBstMode = voice_driver_codec_params.amic_bst_mode;
+
+ /* MIC channel 0 initialization parameters section */
+ CODEC_InitStruct.CODEC_Ch0Mute = voice_driver_codec_params.codec_ch0_mute;
+ CODEC_InitStruct.CODEC_Ch0MicType = voice_driver_codec_params.codec_ch0_mic_type;
+ CODEC_InitStruct.CODEC_Ch0DmicDataLatch = voice_driver_codec_params.codec_ch0_dmic_data_latch;
+ CODEC_InitStruct.CODEC_Ch0AdGain = voice_driver_codec_params.codec_ch0_ad_gain;
+ CODEC_InitStruct.CODEC_Ch0BoostGain = voice_driver_codec_params.codec_ch0_boost_gain;
+ CODEC_InitStruct.CODEC_Ch0ZeroDetTimeout = voice_driver_codec_params.codec_ch0_zero_det_timeout;
+
+ CODEC_Init(CODEC, &CODEC_InitStruct);
+}
+
+/******************************************************************
+ * @brief Deinitialize codec peripheral.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_driver_deinit_codec(void)
+{
+ CODEC_DeInit(CODEC);
+
+ /* restore power mode */
+ SystemCall(3, 0);
+}
+
+/******************************************************************
+ * @brief Initialize GDMA peripheral.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_driver_init_rx_gdma(void)
+{
+ /* Enable GDMA clock */
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+
+ /* Initialize GDMA peripheral */
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = VOICE_GDMA_Channel_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToMemory;
+ GDMA_InitStruct.GDMA_BufferSize = VOICE_GDMA_FRAME_SIZE / 4;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Inc;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_16;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)(&(I2S0->RX_DR));
+ GDMA_InitStruct.GDMA_SourceHandshake = GDMA_Handshake_I2S0_RX;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)voice_driver_global_data.gdma_buffer.buf0;
+ GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_SPIC0_RX;
+ GDMA_InitStruct.GDMA_Multi_Block_En = 1;
+ GDMA_InitStruct.GDMA_Multi_Block_Struct = (uint32_t)voice_driver_gdma_link_list;
+ GDMA_InitStruct.GDMA_Multi_Block_Mode = LLI_TRANSFER;
+
+ /* Initialize GDMA Link List Struct */
+ for (uint8_t i = 0; i < 2; i++)
+ {
+ if (i == 0)
+ {
+ voice_driver_gdma_link_list[i].DAR = (uint32_t)voice_driver_global_data.gdma_buffer.buf0;
+ voice_driver_gdma_link_list[i].LLP = (uint32_t)&voice_driver_gdma_link_list[i +
+ 1]; /* link to buffer 1 */
+ }
+ else
+ {
+ voice_driver_gdma_link_list[i].DAR = (uint32_t)voice_driver_global_data.gdma_buffer.buf1;
+ voice_driver_gdma_link_list[i].LLP = (uint32_t)&voice_driver_gdma_link_list[i -
+ 1]; /* link back to buffer 0 */
+ }
+ voice_driver_gdma_link_list[i].SAR = GDMA_InitStruct.GDMA_SourceAddr;
+
+ /* Configure low 32 bit of CTL register */
+ voice_driver_gdma_link_list[i].CTL_LOW = BIT(0)
+ | (GDMA_InitStruct.GDMA_DestinationDataSize << 1)
+ | (GDMA_InitStruct.GDMA_SourceDataSize << 4)
+ | (GDMA_InitStruct.GDMA_DestinationInc << 7)
+ | (GDMA_InitStruct.GDMA_SourceInc << 9)
+ | (GDMA_InitStruct.GDMA_DestinationMsize << 11)
+ | (GDMA_InitStruct.GDMA_SourceMsize << 14)
+ | (GDMA_InitStruct.GDMA_DIR << 20)
+ | (GDMA_InitStruct.GDMA_Multi_Block_Mode & LLP_SELECTED_BIT);
+ /* Configure high 32 bit of CTL register */
+ voice_driver_gdma_link_list[i].CTL_HIGH = GDMA_InitStruct.GDMA_BufferSize;
+ }
+
+ GDMA_Init(VOICE_GDMA_Channel, &GDMA_InitStruct);
+
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = VOICE_GDMA_Channel_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ GDMA_INTConfig(VOICE_GDMA_Channel_NUM, GDMA_INT_Block, ENABLE);
+ GDMA_Cmd(VOICE_GDMA_Channel_NUM, ENABLE);
+}
+
+/******************************************************************
+ * @brief Deinitialize GDMA peripheral.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_driver_deinit_rx_gdma(void)
+{
+ GDMA_Cmd(VOICE_GDMA_Channel_NUM, DISABLE);
+}
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/******************************************************************
+ * @brief Initialize voice driver global data.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_driver_init_data(void)
+{
+ APP_PRINT_INFO0("[voice_driver_init_data] init data");
+ memset(&voice_driver_global_data, 0, sizeof(voice_driver_global_data));
+ voice_driver_global_data.is_allowed_to_enter_dlps = true;
+}
+
+/******************************************************************
+ * @brief Initialize codec parameters.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_driver_init_codec_params(void)
+{
+ APP_PRINT_INFO0("[voice_driver_init_codec_params] init codec parameters");
+
+ memset(&voice_driver_codec_params, 0, sizeof(voice_driver_codec_params));
+
+ /* Basic parameters section */
+ voice_driver_codec_params.codec_i2s_format = CODEC_I2S_DataFormat_I2S;
+ voice_driver_codec_params.codec_i2s_data_width = CODEC_I2S_DataWidth_16Bits;
+ voice_driver_codec_params.dmic_clock = DMIC_Clock_2500KHz;
+#if (CODEC_SAMPLE_RATE_SEL == CODEC_SAMPLE_RATE_8KHz)
+ voice_driver_codec_params.codec_sample_rate = SAMPLE_RATE_8KHz;
+#elif (CODEC_SAMPLE_RATE_SEL == CODEC_SAMPLE_RATE_16KHz)
+ voice_driver_codec_params.codec_sample_rate = SAMPLE_RATE_16KHz;
+#endif
+
+#if SUPPORT_MIC_BIAS_OUTPUT
+ voice_driver_codec_params.is_mic_bias_output_en = true;
+ voice_driver_codec_params.mic_bias_voltage = MICBIAS_VOLTAGE_1_8;
+#endif
+
+ voice_driver_codec_params.codec_ch0_mute = CODEC_CH0_UNMUTE;
+ voice_driver_codec_params.codec_i2s_ch_sequence = CODEC_I2S_CH_L_L;
+
+#if (VOICE_MIC_TYPE == AMIC_TYPE)
+ voice_driver_codec_params.codec_ch0_mic_type = CODEC_CH0_AMIC;
+ voice_driver_codec_params.amic_bst_gain = MICBST_Gain_30dB;
+ voice_driver_codec_params.codec_ch0_ad_gain =
+ 0x18; /* 0x2F - 0dB, step 0.375dB, range -17.625dB ~ 30dB */
+ voice_driver_codec_params.codec_ch0_boost_gain = Ch0_Boost_Gain_0dB;
+#if (AMIC_INPUT_TYPE_SEL == AMIC_INPUT_TYPE_DIFF)
+ voice_driver_codec_params.amic_bst_mode = MICBST_Mode_Differential;
+#elif (AMIC_INPUT_TYPE_SEL == AMIC_INPUT_TYPE_SINGLE)
+ voice_driver_codec_params.amic_bst_mode = MICBST_Mode_Single;
+#endif
+
+#elif (VOICE_MIC_TYPE == DMIC_TYPE)
+ voice_driver_codec_params.codec_ch0_mic_type = CODEC_CH0_DMIC;
+ voice_driver_codec_params.codec_ch0_boost_gain = Ch0_Boost_Gain_24dB;
+ voice_driver_codec_params.codec_ch0_ad_gain =
+ 0x2F; /* 0x2F - 0dB, step 0.375dB, range -17.625dB ~ 30dB */
+ voice_driver_codec_params.codec_ch0_zero_det_timeout = Ch0_ADC_Zero_DetTimeout_1024_32_Sample;
+#if (DMIC0_DATA_LATCH_TYPE == DMIC_DATA_LATCH_RISING_EDGE)
+ voice_driver_codec_params.codec_ch0_dmic_data_latch = DMIC_Ch0_Rising_Latch;
+#elif (DMIC0_DATA_LATCH_TYPE == DMIC_DATA_LATCH_FALLING_EDGE)
+ voice_driver_codec_params.codec_ch0_dmic_data_latch = DMIC_Ch0_Falling_Latch;
+#endif
+#endif
+}
+
+/******************************************************************
+ * @brief Initialize voice driver.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_driver_init(void)
+{
+ voice_driver_init_data();
+ voice_driver_global_data.is_allowed_to_enter_dlps = false;
+ voice_driver_global_data.is_voice_driver_working = true;
+
+ voice_driver_init_pad_and_pinmux();
+ voice_driver_init_i2s();
+ voice_driver_init_codec();
+ voice_driver_init_rx_gdma();
+}
+
+/******************************************************************
+ * @brief Deinitialize voice driver.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void voice_driver_deinit(void)
+{
+ voice_driver_global_data.is_allowed_to_enter_dlps = true;
+ voice_driver_global_data.is_voice_driver_working = false;
+
+ voice_driver_deinit_i2s();
+ voice_driver_deinit_codec();
+ voice_driver_deinit_rx_gdma();
+}
+
+/******************************************************************
+ * @brief voice driver check DLPS callback
+ * @param none
+ * @return bool
+ * @retval true or false
+ */
+bool voice_driver_dlps_check(void)
+{
+ return voice_driver_global_data.is_allowed_to_enter_dlps;
+}
+
+/******************************************************************
+ * @brief GDMA interrupt handler function.
+ * @param none
+ * @return none
+ * @retval void
+ */
+void VOICE_GDMA_Channel_Handler(void)
+{
+ GDMA_ClearINTPendingBit(VOICE_GDMA_Channel_NUM, GDMA_INT_Block);
+ if (voice_driver_global_data.is_voice_driver_working == true)
+ {
+ T_IO_MSG gdma_msg;
+
+ APP_PRINT_INFO0("[VOICE_GDMA_Channel_Handler] GDMA interrupt!");
+ gdma_msg.type = IO_MSG_TYPE_GDMA;
+ gdma_msg.subtype = 0;
+ if (voice_driver_global_data.current_bibuff_index == 0)
+ {
+ voice_driver_global_data.current_bibuff_index = 1;
+ gdma_msg.u.buf = (void *)voice_driver_global_data.gdma_buffer.buf0;
+ }
+ else
+ {
+ voice_driver_global_data.current_bibuff_index = 0;
+ gdma_msg.u.buf = (void *)voice_driver_global_data.gdma_buffer.buf1;
+ }
+ if (false == app_send_msg_to_apptask(&gdma_msg))
+ {
+ APP_PRINT_WARN0("[VOICE_GDMA_Channel_Handler] Send IO_MSG_TYPE_GDMA failed!");
+ }
+
+ }
+}
+
+#if SUPPORT_UART_DUMP_FEATURE
+/******************************************************************
+ * @brief Initialize UART driver.
+ */
+void voice_driver_uart_init(void)
+{
+ Pad_Config(VOICE_UART_TEST_TX, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(VOICE_UART_TEST_TX, UART0_TX);
+
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ UART_InitTypeDef UART_InitStruct;
+ UART_StructInit(&UART_InitStruct);
+ /* change to 3M baudrate */
+ UART_InitStruct.UART_Div = 1;
+ UART_InitStruct.UART_Ovsr = 8;
+ UART_InitStruct.UART_OvsrAdj = 0x492;
+ UART_InitStruct.UART_TxWaterLevel = 12;
+ UART_InitStruct.UART_TxDmaEn = ENABLE;
+ UART_InitStruct.UART_DmaEn = UART_DMA_ENABLE;
+ UART_Init(UART0, &UART_InitStruct);
+}
+
+/******************************************************************
+ * @brief Initialize GDMA driver.
+ */
+void voice_uart_dump_init_rx_gdma(void)
+{
+ /* Enable GDMA clock */
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+
+ /* Initialize GDMA peripheral */
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = VOICE_GDMA_Channel_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToPeripheral;
+ GDMA_InitStruct.GDMA_BufferSize = VOICE_GDMA_FRAME_SIZE / 4;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_16;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)(&(I2S0->RX_DR));
+ GDMA_InitStruct.GDMA_SourceHandshake = GDMA_Handshake_I2S0_RX;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(UART0->RB_THR));
+ GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_UART0_TX;
+ GDMA_InitStruct.GDMA_Multi_Block_En = 1;
+ GDMA_InitStruct.GDMA_Multi_Block_Struct = (uint32_t)voice_driver_gdma_link_list;
+ GDMA_InitStruct.GDMA_Multi_Block_Mode = LLI_TRANSFER;
+
+ /* Initialize GDMA Link List Struct */
+ for (uint8_t i = 0; i < 2; i++)
+ {
+ if (i == 0)
+ {
+ voice_driver_gdma_link_list[i].LLP = (uint32_t)&voice_driver_gdma_link_list[i +
+ 1]; /* link to buffer 1 */
+ }
+ else
+ {
+ voice_driver_gdma_link_list[i].LLP = (uint32_t)&voice_driver_gdma_link_list[i -
+ 1]; /* link back to buffer 0 */
+ }
+ voice_driver_gdma_link_list[i].DAR = GDMA_InitStruct.GDMA_DestinationAddr;
+ voice_driver_gdma_link_list[i].SAR = GDMA_InitStruct.GDMA_SourceAddr;
+
+ /* Configure low 32 bit of CTL register */
+ voice_driver_gdma_link_list[i].CTL_LOW = BIT(0)
+ | (GDMA_InitStruct.GDMA_DestinationDataSize << 1)
+ | (GDMA_InitStruct.GDMA_SourceDataSize << 4)
+ | (GDMA_InitStruct.GDMA_DestinationInc << 7)
+ | (GDMA_InitStruct.GDMA_SourceInc << 9)
+ | (GDMA_InitStruct.GDMA_DestinationMsize << 11)
+ | (GDMA_InitStruct.GDMA_SourceMsize << 14)
+ | (GDMA_InitStruct.GDMA_DIR << 20)
+ | (GDMA_InitStruct.GDMA_Multi_Block_Mode & LLP_SELECTED_BIT);
+ /* Configure high 32 bit of CTL register */
+ voice_driver_gdma_link_list[i].CTL_HIGH = GDMA_InitStruct.GDMA_BufferSize;
+ }
+
+ GDMA_Init(VOICE_GDMA_Channel, &GDMA_InitStruct);
+ GDMA_Cmd(VOICE_GDMA_Channel_NUM, ENABLE);
+}
+
+/******************************************************************
+ * @brief Start voice recording.
+ */
+void voice_uart_dump_start_recording(void)
+{
+ voice_driver_init_data();
+ voice_driver_global_data.is_allowed_to_enter_dlps = false;
+ voice_driver_global_data.is_voice_driver_working = true;
+
+ voice_driver_init_pad_and_pinmux();
+ voice_driver_init_i2s();
+ voice_driver_init_codec();
+ voice_uart_dump_init_rx_gdma();
+}
+
+/******************************************************************
+ * @brief Start UART dump voice data.
+ */
+void voice_uart_dump_start(void)
+{
+ voice_driver_uart_init();
+ voice_uart_dump_start_recording();
+}
+
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/app/google_rcu/voice_module/voice_driver.h b/src/app/google_rcu/voice_module/voice_driver.h
new file mode 100644
index 0000000..422a7c0
--- /dev/null
+++ b/src/app/google_rcu/voice_module/voice_driver.h
@@ -0,0 +1,126 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file voice_driver.h
+* @brief This is the header file of user code which the voice driver resides in.
+* @details
+* @author chenjie jin
+* @date 2018-05-03
+* @version v1.1
+*********************************************************************************************************
+*/
+
+#ifndef _VOICE_DRIVER_H_
+#define _VOICE_DRIVER_H_
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "stdint.h"
+#include "stdbool.h"
+#include "board.h"
+#include "rtl876x_codec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/*voice config*/
+#if (VOICE_ENC_TYPE == SW_MSBC_ENC)
+#define VOICE_PCM_FRAME_SIZE 240
+#define VOICE_PCM_FRAME_CNT 2
+#define VOICE_GDMA_FRAME_SIZE (VOICE_PCM_FRAME_SIZE * VOICE_PCM_FRAME_CNT)
+#define VOICE_FRAME_SIZE_AFTER_ENC 57
+#define VOICE_REPORT_FRAME_SIZE ((VOICE_FRAME_SIZE_AFTER_ENC + 3) * VOICE_PCM_FRAME_CNT) /* 3 bytes header per frame */
+
+#elif (VOICE_ENC_TYPE == SW_SBC_ENC)
+#define VOICE_PCM_FRAME_CNT 2
+#define VOICE_PCM_FRAME_SIZE 256
+#define VOICE_FRAME_SIZE_AFTER_ENC (2 * BIT_POOL_SIZE + 8)
+#define VOICE_REPORT_FRAME_SIZE (VOICE_FRAME_SIZE_AFTER_ENC * VOICE_PCM_FRAME_CNT)
+#define VOICE_GDMA_FRAME_SIZE (VOICE_PCM_FRAME_SIZE * VOICE_PCM_FRAME_CNT)
+#define BIT_POOL_SIZE 14
+
+#elif (VOICE_ENC_TYPE == SW_IMA_ADPCM_ENC)
+#define VOICE_PCM_FRAME_CNT 1
+#define VOICE_PCM_FRAME_SIZE 512
+#define VOICE_FRAME_SIZE_AFTER_ENC 128
+#define VOICE_FRAME_HEADER_SIZE 6
+#define VOICE_REPORT_FRAME_SIZE (VOICE_FRAME_SIZE_AFTER_ENC * VOICE_PCM_FRAME_CNT + VOICE_FRAME_HEADER_SIZE)
+#define VOICE_GDMA_FRAME_SIZE (VOICE_PCM_FRAME_SIZE * VOICE_PCM_FRAME_CNT)
+
+#endif
+
+/* Voice GDMA definitions */
+#define VOICE_GDMA_Channel GDMA_Channel0
+#define VOICE_GDMA_Channel_NUM 0
+#define VOICE_GDMA_Channel_IRQn GDMA0_Channel0_IRQn
+#define VOICE_GDMA_Channel_Handler GDMA0_Channel0_Handler
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/**
+ * @brief Loop queue data struct
+ */
+typedef struct
+{
+ uint8_t buf0[VOICE_GDMA_FRAME_SIZE];
+ uint8_t buf1[VOICE_GDMA_FRAME_SIZE];
+} T_GDMA_BUF_TYPE_DEF __attribute__((aligned(4)));
+
+typedef struct
+{
+ bool is_allowed_to_enter_dlps; /* to indicate whether to allow to enter dlps or not */
+ bool is_voice_driver_working; /* to indicate whether voice driver is working or not */
+
+ uint8_t current_bibuff_index; /* to indicate which buffer the voice using now */
+ T_GDMA_BUF_TYPE_DEF gdma_buffer; /* to indicate the buffer used by voice gdma */
+} T_VOICE_DRIVER_GLOBAL_DATA;
+
+typedef struct
+{
+ /* basic parameters section */
+ bool is_mic_bias_output_en; /* to indicate whether to enable mic bias voltage or not */
+ uint32_t mic_bias_voltage; /* to indicate the MICBIAS voltage */
+ uint32_t codec_sample_rate; /* to indicate the codec sample rate */
+ uint32_t amic_bst_gain; /* to indicate the MICBST gain */
+ uint32_t amic_bst_mode; /* to indicate the MICBST mode */
+ uint32_t dmic_clock; /* to indicate the dmic clock */
+ uint32_t codec_i2s_format; /* to indicate the I2S format of codec part */
+ uint32_t codec_i2s_data_width; /* to indicate the I2S data width of codec part */
+ uint32_t codec_i2s_ch_sequence; /* to indicate the I2S channel sequence */
+
+ /* MIC channel 0 initialization parameters section */
+ uint32_t codec_ch0_mute; /* to indicate the mute state of codec channel 0 */
+ uint32_t codec_ch0_mic_type; /* to indicate the mic type of codec channel 0 */
+ uint32_t codec_ch0_dmic_data_latch; /* to indicate the dmic data latch type of codec channel 0 */
+ uint32_t codec_ch0_ad_gain; /* to indicate the ADC digital volume of codec channel 0 */
+ uint32_t codec_ch0_boost_gain; /* to indicate the boost gain of codec channel 0 */
+ uint32_t codec_ch0_zero_det_timeout; /* to indicate the zero detection timeout of channel 0 */
+} T_VOICE_DRIVER_CODEC_PARAMS;
+
+/*============================================================================*
+* Export Global Variables
+*============================================================================*/
+extern T_VOICE_DRIVER_GLOBAL_DATA voice_driver_global_data;
+extern T_VOICE_DRIVER_CODEC_PARAMS voice_driver_codec_params;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void voice_driver_init_data(void);
+void voice_driver_init_codec_params(void);
+void voice_driver_init(void);
+void voice_driver_deinit(void);
+bool voice_driver_dlps_check(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/ble/privacy/privacy_mgnt.c b/src/ble/privacy/privacy_mgnt.c
new file mode 100644
index 0000000..f8dc76b
--- /dev/null
+++ b/src/ble/privacy/privacy_mgnt.c
@@ -0,0 +1,578 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file privacy_mgnt.c
+* @brief privacy1.2 management file.
+* @details Demonstration of how to implement privacy.
+* @author
+* @date 2016-02-18
+* @version v0.1
+*********************************************************************************************************
+*/
+#include <trace.h>
+#include <string.h>
+#include <gap.h>
+#include <privacy_mgnt.h>
+#include <os_mem.h>
+#include <gap_privacy.h>
+
+typedef enum
+{
+ PRIVACY_RESOLVING_LIST_IDLE,
+ PRIVACY_RESOLVING_LIST_ADD_PENDING,
+ PRIVACY_RESOLVING_LIST_REMOVE_PENDING,
+} T_PRIVACY_MODIFY_STATE;
+
+typedef enum
+{
+ PRIVACY_RESOLVING_ADDED_IDLE,
+ PRIVACY_RESOLVING_ADDED_PENDING,
+ PRIVACY_RESOLVING_ADDED,
+} T_PRIVACY_ADDED_STATE;
+
+typedef struct
+{
+ bool is_used;
+ T_PRIVACY_ADDED_STATE is_added;
+ T_PRIVACY_MODIFY_STATE state;
+ bool device_mode;
+ T_GAP_IDENT_ADDR_TYPE remote_bd_type;
+ uint8_t addr[6];
+} T_LE_PRIVACY_ENTRY, *P_LE_PRIVACY_ENTRY;
+
+T_LE_PRIVACY_ENTRY *privacy_table;
+bool privacy_clear_pending = false;
+bool privacy_modify_resolv_list_pending = false;
+uint8_t privacy_modify_resolv_list_idx = 0xff;
+T_PRIVACY_STATE privacy_state = PRIVACY_STATE_INIT;
+T_LE_PRIVACY_STATE privacy_resolution_status = LE_PRIVACY_RESOLUTION_DISABLED;
+bool privacy_whitelist = false;
+bool privacy_mode_manage = true;
+static P_FUN_PRIVACY_STATE_CB privacy_app_cb = NULL;
+
+extern T_GAP_DEV_STATE gap_dev_state;
+
+void privacy_modify_resolving_list(T_GAP_RESOLV_LIST_OP op, T_GAP_IDENT_ADDR_TYPE addr_type,
+ uint8_t *addr, bool device_mode);
+
+T_APP_RESULT privacy_msg_callback(uint8_t msg_type, T_LE_PRIVACY_CB_DATA msg_data);
+
+void privacy_change_state(T_PRIVACY_STATE state)
+{
+ if (privacy_state != state)
+ {
+
+ privacy_state = state;
+ if (privacy_app_cb)
+ {
+ T_PRIVACY_CB_DATA cb_data;
+ cb_data.privacy_state = privacy_state;
+ privacy_app_cb(PRIVACY_STATE_MSGTYPE, cb_data);
+ }
+ }
+}
+
+bool privacy_add_device(T_LE_KEY_ENTRY *p_entry)
+{
+ if (p_entry != NULL && p_entry->is_used)
+ {
+ bool device_mode = true;
+ T_LE_PRIVACY_INFO privacy_info;
+ if (le_get_privacy_info(p_entry, &privacy_info))
+ {
+ if (privacy_info.is_discov && privacy_info.resolv_addr_only)
+ {
+ device_mode = false;
+ }
+ }
+ if ((p_entry->remote_bd.remote_bd_type == GAP_REMOTE_ADDR_LE_PUBLIC) ||
+ ((p_entry->remote_bd.remote_bd_type == GAP_REMOTE_ADDR_LE_RANDOM) &&
+ ((p_entry->remote_bd.addr[5] & RANDOM_ADDR_MASK) == RANDOM_ADDR_MASK_STATIC))
+ )
+ {
+ privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_ADD,
+ (T_GAP_IDENT_ADDR_TYPE)p_entry->remote_bd.remote_bd_type,
+ p_entry->remote_bd.addr, device_mode);
+ return true;
+ }
+ else
+ {
+ if (p_entry->flags & LE_KEY_STORE_REMOTE_IRK_BIT)
+ {
+ privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_ADD,
+ (T_GAP_IDENT_ADDR_TYPE)p_entry->resolved_remote_bd.remote_bd_type,
+ p_entry->resolved_remote_bd.addr, device_mode);
+ return true;
+ }
+ else
+ {
+ APP_PRINT_ERROR1("[PRIVACY] privacy_add_device: failed, idx %d", p_entry->idx);
+ }
+ }
+ }
+ return false;
+}
+
+void privacy_init(P_FUN_PRIVACY_STATE_CB privacy_callback, bool whitelist)
+{
+ uint8_t i;
+ uint16_t size;
+ T_LE_KEY_ENTRY *p_entry;
+ uint8_t bond_storage_num = le_get_max_le_paired_device_num();
+
+ APP_PRINT_INFO1("[PRIVACY] privacy_init: whitelist %d", whitelist);
+ size = bond_storage_num * sizeof(T_LE_PRIVACY_ENTRY);
+ privacy_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+ privacy_app_cb = privacy_callback;
+ privacy_whitelist = whitelist;
+ le_privacy_register_cb(privacy_msg_callback);
+
+ privacy_change_state(PRIVACY_STATE_IDLE);
+
+ for (i = 0; i < bond_storage_num; i++)
+ {
+ p_entry = le_find_key_entry_by_idx(i);
+ privacy_add_device(p_entry);
+ }
+ return;
+}
+
+T_PRIVACY_STATE privacy_handle_resolv_list_int(void)
+{
+ uint8_t i;
+ T_GAP_CAUSE cause;
+ T_PRIVACY_STATE state = PRIVACY_STATE_BUSY;
+ uint8_t bond_storage_num = le_get_max_le_paired_device_num();
+
+ if (privacy_modify_resolv_list_pending)
+ {
+ APP_PRINT_INFO0("[PRIVACY] wait rsp");
+ return state;
+ }
+ if (privacy_clear_pending)
+ {
+ APP_PRINT_INFO0("[PRIVACY] clear");
+ cause = le_privacy_modify_resolv_list(GAP_RESOLV_LIST_OP_CLEAR, GAP_IDENT_ADDR_PUBLIC, NULL);
+ if (cause == GAP_CAUSE_SUCCESS)
+ {
+ if (privacy_whitelist)
+ {
+ le_modify_white_list(GAP_WHITE_LIST_OP_CLEAR, NULL, GAP_REMOTE_ADDR_LE_PUBLIC);
+ }
+ privacy_modify_resolv_list_pending = true;
+ return state;
+ }
+ else
+ {
+ APP_PRINT_ERROR1("[PRIVACY] clear failed: cause %d", cause);
+ return state;
+ }
+ }
+ for (i = 0; i < bond_storage_num; i++)
+ {
+ if (privacy_table[i].is_used && privacy_table[i].state != PRIVACY_RESOLVING_LIST_IDLE)
+ {
+ if (privacy_table[i].state == PRIVACY_RESOLVING_LIST_ADD_PENDING)
+ {
+
+ APP_PRINT_INFO3("[PRIVACY] Add: i %d, BD %s, type %d\n", i,
+ TRACE_BDADDR(privacy_table[i].addr),
+ privacy_table[i].remote_bd_type);
+ cause = le_privacy_modify_resolv_list(GAP_RESOLV_LIST_OP_ADD,
+ privacy_table[i].remote_bd_type,
+ privacy_table[i].addr);
+ if (cause == GAP_CAUSE_SUCCESS)
+ {
+ privacy_modify_resolv_list_pending = true;
+ privacy_modify_resolv_list_idx = i;
+ privacy_table[i].is_added = PRIVACY_RESOLVING_ADDED_PENDING;
+ if (privacy_whitelist)
+ {
+ le_modify_white_list(GAP_WHITE_LIST_OP_ADD, privacy_table[i].addr,
+ (T_GAP_REMOTE_ADDR_TYPE)privacy_table[i].remote_bd_type);
+ }
+ if (privacy_table[i].device_mode && privacy_mode_manage)
+ {
+ le_privacy_set_mode(privacy_table[i].remote_bd_type, privacy_table[i].addr,
+ GAP_PRIVACY_MODE_DEVICE);
+ }
+ return state;
+ }
+ else if (cause != GAP_CAUSE_INVALID_STATE)
+ {
+ APP_PRINT_ERROR2("[PRIVACY] Add failed: cause %d, remove i=%d from pend add\n", cause, i);
+ memset(&privacy_table[i], 0, sizeof(T_LE_PRIVACY_ENTRY));
+ }
+ else
+ {
+ APP_PRINT_ERROR0("[PRIVACY] Add failed: invalid state");
+ return state;
+ }
+ }
+ else
+ {
+ APP_PRINT_INFO3("[PRIVACY] Remove: i %d, BD %s, type %d", i,
+ TRACE_BDADDR(privacy_table[i].addr),
+ privacy_table[i].remote_bd_type);
+ cause = le_privacy_modify_resolv_list(GAP_RESOLV_LIST_OP_REMOVE,
+ privacy_table[i].remote_bd_type,
+ privacy_table[i].addr);
+ if (cause == GAP_CAUSE_SUCCESS)
+ {
+ privacy_modify_resolv_list_pending = true;
+ privacy_modify_resolv_list_idx = i;
+ if (privacy_whitelist)
+ {
+ le_modify_white_list(GAP_WHITE_LIST_OP_REMOVE, privacy_table[i].addr,
+ (T_GAP_REMOTE_ADDR_TYPE)privacy_table[i].remote_bd_type);
+ }
+ return state;
+ }
+ else if (cause != GAP_CAUSE_INVALID_STATE)
+ {
+ APP_PRINT_ERROR2("[PRIVACY] Remove failed: cause %d, remove i=%d from pend add\n", cause, i);
+ memset(&privacy_table[i], 0, sizeof(T_LE_PRIVACY_ENTRY));
+ }
+ else
+ {
+ APP_PRINT_ERROR0("[PRIVACY] Remove failed: invalid state");
+ return state;
+ }
+ }
+ }
+ }
+ APP_PRINT_INFO0("[PRIVACY] privacy_handle_resolv_list_int: idle");
+ state = PRIVACY_STATE_IDLE;
+ return state;
+}
+
+T_PRIVACY_STATE privacy_handle_resolv_list(void)
+{
+ T_GAP_DEV_STATE dev_state;
+ le_get_gap_param(GAP_PARAM_DEV_STATE, &dev_state);
+ if (privacy_resolution_status == LE_PRIVACY_RESOLUTION_DISABLED
+ || ((dev_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ && (dev_state.gap_conn_state == GAP_CONN_DEV_STATE_IDLE)))
+ {
+ T_PRIVACY_STATE state = privacy_handle_resolv_list_int();
+ privacy_change_state(state);
+ }
+ return privacy_state;
+}
+
+void privacy_handle_bond_modify_msg(T_LE_BOND_MODIFY_TYPE type, T_LE_KEY_ENTRY *p_entry,
+ bool handle_add)
+{
+ APP_PRINT_INFO1("[PRIVACY] privacy_handle_bond_modify_msg: type 0x%x", type);
+
+ if (type == LE_BOND_CLEAR)
+ {
+ privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_CLEAR, GAP_IDENT_ADDR_PUBLIC, NULL, false);
+ }
+ else if (type == LE_BOND_DELETE)
+ {
+ if (p_entry->flags & LE_KEY_STORE_REMOTE_IRK_BIT)
+ {
+ privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE,
+ (T_GAP_IDENT_ADDR_TYPE)p_entry->resolved_remote_bd.remote_bd_type,
+ p_entry->resolved_remote_bd.addr, false);
+ }
+ else
+ {
+ privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE,
+ (T_GAP_IDENT_ADDR_TYPE)p_entry->remote_bd.remote_bd_type,
+ p_entry->remote_bd.addr, false);
+ }
+ }
+ else if (type == LE_BOND_ADD)
+ {
+ if (handle_add)
+ {
+ privacy_add_device(p_entry);
+ }
+ }
+ privacy_handle_resolv_list();
+}
+
+T_GAP_CAUSE privacy_set_addr_resolution(bool enable)
+{
+ return le_privacy_set_addr_resolution(enable);
+}
+
+T_GAP_CAUSE privacy_read_peer_resolv_addr(T_GAP_REMOTE_ADDR_TYPE peer_address_type,
+ uint8_t *peer_address)
+{
+ uint8_t *peer_identity_address = peer_address;
+ uint8_t resolved_addr[6];
+ T_GAP_IDENT_ADDR_TYPE peer_identity_address_type = le_privacy_convert_addr_type(peer_address_type);
+ if (peer_address_type == GAP_REMOTE_ADDR_LE_RANDOM)
+ {
+ if (le_resolve_random_address(peer_address, resolved_addr, &peer_identity_address_type))
+ {
+ peer_identity_address = resolved_addr;
+ }
+ }
+ return le_privacy_read_peer_resolv_addr(peer_identity_address_type, peer_identity_address);
+}
+
+T_GAP_CAUSE privacy_read_local_resolv_addr(T_GAP_REMOTE_ADDR_TYPE peer_address_type,
+ uint8_t *peer_address)
+{
+ uint8_t *peer_identity_address = peer_address;
+ uint8_t resolved_addr[6];
+ T_GAP_IDENT_ADDR_TYPE peer_identity_address_type = le_privacy_convert_addr_type(peer_address_type);
+ if (peer_address_type == GAP_REMOTE_ADDR_LE_RANDOM)
+ {
+ if (le_resolve_random_address(peer_address, resolved_addr, &peer_identity_address_type))
+ {
+ peer_identity_address = resolved_addr;
+ }
+ }
+ return le_privacy_read_local_resolv_addr(peer_identity_address_type, peer_identity_address);
+}
+
+void privacy_manage_mode(bool is_manage)
+{
+ privacy_mode_manage = is_manage;
+}
+
+T_GAP_CAUSE privacy_set_peer_mode(T_GAP_REMOTE_ADDR_TYPE peer_address_type,
+ uint8_t *peer_address, bool device_mode)
+{
+ uint8_t *peer_identity_address = peer_address;
+ uint8_t resolved_addr[6];
+ T_GAP_PRIVACY_MODE privacy_mode = GAP_PRIVACY_MODE_NETWORK;
+ T_GAP_IDENT_ADDR_TYPE peer_identity_address_type = le_privacy_convert_addr_type(peer_address_type);
+ if (peer_address_type == GAP_REMOTE_ADDR_LE_RANDOM)
+ {
+ if (le_resolve_random_address(peer_address, resolved_addr, &peer_identity_address_type))
+ {
+ peer_identity_address = resolved_addr;
+ }
+ }
+ if (device_mode)
+ {
+ privacy_mode = GAP_PRIVACY_MODE_DEVICE;
+ }
+ return le_privacy_set_mode(peer_identity_address_type, peer_identity_address, privacy_mode);
+}
+
+T_GAP_CAUSE privacy_set_gen_priv_addr_interval(uint16_t interval)
+{
+ T_GAP_DEV_STATE dev_state;
+ le_get_gap_param(GAP_PARAM_DEV_STATE, &dev_state);
+ le_privacy_set_param(GAP_PARAM_PRIVACY_TIMEOUT, sizeof(uint16_t), &interval);
+ if (dev_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ return le_privacy_set_resolv_priv_addr_timeout();
+ }
+ return GAP_CAUSE_SUCCESS;
+}
+
+void privacy_modify_resolving_list(T_GAP_RESOLV_LIST_OP op, T_GAP_IDENT_ADDR_TYPE addr_type,
+ uint8_t *addr, bool device_mode)
+{
+ uint8_t bond_storage_num = le_get_max_le_paired_device_num();
+ APP_PRINT_INFO1("[PRIVACY] privacy_modify_resolving_list op = %d", op);
+ switch (op)
+ {
+ case GAP_RESOLV_LIST_OP_CLEAR:
+ privacy_clear_pending = true;
+ privacy_change_state(PRIVACY_STATE_BUSY);
+ break;
+
+ case GAP_RESOLV_LIST_OP_ADD:
+ {
+ uint8_t i;
+ APP_PRINT_INFO2("[PRIVACY] privacy_add_device add: addr %s, addr type %d", TRACE_BDADDR(addr),
+ addr_type);
+ for (i = 0; i < bond_storage_num; i++)
+ {
+ if (privacy_table[i].is_used)
+ {
+ if ((privacy_table[i].remote_bd_type == addr_type)
+ && (memcmp(privacy_table[i].addr, addr, 6) == 0))
+ {
+ APP_PRINT_ERROR0("[PRIVACY] privacy_add_device add: failed, exist");
+ return;
+ }
+ }
+ }
+ for (i = 0; i < bond_storage_num; i++)
+ {
+ if (!privacy_table[i].is_used)
+ {
+ privacy_table[i].is_used = true;
+ privacy_table[i].remote_bd_type = addr_type;
+ memcpy(privacy_table[i].addr, addr, 6);
+ privacy_table[i].state = PRIVACY_RESOLVING_LIST_ADD_PENDING;
+ privacy_table[i].device_mode = device_mode;
+ privacy_change_state(PRIVACY_STATE_BUSY);
+ return;
+ }
+ }
+ APP_PRINT_ERROR0("[PRIVACY] privacy_add_device add: failed, no free entry");
+ }
+ break;
+
+ case GAP_RESOLV_LIST_OP_REMOVE:
+ {
+ uint8_t i;
+ APP_PRINT_INFO2("[PRIVACY] privacy_add_device remove: addr %s, addr type %d", TRACE_BDADDR(addr),
+ addr_type);
+ for (i = 0; i < bond_storage_num; i++)
+ {
+ if (privacy_table[i].is_used)
+ {
+ if ((privacy_table[i].remote_bd_type == addr_type)
+ && (memcmp(privacy_table[i].addr, addr, 6) == 0))
+ {
+ if (privacy_table[i].is_added != PRIVACY_RESOLVING_ADDED_IDLE)
+ {
+ privacy_table[i].state = PRIVACY_RESOLVING_LIST_REMOVE_PENDING;
+ privacy_change_state(PRIVACY_STATE_BUSY);
+ }
+ else
+ {
+ memset(&privacy_table[i], 0, sizeof(T_LE_PRIVACY_ENTRY));
+ APP_PRINT_INFO0("[PRIVACY] privacy_add_device remove: not added");
+ }
+ break;
+ }
+ }
+ }
+ APP_PRINT_ERROR0("[PRIVACY] privacy_add_device remove: failed, no find");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void privacy_handle_le_privacy_resolution_status_info(T_LE_PRIVACY_RESOLUTION_STATUS_INFO
+ resolv_status)
+{
+ APP_PRINT_INFO1("[PRIVACY] privacy_handle_le_privacy_resolution_status_info: status 0x%x\n",
+ resolv_status.status);
+ privacy_resolution_status = resolv_status.status;
+ if (privacy_app_cb)
+ {
+ T_PRIVACY_CB_DATA cb_data;
+ cb_data.resolution_state = (T_PRIVACY_ADDR_RESOLUTION_STATE)resolv_status.status;
+ privacy_app_cb(PRIVACY_RESOLUTION_STATUS_MSGTYPE, cb_data);
+ }
+}
+
+void privacy_handle_le_privacy_modify_resolv_list_rsp(T_LE_PRIVACY_MODIFY_RESOLV_LIST_RSP *p_rsp)
+{
+ uint8_t bond_storage_num = le_get_max_le_paired_device_num();
+ APP_PRINT_INFO2("[PRIVACY] privacy_handle_le_privacy_modify_resolv_list_rsp: operation 0x%x, casue 0x%x",
+ p_rsp->operation, p_rsp->cause);
+ privacy_modify_resolv_list_pending = false;
+ if (p_rsp->cause != GAP_SUCCESS)
+ {
+ if (p_rsp->cause == (HCI_ERR | HCI_ERR_UNKNOWN_CONN_ID)
+ || p_rsp->cause == (HCI_ERR | HCI_ERR_MEMORY_FULL)
+ || p_rsp->cause == (HCI_ERR | HCI_ERR_INVALID_PARAM))
+ {
+ memset(&privacy_table[privacy_modify_resolv_list_idx], 0, sizeof(T_LE_PRIVACY_ENTRY));
+ }
+ privacy_modify_resolv_list_idx = 0xff;
+ }
+ else
+ {
+ if (p_rsp->operation == GAP_RESOLV_LIST_OP_CLEAR)
+ {
+ privacy_clear_pending = false;
+ memset(privacy_table, 0, bond_storage_num * sizeof(T_LE_PRIVACY_ENTRY));
+ }
+ else if (p_rsp->operation == GAP_RESOLV_LIST_OP_ADD)
+ {
+ if (privacy_modify_resolv_list_idx < bond_storage_num)
+ {
+ privacy_table[privacy_modify_resolv_list_idx].is_added = PRIVACY_RESOLVING_ADDED;
+ privacy_table[privacy_modify_resolv_list_idx].state = PRIVACY_RESOLVING_LIST_IDLE;
+ privacy_modify_resolv_list_idx = 0xff;
+ }
+ }
+ else
+ {
+ if (privacy_modify_resolv_list_idx < bond_storage_num)
+ {
+ memset(&privacy_table[privacy_modify_resolv_list_idx], 0, sizeof(T_LE_PRIVACY_ENTRY));
+ privacy_modify_resolv_list_idx = 0xff;
+ }
+ }
+ privacy_handle_resolv_list();
+ }
+}
+
+T_APP_RESULT privacy_msg_callback(uint8_t msg_type, T_LE_PRIVACY_CB_DATA msg_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ APP_PRINT_INFO1("[PRIVACY] privacy_msg_callback: msg_type %d", msg_type);
+
+ switch (msg_type)
+ {
+ case GAP_MSG_LE_PRIVACY_RESOLUTION_STATUS_INFO:
+ privacy_handle_le_privacy_resolution_status_info(msg_data.le_privacy_resolution_status_info);
+ break;
+
+ case GAP_MSG_LE_PRIVACY_MODIFY_RESOLV_LIST:
+ privacy_handle_le_privacy_modify_resolv_list_rsp(msg_data.p_le_privacy_modify_resolv_list_rsp);
+ break;
+
+ case GAP_MSG_LE_PRIVACY_SET_MODE:
+ APP_PRINT_INFO1("[PRIVACY] GAP_MSG_LE_PRIVACY_SET_MODE: cause 0x%x",
+ msg_data.p_le_privacy_set_mode_rsp->cause);
+ if (privacy_mode_manage == false && privacy_app_cb)
+ {
+ T_PRIVACY_CB_DATA cb_data;
+ cb_data.cause = msg_data.p_le_privacy_set_mode_rsp->cause;
+ privacy_app_cb(PRIVACY_SET_PEER_MODE_MSGTYPE, cb_data);
+ }
+ break;
+
+ case GAP_MSG_LE_PRIVACY_SET_RESOLV_PRIV_ADDR_TIMEOUT:
+ APP_PRINT_INFO1("[PRIVACY] GAP_MSG_LE_PRIVACY_SET_RESOLV_PRIV_ADDR_TIMEOUT: cause 0x%x",
+ msg_data.p_le_privacy_set_resolv_priv_addr_timeout_rsp->cause);
+ if (privacy_app_cb)
+ {
+ T_PRIVACY_CB_DATA cb_data;
+ cb_data.cause = msg_data.p_le_privacy_set_resolv_priv_addr_timeout_rsp->cause;
+ privacy_app_cb(PRIVACY_GEN_PRIV_ADDR_INTERVAL_MSGTYPE, cb_data);
+ }
+ break;
+
+ case GAP_MSG_LE_PRIVACY_READ_PEER_RESOLV_ADDR:
+ APP_PRINT_INFO1("[PRIVACY] GAP_MSG_LE_PRIVACY_READ_PEER_RESOLV_ADDR: cause 0x%x",
+ msg_data.p_le_privacy_read_peer_resolv_addr_rsp->cause);
+ if (privacy_app_cb)
+ {
+ T_PRIVACY_CB_DATA cb_data;
+ cb_data.p_privacy_read_resolv_addr_rsp = (T_PRIVACY_READ_RESOLV_ADDR_RSP *)
+ msg_data.p_le_privacy_read_peer_resolv_addr_rsp;
+ privacy_app_cb(PRIVACY_READ_PEER_RESOLV_ADDR_MSGTYPE, cb_data);
+ }
+ break;
+
+ case GAP_MSG_LE_PRIVACY_READ_LOCAL_RESOLV_ADDR:
+ APP_PRINT_INFO1("[PRIVACY] GAP_MSG_LE_PRIVACY_READ_LOCAL_RESOLV_ADDR: cause 0x%x",
+ msg_data.p_le_privacy_read_local_resolv_addr_rsp->cause);
+ if (privacy_app_cb)
+ {
+ T_PRIVACY_CB_DATA cb_data;
+ cb_data.p_privacy_read_resolv_addr_rsp = (T_PRIVACY_READ_RESOLV_ADDR_RSP *)
+ msg_data.p_le_privacy_read_local_resolv_addr_rsp;
+ privacy_app_cb(PRIVACY_READ_LOCAL_RESOLV_ADDR_MSGTYPE, cb_data);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
diff --git a/src/ble/privacy/privacy_mgnt.h b/src/ble/privacy/privacy_mgnt.h
new file mode 100644
index 0000000..8984167
--- /dev/null
+++ b/src/ble/privacy/privacy_mgnt.h
@@ -0,0 +1,492 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file privacy_mgnt.h
+ * @brief privacy management module.
+ * @details privacy management module.
+ * @author jane
+ * @date 2018-06-19
+ * @version v0.1
+ * *************************************************************************************
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef _PRIVACY_MGNT_H_
+#define _PRIVACY_MGNT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_bond_le.h>
+
+/** @defgroup BLE_PRIV_MODULE BLE Privacy Management Module
+ * @brief Application uses this module to handle privacy procedures.
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup BLE_PRIV_MODULE_Exported_Types BLE Privacy Management Module Exported Types
+ * @{
+ */
+/** @brief Privacy management module callback type*/
+typedef enum
+{
+ PRIVACY_STATE_MSGTYPE, //!< Privacy management module state.
+ PRIVACY_RESOLUTION_STATUS_MSGTYPE, //!< Response msg type for privacy_set_addr_resolution
+ PRIVACY_READ_PEER_RESOLV_ADDR_MSGTYPE, //!< Response msg type for privacy_read_peer_resolv_addr
+ PRIVACY_READ_LOCAL_RESOLV_ADDR_MSGTYPE,//!< Response msg type for privacy_read_local_resolv_addr
+ PRIVACY_GEN_PRIV_ADDR_INTERVAL_MSGTYPE,//!< Response msg type for privacy_set_gen_priv_addr_interval
+ PRIVACY_SET_PEER_MODE_MSGTYPE,
+} T_PRIVACY_CB_TYPE;
+
+/** @brief Privacy management module state*/
+typedef enum
+{
+ PRIVACY_STATE_INIT, //!< Privacy management module is not initialization.
+ PRIVACY_STATE_IDLE, //!< Idle. No pending resolving list modification procedure.
+ PRIVACY_STATE_BUSY //!< Busy. Resolving list modification procedure is not completed.
+} T_PRIVACY_STATE;
+
+/** @brief Define the privacy address resolution state */
+typedef enum
+{
+ PRIVACY_ADDR_RESOLUTION_DISABLED,
+ PRIVACY_ADDR_RESOLUTION_DISABLING,
+ PRIVACY_ADDR_RESOLUTION_ENABLING,
+ PRIVACY_ADDR_RESOLUTION_ENABLED
+} T_PRIVACY_ADDR_RESOLUTION_STATE;
+
+/** @brief Callback data of PRIVACY_READ_PEER_RESOLV_ADDR_MSGTYPE or PRIVACY_READ_LOCAL_RESOLV_ADDR_MSGTYPE*/
+typedef struct
+{
+ uint16_t cause;
+ uint8_t resolv_addr[6];
+} T_PRIVACY_READ_RESOLV_ADDR_RSP;
+
+/** @brief Privacy management module callback data */
+typedef union
+{
+ uint16_t cause; //!< Callback data of PRIVACY_GEN_PRIV_ADDR_INTERVAL_MSGTYPE
+ T_PRIVACY_STATE privacy_state; //!< Callback data of PRIVACY_STATE_MSGTYPE
+ T_PRIVACY_ADDR_RESOLUTION_STATE
+ resolution_state; //!< Callback data of PRIVACY_RESOLUTION_STATUS_MSGTYPE
+ T_PRIVACY_READ_RESOLV_ADDR_RSP *p_privacy_read_resolv_addr_rsp;
+} T_PRIVACY_CB_DATA;
+/** End of BLE_PRIV_MODULE_Exported_Types
+ * @}
+ */
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @defgroup BLE_PRIV_MODULE_EXPORT_Functions BLE Privacy Management Module Exported Functions
+ *
+ * @{
+ */
+/**
+ * @brief Callback for privacy management module to notify app
+ * @param[in] type callback msy type @ref T_PRIVACY_CB_TYPE.
+ * @param[in] cb_data callback data @ref T_PRIVACY_CB_DATA.
+ * @retval void
+ */
+typedef void(*P_FUN_PRIVACY_STATE_CB)(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data);
+
+/**
+ * @brief Initialize privacy management module.
+ * @param[in] p_fun Callback function provided by the APP to handle privacy messages sent from the privacy management module.
+ * @param[in] whitelist Whether manage the white list when modify the resolving list.
+ * @return none
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_gap_init(void)
+ {
+ ......
+ privacy_init(app_privacy_callback, true);
+ }
+ void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data)
+ {
+ APP_PRINT_INFO1("app_privacy_callback: type %d", type);
+ switch (type)
+ {
+ case PRIVACY_STATE_MSGTYPE:
+ app_privacy_state = cb_data.privacy_state;
+ break;
+
+ case PRIVACY_RESOLUTION_STATUS_MSGTYPE:
+ app_privacy_resolution_state = cb_data.resolution_state;
+ break;
+
+ default:
+ break;
+ }
+ }
+ * \endcode
+ */
+void privacy_init(P_FUN_PRIVACY_STATE_CB p_fun, bool whitelist);
+
+/**
+ * @brief Handle the pending resolving list modification procedure.
+ *
+ * Application shall call this function when the device state is in the idle state.
+ *
+ * @return The current privacy management module state.
+ * @retval T_PRIVACY_STATE module state
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+ {
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+
+ if ((new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ && (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ && (new_state.gap_conn_state == GAP_CONN_DEV_STATE_IDLE))
+ {
+ privacy_handle_resolv_list();
+ }
+
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ app_adv_start();
+ }
+ }
+ ......
+ }
+ * \endcode
+ */
+T_PRIVACY_STATE privacy_handle_resolv_list(void);
+
+/**
+ * @brief Hande the GAP_MSG_LE_BOND_MODIFY_INFO message.
+ *
+ * Application shall call this function to handle the message GAP_MSG_LE_BOND_MODIFY_INFO.
+ *
+ * @param[in] type Bond modification type @ref T_LE_BOND_MODIFY_TYPE.
+ * @param[in] p_entry The key entry of the modified device.
+ * @param[in] handle_add Whether handle the type @ref LE_BOND_ADD.
+ * @return none
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ ......
+ case GAP_MSG_LE_BOND_MODIFY_INFO:
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x",
+ p_data->p_le_bond_modify_info->type);
+ privacy_handle_bond_modify_msg(p_data->p_le_bond_modify_info->type,
+ p_data->p_le_bond_modify_info->p_entry, true);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+ }
+ * \endcode
+ */
+void privacy_handle_bond_modify_msg(T_LE_BOND_MODIFY_TYPE type, T_LE_KEY_ENTRY *p_entry,
+ bool handle_add);
+
+/**
+ * @brief Add the device to the resolving list.
+ *
+ * Application can call this funcation when the parameter handle_add of the privacy_handle_bond_modify_msg is false.
+ *
+ * @param[in] p_entry The key entry of the device.
+ * @return result
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+ {
+ ......
+ switch (cb_type)
+ {
+ ......
+ case GAP_MSG_LE_BOND_MODIFY_INFO:
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x",
+ p_data->p_le_bond_modify_info->type);
+ privacy_handle_bond_modify_msg(p_data->p_le_bond_modify_info->type,
+ p_data->p_le_bond_modify_info->p_entry, false);
+ break;
+ }
+ return result;
+ }
+ bool app_save_privacy_info(uint8_t conn_id)
+ {
+ if (app_link_table[conn_id].p_entry != NULL)
+ {
+ le_set_privacy_info(app_link_table[conn_id].p_entry, &app_link_table[conn_id].privacy_info);
+ privacy_add_device(app_link_table[conn_id].p_entry);
+ privacy_handle_resolv_list();
+ }
+ return true;
+ }
+ * \endcode
+ */
+bool privacy_add_device(T_LE_KEY_ENTRY *p_entry);
+
+/**
+ * @brief Enable/disable le privacy address resolution mode.
+ * @param[in] enable Enable or disable address resolution.
+ * @return Operation result
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_adv_start(void)
+ {
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ T_LE_KEY_ENTRY *p_entry;
+ p_entry = le_get_high_priority_bond();
+
+ if (p_entry == NULL)
+ {
+ app_work_mode = APP_PAIRABLE_MODE;
+ adv_filter_policy = GAP_ADV_FILTER_ANY;
+ if (app_privacy_resolution_state == PRIVACY_ADDR_RESOLUTION_ENABLED)
+ {
+ privacy_set_addr_resolution(false);
+ }
+ }
+ ......
+ }
+ void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data)
+ {
+ APP_PRINT_INFO1("app_privacy_callback: type %d", type);
+ switch (type)
+ {
+ case PRIVACY_RESOLUTION_STATUS_MSGTYPE:
+ app_privacy_resolution_state = cb_data.resolution_state;
+ break;
+
+ ......
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE privacy_set_addr_resolution(bool enable);
+
+/**
+ * @brief Read peer resolvable random address.
+ * @param[in] peer_address_type Peer address type.
+ * @param[in] peer_address Peer address.
+ * @return Operation result
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_readpra(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t idx = p_parse_value->dw_param[0];
+ T_GAP_CAUSE cause;
+ T_LE_KEY_ENTRY *p_entry;
+ p_entry = le_find_key_entry_by_idx(idx);
+ if (p_entry)
+ {
+ cause = privacy_read_peer_resolv_addr((T_GAP_REMOTE_ADDR_TYPE)p_entry->remote_bd.remote_bd_type,
+ p_entry->remote_bd.addr);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ else
+ {
+ return RESULT_ERR;
+ }
+ }
+ void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data)
+ {
+ APP_PRINT_INFO1("app_privacy_callback: type %d", type);
+ switch (type)
+ {
+ case PRIVACY_READ_PEER_RESOLV_ADDR_MSGTYPE:
+ APP_PRINT_INFO2("PRIVACY_READ_PEER_RESOLV_ADDR_MSGTYPE: cause 0x%x, addr %b",
+ cb_data.p_privacy_read_resolv_addr_rsp->cause,
+ TRACE_BDADDR(cb_data.p_privacy_read_resolv_addr_rsp->resolv_addr));
+ break;
+
+ default:
+ break;
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE privacy_read_peer_resolv_addr(T_GAP_REMOTE_ADDR_TYPE peer_address_type,
+ uint8_t *peer_address);
+
+/**
+ * @brief Read local resolvable random address.
+ * @param[in] peer_address_type Peer address type.
+ * @param[in] peer_address Peer address.
+ * @return Operation result
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_readlra(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t idx = p_parse_value->dw_param[0];
+ T_GAP_CAUSE cause;
+ T_LE_KEY_ENTRY *p_entry;
+ p_entry = le_find_key_entry_by_idx(idx);
+ if (p_entry)
+ {
+ cause = privacy_read_local_resolv_addr((T_GAP_REMOTE_ADDR_TYPE)p_entry->remote_bd.remote_bd_type,
+ p_entry->remote_bd.addr);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ else
+ {
+ return RESULT_ERR;
+ }
+ }
+ void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data)
+ {
+ APP_PRINT_INFO1("app_privacy_callback: type %d", type);
+ switch (type)
+ {
+ case PRIVACY_READ_LOCAL_RESOLV_ADDR_MSGTYPE:
+ APP_PRINT_INFO2("PRIVACY_READ_LOCAL_RESOLV_ADDR_MSGTYPE: cause 0x%x, addr %b",
+ cb_data.p_privacy_read_resolv_addr_rsp->cause,
+ TRACE_BDADDR(cb_data.p_privacy_read_resolv_addr_rsp->resolv_addr));
+ break;
+
+ default:
+ break;
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE privacy_read_local_resolv_addr(T_GAP_REMOTE_ADDR_TYPE peer_address_type,
+ uint8_t *peer_address);
+
+/**
+ * @brief Set privacy address generation interavl.
+ * @param[in] interval Privacy address generation interavl.
+ * Range:0x0001 - 0xA1B8(1s/step). Default value is 0x0384.
+ * @return Operation result
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint16_t privacy_timeout = 0x384;
+ privacy_set_gen_priv_addr_interval(privacy_timeout);
+ }
+ void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data)
+ {
+ APP_PRINT_INFO1("app_privacy_callback: type %d", type);
+ switch (type)
+ {
+ case PRIVACY_GEN_PRIV_ADDR_INTERVAL_MSGTYPE:
+ APP_PRINT_INFO1("PRIVACY_GEN_PRIV_ADDR_INTERVAL_MSGTYPE: cause 0x%x", cb_data.cause);
+ break;
+
+ default:
+ break;
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE privacy_set_gen_priv_addr_interval(uint16_t interval);
+
+/**
+ * @brief Configure privacy management module whether manage privacy mode when add device to the resolving list.
+ * @param[in] is_manage Whether manage privacy mode.
+ * @return None
+ */
+void privacy_manage_mode(bool is_manage);
+
+/**
+ * @brief Configure privacy mode.
+ *
+ * The default mode is network privacy mode.
+ * Application can call this funcation when the parameter is_manage of the privacy_manage_mode() is false.
+ *
+ * @param[in] peer_address_type Peer address type.
+ * @param[in] peer_address Peer address.
+ * @param[in] device_mode Configure the privacy mode.
+ * false - Network Privacy mode
+ * true - Device Privacy mode
+ * @return Operation result
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval Others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_gap_init(void)
+ {
+ ......
+ privacy_manage_mode(false);
+ privacy_init(app_privacy_callback, true);
+ }
+ static T_USER_CMD_PARSE_RESULT cmd_setprivacy(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t idx = p_parse_value->dw_param[0];
+ bool mode = p_parse_value->dw_param[1];
+ T_LE_KEY_ENTRY *p_entry;
+ T_GAP_CAUSE cause;
+ p_entry = le_find_key_entry_by_idx(idx);
+ if (p_entry != NULL)
+ {
+ cause = privacy_set_peer_mode((T_GAP_REMOTE_ADDR_TYPE)p_entry->remote_bd.remote_bd_type,
+ p_entry->remote_bd.addr,
+ mode);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ else
+ {
+ return RESULT_CMD_ERR_PARAM;
+ }
+ }
+ void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data)
+ {
+ APP_PRINT_INFO1("app_privacy_callback: type %d", type);
+ switch (type)
+ {
+ case PRIVACY_SET_PEER_MODE_MSGTYPE:
+ APP_PRINT_INFO1("PRIVACY_SET_PEER_MODE_MSGTYPE: cause 0x%x", cb_data.cause);
+ break;
+
+ default:
+ break;
+ }
+ }
+ * \endcode
+ */
+T_GAP_CAUSE privacy_set_peer_mode(T_GAP_REMOTE_ADDR_TYPE peer_address_type,
+ uint8_t *peer_address, bool device_mode);
+
+
+/** @} */ /* End of group BLE_PRIV_MODULE_EXPORT_Functions */
+/** @} */ /* End of group BLE_PRIV_MODULE */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PRIVACY_MGNT_H_ */
diff --git a/src/ble/profile/client/ams_client.c b/src/ble/profile/client/ams_client.c
new file mode 100644
index 0000000..46861d2
--- /dev/null
+++ b/src/ble/profile/client/ams_client.c
@@ -0,0 +1,536 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ams_client.c
+ * @brief
+ * @details
+ * @author
+ * @date
+ * @version v1.0
+ ***************************************************************************************
+*/
+#include <string.h>
+#include "ams_client.h"
+#include "os_mem.h"
+#include "trace.h"
+
+/**
+ * @brief AMS Link control block definition.
+ */
+typedef struct
+{
+ T_AMS_DISC_STATE disc_state;
+ bool remote_cmd_notify;
+ bool entity_upd_notify;
+ uint16_t hdl_cache[AMS_HDL_CACHE_LEN];
+} T_AMS_LINK, *P_AMS_LINK;
+
+//AMS service UUID 89D3502B-0F36-433A-8EF4-C502AD55F8DC
+uint8_t AMS_SRV_UUID128[16] = {0xdc, 0xf8, 0x55, 0xad, 0x02, 0xc5, 0xf4, 0x8e, 0x3a, 0x43, 0x36, 0x0f, 0x2b, 0x50, 0xd3, 0x89};
+//Remote Command UUID 9B3C81D8-57B1-4A8A-B8DF-0E56F7CA51C2 (writeable, notifiable)
+const uint8_t AMS_CHAR_REMOTE_CMD_UUID128[16] = {0xc2, 0x51, 0xca, 0xf7, 0x56, 0x0e, 0xdf, 0xb8, 0x8a, 0x4a, 0xb1, 0x57, 0xd8, 0x81, 0x3c, 0x9b};
+//Entity Update UUID 2F7CABCE-808D-411F-9A0C-BB92BA96C102 (writeable with response, notifiable)
+const uint8_t AMS_CHAR_ENTITY_UPD_UUID128[16] = {0x02, 0xc1, 0x96, 0xba, 0x92, 0xbb, 0x0c, 0x9a, 0x1f, 0x41, 0x8d, 0x80, 0xce, 0xab, 0x7c, 0x2f};
+//Entity Attribute UUID C6B2F38C-23AB-46D8-A6AB-A3A870BBD5D7 (readable, writeable)
+const uint8_t AMS_CHAR_ENTITY_ATTR_UUID128[16] = {0xd7, 0xd5, 0xbb, 0x70, 0xa8, 0xa3, 0xab, 0xa6, 0xd8, 0x46, 0xab, 0x23, 0x8c, 0xf3, 0xb2, 0xc6};
+
+P_AMS_LINK ams_table;
+static uint8_t ams_link_num;
+T_CLIENT_ID ams_client_id = CLIENT_PROFILE_GENERAL_ID;
+static P_FUN_GENERAL_APP_CB ams_client_cb = NULL;
+
+uint16_t ams_search_handle(uint8_t conn_id, T_AMS_HANDLE_TYPE handle_type)
+{
+ uint16_t handle = 0;
+ P_AMS_LINK link_info = ams_table;
+
+ if (handle_type >= AMS_HDL_CACHE_LEN)
+ {
+ APP_PRINT_ERROR1("ams_search_handle: no handle_type %d", handle_type);
+ return AMS_HDL_CACHE_LEN;
+ }
+
+ handle = link_info[conn_id].hdl_cache[handle_type];
+
+ APP_PRINT_INFO1("ams_search_handle: ams handle 0x%08x", handle);
+
+ return handle;
+}
+
+
+
+/**
+ * @brief start AMS service discovery procedure.
+ */
+bool ams_start_discovery(uint8_t conn_id)
+{
+ if (conn_id >= ams_link_num)
+ {
+ PROFILE_PRINT_ERROR2("ams_start_discovery: failed invalid conn_id %d, ams_link_num = %d", conn_id,
+ ams_link_num);
+ return false;
+ }
+
+ //clear handle cache first
+ memset(ams_table[conn_id].hdl_cache, 0, 2 * AMS_HDL_CACHE_LEN);
+ ams_table[conn_id].disc_state = AMS_DISC_START;
+ APP_PRINT_INFO0("ams_start_discovery");
+ if (client_by_uuid128_srv_discovery(conn_id, ams_client_id, AMS_SRV_UUID128) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief start AMS characteristic discovery procedure.
+ */
+bool ams_discovery_char(uint8_t conn_id)
+{
+ uint16_t start_handle = ams_table[conn_id].hdl_cache[AMS_HDL_SRV_START];
+ uint16_t end_handle = ams_table[conn_id].hdl_cache[AMS_HDL_SRV_END];
+
+ APP_PRINT_INFO0("ams_start_char_discovery");
+ if (client_all_char_discovery(conn_id, ams_client_id, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief AMS remote command subscribe.
+ */
+bool ams_subscribe_remote_cmd(uint8_t conn_id, bool subscribe)
+{
+ uint16_t handle;
+ if (conn_id >= ams_link_num)
+ {
+ PROFILE_PRINT_ERROR1("ams_subscribe_remote_cmd: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ handle = ams_table[conn_id].hdl_cache[AMS_HDL_REMOTE_CMD_CCCD];
+ if (handle)
+ {
+ uint16_t cccd = subscribe ? 1 : 0;
+ APP_PRINT_INFO0("ams_subscribe_remote_cmd");
+ if (client_attr_write(conn_id, ams_client_id, GATT_WRITE_TYPE_REQ, handle, sizeof(uint16_t),
+ (uint8_t *)&cccd) == GAP_CAUSE_SUCCESS)
+ {
+ ams_table[conn_id].remote_cmd_notify = 1;
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * @brief AMS write remote command.
+ */
+bool ams_write_remote_cmd(uint8_t conn_id, T_AMS_REMOTE_CMD_ID cmd_id)
+{
+ uint16_t handle = ams_table[conn_id].hdl_cache[AMS_HDL_REMOTE_CMD_VALUE];
+ if (handle)
+ {
+ APP_PRINT_INFO0("ams_write_remote_cmd");
+ if (client_attr_write(conn_id, ams_client_id, GATT_WRITE_TYPE_REQ, handle,
+ 1, (uint8_t *)&cmd_id) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/**
+ * @brief AMS entity update subscribe.
+ */
+bool ams_subscribe_entity_upd(uint8_t conn_id, bool subscribe)
+{
+ uint16_t handle;
+ if (conn_id >= ams_link_num)
+ {
+ PROFILE_PRINT_ERROR1("ams_subscribe_entity_upd: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ handle = ams_table[conn_id].hdl_cache[AMS_HDL_ENTITY_UPD_CCCD];
+ if (handle)
+ {
+ uint16_t cccd = subscribe ? 1 : 0;
+ APP_PRINT_INFO0("ams_subscribe_entity_upd");
+ if (client_attr_write(conn_id, ams_client_id, GATT_WRITE_TYPE_REQ, handle, sizeof(uint16_t),
+ (uint8_t *)&cccd) == GAP_CAUSE_SUCCESS)
+ {
+ ams_table[conn_id].entity_upd_notify = 1;
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * @brief AMS write entity update command.
+ entity_attr_id, first byte is entity id, the other bytes are attribute id list.
+ */
+bool ams_write_entity_upd_cmd(uint8_t conn_id, uint8_t *p_value, uint8_t value_len)
+{
+ uint16_t handle = ams_table[conn_id].hdl_cache[AMS_HDL_ENTITY_UPD_VALUE];
+ if (handle)
+ {
+ APP_PRINT_INFO0("ams_write_entity_upd_cmd");
+ if (client_attr_write(conn_id, ams_client_id, GATT_WRITE_TYPE_REQ, handle,
+ value_len, p_value) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/**
+ * @brief AMS write entity attribute.
+ */
+bool ams_write_entity_attr(uint8_t conn_id, T_AMS_ENTITY_ATTR entity_attr)
+{
+ uint16_t handle = ams_table[conn_id].hdl_cache[AMS_HDL_ENTITY_ATTR_VALUE];
+ if (handle)
+ {
+ APP_PRINT_INFO0("ams_write_entity_attr");
+ if (client_attr_write(conn_id, ams_client_id, GATT_WRITE_TYPE_REQ, handle, sizeof(entity_attr),
+ (uint8_t *)&entity_attr) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/**
+ * @brief AMS read entity attribute.
+ */
+bool ams_read_entity_attr(uint8_t conn_id, T_AMS_ENTITY_ATTR entity_attr)
+{
+ uint16_t handle = ams_table[conn_id].hdl_cache[AMS_HDL_ENTITY_ATTR_VALUE];
+ if (handle)
+ {
+ APP_PRINT_INFO0("ams_read_entity_attr");
+ if (client_attr_read(conn_id, ams_client_id, handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/**
+ * @brief Called by profile client layer, when discover state of discovery procedure changed.
+ */
+static void ams_client_cb_discover_state(uint8_t conn_id, T_DISCOVERY_STATE discovery_state)
+{
+ bool cb_flag = false;
+ T_AMS_CB_DATA cb_data;
+ cb_data.cb_type = AMS_CLIENT_CB_TYPE_DISC_STATE;
+
+ APP_PRINT_INFO1("ams_client_cb_discover_state: discovery state = %d", discovery_state);
+ if (ams_table[conn_id].disc_state == AMS_DISC_START)
+ {
+ switch (discovery_state)
+ {
+ case DISC_STATE_SRV_DONE:
+ if ((ams_table[conn_id].hdl_cache[AMS_HDL_SRV_START] != 0) ||
+ (ams_table[conn_id].hdl_cache[AMS_HDL_SRV_END] != 0))
+ {
+ // start discover characteristic.
+ if (ams_discovery_char(conn_id) == false)
+ {
+ ams_table[conn_id].disc_state = AMS_DISC_FAILED;
+ cb_flag = true;
+ }
+ }
+ else // No AMS handle found.
+ {
+ ams_table[conn_id].disc_state = AMS_DISC_FAILED;
+ cb_flag = true;
+ }
+ break;
+
+ case DISC_STATE_CHAR_DONE:
+ ams_table[conn_id].disc_state = AMS_DISC_DONE;
+ cb_flag = true;
+ break;
+
+ case DISC_STATE_FAILED:
+ ams_table[conn_id].disc_state = AMS_DISC_FAILED;
+ cb_flag = true;
+ break;
+
+ default:
+ APP_PRINT_ERROR0("ams_client_cb_discover_state: invalid discovery state!");
+ break;
+ }
+ }
+
+ // send discover state to app if need
+ if (cb_flag && ams_client_cb)
+ {
+ cb_data.cb_content.disc_state = ams_table[conn_id].disc_state;
+ (*ams_client_cb)(ams_client_id, conn_id, &cb_data);
+ }
+ return;
+}
+
+/**
+ * @brief Called by profile client layer, when discover result fetched.
+ */
+static void ams_client_cb_discover_result(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ APP_PRINT_INFO1("ams_client_discover_result_cb: result type = %d", result_type);
+ if (ams_table[conn_id].disc_state == AMS_DISC_START)
+ {
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ {
+ ams_table[conn_id].hdl_cache[AMS_HDL_SRV_START] = result_data.p_srv_disc_data->att_handle;
+ ams_table[conn_id].hdl_cache[AMS_HDL_SRV_END] = result_data.p_srv_disc_data->end_group_handle;
+ }
+ break;
+
+ case DISC_RESULT_CHAR_UUID128:
+ {
+ uint16_t handle;
+ handle = result_data.p_char_uuid128_disc_data->value_handle;
+ if (0 == memcmp(AMS_CHAR_REMOTE_CMD_UUID128, result_data.p_char_uuid128_disc_data->uuid128, 16))
+ {
+ ams_table[conn_id].hdl_cache[AMS_HDL_REMOTE_CMD_VALUE] = handle;
+ ams_table[conn_id].hdl_cache[AMS_HDL_REMOTE_CMD_CCCD] = handle + 2;
+ }
+ else if (0 == memcmp(AMS_CHAR_ENTITY_UPD_UUID128, result_data.p_char_uuid128_disc_data->uuid128,
+ 16))
+ {
+ ams_table[conn_id].hdl_cache[AMS_HDL_ENTITY_UPD_VALUE] = handle;
+ ams_table[conn_id].hdl_cache[AMS_HDL_ENTITY_UPD_CCCD] = handle + 2;
+ }
+ else if (0 == memcmp(AMS_CHAR_ENTITY_ATTR_UUID128, result_data.p_char_uuid128_disc_data->uuid128,
+ 16))
+ {
+ ams_table[conn_id].hdl_cache[AMS_HDL_ENTITY_ATTR_VALUE] = handle;
+ }
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR0("ams_client_discover_result_cb: invalid discovery result type");
+ break;
+ }
+ }
+
+ return;
+}
+
+static void ams_client_cb_read_result(uint8_t conn_id, uint16_t cause,
+ uint16_t handle, uint16_t value_size, uint8_t *p_value)
+{
+ T_AMS_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = ams_table[conn_id].hdl_cache;
+
+ cb_data.cb_type = AMS_CLIENT_CB_TYPE_READ_RESULT;
+
+ APP_PRINT_INFO2("ams_client_cb_read_result: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.read_data.cause = cause;
+
+ if (handle == hdl_cache[AMS_HDL_ENTITY_ATTR_VALUE])
+ {
+ cb_data.cb_content.read_data.type = AMS_READ_FROM_ENTITY_UPD;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_data.p_value = p_value;
+ cb_data.cb_content.read_data.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_data.value_size = 0;
+ }
+ }
+ else
+ {
+ return;
+ }
+ /* Inform application the read result. */
+ if (ams_client_cb)
+ {
+ (*ams_client_cb)(ams_client_id, conn_id, &cb_data);
+ }
+
+ return;
+}
+
+/**
+ * @brief Called by profile client layer, when write result arrived.
+ */
+static void ams_client_cb_write_result(uint8_t conn_id, T_GATT_WRITE_TYPE type, uint16_t handle,
+ uint16_t cause, uint8_t credits)
+{
+ T_AMS_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = ams_table[conn_id].hdl_cache;
+ cb_data.cb_type = AMS_CLIENT_CB_TYPE_WRITE_RESULT;
+
+ APP_PRINT_INFO2("ams_client_write_result_cb: handle=0x%x cause = 0x%x", handle, cause);
+ cb_data.cb_content.write_result.cause = cause;
+
+ if (handle == hdl_cache[AMS_HDL_REMOTE_CMD_CCCD])
+ {
+ if (ams_table[conn_id].remote_cmd_notify == 1)
+ {
+ cb_data.cb_content.write_result.type = AMS_WRITE_REMOTE_CMD_NOTIFY_ENABLE;
+ }
+ else
+ {
+ cb_data.cb_content.write_result.type = AMS_WRITE_REMOTE_CMD_NOTIFY_DISABLE;
+ }
+ }
+ else if (handle == hdl_cache[AMS_HDL_ENTITY_UPD_CCCD])
+ {
+ if (ams_table[conn_id].entity_upd_notify == 1)
+ {
+ cb_data.cb_content.write_result.type = AMS_WRITE_ENTITY_UPD_NOTIFY_ENABLE;
+ }
+ else
+ {
+ cb_data.cb_content.write_result.type = AMS_WRITE_ENTITY_UPD_NOTIFY_DISABLE;
+ }
+ }
+ else if (handle == hdl_cache[AMS_HDL_REMOTE_CMD_VALUE])
+ {
+ cb_data.cb_content.write_result.type = AMS_WRITE_REMOTE_CMD_VALUE;
+ }
+ else if (handle == hdl_cache[AMS_HDL_ENTITY_UPD_VALUE])
+ {
+ cb_data.cb_content.write_result.type = AMS_WRITE_ENTITY_UPD_VALUE;
+ }
+ else if (handle == hdl_cache[AMS_HDL_ENTITY_ATTR_VALUE])
+ {
+ cb_data.cb_content.write_result.type = AMS_WRITE_ENTITY_ATTR_VALUE;
+ }
+ else
+ {
+ return;
+ }
+
+ if (ams_client_cb)
+ {
+ (*ams_client_cb)(ams_client_id, conn_id, &cb_data);
+ }
+
+ return;
+}
+
+/**
+ * @brief Called by profile client layer, when notification or indication arrived.
+ */
+static T_APP_RESULT ams_client_cb_notify_ind(uint8_t conn_id, bool notify, uint16_t handle,
+ uint16_t value_size, uint8_t *p_value)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ T_AMS_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+
+ hdl_cache = ams_table[conn_id].hdl_cache;
+ cb_data.cb_type = AMS_CLIENT_CB_TYPE_NOTIF_IND_RESULT;
+
+ if (handle == hdl_cache[AMS_HDL_REMOTE_CMD_VALUE])
+ {
+ cb_data.cb_content.notify_data.type = AMS_NOTIFY_FROM_REMOTE_CMD;
+ cb_data.cb_content.notify_data.value_size = value_size;
+ cb_data.cb_content.notify_data.p_value = p_value;
+ }
+ else if (handle == hdl_cache[AMS_HDL_ENTITY_UPD_VALUE])
+ {
+ cb_data.cb_content.notify_data.type = AMS_NOTIFY_FROM_ENTITY_UPD;
+ cb_data.cb_content.notify_data.value_size = value_size;
+ cb_data.cb_content.notify_data.p_value = p_value;
+ }
+ else
+ {
+ return APP_RESULT_SUCCESS;
+ }
+
+ if (ams_client_cb)
+ {
+ app_result = (*ams_client_cb)(ams_client_id, conn_id, &cb_data);
+ }
+
+ return app_result;
+}
+
+/**
+ * @brief Called by profile client layer, when one LE link is disconnected.
+ */
+static void ams_client_cb_disc(uint8_t conn_id)
+{
+ APP_PRINT_INFO0("ams_client_disc_cb.");
+ memset(&ams_table[conn_id], 0, sizeof(T_AMS_LINK));
+ if (ams_client_cb)
+ {
+ T_AMS_CB_DATA cb_data;
+ cb_data.cb_type = AMS_CLIENT_CB_TYPE_DISCONNECT_INFO;
+ (*ams_client_cb)(ams_client_id, conn_id, &cb_data);
+ }
+ return;
+}
+/**
+ * @brief AMS Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS ams_cbs =
+{
+ ams_client_cb_discover_state, //!< Discovery State callback function pointer
+ ams_client_cb_discover_result, //!< Discovery result callback function pointer
+ ams_client_cb_read_result, //!< Read response callback function pointer
+ ams_client_cb_write_result, //!< Write result callback function pointer
+ ams_client_cb_notify_ind, //!< Notify Indicate callback function pointer
+ ams_client_cb_disc //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief Add ams client.
+ *
+ * @param[in] app_cb Callback to notify client read/write/notify/indicate events.
+ * @param[in] link_num Initialize link number
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ */
+T_CLIENT_ID ams_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+{
+ uint16_t size;
+ if (link_num > AMS_MAX_LINKS)
+ {
+ PROFILE_PRINT_ERROR1("ams_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&ams_client_id, &ams_cbs))
+ {
+ ams_client_id = CLIENT_PROFILE_GENERAL_ID;
+ APP_PRINT_ERROR0("ams_add_client Fail !!!");
+ return ams_client_id;
+ }
+ APP_PRINT_INFO1("ams_add_client: client ID = %d", ams_client_id);
+
+ /* register callback for profile to inform application that some events happened. */
+ ams_client_cb = app_cb;
+ ams_link_num = link_num;
+ size = ams_link_num * sizeof(T_AMS_LINK);
+ ams_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ return ams_client_id;
+}
+
diff --git a/src/ble/profile/client/ancs_client.c b/src/ble/profile/client/ancs_client.c
new file mode 100644
index 0000000..5e5e841
--- /dev/null
+++ b/src/ble/profile/client/ancs_client.c
@@ -0,0 +1,681 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs_client.c
+ * @brief
+ * @details
+ * @author jane
+ * @date 2016-02-18
+ * @version v1.0
+ ******************************************************************************
+ */
+
+/** Add Includes here **/
+#include <string.h>
+#include <ancs_client.h>
+#include <os_mem.h>
+#include <trace.h>
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+/**
+ * @brief ANCS Link control block definition.
+ */
+typedef struct
+{
+ T_ANCS_DISC_STATE disc_state;
+ bool write_notify_value;
+ uint16_t hdl_cache[HDL_ANCS_CACHE_LEN];
+} T_ANCS_LINK, *P_ANCS_LINK;
+
+/** @brief ANCS link table */
+static P_ANCS_LINK ancs_table;
+static uint8_t ancs_link_num;
+
+/**< ANCS client ID. */
+static T_CLIENT_ID ancs_client_id = CLIENT_PROFILE_GENERAL_ID;
+/**< Callback used to send data to app from ANCS client layer. */
+static P_FUN_GENERAL_APP_CB ancs_client_cb = NULL;
+
+uint8_t ANCS_UUID128_SRV[16] = {0xd0, 0x00, 0x2d, 0x12, 0x1e, 0x4b, 0x0f, 0xa4, 0x99, 0x4e, 0xce, 0xb5, 0x31, 0xf4, 0x05, 0x79};
+const uint8_t ANCS_UUID128_CHAR_CONTROL_POINT[16] = {0xd9, 0xd9, 0xaa, 0xfd, 0xbd, 0x9b, 0x21, 0x98, 0xa8, 0x49, 0xe1, 0x45, 0xf3, 0xd8, 0xd1, 0x69};
+const uint8_t ANCS_UUID128_CHAR_NOTIFICATION_SOURCE[16] = {0xBD, 0x1D, 0xA2, 0x99, 0xE6, 0x25, 0x58, 0x8C, 0xD9, 0x42, 0x01, 0x63, 0x0D, 0x12, 0xBF, 0x9F};
+const uint8_t ANCS_UUID128_CHAR_DATA_SOURCE[16] = {0xFB, 0x7B, 0x7C, 0xCE, 0x6A, 0xB3, 0x44, 0xBE, 0xB5, 0x4B, 0xD6, 0x24, 0xE9, 0xC6, 0xEA, 0x22};
+
+
+uint16_t ancs_search_handle(uint8_t conn_id, T_ANCS_HANDLE_TYPE handle_type)
+{
+ uint16_t handle = 0;
+ P_ANCS_LINK link_info = ancs_table;
+
+ if (handle_type >= HDL_ANCS_CACHE_LEN)
+ {
+ APP_PRINT_ERROR1("ancs_search_handle: no handle_type %d", handle_type);
+ return HDL_ANCS_CACHE_LEN;
+ }
+
+ handle = link_info[conn_id].hdl_cache[handle_type];
+
+ APP_PRINT_INFO1("ancs_search_handle: ancs handle 0x%08x", handle);
+
+ return handle;
+}
+
+
+/**
+ * @brief Used by application, to start the discovery procedure of ANCS.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ancs_start_discovery(uint8_t conn_id)
+{
+ APP_PRINT_INFO0("ancs_start_discovery");
+ if (conn_id >= ancs_link_num)
+ {
+ PROFILE_PRINT_ERROR1("ancs_start_discovery: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ /* First clear handle cache. */
+ memset(ancs_table[conn_id].hdl_cache, 0, 2 * HDL_ANCS_CACHE_LEN);
+ ancs_table[conn_id].disc_state = DISC_ANCS_START;
+ if (client_by_uuid128_srv_discovery(conn_id, ancs_client_id,
+ ANCS_UUID128_SRV) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Used internal, start the discovery of ANCS characteristics.
+ * NOTE--user can offer this interface for application if required.
+ * @param[in] conn_id: connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+static bool ancs_start_char_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ APP_PRINT_INFO0("ancs_start_char_discovery");
+ start_handle = ancs_table[conn_id].hdl_cache[HDL_ANCS_SRV_START];
+ end_handle = ancs_table[conn_id].hdl_cache[HDL_ANCS_SRV_END];
+ if (client_all_char_discovery(conn_id, ancs_client_id, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_ancshdl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t hdl_cache[HDL_ANCS_CACHE_LEN];
+ bool ret = ancs_get_hdl_cache(conn_id, hdl_cache,
+ sizeof(uint16_t) * HDL_ANCS_CACHE_LEN);
+
+ ......
+ }
+ * \endcode
+ */
+bool ancs_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= ancs_link_num)
+ {
+ PROFILE_PRINT_ERROR1("ancs_get_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (ancs_table[conn_id].disc_state != DISC_ANCS_DONE)
+ {
+ PROFILE_PRINT_ERROR1("ancs_get_hdl_cache: failed invalid state %d", ancs_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_ANCS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("ancs_get_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(p_hdl_cache, ancs_table[conn_id].hdl_cache, len);
+ return true;
+}
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_discov_services(uint8_t conn_id, bool start)
+ {
+ ......
+ if (app_srvs_table.srv_found_flags & APP_DISCOV_ANCS_FLAG)
+ {
+ ancs_set_hdl_cache(conn_id, app_srvs_table.ancs_hdl_cache, sizeof(uint16_t) * HDL_ANCS_CACHE_LEN);
+ }
+ ......
+ }
+ * \endcode
+ */
+bool ancs_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= ancs_link_num)
+ {
+ PROFILE_PRINT_ERROR1("ancs_set_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (ancs_table[conn_id].disc_state != DISC_ANCS_IDLE)
+ {
+ PROFILE_PRINT_ERROR1("ancs_set_hdl_cache: failed invalid state %d", ancs_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_ANCS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("ancs_set_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(ancs_table[conn_id].hdl_cache, p_hdl_cache, len);
+ ancs_table[conn_id].disc_state = DISC_ANCS_DONE;
+ return true;
+}
+
+/**
+ * @brief Used by application, to set the notification flag of notification source.
+ * @param[in] conn_id connection ID.
+ * @param[in] notify value to enable or disable notify.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ancs_set_notification_source_notify(uint8_t conn_id, bool notify)
+{
+ if (conn_id >= ancs_link_num)
+ {
+ PROFILE_PRINT_ERROR1("ancs_set_notification_source_notify: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (ancs_table[conn_id].hdl_cache[HDL_ANCS_NOTIFICATION_SOURCE_CCCD])
+ {
+ uint16_t handle = ancs_table[conn_id].hdl_cache[HDL_ANCS_NOTIFICATION_SOURCE_CCCD];
+ uint16_t length = sizeof(uint16_t);
+ uint16_t cccd_bits = notify ? 1 : 0;
+ if (client_attr_write(conn_id, ancs_client_id, GATT_WRITE_TYPE_REQ, handle,
+ length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+ {
+ ancs_table[conn_id].write_notify_value = notify;
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * @brief Used by application, to set the notification flag of data source.
+ * @param[in] conn_id connection ID.
+ * @param[in] notify value to enable or disable notify.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ancs_set_data_source_notify(uint8_t conn_id, bool notify)
+{
+ if (conn_id >= ancs_link_num)
+ {
+ PROFILE_PRINT_ERROR1("ancs_set_data_source_notify: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (ancs_table[conn_id].hdl_cache[HDL_ANCS_DATA_SOURCE_CCCD])
+ {
+ uint16_t handle = ancs_table[conn_id].hdl_cache[HDL_ANCS_DATA_SOURCE_CCCD];
+ uint16_t length = sizeof(uint16_t);
+ uint16_t cccd_bits = notify ? 1 : 0;
+ if (client_attr_write(conn_id, ancs_client_id, GATT_WRITE_TYPE_REQ, handle,
+ length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+ {
+ ancs_table[conn_id].write_notify_value = notify;
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * @brief Used by application, to get the notification attribute.
+ * @param[in] conn_id connection ID.
+ * @param[in] notification_uid value to enable or disable notify.
+ * @param[in] p_attribute_ids Pointer to attribute ids.
+ * @param[in] attribute_ids_len Length of attribute ids.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ancs_get_notification_attr(uint8_t conn_id, uint32_t notification_uid,
+ uint8_t *p_attribute_ids, uint8_t attribute_ids_len)
+{
+ bool result = false;
+ uint8_t command_id = CP_CMD_ID_GET_NOTIFICATION_ATTR;
+ uint16_t length = sizeof(command_id) + sizeof(notification_uid) + attribute_ids_len;
+ if (conn_id >= ancs_link_num)
+ {
+ PROFILE_PRINT_ERROR1("ancs_get_notification_attr: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (attribute_ids_len > 25)
+ {
+ return false;
+ }
+ if (ancs_table[conn_id].hdl_cache[HDL_ANCS_CONTROL_POINT])
+ {
+ uint8_t buffer[30];
+ uint16_t offset = 0;
+ memcpy(buffer + offset, &command_id, sizeof(command_id));
+ offset += sizeof(command_id);
+ memcpy(buffer + offset, &notification_uid, sizeof(notification_uid));
+ offset += sizeof(notification_uid);
+ memcpy(buffer + offset, p_attribute_ids, attribute_ids_len);
+ if (client_attr_write(conn_id, ancs_client_id, GATT_WRITE_TYPE_REQ,
+ ancs_table[conn_id].hdl_cache[HDL_ANCS_CONTROL_POINT],
+ length, buffer) == GAP_CAUSE_SUCCESS)
+ {
+ result = true;
+ }
+ }
+ return result;
+}
+
+/**
+ * @brief Used by application, to get the app attribute.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_app_identifier value to enable or disable notify.
+ * @param[in] p_attribute_ids Pointer to attribute ids.
+ * @param[in] attribute_ids_len Length of attribute ids.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ancs_get_app_attr(uint8_t conn_id, char *p_app_identifier, uint8_t *p_attribute_ids,
+ uint8_t attribute_ids_len)
+{
+ bool result = false;
+ uint8_t command_id = CP_CMD_ID_GET_APP_ATTR;
+ uint16_t length = sizeof(command_id) + strlen((const char *)p_app_identifier) + attribute_ids_len +
+ 1;
+ uint8_t *p_buffer = NULL;
+ if (conn_id >= ancs_link_num)
+ {
+ PROFILE_PRINT_ERROR1("ancs_get_app_attr: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (ancs_table[conn_id].hdl_cache[HDL_ANCS_CONTROL_POINT])
+ {
+ uint16_t offset = 0;
+ p_buffer = os_mem_zalloc(RAM_TYPE_DATA_ON, length);
+
+ if (!p_buffer)
+ {
+ PROFILE_PRINT_ERROR2("ancs_get_app_attr: allocation failed, conn_id %d, length %d", conn_id,
+ length);
+ return false;
+ }
+
+ memcpy(p_buffer + offset, &command_id, sizeof(command_id));
+ offset += sizeof(command_id);
+ memcpy(p_buffer + offset, p_app_identifier, strlen((const char *)p_app_identifier));
+ offset += strlen((const char *)p_app_identifier);
+ p_buffer[offset] = 0;
+ offset += 1;
+ memcpy(p_buffer + offset, p_attribute_ids, attribute_ids_len);
+ if (client_attr_write(conn_id, ancs_client_id, GATT_WRITE_TYPE_REQ,
+ ancs_table[conn_id].hdl_cache[HDL_ANCS_CONTROL_POINT],
+ length, p_buffer) == GAP_CAUSE_SUCCESS)
+ {
+ result = true;
+ }
+ }
+ if (p_buffer != NULL)
+ {
+ os_mem_free(p_buffer);
+ }
+
+ return result;
+}
+
+/**
+ * @brief Used by application, to perfome the notication action.
+ * @param[in] conn_id Connection ID.
+ * @param[in] notification_uid Notification UUID.
+ * @param[in] action_id Action id.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ancs_perform_notification_action(uint8_t conn_id, uint32_t notification_uid, uint8_t action_id)
+{
+ bool result = false;
+ uint8_t command_id = CP_CMD_ID_PERFORM_NOTIFICATION_ACTION;
+ uint16_t length = sizeof(command_id) + sizeof(notification_uid) + sizeof(action_id);
+ if (conn_id >= ancs_link_num)
+ {
+ PROFILE_PRINT_ERROR1("ancs_perform_notification_action: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (ancs_table[conn_id].hdl_cache[HDL_ANCS_CONTROL_POINT])
+ {
+ uint8_t buffer[12];
+ uint16_t offset = 0;
+ memcpy(buffer + offset, &command_id, sizeof(command_id));
+ offset += sizeof(command_id);
+ memcpy(buffer + offset, &notification_uid, sizeof(notification_uid));
+ offset += sizeof(notification_uid);
+ memcpy(buffer + offset, &action_id, sizeof(action_id));
+ if (client_attr_write(conn_id, ancs_client_id, GATT_WRITE_TYPE_REQ,
+ ancs_table[conn_id].hdl_cache[HDL_ANCS_CONTROL_POINT],
+ length, buffer) == GAP_CAUSE_SUCCESS)
+ {
+ result = true;
+ }
+ }
+ return result;
+}
+
+/**
+ * @brief Called by profile client layer, when discover state of discovery procedure changed.
+ * @param[in] conn_id: connection ID.
+ * @param[in] discovery_state: current service discovery state.
+ * @retval None
+ */
+static void ancs_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state)
+{
+ bool cb_flag = false;
+ T_ANCS_CB_DATA cb_data;
+ cb_data.cb_type = ANCS_CLIENT_CB_TYPE_DISC_STATE;
+
+ APP_PRINT_INFO1("ancs_client_discover_state_cb: discoveryState %d", discovery_state);
+ if (ancs_table[conn_id].disc_state == DISC_ANCS_START)
+ {
+ switch (discovery_state)
+ {
+ case DISC_STATE_SRV_DONE:
+ /* Indicate that service handle found. Start discover characteristic. */
+ if ((ancs_table[conn_id].hdl_cache[HDL_ANCS_SRV_START] != 0)
+ || (ancs_table[conn_id].hdl_cache[HDL_ANCS_SRV_END] != 0))
+ {
+ if (ancs_start_char_discovery(conn_id) == false)
+ {
+ ancs_table[conn_id].disc_state = DISC_ANCS_FAILED;
+ cb_flag = true;
+ }
+ }
+ /* No ANCS handle found. Discover procedure complete. */
+ else
+ {
+ ancs_table[conn_id].disc_state = DISC_ANCS_FAILED;
+ cb_flag = true;
+ }
+ break;
+ case DISC_STATE_CHAR_DONE:
+ ancs_table[conn_id].disc_state = DISC_ANCS_DONE;
+ cb_flag = true;
+ break;
+
+ case DISC_STATE_FAILED:
+ ancs_table[conn_id].disc_state = DISC_ANCS_FAILED;
+ cb_flag = true;
+ break;
+ default:
+ APP_PRINT_ERROR0("Invalid Discovery State!");
+ break;
+ }
+ }
+
+ /* Send discover state to application if needed. */
+ if (cb_flag && ancs_client_cb)
+ {
+ cb_data.cb_content.disc_state = ancs_table[conn_id].disc_state;
+ (*ancs_client_cb)(ancs_client_id, conn_id, &cb_data);
+ }
+ return;
+}
+
+/**
+ * @brief Called by profile client layer, when discover result fetched.
+ * @param[in] conn_id: connection ID.
+ * @param[in] result_type: indicate which type of value discovered in service discovery procedure.
+ * @param[in] result_data: value discovered.
+ * @retval None
+ */
+static void ancs_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ APP_PRINT_INFO1("gap_client_discover_result_cb: resultType %d", result_type);
+ if (ancs_table[conn_id].disc_state == DISC_ANCS_START)
+ {
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ ancs_table[conn_id].hdl_cache[HDL_ANCS_SRV_START] =
+ result_data.p_srv_disc_data->att_handle;
+ ancs_table[conn_id].hdl_cache[HDL_ANCS_SRV_END] =
+ result_data.p_srv_disc_data->end_group_handle;
+ break;
+ case DISC_RESULT_CHAR_UUID128:
+ {
+ uint16_t handle;
+ handle = result_data.p_char_uuid128_disc_data->value_handle;
+ if (0 == memcmp(ANCS_UUID128_CHAR_CONTROL_POINT, result_data.p_char_uuid128_disc_data->uuid128, 16))
+ {
+ ancs_table[conn_id].hdl_cache[HDL_ANCS_CONTROL_POINT] = handle;
+ }
+ else if (0 == memcmp(ANCS_UUID128_CHAR_NOTIFICATION_SOURCE,
+ result_data.p_char_uuid128_disc_data->uuid128, 16))
+ {
+ ancs_table[conn_id].hdl_cache[HDL_ANCS_NOTIFICATION_SOURCE] = handle;
+ ancs_table[conn_id].hdl_cache[HDL_ANCS_NOTIFICATION_SOURCE_CCCD] = handle + 1;
+ }
+ else if (0 == memcmp(ANCS_UUID128_CHAR_DATA_SOURCE, result_data.p_char_uuid128_disc_data->uuid128,
+ 16))
+ {
+ ancs_table[conn_id].hdl_cache[HDL_ANCS_DATA_SOURCE] = handle;
+ ancs_table[conn_id].hdl_cache[HDL_ANCS_DATA_SOURCE_CCCD] = handle + 1;
+ }
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR0("Invalid Discovery Result Type!");
+ break;
+ }
+ }
+
+ return;
+}
+
+/**
+ * @brief Called by profile client layer, when write result arrived.
+ * @param[in] conn_id: connection ID.
+ * @param[in] type: write type
+ * @param[in] handle: handle of the value in write request.
+ * @param[in] cause: the write result.
+ * @param[in] credits: write commands credit.
+ * @retval void
+ */
+static void ancs_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type,
+ uint16_t handle,
+ uint16_t cause,
+ uint8_t credits)
+{
+ T_ANCS_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = ancs_table[conn_id].hdl_cache;
+ cb_data.cb_type = ANCS_CLIENT_CB_TYPE_WRITE_RESULT;
+
+ APP_PRINT_INFO2("ancs_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.write_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_ANCS_NOTIFICATION_SOURCE_CCCD])
+ {
+ if (ancs_table[conn_id].write_notify_value == 0)
+ {
+ cb_data.cb_content.write_result.type = ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE;
+ }
+ else
+ {
+ cb_data.cb_content.write_result.type = ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE;
+ }
+ }
+ else if (handle == hdl_cache[HDL_ANCS_DATA_SOURCE_CCCD])
+ {
+ if (ancs_table[conn_id].write_notify_value == 0)
+ {
+ cb_data.cb_content.write_result.type = ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE;
+ }
+ else
+ {
+ cb_data.cb_content.write_result.type = ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE;
+ }
+ }
+ else if (handle == hdl_cache[HDL_ANCS_CONTROL_POINT])
+ {
+ cb_data.cb_content.write_result.type = ANCS_WRITE_CONTROL_POINT;
+ }
+ else
+ {
+ return;
+ }
+
+ if (ancs_client_cb)
+ {
+ (*ancs_client_cb)(ancs_client_id, conn_id, &cb_data);
+ }
+ return;
+}
+/**
+ * @brief Called by profile client layer, when notification or indication arrived.
+ * @param[in] conn_id: connection ID.
+ * @param[in] notify: Whether the data is notification
+ * @param[in] handle: handle of the value in received data.
+ * @param[in] value_size: size of the value in received data.
+ * @param[in] p_value: pointer to the value in received data.
+ * @retval APP_RESULT_SUCCESS procedure OK.
+ * @retval other procedure exception.
+ */
+static T_APP_RESULT ancs_client_notify_ind_cb(uint8_t conn_id, bool notify, uint16_t handle,
+ uint16_t value_size, uint8_t *p_value)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+
+ hdl_cache = ancs_table[conn_id].hdl_cache;
+ cb_data.cb_type = ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT;
+
+ if (handle == hdl_cache[HDL_ANCS_DATA_SOURCE])
+ {
+ cb_data.cb_content.notify_data.type = ANCS_FROM_DATA_SOURCE;
+ cb_data.cb_content.notify_data.value_size = value_size;
+ cb_data.cb_content.notify_data.p_value = p_value;
+ }
+ else if (handle == hdl_cache[HDL_ANCS_NOTIFICATION_SOURCE])
+ {
+ cb_data.cb_content.notify_data.type = ANCS_FROM_NOTIFICATION_SOURCE;
+ cb_data.cb_content.notify_data.value_size = value_size;
+ cb_data.cb_content.notify_data.p_value = p_value;
+ }
+ else
+ {
+ return APP_RESULT_SUCCESS;
+ }
+
+ if (ancs_client_cb)
+ {
+ app_result = (*ancs_client_cb)(ancs_client_id, conn_id, &cb_data);
+ }
+
+ return app_result;
+}
+
+/**
+ * @brief Called by profile client layer, when one LE link is disconnected.
+ * @param[in] conn_id: connection ID.
+ * @retval void
+ */
+static void ancs_client_disc_cb(uint8_t conn_id)
+{
+ APP_PRINT_INFO0("gap_client_disc_cb.");
+ memset(&ancs_table[conn_id], 0, sizeof(T_ANCS_LINK));
+ if (ancs_client_cb)
+ {
+ T_ANCS_CB_DATA cb_data;
+ cb_data.cb_type = ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO;
+ (*ancs_client_cb)(ancs_client_id, conn_id, &cb_data);
+ }
+ return;
+}
+/**
+ * @brief ANCS Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS ancs_cbs =
+{
+ ancs_client_discover_state_cb, //!< Discovery State callback function pointer
+ ancs_client_discover_result_cb, //!< Discovery result callback function pointer
+ NULL, //!< Read response callback function pointer
+ ancs_client_write_result_cb, //!< Write result callback function pointer
+ ancs_client_notify_ind_cb, //!< Notify Indicate callback function pointer
+ ancs_client_disc_cb //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief Add ancs client.
+ *
+ * @param[in] app_cb Callbackto notify client read/write/notify/indicate events.
+ * @param[in] link_num Initialize link number
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void ancs_init(uint8_t link_num)
+ {
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+ }
+ * \endcode
+ */
+T_CLIENT_ID ancs_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+{
+ uint16_t size;
+ if (link_num > ANCS_MAX_LINKS)
+ {
+ PROFILE_PRINT_ERROR1("ancs_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&ancs_client_id, &ancs_cbs))
+ {
+ ancs_client_id = CLIENT_PROFILE_GENERAL_ID;
+ APP_PRINT_ERROR0("ancs_add_client Fail !!!");
+ return ancs_client_id;
+ }
+ APP_PRINT_INFO1("ancs_add_client: client ID %d", ancs_client_id);
+
+ /* register callback for profile to inform application that some events happened. */
+ ancs_client_cb = app_cb;
+ ancs_link_num = link_num;
+ size = ancs_link_num * sizeof(T_ANCS_LINK);
+ ancs_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ return ancs_client_id;
+}
+
diff --git a/src/ble/profile/client/bas_client.c b/src/ble/profile/client/bas_client.c
new file mode 100644
index 0000000..181fca1
--- /dev/null
+++ b/src/ble/profile/client/bas_client.c
@@ -0,0 +1,613 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file bas_client.c
+ * @brief
+ * @details
+ * @author jane
+ * @date 2016-02-18
+ * @version v1.0
+ ******************************************************************************
+ */
+
+/** Add Includes here **/
+#include <string.h>
+#include <bas_client.h>
+#include <trace.h>
+#include <os_mem.h>
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+#define GATT_UUID_BATTERY 0x180F
+#define GATT_UUID_CHAR_BAS_LEVEL 0x2A19
+/**
+ * @brief BAS client Link control block definition.
+ */
+typedef struct
+{
+ T_BAS_DISC_STATE disc_state;
+ bool write_notify_value;
+ uint16_t properties;
+ uint16_t hdl_cache[HDL_BAS_CACHE_LEN];
+} T_BAS_LINK, *P_BAS_LINK;
+
+static P_BAS_LINK bas_table;
+static uint8_t bas_link_num;
+
+/**< BAS client ID. */
+static T_CLIENT_ID bas_client = CLIENT_PROFILE_GENERAL_ID;
+/**< Callback used to send data to app from BAS client layer. */
+static P_FUN_GENERAL_APP_CB bas_client_cb = NULL;
+
+/**
+ * @brief Used by application, to start the discovery procedure of battery service.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_basdis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = bas_start_discovery(conn_id);
+ ......
+ }
+ * \endcode
+ */
+bool bas_start_discovery(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("bas_start_discovery");
+ if (conn_id >= bas_link_num)
+ {
+ PROFILE_PRINT_ERROR1("bas_start_discovery: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ /* First clear handle cache. */
+ memset(&bas_table[conn_id], 0, sizeof(T_BAS_LINK));
+ bas_table[conn_id].disc_state = DISC_BAS_START;
+ if (client_by_uuid_srv_discovery(conn_id, bas_client,
+ GATT_UUID_BATTERY) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Used by application, to read battery level.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_basread(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = false;
+ ret = bas_read_battery_level(conn_id);
+ ......
+ }
+ * \endcode
+ */
+bool bas_read_battery_level(uint8_t conn_id)
+{
+ if (conn_id >= bas_link_num)
+ {
+ PROFILE_PRINT_ERROR1("bas_read_battery_level: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL])
+ {
+ uint16_t handle = bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL];
+ if (client_attr_read(conn_id, bas_client, handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+ PROFILE_PRINT_ERROR0("bas_read_battery_level: false handle = 0");
+ return false;
+}
+/**
+ * @brief Used by application, to set the notification flag.
+ * @param[in] conn_id connection ID.
+ * @param[in] notify value to enable or disable notify.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_bascccd(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool notify = p_parse_value->dw_param[1];
+ bool ret;
+ ret = bas_set_notify(conn_id, notify);
+ ......
+ }
+ * \endcode
+ */
+bool bas_set_notify(uint8_t conn_id, bool notify)
+{
+ if (conn_id >= bas_link_num)
+ {
+ PROFILE_PRINT_ERROR1("bas_set_notify: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD])
+ {
+ uint16_t handle = bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD];
+ uint16_t length = sizeof(uint16_t);
+ uint16_t cccd_bits = notify ? 1 : 0;
+ if (client_attr_write(conn_id, bas_client, GATT_WRITE_TYPE_REQ, handle,
+ length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+ {
+ bas_table[conn_id].write_notify_value = notify;
+ return true;
+ }
+ }
+ PROFILE_PRINT_ERROR0("bas_set_notify: false handle = 0");
+ return false;
+}
+
+/**
+ * @brief Used by application, to read the notification flag.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_basread(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = false;
+ ret = bas_read_notify(conn_id);
+ ......
+ }
+ * \endcode
+ */
+bool bas_read_notify(uint8_t conn_id)
+{
+ if (conn_id >= bas_link_num)
+ {
+ PROFILE_PRINT_ERROR1("bas_read_notify: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD])
+ {
+ uint16_t handle = bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD];
+ if (client_attr_read(conn_id, bas_client, handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+ PROFILE_PRINT_ERROR0("bas_read_battery_level: false handle = 0");
+ return false;
+}
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_bashdl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t hdl_cache[HDL_BAS_CACHE_LEN];
+ bool ret = bas_get_hdl_cache(conn_id, hdl_cache,
+ sizeof(uint16_t) * HDL_BAS_CACHE_LEN);
+
+ ......
+ }
+ * \endcode
+ */
+bool bas_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= bas_link_num)
+ {
+ PROFILE_PRINT_ERROR1("bas_get_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (bas_table[conn_id].disc_state != DISC_BAS_DONE)
+ {
+ PROFILE_PRINT_ERROR1("bas_get_hdl_cache: failed invalid state %d", bas_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_BAS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("bas_get_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(p_hdl_cache, bas_table[conn_id].hdl_cache, len);
+ return true;
+}
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_discov_services(uint8_t conn_id, bool start)
+ {
+ ......
+ if (app_srvs_table.srv_found_flags & APP_DISCOV_BAS_FLAG)
+ {
+ bas_set_hdl_cache(conn_id, app_srvs_table.bas_hdl_cache, sizeof(uint16_t) * HDL_BAS_CACHE_LEN);
+ }
+ ......
+ }
+ * \endcode
+ */
+bool bas_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= bas_link_num)
+ {
+ PROFILE_PRINT_ERROR1("bas_set_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (bas_table[conn_id].disc_state != DISC_BAS_IDLE)
+ {
+ PROFILE_PRINT_ERROR1("bas_set_hdl_cache: failed invalid state %d", bas_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_BAS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("bas_set_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(bas_table[conn_id].hdl_cache, p_hdl_cache, len);
+ bas_table[conn_id].disc_state = DISC_BAS_DONE;
+ return true;
+}
+
+static bool bas_start_char_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ PROFILE_PRINT_INFO0("bas_start_char_discovery");
+ start_handle = bas_table[conn_id].hdl_cache[HDL_BAS_SRV_START];
+ end_handle = bas_table[conn_id].hdl_cache[HDL_BAS_SRV_END];
+ if (client_all_char_discovery(conn_id, bas_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+static bool bas_start_char_descriptor_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ PROFILE_PRINT_INFO0("bas_start_char_descriptor_discovery");
+ start_handle = bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL];
+ end_handle = bas_table[conn_id].hdl_cache[HDL_BAS_SRV_END];
+ if (client_all_char_descriptor_discovery(conn_id, bas_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+static void bas_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state)
+{
+ bool cb_flag = false;
+ T_BAS_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = BAS_CLIENT_CB_TYPE_DISC_STATE;
+
+ PROFILE_PRINT_INFO1("bas_client_discover_state_cb: discovery_state = %d", discovery_state);
+ if (bas_table[conn_id].disc_state == DISC_BAS_START)
+ {
+ switch (discovery_state)
+ {
+ case DISC_STATE_SRV_DONE:
+ /* Indicate that service handle found. Start discover characteristic. */
+ if ((bas_table[conn_id].hdl_cache[HDL_BAS_SRV_START] != 0)
+ || (bas_table[conn_id].hdl_cache[HDL_BAS_SRV_END] != 0))
+ {
+ if (bas_start_char_discovery(conn_id) == false)
+ {
+ bas_table[conn_id].disc_state = DISC_BAS_FAILED;
+ cb_flag = true;
+ }
+ }
+ /* No BAS handle found. Discover procedure complete. */
+ else
+ {
+ bas_table[conn_id].disc_state = DISC_BAS_FAILED;
+ cb_flag = true;
+ }
+ break;
+ case DISC_STATE_CHAR_DONE:
+ if (bas_table[conn_id].properties & GATT_CHAR_PROP_NOTIFY)
+ {
+ //discovery cccd
+ if (bas_start_char_descriptor_discovery(conn_id) == false)
+ {
+ bas_table[conn_id].disc_state = DISC_BAS_FAILED;
+ cb_flag = true;
+ }
+ }
+ else
+ {
+ bas_table[conn_id].disc_state = DISC_BAS_DONE;
+ cb_flag = true;
+ }
+ break;
+
+ case DISC_STATE_CHAR_DESCRIPTOR_DONE:
+ bas_table[conn_id].disc_state = DISC_BAS_DONE;
+ cb_flag = true;
+ break;
+
+ case DISC_STATE_FAILED:
+ bas_table[conn_id].disc_state = DISC_BAS_FAILED;
+ cb_flag = true;
+ break;
+
+ default:
+ PROFILE_PRINT_ERROR0("Invalid Discovery State!");
+ break;
+ }
+ }
+
+ /* Send discover state to application if needed. */
+ if (cb_flag && bas_client_cb)
+ {
+ cb_data.cb_content.disc_state = bas_table[conn_id].disc_state;
+ (*bas_client_cb)(bas_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+
+static void bas_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ PROFILE_PRINT_INFO1("bas_client_discover_result_cb: result_type = %d", result_type);
+ if (bas_table[conn_id].disc_state == DISC_BAS_START)
+ {
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ bas_table[conn_id].hdl_cache[HDL_BAS_SRV_START] =
+ result_data.p_srv_disc_data->att_handle;
+ bas_table[conn_id].hdl_cache[HDL_BAS_SRV_END] =
+ result_data.p_srv_disc_data->end_group_handle;
+ break;
+
+ case DISC_RESULT_CHAR_UUID16:
+ {
+ uint16_t handle;
+ handle = result_data.p_char_uuid16_disc_data->value_handle;
+ if (result_data.p_char_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_BAS_LEVEL)
+ {
+ bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL] = handle;
+ bas_table[conn_id].properties = result_data.p_char_uuid16_disc_data->properties;
+ }
+ }
+ break;
+
+ case DISC_RESULT_CHAR_DESC_UUID16:
+ if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG)
+ {
+ bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD] =
+ result_data.p_char_desc_uuid16_disc_data->handle;
+ }
+ break;
+
+ default:
+ PROFILE_PRINT_ERROR0("Invalid Discovery Result Type!");
+ break;
+ }
+ }
+
+ return;
+}
+
+static void bas_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type,
+ uint16_t handle,
+ uint16_t cause,
+ uint8_t credits)
+{
+ T_BAS_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = bas_table[conn_id].hdl_cache;
+ cb_data.cb_type = BAS_CLIENT_CB_TYPE_WRITE_RESULT;
+
+ PROFILE_PRINT_INFO2("bas_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.write_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD])
+ {
+ if (bas_table[conn_id].write_notify_value)
+ {
+ cb_data.cb_content.write_result.type = BAS_WRITE_NOTIFY_ENABLE;
+ }
+ else
+ {
+ cb_data.cb_content.write_result.type = BAS_WRITE_NOTIFY_DISABLE;
+ }
+ }
+ else
+ {
+ return;
+ }
+
+ if (bas_client_cb)
+ {
+ (*bas_client_cb)(bas_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+static void bas_client_read_result_cb(uint8_t conn_id, uint16_t cause,
+ uint16_t handle, uint16_t value_size, uint8_t *p_value)
+{
+ T_BAS_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = bas_table[conn_id].hdl_cache;
+ cb_data.cb_type = BAS_CLIENT_CB_TYPE_READ_RESULT;
+
+ PROFILE_PRINT_INFO2("bas_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.read_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD])
+ {
+ cb_data.cb_content.read_result.type = BAS_READ_NOTIFY;
+ if (cause == GAP_SUCCESS)
+ {
+ uint16_t ccc_bit;
+ if (value_size != 2)
+ {
+ PROFILE_PRINT_ERROR1("bas_client_read_result_cb: invalid cccd len %d", value_size);
+ return;
+ }
+ LE_ARRAY_TO_UINT16(ccc_bit, p_value);
+
+ if (ccc_bit & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ cb_data.cb_content.read_result.data.notify = true;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.notify = false;
+ }
+ }
+ }
+ else if (handle == hdl_cache[HDL_BAS_BATTERY_LEVEL])
+ {
+ cb_data.cb_content.read_result.type = BAS_READ_BATTERY_LEVEL;
+ if (cause == GAP_SUCCESS)
+ {
+ if (value_size != 1)
+ {
+ PROFILE_PRINT_ERROR1("bas_client_read_result_cb: invalid battery value len %d", value_size);
+ return;
+ }
+ cb_data.cb_content.read_result.data.battery_level = *p_value;
+ }
+ }
+ else
+ {
+ return;
+ }
+
+ if (bas_client_cb)
+ {
+ (*bas_client_cb)(bas_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+static T_APP_RESULT bas_client_notify_ind_cb(uint8_t conn_id, bool notify, uint16_t handle,
+ uint16_t value_size, uint8_t *p_value)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ T_BAS_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+
+ hdl_cache = bas_table[conn_id].hdl_cache;
+ cb_data.cb_type = BAS_CLIENT_CB_TYPE_NOTIF_IND_RESULT;
+
+ if (handle == hdl_cache[HDL_BAS_BATTERY_LEVEL])
+ {
+ cb_data.cb_content.notify_data.battery_level = *p_value;
+ }
+ else
+ {
+ return APP_RESULT_SUCCESS;
+ }
+
+ if (bas_client_cb)
+ {
+ app_result = (*bas_client_cb)(bas_client, conn_id, &cb_data);
+ }
+
+ return app_result;
+}
+
+static void bas_client_disc_cb(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("bas_client_disc_cb.");
+ if (conn_id >= bas_link_num)
+ {
+ PROFILE_PRINT_ERROR1("bas_client_disc_cb: failed invalid conn_id %d", conn_id);
+ return;
+ }
+ memset(&bas_table[conn_id], 0, sizeof(T_BAS_LINK));
+ return;
+}
+/**
+ * @brief BAS Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS bas_client_cbs =
+{
+ bas_client_discover_state_cb, //!< Discovery State callback function pointer
+ bas_client_discover_result_cb, //!< Discovery result callback function pointer
+ bas_client_read_result_cb, //!< Read response callback function pointer
+ bas_client_write_result_cb, //!< Write result callback function pointer
+ bas_client_notify_ind_cb, //!< Notify Indicate callback function pointer
+ bas_client_disc_cb //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief Add bas client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ bas_client_id = bas_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID bas_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+{
+ uint16_t size;
+ if (link_num > BAS_MAX_LINKS)
+ {
+ PROFILE_PRINT_ERROR1("bas_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&bas_client, &bas_client_cbs))
+ {
+ bas_client = CLIENT_PROFILE_GENERAL_ID;
+ PROFILE_PRINT_ERROR0("bas_add_client:register fail");
+ return bas_client;
+ }
+ PROFILE_PRINT_INFO1("bas_add_client: client id %d", bas_client);
+
+ /* register callback for profile to inform application that some events happened. */
+ bas_client_cb = app_cb;
+ bas_link_num = link_num;
+ size = bas_link_num * sizeof(T_BAS_LINK);
+ bas_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ return bas_client;
+}
+
diff --git a/src/ble/profile/client/dfu_client.c b/src/ble/profile/client/dfu_client.c
new file mode 100644
index 0000000..8659d4f
--- /dev/null
+++ b/src/ble/profile/client/dfu_client.c
@@ -0,0 +1,1344 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file dfu_client.c
+ * @brief dfu service client source file.
+ * @details
+ * @author bill
+ * @date 2017-8-28
+ * @version v1.0
+ ******************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2015 Realtek Semiconductor Corporation</center></h2>
+ ******************************************************************************
+ */
+#include <string.h>
+#include <stdbool.h>
+#include "gap_conn_le.h"
+#include "gap_scan.h"
+#include "aes_api.h"
+#include "mem_types.h"
+#include "os_mem.h"
+#include "os_sched.h"
+#include "otp.h"
+#include "dfu_api.h"
+#include "patch_header_check.h"
+#include "trace.h"
+#include "dfu_client.h"
+#include "mem_config.h"
+#include "board.h" //include OTA config
+
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+
+/**
+ * @brief dfu client Link control block definition.
+ */
+typedef struct
+{
+ T_DFU_DISC_STATE disc_state;
+ uint16_t properties; //for what
+ uint16_t hdl_cache[HDL_DFU_CACHE_LEN];
+} T_DFU_LINK, *P_DFU_LINK;
+
+
+/*============================================================================*
+ * Local variables
+ *============================================================================*/
+static P_DFU_LINK dfu_table;
+static uint8_t dfu_link_num;
+
+/**< Callback used to send data to app from Dfu client layer. */
+static P_FUN_GENERAL_APP_CB pf_dfu_client_cb = NULL;
+static P_FUN_GENERAL_APP_CB pf_dfu_client_app_info_cb = NULL;
+
+P_FUN_DFU_CLIENT_INIT_APP_CB pf_dfu_client_init __attribute__((weak)) = NULL;
+/**< Dfu client ID. */
+static T_CLIENT_ID dfu_client = CLIENT_PROFILE_GENERAL_ID;
+
+/* for record data that target send by notification*/
+static uint8_t dfu_temp_cp_notify_msg[20]; //for cache control point masg
+static uint8_t dfu_temp_cp_notify_msg_len;
+
+static T_DFU_CTX dfu_client_ctx;
+static T_DFU_CLIENT_FSM_WRITE dfu_fsm_write = DFU_FSM_WRITE_IDLE;
+static uint8_t buf_check_retry_cnt = 0;
+
+const uint8_t dfu_data_uuid[16] = {GATT_UUID128_DFU_DATA};
+const uint8_t dfu_control_point_uuid[16] = {GATT_UUID128_DFU_CONTROL_POINT};
+const uint8_t dfu_service_uuid[16] = {GATT_UUID128_DFU_SERVICE};
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+static void swap_buf(uint8_t *dst, const uint8_t *src, uint16_t len)
+{
+ int i;
+ if (dst == NULL || src == NULL)
+ {
+ return;
+ }
+
+ for (i = 0; i < len; i++)
+ {
+ dst[len - 1 - i] = src[i];
+ }
+}
+
+/**
+ * @brief get 16bit data swapped.
+ *
+ * @param val 16bit data to be swapped.
+ * @return value after being swapped.
+*/
+static uint16_t swap_16(uint16_t val)
+{
+ uint16_t result;
+
+ /* Idiom Recognition for REV16 */
+ result = ((val & 0xff) << 8) | ((val & 0xff00) >> 8);
+
+ return result;
+}
+
+bool dfu_encrypt(uint8_t image[16])
+{
+ bool ret;
+ uint8_t image_tmp[16] = {0};
+ swap_buf(image_tmp, image, 16);
+ ret = aes256_ecb_encrypt_msb2lsb(image_tmp, (uint8_t *)OTP->aes_key, image_tmp);
+ swap_buf(image, image_tmp, 16);
+ return ret;
+}
+
+uint16_t dfu_client_temp_crc_cal(uint8_t *p_temp, uint32_t length, uint16_t init_cksum16)
+{
+ uint16_t temp_checksum16 = init_cksum16;
+ uint16_t *p16 = (uint16_t *)p_temp;
+
+ for (uint32_t i = 0; i < length / 2; ++i)
+ {
+ temp_checksum16 = temp_checksum16 ^ (*p16);
+ ++p16;
+ }
+ return temp_checksum16;
+}
+
+uint16_t dfu_client_buf_crc_cal(uint8_t *buf, uint32_t length)
+{
+ uint16_t checksum16 = dfu_client_temp_crc_cal(buf, length, 0);
+ return swap_16(checksum16);
+}
+
+void dfu_client_set_dfu_ctx_value(T_DFU_SET_CLIENT_CTX_TYPE type, void *p_value)
+{
+ DFU_PRINT_INFO1("dfu_client_set_dfu_ctx_value: type=%d", type);
+ if (p_value)
+ {
+ switch (type)
+ {
+ case DFU_SET_FEATURE:
+ dfu_client_ctx.dfu_feature = *(T_DFU_CLIENT_FEATURE_TYPE *)p_value;
+ break;
+ case DFU_SET_MODE_VALUE:
+ dfu_client_ctx.ota_mode.value = *(uint8_t *)p_value;
+ break;
+ case DFU_SET_MAX_BUF_SIZE:
+ dfu_client_ctx.max_buffer_size = *(uint32_t *)p_value;
+ break;
+ case DFU_SET_DFU_IMG_ADDR:
+ dfu_client_ctx.dfu_img_start_addr = *(uint32_t *)p_value;
+ DFU_PRINT_INFO1("dfu_client_set_dfu_ctx_value: dfu_img_start_addr=0x%x",
+ dfu_client_ctx.dfu_img_start_addr);
+ break;
+ case DFU_SET_DFU_IMG_VER:
+ dfu_client_ctx.dfu_img_version = *(uint32_t *)p_value;
+ break;
+ case DFU_SET_NORMAL_OTA_FLAG:
+ dfu_client_ctx.is_normal_ota = *(bool *)p_value;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/**
+ * @brief Used by application, to set the handles in Dfu handle cache.
+ * @param handle_type: handle types of this specific profile.
+ * @param handle_value: handle value to set.
+ * @retval true--set success.
+ * false--set failed.
+ */
+bool dfu_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= dfu_link_num)
+ {
+ DFU_PRINT_ERROR1("dfu_client_set_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (dfu_table[conn_id].disc_state != DISC_DFU_IDLE)
+ {
+ DFU_PRINT_ERROR1("dfu_client_set_hdl_cache: failed invalid state %d",
+ dfu_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_DFU_CACHE_LEN)
+ {
+ DFU_PRINT_ERROR1("dfu_client_set_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(dfu_table[conn_id].hdl_cache, p_hdl_cache, len);
+ dfu_table[conn_id].disc_state = DISC_DFU_DONE;
+ return true;
+}
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool dfu_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= dfu_link_num)
+ {
+ DFU_PRINT_ERROR1("dfu_client_get_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (dfu_table[conn_id].disc_state != DISC_DFU_DONE)
+ {
+ DFU_PRINT_ERROR1("dfu_client_get_hdl_cache: failed invalid state %d",
+ dfu_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_DFU_CACHE_LEN)
+ {
+ DFU_PRINT_ERROR1("dfu_client_get_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(p_hdl_cache, dfu_table[conn_id].hdl_cache, len);
+ return true;
+}
+
+
+/**
+ * @brief Used by application, to start the discovery procedure of Dfu server.
+ * @retval true--send request to upper stack success.
+ * false--send request to upper stack failed.
+ */
+bool dfu_client_start_discovery(uint8_t conn_id)
+{
+ if (conn_id >= dfu_link_num)
+ {
+ DFU_PRINT_ERROR1("dfu_client_start_discovery: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ DFU_PRINT_INFO0("dfu_client_start_discovery!");
+ /* First clear handle cache. */
+ memset(&dfu_table[conn_id], 0, sizeof(T_DFU_LINK));
+ dfu_table[conn_id].disc_state = DISC_DFU_START;
+ if (client_by_uuid128_srv_discovery(conn_id, dfu_client,
+ (uint8_t *)dfu_service_uuid) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+
+/**
+ * @brief Used by application, read data from server by using handles.
+ * @param readCharType: one of characteristic that has the readable property.
+ * @retval true--send request to upper stack success.
+ * false--send request to upper stack failed.
+ */
+bool dfu_client_read_by_handle(uint8_t conn_id, T_DFU_READ_TYPE type)
+{
+ bool hdl_valid = false;
+ uint16_t handle = 0;
+
+ if (conn_id >= dfu_link_num)
+ {
+ DFU_PRINT_ERROR1("dfu_client_read_by_handle: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ switch (type)
+ {
+ case DFU_READ_CP_CCCD:
+ if (dfu_table[conn_id].hdl_cache[DFU_READ_CP_CCCD])
+ {
+ handle = dfu_table[conn_id].hdl_cache[DFU_READ_CP_CCCD];
+ hdl_valid = true;
+ }
+ break;
+ default:
+ return false;
+ }
+
+ if (hdl_valid)
+ {
+ if (client_attr_read(conn_id, dfu_client, handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ DFU_PRINT_INFO1("dfu_client_read_by_handle fail! type=%d", type);
+ return false;
+}
+
+/**
+ * @brief Used by application, read data from server by using UUIDs.
+ * @param readCharType: one of characteristic that has the readable property.
+ * @retval true--send request to upper stack success.
+ * false--send request to upper stack failed.
+ */
+bool dfu_client_read_by_uuid(uint8_t conn_id, T_DFU_READ_TYPE type)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint16_t uuid16;
+ switch (type)
+ {
+ case DFU_READ_CP_CCCD:
+ start_handle = dfu_table[conn_id].hdl_cache[HDL_DFU_CP] + 1;
+ end_handle = dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_END];
+ uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG;
+ break;
+ default:
+ return false;
+ }
+
+ if (client_attr_read_using_uuid(conn_id, dfu_client, start_handle, end_handle, uuid16,
+ NULL) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ DFU_PRINT_INFO1("dfu_client_read_by_uuid fail! type=%d", type);
+ return false;
+}
+
+/**
+ * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic.
+ * @param command: 0--disable the notification, 1--enable the notification.
+ * @retval true--send request to upper stack success.
+ * false--send request to upper stack failed.
+ */
+bool dfu_client_cp_cccd_set(uint8_t conn_id, bool command)
+{
+ uint16_t handle;
+ uint16_t length;
+ uint8_t *pdata;
+ uint16_t cccd_value;
+ handle = dfu_table[conn_id].hdl_cache[HDL_DFU_CP_CCCD];
+ if (handle)
+ {
+ cccd_value = command ? 1 : 0;
+ length = sizeof(uint16_t);
+ pdata = (uint8_t *)&cccd_value;
+ if (client_attr_write(conn_id, dfu_client, GATT_WRITE_TYPE_REQ, handle, length,
+ pdata) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ DFU_PRINT_INFO1("dfu_client_cp_cccd_set fail! handle=0x%x", handle);
+ return false;
+}
+
+/**
+ * @brief Used internal, to send write request to peer server's V5 Control Point Characteristic.
+ * @param ctl_pnt_ptr: pointer of control point data to write.
+ * @retval true--send request to upper stack success.
+ * false--send request to upper stack failed.
+ */
+bool dfu_client_cp_write(uint8_t conn_id, uint8_t *pdata, uint16_t length)
+{
+ uint16_t handle;
+ dfu_fsm_write = DFU_FSM_WRITE_WAIT_WRITE_RESP;
+ handle = dfu_table[conn_id].hdl_cache[HDL_DFU_CP];
+ if (handle)
+ {
+ if (client_attr_write(conn_id, dfu_client, GATT_WRITE_TYPE_REQ, handle, length,
+ pdata) == GAP_CAUSE_SUCCESS)
+ {
+ DFU_PRINT_INFO3("==>dfu_client_cp_write success: conn_id=%d, opcode=0x%x, len=%d",
+ conn_id, pdata[0], length);
+ return true;
+ }
+ }
+
+ DFU_PRINT_INFO1("==>dfu_client_cp_write fail! handle=0x%x", handle);
+ return false;
+}
+
+/**
+ * @brief Used internal, to send write request to peer server's V5 Control Point Characteristic.
+ * @param ctl_pnt_ptr: pointer of control point data to write.
+ * @retval true--send request to upper stack success.
+ * false--send request to upper stack failed.
+ */
+bool dfu_client_data_write(uint8_t conn_id, uint8_t *pdata, uint16_t length)
+{
+ uint16_t handle;
+ dfu_fsm_write = DFU_FSM_WRITE_DFU_DATA;
+ handle = dfu_table[conn_id].hdl_cache[HDL_DFU_DATA];
+ if (handle)
+ {
+ if (client_attr_write(conn_id, dfu_client, GATT_WRITE_TYPE_CMD, handle, length,
+ pdata) == GAP_CAUSE_SUCCESS)
+ {
+ DFU_PRINT_INFO2("==>dfu_client_data_write success: conn_id=%d, len=%d", conn_id, length);
+ return true;
+ }
+ }
+
+ DFU_PRINT_INFO1("dfu_client_data_write fail! handle=0x%x", handle);
+ return false;
+}
+
+/**
+ * @brief Used internal, start the discovery of Dfu characteristics.
+ * NOTE--user can offer this interface for application if required.
+ * @retval true--send request to upper stack success.
+ * false--send request to upper stack failed.
+ */
+static bool dfu_client_start_all_char_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ DFU_PRINT_INFO0("dfu_client_start_all_char_discovery");
+ start_handle = dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_START];
+ end_handle = dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_END];
+ return (client_all_char_discovery(conn_id, dfu_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS);
+}
+
+/**
+ * @brief Used internal, start the discovery of Dfu characteristics descriptor.
+ * NOTE--user can offer this interface for application if required.
+ * @retval true--send request to upper stack success.
+ * false--send request to upper stack failed.
+ */
+static bool dfu_client_start_all_char_descriptor_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+ DFU_PRINT_INFO0("dfu_client_start_all_char_descriptor_discovery");
+ start_handle = dfu_table[conn_id].hdl_cache[HDL_DFU_CP];
+ end_handle = dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_END];
+ return (client_all_char_descriptor_discovery(conn_id, dfu_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS);
+}
+
+
+/**
+ * @brief Called by profile client layer, when discover state of discovery procedure changed.
+ * @param discoveryState: current service discovery state.
+ * @retval ProfileResult_Success--procedure OK.
+ * other--procedure exception.
+ */
+static void dfu_client_disc_state_cb(uint8_t conn_id, T_DISCOVERY_STATE disc_state)
+{
+ bool cb_flag = false;
+
+ T_DFU_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = DFU_CLIENT_CB_TYPE_DISC_STATE;
+
+ DFU_PRINT_INFO1("dfu_client_disc_state_cb: disc_state = %d", disc_state);
+ if (dfu_table[conn_id].disc_state == DISC_DFU_START)
+ {
+ switch (disc_state)
+ {
+ case DISC_STATE_SRV_DONE:
+ /* Indicate that service handle found. Start discover characteristic. */
+ if ((dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_START] != 0)
+ || (dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_END] != 0))
+ {
+ DFU_PRINT_INFO0("GG2 dfu_client_disc_state_cb: Start Find all characteristic!");
+ if (dfu_client_start_all_char_discovery(conn_id) == false)
+ {
+ cb_data.cb_content.disc_state = DISC_DFU_FAIL;
+ cb_flag = true;
+ }
+ }
+ /* No dfu service handle found. Discover procedure complete. */
+ else
+ {
+ cb_data.cb_content.disc_state = DISC_DFU_FAIL;
+ cb_flag = true;
+ }
+ break;
+ case DISC_STATE_CHAR_DONE:
+
+ //discovery cccd
+ if (dfu_client_start_all_char_descriptor_discovery(conn_id) == false)
+ {
+ dfu_table[conn_id].disc_state = DISC_DFU_FAIL;
+ cb_flag = true;
+ }
+ break;
+ case DISC_STATE_CHAR_DESCRIPTOR_DONE:
+ /* Find the next descriptor to be discovered. */
+ cb_data.cb_content.disc_state = DISC_DFU_DONE;
+ cb_flag = true;
+ break;
+ default:
+ DFU_PRINT_INFO0("dfu_client_disc_state_cb: Invalid Discovery State!");
+ break;
+ }
+ }
+
+ if (cb_data.cb_content.disc_state == DISC_DFU_DONE)
+ {
+ /* Discovery Simple BLE service procedure successfully done. */
+ DFU_PRINT_INFO0("==>dfu_client_disc_state_cb: discover procedure done.");
+ if (dfu_client_cp_cccd_set(conn_id, 1)) //enable server notification
+ {
+ dfu_fsm_write = DFU_FSM_WRITE_CCCD_ENABLE;
+ DFU_PRINT_INFO0("==>dfu_client_disc_state_cb: Enable CCCD.");
+ }
+ }
+ else if (cb_data.cb_content.disc_state == DISC_DFU_FAIL)
+ {
+ /* Discovery Request failed. */
+ DFU_PRINT_INFO0("==>dfu client hdl msg: discover request failed.");
+ }
+ else
+ {
+ //don't handle type
+ }
+
+ /* Send discover state to application if needed. */
+ if (cb_flag && pf_dfu_client_cb)
+ {
+ (*pf_dfu_client_cb)(dfu_client, conn_id, &cb_data);
+ }
+}
+
+/**
+ * @brief Called by profile client layer, when discover result fetched.
+ * @param resultType: indicate which type of value discovered in service discovery procedure.
+ * @param resultData: value discovered.
+ * @retval ProfileResult_Success--procedure OK.
+ * other--procedure exception.
+ */
+static void dfu_client_disc_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ DFU_PRINT_INFO1("==>dfu_client_disc_result_cb: result_type=%d", result_type);
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ /* send service handle range to application. */
+ DFU_PRINT_INFO2("==>dfu_client_disc_result_cb: Primary service Found! Set dfu start_handle=0x%4x, end_handle=0x%4x",
+ result_data.p_srv_disc_data->att_handle, result_data.p_srv_disc_data->end_group_handle);
+ dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_START] = result_data.p_srv_disc_data->att_handle;
+ dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_END] = result_data.p_srv_disc_data->end_group_handle;
+ break;
+ case DISC_RESULT_CHAR_UUID128:
+ /* we should inform intrested handles to upper application. */
+ if (0 == memcmp(result_data.p_char_uuid128_disc_data->uuid128, dfu_data_uuid, 16))
+ {
+ DFU_PRINT_INFO1("==>dfu_client_disc_result_cb: Set dfu_data handle=0x%4x",
+ result_data.p_char_uuid128_disc_data->value_handle);
+ dfu_table[conn_id].hdl_cache[HDL_DFU_DATA] = result_data.p_char_uuid128_disc_data->value_handle;
+ }
+ else if (0 == memcmp(result_data.p_char_uuid128_disc_data->uuid128, dfu_control_point_uuid, 16))
+ {
+ DFU_PRINT_INFO1("==>dfu_client_disc_result_cb: Set dfu_control_point handle=0x%4x",
+ result_data.p_char_uuid128_disc_data->value_handle);
+ dfu_table[conn_id].hdl_cache[HDL_DFU_CP] = result_data.p_char_uuid128_disc_data->value_handle;
+ }
+ break;
+ case DISC_RESULT_CHAR_DESC_UUID16:
+ /* When use clientAPI_AllCharDescriptorDiscovery. */
+ if (result_data.p_char_desc_uuid16_disc_data->uuid16 ==
+ GATT_UUID_CHAR_CLIENT_CONFIG) //GATT Client Characteristic Configuration descriptors uuid
+ {
+ uint16_t temp_handle = result_data.p_char_desc_uuid16_disc_data->handle;
+ DFU_PRINT_INFO2("==>dfu_client_disc_result_cb: Set dfu_cccd handle=0x%4x, properties=0x%x",
+ temp_handle, result_data.p_char_uuid16_disc_data->properties);
+ dfu_table[conn_id].hdl_cache[HDL_DFU_CP_CCCD] = temp_handle;
+ dfu_table[conn_id].properties = result_data.p_char_uuid16_disc_data->properties;
+ }
+ break;
+ default:
+ DFU_PRINT_INFO0("dfu_client_disc_result_cb: Invalid Discovery Result Type!");
+ break;
+ }
+}
+
+/**
+ * @brief Called by profile client layer, when read request responsed.
+ * @param reqResult: read request from peer device success or not.
+ * @param wHandle: handle of the value in read response.
+ * @param iValueSize: size of the value in read response.
+ * @param pValue: pointer to the value in read response.
+ * @retval ProfileResult_Success--procedure OK.
+ * other--procedure exception.
+ */
+static void dfu_client_read_result_cb(uint8_t conn_id, uint16_t cause, uint16_t handle,
+ uint16_t len, uint8_t *pvalue)
+{
+ T_DFU_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = DFU_CLIENT_CB_TYPE_READ_RESULT;
+ cb_data.cb_content.read_result.cause = cause;
+ DFU_PRINT_INFO3("==>dfu_client_read_result_cb: cause=%d, handle=0x%x, size=%d", cause,
+ handle, len);
+ /* If read req success, branch to fetch value and send to application. */
+ if (handle == dfu_table[conn_id].hdl_cache[HDL_DFU_CP_CCCD])
+ {
+ cb_data.cb_content.read_result.type = DFU_READ_CP_CCCD;
+ if (cause == GAP_SUCCESS && len == sizeof(uint16_t))
+ {
+ uint16_t cccd_value;
+ LE_ARRAY_TO_UINT16(cccd_value, pvalue);
+ cb_data.cb_content.read_result.data.dfu_cp_cccd = cccd_value &
+ GATT_CLIENT_CHAR_CONFIG_NOTIFY;
+ }
+ }
+
+ /* Inform application the read result. */
+ if (pf_dfu_client_cb)
+ {
+ (*pf_dfu_client_cb)(dfu_client, conn_id, &cb_data);
+ }
+}
+
+/**
+ * @brief Called by profile client layer, when write request complete.
+ * @param reqResult: write request send success or not.
+ * @retval ProfileResult_Success--procedure OK.
+ * other--procedure exception.
+ */
+static void dfu_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, uint16_t handle,
+ uint16_t cause, uint8_t credits)
+{
+ T_DFU_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = DFU_CLIENT_CB_TYPE_WRITE_RESULT;
+ cb_data.cb_content.write_result.cause = cause;
+
+ DFU_PRINT_INFO4("==>dfu_client_write_result_cb: cause=%d, handle=0x%x, type=%d, credits=%d",
+ cause, handle, type, credits);
+ /* If write req success, branch to fetch value and send to application. */
+ if (handle == dfu_table[conn_id].hdl_cache[HDL_DFU_CP_CCCD])
+
+ {
+ cb_data.cb_content.write_result.type = DFU_WRITE_CP_CCCD;
+ }
+ else if (handle == dfu_table[conn_id].hdl_cache[HDL_DFU_CP])
+ {
+ cb_data.cb_content.write_result.type = DFU_WRITE_CP;
+ }
+ else if (handle == dfu_table[conn_id].hdl_cache[HDL_DFU_DATA])
+ {
+ cb_data.cb_content.write_result.type = DFU_WRITE_DATA;
+ }
+ else
+ {
+ DFU_PRINT_ERROR1("==>dfu_client_write_result_cb: invalid handle=0x%x!", handle);
+ return;
+ }
+
+ /* Inform application the write result. */
+ if (pf_dfu_client_cb)
+ {
+ (*pf_dfu_client_cb)(dfu_client, conn_id, &cb_data);
+ }
+}
+
+/**
+ * @brief Called by profile client layer, when notification or indication arrived.
+ * @param wHandle: handle of the value in received data.
+ * @param iValueSize: size of the value in received data.
+ * @param pValue: pointer to the value in received data.
+ * @retval ProfileResult_Success--procedure OK.
+ * other--procedure exception.
+ */
+static T_APP_RESULT dfu_client_notify_indicate_cb(uint8_t conn_id, bool notify,
+ uint16_t handle, uint16_t len, uint8_t *pvalue)
+{
+ T_APP_RESULT app_result = APP_RESULT_REJECT;
+ T_DFU_CLIENT_CB_DATA cb_data;
+
+ DFU_PRINT_INFO3("==>dfu_client_notify_indicate_cb: handle=0x%x, len=%d, is notify=%d",
+ handle, len, notify);
+ if (handle == dfu_table[conn_id].hdl_cache[HDL_DFU_CP])
+ {
+ cb_data.cb_type = DFU_CLIENT_CB_TYPE_NOTIF_IND_RESULT;
+ cb_data.cb_content.notif_ind_data.type = DFU_RECEIVE_CP_NOTIFY;
+ cb_data.cb_content.notif_ind_data.value.len = len;
+ cb_data.cb_content.notif_ind_data.value.pdata = pvalue;
+
+ /* Inform application the notif/ind result. */
+ if (pf_dfu_client_cb)
+ {
+ (*pf_dfu_client_cb)(dfu_client, conn_id, &cb_data);
+ }
+ app_result = APP_RESULT_SUCCESS;
+ }
+
+ return app_result;
+}
+
+static void dfu_client_disconnect_cb(uint8_t conn_id)
+{
+ DFU_PRINT_INFO0("dfu_client_disc_cb");
+ if (conn_id >= dfu_link_num)
+ {
+ DFU_PRINT_ERROR1("dfu_client_disc_cb: failed invalid conn_id %d", conn_id);
+ return;
+ }
+ memset(&dfu_table[conn_id], 0, sizeof(T_DFU_LINK));
+ return;
+}
+
+/**
+ * @brief procedure that client send control point cmd to server.
+ * @param conn_id: connection id.
+ * @param opcode: control point opcode.
+ */
+void dfu_client_process_control_point(uint8_t conn_id, T_DFU_CP_OPCODE opcode)
+{
+ uint8_t data[DFU_LENGTH_MAX];
+ data[0] = opcode;
+
+ DFU_PRINT_INFO1("===>dfu_client_process_control_point: opcode=0x%x", opcode);
+ switch (opcode)
+ {
+ case DFU_OPCODE_START_DFU: //0x1
+ {
+ uint8_t *pheader = (uint8_t *)dfu_client_ctx.dfu_img_start_addr;
+ dfu_client_ctx.dfu_img_total_length = ((T_IMG_CTRL_HEADER_FORMAT *)pheader)->payload_len +
+ IMG_HEADER_SIZE;
+ DFU_PRINT_INFO3("==>dfu_client_process_control_point: START_DFU img_id=0x%x, ic_type=0x%x, dfu_img_total_len=%d",
+ dfu_client_ctx.dfu_ctrl_header.image_id,
+ dfu_client_ctx.dfu_ctrl_header.ic_type,
+ dfu_client_ctx.dfu_img_total_length);
+
+ memcpy(data + 1, pheader, DFU_HEADER_SIZE);
+ memset(data + 1 + DFU_HEADER_SIZE, 0, 4);
+ //aes encrypt when ota
+ if (dfu_client_ctx.ota_mode.mode_flag.aesflg)
+ {
+ DFU_PRINT_INFO1("===>Ctrl Header before encryped: %b", TRACE_BINARY(16, data + 1));
+ dfu_encrypt(data + 1);
+ DFU_PRINT_INFO1("===>Ctrl Header after encryped: %b", TRACE_BINARY(16, data + 1));
+ }
+ dfu_client_cp_write(conn_id, data, DFU_LENGTH_START_DFU);
+ //update offset
+ dfu_client_ctx.curr_offset = DFU_HEADER_SIZE;
+ }
+ break;
+ case DFU_OPCODE_RECEIVE_FW_IMAGE_INFO: //0x2
+ {
+ LE_UINT16_TO_ARRAY(data + 1, dfu_client_ctx.dfu_ctrl_header.image_id);
+ LE_UINT32_TO_ARRAY(data + 3, dfu_client_ctx.curr_offset);
+ dfu_client_cp_write(conn_id, data, DFU_LENGTH_RECEIVE_FW_IMAGE_INFO);
+ }
+ break;
+ case DFU_OPCODE_VALID_FW: //0x3
+ {
+ DFU_PRINT_INFO1("===>DFU_OPCODE_VALID_FW: image_id=0x%x", dfu_client_ctx.dfu_ctrl_header.image_id);
+ LE_UINT16_TO_ARRAY(data + 1, dfu_client_ctx.dfu_ctrl_header.image_id);
+ dfu_client_cp_write(conn_id, data, DFU_LENGTH_VALID_FW);
+ }
+ break;
+ case DFU_OPCODE_ACTIVE_IMAGE_RESET: //0x4
+ {
+ dfu_client_cp_write(conn_id, data, DFU_LENGTH_ACTIVE_IMAGE_RESET);
+ }
+ break;
+ case DFU_OPCODE_SYSTEM_RESET: //0x5
+ {
+ dfu_client_cp_write(conn_id, data, DFU_LENGTH_SYSTEM_RESET);
+ }
+ break;
+ case DFU_OPCODE_REPORT_TARGET_INFO: //0x6
+ {
+ DFU_PRINT_INFO1("===>DFU_OPCODE_REPORT_TARGET_INFO: image_id=0x%x",
+ dfu_client_ctx.dfu_ctrl_header.image_id);
+ LE_UINT16_TO_ARRAY(data + 1, dfu_client_ctx.dfu_ctrl_header.image_id);
+ dfu_client_cp_write(conn_id, data, DFU_LENGTH_REPORT_TARGET_INFO);
+ }
+ break;
+ case DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ: //0x7
+ {
+ }
+ break;
+ case DFU_OPCODE_BUFFER_CHECK_EN: //0x9
+ {
+ dfu_client_cp_write(conn_id, data, DFU_LENGTH_BUFFER_CHECK_EN);
+ }
+ break;
+ case DFU_OPCODE_REPORT_BUFFER_CRC: //0xa
+ {
+ DFU_PRINT_INFO2("===>DFU_OPCODE_REPORT_BUFFER_CRC: dfu_buf_check_size=0x%x, dfu_buf_check_crc_val",
+ dfu_client_ctx.dfu_buf_check_size,
+ dfu_client_ctx.dfu_buf_check_crc_val);
+
+ LE_UINT16_TO_ARRAY(data + 1, dfu_client_ctx.dfu_buf_check_size);
+ LE_UINT16_TO_ARRAY(data + 3, dfu_client_ctx.dfu_buf_check_crc_val);
+ dfu_client_cp_write(conn_id, data, DFU_LENGTH_REPORT_BUFFER_CRC);
+ }
+ break;
+ case DFU_OPCODE_COPY_IMG:
+ {
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief procedure that client send image data to server.
+ * @param conn_id: connection id.
+ */
+bool dfu_client_push_image(uint8_t conn_id)
+{
+ uint16_t mtu_size = 0;
+ uint16_t push_img_size = 0;
+ uint32_t image_size = 0;
+ uint8_t *p_dfu_header;
+ uint8_t *pdata;
+
+ p_dfu_header = (uint8_t *)dfu_client_ctx.dfu_img_start_addr;
+ //DFU_PRINT_INFO1("==>dfu_client_push_image: p_dfu_header=0x%x", p_dfu_header);
+
+ if (dfu_fsm_write == DFU_FSM_WRITE_WAIT_WRITE_RESP)
+ {
+ // in case that the credit is bigger than the buffer check packet num
+ DFU_PRINT_INFO0("==>dfu_client_push_image fail! Waiting for control point response!");
+ return false;
+ }
+
+ mtu_size = (dfu_client_ctx.mtu_size - 3) & 0xfff0; //mtu size down align 16 bytes
+ image_size = dfu_client_ctx.dfu_img_total_length - dfu_client_ctx.curr_offset;
+ push_img_size = (image_size > mtu_size ? mtu_size : image_size); //get min value
+ DFU_PRINT_INFO3("==>dfu_client_push_image: MIN(mtu_size=%d, img_size=%d)= push_img_size %d",
+ mtu_size, image_size, push_img_size);
+
+ if (dfu_client_ctx.dfu_pkt_counter == (dfu_client_ctx.dfu_pkt_num - 1) &&
+ !dfu_client_ctx.ota_mode.mode_flag.buf_check_en)
+ {
+ push_img_size = dfu_client_ctx.dfu_last_pkt_size;
+ }
+ DFU_PRINT_INFO3("==>dfu_client_push_image: push_img_size=%d, curr_offset=%d, dfu_img_total_length=%d",
+ push_img_size, dfu_client_ctx.curr_offset, dfu_client_ctx.dfu_img_total_length);
+
+ pdata = os_mem_alloc(RAM_TYPE_DATA_ON, push_img_size); //send one packet(mtu size) or left img size
+ if (pdata == NULL)
+ {
+ return false;
+ }
+
+ memcpy(pdata, p_dfu_header + dfu_client_ctx.curr_offset, push_img_size);
+ if (dfu_client_ctx.ota_mode.mode_flag.aesflg && dfu_client_ctx.ota_mode.mode_flag.aesmode)
+ {
+ uint8_t *ptmp = pdata;
+ for (uint16_t loop = 0; loop < push_img_size / 16; loop++) //only encrypt 16 bytes align
+ {
+ dfu_encrypt(ptmp);
+ ptmp += 16;
+ }
+ }
+
+ if (dfu_client_data_write(conn_id, pdata, push_img_size))
+ {
+ dfu_client_ctx.curr_offset += push_img_size;
+
+ /*Target Enable Buffer Check Case*/
+ if (dfu_client_ctx.ota_mode.mode_flag.buf_check_en) //enable buffer check
+ {
+ if (!dfu_client_ctx.dfu_pkt_counter)
+ {
+ dfu_client_ctx.dfu_buf_check_crc_val = 0;
+ }
+ dfu_client_ctx.dfu_pkt_counter++;
+ dfu_client_ctx.dfu_buf_check_crc_val = dfu_client_temp_crc_cal(pdata, push_img_size,
+ dfu_client_ctx.dfu_buf_check_crc_val);
+ /*can do buffer check or not*/
+ if (dfu_client_ctx.dfu_pkt_counter == dfu_client_ctx.dfu_pkt_num ||
+ dfu_client_ctx.curr_offset == dfu_client_ctx.dfu_img_total_length)
+ {
+ dfu_client_ctx.dfu_buf_check_crc_val = swap_16(dfu_client_ctx.dfu_buf_check_crc_val);
+ dfu_client_ctx.dfu_buf_check_size = push_img_size +
+ (dfu_client_ctx.dfu_pkt_counter - 1) * mtu_size;
+ /*send opcode 0xa*/
+ dfu_client_process_control_point(conn_id, DFU_OPCODE_REPORT_BUFFER_CRC);
+ dfu_client_ctx.dfu_pkt_counter = 0;
+ }
+ }
+ else //disable buffer check
+ {
+ DFU_PRINT_INFO0("==>dfu_client_push_image: buffer check disable");
+ dfu_client_ctx.dfu_pkt_counter++;
+ if (dfu_client_ctx.dfu_pkt_counter == dfu_client_ctx.dfu_pkt_num)
+ {
+ DFU_PRINT_INFO0("==>dfu_client_push_image: buffer check disable, target need write flash");
+ //wait for slave write image to flash
+ os_delay(200);
+ dfu_client_ctx.dfu_pkt_counter = 0;
+ }
+ }
+ os_mem_free(pdata);
+ return true;
+ }
+ else
+ {
+ DFU_PRINT_INFO0("==>dfu_client_push_image: fail write data");
+
+ os_mem_free(pdata);
+ return false;
+ }
+}
+
+
+void dfu_client_handle_cp_notify_msg(uint8_t conn_id, uint8_t *p_notif_data, uint16_t len)
+{
+ /*Notification Format: notify_opcode(1 byte)+cp opcode(1 byte)+error code(1 byte)+ payload(different length)*/
+ uint8_t notify_opcode = p_notif_data[0];
+ uint8_t opcode = p_notif_data[1];
+ T_DFU_ARV_ERROR_CODE error_code = (T_DFU_ARV_ERROR_CODE)p_notif_data[2];
+ if (notify_opcode != DFU_OPCODE_NOTIFICATION)
+ {
+ DFU_PRINT_INFO1("==>dfu_client_handle_cp_notify_msg: invalid notify_opcode=0x%x!", notify_opcode);
+ return;
+ }
+
+ DFU_PRINT_INFO2("==>dfu_client_handle_cp_notify_msg: opcode=0x%x, len=%d", opcode, len);
+ switch (opcode)
+ {
+ case DFU_OPCODE_BUFFER_CHECK_EN: //0x9
+ {
+ if (len == DFU_NOTIFY_LENGTH_BUFFER_CHECK_EN)
+ {
+ LE_ARRAY_TO_UINT16(dfu_client_ctx.max_buffer_size, p_notif_data + 3);
+ LE_ARRAY_TO_UINT16(dfu_client_ctx.mtu_size, p_notif_data + 5);
+ DFU_PRINT_INFO2("==>dfu_client_handle_cp_notify_msg: max_buffer_size=0x%x, mtu_size=0x%x",
+ dfu_client_ctx.max_buffer_size, dfu_client_ctx.mtu_size);
+
+ if (error_code == DFU_ARV_SUCCESS)
+ {
+ //target enable buffer check
+
+ dfu_client_ctx.dfu_pkt_num = dfu_client_ctx.max_buffer_size /
+ ((dfu_client_ctx.mtu_size - 3) & 0xfff0);
+ dfu_client_ctx.dfu_pkt_counter = 0;
+ DFU_PRINT_INFO1("==>dfu_client_handle_cp_notify_msg: Target buffer check enable, dfu_pkt_num=%d",
+ dfu_client_ctx.dfu_pkt_num);
+ }
+ else
+ {
+ uint32_t max_buffer_size = dfu_client_ctx.max_buffer_size - (dfu_client_ctx.max_buffer_size % 20);
+ uint16_t mtu_size = (dfu_client_ctx.mtu_size - 3) & 0xfff0;
+ dfu_client_ctx.dfu_pkt_num = (max_buffer_size + mtu_size - 1) / mtu_size;
+ dfu_client_ctx.dfu_last_pkt_size = (max_buffer_size % mtu_size) ? (max_buffer_size % mtu_size) :
+ mtu_size;
+ dfu_client_ctx.dfu_pkt_counter = 0;
+ DFU_PRINT_INFO2("==>dfu_client_handle_cp_notify_msg: Target buffer check disable, max_buffer_size=%d, dfu_pkt_num=%d",
+ max_buffer_size, dfu_client_ctx.dfu_pkt_num);
+
+ }
+
+ dfu_client_process_control_point(conn_id, DFU_OPCODE_REPORT_TARGET_INFO);
+ }
+ }
+ break;
+ case DFU_OPCODE_REPORT_TARGET_INFO: //0x6
+ {
+ if (len == DFU_NOTIFY_LENGTH_REPORT_TARGET_INFO)
+ {
+ LE_ARRAY_TO_UINT32(dfu_client_ctx.target_img_version, p_notif_data + 3);
+ LE_ARRAY_TO_UINT32(dfu_client_ctx.curr_offset, p_notif_data + 7);
+ DFU_PRINT_INFO2("dfu_client_handle_cp_notify_msg: target_version=0x%x, img_id=0x%x",
+ dfu_client_ctx.target_img_version,
+ dfu_client_ctx.dfu_ctrl_header.image_id);
+
+ DFU_PRINT_INFO5("dfu_client_handle_cp_notify_msg: target_version=%d.%d.%d.%d, dfu_client_ctx.curr_offset=0x%x",
+ MAJOR_IMG_VER(dfu_client_ctx.target_img_version),
+ MINOR_IMG_VER(dfu_client_ctx.target_img_version),
+ REVISION_IMG_VER(dfu_client_ctx.target_img_version),
+ RESERVE_IMG_VER(dfu_client_ctx.target_img_version),
+ dfu_client_ctx.curr_offset);
+ if (DFU_FEATURE_AUTO_COPY_DFU == dfu_client_ctx.dfu_feature)
+ {
+ uint32_t le_target_ver = IMAGE_VERSION_TO_LE_UINT32(dfu_client_ctx.target_img_version);
+ uint32_t le_dfu_ver = 0;
+ if (dfu_client_ctx.dfu_ctrl_header.image_id == AppPatch)
+ {
+ //init dfu_client_ctx.dfu_img_version in format T_IMAGE_VERSION
+ get_active_bank_image_version(AppPatch, (T_IMAGE_VERSION *)&dfu_client_ctx.dfu_img_version);
+
+ le_dfu_ver = IMAGE_VERSION_TO_LE_UINT32(dfu_client_ctx.dfu_img_version);
+ DFU_PRINT_INFO2("dfu_client_handle_cp_notify_msg: le_dfu_ver=0x%x, le_target_ver=0x%x",
+ le_dfu_ver, le_target_ver);
+ //compare target image version with dfu img version to determine continue dfu procedure or not
+ if (le_dfu_ver <= le_target_ver)
+ {
+ DBG_DIRECT("auto Copy OTA: app no need ota!");
+
+ dfu_client_ctx.dfu_ctrl_header.image_id = RomPatch;
+ dfu_client_ctx.dfu_img_start_addr = get_header_addr_by_img_id(RomPatch);
+ /*get target patch image version*/
+ dfu_client_process_control_point(conn_id, DFU_OPCODE_REPORT_TARGET_INFO);
+ return;
+ }
+ }
+ else if (dfu_client_ctx.dfu_ctrl_header.image_id == RomPatch)
+ {
+ get_active_bank_image_version(RomPatch, (T_IMAGE_VERSION *)&dfu_client_ctx.dfu_img_version);
+
+ le_dfu_ver = IMAGE_VERSION_TO_LE_UINT32(dfu_client_ctx.dfu_img_version);
+
+ DFU_PRINT_INFO2("dfu_client_handle_cp_notify_msg: le_dfu_ver=0x%x, le_target_ver=0x%x",
+ le_dfu_ver, le_target_ver);
+ //if dfu patch version less than and equal target img version, don't OTA
+ if (le_dfu_ver <= le_target_ver)
+ {
+ DBG_DIRECT("auto Copy OTA: patch no need OTA!");
+ return;
+ }
+ }
+ else
+ {
+ return;
+ }
+
+ dfu_client_process_control_point(conn_id, DFU_OPCODE_START_DFU);
+ }
+ else // not auto copy dfu
+ {
+ dfu_client_ctx.dfu_img_version = ((T_IMG_HEADER_FORMAT *)
+ dfu_client_ctx.dfu_img_start_addr)->git_ver.ver_info.version;
+ /*if only support upgrade, need compare version value in litte endian */
+ dfu_client_process_control_point(conn_id, DFU_OPCODE_START_DFU);
+ }
+
+
+ /*notify application*/
+ if (pf_dfu_client_app_info_cb)
+ {
+ T_DFU_CLIENT_CB_MSG cb_msg;
+ cb_msg.conn_id = conn_id;
+ cb_msg.type = DFU_CB_START;
+ pf_dfu_client_app_info_cb(dfu_client, conn_id, &cb_msg);
+ }
+ }
+ }
+ break;
+ case DFU_OPCODE_START_DFU: //0x1
+ {
+ if (len == DFU_NOTIFY_LENGTH_START_DFU && error_code == DFU_ARV_SUCCESS)
+ {
+ //start push image, make use of credits
+ for (uint8_t loop = 0; loop < 8; loop++)
+ {
+ dfu_client_push_image(conn_id);
+ }
+ }
+ else
+ {
+ if (pf_dfu_client_app_info_cb)
+ {
+ T_DFU_CLIENT_CB_MSG cb_msg;
+ cb_msg.conn_id = conn_id;
+ cb_msg.type = DFU_CB_FAIL;
+ cb_msg.data.dfu_fail_reason = DFU_FAIL_START_DFU;
+ pf_dfu_client_app_info_cb(dfu_client, conn_id, &cb_msg);
+ }
+ }
+ }
+ break;
+ case DFU_OPCODE_REPORT_BUFFER_CRC: //0xa
+ {
+ if (len == DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC)
+ {
+ uint32_t target_offset;
+ LE_ARRAY_TO_UINT32(target_offset, p_notif_data + 3);
+ DFU_PRINT_INFO2("==>dfu_client_handle_cp_notify_msg: target_offset=%d, dfu_client_ctx.curr_offset=%d",
+ target_offset, dfu_client_ctx.curr_offset);
+
+ /*if buffer check fail, only retry 3 times*/
+ if (error_code != DFU_ARV_SUCCESS)
+ {
+ DFU_PRINT_INFO0("==>dfu_client_handle_cp_notify_msg: target buffer check fail!");
+ buf_check_retry_cnt++;
+ if (buf_check_retry_cnt >= 3)
+ {
+ DFU_PRINT_INFO0("==>dfu_client_handle_cp_notify_msg: one packet retry buffer check 3 times fail!");
+ dfu_client_process_control_point(conn_id, DFU_OPCODE_SYSTEM_RESET);
+
+ if (pf_dfu_client_app_info_cb)
+ {
+ T_DFU_CLIENT_CB_MSG cb_msg;
+ cb_msg.conn_id = conn_id;
+ cb_msg.type = DFU_CB_FAIL;
+ cb_msg.data.dfu_fail_reason = DFU_FAIL_BUF_CHECK;
+ pf_dfu_client_app_info_cb(dfu_client, conn_id, &cb_msg);
+ }
+
+ return;
+ }
+ }
+ else
+ {
+ DFU_PRINT_INFO0("==>dfu_client_handle_cp_notify_msg: target buffer check success!");
+ buf_check_retry_cnt = 0;
+ }
+
+ dfu_client_ctx.curr_offset = target_offset;
+ if (dfu_client_ctx.dfu_img_total_length > dfu_client_ctx.curr_offset)
+ {
+ DFU_PRINT_INFO0("==>dfu_client_handle_cp_notify_msg: Image transmitting (Buffer Check Enable)");
+ dfu_client_push_image(conn_id);
+ }
+ else
+ {
+ //buffer check enable image trans done
+ DFU_PRINT_INFO0("==>dfu_client_handle_cp_notify_msg: Image trans done (Buffer Check Enable)");
+ dfu_client_process_control_point(conn_id, DFU_OPCODE_VALID_FW);
+ }
+ }
+ }
+ break;
+ case DFU_OPCODE_VALID_FW: //0x3
+ {
+ if (len == DFU_NOTIFY_LENGTH_VALID_FW)
+ {
+ T_DFU_CP_OPCODE next_opcode;
+ next_opcode = (error_code == DFU_ARV_SUCCESS) ? DFU_OPCODE_ACTIVE_IMAGE_RESET :
+ DFU_OPCODE_SYSTEM_RESET;
+ dfu_client_process_control_point(conn_id, next_opcode);
+
+ if (pf_dfu_client_app_info_cb)
+ {
+ T_DFU_CLIENT_CB_MSG cb_msg;
+ cb_msg.conn_id = conn_id;
+ cb_msg.type = (error_code == DFU_ARV_SUCCESS) ? DFU_CB_END : DFU_CB_FAIL;
+ cb_msg.data.dfu_fail_reason = (error_code == DFU_ARV_SUCCESS) ? DFU_SUCCESS : DFU_FAIL_VALIDATE_FW;
+ pf_dfu_client_app_info_cb(dfu_client, conn_id, &cb_msg);
+ }
+ }
+ }
+ break;
+ default: //other opcode no ack
+ break;
+ }
+}
+
+
+T_APP_RESULT dfu_client_handle_read_cb(uint8_t conn_id, T_DFU_READ_RESULT *pcb_read_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ switch (pcb_read_data->type)
+ {
+ case DFU_READ_CP_CCCD:
+ DFU_PRINT_INFO1("==>dfu_client_handle_read_cb: dfu_cp_cccd=%d(1:CCCD Enable)",
+ pcb_read_data->data.dfu_cp_cccd);
+ break;
+ default:
+ break;
+ }
+ return result;
+}
+
+T_APP_RESULT dfu_client_handle_write_cb(uint8_t conn_id, T_DFU_WRITE_RESULT *pcb_write_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ DFU_PRINT_INFO1("==>dfu_client_handle_write_cb: type=%d(0: write cp, 1: write cp ccd, 2: write data)",
+ pcb_write_data->type);
+ DFU_PRINT_INFO1("==>dfu_client_handle_write_cb: dfu_fsm_write=%d(0:idle, 1:cccd_enabled, 2: wrote_data, 3: wait for rsp )",
+ dfu_client_ctx.dfu_fsm_write);
+ if (pcb_write_data->cause == 0)
+ {
+ switch (pcb_write_data->type)
+ {
+ case DFU_WRITE_CP_CCCD:
+ DFU_PRINT_INFO1("==>dfu_client_handle_write_cb: DFU_WRITE_CP_CCCD",
+ dfu_fsm_write);
+ if (dfu_fsm_write == DFU_FSM_WRITE_CCCD_ENABLE)
+ {
+ T_IMG_HEADER_FORMAT *p_header = (T_IMG_HEADER_FORMAT *)dfu_client_ctx.dfu_img_start_addr;
+ dfu_client_ctx.dfu_ctrl_header.image_id = p_header->ctrl_header.image_id;
+ dfu_client_process_control_point(conn_id, DFU_OPCODE_BUFFER_CHECK_EN);
+ }
+ break;
+ case DFU_WRITE_DATA:
+ DFU_PRINT_INFO1("==>dfu_client_handle_write_cb: DFU_WRITE_DATA, dfu_fsm_write=%d.",
+ dfu_fsm_write);
+ if (dfu_fsm_write == DFU_FSM_WRITE_DFU_DATA)
+ {
+ if (dfu_client_ctx.dfu_img_total_length > dfu_client_ctx.curr_offset)
+ {
+ DFU_PRINT_INFO0("==>dfu_client_handle_write_cb: DFU_WRITE_DATA, continue push image!");
+ dfu_client_push_image(conn_id);
+ }
+ else
+ {
+ if (!dfu_client_ctx.ota_mode.mode_flag.buf_check_en)
+ {
+ /*when not enable buf check, img trans done, verify img*/
+ DFU_PRINT_INFO0("==>dfu_client_handle_write_cb: Img trans done(BufCheckDisable), validate fw");
+ dfu_client_process_control_point(conn_id, DFU_OPCODE_VALID_FW);
+ }
+ }
+ }
+ break;
+ case DFU_WRITE_CP:
+ DFU_PRINT_INFO1("==>dfu_client_handle_write_cb: DFU_WRITE_CP, dfu_fsm_write=%d.",
+ dfu_fsm_write);
+ if (dfu_fsm_write == DFU_FSM_WRITE_WAIT_WRITE_RESP)
+ {
+ //means received write response
+ dfu_fsm_write = DFU_FSM_WRITE_IDLE;
+ if (dfu_temp_cp_notify_msg_len)
+ {
+ //means first received notification then received write response
+ DFU_PRINT_INFO2("==>dfu_client_handle_write_cb: DFU_WRITE_CP, dfu_fsm_write=%d, dfu_cp_temp_msg_len=%d",
+ dfu_fsm_write, dfu_temp_cp_notify_msg_len);
+ dfu_client_handle_cp_notify_msg(conn_id, dfu_temp_cp_notify_msg, dfu_temp_cp_notify_msg_len);
+ dfu_temp_cp_notify_msg_len = 0;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ DFU_PRINT_INFO3("==>dfu_client_handle_write_cb: write data fail! type=%d, cause=0x%x, dfu_fsm_write=%d",
+ pcb_write_data->type, pcb_write_data->cause, dfu_fsm_write);
+ DFU_PRINT_INFO0("==>dfu_client_handle_write_cb: le_disconnect");
+ le_disconnect(conn_id);
+ }
+
+ return result;
+}
+
+T_APP_RESULT dfu_client_handle_notif_ind_cb(uint8_t conn_id,
+ T_DFU_NOTIFY_INDICATE_DATA *pcb_notif_ind_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ DFU_PRINT_INFO1("==>dfu_client_handle_notif_ind_cb: type=%d(0: DFU_RECEIVE_CP_NOTIFY)",
+ pcb_notif_ind_data->type);
+ switch (pcb_notif_ind_data->type)
+ {
+ case DFU_RECEIVE_CP_NOTIFY:
+ {
+ DFU_PRINT_INFO1("==>dfu_client_handle_notif_ind_cb: dfu_fsm_write=%d(if 0 hdl cp msg, else cache msg)",
+ dfu_fsm_write);
+ if (dfu_fsm_write == DFU_FSM_WRITE_IDLE)
+ {
+ dfu_client_handle_cp_notify_msg(conn_id, pcb_notif_ind_data->value.pdata,
+ pcb_notif_ind_data->value.len);
+ }
+ else
+ {
+ //cache
+ dfu_temp_cp_notify_msg_len = pcb_notif_ind_data->value.len;
+ memcpy(dfu_temp_cp_notify_msg, pcb_notif_ind_data->value.pdata,
+ dfu_temp_cp_notify_msg_len > 20 ? 20 : dfu_temp_cp_notify_msg_len);
+ DFU_PRINT_INFO1("==>dfu_client_handle_notif_ind_cb: cached received notification, len=%d",
+ dfu_temp_cp_notify_msg_len);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return result;
+}
+
+/*profile callback to handle msg*/
+T_APP_RESULT dfu_client_handle_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_DFU_CLIENT_CB_DATA *pcb_data = (T_DFU_CLIENT_CB_DATA *)p_data;
+ DFU_PRINT_INFO1("==>dfu_client_handle_cb: cb_type=%d(0: disc, 1: read, 2: write, 3: notify)",
+ pcb_data->cb_type);
+ switch (pcb_data->cb_type)
+ {
+ case DFU_CLIENT_CB_TYPE_DISC_STATE:
+ break;
+ case DFU_CLIENT_CB_TYPE_READ_RESULT:
+ result = dfu_client_handle_read_cb(conn_id, &pcb_data->cb_content.read_result);
+ break;
+ case DFU_CLIENT_CB_TYPE_WRITE_RESULT:
+ result = dfu_client_handle_write_cb(conn_id, &pcb_data->cb_content.write_result);
+ break;
+ case DFU_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ result = dfu_client_handle_notif_ind_cb(conn_id, &pcb_data->cb_content.notif_ind_data);
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+/**
+ * @brief Dfu Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS dfu_client_cbs =
+{
+ dfu_client_disc_state_cb, //!< Discovery State callback function pointer
+ dfu_client_disc_result_cb, //!< Discovery result callback function pointer
+ dfu_client_read_result_cb, //!< Read response callback function pointer
+ dfu_client_write_result_cb, //!< Write result callback function pointer
+ dfu_client_notify_indicate_cb, //!< Notify Indicate callback function pointer
+ dfu_client_disconnect_cb //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief add Dfu client to application.
+ * @param appCB: pointer of app callback function to handle specific client module data.
+ * @retval Client ID of the specific client module.
+ */
+T_CLIENT_ID dfu_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+{
+ uint16_t size;
+ if (link_num > DFU_MAX_LINKS)
+ {
+ DFU_PRINT_ERROR1("dfu_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&dfu_client, &dfu_client_cbs))
+ {
+ dfu_client = CLIENT_PROFILE_GENERAL_ID;
+ DFU_PRINT_ERROR0("dfu_client_add: fail!");
+ return dfu_client;
+ }
+ DFU_PRINT_INFO1("dfu_client_add: client ID = %d", dfu_client);
+
+ dfu_link_num = link_num;
+ size = dfu_link_num * sizeof(T_DFU_LINK);
+ dfu_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ /* register callback for profile to inform application that some events happened. */
+ pf_dfu_client_cb = dfu_client_handle_cb;
+ pf_dfu_client_app_info_cb = app_cb;
+
+ if (pf_dfu_client_init)
+ {
+ pf_dfu_client_init();
+ }
+
+ return dfu_client;
+}
+
+
diff --git a/src/ble/profile/client/dis_client.c b/src/ble/profile/client/dis_client.c
new file mode 100644
index 0000000..32d30a5
--- /dev/null
+++ b/src/ble/profile/client/dis_client.c
@@ -0,0 +1,825 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file dis_client.c
+ * @brief Dis BLE client source file.
+ * @details
+ * @author ken
+ * @date 2017-12-05
+ * @version v1.0
+ ******************************************************************************
+ */
+
+/** Add Includes here **/
+#include <trace.h>
+#include <string.h>
+#include <dis_client.h>
+#include <os_mem.h>
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+typedef struct
+{
+ T_DIS_DISC_STATE disc_state;
+ uint16_t hdl_cache[HDL_DIS_CACHE_LEN];
+} T_DIS_LINK, *P_DIS_LINK;
+
+static P_DIS_LINK dis_table;
+static uint8_t dis_link_num;
+
+/**< dis client ID. */
+static T_CLIENT_ID dis_client = CLIENT_PROFILE_GENERAL_ID;
+/**< Callback used to send data to app from dis client layer. */
+static P_FUN_GENERAL_APP_CB dis_client_cb = NULL;
+
+/**
+ * @brief Used by application, to start the discovery procedure of lls server.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool dis_client_start_discovery(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("dis_client_start_discovery");
+ if (conn_id >= dis_link_num)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_start_discovery: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ /* First clear handle cache. */
+ memset(&dis_table[conn_id], 0, sizeof(T_DIS_LINK));
+ dis_table[conn_id].disc_state = DISC_DIS_START;
+ if (client_by_uuid_srv_discovery(conn_id, dis_client,
+ GATT_UUID_DEVICE_INFORMATION_SERVICE) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Used by application, to read data from server by using handles.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool dis_client_read_by_handle(uint8_t conn_id, T_DIS_READ_TYPE read_type)
+{
+ bool hdl_valid = false;
+ uint16_t handle;
+ if (conn_id >= dis_link_num)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_read_by_handle: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ switch (read_type)
+ {
+ case DIS_READ_SYSTEM_ID:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_SYSTEM_ID])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_SYSTEM_ID];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_MODEL_NUMBER:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_MODEL_NUMBER])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_MODEL_NUMBER];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_SERIAL_NUMBER:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_SERIAL_NUMBER])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_SERIAL_NUMBER];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_FIRMWARE_REVISION:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_FIRMWARE_REVISION])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_FIRMWARE_REVISION];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_HARDWARE_REVISION:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_HARDWARE_REVISION])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_HARDWARE_REVISION];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_SOFTWARE_REVISION:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_SOFTWARE_REVISION])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_SOFTWARE_REVISION];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_MANUFACTURER_NAME:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_MANUFACTURER_NAME])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_MANUFACTURER_NAME];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_IEEE_CERTIF_DATA_LIST:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_IEEE_CERTIF_DATA_LIST])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_IEEE_CERTIF_DATA_LIST];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_PNP_ID:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_PNP_ID])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_PNP_ID];
+ hdl_valid = true;
+ }
+ break;
+ default:
+ return false;
+ }
+
+ if (hdl_valid)
+ {
+ if (client_attr_read(conn_id, dis_client, handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ APP_PRINT_WARN0("dis_client_read_by_handle: Request fail! Please check!");
+ return false;
+}
+
+/**
+ * @brief Used by application, to read data from server by using UUIDs.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool dis_client_read_by_uuid(uint8_t conn_id,
+ T_DIS_READ_TYPE read_type)//~~~~~~~~~~~~~~~~~~will delete
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint16_t uuid16;
+ if (conn_id >= dis_link_num)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_read_by_uuid: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ switch (read_type)
+ {
+ case DIS_READ_SYSTEM_ID:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_SYSTEM_ID;
+ break;
+ case DIS_READ_MODEL_NUMBER:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_MODEL_NUMBER;
+ break;
+ case DIS_READ_SERIAL_NUMBER:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_SERIAL_NUMBER;
+ break;
+ case DIS_READ_FIRMWARE_REVISION:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_FIRMWARE_REVISION;
+ break;
+ case DIS_READ_HARDWARE_REVISION:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_HARDWARE_REVISION;
+ break;
+ case DIS_READ_SOFTWARE_REVISION:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_SOFTWARE_REVISION;
+ break;
+ case DIS_READ_MANUFACTURER_NAME:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_MANUFACTURER_NAME;
+ break;
+ case DIS_READ_IEEE_CERTIF_DATA_LIST:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_IEEE_CERTIF_DATA_LIST;
+ break;
+ case DIS_READ_PNP_ID:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_PNP_ID;
+ break;
+
+ default:
+ return false;
+ }
+
+ if (client_attr_read_using_uuid(conn_id, dis_client, start_handle, end_handle,
+ uuid16, NULL) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+///**
+// * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic.
+// * @param[in] conn_id connection ID.
+// * @param[in] notify 0--disable the notification, 1--enable the notification.
+// * @retval true send request to upper stack success.
+// * @retval false send request to upper stack failed.
+// */
+//bool lls_client_set_v3_notify(uint8_t conn_id, bool notify)
+//{
+// if (conn_id >= kns_link_num)
+// {
+// PROFILE_PRINT_ERROR1("kns_client_set_v3_notify: failed invalid conn_id %d", conn_id);
+// return false;
+// }
+
+// if (kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD])
+// {
+// uint16_t handle = kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD];
+// uint16_t length = sizeof(uint16_t);
+// uint16_t cccd_bits = notify ? 1 : 0;
+// if (client_attr_write(conn_id, kns_client, GATT_WRITE_TYPE_REQ, handle,
+// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// }
+
+// APP_PRINT_WARN0("kns_client_set_v3_notify: Request fail! Please check!");
+// return false;
+//}
+
+/**
+ * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] ind 0--disable the indication, 1--enable the indication.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool simp_ble_client_set_v4_ind(uint8_t conn_id, bool ind)
+//{
+// if (conn_id >= simp_link_num)
+// {
+// PROFILE_PRINT_ERROR1("simp_ble_client_set_v4_ind: failed invalid conn_id %d", conn_id);
+// return false;
+// }
+
+// if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD])
+// {
+// uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD];
+// uint16_t length = sizeof(uint16_t);
+// uint16_t cccd_bits = ind ? 2 : 0;
+// if (client_attr_write(conn_id, simp_client, GATT_WRITE_TYPE_REQ, handle,
+// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// }
+
+// APP_PRINT_WARN0("simp_ble_client_set_v4_ind: Request fail! Please check!");
+// return false;
+//}
+
+/**
+ * @brief Used by application, to write data of write Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] length write data length
+ * @param[in] p_value point the value to write
+ * @param[in] type write type.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool lls_client_write_char(uint8_t conn_id, uint16_t length, uint8_t *p_value,
+// T_GATT_WRITE_TYPE type)
+//{
+// if (conn_id >= lls_link_num)
+// {
+// PROFILE_PRINT_ERROR1("lls_client_write_char: failed invalid conn_id %d", conn_id);
+// return false;
+// }
+
+// if (lls_table[conn_id].hdl_cache[HDL_LLS_PARA])
+// {
+// uint16_t handle = lls_table[conn_id].hdl_cache[HDL_LLS_PARA];
+// if (client_attr_write(conn_id, lls_client, type, handle,
+// length, p_value) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// }
+
+// APP_PRINT_WARN0("lls_ble_client_write_char: Request fail! Please check!");
+// return false;
+//}
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool dis_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= dis_link_num)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_get_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (dis_table[conn_id].disc_state != DISC_DIS_DONE)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_get_hdl_cache: failed invalid state %d",
+ dis_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_DIS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_get_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(p_hdl_cache, dis_table[conn_id].hdl_cache, len);
+ return true;
+}
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool dis_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= dis_link_num)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_set_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (dis_table[conn_id].disc_state != DISC_DIS_IDLE)
+ {
+ PROFILE_PRINT_ERROR1("lls_client_set_hdl_cache: failed invalid state %d",
+ dis_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_DIS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_set_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(dis_table[conn_id].hdl_cache, p_hdl_cache, len);
+ dis_table[conn_id].disc_state = DISC_DIS_DONE;
+ return true;
+}
+
+static bool dis_client_start_char_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ APP_PRINT_INFO0("dis_client_start_ias_char_discovery");
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ if (client_all_char_discovery(conn_id, dis_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+//static bool lls_client_start_char_descriptor_discovery(uint8_t conn_id)
+//{
+// uint16_t start_handle;
+// uint16_t end_handle;
+
+// PROFILE_PRINT_INFO0("lls_client_start_char_descriptor_discovery");
+// start_handle = lls_table[conn_id].hdl_cache[HDL_LLS_NOTIFY_KEY];
+// end_handle = lls_table[conn_id].hdl_cache[HDL_LLS_SRV_END];
+// if (client_all_char_descriptor_discovery(conn_id, lls_client, start_handle,
+// end_handle) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// return false;
+//}
+static void dis_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state)
+{
+ bool cb_flag = false;
+ T_DIS_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = DIS_CLIENT_CB_TYPE_DISC_STATE;
+
+ APP_PRINT_INFO1("dis_client_discover_state_cb: discovery_state %d", discovery_state);
+ if (dis_table[conn_id].disc_state == DISC_DIS_START)
+ {
+ uint16_t *hdl_cache;
+ hdl_cache = dis_table[conn_id].hdl_cache;
+
+ switch (discovery_state)
+ {
+ case DISC_STATE_SRV_DONE:
+ /* Indicate that service handle found. Start discover characteristic. */
+ if ((hdl_cache[HDL_DIS_SRV_START] != 0)
+ || (hdl_cache[HDL_DIS_SRV_END] != 0))
+ {
+ if (dis_client_start_char_discovery(conn_id) == false)
+ {
+ dis_table[conn_id].disc_state = DISC_DIS_FAILED;
+ cb_flag = true;
+ }
+ }
+ /* No Ias BLE service handle found. Discover procedure complete. */
+ else
+ {
+ dis_table[conn_id].disc_state = DISC_DIS_FAILED;
+ cb_flag = true;
+ }
+ break;
+ case DISC_STATE_CHAR_DONE:
+ dis_table[conn_id].disc_state = DISC_DIS_DONE;
+ cb_flag = true;
+ break;
+ case DISC_STATE_FAILED:
+ dis_table[conn_id].disc_state = DISC_DIS_FAILED;
+ cb_flag = true;
+ break;
+ default:
+ APP_PRINT_ERROR0("dis_handle_discover_state: Invalid Discovery State!");
+ break;
+ }
+ }
+
+ /* Send discover state to application if needed. */
+ if (cb_flag && dis_client_cb)
+ {
+ cb_data.cb_content.disc_state = dis_table[conn_id].disc_state;
+ (*dis_client_cb)(dis_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+/**
+ * @brief Called by profile client layer, when discover result fetched.
+ * @param conn_id: connection ID.
+ * @param result_type: indicate which type of value discovered in service discovery procedure.
+ * @param result_data: value discovered.
+ * @retval None
+ */
+static void dis_client_discover_result_cb(uint8_t conn_id,
+ T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ APP_PRINT_INFO1("dis_client_discover_result_cb: result_type %d", result_type);
+ if (dis_table[conn_id].disc_state == DISC_DIS_START)
+ {
+ uint16_t handle;
+ uint16_t *hdl_cache;
+ hdl_cache = dis_table[conn_id].hdl_cache;
+
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ hdl_cache[HDL_DIS_SRV_START] = result_data.p_srv_disc_data->att_handle;
+ hdl_cache[HDL_DIS_SRV_END] = result_data.p_srv_disc_data->end_group_handle;
+ break;
+ case DISC_RESULT_CHAR_UUID128:
+ break;
+
+ case DISC_RESULT_CHAR_UUID16:
+ handle = result_data.p_char_uuid16_disc_data->value_handle;
+ switch (result_data.p_char_uuid16_disc_data->uuid16)
+ {
+ case GATT_UUID_CHAR_SYSTEM_ID:
+ hdl_cache[HDL_DIS_SYSTEM_ID] = handle;
+ break;
+ case GATT_UUID_CHAR_MODEL_NUMBER:
+ hdl_cache[HDL_DIS_MODEL_NUMBER] = handle;
+ break;
+ case GATT_UUID_CHAR_SERIAL_NUMBER:
+ hdl_cache[HDL_DIS_SERIAL_NUMBER] = handle;
+ break;
+ case GATT_UUID_CHAR_FIRMWARE_REVISION:
+ hdl_cache[HDL_DIS_FIRMWARE_REVISION] = handle;
+ break;
+ case GATT_UUID_CHAR_HARDWARE_REVISION:
+ hdl_cache[HDL_DIS_HARDWARE_REVISION] = handle;
+ break;
+ case GATT_UUID_CHAR_SOFTWARE_REVISION:
+ hdl_cache[HDL_DIS_SOFTWARE_REVISION] = handle;
+ break;
+ case GATT_UUID_CHAR_MANUFACTURER_NAME:
+ hdl_cache[HDL_DIS_MANUFACTURER_NAME] = handle;
+ break;
+ case GATT_UUID_CHAR_IEEE_CERTIF_DATA_LIST:
+ hdl_cache[HDL_DIS_IEEE_CERTIF_DATA_LIST] = handle;
+ break;
+ case GATT_UUID_CHAR_PNP_ID:
+ hdl_cache[HDL_DIS_PNP_ID] = handle;
+ break;
+ default:
+ /* have no interest on this handle. */
+ break;
+ }
+ break;
+
+ case DISC_RESULT_CHAR_DESC_UUID16:
+ /* When use client_all_char_descriptor_discovery. */
+ break;
+
+ default:
+ APP_PRINT_ERROR0("lls_handle_discover_result: Invalid Discovery Result Type!");
+ break;
+ }
+ }
+
+ return;
+}
+
+static void dis_client_read_result_cb(uint8_t conn_id, uint16_t cause,
+ uint16_t handle, uint16_t value_size, uint8_t *p_value)
+{
+ T_DIS_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = dis_table[conn_id].hdl_cache;
+
+ cb_data.cb_type = DIS_CLIENT_CB_TYPE_READ_RESULT;
+
+ APP_PRINT_INFO2("dis_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.read_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_DIS_SYSTEM_ID])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_SYSTEM_ID;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_MODEL_NUMBER])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_MODEL_NUMBER;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_SERIAL_NUMBER])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_SERIAL_NUMBER;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_FIRMWARE_REVISION])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_FIRMWARE_REVISION;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_HARDWARE_REVISION])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_HARDWARE_REVISION;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_SOFTWARE_REVISION])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_SOFTWARE_REVISION;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_MANUFACTURER_NAME])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_MANUFACTURER_NAME;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_IEEE_CERTIF_DATA_LIST])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_IEEE_CERTIF_DATA_LIST;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_PNP_ID])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_PNP_ID;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else
+ {
+ return;
+ }
+ /* Inform application the read result. */
+ if (dis_client_cb)
+ {
+ (*dis_client_cb)(dis_client, conn_id, &cb_data);
+ }
+
+ return;
+}
+
+//static void dis_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type,
+// uint16_t handle, uint16_t cause,
+// uint8_t credits)
+//{
+// T_LLS_CLIENT_CB_DATA cb_data;
+// uint16_t *hdl_cache;
+// hdl_cache = dis_table[conn_id].hdl_cache;
+// cb_data.cb_type = DIS_CLIENT_CB_TYPE_WRITE_RESULT;
+
+// PROFILE_PRINT_INFO2("dis_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+// cb_data.cb_content.write_result.cause = cause;
+
+// if (handle == hdl_cache[HDL_DIS_PARA])
+// {
+// cb_data.cb_content.write_result.type = DIS_WRITE_PARA;
+// }
+// else
+// {
+// return;
+// }
+// /* Inform application the write result. */
+// if (dis_client_cb)
+// {
+// (*dis_client_cb)(lls_client, conn_id, &cb_data);
+// }
+
+// return;
+//}
+
+//static T_APP_RESULT lls_client_notif_ind_result_cb(uint8_t conn_id, bool notify,
+// uint16_t handle,
+// uint16_t value_size, uint8_t *p_value)
+//{
+// T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+// T_KNS_CLIENT_CB_DATA cb_data;
+// uint16_t *hdl_cache;
+// hdl_cache = kns_table[conn_id].hdl_cache;
+
+// cb_data.cb_type = KNS_CLIENT_CB_TYPE_NOTIF_IND_RESULT;
+
+// if (handle == hdl_cache[HDL_KNS_NOTIFY_KEY])
+// {
+// cb_data.cb_content.notif_ind_data.type = KNS_KEY_NOTIFY;
+// cb_data.cb_content.notif_ind_data.data.value_size = value_size;
+// cb_data.cb_content.notif_ind_data.data.p_value = p_value;
+// }
+// else
+// {
+// return app_result;
+// }
+// /* Inform application the notif/ind result. */
+// if (kns_client_cb)
+// {
+// app_result = (*kns_client_cb)(kns_client, conn_id, &cb_data);
+// }
+
+// return app_result;
+//}
+
+static void dis_client_disconnect_cb(uint8_t conn_id)
+{
+ APP_PRINT_INFO0("dis_client_disconnect_cb.");
+ if (conn_id >= dis_link_num)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_disconnect_cb: failed invalid conn_id %d", conn_id);
+ return;
+ }
+ memset(&dis_table[conn_id], 0, sizeof(T_DIS_LINK));
+ return;
+}
+
+/**
+ * @brief Ias BLE Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS dis_client_cbs =
+{
+ dis_client_discover_state_cb, //!< Discovery State callback function pointer
+ dis_client_discover_result_cb, //!< Discovery result callback function pointer
+ dis_client_read_result_cb, //!< Read response callback function pointer
+ NULL,//lls_client_write_result_cb, //!< Write result callback function pointer
+ NULL,//kns_client_notif_ind_result_cb, //!< Notify Indicate callback function pointer
+ dis_client_disconnect_cb //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief Add dis service client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ dis_client_id = dis_ble_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID dis_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+{
+ uint16_t size;
+ if (link_num > DIS_MAX_LINKS)
+ {
+ PROFILE_PRINT_ERROR1("dis_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&dis_client, &dis_client_cbs))
+ {
+ dis_client = CLIENT_PROFILE_GENERAL_ID;
+ APP_PRINT_ERROR0("dis_add_client failed");
+ return dis_client;
+ }
+ APP_PRINT_INFO1("dis_add_client: dis_client %d", dis_client);
+
+ /* register callback for profile to inform application that some events happened. */
+ dis_client_cb = app_cb;
+ dis_link_num = link_num;
+ size = dis_link_num * sizeof(T_DIS_LINK);
+ dis_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ return dis_client;
+}
+
diff --git a/src/ble/profile/client/gaps_client.c b/src/ble/profile/client/gaps_client.c
new file mode 100644
index 0000000..81b6837
--- /dev/null
+++ b/src/ble/profile/client/gaps_client.c
@@ -0,0 +1,500 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gaps_client.c
+ * @brief GAPS client source file.
+ * @details
+ * @author jane
+ * @date 2016-02-18
+ * @version v0.1
+ ******************************************************************************
+ */
+
+/** Add Includes here **/
+#include <trace.h>
+#include <string.h>
+#include <gaps_client.h>
+#include <os_mem.h>
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+/**
+ * @brief GAPS Client Link control block definition.
+ */
+typedef struct
+{
+ T_GAPS_DISC_STATE disc_state;
+ uint16_t hdl_cache[HDL_GAPS_CACHE_LEN];
+} T_GAPS_LINK, *P_GAPS_LINK;
+
+/** @brief GAPS Client link table */
+static P_GAPS_LINK gaps_table;
+static uint8_t gaps_link_num;
+
+/**< GAPS client ID. */
+static T_CLIENT_ID gaps_client = CLIENT_PROFILE_GENERAL_ID;
+/**< Callback used to send data to app from GAPS client layer. */
+static P_FUN_GENERAL_APP_CB gaps_client_cb = NULL;
+
+/**
+ * @brief Used by application, to start the discovery procedure of GAP service.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_gapdis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = gaps_start_discovery(conn_id);
+ ......
+ }
+ * \endcode
+ */
+bool gaps_start_discovery(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("gaps_start_discovery");
+ /* First clear handle cache. */
+ if (conn_id >= gaps_link_num)
+ {
+ PROFILE_PRINT_ERROR1("gaps_start_discovery: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ memset(&gaps_table[conn_id], 0, sizeof(T_GAPS_LINK));
+ gaps_table[conn_id].disc_state = DISC_GAPS_START;
+ if (client_by_uuid_srv_discovery(conn_id, gaps_client,
+ GATT_UUID_GAP) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+
+/**
+ * @brief Used by application, to read data from server by using handles.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_gapread(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAPS_READ_TYPE read_type = (T_GAPS_READ_TYPE)p_parse_value->dw_param[1];
+ bool ret = gaps_read(conn_id, read_type);
+ ......
+ }
+ * \endcode
+ */
+bool gaps_read(uint8_t conn_id, T_GAPS_READ_TYPE read_type)
+{
+ bool hdl_valid = false;
+ uint16_t handle;
+ uint16_t *hdl_cache;
+ if (conn_id >= gaps_link_num)
+ {
+ PROFILE_PRINT_ERROR1("gaps_read: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ hdl_cache = gaps_table[conn_id].hdl_cache;
+
+ PROFILE_PRINT_INFO1("gaps_read: charType = %d", read_type);
+
+ switch (read_type)
+ {
+ case GAPS_READ_DEVICE_NAME:
+ if (hdl_cache[HDL_GAPS_DEVICE_NAME])
+ {
+ handle = hdl_cache[HDL_GAPS_DEVICE_NAME];
+ hdl_valid = true;
+ }
+ break;
+ case GAPS_READ_APPEARANCE:
+ if (hdl_cache[HDL_GAPS_APPEARANCE])
+ {
+ handle = hdl_cache[HDL_GAPS_APPEARANCE];
+ hdl_valid = true;
+ }
+ break;
+ case GAPS_READ_CENTRAL_ADDR_RESOLUTION:
+ if (hdl_cache[HDL_GAPS_CENTRAL_ADDR_RESOLUTION])
+ {
+ handle = hdl_cache[HDL_GAPS_CENTRAL_ADDR_RESOLUTION];
+ hdl_valid = true;
+ }
+ break;
+ default:
+ return false;
+ }
+
+ if (hdl_valid)
+ {
+ if (client_attr_read(conn_id, gaps_client, handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ PROFILE_PRINT_WARN0("gaps_read: Request fail! Please check!");
+ return false;
+}
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in,out] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_gaphdl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t hdl_cache[HDL_GAPS_CACHE_LEN];
+ uint8_t hdl_idx;
+ bool ret = gaps_get_hdl_cache(conn_id, hdl_cache, sizeof(uint16_t) * HDL_GAPS_CACHE_LEN);
+ ......
+ }
+ * \endcode
+ */
+bool gaps_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= gaps_link_num)
+ {
+ PROFILE_PRINT_ERROR1("gaps_get_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (gaps_table[conn_id].disc_state != DISC_GAPS_DONE)
+ {
+ PROFILE_PRINT_ERROR1("gaps_get_hdl_cache: failed invalid state %d", gaps_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_GAPS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("gaps_get_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(p_hdl_cache, gaps_table[conn_id].hdl_cache, len);
+ return true;
+}
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_discov_services(uint8_t conn_id, bool start)
+ {
+ ......
+ if (app_srvs_table.srv_found_flags & APP_DISCOV_GAPS_FLAG)
+ {
+ gaps_set_hdl_cache(conn_id, app_srvs_table.gaps_hdl_cache, sizeof(uint16_t) * HDL_GAPS_CACHE_LEN);
+ }
+ ......
+ }
+ * \endcode
+ */
+bool gaps_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= gaps_link_num)
+ {
+ PROFILE_PRINT_ERROR1("gaps_set_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (gaps_table[conn_id].disc_state != DISC_GAPS_IDLE)
+ {
+ PROFILE_PRINT_ERROR1("gaps_set_hdl_cache: failed invalid state %d", gaps_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_GAPS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("gaps_set_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(gaps_table[conn_id].hdl_cache, p_hdl_cache, len);
+ gaps_table[conn_id].disc_state = DISC_GAPS_DONE;
+ return true;
+}
+
+/**
+ * @brief Used by application, to check Resolvable Private Address Only Characteristics whether existing.
+ * @param[in] conn_id connection ID.
+ * @param[in,out] p_is_exist whether existing
+ * @retval true success.
+ * @retval false failed.
+ */
+bool gaps_check_resolvable_private_addr_only_char(uint8_t conn_id, bool *p_is_exist)
+{
+ if (conn_id >= gaps_link_num)
+ {
+ PROFILE_PRINT_ERROR1("gaps_get_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (gaps_table[conn_id].disc_state != DISC_GAPS_DONE)
+ {
+ PROFILE_PRINT_ERROR1("gaps_get_hdl_cache: failed invalid state %d", gaps_table[conn_id].disc_state);
+ return false;
+ }
+ if (gaps_table[conn_id].hdl_cache[HDL_GAPS_RESOLVABLE_PRIVATE_ADDR_ONLY] == 0)
+ {
+ *p_is_exist = false;
+ }
+ else
+ {
+ *p_is_exist = true;
+ }
+ return true;
+}
+
+static bool gaps_client_start_gap_char_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ PROFILE_PRINT_INFO0("gap_client_start_gap_char_discovery");
+ start_handle = gaps_table[conn_id].hdl_cache[HDL_GAPS_SRV_START];
+ end_handle = gaps_table[conn_id].hdl_cache[HDL_GAPS_SRV_END];
+ if (client_all_char_discovery(conn_id, gaps_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+static void gaps_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state)
+{
+ bool cb_flag = false;
+ T_GAPS_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = GAPS_CLIENT_CB_TYPE_DISC_STATE;
+
+ PROFILE_PRINT_INFO1("gaps_client_discover_state_cb: discovery_state %d", discovery_state);
+
+ switch (discovery_state)
+ {
+ case DISC_STATE_SRV_DONE:
+ /* Indicate that service handle found. Start discover characteristic. */
+ if ((gaps_table[conn_id].hdl_cache[HDL_GAPS_SRV_START] != 0)
+ || (gaps_table[conn_id].hdl_cache[HDL_GAPS_SRV_END] != 0))
+ {
+ if (gaps_client_start_gap_char_discovery(conn_id) == false)
+ {
+ gaps_table[conn_id].disc_state = DISC_GAPS_FAILED;
+ cb_flag = true;
+ }
+ }
+ /* No GAP service handle found. Discover procedure complete. */
+ else
+ {
+ gaps_table[conn_id].disc_state = DISC_GAPS_FAILED;
+ cb_flag = true;
+ }
+ break;
+
+ case DISC_STATE_CHAR_DONE:
+ gaps_table[conn_id].disc_state = DISC_GAPS_DONE;
+ cb_flag = true;
+ break;
+
+ case DISC_STATE_FAILED:
+ PROFILE_PRINT_ERROR0("DISC_STATE_FAILED");
+ gaps_table[conn_id].disc_state = DISC_GAPS_FAILED;
+ cb_flag = true;
+ break;
+ default:
+ PROFILE_PRINT_ERROR0("Invalid Discovery State!");
+ break;
+ }
+ /* Send discover state to application if needed. */
+ if (cb_flag && gaps_client_cb)
+ {
+ cb_data.cb_content.disc_state = gaps_table[conn_id].disc_state;
+ (*gaps_client_cb)(gaps_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+static void gaps_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ PROFILE_PRINT_INFO1("gap_client_discover_result_cb: result_type = %d", result_type);
+ uint16_t handle;
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ gaps_table[conn_id].hdl_cache[HDL_GAPS_SRV_START] =
+ result_data.p_srv_disc_data->att_handle;
+ gaps_table[conn_id].hdl_cache[HDL_GAPS_SRV_END] =
+ result_data.p_srv_disc_data->end_group_handle;
+ break;
+
+ case DISC_RESULT_CHAR_UUID16:
+ handle = result_data.p_char_uuid16_disc_data->value_handle;
+ /* we should inform intrested handles to upper application. */
+ switch (result_data.p_char_uuid16_disc_data->uuid16)
+ {
+ case GATT_UUID_CHAR_DEVICE_NAME:
+ gaps_table[conn_id].hdl_cache[HDL_GAPS_DEVICE_NAME] = handle;
+ break;
+ case GATT_UUID_CHAR_APPEARANCE:
+ gaps_table[conn_id].hdl_cache[HDL_GAPS_APPEARANCE] = handle;
+ break;
+ case GATT_UUID_CHAR_CENTRAL_ADDRESS_RESOLUTION:
+ gaps_table[conn_id].hdl_cache[HDL_GAPS_CENTRAL_ADDR_RESOLUTION] = handle;
+ PROFILE_PRINT_INFO0("GATT_UUID_CHAR_CENTRAL_ADDRESS_RESOLUTION found");
+ break;
+ case GATT_UUID_CHAR_RESOLVABLE_PRIVATE_ADDRESS_ONLY:
+ gaps_table[conn_id].hdl_cache[HDL_GAPS_RESOLVABLE_PRIVATE_ADDR_ONLY] = handle;
+ PROFILE_PRINT_INFO0("GATT_UUID_CHAR_RESOLVABLE_PRIVATE_ADDRESS_ONLY found");
+ break;
+ default:
+ /* have no interest on this handle. */
+ break;
+ }
+ break;
+
+ default:
+ PROFILE_PRINT_ERROR0("Invalid Discovery Result Type!");
+ break;
+ }
+
+ return;
+}
+
+static void gaps_client_read_result_cb(uint8_t conn_id, uint16_t cause,
+ uint16_t handle, uint16_t value_size, uint8_t *p_value)
+{
+ T_GAPS_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = gaps_table[conn_id].hdl_cache;
+ cb_data.cb_type = GAPS_CLIENT_CB_TYPE_READ_RESULT;
+ cb_data.cb_content.read_result.cause = cause;
+
+ PROFILE_PRINT_INFO2("gap_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+
+ if (handle == hdl_cache[HDL_GAPS_APPEARANCE])
+ {
+ cb_data.cb_content.read_result.type = GAPS_READ_APPEARANCE;
+ if (cause == GAP_SUCCESS)
+ {
+ uint16_t appearance;
+ if (value_size != 2)
+ {
+ PROFILE_PRINT_ERROR1("gaps_client_read_result_cb: invalid cccd len %d", value_size);
+ return;
+ }
+ LE_ARRAY_TO_UINT16(appearance, p_value);
+ cb_data.cb_content.read_result.data.appearance = appearance;
+ }
+ }
+ else if (handle == hdl_cache[HDL_GAPS_DEVICE_NAME])
+ {
+ cb_data.cb_content.read_result.type = GAPS_READ_DEVICE_NAME;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.device_name.value_size = value_size;
+ cb_data.cb_content.read_result.data.device_name.p_value = p_value;
+ }
+ }
+ else if (handle == hdl_cache[HDL_GAPS_CENTRAL_ADDR_RESOLUTION])
+ {
+ cb_data.cb_content.read_result.type = GAPS_READ_CENTRAL_ADDR_RESOLUTION;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.central_addr_res = *p_value;
+ }
+ }
+ else
+ {
+ return;
+ }
+
+ /* Inform application the read result. */
+ if (gaps_client_cb)
+ {
+ (*gaps_client_cb)(gaps_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+
+static void gaps_client_disc_cb(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("gap_client_disc_cb.");
+ if (conn_id >= gaps_link_num)
+ {
+ PROFILE_PRINT_ERROR1("gaps_client_disc_cb: failed invalid conn_id %d", conn_id);
+ return;
+ }
+ memset(&gaps_table[conn_id], 0, sizeof(T_GAPS_LINK));
+ return;
+}
+/**
+ * @brief GAPS Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS gaps_client_cbs =
+{
+ gaps_client_discover_state_cb, //!< Discovery State callback function pointer
+ gaps_client_discover_result_cb, //!< Discovery result callback function pointer
+ gaps_client_read_result_cb, //!< Read response callback function pointer
+ NULL, //!< Write result callback function pointer
+ NULL, //!< Notify Indicate callback function pointer
+ gaps_client_disc_cb //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief Add gap service client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ gaps_client_id = gaps_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID gaps_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+{
+ uint16_t size;
+ if (link_num > GAPS_MAX_LINKS)
+ {
+ PROFILE_PRINT_ERROR1("gaps_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&gaps_client, &gaps_client_cbs))
+ {
+ gaps_client = CLIENT_PROFILE_GENERAL_ID;
+ PROFILE_PRINT_ERROR0("gaps_add_client Fail !!!");
+ return gaps_client;
+ }
+ PROFILE_PRINT_INFO1("gaps_add_client: client ID = %d", gaps_client);
+
+ /* register callback for profile to inform application that some events happened. */
+ gaps_client_cb = app_cb;
+ gaps_link_num = link_num;
+ size = gaps_link_num * sizeof(T_GAPS_LINK);
+ gaps_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ return gaps_client;
+}
+
diff --git a/src/ble/profile/client/gatts_client.c b/src/ble/profile/client/gatts_client.c
new file mode 100644
index 0000000..16ed418
--- /dev/null
+++ b/src/ble/profile/client/gatts_client.c
@@ -0,0 +1,479 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gatts_client.c
+ * @brief GATTS client source file.
+ * @details
+ * @author
+ * @date 2019-05-27
+ * @version v0.1
+ ******************************************************************************
+ */
+
+/** Add Includes here **/
+#include <trace.h>
+#include <string.h>
+#include <gatts_client.h>
+#include <os_mem.h>
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+/**
+ * @brief GATTS Client Link control block definition.
+ */
+typedef struct
+{
+ T_GATTS_DISC_STATE disc_state;
+ bool write_ind_value;
+ uint16_t hdl_cache[HDL_GATTS_CACHE_LEN];
+} T_GATTS_LINK, *P_GATTS_LINK;
+
+/** @brief GATTS Client link table */
+static P_GATTS_LINK gatts_table;
+static uint8_t gatts_link_num;
+
+/**< GATTS client ID. */
+static T_CLIENT_ID gatts_client = CLIENT_PROFILE_GENERAL_ID;
+/**< Callback used to send data to app from GATTS client layer. */
+static P_FUN_GENERAL_APP_CB gatts_client_cb = NULL;
+
+/**
+ * @brief Used by application, to start the discovery procedure of GATT service.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_gattsdis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = gatts_start_discovery(conn_id);
+ ......
+ }
+ * \endcode
+ */
+bool gatts_start_discovery(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("gatts_start_discovery");
+ /* First clear handle cache. */
+ if (conn_id >= gatts_link_num)
+ {
+ PROFILE_PRINT_ERROR1("gatts_start_discovery: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ memset(&gatts_table[conn_id], 0, sizeof(T_GATTS_LINK));
+ gatts_table[conn_id].disc_state = DISC_GATTS_START;
+ if (client_by_uuid_srv_discovery(conn_id, gatts_client,
+ GATT_UUID_GATT) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Used by application, to enable or disable the indication of peer server's Service Changed Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] ind 0--disable the indication, 1--enable the indication.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool gatts_client_set_service_changed_ind(uint8_t conn_id, bool ind)
+{
+ if (conn_id >= gatts_link_num)
+ {
+ PROFILE_PRINT_ERROR1("gatts_client_set_service_changed_ind: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ if (gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED_CCCD])
+ {
+ uint16_t handle = gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED_CCCD];
+ uint16_t length = sizeof(uint16_t);
+ uint16_t cccd_bits = ind ? 2 : 0;
+ if (client_attr_write(conn_id, gatts_client, GATT_WRITE_TYPE_REQ, handle,
+ length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+ {
+ gatts_table[conn_id].write_ind_value = ind;
+ return true;
+ }
+ }
+
+ APP_PRINT_WARN0("gatts_client_set_service_changed_ind: Request fail! Please check!");
+ return false;
+}
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in,out] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_gattshdl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t hdl_cache[HDL_GATTS_CACHE_LEN];
+ uint8_t hdl_idx;
+ bool ret = gatts_get_hdl_cache(conn_id, hdl_cache, sizeof(uint16_t) * HDL_GATTS_CACHE_LEN);
+ ......
+ }
+ * \endcode
+ */
+bool gatts_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= gatts_link_num)
+ {
+ PROFILE_PRINT_ERROR1("gatts_get_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (gatts_table[conn_id].disc_state != DISC_GATTS_DONE)
+ {
+ PROFILE_PRINT_ERROR1("gatts_get_hdl_cache: failed invalid state %d",
+ gatts_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_GATTS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("gatts_get_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(p_hdl_cache, gatts_table[conn_id].hdl_cache, len);
+ return true;
+}
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_discov_services(uint8_t conn_id, bool start)
+ {
+ ......
+ if (app_srvs_table.srv_found_flags & APP_DISCOV_GATTS_FLAG)
+ {
+ gatts_set_hdl_cache(conn_id, app_srvs_table.gatts_hdl_cache, sizeof(uint16_t) * HDL_GATTS_CACHE_LEN);
+ }
+ ......
+ }
+ * \endcode
+ */
+bool gatts_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= gatts_link_num)
+ {
+ PROFILE_PRINT_ERROR1("gatts_set_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (gatts_table[conn_id].disc_state != DISC_GATTS_IDLE)
+ {
+ PROFILE_PRINT_ERROR1("gatts_set_hdl_cache: failed invalid state %d",
+ gatts_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_GATTS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("gatts_set_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(gatts_table[conn_id].hdl_cache, p_hdl_cache, len);
+ gatts_table[conn_id].disc_state = DISC_GATTS_DONE;
+ return true;
+}
+
+static bool gatts_client_start_char_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ PROFILE_PRINT_INFO0("gatts_client_start_gap_char_discovery");
+ start_handle = gatts_table[conn_id].hdl_cache[HDL_GATTS_SRV_START];
+ end_handle = gatts_table[conn_id].hdl_cache[HDL_GATTS_SRV_END];
+ if (client_all_char_discovery(conn_id, gatts_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+static bool gatts_client_start_char_descriptor_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ PROFILE_PRINT_INFO0("gatts_client_start_char_descriptor_discovery");
+ start_handle = gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED];
+ end_handle = gatts_table[conn_id].hdl_cache[HDL_GATTS_SRV_END];
+ if (client_all_char_descriptor_discovery(conn_id, gatts_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+static void gatts_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state)
+{
+ bool cb_flag = false;
+ T_GATTS_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = GATTS_CLIENT_CB_TYPE_DISC_STATE;
+
+ PROFILE_PRINT_INFO1("gatts_client_discover_state_cb: discovery_state %d", discovery_state);
+
+ switch (discovery_state)
+ {
+ case DISC_STATE_SRV_DONE:
+ /* Indicate that service handle found. Start discover characteristic. */
+ if ((gatts_table[conn_id].hdl_cache[HDL_GATTS_SRV_START] != 0)
+ || (gatts_table[conn_id].hdl_cache[HDL_GATTS_SRV_END] != 0))
+ {
+ if (gatts_client_start_char_discovery(conn_id) == false)
+ {
+ gatts_table[conn_id].disc_state = DISC_GATTS_FAILED;
+ cb_flag = true;
+ }
+ }
+ /* No GATT service handle found. Discover procedure complete. */
+ else
+ {
+ gatts_table[conn_id].disc_state = DISC_GATTS_FAILED;
+ cb_flag = true;
+ }
+ break;
+
+ case DISC_STATE_CHAR_DONE:
+ if (gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED] != 0)
+ {
+ if (gatts_client_start_char_descriptor_discovery(conn_id) == false)
+ {
+ gatts_table[conn_id].disc_state = DISC_GATTS_FAILED;
+ cb_flag = true;
+ }
+ }
+ else
+ {
+ gatts_table[conn_id].disc_state = DISC_GATTS_FAILED;
+ cb_flag = true;
+ }
+ break;
+
+ case DISC_STATE_CHAR_DESCRIPTOR_DONE:
+ gatts_table[conn_id].disc_state = DISC_GATTS_DONE;
+ cb_flag = true;
+ break;
+
+ case DISC_STATE_FAILED:
+ PROFILE_PRINT_ERROR0("DISC_STATE_FAILED");
+ gatts_table[conn_id].disc_state = DISC_GATTS_FAILED;
+ cb_flag = true;
+ break;
+ default:
+ PROFILE_PRINT_ERROR0("Invalid Discovery State!");
+ break;
+ }
+ /* Send discover state to application if needed. */
+ if (cb_flag && gatts_client_cb)
+ {
+ cb_data.cb_content.disc_state = gatts_table[conn_id].disc_state;
+ (*gatts_client_cb)(gatts_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+static void gatts_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ PROFILE_PRINT_INFO1("gatts_client_discover_result_cb: result_type = %d", result_type);
+ if (gatts_table[conn_id].disc_state == DISC_GATTS_START)
+ {
+ uint16_t handle;
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ gatts_table[conn_id].hdl_cache[HDL_GATTS_SRV_START] =
+ result_data.p_srv_disc_data->att_handle;
+ gatts_table[conn_id].hdl_cache[HDL_GATTS_SRV_END] =
+ result_data.p_srv_disc_data->end_group_handle;
+ break;
+
+ case DISC_RESULT_CHAR_UUID16:
+ handle = result_data.p_char_uuid16_disc_data->value_handle;
+ /* we should inform intrested handles to upper application. */
+ switch (result_data.p_char_uuid16_disc_data->uuid16)
+ {
+ case GATT_UUID_CHAR_SERVICE_CHANGED:
+ gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED] = handle;
+ break;
+
+ default:
+ /* have no interest on this handle. */
+ break;
+ }
+ break;
+
+ case DISC_RESULT_CHAR_DESC_UUID16:
+ if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG)
+ {
+ handle = result_data.p_char_desc_uuid16_disc_data->handle;
+ if ((handle > gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED])
+ && (gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED_CCCD] == 0))
+ {
+ gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED_CCCD] = handle;
+ }
+ }
+ break;
+
+
+ default:
+ PROFILE_PRINT_ERROR0("Invalid Discovery Result Type!");
+ break;
+ }
+ }
+ return;
+}
+
+static void gatts_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type,
+ uint16_t handle, uint16_t cause,
+ uint8_t credits)
+{
+ T_GATTS_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = gatts_table[conn_id].hdl_cache;
+ cb_data.cb_type = GATTS_CLIENT_CB_TYPE_WRITE_RESULT;
+
+ PROFILE_PRINT_INFO2("gatts_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.write_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_GATTS_SERVICE_CHANGED_CCCD])
+ {
+ if (gatts_table[conn_id].write_ind_value)
+ {
+ cb_data.cb_content.write_result.type = GATTS_WRITE_SERVICE_CHANGED_IND_ENABLE;
+ }
+ else
+ {
+ cb_data.cb_content.write_result.type = GATTS_WRITE_SERVICE_CHANGED_IND_DISABLE;
+ }
+ }
+ else
+ {
+ return;
+ }
+ /* Inform application the write result. */
+ if (gatts_client_cb)
+ {
+ (*gatts_client_cb)(gatts_client, conn_id, &cb_data);
+ }
+
+ return;
+}
+
+static T_APP_RESULT gatts_client_notif_ind_result_cb(uint8_t conn_id, bool notify,
+ uint16_t handle,
+ uint16_t value_size, uint8_t *p_value)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ T_GATTS_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = gatts_table[conn_id].hdl_cache;
+
+ cb_data.cb_type = GATTS_CLIENT_CB_TYPE_NOTIF_IND_RESULT;
+
+ if (handle == hdl_cache[HDL_GATTS_SERVICE_CHANGED])
+ {
+ cb_data.cb_content.notif_ind_data.type = GATTS_SERVICE_CHANGED_INDICATE;
+ cb_data.cb_content.notif_ind_data.data.value_size = value_size;
+ cb_data.cb_content.notif_ind_data.data.p_value = p_value;
+ }
+ else
+ {
+ return app_result;
+ }
+ /* Inform application the notif/ind result. */
+ if (gatts_client_cb)
+ {
+ app_result = (*gatts_client_cb)(gatts_client, conn_id, &cb_data);
+ }
+
+ return app_result;
+}
+
+static void gatts_client_disc_cb(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("gatts_client_disc_cb.");
+ if (conn_id >= gatts_link_num)
+ {
+ PROFILE_PRINT_ERROR1("gatts_client_disc_cb: failed invalid conn_id %d", conn_id);
+ return;
+ }
+ memset(&gatts_table[conn_id], 0, sizeof(T_GATTS_LINK));
+ return;
+}
+/**
+ * @brief GATTS Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS gatts_client_cbs =
+{
+ gatts_client_discover_state_cb, //!< Discovery State callback function pointer
+ gatts_client_discover_result_cb, //!< Discovery result callback function pointer
+ NULL, //!< Read response callback function pointer
+ gatts_client_write_result_cb, //!< Write result callback function pointer
+ gatts_client_notif_ind_result_cb, //!< Notify Indicate callback function pointer
+ gatts_client_disc_cb //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief Add gatt service client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ gatts_client_id = gatts_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID gatts_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+{
+ uint16_t size;
+ if (link_num > GATTS_MAX_LINKS)
+ {
+ PROFILE_PRINT_ERROR1("gatts_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&gatts_client, &gatts_client_cbs))
+ {
+ gatts_client = CLIENT_PROFILE_GENERAL_ID;
+ PROFILE_PRINT_ERROR0("gatts_add_client Fail !!!");
+ return gatts_client;
+ }
+ PROFILE_PRINT_INFO1("gatts_add_client: client ID = %d", gatts_client);
+
+ /* register callback for profile to inform application that some events happened. */
+ gatts_client_cb = app_cb;
+ gatts_link_num = link_num;
+ size = gatts_link_num * sizeof(T_GATTS_LINK);
+ gatts_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ return gatts_client;
+}
+
diff --git a/src/ble/profile/client/gcs_client.c b/src/ble/profile/client/gcs_client.c
new file mode 100644
index 0000000..5603d2d
--- /dev/null
+++ b/src/ble/profile/client/gcs_client.c
@@ -0,0 +1,417 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file gcs_client.c
+ * @brief General Common Services client source file.
+ * @details
+ * @author jane
+ * @date 2018-12-13
+ * @version v0.1
+ ******************************************************************************
+ */
+
+/** Add Includes here **/
+#include <trace.h>
+#include <string.h>
+#include <gcs_client.h>
+#include <os_mem.h>
+#include <bt_types.h>
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+/**
+ * @brief GCS Client Link control block definition.
+ */
+typedef struct
+{
+ T_GCS_DISCOV_TYPE discov_type;
+ uint16_t result_num;
+ T_GCS_DISCOV_RESULT *p_result_table;
+} T_GCS_LINK;
+
+/** @brief GAPS Client link table */
+static T_GCS_LINK *gcs_table = NULL;
+static uint8_t gcs_link_num = 0;
+static uint16_t gcs_max_discov_table_num = 0;
+/**< GATTS client ID. */
+static T_CLIENT_ID gcs_cl_id = CLIENT_PROFILE_GENERAL_ID;
+/**< Callback used to send data to app from gcs client layer. */
+static P_FUN_GENERAL_APP_CB gcs_client_cb = NULL;
+
+T_GAP_CAUSE gcs_all_primary_srv_discovery(uint8_t conn_id)
+{
+ T_GAP_CAUSE cause;
+ cause = client_all_primary_srv_discovery(conn_id, gcs_cl_id);
+ if (cause != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR2("gcs_all_primary_srv_discovery: failed, conn_id %d, cause %d",
+ conn_id, cause);
+ }
+ else
+ {
+ gcs_table[conn_id].discov_type = GCS_ALL_PRIMARY_SRV_DISCOV;
+ }
+ return cause;
+}
+
+T_GAP_CAUSE gcs_by_uuid128_srv_discovery(uint8_t conn_id, uint8_t *p_uuid128)
+{
+ T_GAP_CAUSE cause;
+ cause = client_by_uuid128_srv_discovery(conn_id, gcs_cl_id, p_uuid128);
+ if (cause != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR3("gcs_by_uuid128_srv_discovery: failed, conn_id %d, cause %d, p_uuid128 %p",
+ conn_id, cause, p_uuid128);
+ }
+ else
+ {
+ gcs_table[conn_id].discov_type = GCS_BY_UUID128_SRV_DISCOV;
+ }
+ return cause;
+}
+
+T_GAP_CAUSE gcs_by_uuid_srv_discovery(uint8_t conn_id, uint16_t uuid16)
+{
+ T_GAP_CAUSE cause;
+ cause = client_by_uuid_srv_discovery(conn_id, gcs_cl_id, uuid16);
+ if (cause != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR3("gcs_by_uuid_srv_discovery: failed, conn_id %d, cause %d, uuid16 0x%x",
+ conn_id, cause, uuid16);
+ }
+ else
+ {
+ gcs_table[conn_id].discov_type = GCS_BY_UUID_SRV_DISCOV;
+ }
+ return cause;
+}
+
+T_GAP_CAUSE gcs_all_char_discovery(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle)
+{
+ T_GAP_CAUSE cause;
+ cause = client_all_char_discovery(conn_id, gcs_cl_id, start_handle, end_handle);
+ if (cause != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR4("gcs_all_char_discovery: failed, conn_id %d, cause %d, start_handle 0x%x, end_handle 0x%x",
+ conn_id, cause, start_handle, end_handle);
+ }
+ else
+ {
+ gcs_table[conn_id].discov_type = GCS_ALL_CHAR_DISCOV;
+ }
+ return cause;
+}
+
+T_GAP_CAUSE gcs_by_uuid_char_discovery(uint8_t conn_id, uint16_t start_handle,
+ uint16_t end_handle, uint16_t uuid16)
+{
+ T_GAP_CAUSE cause;
+ cause = client_by_uuid_char_discovery(conn_id, gcs_cl_id, start_handle, end_handle, uuid16);
+ if (cause != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR5("gcs_by_uuid_char_discovery: failed, conn_id %d, cause %d, start_handle 0x%x, end_handle 0x%x, uuid16 0x%x",
+ conn_id, cause, start_handle, end_handle, uuid16);
+ }
+ else
+ {
+ gcs_table[conn_id].discov_type = GCS_BY_UUID_CHAR_DISCOV;
+ }
+ return cause;
+}
+
+T_GAP_CAUSE gcs_by_uuid128_char_discovery(uint8_t conn_id, uint16_t start_handle,
+ uint16_t end_handle, uint8_t *p_uuid128)
+{
+ T_GAP_CAUSE cause;
+ cause = client_by_uuid128_char_discovery(conn_id, gcs_cl_id, start_handle, end_handle, p_uuid128);
+ if (cause != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR5("gcs_by_uuid128_char_discovery: failed, conn_id %d, cause %d, start_handle 0x%x, end_handle 0x%x, p_uuid128 %p",
+ conn_id, cause, start_handle, end_handle, p_uuid128);
+ }
+ else
+ {
+ gcs_table[conn_id].discov_type = GCS_BY_UUID128_CHAR_DISCOV;
+ }
+ return cause;
+}
+
+T_GAP_CAUSE gcs_all_char_descriptor_discovery(uint8_t conn_id, uint16_t start_handle,
+ uint16_t end_handle)
+{
+ T_GAP_CAUSE cause;
+ cause = client_all_char_descriptor_discovery(conn_id, gcs_cl_id, start_handle, end_handle);
+ if (cause != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR4("gcs_all_char_descriptor_discovery: failed, conn_id %d, cause %d, start_handle 0x%x, end_handle 0x%x",
+ conn_id, cause, start_handle, end_handle);
+ }
+ else
+ {
+ gcs_table[conn_id].discov_type = GCS_ALL_CHAR_DESC_DISCOV;
+ }
+ return cause;
+}
+
+T_GAP_CAUSE gcs_attr_read(uint8_t conn_id, uint16_t handle)
+{
+ T_GAP_CAUSE cause;
+ cause = client_attr_read(conn_id, gcs_cl_id, handle);
+ if (cause != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR3("gcs_attr_read: failed, conn_id %d, cause %d, handle 0x%x",
+ conn_id, cause, handle);
+ }
+ return cause;
+}
+
+T_GAP_CAUSE gcs_attr_read_using_uuid16(uint8_t conn_id, uint16_t start_handle,
+ uint16_t end_handle, uint16_t uuid16)
+{
+ T_GAP_CAUSE cause;
+ cause = client_attr_read_using_uuid(conn_id, gcs_cl_id, start_handle, end_handle, uuid16, NULL);
+ if (cause != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR5("gcs_attr_read_using_uuid16: failed, conn_id %d, cause %d, start_handle 0x%x, end_handle 0x%x, uuid16 0x%x",
+ conn_id, cause, start_handle, end_handle, uuid16);
+ }
+ return cause;
+}
+
+T_GAP_CAUSE gcs_attr_read_using_uuid128(uint8_t conn_id, uint16_t start_handle,
+ uint16_t end_handle, uint8_t *p_uuid128)
+{
+ T_GAP_CAUSE cause;
+ cause = client_attr_read_using_uuid(conn_id, gcs_cl_id, start_handle, end_handle, 0, p_uuid128);
+ if (cause != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR5("gcs_attr_read_using_uuid128: failed, conn_id %d, cause %d, start_handle 0x%x, end_handle 0x%x, p_uuid128 %p",
+ conn_id, cause, start_handle, end_handle, p_uuid128);
+ }
+ return cause;
+}
+
+T_GAP_CAUSE gcs_attr_ind_confirm(uint8_t conn_id)
+{
+ T_GAP_CAUSE cause;
+ cause = client_attr_ind_confirm(conn_id);
+ if (cause != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR2("gcs_attr_ind_confirm: failed, conn_id %d, cause %d",
+ conn_id, cause);
+ }
+ return cause;
+}
+
+T_GAP_CAUSE gcs_attr_write(uint8_t conn_id, T_GATT_WRITE_TYPE write_type, uint16_t handle,
+ uint16_t length, uint8_t *p_data)
+{
+ T_GAP_CAUSE cause;
+ cause = client_attr_write(conn_id, gcs_cl_id, write_type, handle, length, p_data);
+ if (cause != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR5("gcs_attr_write: failed, conn_id %d, cause %d, write_type %d, handle 0x%x, length %d",
+ conn_id, cause, write_type, handle, length);
+ }
+ return cause;
+}
+
+static bool gcs_client_add_discov_result(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ T_GCS_LINK *p_gcs_link;
+ T_GCS_DISCOV_RESULT *p_discov_result;
+ if (conn_id >= gcs_link_num)
+ {
+ APP_PRINT_ERROR1("gcs_client_add_discov_result: invalid conn_id %d", conn_id);
+ return false;
+ }
+ p_gcs_link = &gcs_table[conn_id];
+ if (p_gcs_link->result_num >= gcs_max_discov_table_num)
+ {
+ APP_PRINT_ERROR1("gcs_client_add_discov_result: failed, gcs_max_discov_table_num %d",
+ gcs_max_discov_table_num);
+ return false;
+ }
+ p_discov_result = &(p_gcs_link->p_result_table[p_gcs_link->result_num]);
+ memcpy(&(p_discov_result->result_data), result_data.p_srv_disc_data,
+ sizeof(T_GCS_DISCOV_RESULT_DATA));
+ p_discov_result->result_type = result_type;
+ p_gcs_link->result_num += 1;
+ return true;
+}
+
+static bool gcs_client_clear_discov_table(uint8_t conn_id)
+{
+ if (conn_id < gcs_link_num)
+ {
+ gcs_table[conn_id].result_num = 0;
+ return true;
+ }
+ return false;
+}
+
+static void gcs_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state)
+{
+ T_GCS_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = GCS_CLIENT_CB_TYPE_DISC_RESULT;
+ cb_data.cb_content.discov_result.discov_type = gcs_table[conn_id].discov_type;
+ APP_PRINT_INFO1("gcs discovery_state %d", discovery_state);
+ if (discovery_state == DISC_STATE_FAILED || gcs_table[conn_id].result_num == 0)
+ {
+ cb_data.cb_content.discov_result.is_success = false;
+ cb_data.cb_content.discov_result.result_num = 0;
+ cb_data.cb_content.discov_result.p_result_table = NULL;
+ }
+ else
+ {
+ cb_data.cb_content.discov_result.is_success = true;
+ cb_data.cb_content.discov_result.result_num = gcs_table[conn_id].result_num;
+ cb_data.cb_content.discov_result.p_result_table = gcs_table[conn_id].p_result_table;
+ }
+ if (gcs_client_cb)
+ {
+ (*gcs_client_cb)(gcs_cl_id, conn_id, &cb_data);
+ }
+ gcs_client_clear_discov_table(conn_id);
+ return;
+}
+
+static void gcs_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ APP_PRINT_INFO1("gcs_client_discover_result_cb: result_type = %d", result_type);
+ gcs_client_add_discov_result(conn_id, result_type, result_data);
+
+ return;
+}
+
+static void gcs_client_read_result_cb(uint8_t conn_id, uint16_t cause,
+ uint16_t handle, uint16_t value_size, uint8_t *p_value)
+{
+ T_GCS_CLIENT_CB_DATA cb_data;
+ APP_PRINT_INFO2("gcs_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+
+ cb_data.cb_type = GCS_CLIENT_CB_TYPE_READ_RESULT;
+ cb_data.cb_content.read_result.cause = cause;
+ cb_data.cb_content.read_result.handle = handle;
+ cb_data.cb_content.read_result.value_size = value_size;
+ cb_data.cb_content.read_result.p_value = p_value;
+
+ if (gcs_client_cb)
+ {
+ (*gcs_client_cb)(gcs_cl_id, conn_id, &cb_data);
+ }
+
+ return;
+}
+
+static void gcs_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type,
+ uint16_t handle, uint16_t cause,
+ uint8_t credits)
+{
+ T_GCS_CLIENT_CB_DATA cb_data;
+ APP_PRINT_INFO2("gcs_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+
+ cb_data.cb_type = GCS_CLIENT_CB_TYPE_WRITE_RESULT;
+ cb_data.cb_content.write_result.cause = cause;
+ cb_data.cb_content.write_result.handle = handle;
+ cb_data.cb_content.write_result.type = type;
+
+ if (gcs_client_cb)
+ {
+ (*gcs_client_cb)(gcs_cl_id, conn_id, &cb_data);
+ }
+ return;
+}
+
+static T_APP_RESULT gcs_client_notify_ind_cb(uint8_t conn_id, bool notify,
+ uint16_t handle,
+ uint16_t value_size, uint8_t *p_value)
+{
+ T_GCS_CLIENT_CB_DATA cb_data;
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+
+ cb_data.cb_type = GCS_CLIENT_CB_TYPE_NOTIF_IND;
+ cb_data.cb_content.notif_ind.notify = notify;
+ cb_data.cb_content.notif_ind.handle = handle;
+ cb_data.cb_content.notif_ind.value_size = value_size;
+ cb_data.cb_content.notif_ind.p_value = p_value;
+
+ if (gcs_client_cb)
+ {
+ app_result = (*gcs_client_cb)(gcs_cl_id, conn_id, &cb_data);
+ }
+ return app_result;
+}
+
+static void gcs_client_disc_cb(uint8_t conn_id)
+{
+ APP_PRINT_INFO0("gcs_client_disc_cb.");
+ if (conn_id < gcs_link_num)
+ {
+ gcs_table[conn_id].result_num = 0;
+ }
+}
+
+/**
+ * @brief GATTS Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS gcs_client_cbs =
+{
+ gcs_client_discover_state_cb, //!< Discovery State callback function pointer
+ gcs_client_discover_result_cb, //!< Discovery result callback function pointer
+ gcs_client_read_result_cb, //!< Read response callback function pointer
+ gcs_client_write_result_cb, //!< Write result callback function pointer
+ gcs_client_notify_ind_cb, //!< Notify Indicate callback function pointer
+ gcs_client_disc_cb //!< Link disconnection callback function pointer
+};
+
+T_CLIENT_ID gcs_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num,
+ uint16_t max_discov_table_size)
+{
+ uint8_t i;
+ uint16_t size;
+ if (link_num > GCS_MAX_LINKS)
+ {
+ APP_PRINT_ERROR1("gcs_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+
+ gcs_client_cb = app_cb;
+ gcs_link_num = link_num;
+ gcs_max_discov_table_num = max_discov_table_size;
+ size = gcs_link_num * sizeof(T_GCS_LINK);
+ gcs_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+ if (gcs_table == NULL)
+ {
+ APP_PRINT_ERROR0("gcs_add_client: allocate link table mem fail");
+ gcs_cl_id = 0xff;
+ return gcs_cl_id;
+ }
+ size = gcs_max_discov_table_num * sizeof(T_GCS_DISCOV_RESULT);
+ for (i = 0; i < gcs_link_num; i++)
+ {
+
+ gcs_table[i].p_result_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+ if (gcs_table[i].p_result_table == NULL)
+ {
+ APP_PRINT_ERROR0("gcs_add_client: allocate discov table mem fail");
+ gcs_cl_id = 0xff;
+ return gcs_cl_id;
+ }
+ }
+ if (false == client_register_spec_client_cb(&gcs_cl_id, &gcs_client_cbs))
+ {
+ gcs_cl_id = CLIENT_PROFILE_GENERAL_ID;
+ APP_PRINT_ERROR0("gcs_add_client: register fail");
+ return gcs_cl_id;
+ }
+
+ APP_PRINT_INFO1("gcs_add_client: client id %d", gcs_cl_id);
+ return gcs_cl_id;
+}
+
diff --git a/src/ble/profile/client/hids_client.c b/src/ble/profile/client/hids_client.c
new file mode 100644
index 0000000..460c684
--- /dev/null
+++ b/src/ble/profile/client/hids_client.c
@@ -0,0 +1,1139 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hids_client.c
+ * @brief
+ * @details
+ * @author jane
+ * @date 2016-02-18
+ * @version v1.0
+ ******************************************************************************
+ */
+
+/** Add Includes here **/
+#include <string.h>
+#include <hids_client.h>
+#include <trace.h>
+#include <os_mem.h>
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+typedef enum
+{
+ HDIS_REPORT_VALUE_HANDLE,
+ HDIS_REPORT_CCCD_HANDLE,
+ HDIS_REPORT_REF_HANDLE
+} T_HIDS_HANDLE_TYPE;
+
+/**
+ * @brief HID Host Link control block definition.
+ */
+typedef struct
+{
+ T_HIDS_CLIENT_DISC_STATE disc_state;
+ bool enable_cccd_proc;
+ uint8_t *p_report_map; //allocate mem
+ uint16_t report_map_len;
+ uint8_t report_idx;
+ uint8_t read_proc_flag;
+ uint8_t read_flags;
+ uint8_t protocol_mode;
+ uint8_t report_num;
+ HID_INFO_ATTRB hids_info;
+ uint16_t hdl_cache[HDL_HIDS_CACHE_LEN];
+ T_HIDS_CLIENT_REPORT report[HIDS_CLIENT_MAX_REPORT_NUM];
+} T_HIDS_CLIENT_LINK, *P_HIDS_CLIENT_LINK;
+
+static P_HIDS_CLIENT_LINK hids_client_table;
+static uint8_t hids_client_link_num;
+
+/**< HID client ID. */
+static T_CLIENT_ID hids_client_id = CLIENT_PROFILE_GENERAL_ID;
+/**< Callback used to send data to app from HID client layer. */
+static P_FUN_GENERAL_APP_CB hids_client_cb = NULL;
+
+
+T_HIDS_CLIENT_REPORT *hids_report_add(uint8_t conn_id, uint16_t hdl_report_value)
+{
+ T_HIDS_CLIENT_LINK *p_hids_link;
+ T_HIDS_CLIENT_REPORT *p_report = NULL;
+ PROFILE_PRINT_INFO2("[HIDS]: hids_report_add: conn_id %d, report value handle 0x%x", conn_id,
+ hdl_report_value);
+ if (conn_id >= hids_client_link_num)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_report_add: failed, invalid conn_id %d", conn_id);
+ return NULL;
+ }
+ p_hids_link = &hids_client_table[conn_id];
+ if (p_hids_link->report_num >= HIDS_CLIENT_MAX_REPORT_NUM)
+ {
+ PROFILE_PRINT_ERROR0("[HIDS]: hids_report_add: failed, exceed HIDS_CLIENT_MAX_REPORT_NUM");
+ return NULL;
+ }
+ p_report = &p_hids_link->report[p_hids_link->report_num];
+ p_report->hdl_report_value = hdl_report_value;
+ p_hids_link->report_num++;
+
+ PROFILE_PRINT_INFO1("[HIDS]: hids_report_add: report_num 0x%x", p_hids_link->report_num);
+
+ return p_report;
+}
+
+T_HIDS_CLIENT_REPORT *hids_report_find_by_handle(uint8_t conn_id, T_HIDS_HANDLE_TYPE type,
+ uint16_t handle)
+{
+ uint8_t i;
+ T_HIDS_CLIENT_LINK *p_hids_link;
+ T_HIDS_CLIENT_REPORT *p_report = NULL;
+ PROFILE_PRINT_INFO1("[HIDS]: hids_report_find_by_handle: conn_id %d", conn_id);
+ if (conn_id >= hids_client_link_num)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_report_find_by_handle: failed, invalid conn_id %d", conn_id);
+ return NULL;
+ }
+ p_hids_link = &hids_client_table[conn_id];
+
+ for (i = 0; i < p_hids_link->report_num; i++)
+ {
+ uint16_t compare_handle;
+ p_report = &p_hids_link->report[i];
+ if (type == HDIS_REPORT_VALUE_HANDLE)
+ {
+ compare_handle = p_report->hdl_report_value;
+ }
+ else if (type == HDIS_REPORT_CCCD_HANDLE)
+ {
+ compare_handle = p_report->hdl_report_cccd;
+ }
+ else
+ {
+ compare_handle = p_report->hdl_report_reference;
+ }
+ if (compare_handle == handle)
+ {
+ return p_report;
+ }
+ }
+ GAP_PRINT_ERROR0("[HIDS]: hids_report_find_by_handle: not found");
+ return NULL;
+}
+
+T_HIDS_CLIENT_REPORT *hids_report_find_by_id(uint8_t conn_id, uint8_t report_id,
+ T_HIDS_REPORT_TYPE type)
+{
+ uint8_t i;
+ T_HIDS_CLIENT_LINK *p_hids_link;
+ T_HIDS_CLIENT_REPORT *p_report = NULL;
+ PROFILE_PRINT_INFO1("[HIDS]: hids_report_find_by_id: conn_id %d", conn_id);
+ if (conn_id >= hids_client_link_num)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_report_find_by_id: failed, invalid conn_id %d", conn_id);
+ return NULL;
+ }
+ p_hids_link = &hids_client_table[conn_id];
+
+ for (i = 0; i < p_hids_link->report_num; i++)
+ {
+ p_report = &p_hids_link->report[i];
+
+ if ((p_report->report_ref.report_id == report_id)
+ && ((p_report->report_ref.report_type == type) || type == HIDS_RESERVED_REPORT))
+ {
+ return p_report;
+ }
+ }
+ GAP_PRINT_ERROR0("[HIDS]: hids_report_find_by_id: not found");
+ return NULL;
+}
+
+T_HIDS_CLIENT_REPORT *hids_report_check_desc_handle(uint8_t conn_id, uint16_t handle)
+{
+ uint8_t i;
+ T_HIDS_CLIENT_LINK *p_hids_link;
+ T_HIDS_CLIENT_REPORT *p_report = NULL;
+ PROFILE_PRINT_INFO2("[HIDS]: hids_report_check_desc_handle: conn_id %d, handle 0x%x", conn_id,
+ handle);
+ if (conn_id >= hids_client_link_num)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_report_check_desc_handle: failed, invalid conn_id %d", conn_id);
+ return NULL;
+ }
+ p_hids_link = &hids_client_table[conn_id];
+
+ for (i = 0; i < p_hids_link->report_num; i++)
+ {
+ p_report = &p_hids_link->report[i];
+ if ((handle == p_report->hdl_report_value + 1) ||
+ (handle == p_report->hdl_report_value + 2))
+ {
+ return p_report;
+ }
+ }
+ GAP_PRINT_ERROR0("[HIDS]: hids_report_check_desc_handle: not found");
+ return NULL;
+}
+
+/**
+ * @brief Used by application, to start the discovery procedure of battery service.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_hiddis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = hid_start_discovery(conn_id);
+ ......
+ }
+ * \endcode
+ */
+bool hids_start_discovery(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("[HIDS]: hids_start_discovery");
+ if (conn_id >= hids_client_link_num)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hid_start_discovery: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ /* First clear handle cache. */
+ if (hids_client_table[conn_id].p_report_map != NULL)
+ {
+ os_mem_free(hids_client_table[conn_id].p_report_map);
+ }
+ memset(&hids_client_table[conn_id], 0, sizeof(T_HIDS_CLIENT_LINK));
+ hids_client_table[conn_id].disc_state = DISC_HIDS_START;
+ if (client_by_uuid_srv_discovery(conn_id, hids_client_id,
+ GATT_UUID_HID) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+bool hids_enable_all_cccd(uint8_t conn_id)
+{
+ uint8_t i;
+ uint16_t cccd_bits = 1;
+ PROFILE_PRINT_INFO0("[HIDS]: hids_enable_all_cccd");
+ if (conn_id >= hids_client_link_num)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_enable_all_cccd: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (hids_client_table[conn_id].disc_state != DISC_HIDS_DONE ||
+ hids_client_table[conn_id].enable_cccd_proc)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_enable_all_cccd: failed invalid state %d",
+ hids_client_table[conn_id].disc_state);
+ return false;
+ }
+
+ for (i = 0; i < hids_client_table[conn_id].report_num; i++)
+ {
+ if (hids_client_table[conn_id].report[i].hdl_report_cccd != 0)
+ {
+ if (client_attr_write(conn_id, hids_client_id, GATT_WRITE_TYPE_REQ,
+ hids_client_table[conn_id].report[i].hdl_report_cccd,
+ sizeof(uint16_t), (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+ {
+ hids_client_table[conn_id].report_idx = i;
+ hids_client_table[conn_id].enable_cccd_proc = true;
+ return true;
+ }
+ else
+ {
+ PROFILE_PRINT_ERROR0("[HIDS]: hids_enable_all_cccd: call client_attr_write failed");
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool hids_write_report(uint8_t conn_id, uint8_t report_id, T_HIDS_REPORT_TYPE report_type,
+ uint16_t length, uint8_t *p_value, T_GATT_WRITE_TYPE type)
+{
+ T_HIDS_CLIENT_REPORT *p_report;
+ PROFILE_PRINT_INFO0("[HIDS]: hids_write_report");
+ if (conn_id >= hids_client_link_num)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_write_report: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ p_report = hids_report_find_by_id(conn_id, report_id, report_type);
+ if (p_report != NULL)
+ {
+
+ if (client_attr_write(conn_id, hids_client_id, type,
+ p_report->hdl_report_value,
+ length, p_value) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ else
+ {
+ PROFILE_PRINT_ERROR0("[HIDS]: hids_write_report: call client_attr_write failed");
+ return false;
+ }
+ }
+
+ return false;
+}
+
+bool hids_read_saved_data(uint8_t conn_id, T_HIDS_READ_TYPE read_type, T_HIDS_READ_VALUE *p_value)
+{
+ bool ret = true;
+ if (conn_id >= hids_client_link_num)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_read_saved_data: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ switch (read_type)
+ {
+ case HIDS_READ_PROTOCOL_MODE:
+ {
+ if (hids_client_table[conn_id].read_flags & HIDS_READ_PROTOCOL_MODE_BIT)
+ {
+ p_value->value_size = 1;
+ p_value->p_value = &hids_client_table[conn_id].protocol_mode;
+ }
+ else
+ {
+ ret = false;
+ }
+ }
+ break;
+
+ case HIDS_READ_REPORT_MAP:
+ {
+ if (hids_client_table[conn_id].read_flags & HIDS_READ_REPORT_MAP_BIT)
+ {
+ p_value->value_size = hids_client_table[conn_id].report_map_len;
+ p_value->p_value = hids_client_table[conn_id].p_report_map;
+ }
+ else
+ {
+ ret = false;
+ }
+ }
+ break;
+
+ case HIDS_READ_HID_INFO:
+ {
+ if (hids_client_table[conn_id].read_flags & HIDS_READ_HID_INFO_BIT)
+ {
+ p_value->value_size = sizeof(HID_INFO_ATTRB);
+ p_value->p_value = (uint8_t *)&hids_client_table[conn_id].hids_info;
+ }
+ else
+ {
+ ret = false;
+ }
+
+ }
+ break;
+
+ default:
+ {
+ ret = false;
+
+ }
+ break;
+ }
+
+ if (ret == false)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_read_saved_data failed: read_type %d", read_type);
+ }
+
+ return ret;
+}
+
+void hids_print_infos(uint8_t conn_id)
+{
+ int8_t i;
+ PROFILE_PRINT_INFO1("[HIDS]: hids_print_infos: conn_id %d", conn_id);
+ if (conn_id >= hids_client_link_num)
+ {
+ return;
+ }
+ for (i = 0; i < HDL_HIDS_CACHE_LEN; i++)
+ {
+ PROFILE_PRINT_INFO2("[HIDS]: hdl_cache[%d]: 0x%x", i, hids_client_table[conn_id].hdl_cache[i]);
+ }
+ for (i = 0; i < hids_client_table[conn_id].report_num; i++)
+ {
+ PROFILE_PRINT_INFO3("[HIDS]: report[%d]: report_id 0x%x, report_type 0x%x",
+ i, hids_client_table[conn_id].report[i].report_ref.report_id,
+ hids_client_table[conn_id].report[i].report_ref.report_type);
+ PROFILE_PRINT_INFO3(" hdl_report_value 0x%x, hdl_report_cccd 0x%x, hdl_report_reference 0x%x",
+ hids_client_table[conn_id].report[i].hdl_report_value,
+ hids_client_table[conn_id].report[i].hdl_report_cccd,
+ hids_client_table[conn_id].report[i].hdl_report_reference);
+ }
+ PROFILE_PRINT_INFO5("[HIDS]: read_flags 0x%x, protocol_mode 0x%x, hids_info %b, report_map[%d] %b",
+ hids_client_table[conn_id].read_flags,
+ hids_client_table[conn_id].protocol_mode,
+ TRACE_BINARY(4, &hids_client_table[conn_id].hids_info),
+ hids_client_table[conn_id].report_map_len,
+ TRACE_BINARY(hids_client_table[conn_id].report_map_len, hids_client_table[conn_id].p_report_map));
+
+}
+
+bool hids_read(uint8_t conn_id, T_HIDS_READ_TYPE read_type)
+{
+ uint16_t handle = 0;
+ PROFILE_PRINT_INFO1("[HIDS]: hids_read: type %d", read_type);
+ if (conn_id >= hids_client_link_num)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_read: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ if (read_type == HIDS_READ_PROTOCOL_MODE)
+ {
+ handle = hids_client_table[conn_id].hdl_cache[HDL_HIDS_CHAR_PROTOCOL_MODE];
+ }
+ else if (read_type == HIDS_READ_REPORT_MAP)
+ {
+ handle = hids_client_table[conn_id].hdl_cache[HDL_HIDS_CHAR_REPORT_MAP];
+ }
+ else if (read_type == HIDS_READ_HID_INFO)
+ {
+ handle = hids_client_table[conn_id].hdl_cache[HDL_HIDS_CHAR_HID_INFO];
+ }
+
+ if (handle)
+ {
+ if (client_attr_read(conn_id, hids_client_id, handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+ PROFILE_PRINT_ERROR0("[HIDS]: hids_read: failed");
+ return false;
+}
+
+void hids_start_read(uint8_t conn_id, uint16_t cause)
+{
+ bool cb_flag = false;
+ T_HIDS_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = HIDS_CLIENT_CB_TYPE_DISC_STATE;
+
+ PROFILE_PRINT_INFO2("[HIDS]: hids_start_read: read_proc_flag 0x%x, cause 0x%x",
+ hids_client_table[conn_id].read_proc_flag, cause);
+ if (conn_id >= hids_client_link_num)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_start_read: failed invalid conn_id %d", conn_id);
+ return;
+ }
+
+ if (hids_client_table[conn_id].report_idx == hids_client_table[conn_id].report_num)
+ {
+ hids_client_table[conn_id].read_proc_flag &= ~HIDS_READ_REPORT_REF_BIT;
+ hids_client_table[conn_id].report_idx = 0;
+ }
+
+ if ((cause == GAP_SUCCESS) && (hids_client_table[conn_id].read_proc_flag != 0))
+ {
+ do
+ {
+ if (hids_client_table[conn_id].read_proc_flag & HIDS_READ_PROTOCOL_MODE_BIT)
+ {
+ hids_client_table[conn_id].read_proc_flag &= ~HIDS_READ_PROTOCOL_MODE_BIT;
+ if (hids_read(conn_id, HIDS_READ_PROTOCOL_MODE))
+ {
+ break;
+ }
+ }
+ if (hids_client_table[conn_id].read_proc_flag & HIDS_READ_HID_INFO_BIT)
+ {
+ hids_client_table[conn_id].read_proc_flag &= ~HIDS_READ_HID_INFO_BIT;
+ if (hids_read(conn_id, HIDS_READ_HID_INFO) == false)
+ {
+ cb_flag = true;
+ hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED;
+ }
+ break;
+ }
+
+ if (hids_client_table[conn_id].read_proc_flag & HIDS_READ_REPORT_MAP_BIT)
+ {
+ hids_client_table[conn_id].read_proc_flag &= ~HIDS_READ_REPORT_MAP_BIT;
+ if (hids_read(conn_id, HIDS_READ_REPORT_MAP) == false)
+ {
+ cb_flag = true;
+ hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED;
+ }
+ break;
+ }
+ if (hids_client_table[conn_id].read_proc_flag & HIDS_READ_REPORT_REF_BIT)
+ {
+ uint16_t handle =
+ hids_client_table[conn_id].report[hids_client_table[conn_id].report_idx].hdl_report_reference;
+ if (handle)
+ {
+ if (client_attr_read(conn_id, hids_client_id, handle) == GAP_CAUSE_SUCCESS)
+ {
+ break;
+ }
+ }
+ cb_flag = true;
+ hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED;
+ }
+ }
+ while (0);
+ }
+ else
+ {
+ if (cause == GAP_SUCCESS)
+ {
+ cb_flag = true;
+ hids_client_table[conn_id].disc_state = DISC_HIDS_DONE;
+ }
+ else
+ {
+ cb_flag = true;
+ hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED;
+ }
+ }
+
+ /* Send discover state to application if needed. */
+ if (cb_flag && hids_client_cb)
+ {
+ cb_data.cb_content.disc_state = hids_client_table[conn_id].disc_state;
+ (*hids_client_cb)(hids_client_id, conn_id, &cb_data);
+ }
+}
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in,out] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_hidhdl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_HIDS_CLIENT_STORAGE_INFO hids_client_info;
+ bool ret = hids_get_hdl_cache(conn_id, (&hids_client_info));
+ ......
+ }
+ * \endcode
+ */
+bool hids_get_hdl_cache(uint8_t conn_id, T_HIDS_CLIENT_STORAGE_INFO *p_storage_info)
+{
+ if (conn_id >= hids_client_link_num)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_get_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (hids_client_table[conn_id].disc_state != DISC_HIDS_DONE)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_get_hdl_cache: failed invalid state %d",
+ hids_client_table[conn_id].disc_state);
+ return false;
+ }
+
+ memcpy(p_storage_info, (&(hids_client_table[conn_id].read_flags)),
+ sizeof(T_HIDS_CLIENT_STORAGE_INFO));
+ p_storage_info->read_flags &= ~HIDS_READ_REPORT_MAP_BIT;
+ return true;
+}
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_discov_services(uint8_t conn_id, bool start)
+ {
+ ......
+ if (app_srvs_table.srv_found_flags & APP_DISCOV_HID_FLAG)
+ {
+ hids_set_hdl_cache(conn_id, (&(app_srvs_table.hids_client_info)));
+ }
+ if (!(app_srvs_table.hids_client_info.read_flags & HIDS_READ_REPORT_MAP_BIT))
+ {
+ APP_PRINT_INFO0("app_discov_services: read report map");
+ hids_read_report_map(conn_id);
+ }
+ ......
+ }
+ * \endcode
+ */
+bool hids_set_hdl_cache(uint8_t conn_id, T_HIDS_CLIENT_STORAGE_INFO *p_storage_info)
+{
+ if (conn_id >= hids_client_link_num)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_set_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (hids_client_table[conn_id].disc_state != DISC_HIDS_IDLE)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_set_hdl_cache: failed invalid state %d",
+ hids_client_table[conn_id].disc_state);
+ return false;
+ }
+
+ memcpy((&(hids_client_table[conn_id].read_flags)), p_storage_info,
+ sizeof(T_HIDS_CLIENT_STORAGE_INFO));
+ hids_client_table[conn_id].disc_state = DISC_HIDS_DONE;
+ return true;
+}
+
+bool hids_read_report_map(uint8_t conn_id)
+{
+ if (conn_id >= hids_client_link_num)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_read_report_map: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (hids_client_table[conn_id].disc_state != DISC_HIDS_DONE)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_read_report_map: failed invalid state %d",
+ hids_client_table[conn_id].disc_state);
+ return false;
+ }
+ return hids_read(conn_id, HIDS_READ_REPORT_MAP);
+}
+
+bool hids_handle_report_map(uint8_t conn_id, uint16_t value_size, uint8_t *p_value)
+{
+ if (hids_client_table[conn_id].p_report_map != NULL)
+ {
+ os_mem_free(hids_client_table[conn_id].p_report_map);
+ }
+
+ hids_client_table[conn_id].p_report_map = os_mem_zalloc(RAM_TYPE_DATA_ON, value_size);
+ if (hids_client_table[conn_id].p_report_map != NULL)
+ {
+ memcpy(hids_client_table[conn_id].p_report_map, p_value, value_size);
+ hids_client_table[conn_id].report_map_len = value_size;
+ hids_client_table[conn_id].read_flags |= HIDS_READ_REPORT_MAP_BIT;
+ PROFILE_PRINT_INFO0("[HIDS]: hids_handle_report_map: handle report map success");
+ return true;
+ }
+ else
+ {
+ PROFILE_PRINT_ERROR0("[HIDS]: hids_handle_report_map: handle report map failed, allocate memory failed");
+ return false;
+ }
+}
+
+bool hids_set_report_map(uint8_t conn_id, uint16_t value_size, uint8_t *p_value)
+{
+ if (conn_id >= hids_client_link_num)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_set_report_map: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (hids_client_table[conn_id].disc_state != DISC_HIDS_DONE)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_set_report_map: failed invalid state %d",
+ hids_client_table[conn_id].disc_state);
+ return false;
+ }
+
+ if (value_size != 0)
+ {
+ if (hids_handle_report_map(conn_id, value_size, p_value))
+ {
+ PROFILE_PRINT_INFO0("[HIDS]: hids_set_report_map: configuration of report map success");
+ return true;
+ }
+ else
+ {
+ PROFILE_PRINT_ERROR0("[HIDS]: hids_set_report_map: configuration of report map failed");
+ return false;
+ }
+ }
+ else
+ {
+ PROFILE_PRINT_ERROR0("[HIDS]: hids_set_report_map: configuration of report map failed, invalid size");
+ return false;
+ }
+}
+
+static bool hids_client_start_char_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ PROFILE_PRINT_INFO0("[HIDS]: hids_client_start_char_discovery");
+ start_handle = hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_START];
+ end_handle = hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_END];
+ if (client_all_char_discovery(conn_id, hids_client_id, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+static bool hids_client_start_char_descriptor_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ PROFILE_PRINT_INFO0("[HIDS]: hids_client_start_char_descriptor_discovery");
+ start_handle = hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_START];
+ end_handle = hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_END];
+ if (client_all_char_descriptor_discovery(conn_id, hids_client_id, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+static void hids_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state)
+{
+ bool cb_flag = false;
+ T_HIDS_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = HIDS_CLIENT_CB_TYPE_DISC_STATE;
+
+ PROFILE_PRINT_INFO1("[HIDS]: hids_client_discover_state_cb: discovery_state = %d", discovery_state);
+ if (hids_client_table[conn_id].disc_state == DISC_HIDS_START)
+ {
+ switch (discovery_state)
+ {
+ case DISC_STATE_SRV_DONE:
+ /* Indicate that service handle found. Start discover characteristic. */
+ if ((hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_START] != 0)
+ || (hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_END] != 0))
+ {
+ if (hids_client_start_char_discovery(conn_id) == false)
+ {
+ hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED;
+ cb_flag = true;
+ }
+ }
+ /* No HID handle found. Discover procedure complete. */
+ else
+ {
+ hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED;
+ cb_flag = true;
+ }
+ break;
+ case DISC_STATE_CHAR_DONE:
+ if (hids_client_table[conn_id].hdl_cache[HDL_HIDS_CHAR_REPORT_MAP] != 0)
+ {
+ //discovery cccd
+ if (hids_client_start_char_descriptor_discovery(conn_id) == false)
+ {
+ hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED;
+ cb_flag = true;
+ }
+ }
+ else
+ {
+ hids_client_table[conn_id].disc_state = DISC_HIDS_DONE;
+ cb_flag = true;
+ }
+ break;
+
+ case DISC_STATE_CHAR_DESCRIPTOR_DONE:
+ hids_client_table[conn_id].read_proc_flag = HIDS_READ_HID_INFO_BIT | HIDS_READ_PROTOCOL_MODE_BIT |
+ HIDS_READ_REPORT_MAP_BIT | HIDS_READ_REPORT_REF_BIT;
+ hids_start_read(conn_id, GAP_SUCCESS);
+ break;
+
+ case DISC_STATE_FAILED:
+ hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED;
+ cb_flag = true;
+ break;
+
+ default:
+ PROFILE_PRINT_ERROR0("Invalid Discovery State!");
+ break;
+ }
+ }
+
+ /* Send discover state to application if needed. */
+ if (cb_flag && hids_client_cb)
+ {
+ cb_data.cb_content.disc_state = hids_client_table[conn_id].disc_state;
+ (*hids_client_cb)(hids_client_id, conn_id, &cb_data);
+ }
+ return;
+}
+
+
+static void hids_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ PROFILE_PRINT_INFO1("[HIDS]: hids_client_discover_result_cb: result_type = %d", result_type);
+ if (hids_client_table[conn_id].disc_state == DISC_HIDS_START)
+ {
+ uint16_t handle;
+ uint16_t *hdl_cache;
+ hdl_cache = hids_client_table[conn_id].hdl_cache;
+
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_START] =
+ result_data.p_srv_disc_data->att_handle;
+ hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_END] =
+ result_data.p_srv_disc_data->end_group_handle;
+ break;
+
+ case DISC_RESULT_CHAR_UUID16:
+ {
+ handle = result_data.p_char_uuid16_disc_data->value_handle;
+ switch (result_data.p_char_uuid16_disc_data->uuid16)
+ {
+ case GATT_UUID_CHAR_HID_INFO:
+ hdl_cache[HDL_HIDS_CHAR_HID_INFO] = handle;
+ break;
+
+ case GATT_UUID_CHAR_REPORT_MAP:
+ hdl_cache[HDL_HIDS_CHAR_REPORT_MAP] = handle;
+ break;
+
+ case GATT_UUID_CHAR_HID_CONTROL_POINT:
+ hdl_cache[HDL_HIDS_CHAR_HID_CONTROL_POINT] = handle;
+ break;
+
+ case GATT_UUID_CHAR_PROTOCOL_MODE:
+ hdl_cache[HDL_HIDS_CHAR_PROTOCOL_MODE] = handle;
+ break;
+
+ case GATT_UUID_CHAR_REPORT:
+ {
+ hids_report_add(conn_id, handle);
+ }
+ break;
+
+ default:
+ /* have no interest on this handle. */
+ break;
+ }
+ }
+ break;
+
+ case DISC_RESULT_CHAR_DESC_UUID16:
+ handle = result_data.p_char_desc_uuid16_disc_data->handle;
+ if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG)
+ {
+ T_HIDS_CLIENT_REPORT *p_report = hids_report_check_desc_handle(conn_id, handle);
+ if (p_report != NULL)
+ {
+ p_report->hdl_report_cccd = handle;
+ PROFILE_PRINT_INFO1("[HIDS]: Found report cccd handle 0x%x", handle);
+ }
+ }
+ else if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_REPORT_REFERENCE)
+ {
+ T_HIDS_CLIENT_REPORT *p_report = hids_report_check_desc_handle(conn_id, handle);
+ if (p_report != NULL)
+ {
+ p_report->hdl_report_reference = handle;
+ PROFILE_PRINT_INFO1("[HIDS]: Found report ref handle 0x%x", handle);
+
+ }
+ }
+ break;
+
+ default:
+ PROFILE_PRINT_ERROR0("[HIDS]: Invalid Discovery Result Type!");
+ break;
+ }
+ }
+
+ return;
+}
+
+static void hids_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type,
+ uint16_t handle,
+ uint16_t cause,
+ uint8_t credits)
+{
+ T_HIDS_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = HIDS_CLIENT_CB_TYPE_WRITE_RESULT;
+
+ PROFILE_PRINT_INFO2("[HIDS]: hids_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.write_result.cause = cause;
+
+ if (hids_client_table[conn_id].enable_cccd_proc)
+ {
+ if (cause == GAP_SUCCESS)
+ {
+ uint8_t i = hids_client_table[conn_id].report_idx;
+ uint16_t cccd_bits = 1;
+
+ if (handle == hids_client_table[conn_id].report[i].hdl_report_cccd)
+ {
+ i++;
+ for (; i < hids_client_table[conn_id].report_num; i++)
+ {
+ if (hids_client_table[conn_id].report[i].hdl_report_cccd != 0)
+ {
+ if (client_attr_write(conn_id, hids_client_id, GATT_WRITE_TYPE_REQ,
+ hids_client_table[conn_id].report[i].hdl_report_cccd,
+ sizeof(uint16_t), (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+ {
+ hids_client_table[conn_id].report_idx = i;
+ hids_client_table[conn_id].enable_cccd_proc = true;
+ return;
+ }
+ else
+ {
+ cb_data.cb_content.write_result.cause = GATT_ERR | GATT_ERR_INVALID_PARAM;
+ PROFILE_PRINT_ERROR0("[HIDS]: hids_enable_all_cccd: call client_attr_write failed");
+ }
+ }
+ }
+ }
+ else
+ {
+ cb_data.cb_content.write_result.cause = GATT_ERR | GATT_ERR_INVALID_PARAM;
+ PROFILE_PRINT_ERROR2("[HIDS]: hids_client_write_result_cb: invalid cccd handle 0x%x, hande 0x%x",
+ handle, hids_client_table[conn_id].report[i].hdl_report_cccd);
+ }
+ }
+ hids_client_table[conn_id].report_idx = 0;
+ hids_client_table[conn_id].enable_cccd_proc = false;
+ cb_data.cb_content.write_result.type = HIDS_WRITE_ALL_REPORT_CCCD;
+ }
+ else
+ {
+ T_HIDS_CLIENT_REPORT *p_report = hids_report_find_by_handle(conn_id, HDIS_REPORT_VALUE_HANDLE,
+ handle);
+ if (p_report != NULL)
+ {
+ cb_data.cb_content.write_result.type = HIDS_WRITE_REPORT;
+ cb_data.cb_content.write_result.report_ref = p_report->report_ref;
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ if (hids_client_cb)
+ {
+ (*hids_client_cb)(hids_client_id, conn_id, &cb_data);
+ }
+ return;
+}
+
+static void hids_client_read_result_cb(uint8_t conn_id, uint16_t cause,
+ uint16_t handle, uint16_t value_size, uint8_t *p_value)
+{
+ uint16_t *hdl_cache;
+ hdl_cache = hids_client_table[conn_id].hdl_cache;
+ if (hids_client_table[conn_id].disc_state == DISC_HIDS_START)
+ {
+ if (cause == ATT_SUCCESS)
+ {
+ if (handle == hdl_cache[HDL_HIDS_CHAR_HID_INFO])
+ {
+ if (value_size == 4)
+ {
+ memcpy(&(hids_client_table[conn_id].hids_info), p_value, value_size);
+ hids_client_table[conn_id].read_flags |= HIDS_READ_HID_INFO_BIT;
+ PROFILE_PRINT_INFO0("[HIDS]: Read hid info success");
+ }
+ else
+ {
+ cause = GATT_ERR | GATT_ERR_INVALID_PARAM;
+ PROFILE_PRINT_ERROR0("[HIDS]: Read hid info failed, invalid size");
+ }
+ }
+ else if (handle == hdl_cache[HDL_HIDS_CHAR_REPORT_MAP])
+ {
+ if (value_size != 0)
+ {
+ if (!(hids_handle_report_map(conn_id, value_size, p_value)))
+ {
+ cause = GATT_ERR | GATT_ERR_INVALID_PARAM;
+ }
+ }
+ else
+ {
+ cause = GATT_ERR | GATT_ERR_INVALID_PARAM;
+ PROFILE_PRINT_ERROR0("[HIDS]: Read report map failed, invalid size");
+ }
+ }
+ else if (handle == hdl_cache[HDL_HIDS_CHAR_PROTOCOL_MODE])
+ {
+ if (value_size == 1)
+ {
+ hids_client_table[conn_id].protocol_mode = *p_value;
+ hids_client_table[conn_id].read_flags |= HIDS_READ_PROTOCOL_MODE_BIT;
+ PROFILE_PRINT_INFO0("[HIDS]: Read protocol mode success");
+ }
+ else
+ {
+ cause = GATT_ERR | GATT_ERR_INVALID_PARAM;
+ PROFILE_PRINT_ERROR0("[HIDS]: Read protocol mode failed, invalid size");
+ }
+ }
+ else
+ {
+ T_HIDS_CLIENT_REPORT *p_report = hids_report_find_by_handle(conn_id, HDIS_REPORT_REF_HANDLE,
+ handle);
+ if (p_report != NULL && value_size == 2)
+ {
+ p_report->report_ref.report_id = *p_value;
+ p_report->report_ref.report_type = (T_HIDS_REPORT_TYPE) * (p_value + 1);
+ }
+ else
+ {
+ cause = GATT_ERR | GATT_ERR_INVALID_PARAM;
+ PROFILE_PRINT_ERROR0("[HIDS]: Read report ref, invalid size");
+ }
+ hids_client_table[conn_id].report_idx++;
+ }
+ hids_start_read(conn_id, cause);
+ }
+ else
+ {
+ hids_start_read(conn_id, cause);
+ }
+ }
+ else if (hids_client_table[conn_id].disc_state == DISC_HIDS_DONE)
+ {
+ if (handle == hdl_cache[HDL_HIDS_CHAR_REPORT_MAP])
+ {
+ T_HIDS_CLIENT_CB_DATA cb_data;
+
+ if (cause == ATT_SUCCESS)
+ {
+ if (value_size != 0)
+ {
+ if (!(hids_handle_report_map(conn_id, value_size, p_value)))
+ {
+ cause = GATT_ERR | GATT_ERR_INVALID_PARAM;
+ }
+ }
+ else
+ {
+ cause = GATT_ERR | GATT_ERR_INVALID_PARAM;
+ PROFILE_PRINT_ERROR0("[HIDS]: Read report map failed, invalid size");
+ }
+ }
+
+ cb_data.cb_type = HIDS_CLIENT_CB_TYPE_READ_RESULT;
+ cb_data.cb_content.read_result.type = HIDS_READ_RESULT_REPORT_MAP;
+ cb_data.cb_content.read_result.cause = cause;
+ (*hids_client_cb)(hids_client_id, conn_id, &cb_data);
+ }
+ }
+ return;
+}
+
+static T_APP_RESULT hids_client_notify_ind_cb(uint8_t conn_id, bool notify, uint16_t handle,
+ uint16_t value_size, uint8_t *p_value)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ T_HIDS_CLIENT_CB_DATA cb_data;
+ T_HIDS_CLIENT_REPORT *p_report;
+ cb_data.cb_type = HIDS_CLIENT_CB_TYPE_NOTIF_RESULT;
+
+ p_report = hids_report_find_by_handle(conn_id, HDIS_REPORT_VALUE_HANDLE, handle);
+ if (p_report == NULL)
+ {
+ return APP_RESULT_SUCCESS;
+ }
+ cb_data.cb_content.notify_data.type = HIDS_REPORT_NOTIFY;
+ cb_data.cb_content.notify_data.data.report_id = p_report->report_ref.report_id;
+ cb_data.cb_content.notify_data.data.value_size = value_size;
+ cb_data.cb_content.notify_data.data.p_value = p_value;
+
+ if (hids_client_cb)
+ {
+ app_result = (*hids_client_cb)(hids_client_id, conn_id, &cb_data);
+ }
+
+ return app_result;
+}
+
+static void hids_client_disc_cb(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("[HIDS]: hids_client_disc_cb.");
+ if (conn_id >= hids_client_link_num)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_client_disc_cb: failed invalid conn_id %d", conn_id);
+ return;
+ }
+ if (hids_client_table[conn_id].p_report_map != NULL)
+ {
+ os_mem_free(hids_client_table[conn_id].p_report_map);
+ }
+ memset(&hids_client_table[conn_id], 0, sizeof(T_HIDS_CLIENT_LINK));
+ return;
+}
+
+/**
+ * @brief HID Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS hids_client_cbs =
+{
+ hids_client_discover_state_cb, //!< Discovery State callback function pointer
+ hids_client_discover_result_cb, //!< Discovery result callback function pointer
+ hids_client_read_result_cb, //!< Read response callback function pointer
+ hids_client_write_result_cb, //!< Write result callback function pointer
+ hids_client_notify_ind_cb, //!< Notify Indicate callback function pointer
+ hids_client_disc_cb //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief Add hid client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ hids_client_id = hid_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID hids_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+{
+ uint16_t size;
+ if (link_num > HIDS_CLIENT_MAX_LINKS)
+ {
+ PROFILE_PRINT_ERROR1("[HIDS]: hids_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&hids_client_id, &hids_client_cbs))
+ {
+ hids_client_id = CLIENT_PROFILE_GENERAL_ID;
+ PROFILE_PRINT_ERROR0("[HIDS]: hids_add_client:register fail");
+ return hids_client_id;
+ }
+ PROFILE_PRINT_INFO1("[HIDS]: hids_add_client: client id %d", hids_client_id);
+
+ /* register callback for profile to inform application that some events happened. */
+ hids_client_cb = app_cb;
+ hids_client_link_num = link_num;
+ size = hids_client_link_num * sizeof(T_HIDS_CLIENT_LINK);
+ hids_client_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ return hids_client_id;
+}
+
diff --git a/src/ble/profile/client/ias_client.c b/src/ble/profile/client/ias_client.c
new file mode 100644
index 0000000..ee9f6b0
--- /dev/null
+++ b/src/ble/profile/client/ias_client.c
@@ -0,0 +1,533 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ias_client.c
+ * @brief Ias BLE client source file.
+ * @details
+ * @author jane
+ * @date 2016-02-18
+ * @version v1.0
+ ******************************************************************************
+ */
+
+/** Add Includes here **/
+#include <trace.h>
+#include <string.h>
+#include <ias_client.h>
+#include <os_mem.h>
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+typedef struct
+{
+ T_IAS_DISC_STATE disc_state;
+ uint16_t hdl_cache[HDL_IAS_CACHE_LEN];
+} T_IAS_LINK, *P_IAS_LINK;
+
+static P_IAS_LINK ias_table;
+static uint8_t ias_link_num;
+
+/**< ias client ID. */
+static T_CLIENT_ID ias_client = CLIENT_PROFILE_GENERAL_ID;
+/**< Callback used to send data to app from ias client layer. */
+static P_FUN_GENERAL_APP_CB ias_client_cb = NULL;
+
+/**
+ * @brief Used by application, to start the discovery procedure of ias server.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ias_client_start_discovery(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("ias_client_start_discovery");
+ if (conn_id >= ias_link_num)
+ {
+ PROFILE_PRINT_ERROR1("ias_client_start_discovery: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ /* First clear handle cache. */
+ memset(&ias_table[conn_id], 0, sizeof(T_IAS_LINK));
+ ias_table[conn_id].disc_state = DISC_IAS_START;
+ if (client_by_uuid_srv_discovery(conn_id, ias_client,
+ GATT_UUID_IMMEDIATE_ALERT_SERVICE) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Used by application, to read data from server by using handles.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool ias_client_read_by_handle(uint8_t conn_id, T_IAS_READ_TYPE read_type)//~~~~~~~~~~~~~~~~~~will delete
+//{
+// bool hdl_valid = false;
+// uint16_t handle;
+// if (conn_id >= ias_link_num)
+// {
+// PROFILE_PRINT_ERROR1("ias_client_read_by_handle: failed invalid conn_id %d", conn_id);
+// return false;
+// }
+
+// switch (read_type)
+// {
+// case IAS_READ_V1_READ:
+// if (ias_table[conn_id].hdl_cache[HDL_IAS_V1_READ])
+// {
+// handle = ias_table[conn_id].hdl_cache[HDL_IAS_V1_READ];
+// hdl_valid = true;
+// }
+// break;
+// default:
+// return false;
+// }
+
+// if (hdl_valid)
+// {
+// if (client_attr_read(conn_id, ias_client, handle) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// }
+
+// APP_PRINT_WARN0("ias_client_read_by_handle: Request fail! Please check!");
+// return false;
+//}
+
+/**
+ * @brief Used by application, to read data from server by using UUIDs.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool ias_client_read_by_uuid(uint8_t conn_id, T_IAS_READ_TYPE read_type)//~~~~~~~~~~~~~~~~~~will delete
+//{
+// uint16_t start_handle;
+// uint16_t end_handle;
+// uint16_t uuid16;
+// if (conn_id >= ias_link_num)
+// {
+// PROFILE_PRINT_ERROR1("ias_client_read_by_uuid: failed invalid conn_id %d", conn_id);
+// return false;
+// }
+
+// switch (read_type)
+// {
+// case IAS_READ_V1_READ:
+// start_handle = ias_table[conn_id].hdl_cache[HDL_IAS_SRV_START];
+// end_handle = ias_table[conn_id].hdl_cache[HDL_IAS_SRV_END];
+// uuid16 = GATT_UUID_CHAR_ALERT_LEVEL;
+// break;
+// default:
+// return false;
+// }
+
+// if (client_attr_read_using_uuid(conn_id, ias_client, start_handle, end_handle,
+// uuid16, NULL) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// return false;
+//}
+
+/**
+ * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] notify 0--disable the notification, 1--enable the notification.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool simp_ble_client_set_v3_notify(uint8_t conn_id, bool notify)
+//{
+// if (conn_id >= simp_link_num)
+// {
+// PROFILE_PRINT_ERROR1("simp_ble_client_set_v3_notify: failed invalid conn_id %d", conn_id);
+// return false;
+// }
+
+// if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD])
+// {
+// uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD];
+// uint16_t length = sizeof(uint16_t);
+// uint16_t cccd_bits = notify ? 1 : 0;
+// if (client_attr_write(conn_id, simp_client, GATT_WRITE_TYPE_REQ, handle,
+// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// }
+
+// APP_PRINT_WARN0("simp_ble_client_set_v3_notify: Request fail! Please check!");
+// return false;
+//}
+
+/**
+ * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] ind 0--disable the indication, 1--enable the indication.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool simp_ble_client_set_v4_ind(uint8_t conn_id, bool ind)
+//{
+// if (conn_id >= simp_link_num)
+// {
+// PROFILE_PRINT_ERROR1("simp_ble_client_set_v4_ind: failed invalid conn_id %d", conn_id);
+// return false;
+// }
+
+// if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD])
+// {
+// uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD];
+// uint16_t length = sizeof(uint16_t);
+// uint16_t cccd_bits = ind ? 2 : 0;
+// if (client_attr_write(conn_id, simp_client, GATT_WRITE_TYPE_REQ, handle,
+// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// }
+
+// APP_PRINT_WARN0("simp_ble_client_set_v4_ind: Request fail! Please check!");
+// return false;
+//}
+
+/**
+ * @brief Used by application, to write data of V2 write Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] length write data length
+ * @param[in] p_value point the value to write
+ * @param[in] type write type.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ias_client_write_char(uint8_t conn_id, uint16_t length, uint8_t *p_value,
+ T_GATT_WRITE_TYPE type)
+{
+ if (conn_id >= ias_link_num)
+ {
+ PROFILE_PRINT_ERROR1("ias_client_write_v2_char: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ if (ias_table[conn_id].hdl_cache[HDL_IAS_WRITE])
+ {
+ uint16_t handle = ias_table[conn_id].hdl_cache[HDL_IAS_WRITE];
+ if (client_attr_write(conn_id, ias_client, type, handle,
+ length, p_value) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ APP_PRINT_WARN0("ias_ble_client_write_char: Request fail! Please check!");
+ return false;
+}
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool ias_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= ias_link_num)
+ {
+ PROFILE_PRINT_ERROR1("ias_client_get_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (ias_table[conn_id].disc_state != DISC_IAS_DONE)
+ {
+ PROFILE_PRINT_ERROR1("ias_client_get_hdl_cache: failed invalid state %d",
+ ias_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_IAS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("ias_client_get_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(p_hdl_cache, ias_table[conn_id].hdl_cache, len);
+ return true;
+}
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool ias_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= ias_link_num)
+ {
+ PROFILE_PRINT_ERROR1("ias_client_set_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (ias_table[conn_id].disc_state != DISC_IAS_IDLE)
+ {
+ PROFILE_PRINT_ERROR1("ias_client_set_hdl_cache: failed invalid state %d",
+ ias_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_IAS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("ias_client_set_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(ias_table[conn_id].hdl_cache, p_hdl_cache, len);
+ ias_table[conn_id].disc_state = DISC_IAS_DONE;
+ return true;
+}
+
+static bool ias_client_start_char_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ APP_PRINT_INFO0("ias_client_start_ias_char_discovery");
+ start_handle = ias_table[conn_id].hdl_cache[HDL_IAS_SRV_START];
+ end_handle = ias_table[conn_id].hdl_cache[HDL_IAS_SRV_END];
+ if (client_all_char_discovery(conn_id, ias_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+//static bool ias_client_start_char_descriptor_discovery(uint8_t conn_id)
+//{
+// uint16_t start_handle;
+// uint16_t end_handle;
+
+// PROFILE_PRINT_INFO0("ias_client_start_char_descriptor_discovery");
+// start_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY];
+// end_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_SRV_END];
+// if (client_all_char_descriptor_discovery(conn_id, simp_client, start_handle,
+// end_handle) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// return false;
+//}
+static void ias_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state)
+{
+ bool cb_flag = false;
+ T_IAS_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = IAS_CLIENT_CB_TYPE_DISC_STATE;
+
+ APP_PRINT_INFO1("ias_client_discover_state_cb: discovery_state %d", discovery_state);
+ if (ias_table[conn_id].disc_state == DISC_IAS_START)
+ {
+ uint16_t *hdl_cache;
+ hdl_cache = ias_table[conn_id].hdl_cache;
+
+ switch (discovery_state)
+ {
+ case DISC_STATE_SRV_DONE:
+ /* Indicate that service handle found. Start discover characteristic. */
+ if ((hdl_cache[HDL_IAS_SRV_START] != 0)
+ || (hdl_cache[HDL_IAS_SRV_END] != 0))
+ {
+ if (ias_client_start_char_discovery(conn_id) == false)
+ {
+ ias_table[conn_id].disc_state = DISC_IAS_FAILED;
+ cb_flag = true;
+ }
+ }
+ /* No Ias BLE service handle found. Discover procedure complete. */
+ else
+ {
+ ias_table[conn_id].disc_state = DISC_IAS_FAILED;
+ cb_flag = true;
+ }
+ break;
+ case DISC_STATE_CHAR_DONE:
+ ias_table[conn_id].disc_state = DISC_IAS_DONE;
+ cb_flag = true;
+ break;
+ case DISC_STATE_FAILED:
+ ias_table[conn_id].disc_state = DISC_IAS_FAILED;
+ cb_flag = true;
+ break;
+ default:
+ APP_PRINT_ERROR0("ias_handle_discover_state: Invalid Discovery State!");
+ break;
+ }
+ }
+
+ /* Send discover state to application if needed. */
+ if (cb_flag && ias_client_cb)
+ {
+ cb_data.cb_content.disc_state = ias_table[conn_id].disc_state;
+ (*ias_client_cb)(ias_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+/**
+ * @brief Called by profile client layer, when discover result fetched.
+ * @param conn_id: connection ID.
+ * @param result_type: indicate which type of value discovered in service discovery procedure.
+ * @param result_data: value discovered.
+ * @retval None
+ */
+static void ias_client_discover_result_cb(uint8_t conn_id,
+ T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ APP_PRINT_INFO1("ias_client_discover_result_cb: result_type %d", result_type);
+ if (ias_table[conn_id].disc_state == DISC_IAS_START)
+ {
+ uint16_t handle;
+ uint16_t *hdl_cache;
+ hdl_cache = ias_table[conn_id].hdl_cache;
+
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ hdl_cache[HDL_IAS_SRV_START] = result_data.p_srv_disc_data->att_handle;
+ hdl_cache[HDL_IAS_SRV_END] = result_data.p_srv_disc_data->end_group_handle;
+ break;
+
+ case DISC_RESULT_CHAR_UUID16:
+ handle = result_data.p_char_uuid16_disc_data->value_handle;
+ switch (result_data.p_char_uuid16_disc_data->uuid16)
+ {
+ case GATT_UUID_CHAR_ALERT_LEVEL:
+ hdl_cache[HDL_IAS_WRITE] = handle;
+ break;
+ default:
+ /* have no interest on this handle. */
+ break;
+ }
+ break;
+
+ case DISC_RESULT_CHAR_DESC_UUID16:
+ /* When use client_all_char_descriptor_discovery. */
+ if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG)
+ {
+ handle = result_data.p_char_desc_uuid16_disc_data->handle;
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR0("ias_handle_discover_result: Invalid Discovery Result Type!");
+ break;
+ }
+ }
+ return;
+}
+
+static void ias_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type,
+ uint16_t handle, uint16_t cause,
+ uint8_t credits)
+{
+ T_IAS_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = ias_table[conn_id].hdl_cache;
+ cb_data.cb_type = IAS_CLIENT_CB_TYPE_WRITE_RESULT;
+
+ PROFILE_PRINT_INFO2("ias_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.write_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_IAS_WRITE])
+ {
+ cb_data.cb_content.write_result.type = IAS_WRITE_ALERT;
+ }
+ else
+ {
+ return;
+ }
+ /* Inform application the write result. */
+ if (ias_client_cb)
+ {
+ (*ias_client_cb)(ias_client, conn_id, &cb_data);
+ }
+
+ return;
+}
+
+
+static void ias_client_disconnect_cb(uint8_t conn_id)
+{
+ APP_PRINT_INFO0("ias_client_disconnect_cb.");
+ if (conn_id >= ias_link_num)
+ {
+ PROFILE_PRINT_ERROR1("ias_client_disconnect_cb: failed invalid conn_id %d", conn_id);
+ return;
+ }
+ memset(&ias_table[conn_id], 0, sizeof(T_IAS_LINK));
+ return;
+}
+
+/**
+ * @brief Ias BLE Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS ias_client_cbs =
+{
+ ias_client_discover_state_cb, //!< Discovery State callback function pointer
+ ias_client_discover_result_cb, //!< Discovery result callback function pointer
+ NULL, //!< Read response callback function pointer
+ ias_client_write_result_cb, //!< Write result callback function pointer
+ NULL, //!< Notify Indicate callback function pointer
+ ias_client_disconnect_cb //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief Add ias service client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ ias_client_id = ias_ble_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID ias_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+{
+ uint16_t size;
+ if (link_num > IAS_MAX_LINKS)
+ {
+ PROFILE_PRINT_ERROR1("ias_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&ias_client, &ias_client_cbs))
+ {
+ ias_client = CLIENT_PROFILE_GENERAL_ID;
+ APP_PRINT_ERROR0("ias_add_client failed");
+ return ias_client;
+ }
+ APP_PRINT_INFO1("ias_add_client: ias_client %d", ias_client);
+
+ /* register callback for profile to inform application that some events happened. */
+ ias_client_cb = app_cb;
+ ias_link_num = link_num;
+ size = ias_link_num * sizeof(T_IAS_LINK);
+ ias_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ return ias_client;
+}
+
diff --git a/src/ble/profile/client/ipss_client.c b/src/ble/profile/client/ipss_client.c
new file mode 100644
index 0000000..1181e6e
--- /dev/null
+++ b/src/ble/profile/client/ipss_client.c
@@ -0,0 +1,102 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ipss_client.c
+ * @brief Source file for client of internet protocol support service.
+ * @details Global data and function implement.
+ * @author Jeff_Zheng
+ * @date 2017-12-05
+ * @version v1.0
+ * *************************************************************************************
+ */
+#include "trace.h"
+#include "os_mem.h"
+#include "profile_client.h"
+#include "ipss.h"
+
+
+static T_CLIENT_ID ipss_cl_id = CLIENT_PROFILE_GENERAL_ID;
+//static P_FUN_GENERAL_APP_CB ipss_cl_gen_cb = NULL;
+
+/**
+ * @brief discover IPS service by service uuid .
+ *
+ * @param[in] conn_id connection id.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ */
+bool ipss_find_srv_dcl(uint8_t conn_id)
+{
+ if (client_by_uuid_srv_discovery(conn_id, ipss_cl_id, GATT_UUID_IPSS) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief IPS discover result callback.
+ *
+ * @param[in] conn_id connection id.
+ * @param[in] result_type result type @ref T_DISCOVERY_RESULT_TYPE
+ * @param[in] result_data result data @ref T_DISCOVERY_RESULT_DATA
+ * @return void
+ */
+static void ipss_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ {
+ uint16_t start_handle = result_data.p_srv_disc_data->att_handle;
+ uint16_t end_handle = result_data.p_srv_disc_data->end_group_handle;
+ APP_PRINT_INFO2("ipss_discover_result_cb: start handle %x, end handle %d", start_handle,
+ end_handle);
+ break;
+ }
+
+ default:
+ break;
+
+ }
+}
+
+/**
+ * @brief IPS service client callback function pointer.
+ */
+const T_FUN_CLIENT_CBS ipss_cl_cbs =
+{
+ NULL, //!< Discovery State callback function pointer
+ ipss_discover_result_cb, //!< Discovery result callback function pointer
+ NULL, //!< Read response callback function pointer
+ NULL, //!< Write result callback function pointer
+ NULL, //!< Notify Indicate callback function pointer
+ NULL //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief add IPS service client.
+ *
+ * @param[in] p_func pointer of app callback function called by client.
+ * @return client id.
+ */
+uint8_t ipss_add_client(void *p_func)
+{
+ if (false == client_register_spec_client_cb(&ipss_cl_id, &ipss_cl_cbs))
+ {
+ ipss_cl_id = CLIENT_PROFILE_GENERAL_ID;
+ PROFILE_PRINT_ERROR0("ipss_add_client: register fail");
+ }
+ else
+ {
+ //ipss_cl_gen_cb = (P_FUN_GENERAL_APP_CB)p_func;
+ }
+
+ PROFILE_PRINT_INFO1("ipss_add_client: client id %d", ipss_cl_id);
+
+ return ipss_cl_id;
+}
+
diff --git a/src/ble/profile/client/kns_client.c b/src/ble/profile/client/kns_client.c
new file mode 100644
index 0000000..3fd38d2
--- /dev/null
+++ b/src/ble/profile/client/kns_client.c
@@ -0,0 +1,653 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ias_client.c
+ * @brief Ias BLE client source file.
+ * @details
+ * @author jane
+ * @date 2016-02-18
+ * @version v1.0
+ ******************************************************************************
+ */
+
+/** Add Includes here **/
+#include <trace.h>
+#include <string.h>
+#include <kns_client.h>
+#include <os_mem.h>
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+typedef struct
+{
+ T_KNS_DISC_STATE disc_state;
+ uint16_t hdl_cache[HDL_KNS_CACHE_LEN];
+} T_KNS_LINK, *P_KNS_LINK;
+
+static P_KNS_LINK kns_table;
+static uint8_t kns_link_num;
+const uint8_t GATT_UUID128_PARAM[16] = {0xA6, 0xF6, 0xF6, 0x07, 0x4D, 0xC4, 0x9D, 0x98, 0x6D, 0x45, 0x29, 0xBB, 0xD1, 0xFF, 0x00, 0x00};
+const uint8_t GATT_UUID128_KEY[16] = {0xA6, 0xF6, 0xF6, 0x07, 0x4D, 0xC4, 0x9D, 0x98, 0x6D, 0x45, 0x29, 0xBB, 0xD2, 0xFF, 0x00, 0x00};
+/**< kns client ID. */
+static T_CLIENT_ID kns_client = CLIENT_PROFILE_GENERAL_ID;
+/**< Callback used to send data to app from kns client layer. */
+static P_FUN_GENERAL_APP_CB kns_client_cb = NULL;
+
+/**
+ * @brief Used by application, to start the discovery procedure of ias server.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool kns_client_start_discovery(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("kns_client_start_discovery");
+ if (conn_id >= kns_link_num)
+ {
+ PROFILE_PRINT_ERROR1("kns_client_start_discovery: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ /* First clear handle cache. */
+ memset(&kns_table[conn_id], 0, sizeof(T_KNS_LINK));
+ kns_table[conn_id].disc_state = DISC_KNS_START;
+ if (client_by_uuid128_srv_discovery(conn_id, kns_client,
+ (uint8_t *)GATT_UUID128_KNS_SERVICE) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Used by application, to read data from server by using handles.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool kns_client_read_by_handle(uint8_t conn_id,
+ T_KNS_READ_TYPE read_type)//~~~~~~~~~~~~~~~~~~will delete
+{
+ bool hdl_valid = false;
+ uint16_t handle;
+ if (conn_id >= kns_link_num)
+ {
+ PROFILE_PRINT_ERROR1("kns_client_read_by_handle: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ switch (read_type)
+ {
+ case KNS_READ_PARAM:
+ if (kns_table[conn_id].hdl_cache[HDL_KNS_PARA])
+ {
+ handle = kns_table[conn_id].hdl_cache[HDL_KNS_PARA];
+ hdl_valid = true;
+ }
+ break;
+ default:
+ return false;
+ }
+
+ if (hdl_valid)
+ {
+ if (client_attr_read(conn_id, kns_client, handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ APP_PRINT_WARN0("kns_client_read_by_handle: Request fail! Please check!");
+ return false;
+}
+
+/**
+ * @brief Used by application, to read data from server by using UUIDs.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool kns_client_read_by_uuid(uint8_t conn_id,
+ T_KNS_READ_TYPE read_type)//~~~~~~~~~~~~~~~~~~will delete
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint8_t *uuid128;
+ if (conn_id >= kns_link_num)
+ {
+ PROFILE_PRINT_ERROR1("kns_client_read_by_uuid: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ switch (read_type)
+ {
+ case KNS_READ_PARAM:
+ start_handle = kns_table[conn_id].hdl_cache[HDL_KNS_SRV_START];
+ end_handle = kns_table[conn_id].hdl_cache[HDL_KNS_SRV_END];
+ uuid128 = (uint8_t *)GATT_UUID128_PARAM;
+ break;
+ default:
+ return false;
+ }
+
+ if (client_attr_read_using_uuid(conn_id, kns_client, start_handle, end_handle,
+ 0, uuid128) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] notify 0--disable the notification, 1--enable the notification.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool kns_client_set_v3_notify(uint8_t conn_id, bool notify)
+{
+ if (conn_id >= kns_link_num)
+ {
+ PROFILE_PRINT_ERROR1("kns_client_set_v3_notify: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ if (kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD])
+ {
+ uint16_t handle = kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD];
+ uint16_t length = sizeof(uint16_t);
+ uint16_t cccd_bits = notify ? 1 : 0;
+ if (client_attr_write(conn_id, kns_client, GATT_WRITE_TYPE_REQ, handle,
+ length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ APP_PRINT_WARN0("kns_client_set_v3_notify: Request fail! Please check!");
+ return false;
+}
+
+/**
+ * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] ind 0--disable the indication, 1--enable the indication.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool simp_ble_client_set_v4_ind(uint8_t conn_id, bool ind)
+//{
+// if (conn_id >= simp_link_num)
+// {
+// PROFILE_PRINT_ERROR1("simp_ble_client_set_v4_ind: failed invalid conn_id %d", conn_id);
+// return false;
+// }
+
+// if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD])
+// {
+// uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD];
+// uint16_t length = sizeof(uint16_t);
+// uint16_t cccd_bits = ind ? 2 : 0;
+// if (client_attr_write(conn_id, simp_client, GATT_WRITE_TYPE_REQ, handle,
+// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// }
+
+// APP_PRINT_WARN0("simp_ble_client_set_v4_ind: Request fail! Please check!");
+// return false;
+//}
+
+/**
+ * @brief Used by application, to write data of V2 write Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] length write data length
+ * @param[in] p_value point the value to write
+ * @param[in] type write type.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool kns_client_write_v2_char(uint8_t conn_id, uint16_t length, uint8_t *p_value,
+ T_GATT_WRITE_TYPE type)
+{
+ if (conn_id >= kns_link_num)
+ {
+ PROFILE_PRINT_ERROR1("kns_client_write_v2_char: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ if (kns_table[conn_id].hdl_cache[HDL_KNS_PARA])
+ {
+ uint16_t handle = kns_table[conn_id].hdl_cache[HDL_KNS_PARA];
+ if (client_attr_write(conn_id, kns_client, type, handle,
+ length, p_value) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ APP_PRINT_WARN0("kns_ble_client_write_v2_char: Request fail! Please check!");
+ return false;
+}
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool kns_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= kns_link_num)
+ {
+ PROFILE_PRINT_ERROR1("kns_client_get_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (kns_table[conn_id].disc_state != DISC_KNS_DONE)
+ {
+ PROFILE_PRINT_ERROR1("kns_client_get_hdl_cache: failed invalid state %d",
+ kns_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_KNS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("kns_client_get_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(p_hdl_cache, kns_table[conn_id].hdl_cache, len);
+ return true;
+}
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool kns_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= kns_link_num)
+ {
+ PROFILE_PRINT_ERROR1("kns_client_set_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (kns_table[conn_id].disc_state != DISC_KNS_IDLE)
+ {
+ PROFILE_PRINT_ERROR1("kns_client_set_hdl_cache: failed invalid state %d",
+ kns_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_KNS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("kns_client_set_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(kns_table[conn_id].hdl_cache, p_hdl_cache, len);
+ kns_table[conn_id].disc_state = DISC_KNS_DONE;
+ return true;
+}
+
+static bool kns_client_start_char_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ APP_PRINT_INFO0("kns_client_start_ias_char_discovery");
+ start_handle = kns_table[conn_id].hdl_cache[HDL_KNS_SRV_START];
+ end_handle = kns_table[conn_id].hdl_cache[HDL_KNS_SRV_END];
+ if (client_all_char_discovery(conn_id, kns_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+static bool kns_client_start_char_descriptor_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ PROFILE_PRINT_INFO0("kns_client_start_char_descriptor_discovery");
+ start_handle = kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY];
+ end_handle = kns_table[conn_id].hdl_cache[HDL_KNS_SRV_END];
+ if (client_all_char_descriptor_discovery(conn_id, kns_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+static void kns_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state)
+{
+ bool cb_flag = false;
+ T_KNS_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = KNS_CLIENT_CB_TYPE_DISC_STATE;
+
+ APP_PRINT_INFO1("kns_client_discover_state_cb: discovery_state %d", discovery_state);
+ if (kns_table[conn_id].disc_state == DISC_KNS_START)
+ {
+ uint16_t *hdl_cache;
+ hdl_cache = kns_table[conn_id].hdl_cache;
+
+ switch (discovery_state)
+ {
+ case DISC_STATE_SRV_DONE:
+ /* Indicate that service handle found. Start discover characteristic. */
+ if ((hdl_cache[HDL_KNS_SRV_START] != 0)
+ || (hdl_cache[HDL_KNS_SRV_END] != 0))
+ {
+ if (kns_client_start_char_discovery(conn_id) == false)
+ {
+ kns_table[conn_id].disc_state = DISC_KNS_FAILED;
+ cb_flag = true;
+ }
+ }
+ /* No Ias BLE service handle found. Discover procedure complete. */
+ else
+ {
+ kns_table[conn_id].disc_state = DISC_KNS_FAILED;
+ cb_flag = true;
+ }
+ break;
+ case DISC_STATE_CHAR_DONE:
+ if (hdl_cache[HDL_KNS_NOTIFY_KEY] != 0)
+ {
+ if (kns_client_start_char_descriptor_discovery(conn_id) == false)
+ {
+ kns_table[conn_id].disc_state = DISC_KNS_FAILED;
+ cb_flag = true;
+ }
+ }
+ else
+ {
+ kns_table[conn_id].disc_state = DISC_KNS_FAILED;
+ cb_flag = true;
+ }
+ break;
+ case DISC_STATE_CHAR_DESCRIPTOR_DONE:
+ kns_table[conn_id].disc_state = DISC_KNS_DONE;
+ cb_flag = true;
+ break;
+ case DISC_STATE_FAILED:
+ kns_table[conn_id].disc_state = DISC_KNS_FAILED;
+ cb_flag = true;
+ break;
+ default:
+ APP_PRINT_ERROR0("kns_handle_discover_state: Invalid Discovery State!");
+ break;
+ }
+ }
+
+ /* Send discover state to application if needed. */
+ if (cb_flag && kns_client_cb)
+ {
+ cb_data.cb_content.disc_state = kns_table[conn_id].disc_state;
+ (*kns_client_cb)(kns_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+/**
+ * @brief Called by profile client layer, when discover result fetched.
+ * @param conn_id: connection ID.
+ * @param result_type: indicate which type of value discovered in service discovery procedure.
+ * @param result_data: value discovered.
+ * @retval None
+ */
+static void kns_client_discover_result_cb(uint8_t conn_id,
+ T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ APP_PRINT_INFO1("kns_client_discover_result_cb: result_type %d", result_type);
+ if (kns_table[conn_id].disc_state == DISC_KNS_START)
+ {
+ uint16_t handle;
+ uint16_t *hdl_cache;
+ hdl_cache = kns_table[conn_id].hdl_cache;
+
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ hdl_cache[HDL_KNS_SRV_START] = result_data.p_srv_disc_data->att_handle;
+ hdl_cache[HDL_KNS_SRV_END] = result_data.p_srv_disc_data->end_group_handle;
+ break;
+ case DISC_RESULT_CHAR_UUID128:
+ handle = result_data.p_char_uuid128_disc_data->value_handle;
+ if (!memcmp(result_data.p_char_uuid128_disc_data->uuid128, GATT_UUID128_PARAM, 16))
+ {
+ hdl_cache[HDL_KNS_PARA] = handle;
+ }
+ else if (!memcmp(result_data.p_char_uuid128_disc_data->uuid128, GATT_UUID128_KEY, 16))
+ {
+ hdl_cache[HDL_KNS_NOTIFY_KEY] = handle;
+ }
+ break;
+
+ case DISC_RESULT_CHAR_UUID16:
+ break;
+
+ case DISC_RESULT_CHAR_DESC_UUID16:
+ /* When use client_all_char_descriptor_discovery. */
+ if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG)
+ {
+ handle = result_data.p_char_desc_uuid16_disc_data->handle;
+
+ if ((handle > hdl_cache[HDL_KNS_NOTIFY_KEY])
+ && (hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD] == 0))
+ {
+ hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD] = handle;
+ }
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR0("kns_handle_discover_result: Invalid Discovery Result Type!");
+ break;
+ }
+ }
+
+ return;
+}
+
+static void kns_client_read_result_cb(uint8_t conn_id, uint16_t cause,
+ uint16_t handle, uint16_t value_size, uint8_t *p_value)
+{
+ T_KNS_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = kns_table[conn_id].hdl_cache;
+
+ cb_data.cb_type = KNS_CLIENT_CB_TYPE_READ_RESULT;
+
+ APP_PRINT_INFO2("kns_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.read_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_KNS_PARA])
+ {
+ cb_data.cb_content.read_result.type = KNS_READ_PARAM;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD])
+ {
+ cb_data.cb_content.read_result.type = KNS_READ_KEY_NOTIFY_CCCD;
+ if (cause == GAP_SUCCESS)
+ {
+ uint16_t ccc_bit;
+ if (value_size != 2)
+ {
+ PROFILE_PRINT_ERROR1("kns_client_read_result_cb: invalid cccd len %d", value_size);
+ return;
+ }
+ LE_ARRAY_TO_UINT16(ccc_bit, p_value);
+
+ if (ccc_bit & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ cb_data.cb_content.read_result.data.v3_notify_cccd = true;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v3_notify_cccd = false;
+ }
+ }
+ }
+ else
+ {
+ return;
+ }
+ /* Inform application the read result. */
+ if (kns_client_cb)
+ {
+ (*kns_client_cb)(kns_client, conn_id, &cb_data);
+ }
+
+ return;
+}
+
+static void kns_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type,
+ uint16_t handle, uint16_t cause,
+ uint8_t credits)
+{
+ T_KNS_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = kns_table[conn_id].hdl_cache;
+ cb_data.cb_type = KNS_CLIENT_CB_TYPE_WRITE_RESULT;
+
+ PROFILE_PRINT_INFO2("kns_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.write_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_KNS_PARA])
+ {
+ cb_data.cb_content.write_result.type = KNS_WRITE_PARAM;
+ }
+ else if (handle == hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD])
+ {
+ cb_data.cb_content.write_result.type = KNS_WRITE_KEY_NOTIFY_CCCD;
+ }
+ else
+ {
+ return;
+ }
+ /* Inform application the write result. */
+ if (kns_client_cb)
+ {
+ (*kns_client_cb)(kns_client, conn_id, &cb_data);
+ }
+
+ return;
+}
+
+static T_APP_RESULT kns_client_notif_ind_result_cb(uint8_t conn_id, bool notify,
+ uint16_t handle,
+ uint16_t value_size, uint8_t *p_value)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ T_KNS_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = kns_table[conn_id].hdl_cache;
+
+ cb_data.cb_type = KNS_CLIENT_CB_TYPE_NOTIF_IND_RESULT;
+
+ if (handle == hdl_cache[HDL_KNS_NOTIFY_KEY])
+ {
+ cb_data.cb_content.notif_ind_data.type = KNS_KEY_NOTIFY;
+ cb_data.cb_content.notif_ind_data.data.value_size = value_size;
+ cb_data.cb_content.notif_ind_data.data.p_value = p_value;
+ }
+ else
+ {
+ return app_result;
+ }
+ /* Inform application the notif/ind result. */
+ if (kns_client_cb)
+ {
+ app_result = (*kns_client_cb)(kns_client, conn_id, &cb_data);
+ }
+
+ return app_result;
+}
+
+static void kns_client_disconnect_cb(uint8_t conn_id)
+{
+ APP_PRINT_INFO0("kns_client_disconnect_cb.");
+ if (conn_id >= kns_link_num)
+ {
+ PROFILE_PRINT_ERROR1("kns_client_disconnect_cb: failed invalid conn_id %d", conn_id);
+ return;
+ }
+ memset(&kns_table[conn_id], 0, sizeof(T_KNS_LINK));
+ return;
+}
+
+/**
+ * @brief Ias BLE Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS kns_client_cbs =
+{
+ kns_client_discover_state_cb, //!< Discovery State callback function pointer
+ kns_client_discover_result_cb, //!< Discovery result callback function pointer
+ kns_client_read_result_cb, //!< Read response callback function pointer
+ kns_client_write_result_cb, //!< Write result callback function pointer
+ kns_client_notif_ind_result_cb, //!< Notify Indicate callback function pointer
+ kns_client_disconnect_cb //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief Add kns service client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ kns_client_id = kns_ble_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID kns_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+{
+ uint16_t size;
+ if (link_num > KNS_MAX_LINKS)
+ {
+ PROFILE_PRINT_ERROR1("kns_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&kns_client, &kns_client_cbs))
+ {
+ kns_client = CLIENT_PROFILE_GENERAL_ID;
+ APP_PRINT_ERROR0("ias_add_client failed");
+ return kns_client;
+ }
+ APP_PRINT_INFO1("kns_add_client: kns_client %d", kns_client);
+
+ /* register callback for profile to inform application that some events happened. */
+ kns_client_cb = app_cb;
+ kns_link_num = link_num;
+ size = kns_link_num * sizeof(T_KNS_LINK);
+ kns_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ return kns_client;
+}
+
diff --git a/src/ble/profile/client/lls_client.c b/src/ble/profile/client/lls_client.c
new file mode 100644
index 0000000..ef47d8b
--- /dev/null
+++ b/src/ble/profile/client/lls_client.c
@@ -0,0 +1,623 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file lls_client.c
+ * @brief Lls BLE client source file.
+ * @details
+ * @author ken
+ * @date 2017-12-05
+ * @version v1.0
+ ******************************************************************************
+ */
+
+/** Add Includes here **/
+#include <trace.h>
+#include <string.h>
+#include <lls_client.h>
+#include <os_mem.h>
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+typedef struct
+{
+ T_LLS_DISC_STATE disc_state;
+ uint16_t hdl_cache[HDL_LLS_CACHE_LEN];
+} T_LLS_LINK, *P_LLS_LINK;
+
+static P_LLS_LINK lls_table;
+static uint8_t lls_link_num;
+
+/**< lls client ID. */
+static T_CLIENT_ID lls_client = CLIENT_PROFILE_GENERAL_ID;
+/**< Callback used to send data to app from lls client layer. */
+static P_FUN_GENERAL_APP_CB lls_client_cb = NULL;
+
+/**
+ * @brief Used by application, to start the discovery procedure of lls server.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool lls_client_start_discovery(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("lls_client_start_discovery");
+ if (conn_id >= lls_link_num)
+ {
+ PROFILE_PRINT_ERROR1("lls_client_start_discovery: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ /* First clear handle cache. */
+ memset(&lls_table[conn_id], 0, sizeof(T_LLS_LINK));
+ lls_table[conn_id].disc_state = DISC_LLS_START;
+ if (client_by_uuid_srv_discovery(conn_id, lls_client,
+ GATT_UUID_LINK_LOSS_SERVICE) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Used by application, to read data from server by using handles.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool lls_client_read_by_handle(uint8_t conn_id, T_LLS_READ_TYPE read_type)
+{
+ bool hdl_valid = false;
+ uint16_t handle;
+ if (conn_id >= lls_link_num)
+ {
+ PROFILE_PRINT_ERROR1("lls_client_read_by_handle: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ switch (read_type)
+ {
+ case LLS_READ_PARA:
+ if (lls_table[conn_id].hdl_cache[HDL_LLS_PARA])
+ {
+ handle = lls_table[conn_id].hdl_cache[HDL_LLS_PARA];
+ hdl_valid = true;
+ }
+ break;
+ default:
+ return false;
+ }
+
+ if (hdl_valid)
+ {
+ if (client_attr_read(conn_id, lls_client, handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ APP_PRINT_WARN0("lls_client_read_by_handle: Request fail! Please check!");
+ return false;
+}
+
+/**
+ * @brief Used by application, to read data from server by using UUIDs.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool lls_client_read_by_uuid(uint8_t conn_id,
+ T_LLS_READ_TYPE read_type)//~~~~~~~~~~~~~~~~~~will delete
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint16_t uuid16;
+ if (conn_id >= lls_link_num)
+ {
+ PROFILE_PRINT_ERROR1("lls_client_read_by_uuid: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ switch (read_type)
+ {
+ case LLS_READ_PARA:
+ start_handle = lls_table[conn_id].hdl_cache[HDL_LLS_SRV_START];
+ end_handle = lls_table[conn_id].hdl_cache[HDL_LLS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_ALERT_LEVEL;
+ break;
+ default:
+ return false;
+ }
+
+ if (client_attr_read_using_uuid(conn_id, lls_client, start_handle, end_handle,
+ uuid16, NULL) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+///**
+// * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic.
+// * @param[in] conn_id connection ID.
+// * @param[in] notify 0--disable the notification, 1--enable the notification.
+// * @retval true send request to upper stack success.
+// * @retval false send request to upper stack failed.
+// */
+//bool lls_client_set_v3_notify(uint8_t conn_id, bool notify)
+//{
+// if (conn_id >= kns_link_num)
+// {
+// PROFILE_PRINT_ERROR1("kns_client_set_v3_notify: failed invalid conn_id %d", conn_id);
+// return false;
+// }
+
+// if (kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD])
+// {
+// uint16_t handle = kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD];
+// uint16_t length = sizeof(uint16_t);
+// uint16_t cccd_bits = notify ? 1 : 0;
+// if (client_attr_write(conn_id, kns_client, GATT_WRITE_TYPE_REQ, handle,
+// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// }
+
+// APP_PRINT_WARN0("kns_client_set_v3_notify: Request fail! Please check!");
+// return false;
+//}
+
+/**
+ * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] ind 0--disable the indication, 1--enable the indication.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool simp_ble_client_set_v4_ind(uint8_t conn_id, bool ind)
+//{
+// if (conn_id >= simp_link_num)
+// {
+// PROFILE_PRINT_ERROR1("simp_ble_client_set_v4_ind: failed invalid conn_id %d", conn_id);
+// return false;
+// }
+
+// if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD])
+// {
+// uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD];
+// uint16_t length = sizeof(uint16_t);
+// uint16_t cccd_bits = ind ? 2 : 0;
+// if (client_attr_write(conn_id, simp_client, GATT_WRITE_TYPE_REQ, handle,
+// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// }
+
+// APP_PRINT_WARN0("simp_ble_client_set_v4_ind: Request fail! Please check!");
+// return false;
+//}
+
+/**
+ * @brief Used by application, to write data of write Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] length write data length
+ * @param[in] p_value point the value to write
+ * @param[in] type write type.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool lls_client_write_char(uint8_t conn_id, uint16_t length, uint8_t *p_value,
+ T_GATT_WRITE_TYPE type)
+{
+ if (conn_id >= lls_link_num)
+ {
+ PROFILE_PRINT_ERROR1("lls_client_write_char: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ if (lls_table[conn_id].hdl_cache[HDL_LLS_PARA])
+ {
+ uint16_t handle = lls_table[conn_id].hdl_cache[HDL_LLS_PARA];
+ if (client_attr_write(conn_id, lls_client, type, handle,
+ length, p_value) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ APP_PRINT_WARN0("lls_ble_client_write_char: Request fail! Please check!");
+ return false;
+}
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool lls_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= lls_link_num)
+ {
+ PROFILE_PRINT_ERROR1("lls_client_get_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (lls_table[conn_id].disc_state != DISC_LLS_DONE)
+ {
+ PROFILE_PRINT_ERROR1("lls_client_get_hdl_cache: failed invalid state %d",
+ lls_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_LLS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("lls_client_get_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(p_hdl_cache, lls_table[conn_id].hdl_cache, len);
+ return true;
+}
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool lls_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= lls_link_num)
+ {
+ PROFILE_PRINT_ERROR1("lls_client_set_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (lls_table[conn_id].disc_state != DISC_LLS_IDLE)
+ {
+ PROFILE_PRINT_ERROR1("lls_client_set_hdl_cache: failed invalid state %d",
+ lls_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_LLS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("lls_client_set_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(lls_table[conn_id].hdl_cache, p_hdl_cache, len);
+ lls_table[conn_id].disc_state = DISC_LLS_DONE;
+ return true;
+}
+
+static bool lls_client_start_char_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ APP_PRINT_INFO0("lls_client_start_ias_char_discovery");
+ start_handle = lls_table[conn_id].hdl_cache[HDL_LLS_SRV_START];
+ end_handle = lls_table[conn_id].hdl_cache[HDL_LLS_SRV_END];
+ if (client_all_char_discovery(conn_id, lls_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+//static bool lls_client_start_char_descriptor_discovery(uint8_t conn_id)
+//{
+// uint16_t start_handle;
+// uint16_t end_handle;
+
+// PROFILE_PRINT_INFO0("lls_client_start_char_descriptor_discovery");
+// start_handle = lls_table[conn_id].hdl_cache[HDL_LLS_NOTIFY_KEY];
+// end_handle = lls_table[conn_id].hdl_cache[HDL_LLS_SRV_END];
+// if (client_all_char_descriptor_discovery(conn_id, lls_client, start_handle,
+// end_handle) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// return false;
+//}
+static void lls_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state)
+{
+ bool cb_flag = false;
+ T_LLS_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = LLS_CLIENT_CB_TYPE_DISC_STATE;
+
+ APP_PRINT_INFO1("lls_client_discover_state_cb: discovery_state %d", discovery_state);
+ if (lls_table[conn_id].disc_state == DISC_LLS_START)
+ {
+ uint16_t *hdl_cache;
+ hdl_cache = lls_table[conn_id].hdl_cache;
+
+ switch (discovery_state)
+ {
+ case DISC_STATE_SRV_DONE:
+ /* Indicate that service handle found. Start discover characteristic. */
+ if ((hdl_cache[HDL_LLS_SRV_START] != 0)
+ || (hdl_cache[HDL_LLS_SRV_END] != 0))
+ {
+ if (lls_client_start_char_discovery(conn_id) == false)
+ {
+ lls_table[conn_id].disc_state = DISC_LLS_FAILED;
+ cb_flag = true;
+ }
+ }
+ /* No Ias BLE service handle found. Discover procedure complete. */
+ else
+ {
+ lls_table[conn_id].disc_state = DISC_LLS_FAILED;
+ cb_flag = true;
+ }
+ break;
+ case DISC_STATE_CHAR_DONE:
+ lls_table[conn_id].disc_state = DISC_LLS_DONE;
+ cb_flag = true;
+ break;
+ case DISC_STATE_FAILED:
+ lls_table[conn_id].disc_state = DISC_LLS_FAILED;
+ cb_flag = true;
+ break;
+ default:
+ APP_PRINT_ERROR0("lls_handle_discover_state: Invalid Discovery State!");
+ break;
+ }
+ }
+
+ /* Send discover state to application if needed. */
+ if (cb_flag && lls_client_cb)
+ {
+ cb_data.cb_content.disc_state = lls_table[conn_id].disc_state;
+ (*lls_client_cb)(lls_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+/**
+ * @brief Called by profile client layer, when discover result fetched.
+ * @param conn_id: connection ID.
+ * @param result_type: indicate which type of value discovered in service discovery procedure.
+ * @param result_data: value discovered.
+ * @retval None
+ */
+static void lls_client_discover_result_cb(uint8_t conn_id,
+ T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ APP_PRINT_INFO1("lls_client_discover_result_cb: result_type %d", result_type);
+ if (lls_table[conn_id].disc_state == DISC_LLS_START)
+ {
+ uint16_t handle;
+ uint16_t *hdl_cache;
+ hdl_cache = lls_table[conn_id].hdl_cache;
+
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ hdl_cache[HDL_LLS_SRV_START] = result_data.p_srv_disc_data->att_handle;
+ hdl_cache[HDL_LLS_SRV_END] = result_data.p_srv_disc_data->end_group_handle;
+ break;
+ case DISC_RESULT_CHAR_UUID128:
+ break;
+
+ case DISC_RESULT_CHAR_UUID16:
+ handle = result_data.p_char_uuid16_disc_data->value_handle;
+ switch (result_data.p_char_uuid16_disc_data->uuid16)
+ {
+ case GATT_UUID_CHAR_ALERT_LEVEL:
+ hdl_cache[HDL_LLS_PARA] = handle;
+ break;
+ default:
+ /* have no interest on this handle. */
+ break;
+ }
+ break;
+
+ case DISC_RESULT_CHAR_DESC_UUID16:
+ /* When use client_all_char_descriptor_discovery. */
+ break;
+
+ default:
+ APP_PRINT_ERROR0("lls_handle_discover_result: Invalid Discovery Result Type!");
+ break;
+ }
+ }
+
+ return;
+}
+
+static void lls_client_read_result_cb(uint8_t conn_id, uint16_t cause,
+ uint16_t handle, uint16_t value_size, uint8_t *p_value)
+{
+ T_LLS_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = lls_table[conn_id].hdl_cache;
+
+ cb_data.cb_type = LLS_CLIENT_CB_TYPE_READ_RESULT;
+
+ APP_PRINT_INFO2("lls_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.read_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_LLS_PARA])
+ {
+ cb_data.cb_content.read_result.type = LLS_READ_PARA;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+// else if (handle == hdl_cache[HDL_LLS_NOTIFY_KEY_CCCD])
+// {
+// cb_data.cb_content.read_result.type = LLS_READ_KEY_NOTIFY_CCCD;
+// if (cause == GAP_SUCCESS)
+// {
+// uint16_t ccc_bit;
+// if (value_size != 2)
+// {
+// PROFILE_PRINT_ERROR1("kns_client_read_result_cb: invalid cccd len %d", value_size);
+// return;
+// }
+// LE_ARRAY_TO_UINT16(ccc_bit, p_value);
+
+// if (ccc_bit & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+// {
+// cb_data.cb_content.read_result.data.v3_notify_cccd = true;
+// }
+// else
+// {
+// cb_data.cb_content.read_result.data.v3_notify_cccd = false;
+// }
+// }
+// }
+ else
+ {
+ return;
+ }
+ /* Inform application the read result. */
+ if (lls_client_cb)
+ {
+ (*lls_client_cb)(lls_client, conn_id, &cb_data);
+ }
+
+ return;
+}
+
+static void lls_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type,
+ uint16_t handle, uint16_t cause,
+ uint8_t credits)
+{
+ T_LLS_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = lls_table[conn_id].hdl_cache;
+ cb_data.cb_type = LLS_CLIENT_CB_TYPE_WRITE_RESULT;
+
+ PROFILE_PRINT_INFO2("lls_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.write_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_LLS_PARA])
+ {
+ cb_data.cb_content.write_result.type = LLS_WRITE_PARA;
+ }
+ else
+ {
+ return;
+ }
+ /* Inform application the write result. */
+ if (lls_client_cb)
+ {
+ (*lls_client_cb)(lls_client, conn_id, &cb_data);
+ }
+
+ return;
+}
+
+//static T_APP_RESULT lls_client_notif_ind_result_cb(uint8_t conn_id, bool notify,
+// uint16_t handle,
+// uint16_t value_size, uint8_t *p_value)
+//{
+// T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+// T_KNS_CLIENT_CB_DATA cb_data;
+// uint16_t *hdl_cache;
+// hdl_cache = kns_table[conn_id].hdl_cache;
+
+// cb_data.cb_type = KNS_CLIENT_CB_TYPE_NOTIF_IND_RESULT;
+
+// if (handle == hdl_cache[HDL_KNS_NOTIFY_KEY])
+// {
+// cb_data.cb_content.notif_ind_data.type = KNS_KEY_NOTIFY;
+// cb_data.cb_content.notif_ind_data.data.value_size = value_size;
+// cb_data.cb_content.notif_ind_data.data.p_value = p_value;
+// }
+// else
+// {
+// return app_result;
+// }
+// /* Inform application the notif/ind result. */
+// if (kns_client_cb)
+// {
+// app_result = (*kns_client_cb)(kns_client, conn_id, &cb_data);
+// }
+
+// return app_result;
+//}
+
+static void lls_client_disconnect_cb(uint8_t conn_id)
+{
+ APP_PRINT_INFO0("lls_client_disconnect_cb.");
+ if (conn_id >= lls_link_num)
+ {
+ PROFILE_PRINT_ERROR1("lls_client_disconnect_cb: failed invalid conn_id %d", conn_id);
+ return;
+ }
+ memset(&lls_table[conn_id], 0, sizeof(T_LLS_LINK));
+ return;
+}
+
+/**
+ * @brief Ias BLE Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS lls_client_cbs =
+{
+ lls_client_discover_state_cb, //!< Discovery State callback function pointer
+ lls_client_discover_result_cb, //!< Discovery result callback function pointer
+ lls_client_read_result_cb, //!< Read response callback function pointer
+ lls_client_write_result_cb, //!< Write result callback function pointer
+ NULL,//kns_client_notif_ind_result_cb, //!< Notify Indicate callback function pointer
+ lls_client_disconnect_cb //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief Add lls service client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ lls_client_id = lls_ble_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID lls_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+{
+ uint16_t size;
+ if (link_num > LLS_MAX_LINKS)
+ {
+ PROFILE_PRINT_ERROR1("lls_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&lls_client, &lls_client_cbs))
+ {
+ lls_client = CLIENT_PROFILE_GENERAL_ID;
+ APP_PRINT_ERROR0("lls_add_client failed");
+ return lls_client;
+ }
+ APP_PRINT_INFO1("lls_add_client: lls_client %d", lls_client);
+
+ /* register callback for profile to inform application that some events happened. */
+ lls_client_cb = app_cb;
+ lls_link_num = link_num;
+ size = lls_link_num * sizeof(T_LLS_LINK);
+ lls_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ return lls_client;
+}
+
diff --git a/src/ble/profile/client/ota_client.c b/src/ble/profile/client/ota_client.c
new file mode 100644
index 0000000..25a850e
--- /dev/null
+++ b/src/ble/profile/client/ota_client.c
@@ -0,0 +1,644 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ota_client.c
+ * @brief ota service client source file.
+ * @details
+ * @author
+ * @date
+ * @version
+ ******************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2015 Realtek Semiconductor Corporation</center></h2>
+ ******************************************************************************
+ */
+
+/** Add Includes here **/
+#include <string.h>
+#include <stdbool.h>
+#include "trace.h"
+#include "gap_conn_le.h"
+#include "bt_types.h"
+#include "mem_types.h"
+#include "os_mem.h"
+#include "ota_client.h"
+/**
+ * @brief OTA client Link control block definition.
+ */
+typedef struct
+{
+ T_OTA_DISC_STATE disc_state;
+ uint16_t hdl_cache[HDL_OTA_CACHE_LEN];
+} T_OTA_LINK, *P_OTA_LINK;
+
+
+static P_OTA_LINK ota_table;
+static uint8_t ota_link_num;
+
+/**< OTA client ID. */
+static T_CLIENT_ID ota_client = CLIENT_PROFILE_GENERAL_ID;
+/**< Callback used to send data to app from OTA client layer. */
+static P_FUN_GENERAL_APP_CB ota_client_cb = NULL;
+
+const uint8_t ota_service_uuid[16] = {GATT_UUID_OTA_SERVICE};
+
+/**
+ * @brief Used by application, to start the discovery procedure of OTA server.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ota_client_start_discovery(uint8_t conn_id)
+{
+ DFU_PRINT_INFO0("ota_client_start_discovery");
+ if (conn_id >= ota_link_num)
+ {
+ DFU_PRINT_ERROR1("ota_client_start_discovery: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ /* First clear handle cache. */
+ memset(&ota_table[conn_id], 0, sizeof(T_OTA_LINK));
+ ota_table[conn_id].disc_state = DISC_OTA_START;
+ if (client_by_uuid128_srv_discovery(conn_id, ota_client,
+ (uint8_t *)ota_service_uuid) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+
+static bool ota_client_start_char_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ APP_PRINT_INFO0("ota_client_start_char_discovery");
+ start_handle = ota_table[conn_id].hdl_cache[HDL_OTA_SRV_START];
+ end_handle = ota_table[conn_id].hdl_cache[HDL_OTA_SRV_END];
+ if (client_all_char_discovery(conn_id, ota_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Used by application, to read data from server by using handles.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ota_client_read_by_handle(uint8_t conn_id, T_OTA_READ_TYPE read_type)
+{
+ bool hdl_valid = false;
+ uint16_t handle;
+ if (conn_id >= ota_link_num)
+ {
+ DFU_PRINT_ERROR1("ota_client_read_by_handle: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ switch (read_type)
+ {
+ case OTA_READ_DEVICE_MAC:
+ if (ota_table[conn_id].hdl_cache[HDL_OTA_DEVICE_MAC])
+ {
+ handle = ota_table[conn_id].hdl_cache[HDL_OTA_DEVICE_MAC];
+ hdl_valid = true;
+ }
+ break;
+ case OTA_READ_PATCH_VER:
+ if (ota_table[conn_id].hdl_cache[HDL_OTA_PATCH_VER])
+ {
+ handle = ota_table[conn_id].hdl_cache[HDL_OTA_PATCH_VER];
+ hdl_valid = true;
+ }
+ break;
+ case OTA_READ_APP_VER:
+ if (ota_table[conn_id].hdl_cache[HDL_OTA_APP_VER])
+ {
+ handle = ota_table[conn_id].hdl_cache[HDL_OTA_APP_VER];
+ hdl_valid = true;
+ }
+ break;
+ case OTA_READ_PATCH_EXT_VER:
+ if (ota_table[conn_id].hdl_cache[HDL_OTA_PATCH_EXT_VER])
+ {
+ handle = ota_table[conn_id].hdl_cache[HDL_OTA_PATCH_EXT_VER];
+ hdl_valid = true;
+ }
+ break;
+ case OTA_READ_DEVICE_INFO:
+ if (ota_table[conn_id].hdl_cache[HDL_OTA_DEVICE_INFO])
+ {
+ handle = ota_table[conn_id].hdl_cache[HDL_OTA_DEVICE_INFO];
+ hdl_valid = true;
+ }
+ break;
+ case OTA_READ_IMG_VER:
+ if (ota_table[conn_id].hdl_cache[HDL_OTA_IMG_VER])
+ {
+ handle = ota_table[conn_id].hdl_cache[HDL_OTA_IMG_VER];
+ hdl_valid = true;
+ }
+ break;
+
+ default:
+ return false;
+ }
+
+ if (hdl_valid)
+ {
+ if (client_attr_read(conn_id, ota_client, handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ APP_PRINT_WARN0("ota_client_read_by_handle: Request fail! Please check!");
+ return false;
+}
+
+
+/**
+ * @brief Used by application, to write ota cmd write Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] length write data length
+ * @param[in] p_value point the value to write
+ * @param[in] type write type.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool ota_client_write_char(uint8_t conn_id, T_OTA_WRITE_TYPE write_type)
+{
+ if (conn_id >= ota_link_num)
+ {
+ DFU_PRINT_ERROR1("ota_client_write_char: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ switch (write_type)
+ {
+ case OTA_WRITE_CMD:
+ {
+ DFU_PRINT_INFO1("ota_client_write_char: write handle 0x%x",
+ ota_table[conn_id].hdl_cache[HDL_OTA_CMD]);
+ if (ota_table[conn_id].hdl_cache[HDL_OTA_CMD])
+ {
+ uint16_t handle = ota_table[conn_id].hdl_cache[HDL_OTA_CMD];
+ uint8_t ota_cmd = OTA_WRITE_OTA_CMD_CHAR_VAL;
+ if (client_attr_write(conn_id, ota_client, GATT_WRITE_TYPE_CMD, handle,
+ sizeof(ota_cmd), &ota_cmd) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+ break;
+ }
+ case OTA_WRITE_TEST_MODE:
+ {
+ if (ota_table[conn_id].hdl_cache[HDL_OTA_TEST_MODE])
+ {
+ uint16_t handle = ota_table[conn_id].hdl_cache[HDL_OTA_TEST_MODE];
+ uint8_t test_mode = OTA_WRITE_TEST_MODE_CHAR_VAL;
+ if (client_attr_write(conn_id, ota_client, GATT_WRITE_TYPE_CMD, handle,
+ sizeof(test_mode), &test_mode) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+ break;
+ }
+ case OTA_WRITE_IMG_COUNTER:
+ {
+ if (ota_table[conn_id].hdl_cache[HDL_OTA_IMG_COUNTER])
+ {
+ uint16_t handle = ota_table[conn_id].hdl_cache[HDL_OTA_IMG_COUNTER];
+ uint8_t img_counter = OTA_WRITE_OTA_IMG_COUNTER_CHAR_VAL;
+ if (client_attr_write(conn_id, ota_client, GATT_WRITE_TYPE_CMD, handle,
+ sizeof(img_counter), &img_counter) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+
+ }
+
+ DFU_PRINT_WARN1("ota_client_write_char fail! write_type=%d", write_type);
+ return false;
+}
+
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool ota_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= ota_link_num)
+ {
+ DFU_PRINT_ERROR1("ota_client_get_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (ota_table[conn_id].disc_state != DISC_OTA_DONE)
+ {
+ DFU_PRINT_ERROR1("ota_client_get_hdl_cache: failed invalid state %d",
+ ota_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_OTA_CACHE_LEN)
+ {
+ DFU_PRINT_ERROR1("ota_client_get_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(p_hdl_cache, ota_table[conn_id].hdl_cache, len);
+ return true;
+}
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool ota_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= ota_link_num)
+ {
+ DFU_PRINT_ERROR1("ota_client_set_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (ota_table[conn_id].disc_state != DISC_OTA_IDLE)
+ {
+ DFU_PRINT_ERROR1("ota_client_set_hdl_cache: failed invalid state %d",
+ ota_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_OTA_CACHE_LEN)
+ {
+ DFU_PRINT_ERROR1("ota_client_set_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(ota_table[conn_id].hdl_cache, p_hdl_cache, len);
+ ota_table[conn_id].disc_state = DISC_OTA_DONE;
+ return true;
+}
+
+
+static void ota_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state)
+{
+ bool cb_flag = false;
+ T_OTA_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = OTA_CLIENT_CB_TYPE_DISC_STATE;
+
+ DFU_PRINT_INFO1("ota_client_discover_state_cb: discovery_state = %d", discovery_state);
+ if (ota_table[conn_id].disc_state == DISC_OTA_START)
+ {
+ switch (discovery_state)
+ {
+ case DISC_STATE_SRV_DONE:
+ /* Indicate that service handle found. Start discover characteristic. */
+ if ((ota_table[conn_id].hdl_cache[HDL_OTA_SRV_START] != 0)
+ || (ota_table[conn_id].hdl_cache[HDL_OTA_SRV_END] != 0))
+ {
+ if (ota_client_start_char_discovery(conn_id) == false)
+ {
+ ota_table[conn_id].disc_state = DISC_OTA_FAILED;
+ cb_flag = true;
+ }
+ }
+ /* No ota handle found. Discover procedure complete. */
+ else
+ {
+ ota_table[conn_id].disc_state = DISC_OTA_FAILED;
+ cb_flag = true;
+ }
+ break;
+ case DISC_STATE_CHAR_DONE:
+ ota_table[conn_id].disc_state = DISC_OTA_DONE;
+ cb_flag = true;
+ break;
+ case DISC_STATE_CHAR_DESCRIPTOR_DONE:
+ break;
+ default:
+ DFU_PRINT_ERROR0("Invalid Discovery State!");
+ break;
+ }
+ }
+
+ /* Send discover state to application if needed. */
+ if (cb_flag && ota_client_cb)
+ {
+ cb_data.cb_content.disc_state = ota_table[conn_id].disc_state;
+ (*ota_client_cb)(ota_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+
+static void ota_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ uint16_t handle;
+ uint16_t *hdl_cache;
+ hdl_cache = ota_table[conn_id].hdl_cache;
+ DFU_PRINT_INFO1("ota_client_discover_result_cb: result_type = %d", result_type);
+ if (ota_table[conn_id].disc_state == DISC_OTA_START)
+ {
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ DFU_PRINT_INFO0("DISC_RESULT_SRV_DATA");
+ ota_table[conn_id].hdl_cache[HDL_OTA_SRV_START] =
+ result_data.p_srv_disc_data->att_handle;
+ ota_table[conn_id].hdl_cache[HDL_OTA_SRV_END] =
+ result_data.p_srv_disc_data->end_group_handle;
+ break;
+
+ case DISC_RESULT_CHAR_UUID16:
+ {
+ DFU_PRINT_INFO2("DISC_RESULT_CHAR_UUID16: handle 0x%x, uuid 0x%x",
+ result_data.p_char_uuid16_disc_data->value_handle,
+ result_data.p_char_uuid16_disc_data->uuid16);
+ handle = result_data.p_char_uuid16_disc_data->value_handle;
+ switch (result_data.p_char_uuid16_disc_data->uuid16)
+ {
+ case GATT_UUID_CHAR_OTA:
+ hdl_cache[HDL_OTA_CMD] = handle;
+ break;
+ case GATT_UUID_CHAR_MAC:
+ hdl_cache[HDL_OTA_DEVICE_MAC] = handle;
+ break;
+ case GATT_UUID_CHAR_PATCH:
+ hdl_cache[HDL_OTA_PATCH_VER] = handle;
+ break;
+ case GATT_UUID_CHAR_APP_VERSION:
+ hdl_cache[HDL_OTA_APP_VER] = handle;
+ break;
+ case GATT_UUID_CHAR_PATCH_EXTENSION:
+ hdl_cache[HDL_OTA_PATCH_EXT_VER] = handle;
+ break;
+ case GATT_UUID_CHAR_TEST_MODE:
+ hdl_cache[HDL_OTA_TEST_MODE] = handle;
+ break;
+ case GATT_UUID_CHAR_DEVICE_INFO:
+ hdl_cache[HDL_OTA_DEVICE_INFO] = handle;
+ break;
+ case GATT_UUID_CHAR_IMAGE_COUNT_TO_UPDATE:
+ hdl_cache[HDL_OTA_IMG_COUNTER] = handle;
+ break;
+ case GATT_UUID_CHAR_IMAGE_VERSION:
+ hdl_cache[HDL_OTA_IMG_VER] = handle;
+ break;
+ default:
+ /* have no interest on this handle. */
+ break;
+ }
+ }
+ break;
+
+ default:
+ DFU_PRINT_ERROR0("Invalid Discovery Result Type!");
+ break;
+ }
+ }
+
+ return;
+}
+
+static void ota_client_read_result_cb(uint8_t conn_id, uint16_t cause,
+ uint16_t handle, uint16_t value_size, uint8_t *p_value)
+{
+ T_OTA_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = ota_table[conn_id].hdl_cache;
+ cb_data.cb_type = OTA_CLIENT_CB_TYPE_READ_RESULT;
+
+ DFU_PRINT_INFO2("ota_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.read_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_OTA_DEVICE_MAC])
+ {
+ cb_data.cb_content.read_result.type = OTA_READ_DEVICE_MAC;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.p_value = p_value;
+ cb_data.cb_content.read_result.data.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_OTA_PATCH_VER])
+ {
+ cb_data.cb_content.read_result.type = OTA_READ_PATCH_VER;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.p_value = p_value;
+ cb_data.cb_content.read_result.data.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_OTA_APP_VER])
+ {
+ cb_data.cb_content.read_result.type = OTA_READ_APP_VER;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.p_value = p_value;
+ cb_data.cb_content.read_result.data.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_OTA_PATCH_EXT_VER])
+ {
+ cb_data.cb_content.read_result.type = OTA_READ_PATCH_EXT_VER;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.p_value = p_value;
+ cb_data.cb_content.read_result.data.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_OTA_DEVICE_INFO])
+ {
+ cb_data.cb_content.read_result.type = OTA_READ_DEVICE_INFO;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.p_value = p_value;
+ cb_data.cb_content.read_result.data.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_OTA_IMG_VER])
+ {
+ cb_data.cb_content.read_result.type = OTA_READ_IMG_VER;
+ if (cause == GAP_SUCCESS)
+ {
+ //ota header, secure boot, patch, app version
+ cb_data.cb_content.read_result.data.p_value = p_value;
+ cb_data.cb_content.read_result.data.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.value_size = 0;
+ }
+ }
+ else
+ {
+ return;
+ }
+
+ if (ota_client_cb)
+ {
+ (*ota_client_cb)(ota_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+static void ota_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type,
+ uint16_t handle,
+ uint16_t cause,
+ uint8_t credits)
+{
+ T_OTA_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = ota_table[conn_id].hdl_cache;
+ cb_data.cb_type = OTA_CLIENT_CB_TYPE_WRITE_RESULT;
+
+ DFU_PRINT_INFO2("ota_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.write_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_OTA_CMD])
+ {
+ cb_data.cb_content.write_result.type = OTA_WRITE_CMD;
+ }
+ else if (handle == hdl_cache[HDL_OTA_TEST_MODE])
+ {
+ cb_data.cb_content.write_result.type = OTA_WRITE_TEST_MODE;
+ }
+ else if (handle == hdl_cache[HDL_OTA_IMG_COUNTER])
+ {
+ cb_data.cb_content.write_result.type = OTA_WRITE_IMG_COUNTER;
+ }
+ else
+ {
+ return;
+ }
+
+ /* Inform application the write result. */
+ if (ota_client_cb)
+ {
+ (*ota_client_cb)(ota_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+
+/**
+ * @brief OTA Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS ota_client_cbs =
+{
+ ota_client_discover_state_cb, //!< Discovery State callback function pointer
+ ota_client_discover_result_cb, //!< Discovery result callback function pointer
+ ota_client_read_result_cb, //!< Read response callback function pointer
+ ota_client_write_result_cb, //!< Write result callback function pointer
+ NULL, //ota_client_notify_ind_cb, //!< Notify Indicate callback function pointer
+ NULL//ota_client_disc_cb //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief add Dfu client to application.
+ * @param appCB: pointer of app callback function to handle specific client module data.
+ * @retval Client ID of the specific client module.
+ */
+T_CLIENT_ID ota_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+{
+ uint16_t size;
+ if (link_num > OTA_MAX_LINKS)
+ {
+ DFU_PRINT_ERROR1("ota_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&ota_client, &ota_client_cbs))
+ {
+ ota_client = CLIENT_PROFILE_GENERAL_ID;
+ DFU_PRINT_ERROR0("ota_client_add: fail!");
+ return ota_client;
+ }
+ DFU_PRINT_INFO1("ota_client_add: client ID = %d", ota_client);
+ ota_link_num = link_num;
+ size = ota_link_num * sizeof(T_OTA_LINK);
+ ota_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ /* register callback for profile to inform application that some events happened. */
+ ota_client_cb = app_cb;
+ return ota_client;
+
+}
+
+/**
+ * @brief ota client connect target device.
+ * @param p_le_scan_info: filtered scan info
+ */
+void ota_client_connect_device(T_LE_SCAN_INFO *p_le_scan_info)
+{
+ DFU_PRINT_INFO1("ota_client_connect_device: p_le_scan_info->adv_type = %d",
+ p_le_scan_info->adv_type);
+ if (p_le_scan_info->adv_type != GAP_ADV_EVT_TYPE_UNDIRECTED)
+ {
+ return;
+ }
+
+ T_GAP_LE_CONN_REQ_PARAM conn_req_param;
+ conn_req_param.scan_interval = 0x10;
+ conn_req_param.scan_window = 0x10;
+ conn_req_param.conn_interval_min = 0x80;
+ conn_req_param.conn_interval_max = 0x80;
+ conn_req_param.conn_latency = 0;
+ conn_req_param.supv_tout = 1000;
+ conn_req_param.ce_len_min = 2 * (conn_req_param.conn_interval_min - 1);
+ conn_req_param.ce_len_max = 2 * (conn_req_param.conn_interval_max - 1);
+ le_set_conn_param(GAP_CONN_PARAM_1M, &conn_req_param);
+ T_GAP_CAUSE cause;
+ if (GAP_CAUSE_SUCCESS == (cause = le_connect(GAP_PHYS_CONN_INIT_1M_BIT, p_le_scan_info->bd_addr,
+ p_le_scan_info->remote_addr_type,
+ GAP_LOCAL_ADDR_LE_PUBLIC, 1000)))
+ {
+ DFU_PRINT_INFO2("ota_client_connect_device: try connecting %s, remote_addr_type=%d",
+ TRACE_BDADDR(p_le_scan_info->bd_addr), p_le_scan_info->remote_addr_type);
+ }
+ else
+ {
+ DFU_PRINT_INFO1("ota_client_connect_device: FAIL cause=%d!", cause);
+ }
+
+
+ return;
+}
diff --git a/src/ble/profile/client/simple_ble_client.c b/src/ble/profile/client/simple_ble_client.c
new file mode 100644
index 0000000..2de2c03
--- /dev/null
+++ b/src/ble/profile/client/simple_ble_client.c
@@ -0,0 +1,725 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file simple_ble_client.c
+ * @brief Simple BLE client source file.
+ * @details
+ * @author jane
+ * @date 2016-02-18
+ * @version v1.0
+ ******************************************************************************
+ */
+
+/** Add Includes here **/
+#include <trace.h>
+#include <string.h>
+#include <simple_ble_client.h>
+#include <os_mem.h>
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+typedef struct
+{
+ T_SIMP_DISC_STATE disc_state;
+ uint16_t hdl_cache[HDL_SIMBLE_CACHE_LEN];
+} T_SIMP_LINK, *P_SIMP_LINK;
+
+static P_SIMP_LINK simp_table;
+static uint8_t simp_link_num;
+
+/**< Simple BLE client ID. */
+static T_CLIENT_ID simp_client = CLIENT_PROFILE_GENERAL_ID;
+/**< Callback used to send data to app from Simple BLE client layer. */
+static P_FUN_GENERAL_APP_CB simp_client_cb = NULL;
+
+/**
+ * @brief Used by application, to start the discovery procedure of Simple BLE server.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool simp_ble_client_start_discovery(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("simp_ble_client_start_discovery");
+ if (conn_id >= simp_link_num)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_client_start_discovery: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ /* First clear handle cache. */
+ memset(&simp_table[conn_id], 0, sizeof(T_SIMP_LINK));
+ simp_table[conn_id].disc_state = DISC_SIMP_START;
+ if (client_by_uuid_srv_discovery(conn_id, simp_client,
+ GATT_UUID_SIMPLE_PROFILE) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Used by application, to read data from server by using handles.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool simp_ble_client_read_by_handle(uint8_t conn_id, T_SIMP_READ_TYPE read_type)
+{
+ bool hdl_valid = false;
+ uint16_t handle;
+ if (conn_id >= simp_link_num)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_client_read_by_handle: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ switch (read_type)
+ {
+ case SIMP_READ_V1_READ:
+ if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V1_READ])
+ {
+ handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V1_READ];
+ hdl_valid = true;
+ }
+ break;
+ case SIMP_READ_V3_NOTIFY_CCCD:
+ if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD])
+ {
+ handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD];
+ hdl_valid = true;
+ }
+ break;
+ case SIMP_READ_V4_INDICATE_CCCD:
+ if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD])
+ {
+ handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD];
+ hdl_valid = true;
+ }
+ break;
+
+ default:
+ return false;
+ }
+
+ if (hdl_valid)
+ {
+ if (client_attr_read(conn_id, simp_client, handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ APP_PRINT_WARN0("simp_ble_client_read_by_handle: Request fail! Please check!");
+ return false;
+}
+
+/**
+ * @brief Used by application, to read data from server by using UUIDs.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool simp_ble_client_read_by_uuid(uint8_t conn_id, T_SIMP_READ_TYPE read_type)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint16_t uuid16;
+ if (conn_id >= simp_link_num)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_client_read_by_uuid: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ switch (read_type)
+ {
+ case SIMP_READ_V1_READ:
+ start_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_SRV_START];
+ end_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_SRV_END];
+ uuid16 = GATT_UUID_CHAR_SIMPLE_V1_READ;
+ break;
+ case SIMP_READ_V3_NOTIFY_CCCD:
+ start_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY];
+ end_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE];
+ uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG;
+ break;
+ case SIMP_READ_V4_INDICATE_CCCD:
+ start_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE];
+ end_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_SRV_END];
+ uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG;
+ break;
+ default:
+ return false;
+ }
+
+ if (client_attr_read_using_uuid(conn_id, simp_client, start_handle, end_handle,
+ uuid16, NULL) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] notify 0--disable the notification, 1--enable the notification.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool simp_ble_client_set_v3_notify(uint8_t conn_id, bool notify)
+{
+ if (conn_id >= simp_link_num)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_client_set_v3_notify: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD])
+ {
+ uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD];
+ uint16_t length = sizeof(uint16_t);
+ uint16_t cccd_bits = notify ? 1 : 0;
+ if (client_attr_write(conn_id, simp_client, GATT_WRITE_TYPE_REQ, handle,
+ length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ APP_PRINT_WARN0("simp_ble_client_set_v3_notify: Request fail! Please check!");
+ return false;
+}
+
+/**
+ * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] ind 0--disable the indication, 1--enable the indication.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool simp_ble_client_set_v4_ind(uint8_t conn_id, bool ind)
+{
+ if (conn_id >= simp_link_num)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_client_set_v4_ind: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD])
+ {
+ uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD];
+ uint16_t length = sizeof(uint16_t);
+ uint16_t cccd_bits = ind ? 2 : 0;
+ if (client_attr_write(conn_id, simp_client, GATT_WRITE_TYPE_REQ, handle,
+ length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ APP_PRINT_WARN0("simp_ble_client_set_v4_ind: Request fail! Please check!");
+ return false;
+}
+
+/**
+ * @brief Used by application, to write data of V2 write Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] length write data length
+ * @param[in] p_value point the value to write
+ * @param[in] type write type.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool simp_ble_client_write_v2_char(uint8_t conn_id, uint16_t length, uint8_t *p_value,
+ T_GATT_WRITE_TYPE type)
+{
+ if (conn_id >= simp_link_num)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_client_write_v2_char: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V2_WRITE])
+ {
+ uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V2_WRITE];
+ if (client_attr_write(conn_id, simp_client, type, handle,
+ length, p_value) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ APP_PRINT_WARN0("simp_ble_client_write_v2_char: Request fail! Please check!");
+ return false;
+}
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool simp_ble_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= simp_link_num)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_client_get_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (simp_table[conn_id].disc_state != DISC_SIMP_DONE)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_client_get_hdl_cache: failed invalid state %d",
+ simp_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_SIMBLE_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_client_get_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(p_hdl_cache, simp_table[conn_id].hdl_cache, len);
+ return true;
+}
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool simp_ble_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= simp_link_num)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_client_set_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (simp_table[conn_id].disc_state != DISC_SIMP_IDLE)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_client_set_hdl_cache: failed invalid state %d",
+ simp_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_SIMBLE_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_client_set_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(simp_table[conn_id].hdl_cache, p_hdl_cache, len);
+ simp_table[conn_id].disc_state = DISC_SIMP_DONE;
+ return true;
+}
+
+static bool simp_ble_client_start_char_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ APP_PRINT_INFO0("simp_ble_client_start_simp_char_discovery");
+ start_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_SRV_START];
+ end_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_SRV_END];
+ if (client_all_char_discovery(conn_id, simp_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+static bool simp_ble_client_start_char_descriptor_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ PROFILE_PRINT_INFO0("simp_ble_client_start_char_descriptor_discovery");
+ start_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY];
+ end_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_SRV_END];
+ if (client_all_char_descriptor_discovery(conn_id, simp_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+static void simp_ble_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state)
+{
+ bool cb_flag = false;
+ T_SIMP_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = SIMP_CLIENT_CB_TYPE_DISC_STATE;
+
+ APP_PRINT_INFO1("simp_ble_client_discover_state_cb: discovery_state %d", discovery_state);
+ if (simp_table[conn_id].disc_state == DISC_SIMP_START)
+ {
+ uint16_t *hdl_cache;
+ hdl_cache = simp_table[conn_id].hdl_cache;
+
+ switch (discovery_state)
+ {
+ case DISC_STATE_SRV_DONE:
+ /* Indicate that service handle found. Start discover characteristic. */
+ if ((hdl_cache[HDL_SIMBLE_SRV_START] != 0)
+ || (hdl_cache[HDL_SIMBLE_SRV_END] != 0))
+ {
+ if (simp_ble_client_start_char_discovery(conn_id) == false)
+ {
+ simp_table[conn_id].disc_state = DISC_SIMP_FAILED;
+ cb_flag = true;
+ }
+ }
+ /* No Simple BLE service handle found. Discover procedure complete. */
+ else
+ {
+ simp_table[conn_id].disc_state = DISC_SIMP_FAILED;
+ cb_flag = true;
+ }
+ break;
+ case DISC_STATE_CHAR_DONE:
+ if (hdl_cache[HDL_SIMBLE_V3_NOTIFY] != 0)
+ {
+ if (simp_ble_client_start_char_descriptor_discovery(conn_id) == false)
+ {
+ simp_table[conn_id].disc_state = DISC_SIMP_FAILED;
+ cb_flag = true;
+ }
+ }
+ else
+ {
+ simp_table[conn_id].disc_state = DISC_SIMP_FAILED;
+ cb_flag = true;
+ }
+ break;
+ case DISC_STATE_CHAR_DESCRIPTOR_DONE:
+ simp_table[conn_id].disc_state = DISC_SIMP_DONE;
+ cb_flag = true;
+ break;
+ case DISC_STATE_FAILED:
+ simp_table[conn_id].disc_state = DISC_SIMP_FAILED;
+ cb_flag = true;
+ break;
+ default:
+ APP_PRINT_ERROR0("simp_handle_discover_state: Invalid Discovery State!");
+ break;
+ }
+ }
+
+ /* Send discover state to application if needed. */
+ if (cb_flag && simp_client_cb)
+ {
+ cb_data.cb_content.disc_state = simp_table[conn_id].disc_state;
+ (*simp_client_cb)(simp_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+/**
+ * @brief Called by profile client layer, when discover result fetched.
+ * @param conn_id: connection ID.
+ * @param result_type: indicate which type of value discovered in service discovery procedure.
+ * @param result_data: value discovered.
+ * @retval None
+ */
+static void simp_ble_client_discover_result_cb(uint8_t conn_id,
+ T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ APP_PRINT_INFO1("simp_ble_client_discover_result_cb: result_type %d", result_type);
+ if (simp_table[conn_id].disc_state == DISC_SIMP_START)
+ {
+ uint16_t handle;
+ uint16_t *hdl_cache;
+ hdl_cache = simp_table[conn_id].hdl_cache;
+
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ hdl_cache[HDL_SIMBLE_SRV_START] = result_data.p_srv_disc_data->att_handle;
+ hdl_cache[HDL_SIMBLE_SRV_END] = result_data.p_srv_disc_data->end_group_handle;
+ break;
+
+ case DISC_RESULT_CHAR_UUID16:
+ handle = result_data.p_char_uuid16_disc_data->value_handle;
+ switch (result_data.p_char_uuid16_disc_data->uuid16)
+ {
+ case GATT_UUID_CHAR_SIMPLE_V1_READ:
+ hdl_cache[HDL_SIMBLE_V1_READ] = handle;
+ break;
+
+ case GATT_UUID_CHAR_SIMPLE_V2_WRITE:
+ hdl_cache[HDL_SIMBLE_V2_WRITE] = handle;
+ break;
+
+ case GATT_UUID_CHAR_SIMPLE_V3_NOTIFY:
+ hdl_cache[HDL_SIMBLE_V3_NOTIFY] = handle;
+ break;
+
+ case GATT_UUID_CHAR_SIMPLE_V4_INDICATE:
+ hdl_cache[HDL_SIMBLE_V4_INDICATE] = handle;
+ break;
+
+ default:
+ /* have no interest on this handle. */
+ break;
+ }
+
+ break;
+
+ case DISC_RESULT_CHAR_DESC_UUID16:
+ /* When use client_all_char_descriptor_discovery. */
+ if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG)
+ {
+ handle = result_data.p_char_desc_uuid16_disc_data->handle;
+ if ((handle > hdl_cache[HDL_SIMBLE_V3_NOTIFY])
+ && (handle < hdl_cache[HDL_SIMBLE_V4_INDICATE]))
+ {
+ hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD] = handle;
+ }
+ else if ((handle > hdl_cache[HDL_SIMBLE_V4_INDICATE]) &&
+ (hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD] == 0))
+ {
+ hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD] = handle;
+ }
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR0("simp_handle_discover_result: Invalid Discovery Result Type!");
+ break;
+ }
+ }
+
+ return;
+}
+
+static void simp_ble_client_read_result_cb(uint8_t conn_id, uint16_t cause,
+ uint16_t handle, uint16_t value_size, uint8_t *p_value)
+{
+ T_SIMP_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = simp_table[conn_id].hdl_cache;
+
+ cb_data.cb_type = SIMP_CLIENT_CB_TYPE_READ_RESULT;
+
+ APP_PRINT_INFO2("simp_ble_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.read_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_SIMBLE_V1_READ])
+ {
+ cb_data.cb_content.read_result.type = SIMP_READ_V1_READ;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD])
+ {
+ cb_data.cb_content.read_result.type = SIMP_READ_V3_NOTIFY_CCCD;
+ if (cause == GAP_SUCCESS)
+ {
+ uint16_t ccc_bit;
+ if (value_size != 2)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_client_read_result_cb: invalid cccd len %d", value_size);
+ return;
+ }
+ LE_ARRAY_TO_UINT16(ccc_bit, p_value);
+
+ if (ccc_bit & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ cb_data.cb_content.read_result.data.v3_notify_cccd = true;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v3_notify_cccd = false;
+ }
+ }
+ }
+ else if (handle == hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD])
+ {
+ cb_data.cb_content.read_result.type = SIMP_READ_V4_INDICATE_CCCD;
+ if (cause == GAP_SUCCESS)
+ {
+ uint16_t ccc_bit;
+ if (value_size != 2)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_client_read_result_cb: invalid cccd len %d", value_size);
+ return;
+ }
+ LE_ARRAY_TO_UINT16(ccc_bit, p_value);
+
+ if (ccc_bit & GATT_CLIENT_CHAR_CONFIG_INDICATE)
+ {
+ cb_data.cb_content.read_result.data.v4_indicate_cccd = true;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v4_indicate_cccd = false;
+ }
+ }
+ }
+ else
+ {
+ return;
+ }
+ /* Inform application the read result. */
+ if (simp_client_cb)
+ {
+ (*simp_client_cb)(simp_client, conn_id, &cb_data);
+ }
+
+ return;
+}
+
+static void simp_ble_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type,
+ uint16_t handle, uint16_t cause,
+ uint8_t credits)
+{
+ T_SIMP_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = simp_table[conn_id].hdl_cache;
+ cb_data.cb_type = SIMP_CLIENT_CB_TYPE_WRITE_RESULT;
+
+ PROFILE_PRINT_INFO2("simp_ble_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.write_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_SIMBLE_V2_WRITE])
+ {
+ cb_data.cb_content.write_result.type = SIMP_WRITE_V2_WRITE;
+ }
+ else if (handle == hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD])
+ {
+ cb_data.cb_content.write_result.type = SIMP_WRITE_V3_NOTIFY_CCCD;
+ }
+ else if (handle == hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD])
+ {
+ cb_data.cb_content.write_result.type = SIMP_WRITE_V4_INDICATE_CCCD;
+ }
+ else
+ {
+ return;
+ }
+ /* Inform application the write result. */
+ if (simp_client_cb)
+ {
+ (*simp_client_cb)(simp_client, conn_id, &cb_data);
+ }
+
+ return;
+}
+
+static T_APP_RESULT simp_ble_client_notif_ind_result_cb(uint8_t conn_id, bool notify,
+ uint16_t handle,
+ uint16_t value_size, uint8_t *p_value)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ T_SIMP_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = simp_table[conn_id].hdl_cache;
+
+ cb_data.cb_type = SIMP_CLIENT_CB_TYPE_NOTIF_IND_RESULT;
+
+ if (handle == hdl_cache[HDL_SIMBLE_V3_NOTIFY])
+ {
+ cb_data.cb_content.notif_ind_data.type = SIMP_V3_NOTIFY;
+ cb_data.cb_content.notif_ind_data.data.value_size = value_size;
+ cb_data.cb_content.notif_ind_data.data.p_value = p_value;
+ }
+ else if (handle == hdl_cache[HDL_SIMBLE_V4_INDICATE])
+ {
+ cb_data.cb_content.notif_ind_data.type = SIMP_V4_INDICATE;
+ cb_data.cb_content.notif_ind_data.data.value_size = value_size;
+ cb_data.cb_content.notif_ind_data.data.p_value = p_value;
+ }
+ else
+ {
+ return app_result;
+ }
+ /* Inform application the notif/ind result. */
+ if (simp_client_cb)
+ {
+ app_result = (*simp_client_cb)(simp_client, conn_id, &cb_data);
+ }
+
+ return app_result;
+}
+
+static void simp_ble_client_disconnect_cb(uint8_t conn_id)
+{
+ APP_PRINT_INFO0("simp_ble_client_disconnect_cb.");
+ if (conn_id >= simp_link_num)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_client_disconnect_cb: failed invalid conn_id %d", conn_id);
+ return;
+ }
+ memset(&simp_table[conn_id], 0, sizeof(T_SIMP_LINK));
+ return;
+}
+
+/**
+ * @brief Simple BLE Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS simp_ble_client_cbs =
+{
+ simp_ble_client_discover_state_cb, //!< Discovery State callback function pointer
+ simp_ble_client_discover_result_cb, //!< Discovery result callback function pointer
+ simp_ble_client_read_result_cb, //!< Read response callback function pointer
+ simp_ble_client_write_result_cb, //!< Write result callback function pointer
+ simp_ble_client_notif_ind_result_cb, //!< Notify Indicate callback function pointer
+ simp_ble_client_disconnect_cb //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief Add simple ble service client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ simple_ble_client_id = simp_ble_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID simp_ble_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+{
+ uint16_t size;
+ if (link_num > SIMP_MAX_LINKS)
+ {
+ PROFILE_PRINT_ERROR1("simp_ble_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&simp_client, &simp_ble_client_cbs))
+ {
+ simp_client = CLIENT_PROFILE_GENERAL_ID;
+ APP_PRINT_ERROR0("simp_ble_add_client failed");
+ return simp_client;
+ }
+ APP_PRINT_INFO1("simp_ble_add_client: simp_client %d", simp_client);
+
+ /* register callback for profile to inform application that some events happened. */
+ simp_client_cb = app_cb;
+ simp_link_num = link_num;
+ size = simp_link_num * sizeof(T_SIMP_LINK);
+ simp_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ return simp_client;
+}
+
diff --git a/src/ble/profile/client/tps_client.c b/src/ble/profile/client/tps_client.c
new file mode 100644
index 0000000..aaf3265
--- /dev/null
+++ b/src/ble/profile/client/tps_client.c
@@ -0,0 +1,469 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file tps_client.c
+ * @brief
+ * @details
+ * @author ken
+ * @date 2017-12-06
+ * @version v1.0
+ ******************************************************************************
+ */
+
+/** Add Includes here **/
+#include <string.h>
+#include <tps_client.h>
+#include <trace.h>
+#include <os_mem.h>
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+#define GATT_UUID_TX_POWER_SERVICE 0x1804
+#define GATT_UUID_CHAR_TX_LEVEL 0x2A07
+/**
+ * @brief TPS client Link control block definition.
+ */
+typedef struct
+{
+ T_TPS_DISC_STATE disc_state;
+ uint16_t hdl_cache[HDL_TPS_CACHE_LEN];
+} T_TPS_LINK, *P_TPS_LINK;
+
+static P_TPS_LINK tps_table;
+static uint8_t tps_link_num;
+
+/**< TPS client ID. */
+static T_CLIENT_ID tps_client = CLIENT_PROFILE_GENERAL_ID;
+/**< Callback used to send data to app from TPS client layer. */
+static P_FUN_GENERAL_APP_CB tps_client_cb = NULL;
+
+/**
+ * @brief Used by application, to start the discovery procedure of battery service.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ */
+bool tps_start_discovery(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("tps_start_discovery");
+ if (conn_id >= tps_link_num)
+ {
+ PROFILE_PRINT_ERROR1("bas_start_discovery: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ /* First clear handle cache. */
+ memset(&tps_table[conn_id], 0, sizeof(T_TPS_LINK));
+ tps_table[conn_id].disc_state = DISC_TPS_START;
+ if (client_by_uuid_srv_discovery(conn_id, tps_client,
+ GATT_UUID_TX_POWER_SERVICE) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Used by application, to read tx power level.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ *
+ */
+bool tps_read_power_level(uint8_t conn_id)
+{
+ if (conn_id >= tps_link_num)
+ {
+ PROFILE_PRINT_ERROR1("tps_read_battery_level: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (tps_table[conn_id].hdl_cache[HDL_TPS_PARA])
+ {
+ uint16_t handle = tps_table[conn_id].hdl_cache[HDL_TPS_PARA];
+ if (client_attr_read(conn_id, tps_client, handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+ PROFILE_PRINT_ERROR0("tps_read_battery_level: false handle = 0");
+ return false;
+}
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ */
+bool tps_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= tps_link_num)
+ {
+ PROFILE_PRINT_ERROR1("tps_get_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (tps_table[conn_id].disc_state != DISC_TPS_DONE)
+ {
+ PROFILE_PRINT_ERROR1("tps_get_hdl_cache: failed invalid state %d", tps_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_TPS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("tps_get_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(p_hdl_cache, tps_table[conn_id].hdl_cache, len);
+ return true;
+}
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ *
+ */
+bool tps_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= tps_link_num)
+ {
+ PROFILE_PRINT_ERROR1("tps_set_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (tps_table[conn_id].disc_state != DISC_TPS_IDLE)
+ {
+ PROFILE_PRINT_ERROR1("tps_set_hdl_cache: failed invalid state %d", tps_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_TPS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("tps_set_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(tps_table[conn_id].hdl_cache, p_hdl_cache, len);
+ tps_table[conn_id].disc_state = DISC_TPS_DONE;
+ return true;
+}
+
+static bool tps_start_char_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ PROFILE_PRINT_INFO0("tps_start_char_discovery");
+ start_handle = tps_table[conn_id].hdl_cache[HDL_TPS_SRV_START];
+ end_handle = tps_table[conn_id].hdl_cache[HDL_TPS_SRV_END];
+ if (client_all_char_discovery(conn_id, tps_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+//static bool bas_start_char_descriptor_discovery(uint8_t conn_id)
+//{
+// uint16_t start_handle;
+// uint16_t end_handle;
+
+// PROFILE_PRINT_INFO0("bas_start_char_descriptor_discovery");
+// start_handle = bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL];
+// end_handle = bas_table[conn_id].hdl_cache[HDL_BAS_SRV_END];
+// if (client_all_char_descriptor_discovery(conn_id, bas_client, start_handle,
+// end_handle) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// return false;
+//}
+
+static void tps_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state)
+{
+ bool cb_flag = false;
+ T_TPS_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = TPS_CLIENT_CB_TYPE_DISC_STATE;
+
+ PROFILE_PRINT_INFO1("tps_client_discover_state_cb: discovery_state = %d", discovery_state);
+ if (tps_table[conn_id].disc_state == DISC_TPS_START)
+ {
+ switch (discovery_state)
+ {
+ case DISC_STATE_SRV_DONE:
+ /* Indicate that service handle found. Start discover characteristic. */
+ if ((tps_table[conn_id].hdl_cache[HDL_TPS_SRV_START] != 0)
+ || (tps_table[conn_id].hdl_cache[HDL_TPS_SRV_END] != 0))
+ {
+ if (tps_start_char_discovery(conn_id) == false)
+ {
+ tps_table[conn_id].disc_state = DISC_TPS_FAILED;
+ cb_flag = true;
+ }
+ }
+ /* No TPS handle found. Discover procedure complete. */
+ else
+ {
+ tps_table[conn_id].disc_state = DISC_TPS_FAILED;
+ cb_flag = true;
+ }
+ break;
+ case DISC_STATE_CHAR_DONE:
+ tps_table[conn_id].disc_state = DISC_TPS_DONE;
+ cb_flag = true;
+// if (tps_table[conn_id].properties & GATT_CHAR_PROP_NOTIFY)
+// {
+// //discovery cccd
+// if (tps_start_char_descriptor_discovery(conn_id) == false)
+// {
+// tps_table[conn_id].disc_state = DISC_TPS_FAILED;
+// cb_flag = true;
+// }
+// }
+// else
+// {
+// tps_table[conn_id].disc_state = DISC_TPS_DONE;
+// cb_flag = true;
+// }
+ break;
+
+ case DISC_STATE_CHAR_DESCRIPTOR_DONE:
+// bas_table[conn_id].disc_state = DISC_BAS_DONE;
+// cb_flag = true;
+ break;
+
+ case DISC_STATE_FAILED:
+ tps_table[conn_id].disc_state = DISC_TPS_FAILED;
+ cb_flag = true;
+ break;
+
+ default:
+ PROFILE_PRINT_ERROR0("Invalid Discovery State!");
+ break;
+ }
+ }
+
+ /* Send discover state to application if needed. */
+ if (cb_flag && tps_client_cb)
+ {
+ cb_data.cb_content.disc_state = tps_table[conn_id].disc_state;
+ (*tps_client_cb)(tps_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+
+static void tps_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ PROFILE_PRINT_INFO1("tps_client_discover_result_cb: result_type = %d", result_type);
+ if (tps_table[conn_id].disc_state == DISC_TPS_START)
+ {
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ tps_table[conn_id].hdl_cache[HDL_TPS_SRV_START] =
+ result_data.p_srv_disc_data->att_handle;
+ tps_table[conn_id].hdl_cache[HDL_TPS_SRV_END] =
+ result_data.p_srv_disc_data->end_group_handle;
+ break;
+
+ case DISC_RESULT_CHAR_UUID16:
+ {
+ uint16_t handle;
+ handle = result_data.p_char_uuid16_disc_data->value_handle;
+ if (result_data.p_char_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_TX_LEVEL)
+ {
+ tps_table[conn_id].hdl_cache[HDL_TPS_PARA] = handle;
+ }
+ }
+ break;
+
+ case DISC_RESULT_CHAR_DESC_UUID16:
+// if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG)
+// {
+// bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD] =
+// result_data.p_char_desc_uuid16_disc_data->handle;
+// }
+ break;
+
+ default:
+ PROFILE_PRINT_ERROR0("Invalid Discovery Result Type!");
+ break;
+ }
+ }
+
+ return;
+}
+
+//static void bas_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type,
+// uint16_t handle,
+// uint16_t cause,
+// uint8_t credits)
+//{
+// T_BAS_CLIENT_CB_DATA cb_data;
+// uint16_t *hdl_cache;
+// hdl_cache = bas_table[conn_id].hdl_cache;
+// cb_data.cb_type = BAS_CLIENT_CB_TYPE_WRITE_RESULT;
+
+// PROFILE_PRINT_INFO2("bas_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+// cb_data.cb_content.write_result.cause = cause;
+
+// if (handle == hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD])
+// {
+// if (bas_table[conn_id].write_notify_value)
+// {
+// cb_data.cb_content.write_result.type = BAS_WRITE_NOTIFY_ENABLE;
+// }
+// else
+// {
+// cb_data.cb_content.write_result.type = BAS_WRITE_NOTIFY_DISABLE;
+// }
+// }
+// else
+// {
+// return;
+// }
+
+// if (bas_client_cb)
+// {
+// (*bas_client_cb)(bas_client, conn_id, &cb_data);
+// }
+// return;
+//}
+
+static void tps_client_read_result_cb(uint8_t conn_id, uint16_t cause,
+ uint16_t handle, uint16_t value_size, uint8_t *p_value)
+{
+ T_TPS_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = tps_table[conn_id].hdl_cache;
+ cb_data.cb_type = TPS_CLIENT_CB_TYPE_READ_RESULT;
+
+ PROFILE_PRINT_INFO2("tps_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.read_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_TPS_PARA])
+ {
+ cb_data.cb_content.read_result.type = TPS_READ_PARA;
+ if (cause == GAP_SUCCESS)
+ {
+ if (value_size != 1)
+ {
+ PROFILE_PRINT_ERROR1("tps_client_read_result_cb: invalid battery value len %d", value_size);
+ return;
+ }
+ cb_data.cb_content.read_result.data.txpower_level = *p_value;
+ }
+ }
+ else
+ {
+ return;
+ }
+
+ if (tps_client_cb)
+ {
+ (*tps_client_cb)(tps_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+//static T_APP_RESULT tps_client_notify_ind_cb(uint8_t conn_id, bool notify, uint16_t handle,
+// uint16_t value_size, uint8_t *p_value)
+//{
+// T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+// T_BAS_CLIENT_CB_DATA cb_data;
+// uint16_t *hdl_cache;
+
+// hdl_cache = bas_table[conn_id].hdl_cache;
+// cb_data.cb_type = BAS_CLIENT_CB_TYPE_NOTIF_IND_RESULT;
+
+// if (handle == hdl_cache[HDL_BAS_BATTERY_LEVEL])
+// {
+// cb_data.cb_content.notify_data.battery_level = *p_value;
+// }
+// else
+// {
+// return APP_RESULT_SUCCESS;
+// }
+
+// if (bas_client_cb)
+// {
+// app_result = (*bas_client_cb)(bas_client, conn_id, &cb_data);
+// }
+
+// return app_result;
+//}
+
+static void tps_client_disc_cb(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("tps_client_disc_cb.");
+ if (conn_id >= tps_link_num)
+ {
+ PROFILE_PRINT_ERROR1("tps_client_disc_cb: failed invalid conn_id %d", conn_id);
+ return;
+ }
+ memset(&tps_table[conn_id], 0, sizeof(T_TPS_LINK));
+ return;
+}
+/**
+ * @brief BAS Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS tps_client_cbs =
+{
+ tps_client_discover_state_cb, //!< Discovery State callback function pointer
+ tps_client_discover_result_cb, //!< Discovery result callback function pointer
+ tps_client_read_result_cb, //!< Read response callback function pointer
+ NULL,//bas_client_write_result_cb, //!< Write result callback function pointer
+ NULL,//bas_client_notify_ind_cb, //!< Notify Indicate callback function pointer
+ tps_client_disc_cb //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief Add tps client to application.
+ * @param[in] app_cb pointer of app callback function to handle specific client module data.
+ * @param[in] link_num initialize link num.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ tps_client_id = tps_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID tps_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+{
+ uint16_t size;
+ if (link_num > TPS_MAX_LINKS)
+ {
+ PROFILE_PRINT_ERROR1("tps_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&tps_client, &tps_client_cbs))
+ {
+ tps_client = CLIENT_PROFILE_GENERAL_ID;
+ PROFILE_PRINT_ERROR0("tps_add_client:register fail");
+ return tps_client;
+ }
+ PROFILE_PRINT_INFO1("tps_add_client: client id %d", tps_client);
+
+ /* register callback for profile to inform application that some events happened. */
+ tps_client_cb = app_cb;
+ tps_link_num = link_num;
+ size = tps_link_num * sizeof(T_TPS_LINK);
+ tps_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ return tps_client;
+}
+
diff --git a/src/ble/profile/server/atvv_service.c b/src/ble/profile/server/atvv_service.c
new file mode 100644
index 0000000..d9fea47
--- /dev/null
+++ b/src/ble/profile/server/atvv_service.c
@@ -0,0 +1,392 @@
+enum { __FILE_NUM__ = 0 };
+
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file atvv_service.c
+* @brief ATV voice service source file.
+* @details Interfaces to access ATV voice service.
+* @author Chenjie Jin
+* @date 2020-03-11
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "board.h"
+#include "stdint.h"
+#include "string.h"
+#include "trace.h"
+#include "atvv_service.h"
+
+#if (VOICE_FLOW_SEL == ATV_GOOGLE_VOICE_FLOW)
+
+/*============================================================================*
+ * Global Variables
+ *============================================================================*/
+T_ATVV_GLOBAL_DATA atvv_global_data;
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+static P_FUN_SERVER_GENERAL_CB pfn_atvv_cb = NULL;
+
+const uint8_t GATT_UUID_ATVV_SERVICE[16] = {0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0x01, 0x00, 0x5E, 0xAB};
+
+/**< @brief profile/service definition. */
+const T_ATTRIB_APPL atvv_attr_tbl[] =
+{
+ /* <<Primary Service>>, .. 0*/
+ {
+ (ATTRIB_FLAG_VOID | ATTRIB_FLAG_LE), /* wFlags */
+ {
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE), /* bTypeValue */
+ },
+ UUID_128BIT_SIZE, /* bValueLen */
+ (void *)GATT_UUID_ATVV_SERVICE, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* ATVV_CHAR_TX */
+ /* Characteristic Definition, 1 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* Characteristic Value, 2 */
+ {
+ ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* wFlags */
+ { /* bTypeValue */
+ GATT_UUID_ATV_CHAR_TX
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_WRITE /* wPermissions */
+ },
+
+ /* ATVV_CHAR_RX */
+ /* Characteristic, 3 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* Characteristic Value, 4 */
+ {
+ ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* wFlags */
+ { /* bTypeValue */
+ GATT_UUID_ATV_CHAR_RX
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* client characteristic configuration, 5 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* wFlags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ },
+
+ /* ATVV_CHAR_CTL */
+ /* Characteristic, 6 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* Characteristic Value, 7 */
+ {
+ ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* wFlags */
+ { /* bTypeValue */
+ GATT_UUID_ATV_CHAR_CTL
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* client characteristic configuration, 8 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* wFlags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ }
+};
+/**< @brief ATV Voice service size definition. */
+const int atvv_attr_tbl_size = sizeof(atvv_attr_tbl);
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param conn_id Connection ID.
+ * @param service_id ServiceID to be read.
+ * @param attrib_index Attribute index of getting characteristic data.
+ * @param offset Offset of characteritic to be read.
+ * @param p_length Length of getting characteristic data.
+ * @param pp_value Pointer to pointer of characteristic value to be read.
+ * @return T_APP_RESULT
+*/
+T_APP_RESULT attv_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ *p_length = 0;
+
+ PROFILE_PRINT_INFO2("bas_attr_read_cb attrib_index = %d offset %x", attrib_index, offset);
+
+ switch (attrib_index)
+ {
+ case GATT_SVC_ATVV_CHAR_RX_VALUE_INDEX:
+ {
+ T_ATVV_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = ATVV_READ_CHAR_RX_INDEX;
+ if (pfn_atvv_cb)
+ {
+ cause = pfn_atvv_cb(service_id, (void *)&callback_data);
+ }
+
+ if (cause != APP_RESULT_SUCCESS)
+ {
+ memset(atvv_global_data.char_rx_data_buff, 0, ATVV_CHAR_RX_DATA_LEN);
+ }
+ *pp_value = atvv_global_data.char_rx_data_buff;
+ *p_length = ATVV_CHAR_RX_DATA_LEN;
+ }
+ break;
+
+ case GATT_SVC_ATVV_CHAR_CTL_VALUE_INDEX:
+ {
+ T_ATVV_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = ATVV_READ_CHAR_CTL_INDEX;
+ if (pfn_atvv_cb)
+ {
+ cause = pfn_atvv_cb(service_id, (void *)&callback_data);
+ }
+
+ if (cause != APP_RESULT_SUCCESS)
+ {
+ memset(atvv_global_data.char_ctl_data_buff, 0, ATVV_CHAR_CTL_DATA_LEN);
+ }
+
+ *pp_value = atvv_global_data.char_ctl_data_buff;
+ *p_length = ATVV_CHAR_CTL_DATA_LEN;
+ }
+ break;
+
+ default:
+ {
+ PROFILE_PRINT_ERROR1("attv_attr_read_cb attrib_index = %d not found", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ break;
+ }
+ return (cause);
+}
+
+void atvv_write_post_callback(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t length, uint8_t *p_value)
+{
+ T_ATVV_CALLBACK_DATA callback_data;
+
+ APP_PRINT_INFO4("atvv_write_post_callback: conn_id %d, service_id %d, attrib_index 0x%x, length %d",
+ conn_id, service_id, attrib_index, length);
+
+ if (GATT_SVC_ATVV_CHAR_TX_VALUE_INDEX == attrib_index)
+ {
+ /* Notify Application. */
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_type = ATVV_WRITE_CHAR_TX_INDEX;
+ callback_data.msg_data.write.write_parameter.report_data.len = length;
+ callback_data.msg_data.write.write_parameter.report_data.report = p_value;
+
+ if (pfn_atvv_cb)
+ {
+ pfn_atvv_cb(service_id, (void *)&callback_data);
+ }
+ }
+}
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID to be written.
+ * @param[in] attrib_index Attribute index of characteristic.
+ * @param[in] write_type Write type.
+ * @param[in] length Length of writing characteristic data.
+ * @param[in] p_value Pointer to characteristic data.
+ * @param[in] p_write_ind_post_proc Function pointer after ias_attr_write_cb.
+ * @return TProfileResult
+*/
+T_APP_RESULT atvv_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+
+ APP_PRINT_INFO1("atvv_attr_write_cb write_type = 0x%x", write_type);
+
+ *p_write_ind_post_proc = atvv_write_post_callback;
+
+ if (!p_value)
+ {
+ cause = APP_RESULT_INVALID_PDU;
+ }
+ else if (attrib_index == GATT_SVC_ATVV_CHAR_TX_VALUE_INDEX)
+ {
+ cause = APP_RESULT_SUCCESS;
+ }
+ else
+ {
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+
+ return cause;
+}
+
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param conn_id Connection ID.
+ * @param service_id Service ID.
+ * @param index Attribute index of characteristic data.
+ * @param ccc_bits CCCD bits from stack.
+ * @return None
+*/
+void atvv_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ T_ATVV_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ bool handle = true;
+
+ PROFILE_PRINT_INFO2("atvv_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits);
+ switch (index)
+ {
+ case GATT_SVC_ATVV_CHAR_RX_CCCD_INDEX:
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_data.notification_indification_index = ATVV_CHAR_RX_NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.notification_indification_index = ATVV_CHAR_RX_NOTIFY_DISABLE;
+ }
+ break;
+
+ case GATT_SVC_ATVV_CHAR_CTL_CCCD_INDEX:
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_data.notification_indification_index = ATVV_CHAR_CTL_NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.notification_indification_index = ATVV_CHAR_CTL_NOTIFY_DISABLE;
+ }
+ break;
+
+ default:
+ handle = false;
+ break;
+ }
+ /* Notify Application. */
+ if (pfn_atvv_cb && (handle == true))
+ {
+ pfn_atvv_cb(service_id, (void *)&callback_data);
+ }
+
+ return;
+}
+
+/**
+ * @brief ATV Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS atvv_cbs =
+{
+ attv_attr_read_cb, // Read callback function pointer
+ atvv_attr_write_cb, // Write callback function pointer
+ atvv_cccd_update_cb // CCCD update callback function pointer
+};
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/**
+ * @brief add ATV voice service to application.
+ *
+ * @param[in] pFunc pointer of app callback function called by profile.
+ * @return service ID auto generated by profile layer.
+ * @retval ServiceId
+ */
+uint8_t atvv_add_service(void *p_func)
+{
+ uint8_t service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)atvv_attr_tbl,
+ atvv_attr_tbl_size,
+ atvv_cbs))
+ {
+ APP_PRINT_ERROR1("atvv_add_service: ServiceId %d", service_id);
+ service_id = 0xff;
+ }
+
+ pfn_atvv_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
+#endif /* (VOICE_FLOW_SEL == ATV_GOOGLE_VOICE_FLOW) */
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/ble/profile/server/bas.c b/src/ble/profile/server/bas.c
new file mode 100644
index 0000000..0438f44
--- /dev/null
+++ b/src/ble/profile/server/bas.c
@@ -0,0 +1,374 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file bas.c
+* @brief Battery service source file.
+* @details Interfaces to access Battery service.
+* @author
+* @date
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "stdint.h"
+#include "string.h"
+#include "trace.h"
+#include "profile_server.h"
+#include "bas.h"
+#include "bas_config.h"
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define GATT_UUID_BATTERY 0x180F
+#define GATT_UUID_CHAR_BAS_LEVEL 0x2A19
+
+#define GATT_SVC_BAS_BATTERY_LEVEL_INDEX 2 /**< @brief Index for battery level chars's value */
+#define GATT_SVC_BAS_CHAR_CCCD_INDEX 3 /**< @brief CCCD Index for battery level chars's value */
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+/**< BatteryLevel value. */
+static uint8_t battery_level = 0;
+static bool bas_read_battery_level_pending = false;
+/**< Function pointer used to send event to application from pxp profile. */
+/**< Initiated in PXP_AddService. */
+static P_FUN_SERVER_GENERAL_CB pfn_bas_cb = NULL;
+
+/**< @brief profile/service definition. */
+static const T_ATTRIB_APPL bas_attr_tbl[] =
+{
+ /*----------------- Battery Service -------------------*/
+ /* <<Primary Service>>, .. */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_BATTERY), /* service UUID */
+ HI_WORD(GATT_UUID_BATTERY)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* p_value_context */
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* <<Characteristic>>, .. */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+#if BAS_BATTERY_LEVEL_NOTIFY_SUPPORT
+ (GATT_CHAR_PROP_READ | /* characteristic properties */
+ GATT_CHAR_PROP_NOTIFY)
+#else
+ GATT_CHAR_PROP_READ
+#endif
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ /* Battery Level value */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_BAS_LEVEL),
+ HI_WORD(GATT_UUID_CHAR_BAS_LEVEL)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ }
+#if BAS_BATTERY_LEVEL_NOTIFY_SUPPORT
+ ,
+ /* client characteristic configuration */
+ {
+ ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */
+ }
+#endif
+};
+
+/**< @brief Battery service size definition. */
+const static uint16_t bas_attr_tbl_size = sizeof(bas_attr_tbl);
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/**
+ * @brief Set a battery service parameter.
+ *
+ * NOTE: You can call this function with a battery service parameter type and it will set the
+ * battery service parameter. Battery service parameters are defined in @ref T_BAS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Battery service parameter type: @ref T_BAS_PARAM_TYPE
+ * @param[in] length Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t battery_level = 80;
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ * \endcode
+ */
+bool bas_set_parameter(T_BAS_PARAM_TYPE param_type, uint8_t length, uint8_t *p_value)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ default:
+ {
+ ret = false;
+ PROFILE_PRINT_ERROR1("bas_set_parameter: unknown param_type 0x%02x", param_type);
+ }
+ break;
+
+ case BAS_PARAM_BATTERY_LEVEL:
+ {
+ if (length != sizeof(uint8_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ battery_level = p_value[0];
+ }
+ }
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Send notify battery level notification data .
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] battery_level Battery level value.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t battery_level = 90;
+ bas_battery_level_value_notify(conn_id, bas_id, battery_level);
+ }
+ * \endcode
+ */
+bool bas_battery_level_value_notify(uint8_t conn_id, uint8_t service_id, uint8_t battery_level)
+{
+ return server_send_data(conn_id, service_id, GATT_SVC_BAS_BATTERY_LEVEL_INDEX, &battery_level,
+ sizeof(battery_level), GATT_PDU_TYPE_ANY);
+}
+
+/**
+ * @brief Confirm for read battery level value request.
+ *
+ * @param[in] conn_id Callback when service attribute was read/write.
+ * @param[in] service_id Callback when service attribute was read/write.
+ * @param[in] battery_level Callback when service attribute was read/write.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t battery_level = 90;
+ bas_battery_level_value_read_confirm(conn_id, bas_id, battery_level);
+ }
+ * \endcode
+ */
+bool bas_battery_level_value_read_confirm(uint8_t conn_id, uint8_t service_id,
+ uint8_t battery_level)
+{
+ if (bas_read_battery_level_pending == true)
+ {
+ bas_read_battery_level_pending = false;
+ return server_attr_read_confirm(conn_id, service_id, GATT_SVC_BAS_BATTERY_LEVEL_INDEX,
+ &battery_level, sizeof(battery_level), APP_RESULT_SUCCESS);
+ }
+ else
+ {
+ return false;
+ }
+}
+
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param conn_id Connection ID.
+ * @param service_id ServiceID to be read.
+ * @param attrib_index Attribute index of getting characteristic data.
+ * @param offset Offset of characteritic to be read.
+ * @param p_length Length of getting characteristic data.
+ * @param pp_value Pointer to pointer of characteristic value to be read.
+ * @return T_APP_RESULT
+*/
+T_APP_RESULT bas_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ *p_length = 0;
+
+ PROFILE_PRINT_INFO2("bas_attr_read_cb: attrib_index %d offset %d", attrib_index, offset);
+
+ switch (attrib_index)
+ {
+ default:
+ {
+ PROFILE_PRINT_ERROR0("bas_attr_read_cb: unknown attrib_index");
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ break;
+
+ case GATT_SVC_BAS_BATTERY_LEVEL_INDEX:
+ {
+ T_BAS_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_data.read_value_index = BAS_READ_BATTERY_LEVEL;
+ cause = pfn_bas_cb(service_id, (void *)&callback_data);
+ if (cause == APP_RESULT_PENDING)
+ {
+ bas_read_battery_level_pending = true;
+ }
+
+ *pp_value = &battery_level;
+ *p_length = sizeof(battery_level);
+ }
+ break;
+ }
+ return (cause);
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param conn_id Connection ID.
+ * @param service_id Service ID.
+ * @param index Attribute index of characteristic data.
+ * @param ccc_bits CCCD bits from stack.
+ * @return None
+*/
+void bas_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ T_BAS_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.conn_id = conn_id;
+ bool handle = true;
+ PROFILE_PRINT_INFO2("bas_cccd_update_cb: index %d ccc_bits 0x%04x", index, ccc_bits);
+
+ switch (index)
+ {
+ case GATT_SVC_BAS_CHAR_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_data.notification_indification_index = BAS_NOTIFY_BATTERY_LEVEL_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.notification_indification_index = BAS_NOTIFY_BATTERY_LEVEL_DISABLE;
+ }
+ break;
+ }
+ default:
+ {
+ handle = false;
+ break;
+ }
+
+ }
+
+ if (pfn_bas_cb && (handle == true))
+ {
+ pfn_bas_cb(service_id, (void *)&callback_data);
+ }
+
+ return;
+}
+
+/**
+ * @brief BAS Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS bas_cbs =
+{
+ bas_attr_read_cb, // Read callback function pointer
+ NULL, // Write callback function pointer
+ bas_cccd_update_cb // CCCD update callback function pointer
+};
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/**
+ * @brief Add battery service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ bas_id = bas_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID bas_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)bas_attr_tbl,
+ bas_attr_tbl_size,
+ bas_cbs))
+ {
+ PROFILE_PRINT_ERROR1("bas_add_service: service_id %d", service_id);
+ service_id = 0xff;
+ }
+ pfn_bas_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/ble/profile/server/cscs.c b/src/ble/profile/server/cscs.c
new file mode 100644
index 0000000..0e586f5
--- /dev/null
+++ b/src/ble/profile/server/cscs.c
@@ -0,0 +1,956 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file cscs.c
+* @brief CSC profile interfaces called in profile.c.
+* @details Interfaces to get and put csc characteristics value and csc control point procedure.
+* @author ethan_su
+* @date 2017-10-11
+* @version v1.0
+*********************************************************************************************************
+*/
+#include "trace.h"
+#include <string.h>
+#include "gatt.h"
+#include "cscs.h"
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+typedef struct
+{
+ uint8_t csc_measurement_notify_enable: 1;
+ uint8_t sc_cp_indicate_enable: 1;
+ uint8_t rfu: 6;
+} CSCS_NOTIFY_INDICATE_FLAG;
+
+/** @brief CSC service related UUIDs. */
+#define GATT_UUID_CSCS 0x1816
+#define GATT_UUID_CHAR_CSCS_MEASUREMENT 0x2A5B
+#define GATT_UUID_CHAR_CSCS_FEATURE 0x2A5C
+#define GATT_UUID_CHAR_SENSOR_LOCATION 0x2A5D
+#define GATT_UUID_CHAR_SC_CONTROL_POINT 0x2A55
+
+
+/**< CSC measurement data. */
+static T_CSCS_MEASUREMENT cscs_measurement;
+/**< CSC feature that CSC service supported, can be configured by user. */
+static uint16_t cscs_feature;
+/**< CSC current sensor location, where the CSC sensor located. */
+static uint8_t cscs_cur_sens_location;
+/**< CSC supported sensor location list, can be configured by user. */
+static uint16_t cscs_sens_loc_list;
+/**< CSC control point data. */
+static T_CSCS_CONTROL_POINT cscs_control_point = {0};
+/**< CSC control point indication enable flag. */
+static CSCS_NOTIFY_INDICATE_FLAG cscs_notify_indicate_flag = {0};
+/**< Function pointer used to send event to application from CSC profile. Initiated in cscs_add_service. */
+static P_FUN_SERVER_GENERAL_CB pfn_cscs_cb = NULL;
+
+/**< @brief profile/service definition. */
+const T_ATTRIB_APPL cscs_attr_tbl[] =
+{
+ /*-------------------------- CSC Service ---------------------------*/
+ /* <<Primary Service>>, .. Index 0 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_CSCS), /* service UUID */
+ HI_WORD(GATT_UUID_CSCS)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. Index 1 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /*--- CSC Measurement characteristic value --- Index 2 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CSCS_MEASUREMENT),
+ HI_WORD(GATT_UUID_CHAR_CSCS_MEASUREMENT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_NONE /* wPermissions */
+ },
+ /* client characteristic configuration Index 3 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* wFlags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. Index 4 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /*--- CSC Features characteristic value --- Index 5 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CSCS_FEATURE),
+ HI_WORD(GATT_UUID_CHAR_CSCS_FEATURE),
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ }
+
+#ifdef CSCS_MULTIPLE_SENSOR_LOCATIONS_SUPPORT
+ ,
+ /* <<Characteristic>>, .. Index 6 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /*--- CSC sensor location characteristic value --- Index 7 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_SENSOR_LOCATION),
+ HI_WORD(GATT_UUID_CHAR_SENSOR_LOCATION)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ }
+#endif
+
+#ifdef CSCS_SC_CONTROL_POINT_SUPPORT
+ ,
+ /* <<Characteristic>>, .. Index 8 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_WRITE | /* characteristic properties */
+ GATT_CHAR_PROP_INDICATE)
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /*--- CSC SC Control Point value --- Index 9 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_SC_CONTROL_POINT),
+ HI_WORD(GATT_UUID_CHAR_SC_CONTROL_POINT)
+ },
+ 0, /* bValueLen, 0 : variable length */
+ NULL,
+ GATT_PERM_WRITE /* wPermissions */
+ },
+ /* client characteristic configuration Index 10 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* wFlags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ }
+#endif
+
+};
+/**< @brief CSC service size definition. */
+const int32_t cscs_attr_tbl_size = sizeof(cscs_attr_tbl);
+
+/**
+ * @brief Set a cycling speed and cadence service parameter.
+ *
+ * NOTE: You can call this function with a cycling speed and cadence service parameter type and it will set the
+ * cycling speed and cadence service parameter. Cycling speed and cadence service parameters are defined in @ref T_CSCS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Cycling speed and cadence service parameter type: @ref T_CSCS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and will be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ cscs_set_parameter(CSCS_PARAM_CTL_PNT_PROG_CLR, 0, NULL);
+ }
+ * \endcode
+ */
+bool cscs_set_parameter(T_CSCS_PARAM_TYPE param_type, uint8_t len, void *p_value)
+{
+ bool ret = true;
+ uint8_t inc_flag = cscs_measurement.value[0];
+
+ switch (param_type)
+ {
+ default:
+ ret = false;
+ break;
+ case CSCS_PARAM_CSCS_FEATURE:
+ memcpy(&cscs_feature, p_value, 2);
+ break;
+
+ case CSCS_PARAM_INC_FLAG:
+ cscs_measurement.value[0] = *(uint8_t *)p_value;
+ inc_flag = cscs_measurement.value[0];
+ cscs_measurement.cur_length = 1;
+ if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK)
+ {
+ cscs_measurement.cur_length += 6;
+ }
+ if (inc_flag & CSCS_INC_CRANK_REVOL_MASK)
+ {
+ cscs_measurement.cur_length += 4;
+ }
+ break;
+ case CSCS_PARAM_WHEEL_REVOL:
+ if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK)
+ {
+ LE_UINT32_TO_ARRAY(cscs_measurement.value + 1, *(uint32_t *)p_value);
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case CSCS_PARAM_WHEEL_EVT_TIME:
+ if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK)
+ {
+ LE_UINT16_TO_ARRAY(cscs_measurement.value + 5, *(uint16_t *)p_value);
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case CSCS_PARAM_CRANK_REVOL:
+ if (inc_flag & CSCS_INC_CRANK_REVOL_MASK)
+ {
+ if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK)
+ {
+ LE_UINT16_TO_ARRAY(cscs_measurement.value + 7, *(uint16_t *)p_value);
+ }
+ else
+ {
+ LE_UINT16_TO_ARRAY(cscs_measurement.value + 1, *(uint16_t *)p_value);
+ }
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case CSCS_PARAM_CRANK_EVT_TIME:
+ if (inc_flag & CSCS_INC_CRANK_REVOL_MASK)
+ {
+ if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK)
+ {
+ LE_UINT16_TO_ARRAY(cscs_measurement.value + 9, *(uint16_t *)p_value);
+ }
+ else
+ {
+ LE_UINT16_TO_ARRAY(cscs_measurement.value + 3, *(uint16_t *)p_value);
+ }
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case CSCS_PARAM_SENSOR_LOC:
+ cscs_cur_sens_location = *(uint8_t *)p_value;
+ break;
+ case CSCS_PARAM_CTL_PNT_PROG_CLR:
+ cscs_control_point.value[0] = CSCS_CP_OPCODE_RESERVED;
+ break;
+ }
+
+ if (!ret)
+ {
+ PROFILE_PRINT_INFO0("CSC parameter set failed\n");
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Get a cycling speed and cadence parameter.
+ *
+ * NOTE: You can call this function with a cycling speed and cadence parameter type and it will get a
+ * gulcose parameter. Cycling speed and cadence service parameters are defined in @ref T_CSCS_PARAM_TYPE.
+ *
+ * @param[in] param_type Cycling speed and cadence parameter type: @ref T_CSCS_PARAM_TYPE
+ * @param[in,out] p_value Pointer to the location to get the parameter value. This is dependent on
+ * the parameter type and will be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_INVALID_PARAM Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ int record_num;
+ gls_get_parameter(GLS_PARAM_RECORD_NUM, &len, &record_num);
+ }
+ * \endcode
+ */
+bool cscs_get_parameter(T_CSCS_PARAM_TYPE param_type, void *p_value)
+{
+ bool ret = true;
+ uint8_t inc_flag = cscs_measurement.value[0];
+
+ switch (param_type)
+ {
+ default:
+ ret = false;
+ break;
+ case CSCS_PARAM_INC_FLAG:
+ *(uint8_t *)p_value = cscs_measurement.value[0];
+ break;
+ case CSCS_PARAM_WHEEL_REVOL:
+ if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK)
+ {
+ LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, cscs_measurement.value + 1);
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case CSCS_PARAM_WHEEL_EVT_TIME:
+ if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK)
+ {
+ LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, cscs_measurement.value + 5);
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case CSCS_PARAM_CRANK_REVOL:
+ if (inc_flag & CSCS_INC_CRANK_REVOL_MASK)
+ {
+ if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK)
+ {
+ LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, cscs_measurement.value + 7);
+ }
+ else
+ {
+ LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, cscs_measurement.value + 1);
+ }
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case CSCS_PARAM_CRANK_EVT_TIME:
+ if (inc_flag & CSCS_INC_CRANK_REVOL_MASK)
+ {
+ if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK)
+ {
+ LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, cscs_measurement.value + 9);
+ }
+ else
+ {
+ LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, cscs_measurement.value + 3);
+ }
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case CSCS_PARAM_SENSOR_LOC:
+ *(uint8_t *)p_value = cscs_cur_sens_location;
+ break;
+ }
+
+ if (!ret)
+ {
+ PROFILE_PRINT_INFO0("cscs parameter get failed\n");
+ }
+
+ return ret;
+}
+
+/**
+ * @brief display control point response.
+ *
+ * @param cscs_ctl_pnt_ptr pointer to CSC control point data.
+ * @return none
+ * @retval void
+*/
+static void cscs_ctl_pnt_display_rsp(T_CSCS_CONTROL_POINT *cscs_ctl_pnt_ptr)
+{
+ PROFILE_PRINT_INFO1("cscs cp response: req_op_code=0x%x", cscs_ctl_pnt_ptr->value[1]);
+ PROFILE_PRINT_INFO1("rsp_code=0x%x", cscs_ctl_pnt_ptr->value[2]);
+}
+
+/**
+ * @brief whether the sensor location supported.
+ *
+ * @param[in] sens_location sensor location to be judged(CSC sensor support or not).
+ * @return support result.
+ * @retval 1 support
+ * @retval 0 not support
+*/
+static bool cscs_sens_loc_supported(uint8_t sens_location)
+{
+ uint8_t result = false;
+ if ((cscs_sens_loc_list >> sens_location) & 0x0001)
+ {
+ result = true;
+ }
+
+ return (result);
+}
+
+/**
+ * @brief set cumulative response.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] serviceID
+ * @return none
+ * @retval void
+*/
+static void cscs_ctl_pnt_set_cumulative(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code)
+{
+ uint8_t op_code = CSCS_CP_OPCODE_SET_CUMULATIVE;
+ cscs_ctl_pnt_indicate(conn_id, service_id, op_code, rsp_code);
+}
+
+/**
+ * @brief update sensor location response.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param[in] rsp_code Response Code.
+ * @return none
+ * @retval void
+*/
+static void cscs_ctl_pnt_update_sens_loc(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code)
+{
+ uint8_t op_code = CSCS_CP_OPCODE_UPDATE_SENS_LOC;
+ cscs_ctl_pnt_indicate(conn_id, service_id, op_code, rsp_code);
+}
+
+/**
+ * @brief supported sensor location response.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param[in] rsp_code Response Code.
+ * @return none
+ * @retval void
+*/
+static void cscs_ctl_pnt_req_sens_loc_list(uint8_t conn_id, T_SERVER_ID service_id,
+ uint8_t rsp_code)
+{
+ uint8_t op_code = CSCS_CP_OPCODE_REQ_SENS_LOC_LIST;
+ cscs_ctl_pnt_indicate(conn_id, service_id, op_code, rsp_code);
+}
+
+static uint8_t cscs_handle_ctl_pnt_proc2(uint8_t service_id, uint16_t write_length,
+ uint8_t *p_value)
+{
+ T_CSCS_CALLBACK_DATA callback_data;
+ uint8_t resp_code = CSCS_CP_RSPCODE_SUCCESS;
+ uint16_t parameter_length = 0;
+ memcpy(cscs_control_point.value, p_value, write_length);
+ if (write_length >= 1)
+ {
+ parameter_length = write_length - 1;
+ }
+
+ PROFILE_PRINT_INFO1("cscs_handle_ctl_pnt_proc2 request: op_code=0x%x", cscs_control_point.value[0]);
+
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.opcode = cscs_control_point.value[0];
+
+ switch (cscs_control_point.value[0])
+ {
+
+ case CSCS_CP_OPCODE_SET_CUMULATIVE:
+ {
+ if (parameter_length == 4)
+ {
+ memcpy(&callback_data.msg_data.write.cp_parameter.cumulative_value,
+ &cscs_control_point.value[1], 4);
+ }
+ else
+ {
+ resp_code = CSCS_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+
+ break;
+
+ case CSCS_CP_OPCODE_UPDATE_SENS_LOC:
+ {
+ if (parameter_length == 1)
+ {
+ memcpy(&callback_data.msg_data.write.cp_parameter.sensor_location_value,
+ &cscs_control_point.value[1], 1);
+ if (callback_data.msg_data.write.cp_parameter.sensor_location_value >= CSCS_SENSOR_LOC_MAX)
+ {
+ resp_code = CSCS_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+ else
+ {
+ resp_code = CSCS_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+ break;
+
+ case CSCS_CP_OPCODE_REQ_SENS_LOC_LIST:
+ {
+ if (parameter_length == 0)
+ {
+ }
+ else
+ {
+ resp_code = CSCS_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+ break;
+
+ default:
+ {
+ resp_code = CSCS_CP_RSPCODE_OPCODE_UNSUPPORT;
+ }
+ break;
+ }
+
+ if (resp_code == CSCS_CP_RSPCODE_SUCCESS)
+ {
+ pfn_cscs_cb(service_id, (void *)&callback_data);
+ }
+ return resp_code;
+}
+
+
+/**
+ * @brief handle control point write (request).
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param[in] write_length Write request data length.
+ * @param[in] value_ptr Pointer to write request data.
+ * @return none
+ * @retval void
+*/
+static void cscs_ctl_pnt_handle_req(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t write_length, uint8_t *p_value)
+{
+ uint8_t resp_code = CSCS_CP_RSPCODE_SUCCESS;
+
+ memcpy(cscs_control_point.value, p_value, write_length);
+ cscs_control_point.cur_length = write_length;
+
+ PROFILE_PRINT_INFO1("csccp request: op_code=0x%x", cscs_control_point.value[0]);
+
+ resp_code = cscs_handle_ctl_pnt_proc2(service_id, write_length, p_value);
+
+ if (resp_code == CSCS_CP_RSPCODE_SUCCESS)
+ {
+ switch (cscs_control_point.value[0])
+ {
+ default:
+ resp_code = CSCS_CP_RSPCODE_OPCODE_UNSUPPORT;
+ break;
+ case CSCS_CP_OPCODE_SET_CUMULATIVE:
+ if ((cscs_feature & CSCS_SUPPORT_WHEEL_REVOL_MASK) &&
+ (cscs_measurement.value[0] & CSCS_INC_WHEEL_REVOL_MASK))
+ {
+ cscs_ctl_pnt_set_cumulative(conn_id, service_id, resp_code);
+ return;
+ }
+ break;
+ case CSCS_CP_OPCODE_UPDATE_SENS_LOC:
+ if (cscs_feature & CSCS_SUPPORT_MULTI_SENSOR_MASK)
+ {
+ cscs_ctl_pnt_update_sens_loc(conn_id, service_id, resp_code);
+ return;
+ }
+ break;
+ case CSCS_CP_OPCODE_REQ_SENS_LOC_LIST:
+ if (cscs_feature & CSCS_SUPPORT_MULTI_SENSOR_MASK)
+ {
+ cscs_ctl_pnt_req_sens_loc_list(conn_id, service_id, resp_code);
+ return;
+ }
+ break;
+ }
+ }
+
+ /* Send indication to client when request opcode not supported. */
+ cscs_ctl_pnt_indicate(conn_id, service_id, cscs_control_point.value[0], resp_code);
+}
+
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID of characteristic data.
+ * @param[in] attrib_index Attribute index of getting characteristic data.
+ * @param[in] offset Used for Blob Read.
+ * @param[in,out] p_length length of getting characteristic data.
+ * @param[in,out] pp_value data got from service.
+ * @return Profile procedure result
+*/
+T_APP_RESULT cscs_attr_read(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+
+ switch (attrib_index)
+ {
+ default:
+ PROFILE_PRINT_ERROR1("cscs_attr_read, attr not found, index=%d", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+ case GATT_SVC_CSCS_FEATURE_INDEX:
+ {
+ T_CSCS_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = CSCS_READ_CSCS_FEATURE;
+ pfn_cscs_cb(service_id, &callback_data);
+
+ *pp_value = (uint8_t *)&cscs_feature;
+ *p_length = sizeof(cscs_feature);
+ }
+ break;
+ case GATT_SVC_CSCS_SENS_LOC_INDEX:
+ if (cscs_feature & CSCS_SUPPORT_MULTI_SENSOR_MASK)
+ {
+ T_CSCS_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = CSCS_READ_SENSOR_LOCATION;
+ pfn_cscs_cb(service_id, &callback_data);
+ *pp_value = (uint8_t *)&cscs_cur_sens_location;
+ *p_length = sizeof(cscs_cur_sens_location);
+ }
+ else
+ {
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ break;
+ }
+
+ return (cause);
+}
+
+
+
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID to be written.
+ * @param[in] attrib_index Attribute index of characteristic.
+ * @param[in] length length of value to be written.
+ * @param[in] p_value value to be written.
+ * @param[in] p_write_ind_post_proc pointer of a function to handle control point write.
+ * @return Profile procedure result
+*/
+T_APP_RESULT cscs_attr_write(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value,
+ P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ if (GATT_SVC_CSCS_CTL_PNT_INDEX == attrib_index)
+ {
+ /* Attribute value has variable size, make sure written value size is valid. */
+ if ((length > CSCS_MAX_CTL_PNT_VALUE) || (p_value == NULL))
+ {
+ cause = APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ /* Make sure Control Point is not "Process already in progress". */
+ else if (CSCS_CTL_PNT_OPERATE_ACTIVE(cscs_control_point.value[0]))
+ {
+ cause = (T_APP_RESULT)0x80;//ProfileResult_AppErr_ProcAlreadyInProgress
+ }
+ /* Make sure Control Point is configured indication enable. */
+ else if (false == cscs_notify_indicate_flag.sc_cp_indicate_enable)
+ {
+ cause = (T_APP_RESULT)0x81;//ProfileResult_AppErr_CccdImproperlyConfigured
+ }
+ else
+ {
+ /* handle SCCP request after sending write response */
+ *p_write_ind_post_proc = cscs_ctl_pnt_handle_req;
+ }
+ }
+ else
+ {
+ PROFILE_PRINT_ERROR2("cscs_attr_write Error attrib_index = 0x%x length=%d", attrib_index, length);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+
+ return cause;
+}
+
+/**
+ * @brief Send measurement value notification data .
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ bool op_result;
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ cscs_set_parameter(CSCS_PARAM_WHEEL_REVOL, sizeof(cscs_cul_value), &cscs_cul_value);
+ op_result = cscs_meas_value_notify(conn_id, cscs_id);
+ }
+ * \endcode
+ */
+bool cscs_meas_value_notify(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ uint16_t attrib_index = GATT_SVC_CSCS_MEASUREMENT_INDEX;
+ uint8_t *p_data = cscs_measurement.value;
+ uint16_t dataLen = cscs_measurement.cur_length;
+
+ PROFILE_PRINT_INFO0("cscs measurement notification");
+ return server_send_data(conn_id, service_id, attrib_index, p_data, dataLen,
+ GATT_PDU_TYPE_NOTIFICATION);
+}
+
+/**
+ * @brief Send control point indication.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] op_code Op code.
+ * @param[in] rsp_code Response code.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ */
+bool cscs_ctl_pnt_indicate(uint8_t conn_id, T_SERVER_ID service_id, uint8_t op_code,
+ uint8_t rsp_code)
+{
+ uint16_t attrib_index = GATT_SVC_CSCS_CTL_PNT_INDEX;
+ uint8_t sens_location;
+ uint8_t param_offset;
+ uint8_t *p_data;
+ uint16_t data_len;
+
+ cscs_control_point.value[1] = cscs_control_point.value[0]; /* Control Point request opcode. */
+ cscs_control_point.value[2] = rsp_code;
+ cscs_control_point.value[0] = CSCS_CP_OPCODE_RSP_CODE;
+ cscs_control_point.cur_length = 3 * sizeof(uint8_t);
+
+ /* Diff RspType, different indication contents. */
+ if (op_code == CSCS_CP_OPCODE_REQ_SENS_LOC_LIST)
+ {
+ /* get sensor location list */
+ for (sens_location = CSCS_SENSOR_LOC_OTHER, param_offset = 3; sens_location < CSCS_SENSOR_LOC_MAX;
+ sens_location++)
+ {
+ if (cscs_sens_loc_supported(sens_location))
+ {
+ cscs_control_point.value[param_offset] = sens_location;
+ param_offset++;
+ }
+ }
+ cscs_control_point.cur_length = param_offset;
+ }
+
+ cscs_ctl_pnt_display_rsp(&cscs_control_point);
+ p_data = cscs_control_point.value;
+ data_len = cscs_control_point.cur_length;
+
+ // send indication to client
+ return server_send_data(conn_id, service_id, attrib_index, p_data, data_len,
+ GATT_PDU_TYPE_INDICATION);
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param[in] index Attribute index of characteristic data.
+ * @param[in] ccc_bits CCCD bits from stack.
+ * @return None
+*/
+void cscs_cccd_update(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ T_CSCS_CALLBACK_DATA callback_data;
+ bool handle = false;
+ PROFILE_PRINT_INFO2("cscs_cccd_update index = %d ccc_bits %x", index, ccc_bits);
+ switch (index)
+ {
+ case GATT_SVC_CSCS_MEAS_CCCD_INDEX:
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = CSCS_NOTIFY_INDICATE_MEASUREMENT_ENABLE;
+ cscs_notify_indicate_flag.csc_measurement_notify_enable = true;
+ }
+ else
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = CSCS_NOTIFY_INDICATE_MEASUREMENT_ENABLE;
+ cscs_notify_indicate_flag.csc_measurement_notify_enable = false;
+ }
+ handle = true;
+ break;
+ case GATT_SVC_CSCS_CTL_PNT_CCCD_INDEX:
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE)
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = CSCS_NOTIFY_INDICATE_SC_CP_ENABLE;
+ cscs_notify_indicate_flag.sc_cp_indicate_enable = true;
+
+ }
+ else
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = CSCS_NOTIFY_INDICATE_SC_CP_DISABLE;
+ cscs_notify_indicate_flag.sc_cp_indicate_enable = false;
+ }
+ handle = true;
+ break;
+ default:
+ break;
+ }
+ /* Notify Application. */
+ if (pfn_cscs_cb && (handle == true))
+ {
+ pfn_cscs_cb(service_id, (void *)&callback_data);
+ }
+}
+
+/**
+ * @brief CSC Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS cscs_cbs =
+{
+ cscs_attr_read, // Read callback function pointer
+ cscs_attr_write, // Write callback function pointer
+ cscs_cccd_update // CCCD update callback function pointer
+};
+
+/**
+ * @brief Add cycling speed and cadence service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ cscs_id = cscs_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID cscs_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+
+ /* Initiate CSC service related data, modify according to user's demand. */
+ cscs_feature = CSCS_ALL_FEATURE_SUPPORTED;
+ cscs_measurement.value[0] = CSCS_INC_ALL_PRESENTS;
+ cscs_measurement.cur_length = CSCS_MAX_MEASUREMENT_VALUE;
+ cscs_sens_loc_list = CSCS_ALL_SENS_LOC_SUPPORTED;
+ cscs_cur_sens_location = CSCS_SENSOR_LOC_REAL_WHEEL;
+
+ /* register CSC service to profile layer. */
+ if (false == server_add_service(&service_id,
+ (uint8_t *)cscs_attr_tbl,
+ cscs_attr_tbl_size,
+ cscs_cbs))
+ {
+ PROFILE_PRINT_ERROR1("cscs_add_service: serviceId %d", service_id);
+ service_id = 0xff;
+ return service_id;
+ }
+
+ /* register callback for profile to inform application that some events happened. */
+ pfn_cscs_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
+
diff --git a/src/ble/profile/server/dfu_service.c b/src/ble/profile/server/dfu_service.c
new file mode 100644
index 0000000..ce9001f
--- /dev/null
+++ b/src/ble/profile/server/dfu_service.c
@@ -0,0 +1,1154 @@
+#include <string.h>
+#include "gatt.h"
+#include "gap_conn_le.h"
+#include "patch_header_check.h"
+#include "rtl876x_wdg.h"
+#include "flash_device.h"
+#include "dfu_flash.h"
+#include "dfu_api.h"
+#include "dfu_service.h"
+#include "otp.h"
+#include "trace.h"
+#include "board.h"
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+
+//#define CAL_OFFSET(type, member) ((size_t)(&((type *)0)->member))
+
+/*============================================================================*
+ * External Variables
+ *============================================================================*/
+T_DFU_PARA g_dfu_para;
+uint8_t *p_ota_temp_buffer_head;
+uint16_t g_ota_tmp_buf_used_size;
+uint8_t temp_image_num = 0;
+T_TEMP_IMAGE_INFO temp_image_info[IMAGE_MAX - SecureBoot];
+
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+uint8_t ota_temp_buffer_head[DFU_TEMP_BUFFER_SIZE];
+static bool buffer_check_en = false;
+static uint32_t dfu_resend_offset = 0;
+static T_SERVER_ID dfu_service_id;
+
+P_FUN_SERVER_GENERAL_CB pfn_dfu_service_cb = NULL;
+
+const uint8_t SILENCE_GATT_UUID128_DFU_SERVICE[16] = {GATT_UUID128_DFU_SERVICE};
+
+T_ATTRIB_APPL gatt_dfu_service_table[] =
+{
+
+ /*-------------------------- DFU Service ---------------------------*/
+ /* <<Primary Service>>, .. */
+ {
+ (ATTRIB_FLAG_VOID | ATTRIB_FLAG_LE), /* flags */
+ {
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE), /* type_value */
+ },
+ UUID_128BIT_SIZE, /* bValueLen */
+ (void *)SILENCE_GATT_UUID128_DFU_SERVICE, /* p_value_context */
+ GATT_PERM_READ /* permissions */
+ },
+
+
+
+ /* <<Characteristic>>, .. */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP/* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ /*--- DFU packet characteristic value ---*/
+ {
+ ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */
+ { /* type_value */
+ GATT_UUID128_DFU_DATA
+ },
+ 0, /* bValueLen */
+ NULL,
+#if DFU_SERVER_REQUIRE_AUTH
+ GATT_PERM_WRITE_AUTHEN_MITM_REQ /* permissions */
+#else
+ GATT_PERM_WRITE /* permissions */
+#endif
+ },
+ /* <<Characteristic>>, .. */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_WRITE | /* characteristic properties */
+ GATT_CHAR_PROP_NOTIFY)
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ /*--- DFU Control Point value ---*/
+ {
+ ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */
+ { /* type_value */
+ GATT_UUID128_DFU_CONTROL_POINT
+ },
+ 0, /* bValueLen */
+ NULL,
+#if DFU_SERVER_REQUIRE_AUTH
+ GATT_PERM_WRITE_AUTHEN_MITM_REQ /* permissions */
+#else
+ GATT_PERM_WRITE /* permissions */
+#endif
+ },
+ /* client characteristic configuration */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* flags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+#if DFU_SERVER_REQUIRE_AUTH
+ (GATT_PERM_READ | GATT_PERM_WRITE_AUTHEN_MITM_REQ) /* permissions */
+#else
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */
+#endif
+ }
+
+};
+
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/**
+ * @brief dfu_buffer_check_process
+ *
+ * @param buffer_check_size size for buffer check.
+ * @param buffer_crc calced buffer crc value.
+ * @return None
+*/
+void dfu_buffer_check_process(uint8_t conn_id, uint16_t buffer_check_size, uint16_t buffer_crc)
+{
+ uint8_t notif_data[DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC] = {0};
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_REPORT_BUFFER_CRC;
+
+ T_DFU_CALLBACK_DATA callback_data;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_attrib_index = INDEX_DFU_CONTROL_POINT_CHAR_VALUE;
+
+ if (buffer_check_size > DFU_TEMP_BUFFER_SIZE)
+ {
+ //invalid para
+ DFU_PRINT_ERROR3("<==dfu_buffer_check_process: invalid buffer_check_size=%d(>%d), cur_offset=%d",
+ buffer_check_size, DFU_TEMP_BUFFER_SIZE, g_dfu_para.cur_offset);
+ g_ota_tmp_buf_used_size = 0;
+ notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER;
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+
+ if (g_ota_tmp_buf_used_size == buffer_check_size ||
+ g_dfu_para.cur_offset + g_ota_tmp_buf_used_size == g_dfu_para.image_total_length)
+ {
+ if (dfu_check_buf_crc(p_ota_temp_buffer_head, g_ota_tmp_buf_used_size, buffer_crc))
+ {
+ //crc error
+ DFU_PRINT_ERROR1("<==dfu_buffer_check_process: Buf CRC Error! cur_offset=%d",
+ g_dfu_para.cur_offset);
+ g_ota_tmp_buf_used_size = 0;
+ notif_data[2] = DFU_ARV_FAIL_CRC_ERROR;
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+
+ else //crc ok
+ {
+ //1. devrypt data
+ if (OTP->ota_with_encryption_data)
+ {
+ dfu_hw_aes_decrypt_image(p_ota_temp_buffer_head, p_ota_temp_buffer_head, g_ota_tmp_buf_used_size);
+ }
+ //2. write flash
+ uint32_t result = dfu_update(g_dfu_para.ctrl_header.image_id,
+ g_dfu_para.cur_offset + temp_image_info[temp_image_num].image_offset,
+ g_ota_tmp_buf_used_size, (uint32_t *)p_ota_temp_buffer_head, false);
+
+ if (result == 0)
+ {
+ uint32_t updated_success_len = g_ota_tmp_buf_used_size;
+ callback_data.msg_data.write.opcode = DFU_WRITE_DOING;
+ callback_data.msg_data.write.length = 4;
+ callback_data.msg_data.write.p_value = (uint8_t *)&updated_success_len;
+ if (pfn_dfu_service_cb)
+ {
+ T_APP_RESULT w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ g_dfu_para.cur_offset += g_ota_tmp_buf_used_size;
+
+ if ((g_dfu_para.cur_offset - dfu_resend_offset) >= FMC_SEC_SECTION_LEN)
+ {
+ dfu_resend_offset += FMC_SEC_SECTION_LEN;
+ }
+ g_ota_tmp_buf_used_size = 0;
+ DFU_PRINT_INFO2("<==dfu_buffer_check_process: dfu_update Success! cur_offset=%d, dfu_resend_offset=%d",
+ g_dfu_para.cur_offset, dfu_resend_offset);
+ notif_data[2] = DFU_ARV_SUCCESS; //valid
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+ else
+ {
+ DFU_PRINT_ERROR1("<==dfu_buffer_check_process: dfu_update Fail result=%d", result);
+
+ result = dfu_flash_erase_sector_with_retry(g_dfu_para.ctrl_header.image_id, dfu_resend_offset);
+ if (result)
+ {
+ //erase fail
+ g_ota_tmp_buf_used_size = 0;
+ g_dfu_para.cur_offset = dfu_resend_offset;
+ DFU_PRINT_ERROR1("<==dfu_buffer_check_process: erase flash fail 3 times! cur_offset=%d",
+ g_dfu_para.cur_offset);
+
+ notif_data[2] = DFU_ARV_FAIL_ERASE_ERROR;
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+
+ if ((g_dfu_para.cur_offset - dfu_resend_offset) > FMC_SEC_SECTION_LEN) //need erase two sector
+ {
+ DFU_PRINT_INFO0("<==dfu_buffer_check_process:Need erase two sectors");
+ result = dfu_flash_erase_sector_with_retry(g_dfu_para.ctrl_header.image_id,
+ dfu_resend_offset + FMC_SEC_SECTION_LEN);
+ if (result)
+ {
+ //erase fail
+ g_ota_tmp_buf_used_size = 0;
+ g_dfu_para.cur_offset = dfu_resend_offset;
+ DFU_PRINT_ERROR1("<==dfu_buffer_check_process: erase flash fail 3 times! cur_offset=%d",
+ g_dfu_para.cur_offset);
+
+ notif_data[2] = DFU_ARV_FAIL_ERASE_ERROR;
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+
+ }
+ //erase ok
+ g_ota_tmp_buf_used_size = 0;
+ g_dfu_para.cur_offset = dfu_resend_offset;
+ DFU_PRINT_INFO1("<==dfu_buffer_check_process: erase ok! cur_offset=%d", g_dfu_para.cur_offset);
+ notif_data[2] = DFU_ARV_FAIL_PROG_ERROR;
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+ }
+ }
+ else
+ {
+ DFU_PRINT_ERROR4("<==dfu_buffer_check_process: Error buffer_check_size=%d,buf_used_size=%d,cur_offset=%d,image_total_length=%d",
+ buffer_check_size, g_ota_tmp_buf_used_size,
+ g_dfu_para.cur_offset, g_dfu_para.image_total_length);
+ //flush buffer.
+ g_ota_tmp_buf_used_size = 0;
+ notif_data[2] = DFU_ARV_FAIL_LENGTH_ERROR;
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+}
+
+void dfu_notify_conn_para_update_req(uint8_t conn_id, T_DFU_ARV_ERROR_CODE error_code)
+{
+ if (g_dfu_para.dfu_conn_para_update_in_progress == true)
+ {
+ g_dfu_para.dfu_conn_para_update_in_progress = false;
+ uint8_t notif_data[3] = {0};
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ;
+ notif_data[2] = error_code;
+
+ DFU_PRINT_INFO1("<==dfu_notify_conn_para_update_req error_code=0x%x", error_code);
+ /* Connection Param Update rejected, we should notify the fail result to remote device. */
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_CONN_PARA_UPDATE_REQ, GATT_PDU_TYPE_NOTIFICATION);
+ }
+}
+
+void dfu_service_handle_valid_fw(uint8_t conn_id)
+{
+ uint8_t notif_data[DFU_NOTIFY_LENGTH_VALID_FW] = {0};
+ bool check_result = false;
+ bool is_enable_bank_switch = is_ota_support_bank_switch();
+
+ if (is_enable_bank_switch)
+ {
+ check_result = dfu_check_checksum(g_dfu_para.ctrl_header.image_id, 0);
+ }
+ else
+ {
+ check_result = dfu_check_checksum(temp_image_info[temp_image_num].image_id,
+ temp_image_info[temp_image_num].image_offset);
+ }
+ DFU_PRINT_INFO1("dfu_service_handle_valid_fw: check_result=%d (1: Success, 0: Fail)", check_result);
+
+ if (check_result)
+ {
+ if (!is_enable_bank_switch)
+ {
+ temp_image_num ++;
+ DFU_PRINT_INFO1("DFU_OPCODE_VALID_FW: temp_image_num=%d ", temp_image_num);
+ }
+
+ notif_data[2] = DFU_ARV_SUCCESS;
+ }
+ else
+ {
+ notif_data[2] = DFU_ARV_FAIL_CRC_ERROR;
+ }
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_VALID_FW;
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_VALID_FW, GATT_PDU_TYPE_NOTIFICATION);
+}
+
+
+void dfu_service_handle_active_image(void)
+{
+ if (!is_ota_support_bank_switch())
+ {
+ uint32_t base_addr = 0;
+ T_IMG_CTRL_HEADER_FORMAT *p_header = NULL;
+ if (IMAGE_USER_DATA == g_dfu_para.ctrl_header.image_id)
+ {
+ /* because flash_get_bank_addr(FLASH_BKP_DATA1) is not located flash block protect range, needn't unlock bp */
+ base_addr = flash_get_bank_addr(FLASH_BKP_DATA1) | FLASH_OFFSET_TO_NO_CACHE;
+ }
+ else
+ {
+ /* check OTA temp or running bank to see if received image is OK.*/
+ base_addr = get_temp_ota_bank_addr_by_img_id((T_IMG_ID)g_dfu_para.ctrl_header.image_id);
+ }
+
+ for (uint8_t i = 0; i < temp_image_num; i++)
+ {
+ p_header = (T_IMG_CTRL_HEADER_FORMAT *)(base_addr + temp_image_info[i].image_offset);
+ dfu_set_image_ready(p_header);
+ }
+ }
+
+}
+
+/**
+ * @brief dfu_service_handle_control_point_req
+ *
+ * @param length control point cmd length.
+ * @param p_value control point cmd address..
+ * @return None
+*/
+void dfu_service_handle_control_point_req(uint8_t conn_id, uint16_t length,
+ uint8_t *p_value)
+{
+ T_APP_RESULT w_cause = APP_RESULT_SUCCESS;
+ T_DFU_CTRL_POINT dfu_control_point;
+ uint8_t *p = p_value + 1;
+ uint8_t notif_data[DFU_NOTIFY_LENGTH_MAX] = {0};
+
+ T_DFU_CALLBACK_DATA callback_data;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_attrib_index = INDEX_DFU_CONTROL_POINT_CHAR_VALUE;
+
+ dfu_control_point.opcode = *p_value;
+ DFU_PRINT_TRACE2("==>dfu_service_handle_control_point_req: opcode=0x%x, length=%d",
+ dfu_control_point.opcode, length);
+
+ if (dfu_control_point.opcode >= DFU_OPCODE_MAX || dfu_control_point.opcode <= DFU_OPCODE_MIN)
+ {
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = dfu_control_point.opcode;
+ notif_data[2] = 0xff;
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_START_DFU, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+
+ switch (dfu_control_point.opcode)
+ {
+ case DFU_OPCODE_START_DFU: //0x01
+ if (length == DFU_LENGTH_START_DFU)/*4 bytes is padding for encrypt*/
+ {
+ if (OTP->ota_with_encryption_data)
+ {
+ DFU_PRINT_INFO1("ctrl header before decryped=%b", TRACE_BINARY(16, p));
+ dfu_hw_aes_decrypt_image(p, p, 16);
+ DFU_PRINT_INFO1("ctrl header after decryped=%b", TRACE_BINARY(16, p));
+ }
+
+ dfu_control_point.start_dfu.ic_type = (*p);
+ p += 1;
+ dfu_control_point.start_dfu.secure_version = (*p);
+ p += 1;
+ LE_ARRAY_TO_UINT16(dfu_control_point.start_dfu.ctrl_flag.value, p);
+ p += 2;
+ LE_ARRAY_TO_UINT16(dfu_control_point.start_dfu.image_id, p);
+ p += 2;
+ LE_ARRAY_TO_UINT16(dfu_control_point.start_dfu.crc16, p);
+ p += 2;
+ LE_ARRAY_TO_UINT32(dfu_control_point.start_dfu.payload_len, p);
+
+ DFU_PRINT_INFO6("DFU_OPCODE_START_DFU: ic_type=0x%x, secure_version=0x%x, ctrl_flag.value=0x%x, image_id=0x%x,crc16=0x%x, payload_len=%d",
+ dfu_control_point.start_dfu.ic_type,
+ dfu_control_point.start_dfu.secure_version,
+ dfu_control_point.start_dfu.ctrl_flag.value,
+ dfu_control_point.start_dfu.image_id,
+ dfu_control_point.start_dfu.crc16,
+ dfu_control_point.start_dfu.payload_len
+ );
+ g_dfu_para.ctrl_header.ic_type = dfu_control_point.start_dfu.ic_type;
+ g_dfu_para.ctrl_header.ctrl_flag.value = dfu_control_point.start_dfu.ctrl_flag.value;
+ g_dfu_para.ctrl_header.image_id = dfu_control_point.start_dfu.image_id;
+ g_dfu_para.ctrl_header.crc16 = dfu_control_point.start_dfu.crc16;
+ g_dfu_para.ctrl_header.payload_len = dfu_control_point.start_dfu.payload_len;
+ g_dfu_para.image_total_length = g_dfu_para.ctrl_header.payload_len + IMG_HEADER_SIZE;
+
+ /*check if start dfu fields are valid*/
+ if (g_dfu_para.ctrl_header.ic_type == DEFINED_IC_TYPE)
+ {
+ if (((g_dfu_para.ctrl_header.image_id >= OTA) && (g_dfu_para.ctrl_header.image_id < IMAGE_MAX))
+ || (g_dfu_para.ctrl_header.image_id == IMAGE_USER_DATA))
+ {
+ /*disable bank switch, need record temp image info*/
+ if (!is_ota_support_bank_switch())
+ {
+ temp_image_info[temp_image_num].image_id = (T_IMG_ID)g_dfu_para.ctrl_header.image_id;
+// temp_image_info[temp_image_num].image_size = UP_ALIGN(g_dfu_para.image_total_length, FMC_SEC_SECTION_LEN);
+ temp_image_info[temp_image_num].image_size = g_dfu_para.image_total_length;
+ if (temp_image_num == 0)
+ {
+ temp_image_info[temp_image_num].image_offset = 0;
+ }
+ else
+ {
+ temp_image_info[temp_image_num].image_offset = temp_image_info[temp_image_num - 1].image_offset +
+ temp_image_info[temp_image_num - 1].image_size;
+ }
+ }
+ DFU_PRINT_INFO4("DFU_OPCODE_START_DFU: image_num=%d, image_id=0x%x, image_size=0x%x, image_offset=0x%x",
+ temp_image_num, temp_image_info[temp_image_num].image_id,
+ temp_image_info[temp_image_num].image_size, temp_image_info[temp_image_num].image_offset);
+
+ callback_data.msg_data.write.opcode = DFU_WRITE_START;
+ callback_data.msg_data.write.length = DFU_HEADER_SIZE;
+ callback_data.msg_data.write.p_value = (uint8_t *)&g_dfu_para.ctrl_header;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ uint32_t result = dfu_update(g_dfu_para.ctrl_header.image_id,
+ 0 + temp_image_info[temp_image_num].image_offset, DFU_HEADER_SIZE,
+ (uint32_t *)&g_dfu_para.ctrl_header, true);
+ if (result)
+ {
+ DBG_DIRECT("DFU_OPCODE_START_DFU: dfu_update fail=%d", result);
+ T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_UPDATE_FLASH;
+ callback_data.msg_data.write.opcode = DFU_WRITE_FAIL;
+ callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON);
+ callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ dfu_fw_reboot(false);
+ }
+ else
+ {
+ g_dfu_para.cur_offset += DFU_HEADER_SIZE;
+ DFU_PRINT_INFO0("DFU_OPCODE_START_DFU: start success!");
+
+ uint32_t updated_success_len = DFU_HEADER_SIZE;
+ callback_data.msg_data.write.opcode = DFU_WRITE_DOING;
+ callback_data.msg_data.write.length = 4;
+ callback_data.msg_data.write.p_value = (uint8_t *)&updated_success_len;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_START_DFU;
+ notif_data[2] = DFU_ARV_SUCCESS;
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_START_DFU, GATT_PDU_TYPE_NOTIFICATION);
+ }
+
+
+ }
+ else
+ {
+ DFU_PRINT_ERROR1("DFU_OPCODE_START_DFU: image id=0x%x Error!", g_dfu_para.ctrl_header.image_id);
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_START_DFU;
+ notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER;
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_START_DFU, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+ }
+ else
+ {
+ DFU_PRINT_ERROR1("DFU_OPCODE_START_DFU: ic type=0x%x Error!", g_dfu_para.ctrl_header.ic_type);
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_START_DFU;
+ notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER;
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_START_DFU, GATT_PDU_TYPE_NOTIFICATION);
+ return;
+ }
+ }
+ break;
+
+ case DFU_OPCODE_RECEIVE_FW_IMAGE_INFO://0x02
+ if (length == DFU_LENGTH_RECEIVE_FW_IMAGE_INFO)
+ {
+ LE_ARRAY_TO_UINT16(g_dfu_para.ctrl_header.image_id, p);
+ p += 2;
+ LE_ARRAY_TO_UINT32(g_dfu_para.cur_offset, p);
+ if ((g_dfu_para.cur_offset == 0) || (g_dfu_para.cur_offset == DFU_HEADER_SIZE))
+ {
+ g_ota_tmp_buf_used_size = 0;
+ dfu_resend_offset = 0;
+ }
+ DFU_PRINT_INFO3("DFU_OPCODE_RECEIVE_FW_IMAGE_INFO: image_id=0x%x, cur_offset=%d, g_ota_tmp_buf_used_size=%d",
+ g_dfu_para.ctrl_header.image_id, g_dfu_para.cur_offset, g_ota_tmp_buf_used_size);
+ }
+ else
+ {
+ DFU_PRINT_ERROR1("DFU_OPCODE_RECEIVE_FW_IMAGE_INFO: length=%d Error!", length);
+ }
+ break;
+
+ case DFU_OPCODE_VALID_FW://0x03
+
+ if (length == DFU_LENGTH_VALID_FW)
+ {
+ LE_ARRAY_TO_UINT16(g_dfu_para.ctrl_header.image_id, p);
+ DFU_PRINT_TRACE1("DFU_OPCODE_VALID_FW: image_id=0x%x", g_dfu_para.ctrl_header.image_id);
+
+ /*if ota large img, need modify wdg timeout period*/
+ if (OTP->wdgEnableInRom && g_dfu_para.image_total_length > 0x100000)
+ {
+ /*1M and less---4s, 2M and less---8s,..., 8M and less---32s*/
+ uint32_t img_align_len = ((g_dfu_para.image_total_length + (0x100000 - 1)) & (~(0x100000 - 1)));
+ uint8_t wdg_period_4s = (img_align_len / 0x100000);
+ uint16_t div_factor = (32 * wdg_period_4s - 1);
+ DFU_PRINT_TRACE2("DFU_OPCODE_VALID_FW: Change WDG Period to %ds, div_factor=%d", wdg_period_4s << 2,
+ div_factor);
+ WDG_Config(div_factor, 15, RESET_ALL); //31 - 4s, 63 - 8s
+ }
+ /*It is not recommended to do things that take a long time in upperstack task cb.
+ So dfu service cb need send msg to app task to handle checksum image if support silent ota.
+ While app task must handle IO_MSG_TYPE_DFU_VALID_FW by calling dfu_service_handle_valid_fw.
+ */
+ }
+ else
+ {
+ DFU_PRINT_ERROR1("DFU_OPCODE_VALID_FW: length=%d Error!", length);
+ }
+ break;
+
+ case DFU_OPCODE_ACTIVE_IMAGE_RESET://0x04
+ {
+ /*when disable bank switch, need set image ready*/
+ dfu_service_handle_active_image();
+
+ /*notify bootloader to reset and use new image*/
+ DFU_PRINT_INFO0("DFU_OPCODE_ACTIVE_IMAGE_RESET");
+ callback_data.msg_data.write.opcode = DFU_WRITE_END;
+ callback_data.msg_data.write.length = DFU_HEADER_SIZE;
+ callback_data.msg_data.write.p_value = (uint8_t *)&g_dfu_para.ctrl_header;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ if (!is_ota_support_bank_switch())
+ {
+ /*note: must unlock flash bp for ota copy before reset when not support bank switch*/
+ unlock_flash_bp_all();
+ }
+ }
+ break;
+
+ case DFU_OPCODE_SYSTEM_RESET://0x05
+ {
+ /*whatever cause ota fail, client will send this cmd to reset device*/
+ DBG_DIRECT("DFU_OPCODE_SYSTEM_RESET");
+
+ /*if select not active image by Phone even if image transport successful. Not for single bank user data*/
+ if (g_dfu_para.ctrl_header.image_id >= OTA && g_dfu_para.ctrl_header.image_id < IMAGE_MAX)
+ {
+
+ uint32_t temp_addr = get_temp_ota_bank_addr_by_img_id((T_IMG_ID)g_dfu_para.ctrl_header.image_id);
+
+ T_IMG_CTRL_HEADER_FORMAT *p_temp_header = (T_IMG_CTRL_HEADER_FORMAT *)temp_addr;
+ if (p_temp_header && !p_temp_header->ctrl_flag.flag_value.not_ready)
+ {
+ flash_erase_locked(FLASH_ERASE_SECTOR, temp_addr);
+ }
+ }
+
+ T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_SYSTEM_RESET_CMD;
+ callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON);
+ callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason;
+ callback_data.msg_data.write.opcode = DFU_WRITE_FAIL;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ dfu_fw_reboot(false);
+ }
+ break;
+
+ case DFU_OPCODE_REPORT_TARGET_INFO://0x06
+ if (length == DFU_LENGTH_REPORT_TARGET_INFO)
+ {
+ LE_ARRAY_TO_UINT16(g_dfu_para.ctrl_header.image_id, p);
+ dfu_report_target_fw_info(g_dfu_para.ctrl_header.image_id, &g_dfu_para.origin_image_version,
+ (uint32_t *)&g_dfu_para.cur_offset);
+ g_dfu_para.cur_offset = 0;
+ DFU_PRINT_INFO3("DFU_OPCODE_REPORT_TARGET_INFO: image_id=0x%x,origin_image_ver=0x%x, cur_offset=%d",
+ g_dfu_para.ctrl_header.image_id, g_dfu_para.origin_image_version, g_dfu_para.cur_offset);
+
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_REPORT_TARGET_INFO;
+ notif_data[2] = DFU_ARV_SUCCESS;
+
+ LE_UINT32_TO_ARRAY(&notif_data[3], g_dfu_para.origin_image_version);
+ LE_UINT32_TO_ARRAY(&notif_data[7], g_dfu_para.cur_offset);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_REPORT_TARGET_INFO, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ else
+ {
+ DFU_PRINT_ERROR1("DFU_OPCODE_REPORT_TARGET_INFO: length=%d Error!", length);
+ }
+ break;
+
+ case DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ://0x07
+ {
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ;
+
+ if (length == DFU_LENGTH_CONN_PARA_TO_UPDATE_REQ)
+ {
+ if (g_dfu_para.dfu_conn_para_update_in_progress)
+ {
+ DFU_PRINT_ERROR0("DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ: OTA ConnParaUpdInProgress!");
+ notif_data[2] = DFU_ARV_FAIL_OPERATION;
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_ARV, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ else
+ {
+ uint16_t conn_interval_min;
+ uint16_t conn_interval_max;
+ uint16_t conn_latency;
+ uint16_t superv_tout;
+
+ LE_ARRAY_TO_UINT16(conn_interval_min, p_value + 1);
+ LE_ARRAY_TO_UINT16(conn_interval_max, p_value + 3);
+ LE_ARRAY_TO_UINT16(conn_latency, p_value + 5);
+ LE_ARRAY_TO_UINT16(superv_tout, p_value + 7);
+
+ if (le_update_conn_param(0, conn_interval_min, conn_interval_max, conn_latency,
+ superv_tout, conn_interval_min * 2 - 2, conn_interval_max * 2 - 2) == GAP_CAUSE_SUCCESS)
+ {
+ /* Connection Parameter Update Request sent successfully, means this procedure is in progress. */
+ g_dfu_para.dfu_conn_para_update_in_progress = true;
+ DFU_PRINT_INFO4("DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ: conn_min=0x%x, conn_max=0x%x, latcy=0x%x, timeout=0x%x",
+ conn_interval_min, conn_interval_max, conn_latency, superv_tout);
+ }
+ else
+ {
+ notif_data[2] = DFU_ARV_FAIL_OPERATION;
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_ARV, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ }
+ }
+ else
+ {
+ /*TODO: to be masked.*/
+ DFU_PRINT_ERROR1("DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ: length=%d Error!", length);
+ notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER;
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_ARV, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ }
+ break;
+
+ case DFU_OPCODE_BUFFER_CHECK_EN: //0x09
+ {
+ le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &g_dfu_para.mtu_size, conn_id);
+ DFU_PRINT_TRACE2("DFU_OPCODE_BUFFER_CHECK_EN: mtu_size=%d, max_bufffer_size=%d",
+ g_dfu_para.mtu_size,
+ DFU_TEMP_BUFFER_SIZE);
+
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_BUFFER_CHECK_EN;
+#if (DFU_BUFFER_CHECK_ENABLE == 1)
+ buffer_check_en = true;
+ notif_data[2] = DFU_ARV_SUCCESS;
+#else
+ buffer_check_en = false;
+ notif_data[2] = DFU_ARV_FAIL_OPERATION;
+#endif
+ LE_UINT16_TO_ARRAY(&notif_data[3], DFU_TEMP_BUFFER_SIZE);
+ LE_UINT16_TO_ARRAY(&notif_data[5], g_dfu_para.mtu_size);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_BUFFER_CHECK_EN, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ break;
+
+ case DFU_OPCODE_REPORT_BUFFER_CRC: //0x0a
+ {
+ uint16_t mBufSize;
+ uint16_t mCrcVal;
+ LE_ARRAY_TO_UINT16(mBufSize, p);
+ p += 2;
+ LE_ARRAY_TO_UINT16(mCrcVal, p);
+ DFU_PRINT_INFO2("DFU_OPCODE_REPORT_BUFFER_CRC: mBufSize=0x%x, mCrcVal=0x%x", mBufSize, mCrcVal);
+ dfu_buffer_check_process(conn_id, mBufSize, mCrcVal);
+ }
+ break;
+
+ case DFU_OPCODE_RECEIVE_IC_TYPE://0x0b
+ {
+ uint8_t ic_type = 0; //0 means invalid ic type
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_RECEIVE_IC_TYPE;
+ if (dfu_report_target_ic_type(OTA, &ic_type))
+ {
+ notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER;
+ notif_data[3] = ic_type;
+ }
+ else
+ {
+ notif_data[2] = DFU_ARV_SUCCESS;
+ notif_data[3] = ic_type;
+ }
+ DFU_PRINT_INFO1("DFU_OPCODE_RECEIVE_IC_TYPE: ic_type=0x%x", ic_type);
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_RECEIVE_IC_TYPE, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ break;
+
+#if (ENABLE_BANK_SWITCH_COPY_APP_DATA == 1)
+ case DFU_OPCODE_COPY_IMG://0x0c
+ {
+ uint32_t dlAddress, dlSize;
+ LE_ARRAY_TO_UINT16(g_dfu_para.ctrl_header.image_id, p);
+ p += 2;
+ LE_ARRAY_TO_UINT32(dlAddress, p);
+ p += 4;
+ LE_ARRAY_TO_UINT32(dlSize, p);
+ DFU_PRINT_TRACE2("DFU_OPCODE_COPY_IMG: dlAddress=0x%x,dlSize=0x%x", dlAddress,
+ dlSize);
+
+ notif_data[0] = DFU_OPCODE_NOTIFICATION;
+ notif_data[1] = DFU_OPCODE_COPY_IMG;
+
+ if (dfu_copy_img(g_dfu_para.ctrl_header.image_id, dlAddress, dlSize))
+ {
+ notif_data[2] = DFU_ARV_SUCCESS;
+ }
+ else
+ {
+ notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER;
+ }
+ server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \
+ notif_data, DFU_NOTIFY_LENGTH_ARV, GATT_PDU_TYPE_NOTIFICATION);
+ }
+ break;
+#endif //end ENABLE_BANK_SWITCH_COPY_APP_DATA
+
+ default:
+ {
+ DFU_PRINT_TRACE1("dfu_service_handle_control_point_req: Unknown Opcode=0x%x",
+ dfu_control_point.opcode);
+ }
+ break;
+ }
+}
+
+
+/**
+ * @brief dfu_service_handle_packet_req
+ *
+ * @param length data reviewed length.
+ * @param p_value data receive point address.
+ * @return None
+*/
+void dfu_service_handle_packet_req(uint8_t conn_id, uint16_t length, uint8_t *p_value)
+{
+ T_APP_RESULT w_cause = APP_RESULT_SUCCESS;
+ T_DFU_CALLBACK_DATA callback_data;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_attrib_index = INDEX_DFU_PACKET_VALUE;
+ callback_data.msg_data.write.length = length;
+ callback_data.msg_data.write.p_value = p_value;
+
+ DFU_PRINT_INFO4("dfu_service_handle_packet_req: length=%d, cur_offset=%d, g_ota_tmp_buf_used_size=%d, image_total_length=%d",
+ length, g_dfu_para.cur_offset,
+ g_ota_tmp_buf_used_size, g_dfu_para.image_total_length);
+
+ if (buffer_check_en == true)
+ {
+ /*to avoid memory overflow*/
+ if (g_ota_tmp_buf_used_size + length > DFU_TEMP_BUFFER_SIZE)
+ {
+ DFU_PRINT_ERROR3("<==dfu_service_handle_packet_req: Buf overflow! ota_tmp_buf_used_size=%d,length=%d, max_buffer_size=%d",
+ g_ota_tmp_buf_used_size, length, DFU_TEMP_BUFFER_SIZE);
+
+ T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_EXCEED_MAX_BUFFER_SIZE;
+ callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON);
+ callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason;
+ callback_data.msg_data.write.opcode = DFU_WRITE_FAIL;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ dfu_fw_reboot(false);
+ }
+ else
+ {
+ memcpy(p_ota_temp_buffer_head + g_ota_tmp_buf_used_size, p_value, length);
+ g_ota_tmp_buf_used_size += length;
+ }
+ }
+ else
+ {
+ /*when disable buffer check, Default client send 20bytes per packet*/
+ uint32_t max_buffer_size = DFU_TEMP_BUFFER_SIZE - (DFU_TEMP_BUFFER_SIZE % 20);
+ /*0.check memcpy buffer boundary*/
+ if (g_ota_tmp_buf_used_size + length > max_buffer_size)
+ {
+ DBG_DIRECT("<==dfu_service_handle_packet_req: Buf overflow! ota_tmp_buf_used_size=%d,length=%d, max_buffer_size=%d",
+ g_ota_tmp_buf_used_size, length, max_buffer_size);
+
+ T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_EXCEED_MAX_BUFFER_SIZE;
+ callback_data.msg_data.write.opcode = DFU_WRITE_FAIL;
+ callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON);
+ callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ dfu_fw_reboot(false);
+ }
+
+ /*0.check total length*/
+ if (g_dfu_para.cur_offset + g_ota_tmp_buf_used_size + length > g_dfu_para.image_total_length)
+ {
+ DFU_PRINT_ERROR1("<==dfu_service_handle_packet_req: received data total length beyond image_total_length(%d bytes)",
+ g_dfu_para.image_total_length);
+
+ T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_EXCEED_IMG_TOTAL_LEN;
+ callback_data.msg_data.write.opcode = DFU_WRITE_FAIL;
+ callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON);
+ callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ dfu_fw_reboot(false);
+ }
+
+ /*start handle received data*/
+ //1. deceypt data
+ if (OTP->ota_with_encryption_data)
+ {
+ dfu_hw_aes_decrypt_image(p_value, p_value, length);
+ }
+
+ //2. copy received data to buffer
+ memcpy(p_ota_temp_buffer_head + g_ota_tmp_buf_used_size, p_value, length);
+ g_ota_tmp_buf_used_size += length;
+
+ //3. write to flash
+ if (g_ota_tmp_buf_used_size == max_buffer_size ||
+ g_dfu_para.cur_offset + g_ota_tmp_buf_used_size == g_dfu_para.image_total_length)
+ {
+ uint32_t result = dfu_update(g_dfu_para.ctrl_header.image_id,
+ g_dfu_para.cur_offset + temp_image_info[temp_image_num].image_offset,
+ g_ota_tmp_buf_used_size,
+ (uint32_t *)p_ota_temp_buffer_head, false);
+ if (result)
+ {
+ DBG_DIRECT("Buffer check disable: dfu_update fail=%d", result);
+
+ /*eflash write fail, we should restart ota procedure.*/
+ T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_UPDATE_FLASH;
+ callback_data.msg_data.write.opcode = DFU_WRITE_FAIL;
+ callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON);
+ callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ dfu_fw_reboot(false);
+ }
+ else
+ {
+ uint32_t updated_success_len = g_ota_tmp_buf_used_size;
+ callback_data.msg_data.write.opcode = DFU_WRITE_DOING;
+ callback_data.msg_data.write.length = 4;
+ callback_data.msg_data.write.p_value = (uint8_t *)&updated_success_len;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ /*update varibals value*/
+ g_dfu_para.cur_offset += g_ota_tmp_buf_used_size;
+ g_ota_tmp_buf_used_size = 0;
+ }
+ }
+ }
+
+}
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param ServiceID ServiceID to be written.
+ * @param iAttribIndex Attribute index of characteristic.
+ * @param wLength length of value to be written.
+ * @param pValue value to be written.
+ * @return Profile procedure result
+*/
+T_APP_RESULT dfu_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT w_cause = APP_RESULT_SUCCESS;
+ T_DFU_CALLBACK_DATA callback_data;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_attrib_index = attrib_index;
+ callback_data.msg_data.write.length = length;
+ callback_data.msg_data.write.p_value = p_value;
+
+ /* Notify Application. */
+ callback_data.msg_data.write.opcode = DFU_WRITE_ATTR_ENTER;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return w_cause;
+ }
+ }
+
+ if (attrib_index == INDEX_DFU_CONTROL_POINT_CHAR_VALUE)
+ {
+ dfu_service_handle_control_point_req(conn_id, length, p_value);
+ }
+ else if (attrib_index == INDEX_DFU_PACKET_VALUE)
+ {
+ dfu_service_handle_packet_req(conn_id, length, p_value);
+ }
+ else
+ {
+ DFU_PRINT_INFO1("dfu_attr_write_cb fail! attrib_index=%d", attrib_index);
+ w_cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+
+ /* Notify Application. */
+ callback_data.msg_data.write.opcode = DFU_WRITE_ATTR_EXIT;
+ if (pfn_dfu_service_cb)
+ {
+ w_cause = pfn_dfu_service_cb(service_id, (void *)&callback_data);
+ if (w_cause != APP_RESULT_SUCCESS)
+ {
+ return w_cause;
+ }
+ }
+
+ return w_cause;
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param ServiceId Service ID.
+ * @param Index Attribute index of characteristic data.
+ * @param wCCCBits CCCD bits from stack.
+ * @return None
+*/
+void dfu_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ T_DFU_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.conn_id = conn_id;
+ bool b_handle = true;
+ DFU_PRINT_INFO2("dfu_cccd_update_cb: index=%d, ccc_bits=0x%x", index, ccc_bits);
+ switch (index)
+ {
+ case INDEX_DFU_CHAR_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ // Enable Notification
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = DFU_NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = DFU_NOTIFY_DISABLE;
+ }
+ break;
+ }
+ default:
+ {
+ b_handle = false;
+ break;
+ }
+
+ }
+ /* Notify Application. */
+ if (pfn_dfu_service_cb && (b_handle == true))
+ {
+ T_APP_RESULT update_cause = pfn_dfu_service_cb(service_id, (void *)&callback_data);
+ if (update_cause != APP_RESULT_SUCCESS)
+ {
+ return;
+ }
+ }
+
+ return;
+}
+
+/**
+ * @brief OTA ble Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS DfuServiceCBs =
+{
+ NULL, // Read callback function pointer
+ dfu_attr_write_cb, // Write callback function pointer
+ dfu_cccd_update_cb // CCCD update callback function pointer
+};
+
+/**
+ * @brief add OTA ble service to application.
+ *
+ * @param pFunc pointer of app callback function called by profile.
+ * @return service ID auto generated by profile layer.
+ * @retval ServiceId
+*/
+uint8_t dfu_add_service(void *pFunc)
+{
+ if (false == server_add_service(&dfu_service_id,
+ (uint8_t *)gatt_dfu_service_table,
+ sizeof(gatt_dfu_service_table),
+ DfuServiceCBs))
+ {
+ DFU_PRINT_ERROR1("dfu_add_service: service_id=%d", dfu_service_id);
+ dfu_service_id = 0xff;
+ return dfu_service_id;
+ }
+ pfn_dfu_service_cb = (P_FUN_SERVER_GENERAL_CB)pFunc;
+ p_ota_temp_buffer_head = ota_temp_buffer_head;
+
+ return dfu_service_id;
+}
+
+
diff --git a/src/ble/profile/server/dis.c b/src/ble/profile/server/dis.c
new file mode 100644
index 0000000..3a64cda
--- /dev/null
+++ b/src/ble/profile/server/dis.c
@@ -0,0 +1,699 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file dis.c
+* @brief Device Information service source file.
+* @details Interfaces to access Device Information service.
+* @author
+* @date
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "stdint.h"
+#include "string.h"
+#include "trace.h"
+#include "profile_server.h"
+#include "dis.h"
+#include "dis_config.h"
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @brief IEEE 11073 authoritative body values. */
+#define DIS_IEEE_11073_BODY_EMPTY 0
+#define DIS_IEEE_11073_BODY_IEEE 1
+#define DIS_IEEE_11073_BODY_CONTINUA 2
+#define DIS_IEEE_11073_BODY_EXP 254
+
+/** @brief DIS related UUIDs */
+#define GATT_UUID_DEVICE_INFORMATION_SERVICE 0x180A
+
+#define GATT_UUID_CHAR_SYSTEM_ID 0x2A23
+#define GATT_UUID_CHAR_MODEL_NUMBER 0x2A24
+#define GATT_UUID_CHAR_SERIAL_NUMBER 0x2A25
+#define GATT_UUID_CHAR_FIRMWARE_REVISION 0x2A26
+#define GATT_UUID_CHAR_HARDWARE_REVISION 0x2A27
+#define GATT_UUID_CHAR_SOFTWARE_REVISION 0x2A28
+#define GATT_UUID_CHAR_MANUFACTURER_NAME 0x2A29
+#define GATT_UUID_CHAR_IEEE_CERTIF_DATA_LIST 0x2A2A
+#define GATT_UUID_CHAR_PNP_ID 0x2A50
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+static P_FUN_SERVER_GENERAL_CB pfn_dis_cb = NULL;
+
+
+#if DIS_CHAR_SYSTEM_ID_SUPPORT
+/**< DIS service System ID. */
+static uint8_t dis_system_id[DIS_SYSTEM_ID_LENGTH] = {0, 1, 2, 0, 0, 3, 4, 5};
+#endif
+
+
+#if DIS_CHAR_PNP_ID_SUPPORT
+/**< DIS service PnP ID. */
+static uint8_t dis_pnp_id[DIS_PNP_ID_LENGTH] =
+{
+ 1, // Vendor ID source (1=Bluetooth SIG)
+ LO_WORD(0x005D), HI_WORD(0x005D), // Vendor ID (Realtek Semiconductor Corporation)
+ LO_WORD(0x0000), HI_WORD(0x0000), // Product ID (vendor-specific)
+ LO_WORD(0x0100), HI_WORD(0x0100) // Product version (vendor-assigned-JJ.M.N)
+};
+#endif
+
+#if DIS_CHAR_MANUFACTURER_NAME_SUPPORT
+/**< DIS service Manufacturer Name. A null-terminated byte is reserved*/
+static uint8_t dis_manufacturer_name[DIS_CHAR_MANUFACTURER_NAME_STR_MAX_LENGTH] = "";
+static uint8_t dis_manufacturer_name_len = 0;
+#endif
+
+#if DIS_CHAR_MODEL_NUMBER_SUPPORT
+/**< DIS service Model Number. A null-terminated byte is reserved*/
+static uint8_t dis_model_number[DIS_CHAR_MODEL_NUMBER_STR_MAX_LENGTH] = "";
+static uint8_t dis_model_number_len = 0;
+#endif
+
+#if DIS_CHAR_SERIAL_NUMBER_SUPPORT
+/**< DIS service Serial Number. A null-terminated byte is reserved*/
+static uint8_t dis_serial_number[DIS_CHAR_SERIAL_NUMBER_STR_MAX_LENGTH] = "";
+static uint8_t dis_serial_number_len = 0;
+#endif
+
+#if DIS_CHAR_HARDWARE_REVISION_SUPPORT
+/**< DIS service Hardware Revision. A null-terminated byte is reserved*/
+static uint8_t dis_hardware_rev[DIS_CHAR_HARDWARE_REVISION_STR_MAX_LENGTH] = "";
+static uint8_t dis_hardware_rev_len = 0;
+#endif
+
+#if DIS_CHAR_FIRMWARE_REVISION_SUPPORT
+/**< DIS service Firmware Revision. A null-terminated byte is reserved*/
+static uint8_t dis_firmware_rev[DIS_CHAR_FIRMWARE_REVISION_STR_MAX_LENGTH] = "";
+static uint8_t dis_firmware_rev_len = 0;
+#endif
+
+#if DIS_CHAR_SOFTWARE_REVISION_SUPPORT
+/**< DIS service Software Revision. A null-terminated byte is reserved*/
+static uint8_t dis_software_rev[DIS_CHAR_SOFTWARE_REVISION_STR_MAX_LENGTH] = "";
+static uint8_t dis_software_rev_len = 0;
+#endif
+
+#if DIS_CHAR_IEEE_CERTIF_DATA_LIST_SUPPORT
+/**< DIS service IEEE 11073-20601 Regulatory Certification Data List. */
+static uint8_t dis_ieee_data_list[DIS_CHAR_IEEE_CERTIF_DATA_LIST_MAX_LENGTH] =
+{
+ DIS_IEEE_11073_BODY_EXP, // Authoritative body type
+ 0x00, // Authoritative body structure type
+ // Authoritative body data follows below:
+ 'e', 'x', 'p', 'e', 'r', 'i', 'm', 'e', 'n', 't', 'a', 'l'
+};
+static uint8_t dis_ieee_data_list_len = 14;
+#endif
+
+/**< @brief profile/service definition. */
+static const T_ATTRIB_APPL dis_attr_tbl[] =
+{
+ /*----------------- Device Information Service -------------------*/
+ /* <<Primary Service>> */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_DEVICE_INFORMATION_SERVICE), /* service UUID */
+ HI_WORD(GATT_UUID_DEVICE_INFORMATION_SERVICE)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* p_value_context */
+ GATT_PERM_READ /* permissions */
+ }
+
+#if DIS_CHAR_MANUFACTURER_NAME_SUPPORT
+ ,
+ /* <<Characteristic>> */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ /* Manufacturer Name String characteristic value */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_MANUFACTURER_NAME),
+ HI_WORD(GATT_UUID_CHAR_MANUFACTURER_NAME)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* permissions */
+ }
+#endif
+
+#if DIS_CHAR_MODEL_NUMBER_SUPPORT
+ ,
+ /* <<Characteristic>> */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ /* Model Number characteristic value */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_MODEL_NUMBER),
+ HI_WORD(GATT_UUID_CHAR_MODEL_NUMBER)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* permissions */
+ }
+#endif
+
+#if DIS_CHAR_SERIAL_NUMBER_SUPPORT
+ ,
+ /* <<Characteristic>> */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ /* Serial Number String String characteristic value */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_SERIAL_NUMBER),
+ HI_WORD(GATT_UUID_CHAR_SERIAL_NUMBER)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* permissions */
+ }
+#endif
+
+#if DIS_CHAR_HARDWARE_REVISION_SUPPORT
+ ,
+ /* <<Characteristic>> */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ /* Manufacturer Name String characteristic value */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_HARDWARE_REVISION),
+ HI_WORD(GATT_UUID_CHAR_HARDWARE_REVISION)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* permissions */
+ }
+#endif
+
+#if DIS_CHAR_FIRMWARE_REVISION_SUPPORT
+ ,
+ /* <<Characteristic>> */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ /* Firmware revision String characteristic value */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_FIRMWARE_REVISION),
+ HI_WORD(GATT_UUID_CHAR_FIRMWARE_REVISION)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* permissions */
+ }
+#endif
+
+#if DIS_CHAR_SOFTWARE_REVISION_SUPPORT
+ ,
+ /* <<Characteristic>> */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ /* Manufacturer Name String characteristic value */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_SOFTWARE_REVISION),
+ HI_WORD(GATT_UUID_CHAR_SOFTWARE_REVISION)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* permissions */
+ }
+#endif
+
+#if DIS_CHAR_SYSTEM_ID_SUPPORT
+ ,
+ /* <<Characteristic>> */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ /* System ID String characteristic value */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_SYSTEM_ID),
+ HI_WORD(GATT_UUID_CHAR_SYSTEM_ID)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* permissions */
+ }
+#endif
+
+#if DIS_CHAR_IEEE_CERTIF_DATA_LIST_SUPPORT
+ ,
+
+ /* <<Characteristic>> */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ /* Manufacturer Name String characteristic value */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_IEEE_CERTIF_DATA_LIST),
+ HI_WORD(GATT_UUID_CHAR_IEEE_CERTIF_DATA_LIST)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* permissions */
+ }
+#endif
+
+#if DIS_CHAR_PNP_ID_SUPPORT
+ ,
+ /* <<Characteristic>> */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ /* Manufacturer Name String characteristic value */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_PNP_ID),
+ HI_WORD(GATT_UUID_CHAR_PNP_ID)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* permissions */
+ }
+#endif
+};
+/**< @brief DIS service size definition. */
+const uint16_t dis_attr_tbl_size = sizeof(dis_attr_tbl);
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/**
+ * @brief Set a device information service parameter.
+ *
+ * NOTE: You can call this function with a device information service parameter type and it will set the
+ * device information service parameter. Device information service parameters are defined in @ref T_DIS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Device information service parameter type: @ref T_DIS_PARAM_TYPE
+ * @param[in] length Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ const uint8_t dis_manufacture_name[] = "Realtek BT";
+ dis_set_parameter(DIS_PARAM_MANUFACTURER_NAME,
+ sizeof(dis_manufacture_name),
+ (void *)dis_manufacture_name);
+ }
+ * \endcode
+ */
+bool dis_set_parameter(T_DIS_PARAM_TYPE param_type, uint8_t length, void *p_value)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ default:
+ ret = false;
+ break;
+
+#if DIS_CHAR_MANUFACTURER_NAME_SUPPORT
+ case DIS_PARAM_MANUFACTURER_NAME:
+ if (length > DIS_CHAR_MANUFACTURER_NAME_STR_MAX_LENGTH)
+ {
+ length = DIS_CHAR_MANUFACTURER_NAME_STR_MAX_LENGTH;
+ }
+ dis_manufacturer_name_len = length;
+ memcpy(dis_manufacturer_name, p_value, length);
+ break;
+#endif
+
+#if DIS_CHAR_MODEL_NUMBER_SUPPORT
+ case DIS_PARAM_MODEL_NUMBER:
+ if (length > DIS_CHAR_MODEL_NUMBER_STR_MAX_LENGTH)
+ {
+ length = DIS_CHAR_MODEL_NUMBER_STR_MAX_LENGTH;
+ }
+ dis_model_number_len = length;
+ memcpy(dis_model_number, p_value, length);
+ break;
+#endif
+
+#if DIS_CHAR_SERIAL_NUMBER_SUPPORT
+ case DIS_PARAM_SERIAL_NUMBER:
+ if (length > DIS_CHAR_SERIAL_NUMBER_STR_MAX_LENGTH)
+ {
+ length = DIS_CHAR_SERIAL_NUMBER_STR_MAX_LENGTH;
+ }
+ dis_serial_number_len = length;
+ memcpy(dis_serial_number, p_value, length);
+
+ break;
+#endif
+
+#if DIS_CHAR_HARDWARE_REVISION_SUPPORT
+ case DIS_PARAM_HARDWARE_REVISION:
+ if (length > DIS_CHAR_HARDWARE_REVISION_STR_MAX_LENGTH)
+ {
+ length = DIS_CHAR_HARDWARE_REVISION_STR_MAX_LENGTH;
+ }
+ dis_hardware_rev_len = length;
+ memcpy(dis_hardware_rev, p_value, length);
+ break;
+#endif
+
+#if DIS_CHAR_FIRMWARE_REVISION_SUPPORT
+ case DIS_PARAM_FIRMWARE_REVISION:
+ if (length > DIS_CHAR_FIRMWARE_REVISION_STR_MAX_LENGTH)
+ {
+ length = DIS_CHAR_FIRMWARE_REVISION_STR_MAX_LENGTH;
+ }
+ dis_firmware_rev_len = length;
+ memcpy(dis_firmware_rev, p_value, length);
+ break;
+#endif
+
+#if DIS_CHAR_SOFTWARE_REVISION_SUPPORT
+ case DIS_PARAM_SOFTWARE_REVISION:
+ if (length > DIS_CHAR_SOFTWARE_REVISION_STR_MAX_LENGTH)
+ {
+ length = DIS_CHAR_SOFTWARE_REVISION_STR_MAX_LENGTH;
+ }
+ dis_software_rev_len = length;
+ memcpy(dis_software_rev, p_value, length);
+ break;
+#endif
+
+#if DIS_CHAR_SYSTEM_ID_SUPPORT
+ case DIS_PARAM_SYSTEM_ID:
+ if (length > DIS_SYSTEM_ID_LENGTH)
+ {
+ length = DIS_SYSTEM_ID_LENGTH;
+ }
+ memcpy(dis_system_id, p_value, length);
+ break;
+#endif
+
+#if DIS_CHAR_IEEE_CERTIF_DATA_LIST_SUPPORT
+ case DIS_PARAM_IEEE_DATA_LIST:
+ if (length > DIS_CHAR_IEEE_CERTIF_DATA_LIST_MAX_LENGTH)
+ {
+ length = DIS_CHAR_IEEE_CERTIF_DATA_LIST_MAX_LENGTH;
+ }
+ dis_ieee_data_list_len = length;
+ memcpy(dis_ieee_data_list, p_value, length);
+ break;
+#endif
+
+#if DIS_CHAR_PNP_ID_SUPPORT
+ case DIS_PARAM_PNP_ID:
+ if (length > DIS_PNP_ID_LENGTH)
+ {
+ length = DIS_PNP_ID_LENGTH;
+ }
+ memcpy(dis_pnp_id, p_value, length);
+ break;
+#endif
+ }
+
+ if (!ret)
+ {
+ PROFILE_PRINT_ERROR0("dis_set_parameter: parameter set failed");
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Read characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID to be read.
+ * @param[in] attrib_index Attribute index of getting characteristic data.
+ * @param[in] offset offset of characteritic to be read.
+ * @param[in,out] length_ptr length of getting characteristic data.
+ * @param[in,out] pp_value pointer to pointer of characteristic value to be read.
+ * @return T_APP_RESULT
+*/
+T_APP_RESULT dis_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *length_ptr, uint8_t **pp_value)
+{
+ T_DIS_CALLBACK_DATA callback_data;
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ *length_ptr = 0;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.conn_id = conn_id;
+
+ switch (attrib_index)
+ {
+ default:
+ PROFILE_PRINT_ERROR1("dis_attr_read_cb: attrib_index %d", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+
+#if DIS_CHAR_SYSTEM_ID_SUPPORT
+ case GATT_SVC_DIS_SYSTEM_ID_INDEX:
+ callback_data.msg_data.read_value_index = DIS_READ_SYSTEM_ID_INDEX;
+ pfn_dis_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&dis_system_id;
+ *length_ptr = sizeof(dis_system_id);
+ break;
+#endif
+
+#if DIS_CHAR_MANUFACTURER_NAME_SUPPORT
+ case GATT_SVC_DIS_MANU_NAME_INDEX:
+ callback_data.msg_data.read_value_index = DIS_READ_MANU_NAME_INDEX;
+ pfn_dis_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&dis_manufacturer_name;
+ *length_ptr = dis_manufacturer_name_len;
+ break;
+#endif
+
+#if DIS_CHAR_SERIAL_NUMBER_SUPPORT
+ case GATT_SVC_DIS_SERIAL_NUM_INDEX:
+ callback_data.msg_data.read_value_index = DIS_READ_SERIAL_NUM_INDEX;
+ pfn_dis_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&dis_serial_number;
+ *length_ptr = dis_serial_number_len;
+ break;
+#endif
+
+#if DIS_CHAR_FIRMWARE_REVISION_SUPPORT
+ case GATT_SVC_DIS_FIRMWARE_REV_INDEX:
+ callback_data.msg_data.read_value_index = DIS_READ_FIRMWARE_REV_INDEX;
+ pfn_dis_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&dis_firmware_rev;
+ *length_ptr = dis_firmware_rev_len;
+ break;
+#endif
+
+#if DIS_CHAR_HARDWARE_REVISION_SUPPORT
+ case GATT_SVC_DIS_HARDWARE_REV_INDEX:
+ callback_data.msg_data.read_value_index = DIS_READ_HARDWARE_REV_INDEX;
+ pfn_dis_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&dis_hardware_rev;
+ *length_ptr = dis_hardware_rev_len;
+ break;
+#endif
+
+#if DIS_CHAR_SOFTWARE_REVISION_SUPPORT
+ case GATT_SVC_DIS_SOFTWARE_REV_INDEX:
+ callback_data.msg_data.read_value_index = DIS_READ_SOFTWARE_REV_INDEX;
+ pfn_dis_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&dis_software_rev;
+ *length_ptr = dis_software_rev_len;
+ break;
+#endif
+
+#if DIS_CHAR_IEEE_CERTIF_DATA_LIST_SUPPORT
+ case GATT_SVC_DIS_IEEE_CERT_STR_INDEX:
+ callback_data.msg_data.read_value_index = DIS_READ_IEEE_CERT_STR_INDEX;
+ pfn_dis_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&dis_ieee_data_list;
+ *length_ptr = dis_ieee_data_list_len;
+ break;
+#endif
+
+#if DIS_CHAR_PNP_ID_SUPPORT
+ case GATT_SVC_DIS_PNP_ID_INDEX:
+ callback_data.msg_data.read_value_index = DIS_READ_PNP_ID_INDEX;
+ pfn_dis_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&dis_pnp_id;
+ *length_ptr = sizeof(dis_pnp_id);
+ break;
+#endif
+
+#if DIS_CHAR_MODEL_NUMBER_SUPPORT
+ case GATT_SVC_DIS_MODEL_NUM_INDEX:
+ callback_data.msg_data.read_value_index = DIS_READ_MODEL_NUM_INDEX;
+ pfn_dis_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&dis_model_number;
+ *length_ptr = dis_model_number_len;
+ break;
+#endif
+
+ }
+
+ PROFILE_PRINT_INFO2("dis_attr_read_cb: attrib_index %d, *length_ptr %d",
+ attrib_index,
+ *length_ptr);
+ return (cause);
+}
+
+const T_FUN_GATT_SERVICE_CBS dis_cbs =
+{
+ dis_attr_read_cb, // Read callback function pointer
+ NULL, // Write callback function pointer
+ NULL // Authorization callback function pointer
+};
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/**
+ * @brief Add device information service to the BLE stack database.
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ dis_id = dis_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID dis_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)dis_attr_tbl,
+ dis_attr_tbl_size,
+ dis_cbs))
+ {
+ PROFILE_PRINT_ERROR1("dis_add_service: service_id %d", service_id);
+ service_id = 0xff;
+ }
+ pfn_dis_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/ble/profile/server/gls.c b/src/ble/profile/server/gls.c
new file mode 100644
index 0000000..c98a350
--- /dev/null
+++ b/src/ble/profile/server/gls.c
@@ -0,0 +1,2016 @@
+/****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+
+ * @file gls.c
+ * @brief glucose service source file.
+ * @details Interface to access the glucose service.
+ * @author bill
+ * @date 2017-6-8
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#include "trace.h"
+#include <string.h>
+#include "gatt.h"
+#include "gls.h"
+
+
+/** @brief service related UUIDs. */
+#define GATT_UUID_GLUCOSE 0x1808
+#define GATT_UUID_CHAR_GLC_MEASUREMENT 0x2A18
+#define GATT_UUID_CHAR_GLC_MEASUREMENT_CONTEXT 0x2A34
+#define GATT_UUID_CHAR_GLC_FEATURE 0x2A51
+#define GATT_UUID_CHAR_GLC_RACP 0x2A52
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+/** Value of glucose feature characteristic. */
+static uint16_t features;
+
+/** glucose record access control point */
+T_GLC_RACP glc_racp;
+T_PATIENT_RECORD *p_new_record;
+/** flags of notification and indication for characteristic */
+static T_GLC_NOTIFY_INDICATE_FLAG glc_notify_indicate_flag = {0};
+
+/** parameters used for splitting report records procedure */
+uint16_t gls_num_records_to_report = 0;
+uint16_t gls_current_record_to_report = 0;
+uint16_t gls_report_offset = 0;
+uint8_t gls_send_data_flag = 0;
+/** Flag used for aborting procedure */
+bool gls_abort_flag = false;
+bool gls_abort_by_app_flag = false;
+
+/** Function pointer used to send event to application from GLS. Initiated in gls_add_service. */
+static P_FUN_SERVER_GENERAL_CB pfn_gls_cb = NULL;
+
+/** @brief profile/service definition. */
+const T_ATTRIB_APPL gls_att_tbl[] =
+{
+ /* <<Primary Service>>, .. */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_GLUCOSE), /* service UUID */
+ HI_WORD(GATT_UUID_GLUCOSE)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* <<Characteristic>>, .. */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /*--- Glucose Measurement characteristic value ---*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_GLC_MEASUREMENT),
+ HI_WORD(GATT_UUID_CHAR_GLC_MEASUREMENT)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_NONE /* wPermissions */
+ },
+ /* client characteristic configuration */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* wFlags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ }
+
+#if GLC_MEASUREMENT_CONTEXT_SUPPORT
+ ,
+ /* <<Characteristic>>, .. */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /*--- Glucose Measurement Context characteristic value ---*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_GLC_MEASUREMENT_CONTEXT),
+ HI_WORD(GATT_UUID_CHAR_GLC_MEASUREMENT_CONTEXT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_NONE /* wPermissions */
+ },
+ /* client characteristic configuration */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* wFlags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ }
+#endif /**< end of GLC_MEASUREMENT_CONTEXT_SUPPORT */
+
+ ,
+ /* <<Characteristic>>, .. */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /*--- Glucose features characteristic value ---*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_GLC_FEATURE),
+ HI_WORD(GATT_UUID_CHAR_GLC_FEATURE),
+ },
+ 2, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ }
+
+ ,
+ /* <<Characteristic>>, .. */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_WRITE | /* characteristic properties */
+ GATT_CHAR_PROP_INDICATE)
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /*--- Glucose Record Access Control Point value ---*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_GLC_RACP),
+ HI_WORD(GATT_UUID_CHAR_GLC_RACP)
+ },
+ 0, /* bValueLen, 0 : variable length */
+ NULL,
+ GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */
+ },
+ /* client characteristic configuration */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* wFlags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ }
+};
+
+
+/**
+ * @brief Prepare a new record in database.
+ * @return void.
+ *
+ */
+void gls_prepare_new_record()
+{
+ PROFILE_PRINT_INFO4("gls_prepare_new_record database head: %d, tail: %d, num: %d, seq_num: %d\n",
+ glc_racp.record_db.head, glc_racp.record_db.tail, glc_racp.record_db.record_num,
+ glc_racp.record_db.seq_num);
+ p_new_record = &(glc_racp.record_db.records[glc_racp.record_db.tail]);
+ memset(p_new_record, 0, sizeof(T_PATIENT_RECORD));
+ glc_racp.record_db.seq_num++;
+ p_new_record->glc_measurement_value.seq_num = glc_racp.record_db.seq_num;
+#if GLC_MEASUREMENT_CONTEXT_SUPPORT
+ p_new_record->glc_measurement_context.seq_num = glc_racp.record_db.seq_num;
+#endif
+}
+
+/**
+ * @brief Push a new record into database.
+ * @return void.
+ *
+ */
+void gls_push_new_record()
+{
+ if (((glc_racp.record_db.head - glc_racp.record_db.tail + GLC_RACP_DATABASE_SIZE) %
+ GLC_RACP_DATABASE_SIZE) == 1)
+ {
+ glc_racp.record_db.head = (glc_racp.record_db.head + 1) % GLC_RACP_DATABASE_SIZE;
+ glc_racp.record_db.tail = (glc_racp.record_db.tail + 1) % GLC_RACP_DATABASE_SIZE;
+ }
+ else
+ {
+ glc_racp.record_db.tail = (glc_racp.record_db.tail + 1) % GLC_RACP_DATABASE_SIZE;
+ glc_racp.record_db.record_num++;
+ }
+ PROFILE_PRINT_INFO4("gls_push_new_record database head: %d, tail: %d, num: %d, seq_num: %d\n",
+ glc_racp.record_db.head, glc_racp.record_db.tail, glc_racp.record_db.record_num,
+ glc_racp.record_db.seq_num);
+}
+
+/**
+ * @brief Set a GLS parameter.
+ *
+ * NOTE: You can call this function with a gulcose service parameter type and it will set the
+ * gulcose service parameter. Glucose service parameters are defined in @ref T_GLS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Glucose service parameter type: @ref T_GLS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ T_GLC_MEASUREMENT_FLAG ms_flag =
+ {
+ 1, //time_offset
+ 1, //con_ts_loc
+ GLC_FLAGS_UNITS_MOL_L_ON, //con_units
+ 1, //ss_annuciation
+ 0, //ctxt_info_follows
+ 0 //rfu
+ };
+ gls_set_parameter(GLS_PARAM_GLC_MS_FLAG, 1, &ms_flag);
+ }
+ * \endcode
+ */
+bool gls_set_parameter(T_GLS_PARAM_TYPE param_type, uint8_t len, void *p_value)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ case GLS_PARAM_GLC_FEATURES:
+ if (len == 2)
+ {
+ LE_ARRAY_TO_UINT16(features, (uint8_t *) p_value);
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case GLS_PARAM_CTL_PNT_PROG_CLR:
+ glc_racp.ctrl_point.op_code = GLC_RACP_OPCODE_RESERVED;
+ gls_num_records_to_report = 0;
+ gls_current_record_to_report = 0;
+ gls_report_offset = 0;
+ gls_send_data_flag = 0;
+ gls_abort_flag = false; // Make sure Abort Flag is clear after RACP procedure is over!
+ gls_abort_by_app_flag = false; // Make sure Abort by App Flag is clear after RACP procedure is over!
+ break;
+ case GLS_PARAM_GLC_MS_FLAG:
+ if (len == 1)
+ {
+ memcpy(&(p_new_record->glc_measurement_value.flags), p_value, 1);
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case GLS_PARAM_GLC_MS_BASE_TIME:
+ if (len == sizeof(TIMESTAMP))
+ {
+ memcpy(p_new_record->glc_measurement_value.base_time, p_value, sizeof(TIMESTAMP));
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+#if (GLC_INCLUDE_TIME_OFFSET)
+ case GLS_PARAM_GLC_MS_TIME_OFFSET:
+ if (len == 2)
+ {
+ p_new_record->glc_measurement_value.time_offset = *(int16_t *)p_value;
+ p_new_record->glc_measurement_value.flags.time_offset = 1;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+#endif
+#if (GLC_INCLUDE_CONC_TS_LOC)
+ case GLS_PARAM_GLC_MS_CONCENTRATION:
+ if (len == sizeof(SFLOAT))
+ {
+ memcpy(&(p_new_record->glc_measurement_value.concentration), p_value, sizeof(SFLOAT));
+ p_new_record->glc_measurement_value.flags.con_ts_loc = 1;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case GLS_PARAM_GLC_MS_CONCENTRATION_UNITS:
+ if (len == 1)
+ {
+ p_new_record->glc_measurement_value.flags.con_units = *(uint8_t *)p_value;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case GLS_PARAM_GLC_MS_TYPE_SAMPLE_LOCATION:
+ if (len == 1)
+ {
+ p_new_record->glc_measurement_value.type_sample_location = *(uint8_t *)p_value;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+#endif
+#if (GLC_INCLUDE_SS_ANNUNC)
+ case GLS_PARAM_GLC_MS_SENSOR_STATUS_ANNUNCIATION:
+ if (len == 2)
+ {
+ memcpy(&(p_new_record->glc_measurement_value.ss_annunciation), p_value, 2);
+ p_new_record->glc_measurement_value.flags.ss_annuciation = 1;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+#endif
+#if GLC_MEASUREMENT_CONTEXT_SUPPORT
+ case GLS_PARAM_GLC_MS_CT_FLAG:
+ if (len == 1)
+ {
+ p_new_record->glc_measurement_context.flags = *(T_GLC_MSR_CTXT_FLAG *)p_value;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+#if (GLC_INCLUDE_CARBOHYDRATE)
+ case GLS_PARAM_GLC_MS_CT_CARBOHYDRATE_ID:
+ if (len == 1)
+ {
+ p_new_record->glc_measurement_context.carbohydrate_ID = *(uint8_t *)p_value;
+ p_new_record->glc_measurement_context.flags.carbohydrate = 1;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case GLS_PARAM_GLC_MS_CT_CARBOHYDRATE:
+ if (len == sizeof(SFLOAT))
+ {
+ memcpy(&(p_new_record->glc_measurement_context.carbohydrate), p_value, sizeof(SFLOAT));
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+#endif
+#if (GLC_INCLUDE_MEAL)
+ case GLS_PARAM_GLC_MS_CT_MEAL:
+ if (len == 1)
+ {
+ p_new_record->glc_measurement_context.meal = *(uint8_t *)p_value;
+ p_new_record->glc_measurement_context.flags.meal = 1;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+#endif
+#if (GLC_INCLUDE_TESTER_HEALTH)
+ case GLS_PARAM_GLC_MS_CT_TESTER_HEALTH:
+ if (len == 1)
+ {
+ p_new_record->glc_measurement_context.tester_health = *(uint8_t *)p_value;
+ p_new_record->glc_measurement_context.flags.tester_health = 1;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+#endif
+#if (GLC_INCLUDE_EXERCISE)
+ case GLS_PARAM_GLC_MS_CT_EXERCISE_DURATION:
+ if (len == 2)
+ {
+ LE_ARRAY_TO_UINT16(p_new_record->glc_measurement_context.exercise_duration, (uint8_t *)p_value);
+ p_new_record->glc_measurement_context.flags.exercise = 1;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case GLS_PARAM_GLC_MS_CT_EXERCISE_INTENSITY:
+ if (len == 1)
+ {
+ p_new_record->glc_measurement_context.exercise_intensity = *(uint8_t *)p_value;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+#endif
+#if (GLC_INCLUDE_MEDICATION)
+ case GLS_PARAM_GLC_MS_CT_MEDICATION_ID:
+ if (len == 1)
+ {
+ p_new_record->glc_measurement_context.medication_ID = *(uint8_t *)p_value;
+ p_new_record->glc_measurement_context.flags.medication = 1;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case GLS_PARAM_GLC_MS_CT_MEDICATION:
+ if (len == sizeof(SFLOAT))
+ {
+ memcpy(&(p_new_record->glc_measurement_context.medication), p_value, sizeof(SFLOAT));
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case GLS_PARAM_GLC_MS_CT_MEDICATION_UNITS:
+ if (len == 1)
+ {
+ p_new_record->glc_measurement_context.flags.medication_units = *(uint8_t *)p_value;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+#endif
+#if (GLC_INCLUDE_HbA1c)
+ case GLS_PARAM_GLC_MS_CT_HbA1c:
+ if (len == sizeof(SFLOAT))
+ {
+ memcpy(&(p_new_record->glc_measurement_context.hb_a1c), p_value, sizeof(SFLOAT));
+ p_new_record->glc_measurement_context.flags.hb_a1c = 1;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+#endif
+#endif
+ default:
+ ret = false;
+ break;
+ }
+
+ if (!ret)
+ {
+ PROFILE_PRINT_ERROR1("gls_set_parameter gls parameter set failed: %d\n", param_type);
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Get a GLS parameter.
+ *
+ * NOTE: You can call this function with a gulcose parameter type and it will get a
+ * gulcose parameter. Glucose parameters are defined in @ref T_GLS_PARAM_TYPE.
+ *
+ * @param[in] param_type Glucose parameter type: @ref T_GLS_PARAM_TYPE
+ * @param[in,out] len Pointer to the location to get the length of data.
+ * @param[in,out] p_value Pointer to the location to get the parameter value. This is dependent on
+ * the parameter type and will be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval GAP_CAUSE_SUCCESS Operation success.
+ * @retval GAP_CAUSE_INVALID_PARAM Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ int record_num;
+ gls_get_parameter(GLS_PARAM_RECORD_NUM, &len, &record_num);
+ }
+ * \endcode
+ */
+bool gls_get_parameter(T_GLS_PARAM_TYPE param_type, uint8_t *len, void *p_value)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ case GLS_PARAM_GLC_FEATURES:
+ *len = sizeof(uint16_t);
+ LE_UINT16_TO_ARRAY(p_value, features);
+ break;
+ case GLS_PARAM_RECORD_NUM:
+ *len = sizeof(int);
+ memcpy(p_value, &glc_racp.record_db.record_num, sizeof(int));
+ break;
+ case GLS_PARAM_RECORD_SEQ_NUM:
+ *len = sizeof(uint16_t);
+ memcpy(p_value, &glc_racp.record_db.seq_num, sizeof(uint16_t));
+ break;
+ default:
+ *len = 0;
+ ret = false;
+ break;
+ }
+
+ if (!ret)
+ {
+ PROFILE_PRINT_ERROR1("gls_get_parameter gls parameter get failed: %d\n", param_type);
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Send measurement notification data .
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] index Index.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t battery_level = 90;
+ bas_battery_level_value_notify(conn_id, bas_id, battery_level);
+ }
+ * \endcode
+ */
+bool gls_glc_measurement_notify(uint8_t conn_id, T_SERVER_ID service_id, uint8_t index)
+{
+ int current = (glc_racp.record_db.head + index) % GLC_RACP_DATABASE_SIZE;
+
+ gls_send_data_flag = 1;
+
+ T_GLC_MEASUREMENT_VALUE *pmeasurement_value =
+ &glc_racp.record_db.records[current].glc_measurement_value;
+ uint8_t temp_glc_measurement[sizeof(T_GLC_MEASUREMENT_VALUE)];
+ uint8_t offset = 0;
+ if (index >= glc_racp.record_db.record_num)
+ {
+ PROFILE_PRINT_ERROR0("gls_glc_measurement_notify glucose measurement value access overflow!");
+ return false;
+ }
+ if (current == glc_racp.record_db.tail)
+ {
+ PROFILE_PRINT_ERROR0("gls_glc_measurement_notify glucose measurement database: empty!");
+ return false;
+ }
+
+ memcpy(&temp_glc_measurement[offset], &pmeasurement_value->flags, 1);
+ offset += 1;
+ memcpy(&temp_glc_measurement[offset], &pmeasurement_value->seq_num, 2);
+ offset += 2;
+ memcpy(&temp_glc_measurement[offset], pmeasurement_value->base_time, 7);
+ offset += 7;
+
+#if (GLC_INCLUDE_TIME_OFFSET)
+ if (pmeasurement_value->flags.time_offset)
+ {
+ memcpy(&temp_glc_measurement[offset], &pmeasurement_value->time_offset, 2);
+ offset += 2;
+ }
+#endif
+#if (GLC_INCLUDE_CONC_TS_LOC)
+ if (pmeasurement_value->flags.con_ts_loc)
+ {
+ memcpy(&temp_glc_measurement[offset], pmeasurement_value->concentration, 2);
+ offset += 2;
+ memcpy(&temp_glc_measurement[offset], &pmeasurement_value->type_sample_location, 1);
+ offset += 1;
+ }
+#endif
+#if (GLC_INCLUDE_SS_ANNUNC)
+ if (pmeasurement_value->flags.ss_annuciation)
+ {
+ memcpy(&temp_glc_measurement[offset], &pmeasurement_value->ss_annunciation, 2);
+ offset += 2;
+ }
+#endif
+ PROFILE_PRINT_INFO1("gls_glc_measurement_notify glucose measurement notification: index = %d \n",
+ index);
+ // send notification to client
+ return server_send_data(conn_id, service_id, GLS_CHAR_GLC_MEASUREMENT_INDEX, temp_glc_measurement,
+ offset, GATT_PDU_TYPE_NOTIFICATION);
+}
+
+#if GLC_MEASUREMENT_CONTEXT_SUPPORT
+/**
+ * @brief Send measurement context notification data .
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] index Index.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t battery_level = 90;
+ bas_battery_level_value_notify(conn_id, bas_id, battery_level);
+ }
+ * \endcode
+ */
+bool gls_glc_measurement_context_notify(uint8_t conn_id, T_SERVER_ID service_id, uint8_t index)
+{
+ int current = (glc_racp.record_db.head + index) % GLC_RACP_DATABASE_SIZE;
+
+ gls_send_data_flag = 2;
+
+ T_GLC_MEASUREMENT_CONTEXT *pmeasurement_context =
+ &glc_racp.record_db.records[current].glc_measurement_context;
+ uint8_t temp_glc_measurement_ctxt[sizeof(T_GLC_MEASUREMENT_CONTEXT)];
+ uint8_t offset = 0;
+ if (index >= glc_racp.record_db.record_num)
+ {
+ PROFILE_PRINT_ERROR0("gls_glc_measurement_context_notify glucose measurement context access overflow!");
+ return false;
+ }
+ if (current == glc_racp.record_db.tail)
+ {
+ PROFILE_PRINT_ERROR0("gls_glc_measurement_context_notify glucose measurement database: Empty!");
+ return false;
+ }
+
+ memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->flags, 1);
+ offset += 1;
+ memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->seq_num, 2);
+ offset += 2;
+#if (GLC_INCLUDE_EXT_FLAGS)
+ if (pmeasurement_context->flags.ext_flags)
+ {
+ memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->ext_flags, 1);
+ offset += 1;
+ }
+#endif
+#if (GLC_INCLUDE_CARBOHYDRATE)
+ if (pmeasurement_context->flags.carbohydrate)
+ {
+ memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->carbohydrate_ID, 1);
+ offset += 1;
+ memcpy(&temp_glc_measurement_ctxt[offset], pmeasurement_context->carbohydrate, 2);
+ offset += 2;
+ }
+#endif
+#if (GLC_INCLUDE_MEAL)
+ if (pmeasurement_context->flags.meal)
+ {
+ memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->meal, 1);
+ offset += 1;
+ }
+#endif
+#if (GLC_INCLUDE_TESTER_HEALTH)
+ if (pmeasurement_context->flags.tester_health)
+ {
+ memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->tester_health, 1);
+ offset += 1;
+ }
+#endif
+#if (GLC_INCLUDE_EXERCISE)
+ if (pmeasurement_context->flags.exercise)
+ {
+ memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->exercise_duration, 2);
+ offset += 2;
+ memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->exercise_intensity, 1);
+ offset += 1;
+ }
+#endif
+#if (GLC_INCLUDE_MEDICATION)
+ if (pmeasurement_context->flags.medication)
+ {
+ memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->medication_ID, 1);
+ offset += 1;
+ memcpy(&temp_glc_measurement_ctxt[offset], pmeasurement_context->medication, 2);
+ offset += 2;
+ }
+#endif
+#if (GLC_INCLUDE_HbA1c)
+ if (pmeasurement_context->flags.hb_a1c)
+ {
+ memcpy(&temp_glc_measurement_ctxt[offset], pmeasurement_context->hb_a1c, 2);
+ offset += 2;
+ }
+#endif
+ PROFILE_PRINT_INFO1("gls_glc_measurement_context_notify glucose measurement context notification: index = %d \n",
+ index);
+ // send notification to client
+ return server_send_data(conn_id, service_id, GLS_CHAR_GLC_MEASUREMENT_CONTEXT_INDEX,
+ temp_glc_measurement_ctxt, offset, GATT_PDU_TYPE_NOTIFICATION);
+}
+#endif
+
+/**
+ * @brief Indicate glucose racp procedure result to client.
+ *
+ * @param[in] service_id Service ID to notify.
+ * @param[in] rsp_code racp respondence code.
+ * @return Result of indication.
+ * @retval 0 FALSE
+ * @retval 1 TRUE
+ */
+bool gls_racp_response(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code)
+{
+ bool ret;
+
+ gls_send_data_flag = 3;
+
+ uint16_t attrib_index = GLS_CHAR_GLC_RACP_INDEX;
+
+ glc_racp.ctrl_point.operand[0] = glc_racp.ctrl_point.op_code;
+ glc_racp.ctrl_point.operand[1] = rsp_code;
+ glc_racp.ctrl_point.op_code = GLC_RACP_OPCODE_RESP_CODE;
+ glc_racp.ctrl_point.op = GLC_RACP_OPERATOR_NULL;
+
+ glc_racp.cp_length = sizeof(T_GLC_CTRL_POINT_OPCODE) + sizeof(T_GLC_CTRL_POINT_OPERATOR) + sizeof(
+ T_GLC_CTRL_POINT_OPCODE) + sizeof(T_GLC_CTRL_POINT_RESP_CODES);
+
+ // send indication to client
+ ret = server_send_data(conn_id, service_id, attrib_index, (uint8_t *) &glc_racp.ctrl_point,
+ glc_racp.cp_length, GATT_PDU_TYPE_INDICATION);
+ PROFILE_PRINT_INFO1("gls_racp_response glucose racp resp: %d \n", rsp_code);
+
+ //glc_racp.ctrl_point.op_code = GLC_RACP_OPCODE_RESERVED;
+
+ return ret;
+}
+
+/**
+ * @brief Indicate number of glucose records to client.
+ *
+ * @param[in] service_id Service ID to notify.
+ * @param[in] num Number of glucose records.
+ * @return Result of indication.
+ * @retval 0 FALSE
+ * @retval 1 TRUE
+ */
+bool gls_racp_num_response(uint8_t conn_id, T_SERVER_ID service_id, uint16_t num)
+{
+ bool ret;
+
+ gls_send_data_flag = 3;
+
+ uint16_t attrib_index = GLS_CHAR_GLC_RACP_INDEX;
+
+ LE_UINT16_TO_ARRAY(glc_racp.ctrl_point.operand, num);
+ glc_racp.ctrl_point.op_code = GLC_RACP_OPCODE_NBR_OF_RECS_RESP;
+ glc_racp.ctrl_point.op = GLC_RACP_OPERATOR_NULL;
+
+ glc_racp.cp_length = sizeof(T_GLC_CTRL_POINT_OPCODE) + sizeof(T_GLC_CTRL_POINT_OPERATOR) + sizeof(
+ uint16_t);
+
+ // send indication to client
+ ret = server_send_data(conn_id, service_id, attrib_index, (uint8_t *) &glc_racp.ctrl_point,
+ glc_racp.cp_length, GATT_PDU_TYPE_INDICATION);
+ PROFILE_PRINT_INFO1("gls_racp_num_response glucose racp num response: %d \n", num);
+
+ //glc_racp.ctrl_point.op_code = GLC_RACP_OPCODE_RESERVED;
+
+ return ret;
+}
+
+/**
+ * @brief Indication in abort procedure.
+ *
+ * @param[in] service_id Service ID to notify.
+ * @return Result of indication.
+ * @retval 0 FALSE
+ * @retval 1 TRUE
+ */
+bool gls_abort_success_response(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ glc_racp.ctrl_point.op_code = GLC_RACP_OPCODE_ABORT_OPERATION;
+
+ PROFILE_PRINT_INFO0("gls_abort_success_response gls racp procedure has been aborted!");
+
+ return gls_racp_response(conn_id, service_id, GLC_RACP_RESP_SUCCESS);
+}
+
+/**
+ * @brief Compare two timestamps.
+ *
+ * @param[in] time1 Time to compare.
+ * @param[in] time2 Time to compare.
+ * @return Result of comparison.
+ * @retval 1 Time1 > Time2
+ * @retval 0 Time1 = Time2
+ * @retval -1 Time1 < Time2
+ */
+int time_cmp(const TIMESTAMP time1, const TIMESTAMP time2)
+{
+ uint16_t year1, year2;
+ LE_ARRAY_TO_UINT16(year1, (uint8_t *) time1);
+ LE_ARRAY_TO_UINT16(year2, (uint8_t *) time2);
+ if (year1 < year2)
+ {
+ return -1;
+ }
+ else if (year1 > year2)
+ {
+ return 1;
+ }
+ else
+ {
+ int length;
+ for (length = 0; length < 5; length++)
+ {
+ if (time1[2 + length] < time2[2 + length])
+ {
+ return -1;
+ }
+ else if (time1[2 + length] > time2[2 + length])
+ {
+ return 1;
+ }
+ else
+ ;
+ }
+ return 0;
+ }
+}
+
+/**
+ * @brief Calculate user facing time by adding basetime and timeoffset.
+ *
+ *
+ * @param[in] time_in Connection id.
+ * @param[in] time_offset Service id.
+ * @param[in] time_out Battery level value.
+ * @return void.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ user_face_time(time, 30, time);
+ }
+ * \endcode
+ */
+void user_face_time(TIMESTAMP time_in, int16_t time_offset, TIMESTAMP time_out)
+{
+ uint8_t carry;
+ uint16_t year;
+ LE_ARRAY_TO_UINT16(year, (uint8_t *) time_in);
+
+ TIMESTAMP time_tmp = {0};
+ time_tmp[4] = time_offset / 60; //hour
+ time_tmp[5] = time_offset % 60; //minute
+
+ time_out[6] = time_in[6] + time_tmp[6]; //second
+ carry = 0;
+
+ time_out[5] = time_in[5] + time_tmp[5] + carry; //minute
+ if (time_out[5] > 59)
+ {
+ time_out[5] -= 60;
+ carry = 1;
+ }
+ else
+ {
+ carry = 0;
+ }
+
+ time_out[4] = time_in[4] + time_tmp[4] + carry; //hour
+ if (time_out[4] > 23)
+ {
+ time_out[4] -= 24;
+ carry = 1;
+ }
+ else
+ {
+ carry = 0;
+ }
+
+ time_out[3] = time_in[3] + time_tmp[3] + carry; //day
+
+// switch (time_out[2])
+// {
+// case 2:
+// if(((year % 400) == 0) || (((year % 4) == 0) &&((year % 100) != 0))) //leap year
+// {
+// if(time_out[3] > 29)
+// {
+// time_out[3] -= 29;
+// carry = 1;
+// }
+// else
+// {
+// carry = 0;
+// }
+// }
+// else
+// {
+// if(time_out[3] > 28)
+// {
+// time_out[3] -= 28;
+// carry = 1;
+// }
+// else
+// {
+// carry = 0;
+// }
+// }
+// break;
+// case 1:
+// case 3:
+// case 5:
+// case 7:
+// case 8:
+// case 10:
+// case 12:
+// if(time_out[3] > 31)
+// {
+// time_out[3] -= 31;
+// carry = 1;
+// }
+// else
+// {
+// carry = 0;
+// }
+// break;
+// case 4:
+// case 6:
+// case 9:
+// case 11:
+// if(time_out[3] > 30)
+// {
+// time_out[3] -= 30;
+// carry = 1;
+// }
+// else
+// {
+// carry = 0;
+// }
+// break;
+// default:
+// break;
+// }
+
+ uint8_t month_leap[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+ uint8_t month_common[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+ if (((year % 400) == 0) || (((year % 4) == 0) && ((year % 100) != 0))) //leap year
+ {
+ if (time_out[3] > month_leap[time_out[2]])
+ {
+ time_out[3] -= month_leap[time_out[2]];
+ carry = 1;
+ }
+ else
+ {
+ carry = 0;
+ }
+ }
+ else
+ {
+ if (time_out[3] > month_common[time_out[2]])
+ {
+ time_out[3] -= month_common[time_out[2]];
+ carry = 1;
+ }
+ else
+ {
+ carry = 0;
+ }
+ }
+
+ time_out[2] = time_in[2] + time_tmp[2] + carry; //month
+
+ if (time_out[2] > 12)
+ {
+ time_out[2] -= 12;
+ carry = 1;
+ }
+ else
+ {
+ carry = 0;
+ }
+
+ uint16_t year_in;
+ uint16_t year_tmp;
+ LE_ARRAY_TO_UINT16(year_in, (uint8_t *) time_in);
+ LE_ARRAY_TO_UINT16(year_tmp, (uint8_t *) time_tmp);
+ LE_UINT16_TO_ARRAY(time_out, year_in + year_tmp + carry); //year
+}
+
+/**
+ * @brief Check the write parameters of RACP, used in report/report num/delete opcode
+ * @returen None
+ */
+T_GLC_CTRL_POINT_RESP_CODES gls_racp_check()
+{
+ T_GLC_CTRL_POINT_RESP_CODES ret = GLC_RACP_RESP_SUCCESS;
+
+ PROFILE_PRINT_INFO3("gls_racp_check glucose racp: opcode = %d, operator = %d, length = %d \n",
+ glc_racp.ctrl_point.op_code, glc_racp.ctrl_point.op, glc_racp.cp_length);
+
+ if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_NULL)
+ {
+ ret = GLC_RACP_RESP_INVALID_OPERATOR;
+ }
+ else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_ALL_RECS
+ || glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_FIRST
+ || glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_LAST)
+ {
+ if (glc_racp.cp_length != 2)
+ {
+ ret = GLC_RACP_RESP_INVALID_OPERAND;
+ }
+ }
+ else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_LT_EQ
+ || glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_GT_EQ
+ || glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_RANGE)
+ {
+ if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_RESERVED)
+ {
+ ret = GLC_RACP_RESP_INVALID_OPERAND;
+ }
+ else if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_SEQ_NBR)
+ {
+ if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_RANGE)
+ {
+ uint16_t min_seq;
+ uint16_t max_seq;
+ LE_ARRAY_TO_UINT16(min_seq, &glc_racp.ctrl_point.operand[1]);
+ LE_ARRAY_TO_UINT16(max_seq, &glc_racp.ctrl_point.operand[1 + sizeof(uint16_t)]);
+ if (min_seq > max_seq)
+ {
+ ret = GLC_RACP_RESP_INVALID_OPERAND;
+ }
+ }
+ }
+ else if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_TIME)
+ {
+ if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_RANGE)
+ {
+ if (time_cmp(&glc_racp.ctrl_point.operand[1],
+ &glc_racp.ctrl_point.operand[1 + sizeof(TIMESTAMP)]) > 0)
+ {
+ ret = GLC_RACP_RESP_INVALID_OPERAND;
+ }
+ }
+ }
+ else
+ {
+ /** glc_racp.ctrl_point.operand[0] > GLC_RACP_FILTER_TYPE_TIME */
+ ret = GLC_RACP_RESP_OPERAND_NOT_SUPPORTED;
+ }
+ }
+ else
+ {
+ /** glc_racp.ctrl_point.operator > GLC_RACP_OPERATOR_LAST */
+ ret = GLC_RACP_RESP_OPERATOR_NOT_SUPPORTED;
+ }
+ return ret;
+}
+
+/**
+ * @brief Find record by sequence number
+ * @param[in] op operator of the procedure.
+ * @param[in] set_seq sequence number referenced to.
+ * @return Absolute position of the found record
+ */
+int gls_find_records_by_seq_num(T_GLC_CTRL_POINT_OPERATOR op, uint16_t set_seq)
+{
+ int find;
+ if (op == GLC_RACP_OPERATOR_LT_EQ)
+ {
+ find = glc_racp.record_db.head;
+ while ((find != glc_racp.record_db.tail) &&
+ (glc_racp.record_db.records[find].glc_measurement_value.seq_num <= set_seq))
+ {
+ find = (find + 1) % GLC_RACP_DATABASE_SIZE;
+ }
+ if (find == glc_racp.record_db.head) /**< no record found */
+ {
+ find = glc_racp.record_db.tail;
+ }
+ else
+ {
+ find -= 1; /**< record large than set_seq is found */
+ }
+ }
+ else if (op == GLC_RACP_OPERATOR_GT_EQ)
+ {
+ find = glc_racp.record_db.head;
+ while ((find != glc_racp.record_db.tail) &&
+ (glc_racp.record_db.records[find].glc_measurement_value.seq_num < set_seq))
+ {
+ find = (find + 1) % GLC_RACP_DATABASE_SIZE;
+ }
+ }
+ else
+ {
+ find = glc_racp.record_db.tail;
+ }
+ return find;
+}
+
+/**
+ * @brief Find record by timestamp
+ * @brief Should time_offset be taken into consideration when comparing user-interface time?
+ * PTS test shows that when writing the RACP using the User Facing Time filter type there is no timeoffset part.
+ * @param[in] op operator of the procedure.
+ * @param[in] set_time time referenced to.
+ * @return Absolute position of the found record
+ */
+int gls_find_records_by_time(T_GLC_CTRL_POINT_OPERATOR op, TIMESTAMP set_time)
+{
+ int find;
+ //TIMESTAMP user_time;
+ if (op == GLC_RACP_OPERATOR_LT_EQ)
+ {
+ find = glc_racp.record_db.head;
+ while (find != glc_racp.record_db.tail)
+ {
+ //user_face_time(glc_racp.record_db.records[find].glc_measurement_value.base_time, TimeOffset, user_time);
+ //user_face_time(glc_racp.record_db.records[find].glc_measurement_value.base_time, glc_racp.record_db.records[find].glc_measurement_value.time_offset, user_time);
+ //if (time_cmp(user_time, set_time) <= 0)
+ if (time_cmp(glc_racp.record_db.records[find].glc_measurement_value.base_time, set_time) <= 0)
+ {
+ find = (find + 1) % GLC_RACP_DATABASE_SIZE;
+ }
+ else
+ {
+ break;
+ }
+ }
+ if (find == glc_racp.record_db.head) /**< no record found */
+ {
+ find = glc_racp.record_db.tail;
+ }
+ else
+ {
+ find -= 1; /**< record large than set_seq is found */
+ }
+ }
+ else if (op == GLC_RACP_OPERATOR_GT_EQ)
+ {
+ find = glc_racp.record_db.head;
+ while (find != glc_racp.record_db.tail)
+ {
+ //user_face_time(glc_racp.record_db.records[find].glc_measurement_value.base_time, TimeOffset, user_time);
+ //user_face_time(glc_racp.record_db.records[find].glc_measurement_value.base_time, glc_racp.record_db.records[find].glc_measurement_value.time_offset, user_time);
+ //if (time_cmp(user_time, set_time) < 0)
+ if (time_cmp(glc_racp.record_db.records[find].glc_measurement_value.base_time, set_time) < 0)
+ {
+ find = (find + 1) % GLC_RACP_DATABASE_SIZE;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ find = glc_racp.record_db.tail;
+ }
+ return find;
+}
+
+/**
+ * @brief Find records that meets the conditions.
+ * @param[out] pnum num of records
+ * @param[out] pfirst absolute position of the first record
+ * @param[out] plast absolute position of the last record
+ * @return The check result of the procedure.
+ */
+T_GLC_CTRL_POINT_RESP_CODES gls_find_records(uint16_t *p_num, int *p_first, int *p_last)
+{
+ uint16_t num_of_records = 0;
+ int find1 = 0;
+ int find2 = 0;
+ T_GLC_CTRL_POINT_RESP_CODES ret;
+ ret = gls_racp_check();
+ if (ret == GLC_RACP_RESP_SUCCESS)
+ {
+ if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_ALL_RECS)
+ {
+ find1 = glc_racp.record_db.head;
+ find2 = (glc_racp.record_db.tail - 1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE;
+ num_of_records = glc_racp.record_db.record_num;
+ }
+ else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_LT_EQ)
+ {
+ find1 = glc_racp.record_db.head;
+ if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_SEQ_NBR)
+ {
+ uint16_t seq;
+ LE_ARRAY_TO_UINT16(seq, &glc_racp.ctrl_point.operand[1]);
+ find2 = gls_find_records_by_seq_num(GLC_RACP_OPERATOR_LT_EQ, seq);
+ }
+ else if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_TIME)
+ {
+ find2 = gls_find_records_by_time(GLC_RACP_OPERATOR_LT_EQ, &glc_racp.ctrl_point.operand[1]);
+ }
+ else
+ {
+ find2 = glc_racp.record_db.tail;
+ }
+ if (find2 == glc_racp.record_db.tail)
+ {
+ num_of_records = 0;
+ }
+ else
+ {
+ num_of_records = (find2 - glc_racp.record_db.head + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE
+ + 1;
+ }
+ }
+ else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_GT_EQ)
+ {
+ if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_SEQ_NBR)
+ {
+ uint16_t seq;
+ LE_ARRAY_TO_UINT16(seq, &glc_racp.ctrl_point.operand[1]);
+ find1 = gls_find_records_by_seq_num(GLC_RACP_OPERATOR_GT_EQ, seq);
+ }
+ else if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_TIME)
+ {
+ find1 = gls_find_records_by_time(GLC_RACP_OPERATOR_GT_EQ, &glc_racp.ctrl_point.operand[1]);
+ }
+ else
+ {
+ find1 = glc_racp.record_db.tail;
+ }
+ find2 = (glc_racp.record_db.tail - 1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE;
+ num_of_records = (glc_racp.record_db.tail - find1 + GLC_RACP_DATABASE_SIZE) %
+ GLC_RACP_DATABASE_SIZE;
+ }
+ else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_RANGE)
+ {
+ if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_SEQ_NBR)
+ {
+ uint16_t seq1;
+ uint16_t seq2;
+ LE_ARRAY_TO_UINT16(seq1, &glc_racp.ctrl_point.operand[1]);
+ LE_ARRAY_TO_UINT16(seq2, &glc_racp.ctrl_point.operand[1 + 2]);
+
+ find1 = gls_find_records_by_seq_num(GLC_RACP_OPERATOR_GT_EQ, seq1);
+ find2 = gls_find_records_by_seq_num(GLC_RACP_OPERATOR_LT_EQ, seq2);
+ }
+ else if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_TIME)
+ {
+ find1 = gls_find_records_by_time(GLC_RACP_OPERATOR_GT_EQ, &glc_racp.ctrl_point.operand[1]);
+ find2 = gls_find_records_by_time(GLC_RACP_OPERATOR_LT_EQ,
+ &glc_racp.ctrl_point.operand[1 + sizeof(TIMESTAMP)]);
+ }
+ else
+ {
+ find1 = glc_racp.record_db.tail;
+ find2 = glc_racp.record_db.tail;
+ }
+ if (find1 == glc_racp.record_db.tail || find2 == glc_racp.record_db.tail)
+ {
+ num_of_records = 0;
+ }
+ else
+ {
+ num_of_records = (find2 - find1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE + 1;
+ }
+ }
+ else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_FIRST)
+ {
+ find1 = glc_racp.record_db.head;
+ find2 = find1;
+ if (glc_racp.record_db.record_num == 0)
+ {
+ num_of_records = 0;
+ }
+ else
+ {
+ num_of_records = 1;
+ }
+ }
+ else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_LAST)
+ {
+ find1 = (glc_racp.record_db.tail - 1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE;
+ find2 = find1;
+ if (glc_racp.record_db.record_num == 0)
+ {
+ num_of_records = 0;
+ }
+ else
+ {
+ num_of_records = 1;
+ }
+ }
+ else
+ {
+ ret = GLC_RACP_RESP_OPERATOR_NOT_SUPPORTED;
+ return ret;
+ }
+
+ if (p_num != 0)
+ {
+ *p_num = num_of_records;
+ }
+ if (p_first != 0)
+ {
+ *p_first = find1;
+ }
+ if (p_last != 0)
+ {
+ *p_last = find2;
+ }
+ PROFILE_PRINT_INFO3("gls_find_records glucose find records: num = %d, start = %d, end = %d\n",
+ num_of_records, find1, find2);
+ }
+ return ret;
+}
+
+/**
+ * @brief Report number of records that meet the conditions.
+ * @param[in] service_id The service ID of glucose service
+ * @return None
+ */
+void gls_report_num_of_records(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ T_GLC_CTRL_POINT_RESP_CODES ret;
+ uint16_t num_of_records;
+ int find1, find2;
+ ret = gls_find_records(&num_of_records, &find1, &find2);
+ if (ret != GLC_RACP_RESP_SUCCESS)
+ {
+ gls_racp_response(conn_id, service_id, ret);
+ }
+ else
+ {
+ gls_racp_num_response(conn_id, service_id, num_of_records);
+ }
+}
+
+/**
+ * @brief Report record
+ * @param[in] service_ID The service ID of glucose service
+ * @param[in] index The index of record
+ * Attention: For the purpose of good user experience, the input parameter index of this function is the offset of the head, not the pointer of data record.
+ */
+void gls_report_record(uint8_t conn_id, T_SERVER_ID service_id, int index)
+{
+ PROFILE_PRINT_INFO1("gls_report_record: %d\n", index);
+ gls_glc_measurement_notify(conn_id, service_id, index);
+#if GLC_MEASUREMENT_CONTEXT_SUPPORT
+ int current = (glc_racp.record_db.head + index) % GLC_RACP_DATABASE_SIZE;
+ if (glc_racp.record_db.records[current].glc_measurement_value.flags.ctxt_info_follows == 1)
+ {
+ gls_glc_measurement_context_notify(conn_id, service_id, index);
+ }
+#endif
+}
+
+/**
+ * @brief Report records that meet the conditions.
+ * @param[in] service_id The service ID of glucose service
+ * @return None
+ */
+void gls_report_records(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ T_GLC_CTRL_POINT_RESP_CODES ret;
+ uint16_t num_of_records;
+ int find1, find2;
+ ret = gls_find_records(&num_of_records, &find1, &find2);
+ if (ret == GLC_RACP_RESP_SUCCESS)
+ {
+ if (num_of_records == 0)
+ {
+ ret = GLC_RACP_RESP_NO_RECS_FOUND;
+ gls_racp_response(conn_id, service_id, ret);
+ }
+ else
+ {
+// int offset = (find1 - glc_racp.record_db.head + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE;
+// for (int index = 0; index < num_of_records; index++)
+// {
+// gls_report_record(service_ID, offset + index); // attention!
+// VoidCheckAbortFlag();
+// }
+ gls_report_offset = (find1 - glc_racp.record_db.head + GLC_RACP_DATABASE_SIZE) %
+ GLC_RACP_DATABASE_SIZE;
+ gls_num_records_to_report = num_of_records;
+ gls_current_record_to_report = 0;
+ if (false == gls_report_records_task(conn_id, service_id))
+ {
+ gls_set_parameter(GLS_PARAM_CTL_PNT_PROG_CLR, 0, NULL);
+ }
+ }
+ }
+ else
+ {
+ gls_racp_response(conn_id, service_id, ret);
+ }
+}
+
+/**
+ * @brief Report records sub procedure.
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t battery_level = 90;
+ bas_battery_level_value_notify(conn_id, bas_id, battery_level);
+ }
+ * \endcode
+ */
+bool gls_report_records_task(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ bool ret = true;
+ if (gls_abort_flag == true)
+ {
+ PROFILE_PRINT_INFO2("gls_report_records_task Glucose current record = %d, total = %d, procedure abort successfully!\n",
+ gls_current_record_to_report, gls_num_records_to_report);
+ gls_current_record_to_report = gls_num_records_to_report; // stop transmitting any data
+ ret = gls_abort_success_response(conn_id, service_id);
+ gls_abort_flag = false;
+ gls_abort_by_app_flag = false; // Abort procedure first, prior to abort by application
+ return ret;
+ }
+
+ if (gls_abort_by_app_flag == true)
+ {
+ PROFILE_PRINT_INFO2("gls_report_records_task Glucose current record = %d, total = %d, procedure abort by app successfully!\n",
+ gls_current_record_to_report, gls_num_records_to_report);
+ gls_current_record_to_report = gls_num_records_to_report; // stop transmitting any data
+ ret = gls_racp_response(conn_id, service_id, GLC_RACP_RESP_PROC_NOT_COMPLETED);
+ gls_abort_by_app_flag = false;
+ return ret;
+ }
+
+ PROFILE_PRINT_INFO3("gls_report_records_task Glucose report records, current = %d, total = %d, gls_send_data_flag = %d\n",
+ gls_current_record_to_report, gls_num_records_to_report, gls_send_data_flag);
+
+ if (gls_send_data_flag == 1)
+ {
+#if GLC_MEASUREMENT_CONTEXT_SUPPORT
+ int current = (glc_racp.record_db.head + gls_report_offset + gls_current_record_to_report) %
+ GLC_RACP_DATABASE_SIZE;
+ if (glc_racp.record_db.records[current].glc_measurement_value.flags.ctxt_info_follows == 1)
+ {
+ ret = gls_glc_measurement_context_notify(conn_id, service_id,
+ gls_report_offset + gls_current_record_to_report);
+ }
+#endif
+ gls_current_record_to_report += 1;
+
+ }
+ if (gls_send_data_flag == 2) // Glucose measurement context has been sent.
+ {
+ return ret;
+ }
+ if (gls_current_record_to_report < gls_num_records_to_report)
+ {
+ ret = gls_glc_measurement_notify(conn_id, service_id,
+ gls_report_offset + gls_current_record_to_report);
+ }
+ else
+ {
+ if (gls_send_data_flag != 3)
+ {
+ ret = gls_racp_response(conn_id, service_id, GLC_RACP_RESP_SUCCESS);
+ }
+ else // clear control point
+ {
+ gls_set_parameter(GLS_PARAM_CTL_PNT_PROG_CLR, 0, NULL);
+ }
+ }
+ return ret;
+}
+
+/**
+ * @brief Delete records that meet the conditions.
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id The service ID of glucose service
+ * @return None
+ */
+void gls_delete_records(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ T_GLC_CTRL_POINT_RESP_CODES ret;
+ uint16_t num_of_records;
+ int find1, find2;
+ ret = gls_find_records(&num_of_records, &find1, &find2);
+
+ PROFILE_PRINT_INFO3("gls_delete_records glucose delete records: num = %d, start = %d, end = %d\n",
+ num_of_records, find1, find2);
+ if (ret == GLC_RACP_RESP_SUCCESS)
+ {
+ if (num_of_records > 0)
+ {
+ if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_ALL_RECS)
+ {
+ glc_racp.record_db.head = glc_racp.record_db.tail;
+ glc_racp.record_db.record_num = 0;
+ }
+ else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_LT_EQ)
+ {
+ glc_racp.record_db.head = (find2 + 1) % GLC_RACP_DATABASE_SIZE;
+ glc_racp.record_db.record_num -= num_of_records;
+ }
+ else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_GT_EQ)
+ {
+ glc_racp.record_db.tail = find1;
+ glc_racp.record_db.record_num -= num_of_records;
+ }
+ else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_RANGE)
+ {
+ int front = (find1 - glc_racp.record_db.head + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE;
+ int back = (glc_racp.record_db.tail - find2 - 1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE;
+ int num2move, move_from, move_to, loop;
+ if (front > back)
+ {
+ num2move = back;
+ move_from = (find2 + 1) % GLC_RACP_DATABASE_SIZE;
+ move_to = find1;
+ for (loop = 0; loop < num2move; loop++)
+ {
+ glc_racp.record_db.records[move_to] = glc_racp.record_db.records[move_from];
+ move_from = (move_from + 1) % GLC_RACP_DATABASE_SIZE;
+ move_to = (move_to + 1) % GLC_RACP_DATABASE_SIZE;
+ }
+ glc_racp.record_db.tail = (glc_racp.record_db.tail - num_of_records + GLC_RACP_DATABASE_SIZE) %
+ GLC_RACP_DATABASE_SIZE;
+ glc_racp.record_db.record_num -= num_of_records;
+ }
+ else
+ {
+ num2move = front;
+ move_from = (find1 - 1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE;
+ move_to = find2;
+ for (loop = 0; loop < num2move; loop++)
+ {
+ glc_racp.record_db.records[move_to] = glc_racp.record_db.records[move_from];
+ move_from = (move_from - 1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE;
+ move_to = (move_to - 1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE;
+ }
+ glc_racp.record_db.head = (glc_racp.record_db.head + num_of_records) % GLC_RACP_DATABASE_SIZE;
+ glc_racp.record_db.record_num -= num_of_records;
+ }
+ }
+ else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_FIRST)
+ {
+ glc_racp.record_db.head = (glc_racp.record_db.head + 1) % GLC_RACP_DATABASE_SIZE;
+ glc_racp.record_db.record_num -= 1;
+ }
+ else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_LAST)
+ {
+ glc_racp.record_db.tail = (glc_racp.record_db.tail - 1 + GLC_RACP_DATABASE_SIZE) %
+ GLC_RACP_DATABASE_SIZE;
+ glc_racp.record_db.record_num -= 1;
+ }
+ else
+ {
+ ret = GLC_RACP_RESP_OPERAND_NOT_SUPPORTED;
+ }
+ }
+ else
+ {
+ ret = GLC_RACP_RESP_NO_RECS_FOUND;
+ }
+ }
+ gls_racp_response(conn_id, service_id, ret);
+}
+
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID of characteristic data.
+ * @param[in] attrib_index Attribute index of getting characteristic data.
+ * @param[in] offset Used for Blob Read.
+ * @param[in,out] p_length length of getting characteristic data.
+ * @param[in,out] pp_value data got from service.
+ * @return Profile procedure result
+ */
+T_APP_RESULT gls_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ T_GLS_CALLBACK_DATA gls_upsteam_msg;
+ PROFILE_PRINT_INFO2("gls_attr_read_cb attribIndex = %d offset %x", attrib_index, offset);
+ *p_length = 0;
+ switch (attrib_index)
+ {
+ case GLS_CHAR_GLC_FEATURE_INDEX:
+ {
+ /* Notify Application. */
+ if (pfn_gls_cb)
+ {
+ gls_upsteam_msg.msg_data.read_value_index = GLS_EVT_READ_FEATURE;
+ gls_upsteam_msg.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ pfn_gls_cb(service_id, (void *)&gls_upsteam_msg);
+ }
+ *pp_value = (uint8_t *) &features;
+ *p_length = sizeof(features);
+ }
+ break;
+ default:
+ {
+ PROFILE_PRINT_ERROR1("gls_attr_read_cb, attr not found, index=%d", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ break;
+ }
+ return cause;
+}
+
+/**
+ * @brief handle control point write (request).
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param[in] write_length Write request data length.
+ * @param[in] p_value Pointer to write request data.
+ * @return none
+ * @retval void
+ */
+static void gls_ctl_pnt_write_ind_post_proc(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index, uint16_t write_length, uint8_t *p_value)
+{
+ T_GLS_CALLBACK_DATA GLS_upsteam_msg;
+ /** check if there is any operation running */
+ if (write_length > sizeof(T_GLC_CONTROL_POINT))
+ {
+ PROFILE_PRINT_ERROR1("gls_ctl_pnt_write_ind_post_proc GLS Control Point request error: OpCode=0x%x, invalid write length!",
+ p_value[0]);
+ return;
+ }
+
+ PROFILE_PRINT_INFO4("gls_ctl_pnt_write_ind_post_proc Write GLS Control Point: OpCode = %d, operator = %d, length = %d, filter type = %d",
+ p_value[0], p_value[1], write_length, p_value[2]);
+
+ /* Notify Application. */
+ if (pfn_gls_cb)
+ {
+ GLS_upsteam_msg.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ memset(&GLS_upsteam_msg.msg_data.write, 0, sizeof(T_GLC_CONTROL_POINT));
+ memcpy(&GLS_upsteam_msg.msg_data.write, p_value, write_length);
+ pfn_gls_cb(service_id, (void *)&GLS_upsteam_msg);
+ }
+
+ if (p_value[0] != GLC_RACP_OPCODE_ABORT_OPERATION)
+ {
+ memset(&glc_racp.ctrl_point, 0, sizeof(T_GLC_CONTROL_POINT));
+ memcpy(&glc_racp.ctrl_point, p_value, write_length);
+ glc_racp.cp_length = write_length;
+ switch (glc_racp.ctrl_point.op_code)
+ {
+ case GLC_RACP_OPCODE_REPORT_NBR_OF_RECS:
+ gls_report_num_of_records(conn_id, service_id);
+ break;
+ case GLC_RACP_OPCODE_REPORT_RECS:
+ gls_report_records(conn_id, service_id);
+ break;
+ case GLC_RACP_OPCODE_DELETE_RECS:
+ gls_delete_records(conn_id, service_id);
+ break;
+ default:
+ gls_racp_response(conn_id, service_id, GLC_RACP_RESP_OPCODE_NOT_SUPPORTED);
+ break;
+ }
+ }
+ else
+ {
+ if ((glc_racp.ctrl_point.op_code != GLC_RACP_OPCODE_RESERVED) && (gls_send_data_flag != 3))
+ {
+ gls_abort_flag = true;
+ //while (gls_abort_flag == TRUE) ; /* halt until AbortFlag is disabled when procedure in progress has been aborted */
+ }
+ else
+ {
+ gls_abort_success_response(conn_id, service_id);
+ }
+ }
+}
+
+/**
+ * @brief Check CCCD configuration
+ * @return Result of check
+ * @retval TRUE
+ * @retval FALSE
+ */
+bool gls_check_cccd()
+{
+ if (0 == glc_notify_indicate_flag.GLC_measurement_notify_enable)
+ {
+ return false;
+ }
+ else if (0 == glc_notify_indicate_flag.GLC_measurement_context_notify_enable)
+ {
+ return false;
+ }
+ else if (0 == glc_notify_indicate_flag.GLC_RACP_indicate_enable)
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID to be written.
+ * @param[in] attrib_index Attribute index of characteristic.
+ * @param[in] length Length of value to be written.
+ * @param p_value Value to be written.
+ * @return Profile procedure result
+ */
+T_APP_RESULT gls_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value,
+ P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ PROFILE_PRINT_INFO2("gls_attr_write_cb attrib_index = %d, length = %x", attrib_index, length);
+ switch (attrib_index)
+ {
+ case GLS_CHAR_GLC_RACP_INDEX:
+ {
+ /* Attribute value has variable size, make sure written value size is valid. */
+ if ((length > sizeof(T_GLC_CONTROL_POINT)) || (p_value == NULL))
+ {
+ cause = APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ /* Make sure Control Point is not "Process already in progress". */
+ else if (GLC_RACP_OPERATION_ACTIVE(glc_racp.ctrl_point.op_code) &&
+ (p_value[0] != GLC_RACP_OPCODE_ABORT_OPERATION))
+ {
+ cause = (T_APP_RESULT)(ATT_ERR | GLC_ERR_PROC_ALREADY_IN_PROGRESS);
+ }
+ /* Make sure Control Point is configured indication enable. */
+ else if (!gls_check_cccd())
+ {
+ cause = (T_APP_RESULT)(ATT_ERR | GLC_ERR_CCCD_IMPROPERLY_CONFIGURED);
+ }
+ else
+ {
+ //wCause = GLS_Handle_CtlPntProc(ServiceId, wLength, pValue);
+ /** handle RACP request after sending write response */
+ PROFILE_PRINT_INFO2("gls_attr_write_cb opcode: old = %d, new = %d\n", glc_racp.ctrl_point.op_code,
+ p_value[0]);
+ *p_write_ind_post_proc = gls_ctl_pnt_write_ind_post_proc;
+ }
+
+ }
+ break;
+
+ default:
+ {
+ PROFILE_PRINT_ERROR1("gls_attr_write_cb attribIndex = %d not found", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ break;
+ }
+ return cause;
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param[in] conn_id Connection id.
+ * @param service_id Service ID.
+ * @param index Attribute index of characteristic data.
+ * @param ccc_bits CCCD bits from stack.
+ * @return None
+ */
+void gls_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ T_GLS_CALLBACK_DATA gls_upsteam_msg;
+ bool handle = true;
+ PROFILE_PRINT_INFO2("gls_cccd_update_cb Index = %d ccc_bits %x", index, ccc_bits);
+ switch (index)
+ {
+ case GLS_CHAR_GLC_MEASUREMENT_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ // Enable Notification
+ glc_notify_indicate_flag.GLC_measurement_notify_enable = 1;
+ gls_upsteam_msg.msg_data.notify_indicate_index = GLS_EVT_GLC_MEASUREMENT_NOTIFY_ENABLE;
+ }
+ else
+ {
+ // Disable Notification
+ glc_notify_indicate_flag.GLC_measurement_notify_enable = 0;
+ gls_upsteam_msg.msg_data.notify_indicate_index = GLS_EVT_GLC_MEASUREMENT_NOTIFY_DISABLE;
+ }
+ }
+ break;
+#if GLC_MEASUREMENT_CONTEXT_SUPPORT
+ case GLS_CHAR_GLC_MEASUREMENT_CONTEXT_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ // Enable Notification
+ glc_notify_indicate_flag.GLC_measurement_context_notify_enable = 1;
+ gls_upsteam_msg.msg_data.notify_indicate_index = GLS_EVT_GLC_MEASUREMENT_CONTEXT_NOTIFY_ENABLE;
+ }
+ else
+ {
+ // Disable Notification
+ glc_notify_indicate_flag.GLC_measurement_context_notify_enable = 0;
+ gls_upsteam_msg.msg_data.notify_indicate_index = GLS_EVT_GLC_MEASUREMENT_CONTEXT_NOTIFY_DISABLE;
+ }
+ }
+ break;
+#endif
+ case GLS_CHAR_GLC_RACP_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE)
+ {
+ // Enable Notification
+ glc_notify_indicate_flag.GLC_RACP_indicate_enable = 1;
+ gls_upsteam_msg.msg_data.notify_indicate_index = GLS_EVT_GLC_RACP_INDICATE_ENABLE;
+ }
+ else
+ {
+ // Disable Notification
+ glc_notify_indicate_flag.GLC_RACP_indicate_enable = 0;
+ gls_upsteam_msg.msg_data.notify_indicate_index = GLS_EVT_GLC_RACP_INDICATE_DISABLE;
+ }
+ }
+ break;
+ default:
+ {
+ handle = false;
+ PROFILE_PRINT_ERROR1("gls_cccd_update_cb index = %d not found", index);
+ }
+ break;
+ }
+ /* Notify Application. */
+ if (pfn_gls_cb && (handle == true))
+ {
+ gls_upsteam_msg.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ pfn_gls_cb(service_id, (void *)&gls_upsteam_msg);
+ }
+}
+
+/**
+ * @brief Simple Profile Service Callbacks.
+ */
+const T_FUN_GATT_SERVICE_CBS gls_cbs =
+{
+ gls_attr_read_cb, // Read callback function pointer
+ gls_attr_write_cb, // Write callback function pointer
+ gls_cccd_update_cb // CCCD update callback function pointer
+};
+
+/**
+ * @brief Add gulcose service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ gls_id = gls_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID gls_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)gls_att_tbl,
+ sizeof(gls_att_tbl),
+ gls_cbs))
+ {
+ PROFILE_PRINT_ERROR1("gls_add_service: ServiceId %d", service_id);
+ service_id = 0xff;
+ return service_id;
+ }
+ glc_racp.record_db.record_num = 0;
+ glc_racp.record_db.head = 0;
+ glc_racp.record_db.tail = 0;
+ glc_racp.record_db.seq_num = GLC_RACP_INIT_SEQ_NBR_DEFAULT;
+ pfn_gls_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
+/**
+ * @brief Abort RACP procedure by app.
+ *
+ * @return void.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ gls_abort_racp_procedure();
+ }
+ * \endcode
+ */
+void gls_abort_racp_procedure(void)
+{
+ if ((glc_racp.ctrl_point.op_code != GLC_RACP_OPCODE_RESERVED) && (gls_send_data_flag != 3))
+ {
+ gls_abort_by_app_flag = true;
+ }
+}
diff --git a/src/ble/profile/server/hids.c b/src/ble/profile/server/hids.c
new file mode 100644
index 0000000..0f2bad5
--- /dev/null
+++ b/src/ble/profile/server/hids.c
@@ -0,0 +1,772 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hids.c
+ * @brief Source file for using Human Interface Device Service.
+ * @details Global data and function implement.
+ * @author Jeff_Zheng
+ * @date 2017-12-01
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#include <string.h>
+#include "trace.h"
+#include "profile_server.h"
+#include "hids.h"
+
+
+#define GATT_UUID_HID 0x1812
+#define GATT_UUID_CHAR_PROTOCOL_MODE 0x2A4E
+#define GATT_UUID_CHAR_REPORT 0x2A4D
+#define GATT_UUID_CHAR_REPORT_MAP 0x2A4B
+#define GATT_UUID_CHAR_BOOT_KB_IN_REPORT 0x2A22
+#define GATT_UUID_CHAR_BOOT_KB_OUT_REPORT 0x2A32
+#define GATT_UUID_CHAR_BOOT_MS_IN_REPORT 0x2A33
+#define GATT_UUID_CHAR_HID_INFO 0x2A4A
+#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C
+
+
+static P_FUN_SERVER_GENERAL_CB pfn_hids_cb = NULL;
+
+T_HID_INFO hid_info = {0, 0, 0};
+T_HID_PROTOCOL_MODE hid_protocol_mode = BOOT_PROTOCOL_MODE;
+uint8_t hid_suspand_mode = 0;
+uint16_t external_report_refer = 0;
+
+static const T_ATTRIB_APPL hids_attr_tbl[] =
+{
+ /* <<Primary Service>>, .. 0*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_HID), /* service UUID */
+ HI_WORD(GATT_UUID_HID)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 1*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Protocol Mode characteristic value ..2*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_PROTOCOL_MODE),
+ HI_WORD(GATT_UUID_CHAR_PROTOCOL_MODE)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 3*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Report characteristic value .. 4*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+ },
+
+ /* client characteristic configuration .. 5*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ },
+
+ /*report ID map reference descriptor .. 6*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ 0x00,
+ HID_INPUT_TYPE,
+ },
+ 2, /* bValueLen */
+ NULL,//(void*)&cPointerInputReportIdMap,
+ (GATT_PERM_READ) /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 7*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Report characteristic value .. 8*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+ },
+
+ /*report ID map reference descriptor .. 9*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ 0x00,
+ HID_OUTPUT_TYPE
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ) /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 10*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Report characteristic value .. 11*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+ },
+
+ /*report ID map reference descriptor .. 12*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ 0x00,
+ HID_FEATURE_TYPE
+ },
+ 2, /* bValueLen */
+ (void *)NULL,
+ (GATT_PERM_READ) /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 13*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID report map characteristic value .. 14*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_MAP),
+ HI_WORD(GATT_UUID_CHAR_REPORT_MAP)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<EXTERNAL_REPORT_REFERENCE>>, .. 15*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE),
+ },
+ 0, /* bValueLen */
+ (void *)NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* <<Characteristic>>, .. 16*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ_AUTHEN_REQ /* permissions */
+ },
+
+ /* HID boot keyboard input characteristic value .. 17*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT),
+ HI_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+ },
+
+ /* client characteristic configuration .. 18*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+ },
+
+ /* <<Characteristic>>, .. 19*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ_AUTHEN_REQ /* permissions */
+ },
+
+ /* HID boot keyboard output characteristic value .. 20*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT),
+ HI_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+ },
+
+ /* <<Characteristic>>, .. 21*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID boot mouse input characteristic value .. 22*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_BOOT_MS_IN_REPORT),
+ HI_WORD(GATT_UUID_CHAR_BOOT_MS_IN_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+ },
+
+
+ /* client characteristic configuration .. 23*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+ },
+
+ /* <<Characteristic>>, .. 24*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Information characteristic value .. 25*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_HID_INFO),
+ HI_WORD(GATT_UUID_CHAR_HID_INFO)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 26*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID controlPoint characteristic value .. 27*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT),
+ HI_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+ }
+
+};
+
+/**
+ * @brief Set a HID service parameter.
+ *
+ * NOTE: You can call this function with a HID service parameter type and it will set the
+ * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE.
+ *
+ * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t mode = 1;
+ hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode);
+ }
+ * \endcode
+ */
+bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t length, void *value_ptr)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ case HID_PROTOCOL_MODE:
+ {
+ hid_protocol_mode = (T_HID_PROTOCOL_MODE) * ((uint8_t *)value_ptr);
+ }
+ break;
+
+ case HID_REPORT_INPUT:
+ break;
+
+ case HID_REPORT_OUTPUT:
+ break;
+
+ case HID_REPORT_FEATURE:
+ break;
+
+ case HID_REPORT_MAP:
+ break;
+
+ case HID_EXTERNAL_REPORT_REFER:
+ {
+ external_report_refer = *(uint16_t *)value_ptr;
+ }
+ break;
+
+ case HID_BOOT_KB_IN_REPORT:
+ break;
+
+ case HID_BOOT_KB_OUT_REPORT:
+ break;
+
+ case HID_BOOT_MS_IN_REPORT:
+ break;
+
+ case HID_INFO:
+ {
+ memcpy((void *)&hid_info, value_ptr, length);
+ }
+ break;
+
+ case HID_CONTROL_POINT:
+ hid_suspand_mode = *((uint8_t *)value_ptr);
+ break;
+
+ default:
+ ret = false;
+ break;
+ }
+ return ret;
+}
+
+
+static T_APP_RESULT hids_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ T_HID_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.conn_id = conn_id;
+
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+
+ switch (attrib_index)
+ {
+ default:
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+
+ case GATT_SVC_HID_PROTOCOL_MODE_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX;
+ cause = pfn_hids_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&hid_protocol_mode;
+ *p_length = sizeof(hid_protocol_mode);
+ break;
+
+ case GATT_SVC_HID_REPORT_INPUT_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_OUTPUT_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_FEATURE_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_MAP_INDEX:
+ break;
+
+ case GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX;
+ cause = pfn_hids_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&external_report_refer;
+ *p_length = sizeof(external_report_refer);
+ break;
+
+ case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX:
+ break;
+
+ case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX:
+ break;
+
+ case GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX:
+ break;
+
+ case GATT_SVC_HID_INFO_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_INFO_INDEX;
+ cause = pfn_hids_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&hid_info;
+ *p_length = sizeof(hid_info);
+ break;
+
+ case GATT_SVC_HID_CONTROL_POINT_INDEX:
+ break;
+ }
+
+ return cause;
+}
+
+
+static T_APP_RESULT hids_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index, T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ T_HID_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+
+ if (!p_value)
+ {
+ cause = APP_RESULT_INVALID_PDU;
+ return cause;
+ }
+
+ switch (attrib_index)
+ {
+ default:
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+
+ case GATT_SVC_HID_PROTOCOL_MODE_INDEX:
+ callback_data.msg_data.write_msg.write_type = write_type;
+ callback_data.msg_data.write_msg.write_parameter.protocol_mode = *p_value;
+ hids_set_parameter(HID_PROTOCOL_MODE, length, p_value);
+ break;
+
+ case GATT_SVC_HID_REPORT_INPUT_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_OUTPUT_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_FEATURE_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_MAP_INDEX:
+ break;
+
+ case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX:
+ break;
+
+ case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX:
+ break;
+
+ case GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX:
+ break;
+
+ case GATT_SVC_HID_INFO_INDEX:
+ break;
+
+ case GATT_SVC_HID_CONTROL_POINT_INDEX:
+ break;
+ }
+
+ if (pfn_hids_cb && (cause == APP_RESULT_SUCCESS))
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+
+ return cause;
+
+}
+
+void hids_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ bool cause = true;
+ T_HID_CALLBACK_DATA callback_data;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+
+ PROFILE_PRINT_INFO2("hids_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits);
+
+ switch (index)
+ {
+ default:
+ cause = false;
+ break;
+
+ case GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX:
+ {
+ callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX;
+ if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION)
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE;
+ }
+ break;
+ }
+
+ case GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX:
+ {
+ callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX;
+ if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION)
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE;
+ }
+ break;
+ }
+
+ case GATT_SVC_HID_BOOT_MS_IN_REPORT_CCCD_INDEX:
+ {
+ callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_BOOT_MS_IN_REPORT_CCCD_INDEX;
+ if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION)
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE;
+ }
+ break;
+ }
+ }
+
+ if (pfn_hids_cb && (cause == true))
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+
+ return;
+}
+
+
+/**
+ * @brief Send HIDS notification data .
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] index hids characteristic index.
+ * @param[in] p_data report value pointer.
+ * @param[in] data_len length of report data.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t conn_id = 0;
+ T_SERVER_ID service_id = hids_id;
+ uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
+ hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_INPUT_INDEX, hid_report_input, sizeof(hid_report_input));
+ }
+ * \endcode
+ */
+bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data,
+ uint16_t data_len)
+{
+ PROFILE_PRINT_INFO1("hids_send_report data_len %d", data_len);
+ return server_send_data(conn_id, service_id, index, p_data, data_len, GATT_PDU_TYPE_NOTIFICATION);
+}
+
+
+
+uint16_t hids_attr_tbl_len = sizeof(hids_attr_tbl);
+
+const T_FUN_GATT_SERVICE_CBS hids_cbs =
+{
+ hids_attr_read_cb, // Read callback function pointer
+ hids_attr_write_cb, // Write callback function pointer
+ hids_cccd_update_cb, // Authorization callback function pointer
+};
+
+/**
+ * @brief Add HID service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ hids_id = hids_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID hids_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+ if (false == server_add_service(&service_id, (uint8_t *)hids_attr_tbl, hids_attr_tbl_len, hids_cbs))
+ {
+ PROFILE_PRINT_ERROR1("hids_add_service: ServiceId %d", service_id);
+ service_id = 0xff;
+ }
+
+ pfn_hids_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
diff --git a/src/ble/profile/server/hids_kb.c b/src/ble/profile/server/hids_kb.c
new file mode 100644
index 0000000..644cc82
--- /dev/null
+++ b/src/ble/profile/server/hids_kb.c
@@ -0,0 +1,851 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hids_kb.c
+ * @brief Source file for using Human Interface Device Service.
+ * @details Global data and function implement.
+ * @author Jeff_Zheng
+ * @date 2017-12-01
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#include <string.h>
+#include "trace.h"
+#include "profile_server.h"
+#include "hids_kb.h"
+
+
+#define GATT_UUID_HID 0x1812
+#define GATT_UUID_CHAR_PROTOCOL_MODE 0x2A4E
+#define GATT_UUID_CHAR_REPORT 0x2A4D
+#define GATT_UUID_CHAR_REPORT_MAP 0x2A4B
+#define GATT_UUID_CHAR_BOOT_KB_IN_REPORT 0x2A22
+#define GATT_UUID_CHAR_BOOT_KB_OUT_REPORT 0x2A32
+#define GATT_UUID_CHAR_HID_INFO 0x2A4A
+#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C
+
+/* Report ID for General Keyboard, change: 0x03 to 0x01 */
+#define HOGP_KB_REPORT_ID 0x03
+#define HOGP_MM_REPORT_ID 0x04
+#define MULTIMEDIA_KEYBOARD
+T_HID_INFO hid_info = {0, 0, 0x0100};
+T_HID_PROTOCOL_MODE hid_protocol_mode = BOOT_PROTOCOL_MODE;
+uint8_t hid_suspand_mode = 0;
+uint16_t external_report_refer = 0;
+
+const uint8_t hids_report_descriptor[] =
+{
+ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
+ 0x09, 0x06, /* USAGE (Keyboard) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ 0x85, HOGP_KB_REPORT_ID, /* REPORT_ID (3) */
+ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */
+ 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard Left Control) */
+ 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
+ 0x75, 0x01, /* REPORT_SIZE (1) */
+ 0x95, 0x08, /* REPORT_COUNT (8) */
+ 0x81, 0x02, /* INPUT (Data,Var,Abs) */
+ 0x95, 0x01, /* REPORT_COUNT (1) */
+ 0x75, 0x08, /* REPORT_SIZE (8) */
+ 0x81, 0x01, /* INPUT (Cnst,Var,Abs) */
+ 0x95, 0x05, /* REPORT_COUNT (5) */
+ 0x75, 0x01, /* REPORT_SIZE (1) */
+ 0x05, 0x08, /* USAGE_PAGE (LEDs) */
+ 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */
+ 0x29, 0x05, /* USAGE_MAXIMUM (Kana) */
+ 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */
+ 0x95, 0x01, /* REPORT_COUNT (1) */
+ 0x75, 0x03, /* REPORT_SIZE (3) */
+ 0x91, 0x01, /* OUTPUT (Cnst,Var,Abs) */
+ 0x95, 0x06, /* REPORT_COUNT (6) */
+ 0x75, 0x08, /* REPORT_SIZE (8) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x25, 0xa4, /* LOGICAL_MAXIMUM (164) */ /* Can be 255 */
+ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */
+ 0x19, 0x00, /* USAGE_MINIMUM (Reserved-no event indicated) */
+ 0x29, 0xa4, /* USAGE_MAXIMUM (Keyboard Application) */ /* Can be 255 */
+ 0x81, 0x00, /* INPUT (Data,Ary,Abs) */
+ 0xc0, /* END_COLLECTION */
+#ifdef MULTIMEDIA_KEYBOARD
+ 0x05, 0x0c, /* USAGE_PAGE (Consumer) */
+ 0x09, 0x01, /* USAGE (Consumer Control) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ 0x85, HOGP_MM_REPORT_ID, /* REPORT_ID (4) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
+ 0x75, 0x01, /* REPORT_SIZE (1) */
+ 0x95, 0x18, /* REPORT_COUNT (24) */
+ 0x09, 0xb5, /* USAGE (Scan Next Track) */
+ 0x09, 0xb6, /* USAGE (Scan Previous Track) */
+ 0x09, 0xb7, /* USAGE (Stop) */
+ 0x09, 0xcd, /* USAGE (Play/Pause) */
+ 0x09, 0xe2, /* USAGE (Mute) */
+ 0x09, 0xe5, /* USAGE (Bass Boost) */
+ 0x09, 0xe7, /* USAGE (Loudness) */
+ 0x09, 0xe9, /* USAGE (Volume Increment) */
+ 0x09, 0xea, /* USAGE (Volume Decrement) */
+ 0x0a, 0x52, 0x01, /* USAGE (Bass Increment) */
+ 0x0a, 0x53, 0x01, /* USAGE (Bass Decrement) */
+ 0x0a, 0x54, 0x01, /* USAGE (Treble Increment) */
+ 0x0a, 0x55, 0x01, /* USAGE (Treble Decrement) */
+ 0x0a, 0x83, 0x01, /* USAGE (AL Consumer Control Configuration) */
+ 0x0a, 0x8a, 0x01, /* USAGE (AL Email Reader) */
+ 0x0a, 0x92, 0x01, /* USAGE (AL Calculator) */
+ 0x0a, 0x94, 0x01, /* USAGE (AL Local Machine Browser) */
+ 0x0a, 0x21, 0x02, /* USAGE (AC Search) */
+ 0x0a, 0x23, 0x02, /* USAGE (AC Home) */
+ 0x0a, 0x24, 0x02, /* USAGE (AC Back) */
+ 0x0a, 0x25, 0x02, /* USAGE (AC Forward) */
+ 0x0a, 0x26, 0x02, /* USAGE (AC Stop) */
+ 0x0a, 0x27, 0x02, /* USAGE (AC Refresh) */
+ 0x0a, 0x2a, 0x02, /* USAGE (AC Bookmarks) */
+ 0x81, 0x02, /* INPUT (Data,Var,Abs) */
+ 0xc0 /* END_COLLECTION */
+#endif
+};
+
+static P_FUN_SERVER_GENERAL_CB pfn_hids_cb = NULL;
+
+static const T_ATTRIB_APPL hids_attr_tbl[] =
+{
+ /* <<Primary Service>>, .. 0*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_HID), /* service UUID */
+ HI_WORD(GATT_UUID_HID)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 1*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Protocol Mode characteristic value ..2*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_PROTOCOL_MODE),
+ HI_WORD(GATT_UUID_CHAR_PROTOCOL_MODE)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 3*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Report characteristic value .. 4*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */
+ },
+
+ /* client characteristic configuration .. 5*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */
+ },
+
+ /*report ID map reference descriptor .. 6*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HOGP_KB_REPORT_ID,
+ HID_INPUT_TYPE,
+ },
+ 2, /* bValueLen */
+ NULL,//(void*)&cPointerInputReportIdMap,
+ (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 7*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Report characteristic value .. 8*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */
+ },
+
+ /*report ID map reference descriptor .. 9*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HOGP_KB_REPORT_ID,
+ HID_OUTPUT_TYPE
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 10*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Report characteristic value .. 11*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */
+ },
+
+ /*report ID map reference descriptor .. 12*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ HOGP_KB_REPORT_ID,
+ HID_FEATURE_TYPE
+ },
+ 2, /* bValueLen */
+ (void *)NULL,
+ (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 13*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID report map characteristic value .. 14*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_MAP),
+ HI_WORD(GATT_UUID_CHAR_REPORT_MAP)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ /* wPermissions */
+ },
+
+ /* <<EXTERNAL_REPORT_REFERENCE>>, .. 15*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE),
+ },
+ 0, /* bValueLen */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ /* permissions */
+ },
+
+ /* <<Characteristic>>, .. 16*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* HID boot keyboard input characteristic value .. 17*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT),
+ HI_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+ },
+
+ /* client characteristic configuration .. 18*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+ },
+
+ /* <<Characteristic>>, .. 19*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* HID boot keyboard output characteristic value .. 20*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT),
+ HI_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+ },
+
+ /* <<Characteristic>>, .. 21*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Information characteristic value .. 22*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_HID_INFO),
+ HI_WORD(GATT_UUID_CHAR_HID_INFO)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 23*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID controlPoint characteristic value .. 24*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT),
+ HI_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */
+ },
+
+#ifdef MULTIMEDIA_KEYBOARD
+ /* <<Characteristic>>, .. 25*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Report characteristic value ,multimedia keyboard Input 26*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 3, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */
+ },
+
+ /* client characteristic configuration 27*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* wFlags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */
+ },
+
+ /*report ID map reference descriptor 28*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* wFlags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ HOGP_MM_REPORT_ID, /* client char. config. bit field */
+ HID_INPUT_TYPE
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */
+ }
+#endif
+
+};
+
+/**
+ * @brief Set a HID service parameter.
+ *
+ * NOTE: You can call this function with a HID service parameter type and it will set the
+ * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE.
+ *
+ * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t mode = 1;
+ hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode);
+ }
+ * \endcode
+ */
+bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t length, void *value_ptr)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ case HID_PROTOCOL_MODE:
+ {
+ hid_protocol_mode = (T_HID_PROTOCOL_MODE) * ((uint8_t *)value_ptr);
+ }
+ break;
+
+ case HID_REPORT_INPUT:
+ break;
+
+ case HID_REPORT_OUTPUT:
+ break;
+
+ case HID_REPORT_FEATURE:
+ break;
+
+ case HID_REPORT_MAP:
+ break;
+
+ case HID_EXTERNAL_REPORT_REFER:
+ {
+ external_report_refer = *(uint16_t *)value_ptr;
+ }
+ break;
+
+ case HID_BOOT_KB_IN_REPORT:
+ break;
+
+ case HID_BOOT_KB_OUT_REPORT:
+ break;
+
+ case HID_INFO:
+ {
+ memcpy((void *)&hid_info, value_ptr, length);
+ }
+ break;
+
+ case HID_CONTROL_POINT:
+ hid_suspand_mode = *((uint8_t *)value_ptr);
+ break;
+
+ default:
+ ret = false;
+ break;
+ }
+ return ret;
+}
+
+
+static T_APP_RESULT hids_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ T_HID_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.conn_id = conn_id;
+
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+
+ switch (attrib_index)
+ {
+ default:
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+
+ case GATT_SVC_HID_PROTOCOL_MODE_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX;
+ cause = pfn_hids_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&hid_protocol_mode;
+ *p_length = sizeof(hid_protocol_mode);
+ break;
+
+ case GATT_SVC_HID_REPORT_INPUT_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_OUTPUT_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_FEATURE_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_MAP_INDEX:
+ *pp_value = (uint8_t *)hids_report_descriptor;
+ *p_length = sizeof(hids_report_descriptor);
+ break;
+
+ case GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX;
+ cause = pfn_hids_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&external_report_refer;
+ *p_length = sizeof(external_report_refer);
+ break;
+
+ case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX:
+ break;
+
+ case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX:
+ break;
+
+ case GATT_SVC_HID_INFO_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_INFO_INDEX;
+ cause = pfn_hids_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&hid_info;
+ *p_length = sizeof(hid_info);
+ break;
+
+ case GATT_SVC_HID_CONTROL_POINT_INDEX:
+ break;
+ }
+
+ return cause;
+}
+
+
+static T_APP_RESULT hids_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index, T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ T_HID_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+
+ if (!p_value)
+ {
+ cause = APP_RESULT_INVALID_PDU;
+ return cause;
+ }
+
+ switch (attrib_index)
+ {
+ default:
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+
+ case GATT_SVC_HID_PROTOCOL_MODE_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX;
+ callback_data.msg_data.write_msg.write_type = write_type;
+ callback_data.msg_data.write_msg.write_parameter.protocol_mode = *p_value;
+ hids_set_parameter(HID_PROTOCOL_MODE, length, p_value);
+ break;
+
+ case GATT_SVC_HID_REPORT_INPUT_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_OUTPUT_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_REPORT_OUTPUT_INDEX;
+ callback_data.msg_data.write_msg.write_type = write_type;
+ callback_data.msg_data.write_msg.write_parameter.output = *p_value;
+ break;
+
+ case GATT_SVC_HID_REPORT_FEATURE_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_MAP_INDEX:
+ break;
+
+ case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX:
+ break;
+
+ case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX:
+ break;
+
+ case GATT_SVC_HID_INFO_INDEX:
+ break;
+
+ case GATT_SVC_HID_CONTROL_POINT_INDEX:
+ break;
+ }
+
+ if (pfn_hids_cb && (cause == APP_RESULT_SUCCESS))
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+
+ return cause;
+
+}
+
+void hids_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ bool cause = true;
+ T_HID_CALLBACK_DATA callback_data;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+
+ PROFILE_PRINT_INFO2("hids_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits);
+
+ switch (index)
+ {
+ default:
+ cause = false;
+ break;
+
+ case GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX:
+ {
+ callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX;
+ if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION)
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE;
+ }
+ break;
+ }
+
+ case GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX:
+ {
+ callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX;
+ if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION)
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE;
+ }
+ break;
+ }
+
+ }
+
+ if (pfn_hids_cb && (cause == true))
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+
+ return;
+}
+
+
+/**
+ * @brief Send HIDS notification data .
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] index hids characteristic index.
+ * @param[in] p_data report value pointer.
+ * @param[in] data_len length of report data.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t conn_id = 0;
+ T_SERVER_ID service_id = hids_id;
+ uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
+ hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_INPUT_INDEX, hid_report_input, sizeof(hid_report_input));
+ }
+ * \endcode
+ */
+bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data,
+ uint16_t data_len)
+{
+ PROFILE_PRINT_INFO1("hids_send_report data_len %d", data_len);
+ return server_send_data(conn_id, service_id, index, p_data, data_len, GATT_PDU_TYPE_NOTIFICATION);
+}
+
+
+
+uint16_t hids_attr_tbl_len = sizeof(hids_attr_tbl);
+
+const T_FUN_GATT_SERVICE_CBS hids_cbs =
+{
+ hids_attr_read_cb, // Read callback function pointer
+ hids_attr_write_cb, // Write callback function pointer
+ hids_cccd_update_cb, // Authorization callback function pointer
+};
+
+/**
+ * @brief Add HID service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ hids_id = hids_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID hids_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+ if (false == server_add_service(&service_id, (uint8_t *)hids_attr_tbl, hids_attr_tbl_len, hids_cbs))
+ {
+ PROFILE_PRINT_ERROR1("hids_add_service: ServiceId %d", service_id);
+ service_id = 0xff;
+ }
+
+ pfn_hids_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
diff --git a/src/ble/profile/server/hids_ms.c b/src/ble/profile/server/hids_ms.c
new file mode 100644
index 0000000..8e5a9fc
--- /dev/null
+++ b/src/ble/profile/server/hids_ms.c
@@ -0,0 +1,861 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hids_ms.c
+ * @brief Source file for using Human Interface Device Service.
+ * @details Global data and function implement.
+ * @author Jeff_Zheng
+ * @date 2017-12-01
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#include <string.h>
+#include "trace.h"
+#include "profile_server.h"
+#include "hids_ms.h"
+
+
+#define GATT_UUID_HID 0x1812
+#define GATT_UUID_CHAR_PROTOCOL_MODE 0x2A4E
+#define GATT_UUID_CHAR_REPORT 0x2A4D
+#define GATT_UUID_CHAR_REPORT_MAP 0x2A4B
+#define GATT_UUID_CHAR_BOOT_MS_IN_REPORT 0x2A33
+#define GATT_UUID_CHAR_HID_INFO 0x2A4A
+#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C
+
+#define HOGP_MOUSE_REPORT_ID 1
+#define HOGP_VENDOR_REPORT_ID 0x10
+
+static P_FUN_SERVER_GENERAL_CB pfn_hids_cb = NULL;
+
+T_HID_INFO hid_info = {0, 0, 0};
+T_HID_PROTOCOL_MODE hid_protocol_mode = BOOT_PROTOCOL_MODE;
+uint8_t hid_suspand_mode = 0;
+uint16_t external_report_refer = 0;
+
+const uint8_t hids_report_descriptor[] =
+{
+ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) main item*/
+ 0x09, 0x02, /* USAGE (Mouse) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ 0x85, HOGP_MOUSE_REPORT_ID, /* REPORT_ID (1) */
+ 0x09, 0x01, /* USAGE (Pointer) */
+ 0xa1, 0x00, /* COLLECTION (Physical) */
+ 0x05, 0x09, /* USAGE_PAGE (Button) */
+ 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */
+ 0x29, 0x05, /* USAGE_MAXIMUM (Button 5) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
+ 0x95, 0x05, /* REPORT_COUNT (5) */
+ 0x75, 0x01, /* REPORT_SIZE (1) */
+ 0x81, 0x02, /* INPUT (Data,Var,Abs) */
+ 0x95, 0x01, /* REPORT_COUNT (1) */
+ 0x75, 0x03, /* REPORT_SIZE (3) */
+ 0x81, 0x01, /* INPUT (Cnst,Var,Abs) */
+
+ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) main item*/
+ 0x09, 0x30, /* USAGE (X) */
+ 0x09, 0x31, /* USAGE (Y) */
+ 0x16, 0x01, 0x80, /* LOGICAL_MINIMUM (-32767) */
+ 0x26, 0xff, 0x7f, /* LOGICAL_MAXIMUM (32767) */
+ 0x75, 0x10, /* REPORT_SIZE (16) */
+ 0x95, 0x02, /* REPORT_COUNT (2) */
+ 0x81, 0x06, /* INPUT (Data,Var,Rel) */
+ 0x09, 0x38, /* USAGE (Wheel) */
+ 0x15, 0x81, /* LOGICAL_MINIMUM (-127) */
+ 0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */
+ 0x75, 0x08, /* REPORT_SIZE (8) */
+ 0x95, 0x01, /* REPORT_COUNT (1) */
+ 0x81, 0x06, /* INPUT (Data,Var,Rel) */
+ 0xc0, /* END_COLLECTION */
+ 0xc0, /* END_COLLECTION */
+
+ 0x06, 0x01, 0xff, /* USAGE_PAGE (vendor) */
+ 0x09, 0x01, /* USAGE (vendor) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ 0x85, HOGP_VENDOR_REPORT_ID, /* REPORT_ID (0x10) */
+ 0x19, 0x00, /* USAGE_MINIMUM (0) */
+ 0x29, 0xff, /* USAGE_MAXIMUM (0xff) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x25, 0xff, /* LOGICAL_MAXIMUM (0xff) */
+ 0x75, 0x08, /* REPORT_SIZE (8) */
+ 0x95, 0x04, /* REPORT_COUNT (4) */
+ 0x81, 0x02, /* INPUT (Data,Var,Abs) */
+ 0xc0, /* END_COLLECTION */
+};
+
+
+static const T_ATTRIB_APPL hids_attr_tbl[] =
+{
+ /* <<Primary Service>>, .. 0*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_HID), /* service UUID */
+ HI_WORD(GATT_UUID_HID)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 1*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Protocol Mode characteristic value ..2*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_PROTOCOL_MODE),
+ HI_WORD(GATT_UUID_CHAR_PROTOCOL_MODE)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+#endif
+ },
+
+ /* <<Characteristic>>, .. 3*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Report characteristic value .. 4*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+#endif
+ },
+
+ /* client characteristic configuration .. 5*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+#endif
+ },
+
+ /*report ID map reference descriptor .. 6*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HOGP_MOUSE_REPORT_ID,
+ HID_INPUT_TYPE,
+ },
+ 2, /* bValueLen */
+ NULL,//(void*)&cPointerInputReportIdMap,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* wPermissions */
+#endif
+ },
+
+ /* <<Characteristic>>, .. 7*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Report characteristic value .. 8*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+#endif
+ },
+
+ /* client characteristic configuration .. 9*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+#endif
+ },
+
+ /*report ID map reference descriptor .. 10*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HOGP_VENDOR_REPORT_ID,
+ HID_INPUT_TYPE,
+ },
+ 2, /* bValueLen */
+ NULL,//(void*)&cPointerInputReportIdMap,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* wPermissions */
+#endif
+ },
+
+ /* <<Characteristic>>, .. 11*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Report characteristic value .. 12*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+#endif
+ },
+
+ /*report ID map reference descriptor .. 13*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HOGP_MOUSE_REPORT_ID,
+ HID_OUTPUT_TYPE
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* wPermissions */
+#endif
+ },
+
+ /* <<Characteristic>>, .. 14*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Report characteristic value .. 15*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+#endif
+ },
+
+ /*report ID map reference descriptor .. 16*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ HOGP_MOUSE_REPORT_ID,
+ HID_FEATURE_TYPE
+ },
+ 2, /* bValueLen */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* wPermissions */
+#endif
+ },
+
+ /* <<Characteristic>>, .. 17*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID report map characteristic value .. 18*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_MAP),
+ HI_WORD(GATT_UUID_CHAR_REPORT_MAP)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ /* wPermissions */
+#endif
+ },
+
+ /* <<EXTERNAL_REPORT_REFERENCE>>, .. 19*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE),
+ },
+ 0, /* bValueLen */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* wPermissions */
+#endif /* permissions */
+ },
+
+ /* <<Characteristic>>, .. 20*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID boot mouse input characteristic value .. 21*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_BOOT_MS_IN_REPORT),
+ HI_WORD(GATT_UUID_CHAR_BOOT_MS_IN_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+#endif
+ },
+
+
+ /* client characteristic configuration .. 22*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* permissions */
+#endif
+ },
+
+ /* <<Characteristic>>, .. 23*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Information characteristic value .. 24*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_HID_INFO),
+ HI_WORD(GATT_UUID_CHAR_HID_INFO)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ /* wPermissions */
+#endif
+ },
+
+ /* <<Characteristic>>, .. 25*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID controlPoint characteristic value .. 26*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT),
+ HI_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+#endif
+ }
+
+};
+
+/**
+ * @brief Set a HID service parameter.
+ *
+ * NOTE: You can call this function with a HID service parameter type and it will set the
+ * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE.
+ *
+ * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t mode = 1;
+ hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode);
+ }
+ * \endcode
+ */
+bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t length, void *value_ptr)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ case HID_PROTOCOL_MODE:
+ {
+ hid_protocol_mode = (T_HID_PROTOCOL_MODE) * ((uint8_t *)value_ptr);
+ }
+ break;
+
+ case HID_REPORT_INPUT:
+ break;
+
+ case HID_REPORT_OUTPUT:
+ break;
+
+ case HID_REPORT_FEATURE:
+ break;
+
+ case HID_REPORT_MAP:
+ break;
+
+ case HID_EXTERNAL_REPORT_REFER:
+ {
+ external_report_refer = *(uint16_t *)value_ptr;
+ }
+ break;
+
+ case HID_BOOT_MS_IN_REPORT:
+ break;
+
+ case HID_INFO:
+ {
+ memcpy((void *)&hid_info, value_ptr, length);
+ }
+ break;
+
+ case HID_CONTROL_POINT:
+ hid_suspand_mode = *((uint8_t *)value_ptr);
+ break;
+
+ default:
+ ret = false;
+ break;
+ }
+ return ret;
+}
+
+
+static T_APP_RESULT hids_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ T_HID_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.conn_id = conn_id;
+
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+
+ switch (attrib_index)
+ {
+ default:
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+
+ case GATT_SVC_HID_PROTOCOL_MODE_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX;
+ cause = pfn_hids_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&hid_protocol_mode;
+ *p_length = sizeof(hid_protocol_mode);
+ break;
+
+ case GATT_SVC_HID_REPORT_MOUSE_INPUT_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_OUTPUT_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_FEATURE_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_MAP_INDEX:
+ *pp_value = (uint8_t *)hids_report_descriptor;
+ *p_length = sizeof(hids_report_descriptor);
+ break;
+
+ case GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX;
+ cause = pfn_hids_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&external_report_refer;
+ *p_length = sizeof(external_report_refer);
+ break;
+
+ case GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX:
+ break;
+
+ case GATT_SVC_HID_INFO_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_INFO_INDEX;
+ cause = pfn_hids_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&hid_info;
+ *p_length = sizeof(hid_info);
+ break;
+
+ case GATT_SVC_HID_CONTROL_POINT_INDEX:
+ break;
+ }
+
+ return cause;
+}
+
+
+static T_APP_RESULT hids_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index, T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ T_HID_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+
+ if (!p_value)
+ {
+ cause = APP_RESULT_INVALID_PDU;
+ return cause;
+ }
+
+ switch (attrib_index)
+ {
+ default:
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+
+ case GATT_SVC_HID_PROTOCOL_MODE_INDEX:
+ callback_data.msg_data.write_msg.write_type = write_type;
+ callback_data.msg_data.write_msg.write_parameter.protocol_mode = *p_value;
+ hids_set_parameter(HID_PROTOCOL_MODE, length, p_value);
+ break;
+
+ case GATT_SVC_HID_REPORT_MOUSE_INPUT_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_OUTPUT_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_FEATURE_INDEX:
+ break;
+
+ case GATT_SVC_HID_REPORT_MAP_INDEX:
+ break;
+
+ case GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX:
+ break;
+
+ case GATT_SVC_HID_INFO_INDEX:
+ break;
+
+ case GATT_SVC_HID_CONTROL_POINT_INDEX:
+ break;
+ }
+
+ if (pfn_hids_cb && (cause == APP_RESULT_SUCCESS))
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+
+ return cause;
+
+}
+
+void hids_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ bool cause = true;
+ T_HID_CALLBACK_DATA callback_data;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+
+ PROFILE_PRINT_INFO2("hids_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits);
+
+ switch (index)
+ {
+ default:
+ cause = false;
+ break;
+
+ case GATT_SVC_HID_REPORT_MOUSE_INPUT_CCCD_INDEX:
+ {
+ callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORT_MOUSE_INPUT_CCCD_INDEX;
+ if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION)
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE;
+ }
+ break;
+ }
+ case GATT_SVC_HID_REPORT_VNEDOR_INPUT_CCCD_INDEX:
+ {
+ callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORT_VNEDOR_INPUT_CCCD_INDEX;
+ if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION)
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE;
+ }
+ break;
+ }
+ case GATT_SVC_HID_BOOT_MS_IN_REPORT_CCCD_INDEX:
+ {
+ callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_BOOT_MS_IN_REPORT_CCCD_INDEX;
+ if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION)
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE;
+ }
+ break;
+ }
+ }
+
+ if (pfn_hids_cb && (cause == true))
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+
+ return;
+}
+
+
+/**
+ * @brief Send HIDS notification data .
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] index hids characteristic index.
+ * @param[in] p_data report value pointer.
+ * @param[in] data_len length of report data.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t conn_id = 0;
+ T_SERVER_ID service_id = hids_id;
+ uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
+ hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_MOUSE_INPUT_INDEX, hid_report_input, sizeof(hid_report_input));
+ }
+ * \endcode
+ */
+bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data,
+ uint16_t data_len)
+{
+ PROFILE_PRINT_INFO1("hids_send_report data_len %d", data_len);
+ return server_send_data(conn_id, service_id, index, p_data, data_len, GATT_PDU_TYPE_NOTIFICATION);
+}
+
+
+
+uint16_t hids_attr_tbl_len = sizeof(hids_attr_tbl);
+
+const T_FUN_GATT_SERVICE_CBS hids_cbs =
+{
+ hids_attr_read_cb, // Read callback function pointer
+ hids_attr_write_cb, // Write callback function pointer
+ hids_cccd_update_cb, // Authorization callback function pointer
+};
+
+/**
+ * @brief Add HID service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ hids_id = hids_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID hids_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+ if (false == server_add_service(&service_id, (uint8_t *)hids_attr_tbl, hids_attr_tbl_len, hids_cbs))
+ {
+ PROFILE_PRINT_ERROR1("hids_add_service: ServiceId %d", service_id);
+ service_id = 0xff;
+ }
+
+ pfn_hids_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
diff --git a/src/ble/profile/server/hids_mulkb.c b/src/ble/profile/server/hids_mulkb.c
new file mode 100644
index 0000000..699025e
--- /dev/null
+++ b/src/ble/profile/server/hids_mulkb.c
@@ -0,0 +1,985 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hids_mulkb.c
+ * @brief Source file for using Human Interface Device Service.
+ * @details Global data and function implement.
+ * @author sonny_shen
+ * @date 2022-7-04
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#include <string.h>
+#include "trace.h"
+#include "profile_server.h"
+#include "hids_mulkb.h"
+
+
+#define GATT_UUID_HID 0x1812
+#define GATT_UUID_CHAR_PROTOCOL_MODE 0x2A4E
+#define GATT_UUID_CHAR_REPORT 0x2A4D
+#define GATT_UUID_CHAR_REPORT_MAP 0x2A4B
+#define GATT_UUID_CHAR_BOOT_KB_IN_REPORT 0x2A22
+#define GATT_UUID_CHAR_BOOT_KB_OUT_REPORT 0x2A32
+#define GATT_UUID_CHAR_HID_INFO 0x2A4A
+#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C
+
+/* Report ID for General Keyboard, change: 0x03 to 0x01 */
+#define HOGP_KB_REPORT_ID 0x01
+#define HOGP_FN_KB_REPORT_ID 0x03
+#define HOGP_VENDOR_REPORT_ID 0x10
+#define MULTIMEDIA_KEYBOARD
+T_HID_INFO hid_info = {0, 0, 0x0100};
+T_HID_PROTOCOL_MODE hid_protocol_mode = BOOT_PROTOCOL_MODE;
+uint8_t hid_suspand_mode = 0;
+uint16_t external_report_refer = 0;
+
+const uint8_t hids_report_descriptor[] =
+{
+ /* REPORT_ID (1) */
+ /*USAGE_PAGE (Generic Desktop)*/
+ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
+ 0x09, 0x06, /* USAGE (Keyboard) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ 0x85, HOGP_KB_REPORT_ID, /* REPORT_ID (1) */
+ 0x75, 0x01, /* REPORT_SIZE (1) */
+ 0x95, 0x08, /* REPORT_COUNT (8) */
+ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */
+ 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard Left Control) */
+ 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
+ 0x81, 0x02, /*input (Data,variable,Abs)*/
+// 0x95, 0x01, /* REPORT_COUNT (1) */
+// 0x75, 0x08, /* REPORT_SIZE (8) */
+// 0x81, 0x03, /*input (cons,variable,Abs)*/
+
+ 0x95, 0x05, /* REPORT_COUNT (5) */
+ 0x75, 0x01, /* REPORT_SIZE (1) */
+ 0x05, 0x08, /* USAGE_PAGE (LEDs) */
+ 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */
+ 0x29, 0x05, /* USAGE_MAXIMUM (Kana) */
+ 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */
+ 0x95, 0x01, /* REPORT_COUNT (1) */
+ 0x75, 0x03, /* REPORT_SIZE (3) */
+ 0x91, 0x03, /* OUTPUT (cons,Var,Abs) */
+
+ 0x95, 0x03, /* REPORT_COUNT (6) */
+// 0x95, 0x06, /* REPORT_COUNT (6) */
+ 0x75, 0x08, /* REPORT_SIZE (8) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x25, 0xFF, /* LOGICAL_MAXIMUM (164) */ /* Can be 255 */
+ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */
+ 0x19, 0x00, /* USAGE_MINIMUM (Reserved-no event indicated) */
+ 0x29, 0xFF, /* USAGE_MAXIMUM (Keyboard Application) */ /* Can be 255 */
+ 0x81, 0x00, /* INPUT (Data,Ary,Abs) */
+ 0xc0, /* END_COLLECTION */
+
+ /* REPORT_ID (3) */
+ /* USAGE_PAGE (Consumer) */
+ 0x05, 0x0c, /* USAGE_PAGE (Consumer) */
+ 0x09, 0x01, /* USAGE (Consumer Control) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ 0x85, HOGP_FN_KB_REPORT_ID, /* REPORT_ID (3) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x26, 0x80, 0x03, /* LOGICAL_MAXIMUM (896) */
+ 0x19, 0x00, /* USAGE_MINIMUM */
+ 0x2a, 0x80, 0x03, /* USAGE_MAXIMUM */
+ 0x75, 0x10, /* REPORT_SIZE (16) */
+ 0x95, 0x01, /* REPORT_COUNT (1) */
+ 0x81, 0x00, /* INPUT (Data,Ary,Abs) */
+ 0x95, 0x01, /* REPORT_COUNT (1) */ //test
+ 0x75, 0x10, /* REPORT_SIZE (16) */
+ 0x81, 0x03, /*input (cons,variable,Abs)*/
+ 0xc0, /* END_COLLECTION */
+
+ /* REPORT_ID (4) */
+ /*USAGE_PAGE (Generic Desktop)*/
+ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
+ 0x09, 0x80, /* USAGE (system control) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ 0x85, 0x04, /* REPORT_ID (4) */
+ 0x19, 0x81, /* USAGE_MINIMUM (system power down)*/
+ 0x29, 0x83, /* USAGE_MAXIMUM (system wake up)*/
+ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
+ 0x95, 0x03, /* REPORT_COUNT (3) */
+ 0x75, 0x01, /* REPORT_SIZE (1) */
+ 0x81, 0x02, /* INPUT (Data,value,Abs) */
+ 0x95, 0x01, /* REPORT_COUNT (1) */
+ 0x75, 0x05, /* REPORT_SIZE (5) */
+ 0x81, 0x01, /* INPUT (cons,Ary,Abs) */
+ 0xc0, /* END_COLLECTION */
+
+ /* REPORT_ID (5) */
+ /* USAGE_PAGE (Consumer) */
+ 0x05, 0x0c, /* USAGE_PAGE (Consumer) */
+ 0x09, 0x01, /* USAGE (Consumer Control) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ 0x85, 0x05, /* REPORT_ID (5) */
+ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
+ 0x09, 0x06, /* USAGE (Keyboard) */
+ 0xa1, 0x02, /* COLLECTION (logical) */
+ 0x06, 0x00, 0xFF, /* USAGE_PAGE (vendor defined) */
+ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
+ 0x75, 0x01, /* REPORT_SIZE (1) */
+ 0x95, 0x02, /* REPORT_COUNT (2) */
+ 0x0a, 0x03, 0xfe, /* USAGE (vendor defined) */
+ 0x0a, 0x04, 0xfe, /* USAGE (vendor defined) */
+ 0x81, 0x02, /* INPUT (Data,value,Abs) */
+ 0x75, 0x01, /* REPORT_SIZE (1) */
+ 0x95, 0x01, /* REPORT_COUNT (1) */
+ 0x06, 0xff, 0x00,
+ 0x09, 0x03,
+ 0x81, 0x02, /* INPUT (Data,value,Abs) */
+ 0x95, 0x05, /* REPORT_COUNT (5) */
+ 0x81, 0x03, /* INPUT (cons,value,Abs) */
+ 0xc0, /* END_COLLECTION */
+ 0xc0, /* END_COLLECTION */
+
+ /* REPORT_ID (10) */
+ /* USAGE_PAGE (Consumer) */
+ 0x06, 0x01, 0xff, /* USAGE_PAGE (vendor) */
+ 0x09, 0x01, /* USAGE (vendor) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ 0x85, HOGP_VENDOR_REPORT_ID, /* REPORT_ID (0x10) */
+ 0x19, 0x00, /* USAGE_MINIMUM (0) */
+ 0x29, 0xff, /* USAGE_MAXIMUM (0xff) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x25, 0xff, /* LOGICAL_MAXIMUM (0xff) */
+ 0x75, 0x08, /* REPORT_SIZE (8) */
+ 0x95, 0x04, /* REPORT_COUNT (4) */
+ 0x81, 0x02, /* INPUT (Data,Var,Abs) */
+ 0xc0, /* END_COLLECTION */
+};
+
+static P_FUN_SERVER_GENERAL_CB pfn_hids_cb = NULL;
+
+static const T_ATTRIB_APPL hids_attr_tbl[] =
+{
+ /* <<Primary Service>>, .. 0*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_HID), /* service UUID */
+ HI_WORD(GATT_UUID_HID)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 1*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Protocol Mode characteristic value ..2*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_PROTOCOL_MODE),
+ HI_WORD(GATT_UUID_CHAR_PROTOCOL_MODE)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 3*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID KB Report characteristic value .. 4*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */
+ },
+
+ /* client characteristic configuration .. 5*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */
+ },
+
+ /*report ID map reference descriptor .. 6*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HOGP_KB_REPORT_ID,
+ HID_INPUT_TYPE,
+ },
+ 2, /* bValueLen */
+ NULL,//(void*)&cPointerInputReportIdMap,
+ (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 7*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Report characteristic value .. 8*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */
+ },
+
+ /*report ID map reference descriptor .. 9*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HOGP_KB_REPORT_ID,
+ HID_OUTPUT_TYPE
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 10*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID FN Report characteristic value .. 11*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */
+ },
+
+ /* client characteristic configuration .. 12*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */
+ },
+
+ /*report ID map reference descriptor .. 13*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ HOGP_FN_KB_REPORT_ID,
+ HID_INPUT_TYPE
+ },
+ 2, /* bValueLen */
+ (void *)NULL,
+ (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 14*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Report characteristic value .. 15*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+#endif
+ },
+
+ /* client characteristic configuration .. 16*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+#endif
+ },
+
+ /*report ID map reference descriptor .. 17*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HOGP_VENDOR_REPORT_ID,
+ HID_INPUT_TYPE,
+ },
+ 2, /* bValueLen */
+ NULL,//(void*)&cPointerInputReportIdMap,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* wPermissions */
+#endif
+ },
+
+
+ /*only write report id 1 and report id 3, need to add report id 4 and report id 5 later*/
+
+
+ /* <<Characteristic>>, .. 18*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID report map characteristic value .. 19*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT_MAP),
+ HI_WORD(GATT_UUID_CHAR_REPORT_MAP)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ /* wPermissions */
+ },
+
+// /* <<EXTERNAL_REPORT_REFERENCE>>, .. 16*/
+// {
+// ATTRIB_FLAG_VALUE_APPL, /* flags */
+// { /* type_value */
+// LO_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE),
+// HI_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE),
+// },
+// 0, /* bValueLen */
+// (void *)NULL,
+// GATT_PERM_READ_AUTHEN_REQ /* permissions */
+// },
+
+// /* <<Characteristic>>, .. 17*/
+// {
+// ATTRIB_FLAG_VALUE_INCL, /* flags */
+// { /* type_value */
+// LO_WORD(GATT_UUID_CHARACTERISTIC),
+// HI_WORD(GATT_UUID_CHARACTERISTIC),
+// GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+// /* characteristic UUID not needed here, is UUID of next attrib. */
+// },
+// 1, /* bValueLen */
+// NULL,
+// GATT_PERM_READ /* permissions */
+// },
+
+// /* HID boot keyboard input characteristic value .. 18*/
+// {
+// ATTRIB_FLAG_VALUE_APPL, /* flags */
+// { /* type_value */
+// LO_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT),
+// HI_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT)
+// },
+// 0, /* variable size */
+// (void *)NULL,
+// GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+// },
+
+// /* client characteristic configuration .. 19*/
+// {
+// (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* flags */
+// { /* type_value */
+// LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+// HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+// /* NOTE: this value has an instantiation for each client, a write to */
+// /* this attribute does not modify this default value: */
+// LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+// HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+// },
+// 2, /* bValueLen */
+// NULL,
+// (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+// },
+
+// /* <<Characteristic>>, .. 20*/
+// {
+// ATTRIB_FLAG_VALUE_INCL, /* flags */
+// { /* type_value */
+// LO_WORD(GATT_UUID_CHARACTERISTIC),
+// HI_WORD(GATT_UUID_CHARACTERISTIC),
+// GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+// /* characteristic UUID not needed here, is UUID of next attrib. */
+// },
+// 1, /* bValueLen */
+// NULL,
+// GATT_PERM_READ /* permissions */
+// },
+
+// /* HID boot keyboard output characteristic value .. 21*/
+// {
+// ATTRIB_FLAG_VALUE_APPL, /* flags */
+// { /* type_value */
+// LO_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT),
+// HI_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT)
+// },
+// 0, /* variable size */
+// (void *)NULL,
+// GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+// },
+
+ /* <<Characteristic>>, .. 20*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID Information characteristic value .. 21*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_HID_INFO),
+ HI_WORD(GATT_UUID_CHAR_HID_INFO)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ /* wPermissions */
+ },
+
+ /* <<Characteristic>>, ...22*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* HID controlPoint characteristic value .. 23*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT),
+ HI_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */
+ },
+
+//#ifdef MULTIMEDIA_KEYBOARD
+// /* <<Characteristic>>, .. 25*/
+// {
+// ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+// { /* bTypeValue */
+// LO_WORD(GATT_UUID_CHARACTERISTIC),
+// HI_WORD(GATT_UUID_CHARACTERISTIC),
+// GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */
+// //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+// /* characteristic UUID not needed here, is UUID of next attrib. */
+// },
+// 1, /* bValueLen */
+// NULL,
+// GATT_PERM_READ /* wPermissions */
+// },
+
+// /* HID Report characteristic value ,multimedia keyboard Input 26*/
+// {
+// ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+// { /* bTypeValue */
+// LO_WORD(GATT_UUID_CHAR_REPORT),
+// HI_WORD(GATT_UUID_CHAR_REPORT)
+// },
+// 3, /* variable size */
+// (void *)NULL,
+// GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */
+// },
+
+// /* client characteristic configuration 27*/
+// {
+// (ATTRIB_FLAG_VALUE_INCL | /* wFlags */
+// ATTRIB_FLAG_CCCD_APPL),
+// { /* bTypeValue */
+// LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+// HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+// /* NOTE: this value has an instantiation for each client, a write to */
+// /* this attribute does not modify this default value: */
+// LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+// HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+// },
+// 2, /* bValueLen */
+// NULL,
+// (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */
+// },
+
+// /*report ID map reference descriptor 28*/
+// {
+// (ATTRIB_FLAG_VALUE_INCL | /* wFlags */
+// ATTRIB_FLAG_CCCD_APPL),
+// { /* bTypeValue */
+// LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+// HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+// /* NOTE: this value has an instantiation for each client, a write to */
+// /* this attribute does not modify this default value: */
+// HOGP_MM_REPORT_ID, /* client char. config. bit field */
+// HID_INPUT_TYPE
+// },
+// 2, /* bValueLen */
+// NULL,
+// (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */
+// }
+//#endif
+
+};
+
+/**
+ * @brief Set a HID service parameter.
+ *
+ * NOTE: You can call this function with a HID service parameter type and it will set the
+ * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE.
+ *
+ * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t mode = 1;
+ hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode);
+ }
+ * \endcode
+ */
+bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t length, void *value_ptr)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ case HID_PROTOCOL_MODE:
+ {
+ hid_protocol_mode = (T_HID_PROTOCOL_MODE) * ((uint8_t *)value_ptr);
+ }
+ break;
+
+ case HID_REPORT_INPUT:
+ break;
+
+ case HID_REPORT_OUTPUT:
+ break;
+
+ case HID_REPORT_FEATURE:
+ break;
+
+ case HID_REPORT_MAP:
+ break;
+
+ case HID_EXTERNAL_REPORT_REFER:
+ {
+ external_report_refer = *(uint16_t *)value_ptr;
+ }
+ break;
+
+ case HID_BOOT_KB_IN_REPORT:
+ break;
+
+ case HID_BOOT_KB_OUT_REPORT:
+ break;
+
+ case HID_INFO:
+ {
+ memcpy((void *)&hid_info, value_ptr, length);
+ }
+ break;
+
+ case HID_CONTROL_POINT:
+ hid_suspand_mode = *((uint8_t *)value_ptr);
+ break;
+
+ default:
+ ret = false;
+ break;
+ }
+ return ret;
+}
+
+
+static T_APP_RESULT hids_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ T_HID_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.conn_id = conn_id;
+
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+
+ switch (attrib_index)
+ {
+ default:
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+
+ case GATT_SVC_HID_PROTOCOL_MODE_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX;
+ cause = pfn_hids_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&hid_protocol_mode;
+ *p_length = sizeof(hid_protocol_mode);
+ break;
+
+// case GATT_SVC_HID_REPORT_INPUT_INDEX:
+// break;
+
+ case GATT_SVC_HID_REPORT_OUTPUT_INDEX:
+ break;
+
+// case GATT_SVC_HID_REPORT_FEATURE_INDEX:
+// break;
+
+ case GATT_SVC_HID_REPORT_MAP_INDEX:
+ *pp_value = (uint8_t *)hids_report_descriptor;
+ *p_length = sizeof(hids_report_descriptor);
+ break;
+
+ case GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX;
+ cause = pfn_hids_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&external_report_refer;
+ *p_length = sizeof(external_report_refer);
+ break;
+
+// case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX:
+// break;
+
+// case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX:
+// break;
+
+ case GATT_SVC_HID_INFO_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_INFO_INDEX;
+ cause = pfn_hids_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&hid_info;
+ *p_length = sizeof(hid_info);
+ break;
+
+ case GATT_SVC_HID_CONTROL_POINT_INDEX:
+ break;
+ }
+
+ return cause;
+}
+
+
+static T_APP_RESULT hids_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index, T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ T_HID_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+
+ if (!p_value)
+ {
+ cause = APP_RESULT_INVALID_PDU;
+ return cause;
+ }
+
+ switch (attrib_index)
+ {
+ default:
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+
+ case GATT_SVC_HID_PROTOCOL_MODE_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX;
+ callback_data.msg_data.write_msg.write_type = write_type;
+ callback_data.msg_data.write_msg.write_parameter.protocol_mode = *p_value;
+ hids_set_parameter(HID_PROTOCOL_MODE, length, p_value);
+ break;
+
+// case GATT_SVC_HID_REPORT_INPUT_INDEX:
+// break;
+
+ case GATT_SVC_HID_REPORT_OUTPUT_INDEX:
+ callback_data.msg_data.read_value_index = GATT_SVC_HID_REPORT_OUTPUT_INDEX;
+ callback_data.msg_data.write_msg.write_type = write_type;
+ callback_data.msg_data.write_msg.write_parameter.output = *p_value;
+ break;
+
+// case GATT_SVC_HID_REPORT_FEATURE_INDEX:
+// break;
+
+ case GATT_SVC_HID_REPORT_MAP_INDEX:
+ break;
+
+// case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX:
+// break;
+
+// case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX:
+// break;
+
+ case GATT_SVC_HID_INFO_INDEX:
+ break;
+
+ case GATT_SVC_HID_CONTROL_POINT_INDEX:
+ break;
+ }
+
+ if (pfn_hids_cb && (cause == APP_RESULT_SUCCESS))
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+
+ return cause;
+
+}
+
+void hids_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ bool cause = true;
+ T_HID_CALLBACK_DATA callback_data;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+
+ PROFILE_PRINT_INFO2("hids_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits);
+
+ switch (index)
+ {
+ default:
+ cause = false;
+ break;
+
+ case GATT_SVC_HID_REPORTID1_INPUT_CCCD_INDEX:
+ {
+ callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORTID1_INPUT_CCCD_INDEX;
+ if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION)
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE;
+ }
+ break;
+ }
+
+ case GATT_SVC_HID_REPORTID3_INPUT_CCCD_INDEX:
+ {
+ callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORTID3_INPUT_CCCD_INDEX;
+ if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION)
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE;
+ }
+ break;
+ }
+
+ }
+
+ if (pfn_hids_cb && (cause == true))
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+
+ return;
+}
+
+
+/**
+ * @brief Send HIDS notification data .
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] index hids characteristic index.
+ * @param[in] p_data report value pointer.
+ * @param[in] data_len length of report data.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t conn_id = 0;
+ T_SERVER_ID service_id = hids_id;
+ uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
+ hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_INPUT_INDEX, hid_report_input, sizeof(hid_report_input));
+ }
+ * \endcode
+ */
+bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data,
+ uint16_t data_len)
+{
+ PROFILE_PRINT_INFO1("hids_send_report data_len %d", data_len);
+ return server_send_data(conn_id, service_id, index, p_data, data_len, GATT_PDU_TYPE_NOTIFICATION);
+}
+
+
+
+uint16_t hids_attr_tbl_len = sizeof(hids_attr_tbl);
+
+const T_FUN_GATT_SERVICE_CBS hids_cbs =
+{
+ hids_attr_read_cb, // Read callback function pointer
+ hids_attr_write_cb, // Write callback function pointer
+ hids_cccd_update_cb, // Authorization callback function pointer
+};
+
+/**
+ * @brief Add HID service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ hids_id = hids_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID hids_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+ if (false == server_add_service(&service_id, (uint8_t *)hids_attr_tbl, hids_attr_tbl_len, hids_cbs))
+ {
+ PROFILE_PRINT_ERROR1("hids_add_service: ServiceId %d", service_id);
+ service_id = 0xff;
+ }
+
+ pfn_hids_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
diff --git a/src/ble/profile/server/hids_rmc.c b/src/ble/profile/server/hids_rmc.c
new file mode 100644
index 0000000..117f4c0
--- /dev/null
+++ b/src/ble/profile/server/hids_rmc.c
@@ -0,0 +1,863 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file hids_rmc.c
+* @brief Remote control HID service source file.
+* @details Interfaces to access HIDS service.
+* @author
+* @date 2020-03-11
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "profile_server.h"
+#include "hids_rmc.h"
+#include <string.h>
+#include <trace.h>
+#include "board.h"
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+static P_FUN_SERVER_GENERAL_CB pfn_hids_cb = NULL;
+
+static const uint8_t hids_report_descriptor[] =
+{
+ 0x05, 0x01, /* Usage Page(Generic Desktop) */
+ 0x09, 0x06, /* Usage (Keyboard) */
+ 0xa1, 0x01, /* Collection Application */
+
+ 0x05, 0x07, /* Usage Page (Keyboard) */
+ 0x09, 0x06, /* Usage (Keyboard) */
+ 0xa1, 0x01, /* Collection Application */
+ 0x85, HIDS_KB_REPORT_ID, /* Report Id */
+ 0x95, 0x08, /* Report Count */
+ 0x75, 0x08, /* Report Size */
+ 0x15, 0x00, /* Logical Minimum */
+ 0x25, 0xff, /* Logical Maximum */
+ 0x19, 0x00, /* Usage Minimum */
+ 0x29, 0xff, /* Usage Maximum */
+ 0x81, 0x00, /* Input */
+ 0xc0, /* End Collection */
+
+#if FEATURE_SUPPORT_MULTIMEDIA_KEYBOARD
+ 0x05, 0x0c, /* USAGE_PAGE (Consumer) */
+ 0x09, 0x01, /* USAGE (Consumer Control) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ 0x85, HIDS_MM_KB_REPORT_ID, /* REPORT_ID (4) */
+ 0x95, 0x03, /* report count */
+ 0x75, 0x10, /* report size */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x26, 0x9C, 0x02, /* LOGICAL_MAXIMUM (1) */
+ 0x19, 0x00, /* Usage Minimum */
+ 0x2A, 0x9C, 0x02, /* Usage Maximum */
+ 0x81, 0x00, /* INPUT (Data,Var,Abs) */
+ 0xc0, /* END_COLLECTION */
+#endif
+
+#if SUPPORT_VOICE_FEATURE
+ 0x06, 0x00, 0xff, /* USAGE_PAGE (vendor define) */
+ 0x09, 0x00, /* USAGE (Undefine) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ 0x85, HIDS_VOICE_REPORT_ID, /* REPORT_ID (RMC_VENDOR_REPORT_ID_1) */
+ 0x95, 0xff, /* Report Count */
+ 0x75, 0x08, /* Report Size */
+ 0x15, 0x00, /* Logical Minimum */
+ 0x25, 0xff, /* Logical Maximum */
+ 0x19, 0x00, /* Usage Minimum */
+ 0x29, 0xff, /* Usage Maximum */
+ 0x81, 0x00, /* Input */
+ 0xc0, /* End Collection */
+#endif
+
+ 0xc0 /* End Collection */
+};
+
+static uint8_t hids_protocol_mode = REPORT_PROCOCOL_MODE;
+static uint8_t hids_suspand_mode = 0;
+static HID_INFO_ATTRB hids_info = {0, 0, 0x0100};
+static uint8_t *p_report_data = NULL;
+static uint16_t RmcDataLen = 0;
+
+
+const T_ATTRIB_APPL hids_attr_table[] =
+{
+ /*--------------------------HID Service ---------------------------*/
+ /* <<Primary Service>> 0 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_HID), /* service UUID */
+ HI_WORD(GATT_UUID_HID)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* p_value_context */
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* <<characteristic>> 1 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* HID Information characteristic 2 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_HID_INFO),
+ HI_WORD(GATT_UUID_CHAR_HID_INFO)
+ },
+ 4, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ GATT_PERM_READ_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_READ /* permissions */
+#endif
+ },
+
+ /* <<Characteristic>> 3 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* HID controlPoint characteristic 4 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT),
+ HI_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT)
+ },
+ 1, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* permissions */
+#endif
+ },
+
+ /* <<Characteristic>> 5 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* HID Protocol Mode characteristic 6 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_PROTOCOL_MODE),
+ HI_WORD(GATT_UUID_CHAR_PROTOCOL_MODE)
+ },
+ 1, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* permissions */
+#endif
+ },
+
+ /* <<Characteristic>> 7 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* HID Report Map characteristic 8 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_REPORT_MAP),
+ HI_WORD(GATT_UUID_CHAR_REPORT_MAP)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ GATT_PERM_READ_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_READ /* permissions */
+#endif
+ },
+
+ /* <<Characteristic>> 9 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* Keyboard Input Report characteristic 10 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 8, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* permissions */
+#endif
+ },
+
+ /* client characteristic configuration 11 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* flags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */
+#endif
+ },
+
+ /* Keyboard Input Report reference descriptor 12 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* flags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ HIDS_KB_REPORT_ID, /* client char. config. bit field */
+ 1
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* permissions */
+#endif
+ },
+
+#if SUPPORT_VOICE_FEATURE
+ /* <<Characteristic>> 13 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* HID Report characteristic value, Voice Input 14 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 255, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* permissions */
+#endif
+ },
+
+ /* client characteristic configuration 15 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* flags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */
+#endif
+ },
+
+ /* Voice Input reference descriptor 16 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* flags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ HIDS_VOICE_REPORT_ID, /* client char. config. bit field */
+ HID_INPUT_TYPE
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* permissions */
+#endif
+ },
+
+ /* <<Characteristic>> 17 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* HID Report characteristic value, Voice Output 18 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* permissions */
+#endif
+ },
+
+ /* Voice Output reference descriptor 19 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* flags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ HIDS_VOICE_REPORT_ID, /* client char. config. bit field */
+ HID_OUTPUT_TYPE
+ },
+ 2, /* bValueLen */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* permissions */
+#endif
+ },
+#endif
+
+#if FEATURE_SUPPORT_MULTIMEDIA_KEYBOARD
+ /* <<Characteristic>> 20 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* HID Report characteristic value, multimedia keyboard Input 21 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 3, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* permissions */
+#endif
+ },
+
+ /* client characteristic configuration 22 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* flags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */
+#endif
+ },
+
+ /* multimedia keyboard Input reference descriptor 23 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* flags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ HIDS_MM_KB_REPORT_ID, /* client char. config. bit field */
+ HID_INPUT_TYPE
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* permissions */
+#endif
+ }
+#endif
+};
+
+
+static uint16_t hids_attr_tbl_size = sizeof(hids_attr_table);
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/**
+ * @brief Set a HID service parameter.
+ *
+ * NOTE: You can call this function with a HID service parameter type and it will set the
+ * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE.
+ *
+ * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t mode = 1;
+ hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode);
+ }
+ * \endcode
+ */
+bool hids_set_parameter(uint8_t param_type, uint8_t length, void *value_ptr)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ case HIDS_PARAM_PROTOCOL_MODE:
+ {
+ hids_protocol_mode = *((uint8_t *)value_ptr);
+ }
+ break;
+ case HIDS_PARAM_SUSPEND_MODE:
+ {
+ hids_suspand_mode = *((uint8_t *)value_ptr);
+ }
+ break;
+ case HIDS_PARAM_HID_INFO:
+ {
+ memcpy((void *)&hids_info, value_ptr, length);
+ }
+ break;
+ case HIDS_PARAM_REPORT:
+ {
+ RmcDataLen = length;
+ p_report_data = value_ptr;
+ }
+ break;
+
+ default:
+ ret = false;
+ break;
+
+ }
+ return ret;
+}
+
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param conn_id Connection ID.
+ * @param service_id ServiceID to be read.
+ * @param attrib_index Attribute index of getting characteristic data.
+ * @param offset Offset of characteritic to be read.
+ * @param p_length Length of getting characteristic data.
+ * @param pp_value Pointer to pointer of characteristic value to be read.
+ * @return T_APP_RESULT
+*/
+T_APP_RESULT hids_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ T_HID_CALLBACK_DATA callback_data;
+ *p_length = 0;
+
+ PROFILE_PRINT_INFO2("hids_attr_read_cb attrib_index = %d offset %x", attrib_index, offset);
+
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ switch (attrib_index)
+ {
+ default:
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+
+ case GATT_SRV_HID_KB_INPUT_INDEX:
+#if SUPPORT_VOICE_FEATURE
+ case GATT_SRV_HID_VOICE_INPUT_INDEX:
+ case GATT_SRV_HID_VOICE_OUTPUT_INDEX:
+#endif
+#if FEATURE_SUPPORT_MULTIMEDIA_KEYBOARD
+ case GATT_SRV_HID_MM_KB_INPUT_INDEX:
+#endif
+ {
+ callback_data.msg_data.read_value_index = HIDS_READ_PARAM_REPORT;
+ if (pfn_hids_cb)
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+ *pp_value = p_report_data;
+ *p_length = RmcDataLen;
+ if ((*p_length == 0) || (NULL == p_report_data))
+ {
+ cause = APP_RESULT_APP_ERR;
+ }
+ }
+ break;
+
+ case GATT_SVC_HID_INFO_INDEX:
+ {
+ callback_data.msg_data.read_value_index = HIDS_READ_PARAM_HID_INFO;
+ if (pfn_hids_cb)
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+ *pp_value = (uint8_t *)&hids_info;
+ *p_length = sizeof(hids_info);
+ }
+ break;
+ case GATT_SVC_HID_CONTROL_POINT_INDEX:
+ {
+ callback_data.msg_data.read_value_index = HIDS_READ_PARAM_SUSPEND_MODE;
+ if (pfn_hids_cb)
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+ *pp_value = &hids_suspand_mode;
+ *p_length = 1;
+ }
+ break;
+ case GATT_SVC_HID_PROTOCOL_MODE_INDEX:
+ {
+ callback_data.msg_data.read_value_index = HIDS_READ_PARAM_PROTOCOL_MODE;
+ if (pfn_hids_cb)
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+ *pp_value = &hids_protocol_mode;
+ *p_length = sizeof(hids_protocol_mode);
+ }
+ break;
+ case GATT_SVC_HID_REPORT_MAP_INDEX:
+ {
+ *pp_value = (uint8_t *)hids_report_descriptor;
+ *p_length = sizeof(hids_report_descriptor);
+ }
+ break;
+ }
+
+ return cause;
+}
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID to be written.
+ * @param[in] attrib_index Attribute index of characteristic.
+ * @param[in] write_type Write type.
+ * @param[in] length Length of writing characteristic data.
+ * @param[in] p_value Pointer to characteristic data.
+ * @param[in] p_write_ind_post_proc Function pointer after ias_attr_write_cb.
+ * @return TProfileResult
+*/
+T_APP_RESULT hids_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ T_HID_CALLBACK_DATA callback_data;
+ if (!p_value)
+ {
+ PROFILE_PRINT_ERROR2("hids_attr_write_cb: p_value %p length= 0x%x", p_value, length);
+ cause = APP_RESULT_INVALID_PDU;
+ return cause;
+ }
+
+ switch (attrib_index)
+ {
+ default:
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+#if SUPPORT_VOICE_FEATURE
+ case GATT_SRV_HID_VOICE_OUTPUT_INDEX:
+ APP_PRINT_INFO1("--> host write voice output 0x%x ", *p_value);
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_type = HID_WRITE_VIOCE_CMD;
+ callback_data.msg_data.write.write_parameter.voice_enable = *p_value;
+ break;
+#endif
+ case GATT_SVC_HID_PROTOCOL_MODE_INDEX:
+ {
+ hids_protocol_mode = *p_value;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_type = HID_WRITE_PROTOCOL_MODE;
+ callback_data.msg_data.write.write_parameter.protocol_mode = *p_value;
+
+ cause = APP_RESULT_SUCCESS;
+ APP_PRINT_INFO1("--> host write hids_protocol_mode %d ",
+ hids_protocol_mode);
+ }
+ break;
+ case GATT_SVC_HID_CONTROL_POINT_INDEX:
+ {
+ hids_suspand_mode = *p_value;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_type = HID_WRITE_SUSPEND_MODE;
+ callback_data.msg_data.write.write_parameter.suspend_mode = *p_value;
+
+ cause = APP_RESULT_SUCCESS;
+ APP_PRINT_INFO1("--> host write hids_suspand_mode %d",
+ hids_suspand_mode);
+ }
+ break;
+ case GATT_SRV_HID_KB_INPUT_INDEX:
+#if SUPPORT_VOICE_FEATURE
+ case GATT_SRV_HID_VOICE_INPUT_INDEX:
+#endif
+#if FEATURE_SUPPORT_MULTIMEDIA_KEYBOARD
+ case GATT_SRV_HID_MM_KB_INPUT_INDEX:
+#endif
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_type = HID_WRITE_INPUT_REPORT;
+ callback_data.msg_data.write.write_parameter.report_data.reportLen = length;
+ callback_data.msg_data.write.write_parameter.report_data.report = p_value;
+ cause = APP_RESULT_SUCCESS;
+ }
+ break;
+ }
+
+ if (pfn_hids_cb && (cause == APP_RESULT_SUCCESS))
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+
+ return cause;
+
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param conn_id Connection ID.
+ * @param service_id Service ID.
+ * @param index Attribute index of characteristic data.
+ * @param ccc_bits CCCD bits from stack.
+ * @return None
+*/
+void hids_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ T_HID_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ bool handle = true;
+
+ PROFILE_PRINT_INFO2("hids_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits);
+ switch (index)
+ {
+ case GATT_SRV_HID_KB_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_KB_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_KB_DISABLE;
+ }
+ }
+ break;
+#if SUPPORT_VOICE_FEATURE
+ case (GATT_SRV_HID_VOICE_INPUT_CCCD_INDEX):
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_VOICE_ENABLE;
+ }
+ else if ((ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) == 0)
+ {
+ callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_VOICE_DISABLE;
+ }
+ }
+ break;
+#endif
+
+#if FEATURE_SUPPORT_MULTIMEDIA_KEYBOARD
+ case GATT_SRV_HID_MM_KB_INPUT_CCCD_INDEX:
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_MM_KB_ENABLE;
+
+ }
+ else
+ {
+ callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_MM_KB_DISABLE;
+ }
+ break;
+#endif
+ default:
+ handle = false;
+ break;
+ }
+
+ if (pfn_hids_cb && (handle == true))
+ {
+ pfn_hids_cb(service_id, (void *)&callback_data);
+ }
+
+ return;
+}
+
+/**
+ * @brief HID Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS hids_cbs =
+{
+ hids_attr_read_cb, // Read callback function pointer
+ hids_attr_write_cb, // Write callback function pointer
+ hids_cccd_update_cb // Authorization callback function pointer
+};
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/**
+ * @brief Add HIDS service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ bas_id = hids_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+uint8_t hids_add_service(void *p_func)
+{
+ uint8_t service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)hids_attr_table,
+ hids_attr_tbl_size,
+ hids_cbs))
+ {
+ APP_PRINT_ERROR1("hids_add_service: ServiceId %d", service_id);
+ service_id = 0xff;
+ }
+
+ pfn_hids_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/ble/profile/server/hrs.c b/src/ble/profile/server/hrs.c
new file mode 100644
index 0000000..873a7a0
--- /dev/null
+++ b/src/ble/profile/server/hrs.c
@@ -0,0 +1,639 @@
+/*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file hrs.c
+* @brief Heart Rate service source file.
+* @details Interfaces to access Heart Rate service.
+* @author
+* @date 2017-9-21
+* @version v1.0
+*********************************************************************************************************
+*/
+#include "stdint.h"
+#include "gatt.h"
+#include <string.h>
+#include "trace.h"
+#include "profile_server.h"
+#include "hrs.h"
+
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+#define HRS_BODY_SENSOR_LOCATION_CHAR_SUPPORT
+#define HRS_ENERGY_EXPENDED_FEATURE_SUPPORT
+
+#define HRS_HEART_RATE_MEASUREMENT_VALUE_INDEX 2//notify
+#define HRS_BODY_SENSOR_LOCATION_VALUE_INDEX 5//read
+#define HRS_HEART_RATE_CP_VALUE_INDEX 7//write
+
+#define HRS_HEART_RATE_MEASUREMENT_CCCD_INDEX 3
+
+#define GATT_UUID_SERVICE_HEART_RATE 0x180D
+#define GATT_UUID_CHAR_HRS_HEART_RATE_MEASUREMENT 0x2A37
+#define GATT_UUID_CHAR_HRS_BODY_SENSOR_LOCATION 0x2A38
+#define GATT_UUID_CHAR_HRS_HEART_RATE_CP 0x2A39
+
+#define HRS_CP_RSPCODE_RESERVED 0x00
+#define HRS_CP_RSPCODE_SUCCESS 0x01
+#define HRS_CP_RSPCODE_OPCODE_UNSUPPORT 0x02
+#define HRS_CP_RSPCODE_INVALID_PARAMETER 0x03
+#define HRS_CP_RSPCODE_OPERATION_FAILED 0x04
+
+#define HRS_CTL_PNT_OPERATE_ACTIVE(x) \
+ (x == HRS_HEART_RATE_CP_OPCODE_RESET_ENERGY_EXPENDED)
+
+#define Heart_Rate_Value_Format_UINT8 0
+#define Heart_Rate_Value_Format_UINT16 1
+
+#define HRS_HEART_RATE_MEASUREMENT_VALUE_MAX_LEN 7
+
+
+
+HRS_NOTIFY_INDICATE_FLAG hrs_notify_indicate_flag = {0};
+T_HEART_RATE_MEASUREMENT_VALUE hrs_heart_rate_measurement_value = {0};
+uint8_t hrs_body_sensor_location_value = 0;
+T_HRS_CONTROL_POINT hrs_ctl_pnt = {0};
+
+
+/**< Function pointer used to send event to application from location and navigation profile. */
+
+static P_FUN_SERVER_GENERAL_CB pfn_hrs_app_cb = NULL;
+
+/**< @brief profile/service definition. */
+static const T_ATTRIB_APPL hrs_attr_tbl[] =
+{
+ /*----------------- Heart Rate Service -------------------*/
+ /* <<Primary Service>>, .. 0,*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_SERVICE_HEART_RATE), /* service UUID */
+ HI_WORD(GATT_UUID_SERVICE_HEART_RATE)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic>>, Heart Rate Measurement*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_NOTIFY/* characteristic properties */
+ )
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* Temperature Measurement value 2,*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_HRS_HEART_RATE_MEASUREMENT),
+ HI_WORD(GATT_UUID_CHAR_HRS_HEART_RATE_MEASUREMENT)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_NOTIF_IND/* wPermissions */
+ },
+
+ /* client characteristic configuration */
+ {
+ ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ }
+#ifdef HRS_BODY_SENSOR_LOCATION_CHAR_SUPPORT
+ ,
+ /* <<Characteristic>>Body Sensor Location*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_READ/* characteristic properties */
+ )
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_HRS_BODY_SENSOR_LOCATION),
+ HI_WORD(GATT_UUID_CHAR_HRS_BODY_SENSOR_LOCATION)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ }
+#endif
+
+#ifdef HRS_ENERGY_EXPENDED_FEATURE_SUPPORT
+ ,
+ /* <<Characteristic>> Heart Rate Control Point*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_WRITE/* characteristic properties */
+ )
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_HRS_HEART_RATE_CP),
+ HI_WORD(GATT_UUID_CHAR_HRS_HEART_RATE_CP)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_WRITE/* wPermissions */
+ }
+#endif
+};
+
+/**< @brief Heart Rate service size definition. */
+const uint16_t hrs_attr_tbl_size = sizeof(hrs_attr_tbl);
+
+/**
+ * @brief Set a heart rate service parameter.
+ *
+ * NOTE: You can call this function with a heart rate service parameter type and it will set the
+ * heart rate service parameter. Heart rate service parameters are defined
+ * in @ref T_HTS_TEMPERATURE_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Health thermometer service parameter type: @ref T_HRS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ T_HEART_RATE_MEASUREMENT_VALUE_FLAG flag;
+ flag.heart_rate_value_format_bit = 1;
+ flag.sensor_contact_status_bits = 3;
+ if (p_parse_value->param_count >= 1)
+ {
+ flag.sensor_contact_status_bits = p_parse_value->dw_param[1];
+ }
+
+ flag.energy_expended_status_bit = 1;
+ flag.rr_interval_bit = 1;
+ flag.rfu = 0;
+
+ hrs_set_parameter(HRS_HEART_RATE_MEASUREMENT_PARAM_FLAG, 1, &flag);
+ }
+ * \endcode
+ */
+
+bool hrs_set_parameter(T_HRS_PARAM_TYPE param_type, uint8_t len, void *p_value)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ default:
+ {
+ ret = false;
+ PROFILE_PRINT_ERROR0("hrs_set_parameter failed\n");
+ }
+ break;
+
+ case HRS_HEART_RATE_MEASUREMENT_PARAM_FLAG:
+ {
+ if (len != sizeof(uint8_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&hrs_heart_rate_measurement_value.flag, p_value, len);
+ }
+ }
+ break;
+
+ case HRS_HEART_RATE_MEASUREMENT_PARAM_MEASUREMENT_VALUE:
+ {
+ if (len != sizeof(uint16_t) && len != sizeof(uint8_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&hrs_heart_rate_measurement_value.heart_rate_measurement_value, p_value, len);
+
+ }
+ }
+ break;
+
+ case HRS_HEART_RATE_MEASUREMENT_PARAM_ENERGY_EXPENDED:
+ {
+ if (len != sizeof(uint16_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&hrs_heart_rate_measurement_value.energy_expended, p_value, len);
+
+ }
+ }
+ break;
+
+ case HRS_HEART_RATE_MEASUREMENT_PARAM_RR_INTERVAL:
+ {
+ if (len != sizeof(uint16_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&hrs_heart_rate_measurement_value.rr_interval, p_value, len);
+
+ }
+ }
+ break;
+
+ case HRS_BODY_SENSOR_LOCATION_PARAM_VALUE:
+ {
+ if (len != sizeof(uint8_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&hrs_body_sensor_location_value, p_value, len);
+ }
+ }
+ break;
+
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Send heart rate measurement value notification data.
+ * Application shall call @ref hrs_set_parameter to set heart rate measurement value first,
+ * and the call this api to send the notication value.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ *
+ * @return service id @ref T_SERVER_ID.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ bool op_result;
+
+ T_HEART_RATE_MEASUREMENT_VALUE_FLAG flag;
+ flag.heart_rate_value_format_bit = 1;
+ flag.sensor_contact_status_bits = 3;
+ if (p_parse_value->param_count >= 1)
+ {
+ flag.sensor_contact_status_bits = p_parse_value->dw_param[1];
+ }
+
+ flag.energy_expended_status_bit = 1;
+ flag.rr_interval_bit = 1;
+ flag.rfu = 0;
+
+ hrs_set_parameter(HRS_HEART_RATE_MEASUREMENT_PARAM_FLAG, 1, &flag);
+
+ op_result = hrs_heart_rate_measurement_value_notify(p_parse_value->dw_param[0], hrs_id);
+ }
+ * \endcode
+ */
+bool hrs_heart_rate_measurement_value_notify(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ uint8_t heart_rate_measurement_value[HRS_HEART_RATE_MEASUREMENT_VALUE_MAX_LEN];
+ uint8_t cur_offset = 0;
+
+ memcpy(&heart_rate_measurement_value[cur_offset], &hrs_heart_rate_measurement_value.flag, 1);
+ cur_offset += 1;
+
+ if (hrs_heart_rate_measurement_value.flag.heart_rate_value_format_bit ==
+ Heart_Rate_Value_Format_UINT8)
+ {
+ memcpy(&heart_rate_measurement_value[cur_offset],
+ &hrs_heart_rate_measurement_value.heart_rate_measurement_value, 1);
+ cur_offset += 1;
+ }
+ else
+ {
+ memcpy(&heart_rate_measurement_value[cur_offset],
+ &hrs_heart_rate_measurement_value.heart_rate_measurement_value, 2);
+ cur_offset += 2;
+ }
+
+ if (hrs_heart_rate_measurement_value.flag.energy_expended_status_bit)
+ {
+ memcpy(&heart_rate_measurement_value[cur_offset], &hrs_heart_rate_measurement_value.energy_expended,
+ 2);
+ cur_offset += 2;
+ }
+
+ if (hrs_heart_rate_measurement_value.flag.rr_interval_bit)
+ {
+ memcpy(&heart_rate_measurement_value[cur_offset], &hrs_heart_rate_measurement_value.rr_interval, 2);
+ cur_offset += 2;
+ }
+
+ PROFILE_PRINT_INFO0("hrs_heart_rate_measurement_value_notify");
+ return server_send_data(conn_id, service_id, HRS_HEART_RATE_MEASUREMENT_VALUE_INDEX,
+ heart_rate_measurement_value, cur_offset, GATT_PDU_TYPE_NOTIFICATION);
+}
+
+/**
+ * @brief handle control point write (request).
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param write_length Write request data length.
+ * @param value_ptr Pointer to write request data.
+ * @return none
+ * @retval void
+*/
+static T_APP_RESULT hrs_handle_ctl_pnt_proc(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t write_length, uint8_t *p_value)
+{
+ T_HRS_CALLBACK_DATA callback_data;
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ uint16_t parameter_length = 0;
+ memcpy(hrs_ctl_pnt.value, p_value, write_length);
+ if (write_length >= 1)
+ {
+ parameter_length = write_length - 1;
+ }
+
+ PROFILE_PRINT_INFO1("hrs_handle_ctl_pnt_proc request: OpCode=0x%x", hrs_ctl_pnt.value[0]);
+
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.opcode = (T_HRS_HEART_RATE_CP_OPCODE)hrs_ctl_pnt.value[0];
+
+
+ switch (hrs_ctl_pnt.value[0])
+ {
+ case HRS_HEART_RATE_CP_OPCODE_RESET_ENERGY_EXPENDED:
+ {
+ if (!hrs_notify_indicate_flag.heart_rate_measurement_notify_enable)
+ {
+ cause = APP_RESULT_PROC_ALREADY_IN_PROGRESS;
+ }
+ else if (parameter_length != 0)
+ {
+ cause = APP_RESULT_INVALID_PDU;
+ }
+ }
+ break;
+
+
+ default:
+ {
+ cause = APP_RESULT_APP_ERR;
+ }
+ break;
+ }
+
+ pfn_hrs_app_cb(service_id, (void *)&callback_data);
+ return cause;
+}
+
+
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param[in] attrib_index Attribute index of getting characteristic data.
+ * @param[in] offset Used for Blob Read.
+ * @param[in,out] p_length length of getting characteristic data.
+ * @param[in,out] pp_value data got from service.
+ * @return Profile procedure result
+*/
+T_APP_RESULT hrs_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+
+ PROFILE_PRINT_INFO2("hrs_attr_read_cb iAttribIndex = %d iOffset %x", attrib_index, offset);
+
+ *p_length = 0;
+
+ switch (attrib_index)
+ {
+ case HRS_BODY_SENSOR_LOCATION_VALUE_INDEX:
+ {
+ T_HRS_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = HRS_READ_BODY_SENSOR_LOCATION_VALUE;
+ pfn_hrs_app_cb(service_id, (void *)&callback_data);
+
+ *p_length = sizeof(hrs_body_sensor_location_value);
+ memcpy(pp_value, &hrs_body_sensor_location_value, *p_length);
+ }
+ break;
+
+ default:
+ {
+ PROFILE_PRINT_ERROR1("hrs_attr_read_cb iAttribIndex = %d not found", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ break;
+ }
+
+ return cause;
+}
+
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID to be written.
+ * @param[in] attrib_index Attribute index of characteristic.
+ * @param[in] length length of value to be written.
+ * @param[in] p_value value to be written.
+ * @return Profile procedure result
+*/
+T_APP_RESULT hrs_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ PROFILE_PRINT_INFO2("hrs_attr_write_cb iAttribIndex = %d wLength %x", attrib_index, length);
+
+ switch (attrib_index)
+ {
+ case HRS_HEART_RATE_CP_VALUE_INDEX:
+ {
+ /* Attribute value has variable size, make sure written value size is valid. */
+ if ((length > HRS_MAX_CTL_PNT_VALUE) || (p_value == NULL))
+ {
+ cause = APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ /* Make sure Control Point is not "Process already in progress". */
+ else if (HRS_CTL_PNT_OPERATE_ACTIVE(hrs_ctl_pnt.value[0]))
+ {
+ cause = APP_RESULT_PROC_ALREADY_IN_PROGRESS;
+ }
+ /* Make sure Control Point is configured indication enable. */
+ else if (!hrs_notify_indicate_flag.heart_rate_measurement_notify_enable)
+ {
+ cause = APP_RESULT_CCCD_IMPROPERLY_CONFIGURED;
+ }
+ else
+ {
+ cause = hrs_handle_ctl_pnt_proc(conn_id, service_id, length, p_value);
+ }
+
+ }
+ break;
+
+ default:
+ {
+ PROFILE_PRINT_ERROR1("hrs_attr_write_cb iAttribIndex = %d not found", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ break;
+ }
+ hrs_ctl_pnt.value[0] = HRS_HEART_RATE_CP_OPCODE_RESERVED;
+
+ return cause;
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param[in] index Attribute index of characteristic data.
+ * @param[in] ccc_bits CCCD bits from stack.
+ * @return None
+*/
+void hrs_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ T_HRS_CALLBACK_DATA hrs_callback_data;
+ bool bHandle = true;
+
+ PROFILE_PRINT_INFO2("hrs_cccd_update_cb Index = %d wCCCDBits %x", index, ccc_bits);
+
+ switch (index)
+ {
+ case HRS_HEART_RATE_MEASUREMENT_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ // Enable Notification
+ hrs_notify_indicate_flag.heart_rate_measurement_notify_enable = 1;
+ hrs_callback_data.msg_data.notification_indification_index =
+ HRS_NOTIFY_INDICATE_MEASUREMENT_VALUE_ENABLE;
+ }
+ else
+ {
+ hrs_notify_indicate_flag.heart_rate_measurement_notify_enable = 0;
+ hrs_callback_data.msg_data.notification_indification_index =
+ HRS_NOTIFY_INDICATE_MEASUREMENT_VALUE_DISABLE;
+ }
+ }
+ break;
+
+
+ default:
+ {
+ bHandle = false;
+ PROFILE_PRINT_ERROR1("hrs_cccd_update_cb Index = %d not found", index);
+ }
+ break;
+
+ }
+ /* Notify Application. */
+ if (pfn_hrs_app_cb && (bHandle == true))
+ {
+ pfn_hrs_app_cb(service_id, (void *)&hrs_callback_data);
+ }
+
+ return;
+}
+
+/**
+ * @brief Heart Rate Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS hrs_cbs =
+{
+ hrs_attr_read_cb, // Read callback function pointer
+ hrs_attr_write_cb, // Write callback function pointer
+ hrs_cccd_update_cb // CCCD update callback function pointer
+};
+
+/**
+ * @brief Add heart rate service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ hrs_id = hrs_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID hrs_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)hrs_attr_tbl,
+ hrs_attr_tbl_size,
+ hrs_cbs))
+ {
+ PROFILE_PRINT_ERROR1("hrs_add_service: ServiceId %d", service_id);
+ service_id = 0xff;
+ }
+ pfn_hrs_app_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+
+ return service_id;
+}
+
+
diff --git a/src/ble/profile/server/hts.c b/src/ble/profile/server/hts.c
new file mode 100644
index 0000000..cd5e5b2
--- /dev/null
+++ b/src/ble/profile/server/hts.c
@@ -0,0 +1,724 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2014, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file hts.c
+* @brief Health Thermometer service source file.
+* @details Interfaces to access Health Thermometer service.
+* @author
+* @date 2017-9-20
+* @version v1.0
+*********************************************************************************************************
+*/
+#include "gatt.h"
+#include "string.h"
+#include "trace.h"
+#include "hts.h"
+
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+/**< Temperature Type value. */
+#define HTS_TEMPERATURE_TYPE_CHAR_SUPPORT
+#define HTS_INTERMEDIATE_TEMPERATURE_CHAR_SUPPORT
+#define HTS_MEASUREMENT_INTERVAL_CHAR_SUPPORT
+#define HTS_MEASUREMENT_INTERVAL_CHAR_INDICATE_SUPPORT
+#define HTS_MEASUREMENT_INTERVAL_CHAR_WRITE_SUPPORT
+
+
+#define HTS_TEMPERATURE_MEASUREMENT_INDEX 2
+#define HTS_TEMPERATURE_TYPE_INDEX 5
+#define HTS_INTERMEDIATE_TEMPERATURE_INDEX 7
+#define HTS_MEASUREMENT_INTERVAL_INDEX 10
+#define HTS_MEASUREMENT_INTERVAL_VALID_RANGE_INDEX 12
+
+#define HTS_TEMPERATURE_MEASUREMENT_CCCD_INDEX 3
+#define HTS_INTERMEDIATE_TEMPERATURE_CCCD_INDEX 8
+#define HTS_MEASUREMENT_INTERVAL_CCCD_INDEX 11
+
+#define GATT_UUID_HELTH_TEMPERATURE_SERVICE 0x1809
+#define GATT_UUID_CHAR_HTS_MEASUREMENT_INTERVAL 0x2A21
+#define GATT_UUID_CHAR_HTS_INTERMEDIATE_TMPERATURE 0x2A1E
+#define GATT_UUID_CHAR_HTS_TEMPERATURE_MEASUREMENT 0x2a1c
+#define GATT_UUID_CHAR_HTS_TEMPERATURE_TYPE 0x2a1d
+
+#define HTS_MEASUREMENT_VALUE_MAX_LEN 13
+
+typedef struct
+{
+ T_HEALTH_THERMOMETER_MEASUREMENT_VALUE_FLAG flag;
+ uint32_t temp_celsius_value;
+ uint32_t temp_fahrenheit_value;
+ T_TIME_STAMP time_stamp;
+ uint8_t temper_next_desc;
+} T_HTS_MESAURMENT;
+
+static T_HTS_TEMPERATURE_TYPE temperature_type = HTS_TEMPERATURE_TYPE_ARMPIT;
+static uint16_t hts_measurement_interval = 50;
+static T_HTS_MEASUREMENT_INTERVAL_VALID_RANGE hts_measurement_interval_valid_range = {0};
+
+static P_FUN_SERVER_GENERAL_CB pfn_hts_cb = NULL;
+
+static T_HTS_MESAURMENT hts_measurement = {0};
+static uint8_t hts_measurement_value_for_notify_indicate[HTS_MEASUREMENT_VALUE_MAX_LEN];
+static uint8_t hts_measurement_value_actual_length = 0;
+
+/**< @brief profile/service definition. */
+static const T_ATTRIB_APPL hts_attr_tbl[] =
+{
+ /*----------------- Health Temperature Service -------------------*/
+ /* <<Primary Service>>, .. 0,*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_HELTH_TEMPERATURE_SERVICE), /* service UUID */
+ HI_WORD(GATT_UUID_HELTH_TEMPERATURE_SERVICE)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* <<Characteristic>>, .. 1,*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_INDICATE /* characteristic properties */
+ )
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* Temperature Measurement value 2,*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_HTS_TEMPERATURE_MEASUREMENT),
+ HI_WORD(GATT_UUID_CHAR_HTS_TEMPERATURE_MEASUREMENT)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_NONE /* wPermissions */
+ },
+ /* client characteristic configuration 3*/
+ {
+ ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ }
+
+#ifdef HTS_TEMPERATURE_TYPE_CHAR_SUPPORT
+ ,
+ /* <<Characteristic>>, .. 4*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_READ /* characteristic properties */
+ )
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* Temperature Type value 5*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_HTS_TEMPERATURE_TYPE),
+ HI_WORD(GATT_UUID_CHAR_HTS_TEMPERATURE_TYPE)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ }
+#endif
+
+#ifdef HTS_INTERMEDIATE_TEMPERATURE_CHAR_SUPPORT
+ ,
+ /* <<Characteristic>>, .. 6*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_NOTIFY /* characteristic properties */
+ )
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* Intermediate Temperature value,7*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_HTS_INTERMEDIATE_TMPERATURE),
+ HI_WORD(GATT_UUID_CHAR_HTS_INTERMEDIATE_TMPERATURE)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_NONE /* wPermissions */
+ },
+ /* client characteristic configuration ,8*/
+ {
+ ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ }
+#endif
+
+#ifdef HTS_MEASUREMENT_INTERVAL_CHAR_SUPPORT
+ ,
+ /* <<Characteristic>>, .. ,9*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_READ /* characteristic properties */
+#ifdef HTS_MEASUREMENT_INTERVAL_CHAR_INDICATE_SUPPORT
+ | GATT_CHAR_PROP_INDICATE
+#endif
+#ifdef HTS_MEASUREMENT_INTERVAL_CHAR_WRITE_SUPPORT
+ | GATT_CHAR_PROP_WRITE
+#endif
+ )
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* Measurement Interval value, 10*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_HTS_MEASUREMENT_INTERVAL),
+ HI_WORD(GATT_UUID_CHAR_HTS_MEASUREMENT_INTERVAL)
+ },
+ 0, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ }
+
+#ifdef HTS_MEASUREMENT_INTERVAL_CHAR_INDICATE_SUPPORT
+ ,
+ /* client characteristic configuration, 11*/
+ {
+ ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ }
+#endif
+
+#ifdef HTS_MEASUREMENT_INTERVAL_CHAR_WRITE_SUPPORT
+ ,
+ /* valid range descriptor ,12*/
+ {
+ ATTRIB_FLAG_VALUE_APPL,
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_VALID_RANGE),
+ HI_WORD(GATT_UUID_CHAR_VALID_RANGE),
+
+ },
+ 0, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ) /* wPermissions */
+ }
+#endif
+#endif
+};
+/**< @brief Health Temperature service size definition. */
+const uint16_t hts_attr_tbl_size = sizeof(hts_attr_tbl);
+
+/**
+ * @brief Set a health thermometer service parameter.
+ *
+ * NOTE: You can call this function with a health thermometer service parameter type and it will set the
+ * health thermometer service parameter. Health thermometer service parameters are defined
+ * in @ref T_HTS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Health thermometer service parameter type: @ref T_HTS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t hts_flag = HTS_FLAG_MEASUREMENT_UINT_BIT | HTS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT |
+ HTS_FLAG_MEASUREMENT_TYPE_PRESENT_BIT;
+ T_HTS_TEMPERATURE_TYPE temperature_type = HTS_TEMPERATURE_TYPE_ARMPIT;
+
+ hts_measure_time_stamp.seconds += hts_measurement_interval;
+
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG, sizeof(hts_flag), &hts_flag);
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(hts_measure_time_stamp),
+ &hts_measure_time_stamp);
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE, 1, &temperature_type);
+ }
+ * \endcode
+ */
+bool hts_set_parameter(T_HTS_PARAM_TYPE param_type, uint8_t len, void *p_value)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ default:
+ {
+ ret = false;
+ PROFILE_PRINT_ERROR0("hts_set_parameter failed\n");
+ }
+ break;
+ case HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG:
+ {
+ memcpy(&hts_measurement.flag, p_value, 1);
+ }
+ break;
+ case HTS_PARAM_MEASUREMENT_TEMPERATUER_VALUE:
+ {
+ if (len != 4)
+ {
+ PROFILE_PRINT_ERROR0("hts_set_parameter Temperature value \n");
+ break;
+ }
+ if (hts_measurement.flag.temp_value_units_bit == 0)
+ {
+ memcpy(&hts_measurement.temp_celsius_value, p_value, len);
+ }
+ else
+ {
+ memcpy(&hts_measurement.temp_fahrenheit_value, p_value, len);
+ }
+ }
+ break;
+ case HTS_PARAM_MEASUREMENT_TIME_STAMP:
+ {
+ if (len != sizeof(T_TIME_STAMP))
+ {
+ PROFILE_PRINT_ERROR0("hts_set_parameter Temperature value \n");
+ break;
+ }
+ memcpy(&hts_measurement.time_stamp, p_value, len);
+ }
+ break;
+ case HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE:
+ {
+ hts_measurement.temper_next_desc = *(uint8_t *)p_value;
+ }
+ break;
+
+ case HTS_PARAM_MEASUREMENT_INTERVAL:
+ memcpy(&hts_measurement_interval, p_value, len);
+ break;
+
+ case HTS_PARAM_VALID_RANGE:
+ memcpy(&hts_measurement_interval_valid_range, p_value, len);
+ break;
+ }
+
+ return ret;
+}
+
+
+void hts_format_measurement_value()
+{
+ uint8_t cur_offset = 0;
+
+ memcpy(&hts_measurement_value_for_notify_indicate[cur_offset], &hts_measurement.flag, 1);
+ cur_offset += 1;
+
+ if (hts_measurement.flag.temp_value_units_bit == 0)
+ {
+ memcpy(&hts_measurement_value_for_notify_indicate[cur_offset], &hts_measurement.temp_celsius_value,
+ 4);
+ }
+ else
+ {
+ memcpy(&hts_measurement_value_for_notify_indicate[cur_offset],
+ &hts_measurement.temp_fahrenheit_value, 4);
+ }
+ cur_offset += 4;
+
+ if (hts_measurement.flag.temp_time_stamp_present_bit)
+ {
+ memcpy(&hts_measurement_value_for_notify_indicate[cur_offset], &hts_measurement.time_stamp, 7);
+ cur_offset += 7;
+ }
+
+ if (hts_measurement.flag.temp_type_present_bit)
+ {
+ memcpy(&hts_measurement_value_for_notify_indicate[cur_offset], &hts_measurement.temper_next_desc,
+ 1);
+ cur_offset += 1;
+ }
+
+ hts_measurement_value_actual_length = cur_offset;
+
+}
+
+/**
+ * @brief Send measurement value indication data .
+ * Application shall call @ref hts_set_parameter to set intermediate temperature value first,
+ * and the call this api to send the notication value.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ *
+ * @return service id @ref T_SERVER_ID.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t hts_flag = HTS_FLAG_MEASUREMENT_UINT_BIT | HTS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT |
+ HTS_FLAG_MEASUREMENT_TYPE_PRESENT_BIT;
+ T_HTS_TEMPERATURE_TYPE temperature_type = HTS_TEMPERATURE_TYPE_ARMPIT;
+
+ hts_measure_time_stamp.seconds += hts_measurement_interval;
+
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG, sizeof(hts_flag), &hts_flag);
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(hts_measure_time_stamp),
+ &hts_measure_time_stamp);
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE, 1, &temperature_type);
+
+ hts_measurement_value_indicate(p_parse_value->dw_param[0], hts_id);
+ }
+ * \endcode
+ */
+bool hts_measurement_value_indicate(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ hts_format_measurement_value();
+ return server_send_data(conn_id, service_id, HTS_TEMPERATURE_MEASUREMENT_INDEX,
+ (uint8_t *)&hts_measurement_value_for_notify_indicate, hts_measurement_value_actual_length,
+ GATT_PDU_TYPE_INDICATION);
+}
+
+/**
+ * @brief Send intermediate temperature notification data.
+ * Application shall call @ref hts_set_parameter to set intermediate temperature value first,
+ * and the call this api to send the notication value.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ *
+ * @return service id @ref T_SERVER_ID.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t hts_flag = HTS_FLAG_MEASUREMENT_UINT_BIT
+ | HTS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT
+ | HTS_FLAG_MEASUREMENT_TYPE_PRESENT_BIT;
+ T_HTS_TEMPERATURE_TYPE temperature_type = HTS_TEMPERATURE_TYPE_ARMPIT;
+
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG, sizeof(hts_flag), &hts_flag);
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(hts_measure_time_stamp),
+ &hts_measure_time_stamp);
+ hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE, 1, &temperature_type);
+
+ hts_intermediate_temperature_value_notify(p_parse_value->dw_param[0], hts_id);
+
+ return RESULT_SUCCESS;
+
+ }
+ * \endcode
+ */
+
+bool hts_intermediate_temperature_value_notify(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ hts_format_measurement_value();
+ return server_send_data(conn_id, service_id, HTS_INTERMEDIATE_TEMPERATURE_INDEX,
+ (uint8_t *)&hts_measurement_value_for_notify_indicate, hts_measurement_value_actual_length,
+ GATT_PDU_TYPE_NOTIFICATION);
+}
+
+/**
+ * @brief Send measurement interval notification data.
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] seconds Measurement interval.
+ *
+ * @return service id @ref T_SERVER_ID.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint16_t interval = 90;
+ hts_measurement_interval_notify(p_parse_value->dw_param[0], hts_id, interval);
+ }
+ * \endcode
+ */
+
+bool hts_measurement_interval_notify(uint8_t conn_id, T_SERVER_ID service_id, uint16_t seconds)
+{
+ return server_send_data(conn_id, service_id, HTS_MEASUREMENT_INTERVAL_INDEX, (uint8_t *)&seconds,
+ sizeof(seconds), GATT_PDU_TYPE_NOTIFICATION);
+}
+
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID of characteristic data.
+ * @param[in] attrib_index Attribute index of getting characteristic data.
+ * @param[in] offset Used for Blob Read.
+ * @param[in,out] p_length length of getting characteristic data.
+ * @param[in,out] pp_value data got from service.
+ * @return Profile procedure result
+*/
+T_APP_RESULT hts_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ *p_length = 0;
+ T_HTS_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+
+ if (HTS_MEASUREMENT_INTERVAL_INDEX == attrib_index)
+ {
+ callback_data.msg_data.read_value_index = HTS_READ_MEASUREMENT_INTERVAL_VALUE;
+ pfn_hts_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&hts_measurement_interval;
+ *p_length = sizeof(hts_measurement_interval);
+ }
+ else if (HTS_TEMPERATURE_TYPE_INDEX == attrib_index)
+ {
+ callback_data.msg_data.read_value_index = HTS_READ_TEMPERATURE_TYPE_VALUE;
+ pfn_hts_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&temperature_type;
+ *p_length = 1;
+ }
+ else if (HTS_MEASUREMENT_INTERVAL_VALID_RANGE_INDEX == attrib_index)
+ {
+ callback_data.msg_data.read_value_index = HTS_READ_VALID_RANGE_VALUE;
+ pfn_hts_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&hts_measurement_interval_valid_range;
+ *p_length = sizeof(hts_measurement_interval_valid_range);
+ }
+
+ else
+ {
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+
+ return cause;
+}
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID to be written.
+ * @param[in] attrib_index Attribute index of characteristic.
+ * @param[in] write_type Write type.
+ * @param[in] length length of value to be written.
+ * @param[in] p_value value to be written.
+ * @param[in] p_write_ind_post_proc value to be written.
+ * @return Profile procedure result
+*/
+T_APP_RESULT hts_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ PROFILE_PRINT_ERROR2("hts_attr_write_cb iAttribIndex = %d wLength %x", attrib_index, length);
+
+ switch (attrib_index)
+ {
+ case HTS_MEASUREMENT_INTERVAL_INDEX:
+ {
+ T_HTS_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.write_index = HTS_WRITE_MEASUREMENT_INTERVAL_VALUE;
+ memcpy(&callback_data.msg_data.write.measurement_interval, p_value, 2);
+ pfn_hts_cb(service_id, (void *)&callback_data);
+ }
+ break;
+
+ default:
+ {
+ PROFILE_PRINT_ERROR1("hts_attr_write_cb iAttribIndex = %d not found", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ break;
+ }
+
+ return cause;
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param[in] index Attribute index of characteristic data.
+ * @param[in] ccc_bits CCCD bits from stack.
+ * @return None
+*/
+void hts_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ T_HTS_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ bool handle = true;
+
+ PROFILE_PRINT_INFO2("HtsCccdUpdate Index = %d wCCCDBits %x", index, ccc_bits);
+
+ switch (index)
+ {
+ case HTS_TEMPERATURE_MEASUREMENT_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY_INDICATE)
+ {
+ // Enable Notification
+ callback_data.msg_data.notification_indification_index =
+ HTS_NOTIFY_INDICATE_TEMPERATURE_MEASUREMENT_VALUE_ENABLE;
+
+ }
+ else
+ {
+ callback_data.msg_data.notification_indification_index =
+ HTS_NOTIFY_INDICATE_TEMPERATURE_MEASUREMENT_VALUE_DISABLE;
+ }
+ }
+ break;
+ case HTS_INTERMEDIATE_TEMPERATURE_CCCD_INDEX:
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY_INDICATE)
+ {
+ // Enable Notification
+ callback_data.msg_data.notification_indification_index =
+ HTS_NOTIFY_INDICATE_INTERMEDIATE_TEMPERATURE_VALUE_ENABLE;
+
+ }
+ else
+ {
+ callback_data.msg_data.notification_indification_index =
+ HTS_NOTIFY_INDICATE_INTERMEDIATE_TEMPERATURE_VALUE_DISABLE;
+ }
+ break;
+ case HTS_MEASUREMENT_INTERVAL_CCCD_INDEX:
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY_INDICATE)
+ {
+ // Enable Notification
+ callback_data.msg_data.notification_indification_index =
+ HTS_NOTIFY_INDICATE_MEASUREMENT_INTERVAL_VALUE_ENABLE;
+
+ }
+ else
+ {
+ callback_data.msg_data.notification_indification_index =
+ HTS_NOTIFY_INDICATE_MEASUREMENT_INTERVAL_VALUE_DISABLE;
+ }
+ break;
+
+ default:
+ handle = false;
+ break;
+
+ }
+ /* Notify Application. */
+ if (pfn_hts_cb && (handle == true))
+ {
+ pfn_hts_cb(service_id, (void *)&callback_data);
+ }
+
+ return;
+}
+
+/**
+ * @brief HTS Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS hts_cbs =
+{
+ hts_attr_read_cb, // Read callback function pointer
+ hts_attr_write_cb, // Write callback function pointer
+ hts_cccd_update_cb // CCCD update callback function pointer
+};
+
+/**
+ * @brief Add health thermometer service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ hts_id = hts_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+
+T_SERVER_ID hts_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)hts_attr_tbl,
+ hts_attr_tbl_size,
+ hts_cbs))
+ {
+ PROFILE_PRINT_ERROR1("hts_add_service: service_id %d", service_id);
+ service_id = 0xff;
+ }
+ pfn_hts_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+
+}
+
+
diff --git a/src/ble/profile/server/ias.c b/src/ble/profile/server/ias.c
new file mode 100644
index 0000000..6ecfd99
--- /dev/null
+++ b/src/ble/profile/server/ias.c
@@ -0,0 +1,175 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ias.c
+* @brief immediate alert level service source file.
+* @details Interfaces to access immediate alert level service.
+* @author
+* @date
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#include "stdint.h"
+#include "string.h"
+#include "trace.h"
+#include "profile_server.h"
+#include "ias.h"
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+///@cond
+/** @brief IAS related services UUIDs */
+#define GATT_UUID_IMMEDIATE_ALERT_SERVICE 0x1802
+#define GATT_UUID_CHAR_ALERT_LEVEL 0x2A06
+
+/** @brief Index defines for Characteristic's value */
+#define GATT_SVC_PXP_IMMEDIATE_AlERT_VALUE_INDEX 2
+///@endcond
+
+static P_FUN_SERVER_GENERAL_CB pfn_ias_cb = NULL;
+
+/**< @brief profile/service definition. */
+const T_ATTRIB_APPL ias_attr_tbl[] =
+{
+ /*----------------- Immediate Alert Service -------------------*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_IMMEDIATE_ALERT_SERVICE), /* service UUID */
+ HI_WORD(GATT_UUID_IMMEDIATE_ALERT_SERVICE)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* Alert Level Characteristic */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* Alert Level Characteristic value */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_ALERT_LEVEL),
+ HI_WORD(GATT_UUID_CHAR_ALERT_LEVEL)
+ },
+ 0, /* variable size */
+ NULL,
+ GATT_PERM_WRITE | GATT_PERM_READ /* wPermissions */
+ }
+};
+/**< @brief IAS service size definition. */
+const int ias_attr_tbl_size = sizeof(ias_attr_tbl);
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID to be written.
+ * @param[in] attrib_index Attribute index of characteristic.
+ * @param[in] write_type Write type.
+ * @param[in] length Length of writing characteristic data.
+ * @param[in] p_value Pointer to characteristic data.
+ * @param[in] p_write_ind_post_proc Function pointer after ias_attr_write_cb.
+ * @return TProfileResult
+*/
+T_APP_RESULT ias_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ T_IAS_CALLBACK_DATA callback_data;
+ if (!p_value)
+ {
+ PROFILE_PRINT_ERROR2("ias_attr_write_cb: p_value %p length= 0x%x", p_value, length);
+ cause = APP_RESULT_INVALID_PDU;
+ return cause;
+ }
+
+ switch (attrib_index)
+ {
+ default:
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+
+ case GATT_SVC_PXP_IMMEDIATE_AlERT_VALUE_INDEX:
+ if (length != sizeof(uint8_t))
+ {
+ cause = APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ else
+ {
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write_alert_level = p_value[0];
+ }
+ break;
+ }
+ if (pfn_ias_cb && (cause == APP_RESULT_SUCCESS))
+ {
+ pfn_ias_cb(service_id, (void *)&callback_data);
+ }
+
+ return cause;
+}
+
+/*********************************************************************
+ * SERVICE CALLBACKS
+ */
+// IAS related Service Callbacks
+const T_FUN_GATT_SERVICE_CBS ias_cbs =
+{
+ NULL, // Read callback function pointer
+ ias_attr_write_cb, // Write callback function pointer
+ NULL // CCCD update callback function pointer
+};
+
+/**
+ * @brief Add immediate alert service to the BLE stack database.
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ ias_id = ias_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID ias_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)ias_attr_tbl,
+ ias_attr_tbl_size,
+ ias_cbs))
+ {
+ PROFILE_PRINT_ERROR1("ias_add_service: service_id %d", service_id);
+ service_id = 0xff;
+ }
+
+ pfn_ias_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
diff --git a/src/ble/profile/server/ipss.c b/src/ble/profile/server/ipss.c
new file mode 100644
index 0000000..f26358b
--- /dev/null
+++ b/src/ble/profile/server/ipss.c
@@ -0,0 +1,75 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ipss.c
+ * @brief Source file for using internet protocol support service.
+ * @details Global data and function implement.
+ * @author Jeff_Zheng
+ * @date 2017-12-05
+ * @version v1.0
+ * *************************************************************************************
+ */
+
+#include <string.h>
+#include "trace.h"
+#include "profile_server.h"
+#include "ipss.h"
+
+
+
+static const T_ATTRIB_APPL ipss_attr_tbl[] =
+{
+ /* <<Primary Service>> 0*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_IPSS), /* service UUID */
+ HI_WORD(GATT_UUID_IPSS)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ }
+
+};
+
+uint16_t ipss_attr_tbl_len = sizeof(ipss_attr_tbl);
+//static P_FUN_SERVER_GENERAL_CB p_fn_ipss_cb = NULL;
+
+const T_FUN_GATT_SERVICE_CBS ipss_cbs =
+{
+ NULL, // Read callback function pointer
+ NULL, // Write callback function pointer
+ NULL, // Authorization callback function pointer
+};
+
+/**
+ * @brief add ipss service to application.
+ *
+ * @param[in] p_func pointer of app callback function called by profile.
+ * @return service id auto generated by profile layer.
+ * @retval service id
+ */
+uint8_t ipss_add_service(void *p_func)
+{
+ uint8_t service_id;
+ if (false == server_add_service(&service_id, (uint8_t *)ipss_attr_tbl, ipss_attr_tbl_len, ipss_cbs))
+ {
+ service_id = SERVICE_PROFILE_GENERAL_ID;
+ }
+ else
+ {
+ //p_fn_ipss_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ }
+
+ PROFILE_PRINT_ERROR1("ipss_add_service: service_id %d", service_id);
+
+ return service_id;
+}
+
+
+
+
diff --git a/src/ble/profile/server/lls.c b/src/ble/profile/server/lls.c
new file mode 100644
index 0000000..1e04b4e
--- /dev/null
+++ b/src/ble/profile/server/lls.c
@@ -0,0 +1,255 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file lls.c
+* @brief link loss service source file.
+* @details Interfaces to access link loss service.
+* @author
+* @date
+* @version v1.0
+*********************************************************************************************************
+*/
+#include "stdint.h"
+#include "string.h"
+#include "trace.h"
+#include "profile_server.h"
+#include "lls.h"
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+///@cond
+/** @brief LLS profile related services UUIDs. */
+#define GATT_UUID_LINK_LOSS_SERVICE 0x1803
+#define GATT_UUID_CHAR_ALERT_LEVEL 0x2A06
+
+/** @brief LLS Attribute Index */
+#define GATT_SVC_PXP_LINK_LOSS_ALERT_LEVEL_INDEX 2
+///@endcond
+
+static P_FUN_SERVER_GENERAL_CB pfn_lls_cb = NULL;
+static uint8_t lls_alert_level = 0;
+
+/**< @brief profile/service definition. */
+const T_ATTRIB_APPL lls_attr_tbl[] =
+{
+ /*----------------- Link Loss Service -------------------*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_LINK_LOSS_SERVICE), /* service UUID */
+ HI_WORD(GATT_UUID_LINK_LOSS_SERVICE)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* Alert Level Characteristic */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* Alert Level Characteristic value */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_ALERT_LEVEL),
+ HI_WORD(GATT_UUID_CHAR_ALERT_LEVEL)
+ },
+ 0, /* variable size */
+ NULL,
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+ }
+};
+/**< @brief LLS service size definition. */
+const int lls_attr_tbl_size = sizeof(lls_attr_tbl);
+
+
+/**
+ * @brief Set a link loss service parameter.
+ *
+ * NOTE: You can call this function with a link loss service parameter type and it will set the
+ * link loss service parameter. Link loss service parameters are defined in @ref T_LLS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Link loss service parameter type: @ref T_LLS_PARAM_TYPE
+ * @param[in] length Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ */
+bool lls_set_parameter(T_LLS_PARAM_TYPE param_type, uint8_t length, void *p_value)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ default:
+ ret = false;
+ break;
+ case LLS_PARAM_LINK_LOSS_ALERT_LEVEL:
+ lls_alert_level = *(uint8_t *)p_value;
+ break;
+ }
+
+ if (!ret)
+ {
+ PROFILE_PRINT_ERROR0("lls_set_parameter: lls alert level parameter set failed");
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param conn_id connection id.
+ * @param service_id ServiceID to be read.
+ * @param attrib_index Attribute index of getting characteristic data.
+ * @param offset offset of characteritic to be read.
+ * @param p_length length of getting characteristic data.
+ * @param pp_value pointer to pointer of characteristic value to be read.
+ * @return T_APP_RESULT
+*/
+T_APP_RESULT lls_attr_read_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ *p_length = 0;
+ T_LLS_CALLBACK_DATA callback_data;
+
+ switch (attrib_index)
+ {
+ default:
+ PROFILE_PRINT_ERROR1("lls_attr_read_cb default:attrib_index %d", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+
+ case GATT_SVC_PXP_LINK_LOSS_ALERT_LEVEL_INDEX:
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = LLS_READ_ALERT_LEVEL;
+ pfn_lls_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&lls_alert_level;
+ *p_length = sizeof(lls_alert_level);
+ PROFILE_PRINT_INFO2("lls_attr_read_cb: attrib_index %d, length %d", attrib_index, *p_length);
+ break;
+ }
+
+ return (cause);
+}
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param conn_id connection id.
+ * @param service_id ServiceID to be written.
+ * @param attrib_index Attribute index of characteristic.
+ * @param length length of writing characteristic data.
+ * @param p_value pointer to characteristic data.
+ * @param p_write_ind_post_proc function pointer called after lls_attr_write_cb.
+ * @return T_APP_RESULT
+*/
+T_APP_RESULT lls_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ T_LLS_CALLBACK_DATA callback_data;
+ if (!p_value)
+ {
+ PROFILE_PRINT_ERROR2("lls_attr_write_cb: p_value %p, length 0x%x", p_value, length);
+ cause = APP_RESULT_INVALID_PDU;
+ return cause;
+ }
+
+ switch (attrib_index)
+ {
+ default:
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+ case GATT_SVC_PXP_LINK_LOSS_ALERT_LEVEL_INDEX:
+ if (length != sizeof(uint8_t))
+ {
+ cause = APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ else
+ {
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write_alert_level = p_value[0];
+ }
+ break;
+
+ }
+ if (pfn_lls_cb && (cause == APP_RESULT_SUCCESS))
+ {
+ pfn_lls_cb(service_id, (void *)&callback_data);
+ }
+
+ return cause;
+
+}
+
+
+// LLS related Service Callbacks
+const T_FUN_GATT_SERVICE_CBS lls_cbs =
+{
+ lls_attr_read_cb, // Read callback function pointer
+ lls_attr_write_cb, // Write callback function pointer
+ NULL // CCCD update callback function pointer
+};
+
+/**
+ * @brief Add link loss service to the BLE stack database.
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ lls_id = lls_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID lls_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)lls_attr_tbl,
+ lls_attr_tbl_size,
+ lls_cbs))
+ {
+ PROFILE_PRINT_ERROR1("lls_add_service: service_id %d", service_id);
+ service_id = 0xff;
+ }
+
+ pfn_lls_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
diff --git a/src/ble/profile/server/lns.c b/src/ble/profile/server/lns.c
new file mode 100644
index 0000000..e06b7cf
--- /dev/null
+++ b/src/ble/profile/server/lns.c
@@ -0,0 +1,1712 @@
+/*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file lns.c
+* @brief Location and Navigation Service source file.
+* @details Interfaces to access Location and Navigation Service.
+* @author
+* @date 2017-09-22
+* @version v0.1
+*********************************************************************************************************
+*/
+
+#include "stdint.h"
+#include "gatt.h"
+#include <string.h>
+#include "trace.h"
+#include "lns.h"
+
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+#define LNS_POSITION_QUALITY_CHAR_SUPPORT
+#define LNS_LN_CONTROL_POINT_CHAR_SUPPORT
+#define LNS_LN_NAVIGATION_CHAR_SUPPORT
+
+#define LNS_CP_PARA_NAME_OF_ROUTE_MAX_LEN 10
+
+#define LNS_LN_FEATURE_VALUE_INDEX 2//read
+#define LNS_LN_LOCATION_AND_SPEED_VALUE_INDEX 4//notify
+#define LNS_LN_POSITION_QUALITY_VALUE_INDEX 7//read
+#define LNS_LN_CP_VALUE_INDEX 9 //write, indicate
+#define LNS_LN_NAVIGATION_VALUE_INDEX 12//notify
+
+#define LNS_LN_LOCATION_AND_SPEED_CCCD_INDEX 5
+#define LNS_LN_CP_CCCD_INDEX 10
+#define LNS_LN_NAVIGATION_CCCD_INDEX 13
+
+#define GATT_UUID_SERVICE_LOCATION_AND_NAVIGATION 0x1819
+#define GATT_UUID_CHAR_LNS_LOCATION_AND_SPEED 0x2A67
+#define GATT_UUID_CHAR_LNS_NAVIGATION 0x2A68
+#define GATT_UUID_CHAR_LNS_POSITION_QUALITY 0x2A69
+#define GATT_UUID_CHAR_LNS_LN_FEATURE 0x2A6A
+#define GATT_UUID_CHAR_LNS_LN_CP 0x2A6B
+
+
+
+#define LN_CP_RSPCODE_RESERVED 0x00
+#define LN_CP_RSPCODE_SUCCESS 0x01
+#define LN_CP_RSPCODE_OPCODE_UNSUPPORT 0x02
+#define LN_CP_RSPCODE_INVALID_PARAMETER 0x03
+#define LN_CP_RSPCODE_OPERATION_FAILED 0x04
+
+
+#define LN_CTL_PNT_OPERATE_ACTIVE(x) \
+ ( (x == LN_CP_OPCODE_SET_CUMULATIVE_VALUE) || \
+ (x == LN_CP_OPCODE_MASK_LOCATION_AND_SPEED_CHAR_CONTENT) || \
+ (x == LN_CP_OPCODE_NAVIGATION_CONTROL) || \
+ (x == LN_CP_OPCODE_REQUEST_NUMBER_OF_ROUTES) || \
+ (x == LN_CP_OPCODE_REQUEST_NAME_OF_ROUTE) || \
+ (x == LN_CP_OPCODE_SELECT_ROUTE) || \
+ (x == LN_CP_OPCODE_SET_FIX_RATE) || \
+ (x == LN_CP_OPCODE_SET_ELEVATION) || \
+ (x == LN_CP_OPCODE_RESPONSE_CODE) )
+
+#define LNS_POSITION_AND_QUALITY_VALUE_MAX_LEN 16
+#define LNS_LOCATION_AND_SPEED_VALUE_MAX_LEN 28
+#define LNS_NAVIGATION_VALUE_MAX_LEN 19
+
+uint32_t lns_ln_feature_support = 0;
+
+T_LNS_NOTIFY_INDICATE_FLAG lns_notify_indicate_flag = {0};
+T_LNS_CONTROL_POINT lns_ctl_pnt = {0};
+
+T_POSITION_QUALITY_VALUE lns_position_quality_value = {0};
+uint8_t lns_pq_value_for_read_cfm[LNS_POSITION_AND_QUALITY_VALUE_MAX_LEN] = {0};
+uint8_t lns_pq_value_length_for_read_cfm = 0;
+
+LOCATION_AND_SPEED_VALUE lns_location_and_speed_value = {0};
+T_NAVIGATION_VALUE lns_navigation_value = {0};
+uint16_t lns_cp_number_of_route = 0;
+uint8_t lns_cp_name_of_route[LNS_CP_PARA_NAME_OF_ROUTE_MAX_LEN] = {0};
+uint8_t lns_cp_name_of_route_len = 0;
+
+/**< Function pointer used to send event to application from location and navigation profile. */
+
+static P_FUN_SERVER_GENERAL_CB pfn_lns_app_cb = NULL;
+
+
+/**< @brief profile/service definition. */
+static const T_ATTRIB_APPL lns_attr_tbl[] =
+{
+ /*----------------- Health Temperature Service -------------------*/
+ /* <<Primary Service>>, .. 0,*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_SERVICE_LOCATION_AND_NAVIGATION), /* service UUID */
+ HI_WORD(GATT_UUID_SERVICE_LOCATION_AND_NAVIGATION)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. 1, LN Feature*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* Temperature Measurement value 2,*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_LNS_LN_FEATURE),
+ HI_WORD(GATT_UUID_CHAR_LNS_LN_FEATURE)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic>>, ..Location and Speed */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_LNS_LOCATION_AND_SPEED),
+ HI_WORD(GATT_UUID_CHAR_LNS_LOCATION_AND_SPEED)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* client characteristic configuration */
+ {
+ ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ },
+
+#ifdef LNS_POSITION_QUALITY_CHAR_SUPPORT
+ /* <<Characteristic>>, .. Position Quality*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_LNS_POSITION_QUALITY),
+ HI_WORD(GATT_UUID_CHAR_LNS_POSITION_QUALITY)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+#endif
+
+#ifdef LNS_LN_CONTROL_POINT_CHAR_SUPPORT
+ /* <<Characteristic>>, .. LN Control Point*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_INDICATE) /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* Measurement Interval value*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_LNS_LN_CP),
+ HI_WORD(GATT_UUID_CHAR_LNS_LN_CP)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_WRITE/* wPermissions */
+ },
+ /* client characteristic configuration */
+ {
+ ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ },
+#endif
+
+#ifdef LNS_LN_NAVIGATION_CHAR_SUPPORT
+ /* <<Characteristic>>, .. Navigation*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY/* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_LNS_NAVIGATION),
+ HI_WORD(GATT_UUID_CHAR_LNS_NAVIGATION)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_NOTIF_IND_AUTHEN_REQ/* wPermissions */
+ },
+ /* client characteristic configuration */
+ {
+ ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ }
+#endif
+
+};
+
+/**< @brief Health Temperature service size definition. */
+const uint16_t lns_attr_tbl_size = sizeof(lns_attr_tbl);
+
+/**
+ * @brief Set a Location And Navigation service parameter.
+ *
+ * NOTE: You can call this function with a Location And Navigation service parameter type and it will set the
+ * Location And Navigation service parameter. Location And Navigation service parameters are defined
+ * in @ref T_LNS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Location And Navigation service parameter type: @ref T_LNS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ T_LOCATION_AND_SPEED_VALUE_FLAG flag;
+ flag.instantaneous_speed_present = 1;
+ flag.total_distance_present = 1;
+ flag.location_present = 1;
+ flag.elevation_present = 1;
+ flag.heading_present = 1;
+ flag.rolling_time_present = 1;
+ flag.utc_time_present = 1;
+ flag.position_status = 1;
+ flag.speed_and_distance_format = 1;
+ flag.elevation_source = 1;
+ flag.heading_source = 1;
+ flag.rfu = 0;
+
+ lns_set_parameter(LNS_LAS_PARAM_INC_FLAG, 2, &flag);
+ }
+ * \endcode
+ */
+bool lns_set_parameter(T_LNS_PARAM_TYPE param_type, uint8_t len, void *p_value)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ default:
+ {
+ ret = false;
+ PROFILE_PRINT_ERROR0("lns_set_parameter failed\n");
+ }
+ break;
+
+ case LNS_PARAM_LN_FEATURE_SUPPORT:
+ {
+ if (len != sizeof(uint32_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_ln_feature_support, p_value, len);
+ }
+ }
+ break;
+
+ //Location And Speed Value
+ case LNS_LAS_PARAM_INC_FLAG:
+ {
+ if (len != sizeof(uint16_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_location_and_speed_value.flag, p_value, len);
+ }
+ }
+ break;
+
+ case LNS_LAS_PARAM_INSTANTANEOUS_SPEED:
+ {
+ if (len != sizeof(uint16_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_location_and_speed_value.instantaneous_speed, p_value, len);
+
+ }
+ }
+ break;
+
+ case LNS_LAS_PARAM_TOTAL_DISTANCE:
+ {
+ if (len != 3)
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_location_and_speed_value.total_distance, p_value, len);
+
+ }
+ }
+ break;
+
+ case LNS_LAS_PARAM_LOCATION_LATITUDE:
+ {
+ if (len != 3)
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_location_and_speed_value.location_latitude, p_value, len);
+
+ }
+ }
+ break;
+
+ case LNS_LAS_PARAM_LOCATION_LONGITUDE:
+ {
+ if (len != 3)
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_location_and_speed_value.location_latitude, p_value, len);
+
+ }
+ }
+ break;
+
+ case LNS_LAS_PARAM_ELEVATION:
+ {
+ if (len != 3)
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_location_and_speed_value.elevation, p_value, len);
+
+ }
+ }
+ break;
+
+ case LNS_LAS_PARAM_HEADING:
+ {
+ if (len != sizeof(uint16_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_location_and_speed_value.heading, p_value, len);
+
+ }
+ }
+ break;
+
+ case LNS_LAS_PARAM_ROLLING_TIME:
+ {
+ if (len != sizeof(uint8_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_location_and_speed_value.rolling_time, p_value, len);
+
+ }
+ }
+ break;
+
+ case LNS_LAS_PARAM_UTC_TIME:
+ {
+ if (len != 7)
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_location_and_speed_value.utc_time, p_value, len);
+
+ }
+ }
+ break;
+
+ case LNS_LAS_PARAM_POSITION_STATUS:
+ {
+ lns_location_and_speed_value.flag.position_status = *(uint8_t *)p_value;
+ }
+ break;
+
+ case LNS_LAS_PARAM_SPEED_AND_DISTANCE_FORMAT:
+ {
+ lns_location_and_speed_value.flag.speed_and_distance_format = *(uint8_t *)p_value;
+ }
+ break;
+
+ case LNS_LAS_PARAM_ELEVATION_SOURCE:
+ {
+ lns_location_and_speed_value.flag.elevation_source = *(uint8_t *)p_value;
+ }
+ break;
+
+ case LNS_LAS_PARAM_HEADING_SOURCE:
+ {
+ lns_location_and_speed_value.flag.heading_source = *(uint8_t *)p_value;
+ }
+ break;
+
+ //Navigation value
+ case LNS_NAVIGATION_PARAM_INC_FLAG:
+ {
+ if (len != sizeof(uint16_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_navigation_value.flag, p_value, len);
+ }
+ }
+ break;
+
+ case LNS_NAVIGATION_PARAM_BEARING:
+ {
+ if (len != sizeof(uint16_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_navigation_value.bearing, p_value, len);
+
+ }
+ }
+ break;
+
+ case LNS_NAVIGATION_PARAM_HEADING:
+ {
+ if (len != sizeof(uint16_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_navigation_value.bearing, p_value, len);
+
+ }
+ }
+ break;
+
+ case LNS_NAVIGATION_PARAM_REMAINING_DISTANCE:
+ {
+ if (len != 3)
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_navigation_value.reamining_distance, p_value, len);
+
+ }
+ }
+ break;
+
+ case LNS_NAVIGATION_PARAM_REMAINING_VERTICAL_DISTANCE:
+ {
+ if (len != 3)
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_navigation_value.reamining_vertical_distance, p_value, len);
+
+ }
+ }
+ break;
+
+ case LNS_NAVIGATION_PARAM_ESTIMATED_TIME_OF_ARRIVAL:
+ {
+ if (len != 7)
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_navigation_value.estimated_time_of_arrival, p_value, len);
+
+ }
+ }
+ break;
+
+ case LNS_NAVIGATION_PARAM_POSITION_STATUS:
+ {
+ lns_navigation_value.flag.position_status = *(uint8_t *)p_value;
+ }
+ break;
+ case LNS_NAVIGATION_PARAM_HEADING_SOURCE:
+ {
+ lns_navigation_value.flag.heading_source = *(uint8_t *)p_value;
+ }
+ break;
+
+ case LNS_NAVIGATION_PARAM_NAVIGATION_INDICATOR_TYPE:
+ {
+ lns_navigation_value.flag.navigation_indicator_type = *(uint8_t *)p_value;
+ }
+ break;
+
+ case LNS_NAVIGATION_PARAM_WAYPOINT_REACHED:
+ {
+ lns_navigation_value.flag.waypoint_reached = *(uint8_t *)p_value;
+ }
+ break;
+
+ case LNS_NAVIGATION_PARAM_DESTINATION_REACHED:
+ {
+ lns_navigation_value.flag.destination_reached = *(uint8_t *)p_value;
+ }
+ break;
+
+ case LNS_PQ_PARAM_INC_FLAG:
+ {
+ if (len != sizeof(uint16_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_position_quality_value.flag, p_value, len);
+ }
+ }
+ break;
+
+ case LNS_PQ_PARAM_NUMBER_OF_BEACONS_IN_SOLUTION:
+ {
+ if (len != sizeof(uint8_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_position_quality_value.number_of_beacons_in_solution, p_value, len);
+ }
+ }
+ break;
+
+ case LNS_PQ_PARAM_NUMBER_OF_BEACONS_IN_VIEW:
+ {
+ if (len != sizeof(uint8_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_position_quality_value.number_of_beacons_in_view, p_value, len);
+ }
+ }
+ break;
+
+
+ case LNS_PQ_PARAM_TIME_TO_FIRST_FIX:
+ {
+ if (len != sizeof(uint16_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_position_quality_value.time_to_first_fix, p_value, len);
+ }
+ }
+ break;
+
+ case LNS_PQ_PARAM_EHPE:
+ {
+ if (len != sizeof(uint32_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_position_quality_value.ehpe, p_value, len);
+ }
+ }
+ break;
+
+ case LNS_PQ_PARAM_EVPE:
+ {
+ if (len != sizeof(uint32_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_position_quality_value.evpe, p_value, len);
+ }
+ }
+ break;
+ case LNS_PQ_PARAM_HDOP:
+ {
+ if (len != sizeof(uint8_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_position_quality_value.hdop, p_value, len);
+ }
+ }
+ break;
+
+ case LNS_PQ_PARAM_VDOP:
+ {
+ if (len != sizeof(uint8_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_position_quality_value.vdop, p_value, len);
+ }
+ }
+ break;
+
+ case LNS_CP_PARA_NUMBER_OF_ROUTE:
+ {
+ if (len != sizeof(uint16_t))
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_cp_number_of_route, p_value, len);
+ }
+ }
+ break;
+
+ case LNS_CP_PARA_NAME_OF_ROUTE:
+ {
+ if (len > LNS_CP_PARA_NAME_OF_ROUTE_MAX_LEN)
+ {
+ ret = false;
+ }
+ else
+ {
+ memcpy(&lns_cp_name_of_route, p_value, len);
+ lns_cp_name_of_route_len = len;
+ }
+ }
+ break;
+ case LNS_PARAM_CTL_PNT_PROG_CLR:
+ {
+ if (len != 0)
+ {
+ ret = false;
+ }
+ else
+ {
+ lns_ctl_pnt.value[0] = LN_CP_OPCODE_RESERVED;
+ }
+ }
+ break;
+
+ }
+
+ return ret;
+}
+
+void lns_format_pq_value_for_read()
+{
+ uint8_t cur_offset = 0;
+
+ memcpy(&lns_pq_value_for_read_cfm[cur_offset], &lns_position_quality_value.flag, 2);
+ cur_offset += 2;
+
+ if (lns_position_quality_value.flag.number_of_beacons_in_solution_present)
+ {
+ memcpy(&lns_pq_value_for_read_cfm[cur_offset],
+ &lns_position_quality_value.number_of_beacons_in_solution, 1);
+ cur_offset += 1;
+ }
+
+ if (lns_position_quality_value.flag.number_of_beacons_in_view_present)
+ {
+ memcpy(&lns_pq_value_for_read_cfm[cur_offset],
+ &lns_position_quality_value.number_of_beacons_in_view, 1);
+ cur_offset += 1;
+ }
+
+ if (lns_position_quality_value.flag.time_to_first_fix_present)
+ {
+ memcpy(&lns_pq_value_for_read_cfm[cur_offset], &lns_position_quality_value.time_to_first_fix, 2);
+ cur_offset += 2;
+ }
+
+ if (lns_position_quality_value.flag.ehpe_present)
+ {
+ memcpy(&lns_pq_value_for_read_cfm[cur_offset], &lns_position_quality_value.ehpe, 4);
+ cur_offset += 4;
+ }
+
+ if (lns_position_quality_value.flag.evpe_present)
+ {
+ memcpy(&lns_pq_value_for_read_cfm[cur_offset], &lns_position_quality_value.evpe, 4);
+ cur_offset += 4;
+ }
+
+ if (lns_position_quality_value.flag.hdop_present)
+ {
+ memcpy(&lns_pq_value_for_read_cfm[cur_offset], &lns_position_quality_value.hdop, 1);
+ cur_offset += 1;
+ }
+
+ if (lns_position_quality_value.flag.vdop_present)
+ {
+ memcpy(&lns_pq_value_for_read_cfm[cur_offset],
+ &lns_position_quality_value.vdop, 1);
+ cur_offset += 1;
+ }
+
+ lns_pq_value_length_for_read_cfm = cur_offset;
+
+}
+
+uint8_t lns_get_fisrt_value_offset_to_notify()
+{
+
+ uint8_t cur_offset = 2;
+
+ if (lns_location_and_speed_value.flag.instantaneous_speed_present)
+ {
+ cur_offset += 2;
+ }
+
+ if (lns_location_and_speed_value.flag.total_distance_present)
+ {
+ cur_offset += 3;
+ }
+
+ if (lns_location_and_speed_value.flag.location_present)
+ {
+ cur_offset += 4;
+ cur_offset += 4;
+ }
+
+ if (lns_location_and_speed_value.flag.elevation_present)
+ {
+ cur_offset += 3;
+ }
+
+ if (lns_location_and_speed_value.flag.heading_present)
+ {
+ cur_offset += 2;
+ }
+
+
+ if (lns_location_and_speed_value.flag.rolling_time_present)
+ {
+ cur_offset += 1;
+ }
+
+ if (cur_offset > 20)
+ {
+ return cur_offset - 1;
+ }
+
+
+ if (lns_location_and_speed_value.flag.utc_time_present)
+ {
+ cur_offset += 7;
+ }
+
+ if (cur_offset > 20)
+ {
+ return cur_offset - 7;
+ }
+
+ return cur_offset;
+
+}
+
+/**
+ * @brief Send location and speed value notification data.
+ * Application shall call @ref lns_set_parameter to set location and speed value first,
+ * and the call this api to send the notication value.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ *
+ * @return service id @ref T_SERVER_ID.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ bool op_result;
+ T_LOCATION_AND_SPEED_VALUE_FLAG flag;
+ flag.instantaneous_speed_present = 1;
+ flag.total_distance_present = 1;
+ flag.location_present = 1;
+ flag.elevation_present = 1;
+ flag.heading_present = 1;
+ flag.rolling_time_present = 1;
+ flag.utc_time_present = 1;
+ flag.position_status = 1;
+ flag.speed_and_distance_format = 1;
+ flag.elevation_source = 1;
+ flag.heading_source = 1;
+ flag.rfu = 0;
+
+ lns_set_parameter(LNS_LAS_PARAM_INC_FLAG, 2, &flag);
+
+ op_result = lns_location_and_speed_value_notify(p_parse_value->dw_param[0], lns_id);
+ }
+ * \endcode
+ */
+bool lns_location_and_speed_value_notify(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ bool ret = true;
+
+ T_LOCATION_AND_SPEED_VALUE_FLAG flag = {0};
+ uint8_t location_and_speed_value[20];
+
+
+ uint8_t cur_offset = 2;
+ uint8_t first_notify_value_offset = lns_get_fisrt_value_offset_to_notify();
+
+ if (lns_location_and_speed_value.flag.instantaneous_speed_present)
+ {
+ flag.instantaneous_speed_present = 1;
+ memcpy(&location_and_speed_value[cur_offset], &lns_location_and_speed_value.instantaneous_speed, 2);
+ cur_offset += 2;
+ }
+
+ if (lns_location_and_speed_value.flag.total_distance_present)
+ {
+ flag.total_distance_present = 1;
+ memcpy(&location_and_speed_value[cur_offset], &lns_location_and_speed_value.total_distance, 3);
+ cur_offset += 3;
+ }
+
+ if (lns_location_and_speed_value.flag.location_present)
+ {
+ flag.location_present = 1;
+ memcpy(&location_and_speed_value[cur_offset], &lns_location_and_speed_value.location_latitude, 4);
+ cur_offset += 4;
+ memcpy(&location_and_speed_value[cur_offset], &lns_location_and_speed_value.location_longitude, 4);
+ cur_offset += 4;
+ }
+
+ if (lns_location_and_speed_value.flag.elevation_present)
+ {
+ flag.elevation_present = 1;
+ memcpy(&location_and_speed_value[cur_offset], &lns_location_and_speed_value.elevation, 3);
+ cur_offset += 3;
+ }
+
+ if (lns_location_and_speed_value.flag.heading_present)
+ {
+ flag.heading_present = 1;
+ memcpy(&location_and_speed_value[cur_offset],
+ &lns_location_and_speed_value.heading, 2);
+ cur_offset += 2;
+ }
+
+ if (cur_offset == first_notify_value_offset)
+ {
+ //copy flag
+ memcpy(&location_and_speed_value[0], &flag, 2);
+ //send first notification here
+ server_send_data(conn_id, service_id, LNS_LN_LOCATION_AND_SPEED_VALUE_INDEX,
+ location_and_speed_value, cur_offset, GATT_PDU_TYPE_NOTIFICATION);
+
+ //send remain data
+ memset(&flag, 0, 2);
+ cur_offset = 2;
+ if (lns_location_and_speed_value.flag.rolling_time_present)
+ {
+ memcpy(&location_and_speed_value[cur_offset],
+ &lns_location_and_speed_value.rolling_time, 1);
+ flag.rolling_time_present = 1;
+ cur_offset += 1;
+ }
+
+ if (lns_location_and_speed_value.flag.utc_time_present)
+ {
+
+ memcpy(&location_and_speed_value[cur_offset],
+ &lns_location_and_speed_value.utc_time, 7);
+ flag.utc_time_present = 1;
+ cur_offset += 7;
+ }
+ memcpy(&location_and_speed_value[0], &flag, 2);
+ //send second notification
+ server_send_data(conn_id, service_id, LNS_LN_LOCATION_AND_SPEED_VALUE_INDEX,
+ location_and_speed_value, cur_offset, GATT_PDU_TYPE_NOTIFICATION);
+
+ return ret;
+ }
+
+ if (lns_location_and_speed_value.flag.rolling_time_present)
+ {
+ flag.rolling_time_present = 1;
+ memcpy(&location_and_speed_value[cur_offset],
+ &lns_location_and_speed_value.rolling_time, 1);
+ cur_offset += 1;
+ }
+
+ if (cur_offset == first_notify_value_offset)
+ {
+ //copy flag
+ memcpy(&location_and_speed_value[0], &flag, 2);
+ //send first notification here
+ server_send_data(conn_id, service_id, LNS_LN_LOCATION_AND_SPEED_VALUE_INDEX,
+ location_and_speed_value, cur_offset, GATT_PDU_TYPE_NOTIFICATION);
+
+
+ //send remain data
+ memset(&flag, 0, 2);
+ cur_offset = 2;
+ if (lns_location_and_speed_value.flag.utc_time_present)
+ {
+ memcpy(&location_and_speed_value[cur_offset],
+ &lns_location_and_speed_value.utc_time, 7);
+ flag.utc_time_present = 1;
+ cur_offset += 7;
+ }
+ memcpy(&location_and_speed_value[0], &lns_location_and_speed_value.flag, 2);
+ //send second notification
+ server_send_data(conn_id, service_id, LNS_LN_LOCATION_AND_SPEED_VALUE_INDEX,
+ location_and_speed_value, cur_offset, GATT_PDU_TYPE_NOTIFICATION);
+
+ return ret;
+ }
+
+ if (lns_location_and_speed_value.flag.utc_time_present)
+ {
+ if (cur_offset <= 13)
+ {
+ memcpy(&location_and_speed_value[cur_offset],
+ &lns_location_and_speed_value.utc_time, 7);
+ flag.utc_time_present = 1;
+ cur_offset += 7;
+ }
+ else if ((cur_offset > 13) && (cur_offset <= 19))
+ {
+ memcpy(&location_and_speed_value[cur_offset],
+ &lns_location_and_speed_value.utc_time, (20 - cur_offset));
+ flag.utc_time_present = 1;
+ cur_offset = 20;
+ }
+ }
+ memcpy(&location_and_speed_value[0], &lns_location_and_speed_value.flag, 2);
+ //send nortification
+ server_send_data(conn_id, service_id, LNS_LN_LOCATION_AND_SPEED_VALUE_INDEX,
+ location_and_speed_value, cur_offset, GATT_PDU_TYPE_NOTIFICATION);
+
+ return ret;
+}
+
+/**
+ * @brief Send navigation value notification data.
+ * Application shall call @ref lns_set_parameter to set navigation value first,
+ * and the call this api to send the notication value.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ *
+ * @return service id @ref T_SERVER_ID.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ bool op_result;
+
+ T_NAVIGATION_VALUE_FLAG flag;
+ flag.remaining_distance_present = 1;
+ flag.remaining_vertical_distance_present = 1;
+ flag.estimated_time_of_arrival_present = 1;
+ flag.position_status = 1;
+ flag.heading_source = 1;
+ flag.navigation_indicator_type = 1;
+ flag.waypoint_reached = 1;
+ flag.destination_reached = 1;
+ flag.rfus = 0;
+
+ lns_set_parameter(LNS_NAVIGATION_PARAM_INC_FLAG, 2, &flag);
+
+ op_result = lns_navigation_value_notify(p_parse_value->dw_param[0], lns_id);
+
+ }
+ * \endcode
+ */
+bool lns_navigation_value_notify(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ uint8_t navigation_value[LNS_NAVIGATION_VALUE_MAX_LEN];
+ uint8_t iCurOffset = 0;
+
+ memcpy(&navigation_value[iCurOffset], &lns_navigation_value.flag, 2);
+ iCurOffset += 2;
+ memcpy(&navigation_value[iCurOffset], &lns_navigation_value.bearing, 2);
+ iCurOffset += 2;
+ memcpy(&navigation_value[iCurOffset], &lns_navigation_value.heading, 2);
+ iCurOffset += 2;
+
+ if (lns_navigation_value.flag.remaining_distance_present)
+ {
+ memcpy(&navigation_value[iCurOffset], &lns_navigation_value.reamining_distance, 3);
+ iCurOffset += 3;
+ }
+
+ if (lns_navigation_value.flag.remaining_vertical_distance_present)
+ {
+ memcpy(&navigation_value[iCurOffset], &lns_navigation_value.reamining_vertical_distance, 3);
+ iCurOffset += 3;
+ }
+
+ if (lns_navigation_value.flag.estimated_time_of_arrival_present)
+ {
+ memcpy(&navigation_value[iCurOffset], &lns_navigation_value.estimated_time_of_arrival, 7);
+ iCurOffset += 7;
+ }
+
+ PROFILE_PRINT_INFO0("lns_navigation_value_notify");
+ return server_send_data(conn_id, service_id, LNS_LN_NAVIGATION_VALUE_INDEX, navigation_value,
+ iCurOffset, GATT_PDU_TYPE_NOTIFICATION);
+}
+
+bool lns_ln_ctl_pnt_value_indicate(uint8_t conn_id, T_SERVER_ID service_id, uint8_t op_code,
+ uint8_t rsp_code,
+ uint8_t *p_parameter, uint8_t para_len)
+{
+ uint16_t attrib_index = LNS_LN_CP_VALUE_INDEX;
+
+ uint8_t *p_data;
+ uint16_t data_len;
+
+ lns_ctl_pnt.value[0] = LN_CP_OPCODE_RESPONSE_CODE;
+ lns_ctl_pnt.value[1] = op_code; /* Control Point request opcode. */
+ lns_ctl_pnt.value[2] = rsp_code;
+
+ if (p_parameter != NULL && para_len != 0)
+ {
+ memcpy(&lns_ctl_pnt.value[3], p_parameter, para_len);
+ }
+
+ lns_ctl_pnt.cur_length = 3 * sizeof(uint8_t) + para_len;
+
+
+ p_data = lns_ctl_pnt.value;
+ data_len = lns_ctl_pnt.cur_length;
+
+ // send indication to client
+ return server_send_data(conn_id, service_id, attrib_index, p_data, data_len,
+ GATT_PDU_TYPE_INDICATION);
+}
+
+
+
+
+static void lns_ctl_pnt_set_cumulative_value(uint8_t conn_id, T_SERVER_ID service_id,
+ uint8_t rsp_code)
+{
+ uint8_t op_code = LN_CP_OPCODE_SET_CUMULATIVE_VALUE;
+ lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, NULL, 0);
+}
+
+static void lns_ctl_pnt_mask_location_speed_char_content(uint8_t conn_id, T_SERVER_ID service_id,
+ uint8_t rsp_code)
+{
+ uint8_t op_code = LN_CP_OPCODE_MASK_LOCATION_AND_SPEED_CHAR_CONTENT;
+ lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, NULL, 0);
+}
+
+static void lns_ctl_pnt_navigation_control(uint8_t conn_id, T_SERVER_ID service_id,
+ uint8_t rsp_code)
+{
+ uint8_t op_code = LN_CP_OPCODE_NAVIGATION_CONTROL;
+ lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, NULL, 0);
+}
+
+static void lns_ctl_pnt_request_number_of_routes(uint8_t conn_id, T_SERVER_ID service_id,
+ uint8_t rsp_code, uint16_t number_of_route)
+{
+ uint8_t op_code = LN_CP_OPCODE_REQUEST_NUMBER_OF_ROUTES;
+ lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, (uint8_t *)&number_of_route,
+ 2);
+}
+
+static void lns_ctl_pnt_request_name_of_route(uint8_t conn_id, T_SERVER_ID service_id,
+ uint8_t rsp_code, uint8_t *pNameOfRoute, uint8_t len)
+{
+ uint8_t op_code = LN_CP_OPCODE_REQUEST_NAME_OF_ROUTE;
+ lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, pNameOfRoute, len);
+}
+
+static void lns_ctl_pnt_select_route(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code)
+{
+ uint8_t op_code = LN_CP_OPCODE_SELECT_ROUTE;
+ lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, NULL, 0);
+}
+
+static void lns_ctl_pnt_set_fix_rate(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code)
+{
+ uint8_t op_code = LN_CP_OPCODE_SET_FIX_RATE;
+ lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, NULL, 0);
+}
+
+static void lns_ctl_pnt_set_elevation(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code)
+{
+ uint8_t op_code = LN_CP_OPCODE_SET_ELEVATION;
+ lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, NULL, 0);
+}
+
+static uint8_t lns_handle_ctl_pnt_proc_2(uint8_t service_id, uint16_t write_length,
+ uint8_t *value_ptr)
+{
+ T_LNS_CALLBACK_DATA callback_data;
+ uint8_t resp_code = LN_CP_RSPCODE_SUCCESS;
+ uint16_t parameter_length = 0;
+ memcpy(lns_ctl_pnt.value, value_ptr, write_length);
+ if (write_length >= 1)
+ {
+ parameter_length = write_length - 1;
+ }
+
+ PROFILE_PRINT_INFO1("lns_handle_ctl_pnt_proc request: OpCode=0x%x", lns_ctl_pnt.value[0]);
+
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.opcode = (T_LN_CP_OPCODE)lns_ctl_pnt.value[0];
+
+ switch (lns_ctl_pnt.value[0])
+ {
+ case LN_CP_OPCODE_NAVIGATION_CONTROL:
+ {
+ if (parameter_length == 1)
+ {
+ memcpy(&callback_data.msg_data.write.cp_parameter.navigation_control,
+ &lns_ctl_pnt.value[1], 1);
+ }
+ else
+ {
+ resp_code = LN_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+
+ break;
+
+ case LN_CP_OPCODE_SET_CUMULATIVE_VALUE:
+ {
+ if (parameter_length == 3)
+ {
+ memcpy(&callback_data.msg_data.write.cp_parameter.cumulative_total_distance,
+ &lns_ctl_pnt.value[1], 3);
+ }
+ else
+ {
+ resp_code = LN_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+ break;
+
+ case LN_CP_OPCODE_MASK_LOCATION_AND_SPEED_CHAR_CONTENT:
+ {
+ if (parameter_length == 2)
+ {
+ memcpy(&callback_data.msg_data.write.cp_parameter.mask_location_and_speed,
+ &lns_ctl_pnt.value[1], 2);
+ }
+ else
+ {
+ resp_code = LN_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+ break;
+
+ case LN_CP_OPCODE_REQUEST_NUMBER_OF_ROUTES:
+ {
+ //no parameter
+ }
+ break;
+ case LN_CP_OPCODE_REQUEST_NAME_OF_ROUTE:
+ {
+ if (parameter_length == 2)
+ {
+ memcpy(&callback_data.msg_data.write.cp_parameter.number_of_desired_route,
+ &lns_ctl_pnt.value[1], 1);
+ }
+ else
+ {
+ resp_code = LN_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+ break;
+
+ case LN_CP_OPCODE_SELECT_ROUTE:
+ {
+ if (parameter_length == 2)
+ {
+ memcpy(&callback_data.msg_data.write.cp_parameter.select_route_desired_route_number,
+ &lns_ctl_pnt.value[1], 2);
+ }
+ else
+ {
+ resp_code = LN_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+ break;
+
+ case LN_CP_OPCODE_SET_FIX_RATE:
+ {
+ if (parameter_length == 1)
+ {
+ memcpy(&callback_data.msg_data.write.cp_parameter.set_fix_rate,
+ &lns_ctl_pnt.value[1], 1);
+ }
+ else
+ {
+ resp_code = LN_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+ break;
+
+ case LN_CP_OPCODE_SET_ELEVATION:
+ {
+ if (parameter_length == 3)
+ {
+ memcpy(&callback_data.msg_data.write.cp_parameter.set_elevation,
+ &lns_ctl_pnt.value[1], 3);
+ }
+ else
+ {
+ resp_code = LN_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+ break;
+
+ default:
+ {
+ resp_code = LN_CP_RSPCODE_OPCODE_UNSUPPORT;
+ }
+ break;
+ }
+
+ if (resp_code == LN_CP_RSPCODE_SUCCESS)
+ {
+ pfn_lns_app_cb(service_id, (void *)&callback_data);
+ }
+ return resp_code;
+}
+
+/**
+ * @brief handle control point write (request).
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] write_length write request data length.
+ * @param[in] value_ptr pointer to write request data.
+ * @return none
+ * @retval void
+*/
+static T_APP_RESULT lns_handle_ctl_pnt_proc(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t write_length, uint8_t *p_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ memcpy(lns_ctl_pnt.value, p_value, write_length);
+
+ PROFILE_PRINT_INFO1("lns_handle_ctl_pnt_proc request: op_code=0x%x", lns_ctl_pnt.value[0]);
+
+ switch (lns_ctl_pnt.value[0])
+ {
+ case LN_CP_OPCODE_NAVIGATION_CONTROL:
+ {
+ if (!lns_notify_indicate_flag.navigation_enable)
+ {
+ cause = APP_RESULT_CCCD_IMPROPERLY_CONFIGURED;
+ }
+ }
+ break;
+
+ default:
+ {
+ }
+ break;
+ }
+ return cause;
+}
+
+static void lns_ctl_pnt_write_ind_post_proc(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index, uint16_t write_length, uint8_t *p_value)
+{
+ uint8_t resp_code = LN_CP_RSPCODE_SUCCESS;
+
+ bool error = false;
+ memcpy(lns_ctl_pnt.value, p_value, write_length);
+ lns_ctl_pnt.cur_length = write_length;
+
+ PROFILE_PRINT_INFO1("lns_ctl_pnt_write_ind_post_proc: OpCode=0x%x", lns_ctl_pnt.value[0]);
+
+ resp_code = lns_handle_ctl_pnt_proc_2(service_id, write_length, p_value);
+
+ switch (lns_ctl_pnt.value[0])
+ {
+ default:
+ {
+ error = true;
+ }
+ break;
+
+ case LN_CP_OPCODE_SET_CUMULATIVE_VALUE:
+ {
+ lns_ctl_pnt_set_cumulative_value(conn_id, service_id, resp_code);
+ }
+ break;
+
+ case LN_CP_OPCODE_MASK_LOCATION_AND_SPEED_CHAR_CONTENT:
+ {
+ lns_ctl_pnt_mask_location_speed_char_content(conn_id, service_id, resp_code);
+ }
+ break;
+
+ case LN_CP_OPCODE_NAVIGATION_CONTROL:
+ {
+ lns_ctl_pnt_navigation_control(conn_id, service_id, resp_code);
+ }
+ break;
+
+ case LN_CP_OPCODE_REQUEST_NUMBER_OF_ROUTES:
+ {
+ lns_ctl_pnt_request_number_of_routes(conn_id, service_id, resp_code, lns_cp_number_of_route);
+ }
+ break;
+ case LN_CP_OPCODE_REQUEST_NAME_OF_ROUTE:
+ {
+ lns_ctl_pnt_request_name_of_route(conn_id, service_id, resp_code, lns_cp_name_of_route,
+ lns_cp_name_of_route_len);
+ }
+ break;
+
+ case LN_CP_OPCODE_SELECT_ROUTE:
+ {
+ lns_ctl_pnt_select_route(conn_id, service_id, resp_code);
+ }
+ break;
+
+ case LN_CP_OPCODE_SET_FIX_RATE:
+ {
+ lns_ctl_pnt_set_fix_rate(conn_id, service_id, resp_code);
+ }
+ break;
+
+ case LN_CP_OPCODE_SET_ELEVATION:
+ {
+ lns_ctl_pnt_set_elevation(conn_id, service_id, resp_code);
+ }
+ break;
+ }
+
+ if (error)
+ {
+ lns_ln_ctl_pnt_value_indicate(conn_id, service_id, lns_ctl_pnt.value[0],
+ LN_CP_RSPCODE_OPCODE_UNSUPPORT, NULL, 0);
+ }
+
+}
+
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] attrib_index Attribute index of getting characteristic data.
+ * @param[in] offset Used for Blob Read.
+ * @param[in] p_length length of getting characteristic data.
+ * @param[in] pp_value data got from service.
+ * @return Profile procedure result
+*/
+T_APP_RESULT lns_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+
+ PROFILE_PRINT_INFO2("lns_attr_read_cb iAttribIndex = %d iOffset %x", attrib_index, offset);
+
+ *p_length = 0;
+ lns_ctl_pnt.value[0] = LN_CP_OPCODE_RESERVED;//////
+
+ switch (attrib_index)
+ {
+ case LNS_LN_FEATURE_VALUE_INDEX:
+ {
+ *p_length = sizeof(lns_ln_feature_support);
+ *pp_value = (uint8_t *)&lns_ln_feature_support;
+ }
+ break;
+
+ case LNS_LN_POSITION_QUALITY_VALUE_INDEX:
+ {
+ T_LNS_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = LNS_READ_POSITION_QUALITY_VALUE;
+ pfn_lns_app_cb(service_id, (void *)&callback_data);
+ //after app call lns_set_parameter to set Position Quality Value, profile will response this value to remote device
+ lns_format_pq_value_for_read();
+ *p_length = lns_pq_value_length_for_read_cfm;
+ *pp_value = lns_pq_value_for_read_cfm;
+ }
+ break;
+
+ default:
+ {
+ PROFILE_PRINT_ERROR1("lns_attr_read_cb iAttribIndex = %d not found", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ break;
+ }
+
+ return cause;
+}
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] attrib_index Attribute index of characteristic.
+ * @param[in] write_type Write type.
+ * @param length length of value to be written.
+ * @param p_value value to be written.
+ * @param[in] p_write_ind_post_proc pointer of a function to handle attribute write.
+ * @return Profile procedure result
+*/
+T_APP_RESULT lns_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ PROFILE_PRINT_INFO2("lns_attr_write_cb attrib_index = %d length %x", attrib_index, length);
+
+ switch (attrib_index)
+ {
+ case LNS_LN_CP_VALUE_INDEX:
+ {
+ /* Attribute value has variable size, make sure written value size is valid. */
+ if ((length > LNS_MAX_CTL_PNT_VALUE) || (p_value == NULL))
+ {
+ cause = APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ /* Make sure Control Point is not "Process already in progress". */
+ else if (lns_ctl_pnt.value[0] == LN_CP_OPCODE_RESPONSE_CODE)
+ {
+ PROFILE_PRINT_ERROR1("lns_attr_write_cb: lns_ctl_pnt.value[0] %d ", lns_ctl_pnt.value[0]);
+ cause = APP_RESULT_PROC_ALREADY_IN_PROGRESS;
+ }
+ /* Make sure Control Point is configured indication enable. */
+ else if (!lns_notify_indicate_flag.ln_cp_indicate_enable)
+ {
+ cause = APP_RESULT_CCCD_IMPROPERLY_CONFIGURED;
+ }
+ else
+ {
+ cause = lns_handle_ctl_pnt_proc(conn_id, service_id, length, p_value);
+ if (cause == APP_RESULT_SUCCESS)
+ {
+ *p_write_ind_post_proc = lns_ctl_pnt_write_ind_post_proc;
+ }
+ else
+ {
+ *p_write_ind_post_proc = NULL;
+ }
+ }
+
+ }
+ break;
+
+ default:
+ {
+ PROFILE_PRINT_ERROR1("lns_attr_write_cb attrib_index = %d not found", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ break;
+ }
+
+ return cause;
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] index Attribute index of characteristic data.
+ * @param[in] ccc_bits CCCD bits from stack.
+ * @return None
+*/
+void lns_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ T_LNS_CALLBACK_DATA callback_data;
+ bool bHandle = true;
+
+ PROFILE_PRINT_INFO2("lns_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits);
+
+ switch (index)
+ {
+ case LNS_LN_LOCATION_AND_SPEED_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ // Enable Notification
+ lns_notify_indicate_flag.location_and_speed_notify_enable = 1;
+ callback_data.msg_data.notification_indification_index =
+ LNS_NOTIFY_INDICATE_LOCATION_AND_SPEED_ENABLE;
+ }
+ else
+ {
+ lns_notify_indicate_flag.location_and_speed_notify_enable = 0;
+ callback_data.msg_data.notification_indification_index =
+ LNS_NOTIFY_INDICATE_LOCATION_AND_SPEED_DISABLE;
+ }
+ }
+ break;
+
+ case LNS_LN_CP_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE)
+ {
+ // Enable Indofication
+ lns_notify_indicate_flag.ln_cp_indicate_enable = 1;
+ callback_data.msg_data.notification_indification_index = LNS_NOTIFY_INDICATE_CP_ENABLE;
+ }
+ else
+ {
+ lns_notify_indicate_flag.ln_cp_indicate_enable = 0;
+ callback_data.msg_data.notification_indification_index = LNS_NOTIFY_INDICATE_CP_DISABLE;
+ }
+
+ }
+ break;
+
+ case LNS_LN_NAVIGATION_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ // Enable Notification
+ lns_notify_indicate_flag.navigation_enable = 1;
+ callback_data.msg_data.notification_indification_index = LNS_NOTIFY_INDICATE_NAVIGATION_ENABLE;
+ }
+ else
+ {
+ lns_notify_indicate_flag.navigation_enable = 0;
+ callback_data.msg_data.notification_indification_index = LNS_NOTIFY_INDICATE_NAVIGATION_DISABLE;
+ }
+ }
+ break;
+
+ default:
+ {
+ bHandle = false;
+ PROFILE_PRINT_ERROR1("lns_cccd_update_cb Index = %d not found", index);
+ }
+ break;
+
+ }
+ /* Notify Application. */
+ if (pfn_lns_app_cb && (bHandle == true))
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ pfn_lns_app_cb(service_id, (void *)&callback_data);
+ }
+ return;
+}
+
+/**
+ * @brief LOCATION AND NAVIGATION Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS lns_cbs =
+{
+ lns_attr_read_cb, // Read callback function pointer
+ lns_attr_write_cb, // Write callback function pointer
+ lns_cccd_update_cb // CCCD update callback function pointer
+};
+
+/**
+ * @brief Add location and navigation service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ lns_id = lns_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+uint8_t lns_add_service(void *p_func)
+{
+ uint8_t service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)lns_attr_tbl,
+ lns_attr_tbl_size,
+ lns_cbs))
+ {
+ PROFILE_PRINT_ERROR1("lns_add_service: ServiceId %d", service_id);
+ service_id = 0xff;
+ }
+ pfn_lns_app_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
+
diff --git a/src/ble/profile/server/ota_service.c b/src/ble/profile/server/ota_service.c
new file mode 100644
index 0000000..7923f53
--- /dev/null
+++ b/src/ble/profile/server/ota_service.c
@@ -0,0 +1,830 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ota_service.c
+* @brief
+* @details
+* @author Ken_mei
+* @date 14-May-2018
+* @version v1.0.0
+******************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2015 Realtek Semiconductor Corporation</center></h2>
+******************************************************************************
+*/
+
+#include <string.h>
+#include "gatt.h"
+#include "patch_header_check.h"
+#include "flash_map.h"
+#include "ota_service.h"
+#include "otp.h"
+#include "trace.h"
+#include "board.h"
+
+/*============================================================================*
+ * Micro
+ *============================================================================*/
+#define SOCV_CFG 0
+#define SYS_CFG 1
+#define OTA_HEADER 2
+#define SECURE_BOOT 3
+#define ROM_PATCH 4
+#define APP_IMG 5
+#define APP_DATA1 6
+#define APP_DATA2 7
+#define APP_DATA3 8
+#define APP_DATA4 9
+#define APP_DATA5 10
+#define APP_DATA6 11
+
+#define IMAGE_NOEXIST 0
+#define IMAGE_LOCATION_BANK0 1
+#define IMAGE_LOCATION_BANK1 2
+#define IMAGE_FIX_BANK_EXIST 3
+
+typedef struct
+{
+ uint8_t image_num;
+ uint16_t image_exist;
+ uint32_t image_indicator;
+} T_OTA_ACTIVE_BANK_IMG_INFO;
+
+/*============================================================================*
+ * External Variables
+ *============================================================================*/
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+/**< Function pointer used to send event to application from BWPS extended profile. */
+P_FUN_SERVER_GENERAL_CB pfn_ota_service_cb = NULL;
+uint8_t mac_addr[6];
+uint32_t patch_version = 0;
+uint32_t patch_ext_version = 0;
+uint32_t app_version = 0;
+#if (SUPPORT_OTA_PROTOCOL_TYPE_CHARACTERISTIC == 1)
+uint16_t protocol_type = 0x0;
+#endif
+static uint32_t image_version[IMAGE_MAX - OTA] = {0};
+T_OTA_ACTIVE_BANK_IMG_INFO ota_active_bank_info;
+
+const uint8_t GATT_UUID_OTA_SERVICE[16] = { 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0xFF, 0xD0, 0x00, 0x00};
+
+/**< @brief profile/service definition.
+* here is an example of OTA service table
+* including Write
+*/
+const T_ATTRIB_APPL gatt_Ota_service_table[] =
+{
+ /*--------------------------OTA Service ---------------------------*/
+ /* <<Primary Service>>, .. 0*/
+ {
+ (ATTRIB_FLAG_VOID | ATTRIB_FLAG_LE), /* wFlags */
+ {
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE), /* bTypeValue */
+ },
+ UUID_128BIT_SIZE, /* bValueLen */
+ (void *)GATT_UUID_OTA_SERVICE, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic1>>, .. 1*/ //----------------------OTA CMD 1
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 2*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_OTA),
+ HI_WORD(GATT_UUID_CHAR_OTA),
+ },
+ 2, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+ },
+
+ /* <<Characteristic2>>, .. 3, MAC Address*/ //------------------------MAC Address 2
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 4*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_MAC),
+ HI_WORD(GATT_UUID_CHAR_MAC),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic3>>, .. 5, Patch version*/ //-------------------------Patch Version 3
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 6*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_PATCH),
+ HI_WORD(GATT_UUID_CHAR_PATCH),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* <<Characteristic4>>, .. 7 App version*/ //-----------------------------APP Version 4
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 8*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_APP_VERSION),
+ HI_WORD(GATT_UUID_CHAR_APP_VERSION),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* <<Characteristic5>>, .. 9 Patch extension version*/ //--------------------Patch Ext Version 5
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 0x0A*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_PATCH_EXTENSION),
+ HI_WORD(GATT_UUID_CHAR_PATCH_EXTENSION),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic6>>, .. 0xB TEST MODE*/ //------------------------MP TEST MODE 6
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 0x0C*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_TEST_MODE),
+ HI_WORD(GATT_UUID_CHAR_TEST_MODE),
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_WRITE /* wPermissions */
+ },
+
+ /* <<Characteristic7>>, .. 0x0D OTA Device info*/ //---------------------------Device info 7
+ {
+ ATTRIB_FLAG_VALUE_INCL,
+ {
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ,
+ },
+ 1,
+ NULL,
+ GATT_PERM_READ
+ },
+ /* OTA Device info characteristic value 0x0E*/
+ {
+ ATTRIB_FLAG_VALUE_APPL,
+ {
+ LO_WORD(GATT_UUID_CHAR_DEVICE_INFO),
+ HI_WORD(GATT_UUID_CHAR_DEVICE_INFO),
+ },
+ 1,
+ (void *)NULL,
+ GATT_PERM_READ
+ },
+ /* <<Characteristic8>>, .. 0x0F OTA IMAGE COUNT TO UPDATE*/ //----------------------NUM OF IMG TO UPDATA 8
+ {
+ ATTRIB_FLAG_VALUE_INCL,
+ {
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE,
+ },
+ 1,
+ NULL,
+ GATT_PERM_READ
+ },
+ /* OTA IMAGE COUNT TO UPDATE characteristic value 0x10*/
+ {
+ ATTRIB_FLAG_VALUE_APPL,
+ {
+ LO_WORD(GATT_UUID_CHAR_IMAGE_COUNT_TO_UPDATE),
+ HI_WORD(GATT_UUID_CHAR_IMAGE_COUNT_TO_UPDATE),
+ },
+ 5,
+ (void *)NULL,
+ GATT_PERM_WRITE
+ },
+
+ /* <<Characteristic9>>, .. 0x11,ota pack img version*/ //-------------------------ota pack image version 9
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 0x12*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_IMAGE_VERSION0),
+ HI_WORD(GATT_UUID_CHAR_IMAGE_VERSION0),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic10>>, .. 0x13,ota pack img version*/ //-------------------------ota pack image version 9
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 0x14*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_IMAGE_VERSION1),
+ HI_WORD(GATT_UUID_CHAR_IMAGE_VERSION1),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic11>>, .. 0x15,ota pack img version*/ //-------------------------ota pack image version 9
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 0x16*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_IMAGE_VERSION2),
+ HI_WORD(GATT_UUID_CHAR_IMAGE_VERSION2),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+#if (SUPPORT_OTA_PROTOCOL_TYPE_CHARACTERISTIC == 1)
+ /* <<Characteristic10>>, .. 0x17,ota protocol type*/ //-------------------------ota protocol type 10
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* OTA characteristic value 0x14*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_PROTOCOL_TYPE),
+ HI_WORD(GATT_UUID_CHAR_PROTOCOL_TYPE),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+#endif
+};
+
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param ServiceID ServiceID to be written.
+ * @param iAttribIndex Attribute index of characteristic.
+ * @param wLength length of value to be written.
+ * @param pValue value to be written.
+ * @return Profile procedure result
+*/
+
+T_APP_RESULT ota_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_OTA_CALLBACK_DATA callback_data;
+ T_APP_RESULT wCause = APP_RESULT_SUCCESS;
+
+ if (BLE_SERVICE_CHAR_OTA_INDEX == attrib_index)
+ {
+ /* Make sure written value size is valid. */
+ if ((length != sizeof(uint8_t)) || (p_value == NULL))
+ {
+ wCause = APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ else
+ {
+ /* Notify Application. */
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.opcode = OTA_WRITE_CHAR_VAL;
+ callback_data.msg_data.write.u.value = p_value[0];
+
+ if (pfn_ota_service_cb)
+ {
+ pfn_ota_service_cb(service_id, (void *)&callback_data);
+ }
+ }
+ }
+ else if (BLE_SERVICE_CHAR_IMAGE_COUNT_INDEX == attrib_index)
+ {
+ /* Make sure written value size is valid. */
+ if ((length != OTA_CHAR_IMAGE_COUNT_LEN) || (p_value == NULL))
+ {
+ wCause = APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ else
+ {
+ /* Notify Application. */
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.opcode = OTA_WRITE_IMAGE_COUNT_VAL;
+ callback_data.msg_data.write.u.update_image_info.image_count = p_value[0];
+ callback_data.msg_data.write.u.update_image_info.update_patch_version = CHAR2SHORT(&p_value[1]);
+ callback_data.msg_data.write.u.update_image_info.update_app_version = CHAR2SHORT(&p_value[3]);
+
+ if (pfn_ota_service_cb)
+ {
+ pfn_ota_service_cb(service_id, (void *)&callback_data);
+ }
+ }
+ }
+ else if (BLE_SERVICE_CHAR_TEST_MODE_INDEX == attrib_index)
+ {
+ /* Make sure written value size is valid. */
+ if ((length != sizeof(uint8_t)) || (p_value == NULL))
+ {
+ wCause = APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ else
+ {
+ /* Notify Application. */
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.opcode = OTA_WRITE_TEST_MODE_CHAR_VAL;
+ callback_data.msg_data.write.u.value = p_value[0];
+
+ if (pfn_ota_service_cb)
+ {
+ pfn_ota_service_cb(service_id, (void *)&callback_data);
+ }
+ }
+ }
+ else
+ {
+ DFU_PRINT_INFO2("==>[OTA]ota_attr_write_cb Error! attrib_index=0x%x, length=%d",
+ attrib_index,
+ length);
+ wCause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ return wCause;
+
+}
+
+/**
+ * @brief get OTA active bank image info
+ * @param[out] p_ota_image_info
+ * image_exist
+ * bit0: ota header, bit: fsbl, bit2: patch ..., bit9: appdata6, bit10: upperstack
+ * img_indicator
+ * Indications for each image version.each indication use 2bit.
+ * 00: image is not existed.
+ * 01: image is existed in bank0,ota should update image for bank1.
+ * 10: image is existed in bank1,ota should update image for bank0.
+ * 11: image is standalone. ota should update image for standalone.
+ *
+ * bit[1:0]: Image 0
+ * bit[2N+1:2N]:Image N
+
+ * Image indicator for bee3 is as below:
+ * Image 0 OTA Header File
+ * Image 1 Secure Boot Loader Image
+ * Image 2 ROM Patch Image
+ * Image 3 APP Image
+ * Image 4 APP Data1 File
+ * Image 5 APP Data2 File
+ * Image 6 APP Data3 File
+ * Image 7 APP Data4 File
+ * Image 8 APP Data5 File
+ * Image 9 APP Data6 File
+ * Image 10 Upperstack File
+*/
+static void get_ota_active_bank_image_info(T_OTA_ACTIVE_BANK_IMG_INFO *p_ota_image_info)
+{
+ uint32_t image_location = IMAGE_NOEXIST;
+ bool enable_bank_switch = is_ota_support_bank_switch();
+ p_ota_image_info->image_num = 0;
+
+ if (enable_bank_switch)
+ {
+ uint32_t ota_bank0_addr = flash_get_bank_addr(FLASH_OTA_BANK_0);
+ if (ota_bank0_addr == get_active_ota_bank_addr())
+ {
+ image_location = IMAGE_LOCATION_BANK0;
+ }
+ else
+ {
+ image_location = IMAGE_LOCATION_BANK1;
+ }
+ }
+ else
+ {
+ image_location = IMAGE_FIX_BANK_EXIST;
+ }
+
+ for (T_IMG_ID image_id = OTA; image_id < IMAGE_MAX; image_id++)
+ {
+ if (0 != get_active_bank_image_size_by_img_id(image_id))
+ {
+ p_ota_image_info->image_num++;
+ p_ota_image_info->image_exist |= BIT(image_id - OTA);
+ p_ota_image_info->image_indicator |= image_location << ((OTA_HEADER + image_id - OTA) * 2);
+ }
+ }
+}
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param ServiceId ServiceID of characteristic data.
+ * @param iAttribIndex Attribute index of getting characteristic data.
+ * @param iOffset Used for Blob Read.
+ * @param piLength length of getting characteristic data.
+ * @param ppValue data got from service.
+ * @return Profile procedure result
+*/
+T_APP_RESULT ota_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT wCause = APP_RESULT_SUCCESS;
+ T_OTA_CALLBACK_DATA callback_data;
+ bool defer_handle = false;
+
+ switch (attrib_index)
+ {
+ default:
+ DFU_PRINT_INFO1("==>ota_attr_read_cb: attrib_index=%d not found!", attrib_index);
+ wCause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+ case BLE_SERVICE_CHAR_MAC_ADDRESS_INDEX:
+ {
+ gap_get_param(GAP_PARAM_BD_ADDR, mac_addr);
+ uint8_t addr[6];
+ for (int i = 0; i < 6; i++)
+ {
+ addr[i] = mac_addr[5 - i];
+ }
+ memcpy(mac_addr, addr, 6);
+ *pp_value = (uint8_t *)mac_addr;
+ *p_length = sizeof(mac_addr);
+ }
+ break;
+ case BLE_SERVICE_CHAR_PATCH_INDEX:
+ {
+ T_IMG_HEADER_FORMAT *p_header;
+ uint32_t addr = get_header_addr_by_img_id(RomPatch);
+ p_header = (T_IMG_HEADER_FORMAT *)addr;
+ patch_version = p_header->git_ver.ver_info.version;
+ DFU_PRINT_INFO2("ota_attr_read_cb: Patch addr=0x%x, version=0x%x", addr, patch_version);
+
+ *pp_value = (uint8_t *)&patch_version;
+ *p_length = sizeof(patch_version);
+ }
+ break;
+
+ case BLE_SERVICE_CHAR_APP_VERSION_INDEX:
+ {
+ T_IMG_HEADER_FORMAT *p_header;
+ uint32_t addr = get_header_addr_by_img_id(AppPatch);
+ p_header = (T_IMG_HEADER_FORMAT *)addr;
+ app_version = p_header->git_ver.ver_info.version;
+ DFU_PRINT_INFO2("ota_attr_read_cb: APP addr=0x%x, version=0x%x", addr, app_version);
+
+ *pp_value = (uint8_t *)&app_version;
+ *p_length = sizeof(app_version);
+ }
+ break;
+
+ case BLE_SERVICE_CHAR_PATCH_EXTENSION_INDEX: //not used in bee2
+ {
+
+ }
+ break;
+ case BLE_SERVICE_CHAR_DEVICE_INFO_INDEX:
+ {
+ static T_DFU_DEVICE_INFO DeviceInfo;
+ T_IMG_HEADER_FORMAT *p_ota_header;
+ uint32_t ota_header_addr = get_header_addr_by_img_id(OTA);
+ p_ota_header = (T_IMG_HEADER_FORMAT *)ota_header_addr;
+ DeviceInfo.ic_type = DEFINED_IC_TYPE;
+ DeviceInfo.ota_version = 0x1;
+ DeviceInfo.secure_version = p_ota_header->ctrl_header.secure_version;
+ DFU_PRINT_INFO3("<==ota_attr_read_cb: ic_type=0x%x, ota_version=0x%x, OTA Header secure_version=0x%x",
+ DeviceInfo.ic_type, DeviceInfo.ota_version, DeviceInfo.secure_version);
+
+ DeviceInfo.ota_mode.mode_flag.buf_check_en = DFU_BUFFER_CHECK_ENABLE;
+ DeviceInfo.max_buffer_size = DFU_TEMP_BUFFER_SIZE;
+ DeviceInfo.ota_mode.mode_flag.aesflg = OTP->ota_with_encryption_data;
+ DeviceInfo.ota_mode.mode_flag.aesmode = 1;
+ DFU_PRINT_INFO4("<==ota_attr_read_cb: bufChkEn=%d, bufsize=0x%x, aesflg=%d, aesmode=%d",
+ DeviceInfo.ota_mode.mode_flag.buf_check_en, DeviceInfo.max_buffer_size,
+ DeviceInfo.ota_mode.mode_flag.aesflg, DeviceInfo.ota_mode.mode_flag.aesmode);
+
+ /* default disable copy app data img when bank switch */
+ DeviceInfo.ota_mode.mode_flag.copy_img = 0;
+
+ /* prepare img_indicator, if modify here need to sync with vaule
+ of BLE_SERVICE_CHAR_IMAGE_VERSION_INDEX */
+ if (is_ota_support_bank_switch())
+ {
+ //dual bank must support multiple image update
+ DeviceInfo.ota_mode.mode_flag.multi_img = 1;
+ uint32_t ota_bank0_addr = flash_get_bank_addr(FLASH_OTA_BANK_0);
+ if (ota_bank0_addr == get_active_ota_bank_addr())
+ {
+ /* meaningful only when multi_img = 1 */
+ DeviceInfo.temp_bank_size = flash_get_bank_size(FLASH_OTA_BANK_1) / FMC_SEC_SECTION_LEN;
+ }
+ else
+ {
+ /* meaningful only when multi_img = 1 */
+ DeviceInfo.temp_bank_size = flash_get_bank_size(FLASH_OTA_BANK_0) / FMC_SEC_SECTION_LEN;
+ }
+ }
+ else
+ {
+#if (SUPPORT_TEMP_COMBINED_OTA == 1)
+ DeviceInfo.ota_mode.mode_flag.multi_img = 1;
+#else
+ DeviceInfo.ota_mode.mode_flag.multi_img = 0;
+#endif
+ /* meaningful only when multi_img = 1 */
+ DeviceInfo.temp_bank_size = flash_get_bank_size(FLASH_OTA_TMP) / FMC_SEC_SECTION_LEN;
+ }
+ /*read flash map info to set image indicator*/
+ get_ota_active_bank_image_info(&ota_active_bank_info);
+ DeviceInfo.img_indicator = ota_active_bank_info.image_indicator;
+
+ DFU_PRINT_INFO4("<==ota_attr_read_cb: copy_img=0x%x, multi_img=0x%x, temp_bank_size=0x%x, img_indicator=0x%x",
+ DeviceInfo.ota_mode.mode_flag.copy_img, DeviceInfo.ota_mode.mode_flag.multi_img,
+ DeviceInfo.temp_bank_size, DeviceInfo.img_indicator);
+
+
+ *pp_value = (uint8_t *)&DeviceInfo;
+ *p_length = sizeof(T_DFU_DEVICE_INFO);
+ }
+ break;
+ case BLE_SERVICE_CHAR_IMAGE_VERSION0_INDEX:
+ {
+ uint8_t index = 0;
+ T_IMAGE_VERSION image_ver;
+
+ if (0 == ota_active_bank_info.image_num)
+ {
+ get_ota_active_bank_image_info(&ota_active_bank_info);
+ }
+ DFU_PRINT_INFO2("image_exist=0x%x(BIT0:OTA, BIT1:patch, ...), image_num=%d",
+ ota_active_bank_info.image_exist, ota_active_bank_info.image_num);
+
+ for (T_IMG_ID image_id = OTA; image_id < IMAGE_MAX; image_id++)
+ {
+ if (ota_active_bank_info.image_exist & BIT(image_id - OTA))
+ {
+ get_active_bank_image_version(image_id, &image_ver);
+ image_version[index] = image_ver.ver_info.version;
+ index ++;
+ DFU_PRINT_INFO2("image:0x%x exist!, version=0x%x",
+ image_id, image_ver.ver_info.version);
+ }
+ }
+
+ *pp_value = (uint8_t *)image_version;
+ if (ota_active_bank_info.image_num > 5)
+ {
+ *p_length = 20;
+ }
+ else
+ {
+ *p_length = 4 * ota_active_bank_info.image_num;
+ }
+ DFU_PRINT_INFO5("Image Version[0-4]: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x",
+ image_version[0], image_version[1], image_version[2], image_version[3], image_version[4]);
+
+ /* Notify Application. */
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = OTA_READ_CHAR_IMAGE_VERSION_INDEX;
+ /*defer processing before ota start*/
+ defer_handle = true;
+ }
+ break;
+ case BLE_SERVICE_CHAR_IMAGE_VERSION1_INDEX:
+ {
+ if (ota_active_bank_info.image_num > 5)
+ {
+ *pp_value = (uint8_t *)&image_version[5];
+ if (ota_active_bank_info.image_num > 10)
+ {
+ *p_length = 20;
+ }
+ else
+ {
+ *p_length = 4 * (ota_active_bank_info.image_num - 5);
+ }
+ DFU_PRINT_INFO5("Image Version[5-9]: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x",
+ image_version[5], image_version[6], image_version[7], image_version[8], image_version[9]);
+ }
+ else
+ {
+ *pp_value = NULL;
+ *p_length = 0;
+ }
+
+ /* Notify Application. */
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = OTA_READ_CHAR_IMAGE_VERSION_INDEX;
+ /*defer processing before ota start*/
+ defer_handle = true;
+ }
+ break;
+ case BLE_SERVICE_CHAR_IMAGE_VERSION2_INDEX:
+ {
+ if (ota_active_bank_info.image_num > 10)
+ {
+ *pp_value = (uint8_t *)&image_version[10];
+ *p_length = 4 * (ota_active_bank_info.image_num - 10);
+ //ota 11 images at most now
+ DFU_PRINT_INFO1("Image Version[10]: 0x%x", image_version[10]);
+ }
+ else
+ {
+ *pp_value = NULL;
+ *p_length = 0;
+ }
+
+ /* Notify Application. */
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = OTA_READ_CHAR_IMAGE_VERSION_INDEX;
+ /*defer processing before ota start*/
+ defer_handle = true;
+ }
+ break;
+#if (SUPPORT_OTA_PROTOCOL_TYPE_CHARACTERISTIC == 1)
+ case BLE_SERVICE_CHAR_PROTOCOL_TYPE_INDEX:
+ {
+ protocol_type = 0x0012;
+ *pp_value = (uint8_t *)&protocol_type;
+ *p_length = sizeof(protocol_type);
+ }
+ break;
+#endif
+ }
+
+ /* Notify Application. */
+ if (pfn_ota_service_cb && (defer_handle == true))
+ {
+ pfn_ota_service_cb(service_id, (void *)&callback_data);
+ }
+ return (wCause);
+}
+
+
+/**
+ * @brief OTA ble Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS ota_service_cbs =
+{
+ ota_attr_read_cb, // Read callback function pointer
+ ota_attr_write_cb, // Write callback function pointer
+ NULL // CCCD update callback function pointer
+};
+
+/**
+ * @brief add OTA ble service to application.
+ *
+ * @param p_func pointer of app callback function called by profile.
+ * @return service ID auto generated by profile layer.
+ * @retval ServiceId
+*/
+uint8_t ota_add_service(void *p_func)
+{
+ uint8_t service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)gatt_Ota_service_table,
+ sizeof(gatt_Ota_service_table),
+ ota_service_cbs))
+ {
+ DFU_PRINT_ERROR1("<==ota_add_service: service_id=%d", service_id);
+ service_id = 0xff;
+ return service_id;
+ }
+ pfn_ota_service_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
diff --git a/src/ble/profile/server/plxs.c b/src/ble/profile/server/plxs.c
new file mode 100644
index 0000000..044c615
--- /dev/null
+++ b/src/ble/profile/server/plxs.c
@@ -0,0 +1,1971 @@
+/**
+***************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+***************************************************************************************
+* @file plxs.c
+* @brief Pulse Oximeter Service source file.
+* @details Interface to access the Pulse Oximeter Service.
+* @author danni
+* @date 2018-12-27
+* @version v1.0
+* *************************************************************************************
+*/
+#include "trace.h"
+#include <string.h>
+#include <gatt.h>
+#include "plxs.h"
+
+/** @defgroup PLXS Pulse Oximeter Service
+ * @brief Pulse Oximeter Service
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PLXS_SERVICE_UUID service related UUIDs.
+ * @{
+ */
+#define GATT_UUID_PULSE_OXIMETER 0x1822
+#define GATT_UUID_CHAR_PLX_SPOT_CHECK_MEASUREMENT 0x2A5E
+#define GATT_UUID_CHAR_PLX_CONTINUOUS_MEASUREMENT 0x2A5F
+#define GATT_UUID_CHAR_PLX_FEATURE 0x2A60
+#define GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT 0x2A52
+/** @} End of PLXS_SERVICE_UUID */
+
+/** @brief Check PLXS Record Access Control Point operation is available or not. */
+#define PLXS_RACP_OPERATION_ACTIVE(x) (((x) >= PLXS_RACP_OPCODE_REPORT_RECS) && ((x) < PLXS_RACP_OPCODE_NBR_OF_RECS_RESP))
+
+/** @defgroup PLXS_APP_ERROR_CODE profile specific attribute protocol application error codes
+ * @{
+ */
+#define PLXS_ERR_PROC_ALREADY_IN_PROGRESS 0xFE
+#define PLXS_ERR_CCCD_IMPROPERLY_CONFIGURED 0xFD
+/** @} End of PLXS_APP_ERROR_CODE */
+
+/** @defgroup PLXS_SPOT_CHECK_FLAGS PLX Spot-check Measurement Characteristic Flags,The Flags field is an 8-bit bit field which indicates what fields are present in the PLX Spot-check
+ * Measurement Characteristic value
+ * @{
+ */
+#define PLXS_SPOT_CHECK_MEASUREMENT_FLAG_TIMESTAMP 0x01
+#define PLXS_SPOT_CHECK_MEASUREMENT_FLAG_MEASUREMENT_STATUS 0x02
+#define PLXS_SPOT_CHECK_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS 0x04
+#define PLXS_SPOT_CHECK_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX 0x08
+#define PLXS_SPOT_CHECK_MEASUREMENT_FLAG_DEVICE_CLOCK_NOT_SET 0x10
+/** @} End of PLXS_SPOT_CHECK_FLAGS */
+
+/** @defgroup PLXS_CONTINUOUS_MEAS_FLAGS PLX Continuous Measurement Characteristic Flags,The Flags field is an 8-bit bit field which indicates what fields are present in the PLX Continuous
+ * Measurement Characteristic value.
+ * @{
+ */
+#define PLXS_CONTINUOUS_MEASUREMENT_FLAG_SPO2PR_FAST 0x01
+#define PLXS_CONTINUOUS_MEASUREMENT_FLAG_SPO2PR_SLOW 0x02
+#define PLXS_CONTINUOUS_MEASUREMENT_FLAG_MEASUREMENT_STATUS 0x04
+#define PLXS_CONTINUOUS_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS 0x08
+#define PLXS_CONTINUOUS_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX 0x10
+/** @} End of PLXS_CONTINUOUS_MEAS_FLAGS */
+
+/** @defgroup PLXS_FEASURES_FLAGS PLX Supported Features field. The Supported Features field is a 16-bit bit field which indicates feature support as well as what
+ * fields are present in the PLX Features characteristic.
+ * @{
+ */
+#define PLXS_FEATURES_MEASUREMENT_STATUS 0x0001
+#define PLXS_FEATURES_DEVICE_SENSOR_STATUS 0x0002
+#define PLXS_FEATURES_MEASUREMENT_STORAGE 0x0004
+#define PLXS_FEATURES_TIMESTAMP 0x0008
+#define PLXS_FEATURES_SPO2PR_FAST_METRIC 0x0010
+#define PLXS_FEATURES_SPO2PR_SLOW_METRIC 0x0020
+#define PLXS_FEATURES_PULSE_AMPLITUDE_INDEX 0x0040
+#define PLXS_FEATURES_MULTIPLE_BONDS 0x0080
+/** @} End of PLXS_FEASURES_FLAGS */
+/** @} End of PLXS */
+
+/** @brief The Server should be able to store 30 or more measurements*/
+#define PLXS_RACP_DATABASE_SIZE (PLXS_RACP_MAX_NBR_OF_STORED_RECS + 1)
+/*============================================================================*
+ * Types
+ *============================================================================*/
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+typedef struct
+{
+ T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE plxs_spot_check_measurement_value;
+
+} T_PLXS_PATIENT_RECORD;
+
+/** @brief data base for store spot check measurement value*/
+typedef struct
+{
+ T_PLXS_PATIENT_RECORD records[PLXS_RACP_DATABASE_SIZE];
+ uint8_t record_num;
+ uint8_t head;
+ uint8_t tail;
+} T_PLXS_RECORD_DATA_BASE;
+
+/** @brief PLXS Record Access Control Point OpCodes. */
+typedef enum
+{
+ PLXS_RACP_OPCODE_RESERVED = 0x00,/**< reserved for future use operator:N/A */
+ PLXS_RACP_OPCODE_REPORT_RECS = 0x01,/**< report stored records(operator:All records)*/
+ PLXS_RACP_OPCODE_DELETE_RECS = 0x02,/**< delete stored records(operator:All records)*/
+ PLXS_RACP_OPCODE_ABORT_OPERATION = 0x03,/**< Abort operation(operator:Null 0x00)*/
+ PLXS_RACP_OPCODE_REPORT_NBR_OF_RECS = 0x04,/**< report number of stored records(operator:All records)*/
+ PLXS_RACP_OPCODE_NBR_OF_RECS_RESP = 0x05,/**< number of stored records response(operator:Null 0x00)*/
+ PLXS_RACP_OPCODE_RESP_CODE = 0x06/**< response code (operator:Null 0x00)*/
+} T_PLXS_CTRL_POINT_OPCODE;
+
+/**@brief PLXS Record Access Control Point Operator. */
+typedef enum
+{
+ PLXS_RACP_OPERATOR_NULL = 0x00,
+ PLXS_RACP_OPERATOR_ALL_RECS = 0x01,/**< All records*/
+ PLXS_RACP_OPERATOR_LT_EQ = 0x02,/**< less than or equal to*/
+ PLXS_RACP_OPERATOR_GT_EQ = 0x03,/**< greater than or equal to*/
+ PLXS_RACP_OPERATOR_RANGE = 0x04,/**< within range of */
+ PLXS_RACP_OPERATOR_FIRST = 0x05,/**< first records*/
+ PLXS_RACP_OPERATOR_LAST = 0x06/**< last records*/
+} T_PLXS_CTRL_POINT_OPERATOR;
+
+/** @brief Glucose Record Access Control Point Response Codes. */
+typedef enum
+{
+ PLXS_RACP_RESP_RESERVED = 0x00,
+ PLXS_RACP_RESP_SUCCESS = 0x01,
+ PLXS_RACP_RESP_OPCODE_NOT_SUPPORTED = 0x02,
+ PLXS_RACP_RESP_INVALID_OPERATOR = 0x03,
+ PLXS_RACP_RESP_OPERATOR_NOT_SUPPORTED = 0x04,
+ PLXS_RACP_RESP_INVALID_OPERAND = 0x05,
+ PLXS_RACP_RESP_NO_RECS_FOUND = 0x06,
+ PLXS_RACP_RESP_ABORT_UNSUCCESSFUL = 0x07,
+ PLXS_RACP_RESP_PROC_NOT_COMPLETED = 0x08,
+ PLXS_RACP_RESP_OPERAND_NOT_SUPPORTED = 0x09
+} T_PLXS_CTRL_POINT_RESP_CODES;
+
+typedef struct
+{
+ T_PLXS_CTRL_POINT_OPCODE op_code;
+ T_PLXS_CTRL_POINT_OPERATOR op;/**< operator*/
+ uint8_t operand[18];
+} T_PLXS_CONTROL_POINT;
+
+typedef struct
+{
+ T_PLXS_CONTROL_POINT ctrl_point;
+ uint8_t cp_length;/**< length of current operand of control point*/
+ T_PLXS_RECORD_DATA_BASE record_db;
+} T_PLXS_RACP;
+/** @brief plxs report records procedure flags*/
+typedef struct
+{
+ uint16_t plxs_num_records_to_report;
+ uint16_t plxs_current_record_to_report;
+ uint16_t plxs_record_to_report_start_index;
+ uint16_t plxs_records_to_report_offset;
+ bool plxs_send_data_end_flag;
+} T_PLXS_REPORT_RECORDS_FLAGS;
+#endif
+/** @brief notification or indiaction enabled or not.1:enabled,0: disabled*/
+typedef struct
+{
+ uint8_t spot_check_measurement_indication_enable: 1;
+ uint8_t continuous_measurement_notify_enable: 1;
+ uint8_t racp_indication_enable: 1;
+ uint8_t rfu: 5;
+} T_PLXS_NOTIFY_INDICATE_FLAG;
+/** @brief add flow control for notify and indicate*/
+typedef struct
+{
+ uint8_t spot_check_indication_status_flag;
+ uint8_t continuous_measurement_notify_status_flag;
+ uint8_t report_records_indication_status_flag;
+} T_PLXS_DATA_SEND_STATUS_FLAGS;
+
+/********************************************************************************************************
+* local static and global variables defined here, only used in this source file.
+********************************************************************************************************/
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+/**< @brief plxs record access control point struct*/
+static T_PLXS_RACP plxs_racp;
+/**< @brief report stored repords procedure needs flags*/
+static T_PLXS_REPORT_RECORDS_FLAGS plxs_report_records_flags = {0, 0, 0, 0, 1};
+/**< @brief plxs abort procedure flags*/
+static bool plxs_abort_flag = false;
+static bool plxs_abort_by_app_flag = false;
+#endif
+/**< @brief plxs feature characteristic value struct*/
+static T_PLXS_FEATURES_VALUE plxs_features;
+#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT
+/**< @brief plxs spot check measurement flags*/
+static uint8_t plxs_spot_check_measurement_flags;
+#endif
+#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT
+/**< @brief plxs continuous measurement flags*/
+static uint8_t plxs_continuous_measurement_flags;
+#endif
+/**< @brief flags of notification and indication for characteristic */
+static T_PLXS_NOTIFY_INDICATE_FLAG plxs_notify_indicate_flag = {0};
+
+static T_PLXS_DATA_SEND_STATUS_FLAGS plxs_data_send_status_flags = {PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_IDLE,
+ PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_IDLE,
+ PLXS_STATUS_REPORT_RECORDS_INDICATION_IDLE
+ };
+/**< @brief Function pointer used to send event to application from plxs. Initiated in plxs_add_service. */
+static P_FUN_SERVER_GENERAL_CB pfn_plxs_cb = NULL;
+
+/** @brief profile/service definition. */
+const T_ATTRIB_APPL plxs_att_tbl[] =
+{
+ /* <<Primary Service>>, .. */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /*wFlags*/
+ { /*bTypeValue*/
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_PULSE_OXIMETER), /*service uuid*/
+ HI_WORD(GATT_UUID_PULSE_OXIMETER)
+ },
+ UUID_16BIT_SIZE, /*bValueLen*/
+ NULL, /*pValueContext*/
+ GATT_PERM_READ /*wPermissions*/
+
+ },
+#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT
+ /* <<Characteristic>>, .. */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /*wFlags*/
+ { /*bTypeValue*/
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_INDICATE /*characteristic properties*/
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /*bValueLen*/
+ NULL, /*pValueContext*/
+ GATT_PERM_READ /*wPermissions*/
+
+ },
+ /*--- PLX Spot-check Measurement characteristic value ---*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /*wFlags*/
+ {
+ LO_WORD(GATT_UUID_CHAR_PLX_SPOT_CHECK_MEASUREMENT),
+ HI_WORD(GATT_UUID_CHAR_PLX_SPOT_CHECK_MEASUREMENT)
+ },
+ 0, /*bValueLen*/
+ NULL, /*pValueContext*/
+ GATT_PERM_NONE /*wPermissions*/
+
+ },
+ /*client characteristic configuration */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL),/*wFlags*/
+ {
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value:*/
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT),
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /*bValueLen*/
+ NULL,
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /*wPermissions*/
+ },
+#endif
+
+
+#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT
+ /* <<Characteristic>>, .. */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL, /*pValueContext*/
+ GATT_PERM_READ /* wPermissions */
+ },
+ /*--- PLX Continuous Measurement characteristic value ---*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_PLX_CONTINUOUS_MEASUREMENT),
+ HI_WORD(GATT_UUID_CHAR_PLX_CONTINUOUS_MEASUREMENT)
+ },
+ 0, /* bValueLen */
+ NULL, /*pValueContext*/
+ GATT_PERM_NONE /* wPermissions */
+ },
+ /* client characteristic configuration */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL),/* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value:*/
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT),
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */
+
+ },
+
+#endif
+ /* <<Characteristic>>, .. */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL, /*pValueContext*/
+ GATT_PERM_READ /* wPermissions */
+
+ },
+ /*--- PLXS features characteristic value read ---*/
+ {
+ ATTRIB_FLAG_VALUE_APPL,
+ {
+ LO_WORD(GATT_UUID_CHAR_PLX_FEATURE),
+ HI_WORD(GATT_UUID_CHAR_PLX_FEATURE)
+
+ },
+ 0,
+ NULL,
+ GATT_PERM_READ_AUTHEN_REQ
+ },
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+ /* <<Characteristic>>, .. */
+ {
+ ATTRIB_FLAG_VALUE_INCL,
+ {
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_INDICATE)
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1,
+ NULL,
+ GATT_PERM_READ
+
+ },
+ /*--- PLXS Record Access Control Point value ---*/
+ {
+ ATTRIB_FLAG_VALUE_APPL,
+ {
+ LO_WORD(GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT),
+ HI_WORD(GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT)
+ },
+ 0,
+ NULL,
+ GATT_PERM_WRITE_AUTHEN_REQ
+ },
+ /* client characteristic configuration */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL),/* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value:*/
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL, /*pValueContext*/
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */
+ }
+#endif
+};
+/********************************************************************************************************
+* functions
+********************************************************************************************************/
+/**
+ * @brief init spot-check measurement characteristic flags, continuous measurement
+ * characteristic flags and feature characteristic flags according Macros defined in plxs_config.h
+ *
+ * @param[in] None
+ * @return None
+ * <b>Example usage</b>
+ * \code{.c}
+ T_SERVER_ID plxs_add_service(void * p_func)
+ {
+ plxs_flags_init();
+ ......
+ }
+ * \endcode
+ */
+void plxs_flags_init()
+{
+#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT //spot check start
+#if PLXS_SPOT_CHECK_MEASUREMENT_TIMESTAMP_SUPPORT //TIMESTAMP_SUPPORT start
+ plxs_spot_check_measurement_flags |= PLXS_SPOT_CHECK_MEASUREMENT_FLAG_TIMESTAMP;
+#endif //TIMESTAMP_SUPPORT end
+
+#if PLXS_MEASUREMENT_STATE_SUPPORT //MEASUREMENT_STATE_SUPPORT start
+ plxs_spot_check_measurement_flags |= PLXS_SPOT_CHECK_MEASUREMENT_FLAG_MEASUREMENT_STATUS;
+#endif //MEASUREMENT_STATE_SUPPORT end
+
+#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT //DEVICE_AND_SENSOR_STATUS_SUPPORT start
+ plxs_spot_check_measurement_flags |= PLXS_SPOT_CHECK_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS;
+#endif //DEVICE_AND_SENSOR_STATUS_SUPPORT end
+
+#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT
+ plxs_spot_check_measurement_flags |= PLXS_SPOT_CHECK_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX;
+#endif
+
+#if PLXS_DEVICE_CLOCK_NOT_SET
+ plxs_spot_check_measurement_flags |= PLXS_SPOT_CHECK_MEASUREMENT_FLAG_DEVICE_CLOCK_NOT_SET;
+#endif
+#endif //spot check end
+
+#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT // continueous measurement start
+#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_FAST_SUPPORT
+ plxs_continuous_measurement_flags |= PLXS_CONTINUOUS_MEASUREMENT_FLAG_SPO2PR_FAST;
+#endif
+
+#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_SLOW_SUPPORT
+ plxs_continuous_measurement_flags |= PLXS_CONTINUOUS_MEASUREMENT_FLAG_SPO2PR_SLOW;
+#endif
+
+#if PLXS_MEASUREMENT_STATE_SUPPORT
+ plxs_continuous_measurement_flags |= PLXS_CONTINUOUS_MEASUREMENT_FLAG_MEASUREMENT_STATUS;
+#endif
+
+#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT
+ plxs_continuous_measurement_flags |= PLXS_CONTINUOUS_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS;
+#endif
+
+#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT
+ plxs_continuous_measurement_flags |= PLXS_CONTINUOUS_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX;
+#endif
+#endif //continuous measurement end
+
+//plxs feature support bit init
+#if PLXS_MEASUREMENT_STATE_SUPPORT
+ plxs_features.supported_features |= PLXS_FEATURES_MEASUREMENT_STATUS;
+ plxs_features.measurement_status_support_bits = PLXS_FEATURES_MEASUREMENT_STATUS_SUPPORTS;
+#endif
+
+#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT
+ plxs_features.supported_features |= PLXS_FEATURES_DEVICE_SENSOR_STATUS;
+ plxs_features.device_and_sensor_status_support_bits = PLXS_FEATURES_DEVICE_SENSOR_STATUS_SUPPORTS;
+#endif
+
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+ plxs_features.supported_features |= PLXS_FEATURES_MEASUREMENT_STORAGE;
+#endif
+
+#if PLXS_SPOT_CHECK_MEASUREMENT_TIMESTAMP_SUPPORT
+ plxs_features.supported_features |= PLXS_FEATURES_TIMESTAMP;
+#endif
+
+#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_FAST_SUPPORT
+ plxs_features.supported_features |= PLXS_FEATURES_SPO2PR_FAST_METRIC;
+#endif
+
+#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_SLOW_SUPPORT
+ plxs_features.supported_features |= PLXS_FEATURES_SPO2PR_SLOW_METRIC;
+#endif
+
+#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT
+ plxs_features.supported_features |= PLXS_FEATURES_PULSE_AMPLITUDE_INDEX;
+#endif
+
+#if PLXS_MULTIPLE_BONDS_SUPPORT
+ plxs_features.supported_features |= PLXS_FEATURES_MULTIPLE_BONDS;
+#endif
+}
+/**
+ * @brief Set PLX service parameter.
+ * set spot_check characteristic vaule ,continuous measurement characteristic value,
+ * feature characteristic value and racp characteristic value used parameters
+ * @param[in] param_type parameter type set by T_PLXS_PARAM_TYPE @refT_PLXS_PARAM_TYPE.
+ * @param[in] len type value length to be set
+ * @param[in] p_value type value to be set
+ * @return parameter set result.
+ * @retval PLXS_APP_RESULT_SUCCESS Operation success.
+ * @retval others Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_plxs_feature_flags_set(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ T_PLXS_FEATURES_VALUE plxs_features;
+ ......
+ plxs_set_parameter(PLXS_PARAM_FEATURE_FLAGS, 2, &plxs_features);
+ return RESULT_SUCCESS;
+ }
+ * \endcode
+ */
+T_PLXS_APP_RESULT plxs_set_parameter(T_PLXS_PARAM_TYPE param_type, uint8_t len,
+ void *p_value)////todo: just for bqb,maybe not used by user?????
+{
+ T_PLXS_APP_RESULT ret = PLXS_APP_RESULT_SUCCESS;
+ if (p_value == NULL)
+ {
+ ret = PLXS_APP_RESULT_POINTER_NULL;
+ PROFILE_PRINT_ERROR0("plxs_set_parameter:PLXS_APP_RESULT_POINTER_NULL");
+ return ret;
+ }
+ switch (param_type)
+ {
+ // set plxs feature value according to PLXS_PARAM_FEATURE_FLAGS
+ case PLXS_PARAM_FEATURE_FLAGS:
+ {
+ plxs_features = *((T_PLXS_FEATURES_VALUE *)p_value);
+ }
+ break;
+#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT //spot-check start
+ case PLXS_PARAM_SPOT_CHECK_MEASUREMENT_FLAGS:
+ {
+ //set plxs spot check measurement flags
+ if (len == 1)
+ {
+ plxs_spot_check_measurement_flags = *((uint8_t *)p_value);
+ }
+ else
+ {
+ ret = PLXS_APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ }
+ break;
+#endif //spot-check end
+
+# if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT//continuous-measurement start
+ case PLXS_PARAM_CONTINUOUS_MEASUREMENT_FLAGS:
+ {
+ //set continuous measurement flags
+ if (len == 1)
+ {
+ plxs_continuous_measurement_flags = *((uint8_t *)p_value);
+ }
+ else
+ {
+ ret = PLXS_APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ }
+ break;
+#endif //continuous-measurement end
+ default:
+ {
+ ret = PLXS_APP_RESULT_INVALID_TYPE;
+ }
+ break;
+ }
+ if (ret == PLXS_APP_RESULT_SUCCESS)
+ {
+ PROFILE_PRINT_INFO2("plxs_set_parameter success: param_type = %d,value = %x\n", param_type,
+ *(uint8_t *)p_value);
+ }
+ else
+ {
+ PROFILE_PRINT_ERROR2("plxs_set_parameter failed: param_type = %d,value = %x\n", param_type,
+ *(uint8_t *)p_value);
+ }
+ return ret;
+}
+
+/**
+ * @brief get plxs parameters such as spot check measurement flags,continuous measurement flags or features supports @ref T_PLXS_PARAM_TYPE
+ *
+ * @param[in] param_type @ref T_PLXS_PARAM_TYPE
+ * @param[in,out] p_value get spot check measurement flags,continuous measurement flags or features supports
+ * @return plxs_get_parameter result
+ * @retval PLXS_APP_RESULT_SUCCESS Operation success.
+ * @retval others Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_plxs_feature_flags_set(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+ T_PLXS_FEATURES_VALUE plxs_features;
+ plxs_get_parameter(PLXS_PARAM_FEATURE_FLAGS, &plxs_features);
+ if (p_parse_value->dw_param[0] == 1)
+ {
+ //both measurement status and device sensor status not support
+ plxs_features.supported_features = plxs_features.supported_features & 0xFFFC;
+ }
+ ......
+ }
+ * \endcode
+ */
+T_PLXS_APP_RESULT plxs_get_parameter(T_PLXS_PARAM_TYPE param_type, void *p_value)
+{
+ T_PLXS_APP_RESULT ret = PLXS_APP_RESULT_SUCCESS;
+ if (p_value == NULL)
+ {
+ ret = PLXS_APP_RESULT_POINTER_NULL;
+ PROFILE_PRINT_ERROR0("plxs_get_parameter:PLXS_APP_RESULT_POINTER_NULL");
+ return ret;
+ }
+ switch (param_type)
+ {
+ case PLXS_PARAM_FEATURE_FLAGS:
+ {
+ //get feature value
+ memcpy((T_PLXS_FEATURES_VALUE *)p_value, &plxs_features, sizeof(T_PLXS_FEATURES_VALUE));
+ }
+ break;
+#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT//continuous-measurement start
+ case PLXS_PARAM_CONTINUOUS_MEASUREMENT_FLAGS:
+ {
+ //get continuous measurement flags
+ memcpy((uint8_t *)p_value, &plxs_continuous_measurement_flags, 1);
+ }
+ break;
+#endif //continuous-measurement end
+
+#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT //spot-check start
+ case PLXS_PARAM_SPOT_CHECK_MEASUREMENT_FLAGS:
+ {
+ //get spot check measurement flags
+ memcpy((uint8_t *)p_value, &plxs_spot_check_measurement_flags, 1);
+ }
+ break;
+#endif //spot-check end
+ default:
+ {
+ ret = PLXS_APP_RESULT_INVALID_TYPE;
+ }
+ }
+ return ret;
+}
+
+
+/**
+ * @brief pop record from database
+ *
+ * @param[in] p_spot_check_value pointer to p_spot_check_value @ref T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE
+ * @return result
+ * @retval PLXS_APP_RESULT_SUCCESS operator success
+ * @retval others operator fail
+ */
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+T_PLXS_APP_RESULT pop_record_from_database(T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE *p_spot_check_value)
+{
+ T_PLXS_APP_RESULT ret = PLXS_APP_RESULT_SUCCESS;
+ if (p_spot_check_value == NULL)
+ {
+ ret = PLXS_APP_RESULT_POINTER_NULL;
+ PROFILE_PRINT_ERROR0("pop_record_from_database:PLXS_APP_RESULT_POINTER_NULL");
+ return ret;
+ }
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+ if (plxs_racp.record_db.tail == plxs_racp.record_db.head)
+ {
+ PROFILE_PRINT_ERROR0("pop_record_from_database: PLXS_APP_RESULT_QUEUE_NULL");
+ ret = PLXS_APP_RESULT_QUEUE_NULL;
+ return ret;
+ }
+ *p_spot_check_value =
+ plxs_racp.record_db.records[plxs_racp.record_db.head].plxs_spot_check_measurement_value;
+ plxs_racp.record_db.head = (plxs_racp.record_db.head + 1) % PLXS_RACP_DATABASE_SIZE;
+ plxs_racp.record_db.record_num--;
+#else
+ PROFILE_PRINT_ERROR0("pop_record_from_database: not support");
+ ret = PLXS_APP_RESULT_NOT_SUPPORT;
+#endif
+ return ret;
+}
+
+/**
+ * @brief push spot check measurement records to database
+ * @param[in] spot_check_value
+ * @return result
+ * @retval PLXS_APP_RESULT_SUCCESS operator success
+ * @retval others operator fail
+ * <b>Example usage</b>
+ * \code{.c}
+ void test_plxs(void)
+ {
+ T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE plxs_spot_check_measure_value;
+ //spot_check_indication_test
+ bool result = push_record_to_database(plxs_spot_check_measure_value);
+ if(result == PLXS_APP_RESULT_SUCCESS)
+ {
+ ......
+ }
+ }
+ * \endcode
+ */
+T_PLXS_APP_RESULT push_record_to_database(T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE spot_check_value)
+{
+ T_PLXS_APP_RESULT ret = PLXS_APP_RESULT_SUCCESS;
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+ PROFILE_PRINT_INFO0("plxs_ push_record_to_database enter");
+ if (((plxs_racp.record_db.tail + 1) % PLXS_RACP_DATABASE_SIZE) == plxs_racp.record_db.head)
+ {
+ PROFILE_PRINT_ERROR0("push_record_to_database database full delete the oldest record");
+ T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE spot_check_value;
+ pop_record_from_database(&spot_check_value);
+ }
+ plxs_racp.record_db.records[plxs_racp.record_db.tail].plxs_spot_check_measurement_value =
+ spot_check_value;
+ plxs_racp.record_db.tail = (plxs_racp.record_db.tail + 1) % PLXS_RACP_DATABASE_SIZE;
+ plxs_racp.record_db.record_num++;
+#else
+ PROFILE_PRINT_ERROR0("plxs_ push_record_to_database not support");
+ ret = PLXS_APP_RESULT_NOT_SUPPORT;
+#endif
+ return ret;
+}
+
+/**
+ * @brief send plxs spot check measurement characteristic indication from records database
+ *
+ * @param[in] conn_id connection index
+ * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID.
+ * @param[in] index record index in database
+ * @return plxs_spot_check_measurement_value_store_indicate result
+ * @retval PLXS_APP_RESULT_SUCCESS Operation success.
+ * @retval others Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ bool plxs_report_records_task(uint8_t conn_id, T_SERVER_ID service_id)
+ {
+ if (plxs_spot_check_measurement_value_store_indicate(conn_id, service_id,plxs_report_records_flags.plxs_current_record_to_report++) == PLXS_APP_RESULT_SUCCESS)
+ {
+ PROFILE_PRINT_INFO1("plxs_report_records_task:record:%d,success",plxs_report_records_flags.plxs_current_record_to_report);
+ }
+ else
+ {
+ ret = false;
+ PROFILE_PRINT_ERROR1("plxs_report_records_task:record:%d,fail",plxs_report_records_flags.plxs_current_record_to_report);
+ }
+ }
+ * \endcode
+ */
+T_PLXS_APP_RESULT plxs_spot_check_measurement_value_store_indicate(uint8_t conn_id,
+ T_SERVER_ID service_id, uint8_t index)
+{
+ T_PLXS_APP_RESULT ret = PLXS_APP_RESULT_SUCCESS;
+ PROFILE_PRINT_INFO1("plxs_spot_check_measurement_value_store_indicate enter index = %d", index);
+ if (plxs_data_send_status_flags.report_records_indication_status_flag ==
+ PLXS_STATUS_REPORT_RECORDS_INDICATION_DOING
+ || plxs_data_send_status_flags.spot_check_indication_status_flag ==
+ PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DOING)
+ {
+ ret = PLXS_APP_RESULT_PENDING;
+ PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_store_indicate:indication procedure is doing please send data later!!");
+ return ret;
+ }
+ if (plxs_notify_indicate_flag.spot_check_measurement_indication_enable == 0)
+ {
+ ret = PLXS_APP_RESULT_CCCD_NOT_ENABLED;
+ PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_store_indicate: PLXS_APP_RESULT_CCCD_NOT_ENABLED");
+ return ret;
+ }
+ int current = (plxs_report_records_flags.plxs_record_to_report_start_index + index) %
+ PLXS_RACP_DATABASE_SIZE;
+ T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE *p_spot_check_measurement_value =
+ &plxs_racp.record_db.records[current].plxs_spot_check_measurement_value;
+ uint8_t temp_spot_check_measurement_value[sizeof(T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE)];
+ uint8_t offset = 0;
+ if (index >= plxs_racp.record_db.record_num)
+ {
+ PROFILE_PRINT_ERROR2("plxs_spot_check_measurement_value_store_indicate access overflow, index = %d,total_record_num = %d",
+ index, plxs_racp.record_db.record_num);
+ ret = PLXS_APP_RESULT_INVALID_OFFSET;
+ return ret;
+ }
+ if (current == plxs_racp.record_db.tail)
+ {
+ PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_store_indicate database empty");
+ ret = PLXS_APP_RESULT_QUEUE_NULL;
+ return ret;
+ }
+ memcpy(&temp_spot_check_measurement_value[offset], &plxs_spot_check_measurement_flags, 1);
+ offset += 1;
+ memcpy(&temp_spot_check_measurement_value[offset], &p_spot_check_measurement_value->spo2, 2);
+ offset += 2;
+ memcpy(&temp_spot_check_measurement_value[offset], &p_spot_check_measurement_value->pr, 2);
+ offset += 2;
+#if PLXS_SPOT_CHECK_MEASUREMENT_TIMESTAMP_SUPPORT
+ if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_TIMESTAMP)
+ {
+ memcpy(&temp_spot_check_measurement_value[offset], &p_spot_check_measurement_value->time, 7);
+ offset += 7;
+ }
+#endif
+
+#if PLXS_MEASUREMENT_STATE_SUPPORT
+ if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_MEASUREMENT_STATUS)
+ {
+ memcpy(&temp_spot_check_measurement_value[offset],
+ &p_spot_check_measurement_value->measurement_status, 2);
+ offset += 2;
+ }
+#endif
+
+# if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT
+ if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS)
+ {
+ memcpy(&temp_spot_check_measurement_value[offset],
+ &p_spot_check_measurement_value->device_and_sensor_status, 3);
+ offset += 3;
+ }
+#endif
+
+#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT
+ if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX)
+ {
+ memcpy(&temp_spot_check_measurement_value[offset],
+ &p_spot_check_measurement_value->pulse_amplitude_index, 2);
+ offset += 2;
+ }
+#endif
+
+ if (server_send_data(conn_id, service_id, PLXS_CHAR_SPOT_CHECK_MENSUREMENT_INDEX,
+ temp_spot_check_measurement_value, offset, GATT_PDU_TYPE_INDICATION))
+ {
+ PROFILE_PRINT_INFO0("plxs_spot_check_measurement_value_store_indicate:server_send_data and set status doing success");
+ plxs_data_send_status_flags.report_records_indication_status_flag =
+ PLXS_STATUS_REPORT_RECORDS_INDICATION_DOING;
+ }
+ else
+ {
+ ret = PLXS_APP_RESULT_FAIL;
+ PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_store_indicate:server_send_data fail");
+ plxs_data_send_status_flags.report_records_indication_status_flag =
+ PLXS_STATUS_REPORT_RECORDS_INDICATION_IDLE;
+ }
+ return ret;
+}
+#endif
+/**
+ * @brief send plxs spot check measurement characteristic indication
+ *
+ * @param[in] conn_id connection index
+ * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID.
+ * @param[in] p_spot_check_measurement_value @ref T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE
+ * @return plxs_spot_check_measurement_value_indicate result
+ * @retval PLXS_APP_RESULT_SUCCESS Operation success.
+ * @retval others Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test_plxs(void)
+ {
+ T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE plxs_spot_check_measure_value;
+ ......//plxs_spot_check_measure_value initialization
+ bool result = plxs_spot_check_measurement_value_indicate(conn_id,plxs_srv_id,&plxs_spot_check_measure_value);
+ if(result == PLXS_APP_RESULT_SUCCESS)
+ {
+ }
+ }
+ * \endcode
+ */
+#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT
+T_PLXS_APP_RESULT plxs_spot_check_measurement_value_indicate(uint8_t conn_id, uint8_t service_id,
+ T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE *p_spot_check_measurement_value)
+{
+ T_PLXS_APP_RESULT ret = PLXS_APP_RESULT_SUCCESS;
+ if (p_spot_check_measurement_value == NULL)
+ {
+ ret = PLXS_APP_RESULT_POINTER_NULL;
+ PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_indicate: PLXS_APP_RESULT_POINTER_NULL");
+ return ret;
+ }
+ if (plxs_notify_indicate_flag.spot_check_measurement_indication_enable == 0)
+ {
+ ret = PLXS_APP_RESULT_CCCD_NOT_ENABLED;
+ PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_indicate: PLXS_APP_RESULT_CCCD_NOT_ENABLED");
+ return ret;
+ }
+ PROFILE_PRINT_INFO0("plxs_spot_check_measurement_value_indicate enter");
+ if (plxs_data_send_status_flags.spot_check_indication_status_flag ==
+ PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DOING
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+ || plxs_racp.ctrl_point.op_code == PLXS_RACP_OPCODE_REPORT_RECS
+#endif
+ )
+ {
+ ret = PLXS_APP_RESULT_PENDING;
+ PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_indicate:procedure is doing please send data later!!");
+ return ret;
+ }
+ uint8_t temp_plxs_spot_check_measurement_value[sizeof(T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE)];
+ uint8_t offset = 0;
+ memcpy(&temp_plxs_spot_check_measurement_value[offset], &plxs_spot_check_measurement_flags, 1);
+ offset += 1;
+ memcpy(&temp_plxs_spot_check_measurement_value[offset], &p_spot_check_measurement_value->spo2, 2);
+ offset += 2;
+ memcpy(&temp_plxs_spot_check_measurement_value[offset], &p_spot_check_measurement_value->pr, 2);
+ offset += 2;
+
+#if PLXS_SPOT_CHECK_MEASUREMENT_TIMESTAMP_SUPPORT
+ if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_TIMESTAMP)
+ {
+ memcpy(&temp_plxs_spot_check_measurement_value[offset], &p_spot_check_measurement_value->time, 7);
+ offset += 7;
+ }
+#endif
+
+#if PLXS_MEASUREMENT_STATE_SUPPORT
+ if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_MEASUREMENT_STATUS)
+ {
+ memcpy(&temp_plxs_spot_check_measurement_value[offset],
+ &p_spot_check_measurement_value->measurement_status, 2);
+ offset += 2;
+ }
+#endif
+
+# if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT
+ if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS)
+ {
+ memcpy(&temp_plxs_spot_check_measurement_value[offset],
+ &p_spot_check_measurement_value->device_and_sensor_status, 3);
+ offset += 3;
+ }
+#endif
+
+#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT
+ if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX)
+ {
+ memcpy(&temp_plxs_spot_check_measurement_value[offset],
+ &p_spot_check_measurement_value->pulse_amplitude_index, 2);
+ offset += 2;
+ }
+#endif
+
+ if (server_send_data(conn_id, service_id, PLXS_CHAR_SPOT_CHECK_MENSUREMENT_INDEX,
+ temp_plxs_spot_check_measurement_value, offset,
+ GATT_PDU_TYPE_INDICATION))
+ {
+ PROFILE_PRINT_INFO0("plxs_spot_check_measurement_value_indicate:server_send_data and set status doing success");
+ plxs_data_send_status_flags.spot_check_indication_status_flag =
+ PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DOING;
+ }
+ else
+ {
+ ret = PLXS_APP_RESULT_FAIL;
+ PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_indicate:server_send_data fail");
+ //if send fail data may be need to be stored
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+ push_record_to_database(*p_spot_check_measurement_value);
+#endif
+ plxs_data_send_status_flags.spot_check_indication_status_flag =
+ PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_IDLE;
+ }
+ return ret;
+}
+#endif
+/**
+ * @brief send plxs continuous measurement characteristic notification
+ *
+ * @param[in] conn_id connection index
+ * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID.
+ * @param[in] plxs_continuous_measurement_value @ref T_PLXS_CONTINUOUS_MEASUREMENT_VALUE
+ * @return plxs_continuous_measurement_value_notify result
+ * @retval PLXS_APP_RESULT_SUCCESS Operation success.
+ * @retval others Operation fail.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test_plxs(void)
+ {
+ ......//plxs_continuous_measurement_value initialization
+ bool result = plxs_continuous_measurement_value_notify( conn_id, plxs_srv_id,&plxs_continuous_measurement_value);
+ if(result == PLXS_APP_RESULT_SUCCESS)
+ {
+ PROFILE_PRINT_INFO0("plxs_continuous_measurement_value_notify notify data send success!");
+ }
+ }
+ * \endcode
+ */
+#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT
+T_PLXS_APP_RESULT plxs_continuous_measurement_value_notify(uint8_t conn_id, T_SERVER_ID service_id,
+ T_PLXS_CONTINUOUS_MEASUREMENT_VALUE *p_plxs_continuous_measurement_value)
+{
+ T_PLXS_APP_RESULT ret = PLXS_APP_RESULT_SUCCESS;
+ if (p_plxs_continuous_measurement_value == NULL)
+ {
+ ret = PLXS_APP_RESULT_POINTER_NULL;
+ PROFILE_PRINT_ERROR0("plxs_continuous_measurement_value_notify:PLXS_APP_RESULT_POINTER_NULL");
+ return ret;
+ }
+ if (plxs_notify_indicate_flag.continuous_measurement_notify_enable == 0)
+ {
+ ret = PLXS_APP_RESULT_CCCD_NOT_ENABLED;
+ PROFILE_PRINT_ERROR0("plxs_continuous_measurement_value_notify: PLXS_APP_RESULT_CCCD_NOT_ENABLED");
+ return ret;
+ }
+ if (plxs_data_send_status_flags.continuous_measurement_notify_status_flag ==
+ PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DOING)
+ {
+ ret = PLXS_APP_RESULT_PENDING;
+ PROFILE_PRINT_ERROR0("plxs_continuous_measurement_value_notify:procedure is doing please send data later!!");
+ return ret;
+ }
+ uint8_t temp_plxs_continuous_measurement_value[sizeof(T_PLXS_CONTINUOUS_MEASUREMENT_VALUE)];
+ uint8_t offset = 0;
+
+ memcpy(&temp_plxs_continuous_measurement_value[offset], &plxs_continuous_measurement_flags, 1);
+ offset += 1;
+ memcpy(&temp_plxs_continuous_measurement_value[offset],
+ &p_plxs_continuous_measurement_value->spo2pr_normal.spo2, 2);
+ offset += 2;
+ memcpy(&temp_plxs_continuous_measurement_value[offset],
+ &p_plxs_continuous_measurement_value->spo2pr_normal.pr, 2);
+ offset += 2;
+#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_FAST_SUPPORT
+ if (plxs_continuous_measurement_flags & PLXS_CONTINUOUS_MEASUREMENT_FLAG_SPO2PR_FAST)
+ {
+ memcpy(&temp_plxs_continuous_measurement_value[offset],
+ &p_plxs_continuous_measurement_value->spo2pr_fast.spo2, 2);
+ offset += 2;
+ memcpy(&temp_plxs_continuous_measurement_value[offset],
+ &p_plxs_continuous_measurement_value->spo2pr_fast.pr, 2);
+ offset += 2;
+ }
+#endif
+
+#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_SLOW_SUPPORT
+ if (plxs_continuous_measurement_flags & PLXS_CONTINUOUS_MEASUREMENT_FLAG_SPO2PR_SLOW)
+ {
+ memcpy(&temp_plxs_continuous_measurement_value[offset],
+ &p_plxs_continuous_measurement_value->spo2pr_slow.spo2, 2);
+ offset += 2;
+ memcpy(&temp_plxs_continuous_measurement_value[offset],
+ &p_plxs_continuous_measurement_value->spo2pr_slow.pr, 2);
+ offset += 2;
+ }
+#endif
+
+#if PLXS_MEASUREMENT_STATE_SUPPORT
+ if (plxs_continuous_measurement_flags & PLXS_CONTINUOUS_MEASUREMENT_FLAG_MEASUREMENT_STATUS)
+ {
+ memcpy(&temp_plxs_continuous_measurement_value[offset],
+ &p_plxs_continuous_measurement_value->measurement_status, 2);
+ offset += 2;
+ }
+#endif
+
+# if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT
+ if (plxs_continuous_measurement_flags & PLXS_CONTINUOUS_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS)
+ {
+ memcpy(&temp_plxs_continuous_measurement_value[offset],
+ &p_plxs_continuous_measurement_value->device_and_sensor_status, 3);
+ offset += 3;
+ }
+#endif
+
+#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT
+ if (plxs_continuous_measurement_flags & PLXS_CONTINUOUS_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX)
+ {
+ memcpy(&temp_plxs_continuous_measurement_value[offset],
+ &p_plxs_continuous_measurement_value->pulse_amplitude_index, 2);
+ offset += 2;
+ }
+#endif
+ if (server_send_data(conn_id, service_id, PLXS_CHAR_CONTINUOUS_MEASUREMENT_INDEX,
+ temp_plxs_continuous_measurement_value, offset,
+ GATT_PDU_TYPE_NOTIFICATION))
+ {
+ PROFILE_PRINT_INFO0("plxs_continuous_measurement_value_notify:server_send_data and set status doing success");
+ plxs_data_send_status_flags.continuous_measurement_notify_status_flag =
+ PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DOING;
+
+ }
+ else
+ {
+ ret = PLXS_APP_RESULT_FAIL;
+ PROFILE_PRINT_ERROR0("plxs_continuous_measurement_value_notify:server_send_data fail");
+ plxs_data_send_status_flags.continuous_measurement_notify_status_flag =
+ PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_IDLE;
+ }
+ return ret;
+}
+#endif
+/**
+ * @brief check cccd enabled or disabled
+ *
+ * @param[in] None
+ * @return cccd check result
+ * @retval false Operation failure.
+ * @retval true Operation success.
+ */
+bool plxs_check_cccd()
+{
+ if ((0 == plxs_notify_indicate_flag.racp_indication_enable) ||
+ (0 == plxs_notify_indicate_flag.spot_check_measurement_indication_enable))
+ {
+ return false;//cccd not enabled return false
+ }
+ else
+ {
+ return true;
+ }
+}
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID of characteristic data.
+ * @param[in] attrib_index Attribute index of getting characteristic data.
+ * @param[in] offset Used for Blob Read.
+ * @param[in,out] p_length length of getting characteristic data.
+ * @param[in,out] pp_value data got from service.
+ * @return Profile procedure result
+ */
+T_APP_RESULT plxs_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ PROFILE_PRINT_INFO2("plxs_attr_read_cb attribIndex = %d offset %x", attrib_index, offset);
+ *p_length = 0;
+ static uint8_t temp_plxs_features[sizeof(T_PLXS_FEATURES_VALUE)] = {0};
+ switch (attrib_index)
+ {
+ case PLXS_CHAR_FEATURE_INDEX:
+ {
+ memcpy(&temp_plxs_features[*p_length], &plxs_features.supported_features,
+ sizeof(plxs_features.supported_features));
+ *p_length = sizeof(plxs_features.supported_features);
+#if PLXS_MEASUREMENT_STATE_SUPPORT
+ if (plxs_features.supported_features & PLXS_FEATURES_MEASUREMENT_STATUS)
+ {
+ PROFILE_PRINT_INFO1("plxs_features.measurement_status 0x%x",
+ plxs_features.measurement_status_support_bits);
+ memcpy(&temp_plxs_features[*p_length], &plxs_features.measurement_status_support_bits, 2);
+ *p_length += 2;
+ }
+#endif
+
+#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT
+ if (plxs_features.supported_features & PLXS_FEATURES_DEVICE_SENSOR_STATUS)
+ {
+ PROFILE_PRINT_INFO1("plxs_features.device_and_sensor_status 0x%x",
+ plxs_features.device_and_sensor_status_support_bits);
+ memcpy(&temp_plxs_features[*p_length], &plxs_features.device_and_sensor_status_support_bits, 3);
+ *p_length += 3;
+ }
+#endif
+ *pp_value = temp_plxs_features;
+ }
+ break;
+ default:
+ {
+ PROFILE_PRINT_ERROR1("plxs_attr_read_cb, attr not found, index=%d", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ break;
+ }
+ return cause;
+}
+
+
+/**
+ * @brief abort procedure.
+ * @param[in] None
+ * @return None
+ *
+ */
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+void plxs_abort_racp_procedure(void)
+{
+ if (plxs_racp.ctrl_point.op_code == PLXS_RACP_OPCODE_REPORT_RECS)
+ {
+ plxs_abort_by_app_flag = true;
+ }
+ else
+ {
+ PROFILE_PRINT_INFO0("plxs_abort_racp_procedure no procedure to abort by application");
+ }
+}
+
+/**
+ * @brief response report records number control point procedure result to client
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID of characteristic data.
+ * @param[in] num number of records
+ * @return report records number procedure result
+ */
+bool plxs_racp_num_response(uint8_t conn_id, T_SERVER_ID service_id, uint16_t num)
+{
+ bool ret;
+ T_PLXS_RACP temp_racp;
+ uint16_t attrib_index = PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_INDEX;
+ LE_UINT16_TO_ARRAY(temp_racp.ctrl_point.operand, num);
+ temp_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_NBR_OF_RECS_RESP;
+ temp_racp.ctrl_point.op = PLXS_RACP_OPERATOR_NULL;
+ temp_racp.cp_length = sizeof(T_PLXS_CTRL_POINT_OPCODE) + sizeof(T_PLXS_CTRL_POINT_OPERATOR)
+ + sizeof(uint16_t);
+ ret = server_send_data(conn_id, service_id, attrib_index, (uint8_t *)&temp_racp.ctrl_point,
+ temp_racp.cp_length, GATT_PDU_TYPE_INDICATION);
+ PROFILE_PRINT_INFO1("plxs_racp_num_response num of records: %d \n", num);
+ return ret;
+}
+
+/**
+ * @brief response control point procedure result to client
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID of characteristic data.
+ * @param[in] opcode opcode
+ * @param[in] rsp_code
+ * @return response control point procedure result
+ */
+bool plxs_racp_response(uint8_t conn_id, T_SERVER_ID service_id, uint8_t opcode, uint8_t rsp_code)
+{
+ bool ret;
+ T_PLXS_RACP temp_racp;
+ uint16_t attrib_index = PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_INDEX;
+
+ temp_racp.ctrl_point.operand[0] = opcode;
+ temp_racp.ctrl_point.operand[1] = rsp_code;
+ temp_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESP_CODE;
+ temp_racp.ctrl_point.op = PLXS_RACP_OPERATOR_NULL;
+ temp_racp.cp_length = sizeof(T_PLXS_CTRL_POINT_OPCODE) + sizeof(T_PLXS_CTRL_POINT_OPERATOR)
+ + sizeof(T_PLXS_CTRL_POINT_OPCODE) + sizeof(T_PLXS_CTRL_POINT_RESP_CODES);
+
+ // send indication to client
+ ret = server_send_data(conn_id, service_id, attrib_index, (uint8_t *)&temp_racp.ctrl_point,
+ temp_racp.cp_length, GATT_PDU_TYPE_INDICATION);
+ PROFILE_PRINT_INFO1("plxs_racp_response code value: %d \n", rsp_code);
+ return ret;
+}
+
+/**
+ * @brief delete spot check measurement records from database
+ *
+ * @param[in] None
+ * @return delete result
+ * @retval true success
+ * <b>Example usage</b>
+ * \code{.c}
+ void test_plxs(void)
+ {
+ delete_all_records_from_database();
+ }
+ * \endcode
+ */
+bool delete_all_records_from_database()
+{
+ bool ret = true;
+ plxs_racp.record_db.tail = plxs_racp.record_db.head;
+ plxs_racp.record_db.record_num = 0;
+ return ret;
+}
+
+/**
+ * @brief check if report records procedure has complete,if not complete continuous report records
+ *
+ * @param[in] conn_id connection index
+ * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID.
+ * @return check result
+ * @retval false Operation failure.
+ * @retval true Operation success.
+ */
+bool plxs_check_records_report_complete(uint8_t conn_id, T_SERVER_ID service_id)
+{
+
+ if (plxs_racp.ctrl_point.op_code == PLXS_RACP_OPCODE_REPORT_RECS)
+ {
+ PROFILE_PRINT_INFO1("plxs_records_to_report_offset:%d",
+ plxs_report_records_flags.plxs_records_to_report_offset);
+ plxs_report_records_flags.plxs_records_to_report_offset =
+ plxs_report_records_flags.plxs_current_record_to_report;
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+/**
+ * @brief report spot check measurement value stored in database to client
+ *
+ * @param[in] conn_id connection index
+ * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID.
+ * @return plxs report records task result
+ * @retval false Operation failure.
+ * @retval true Operation success.
+ */
+bool plxs_report_records_task(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ bool ret = true;
+ if (plxs_abort_flag == true)
+ {
+ uint8_t opcode = PLXS_RACP_OPCODE_ABORT_OPERATION;
+ PROFILE_PRINT_INFO2("plxs_report_records_task request opcode = %x,response code value = %x", opcode,
+ PLXS_RACP_RESP_SUCCESS);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp_response(conn_id, service_id, opcode, PLXS_RACP_RESP_SUCCESS);
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ plxs_abort_flag = false;
+ plxs_report_records_flags.plxs_send_data_end_flag = true;
+
+ return ret;
+ }
+ if (plxs_abort_by_app_flag == true)
+ {
+ PROFILE_PRINT_INFO2("plxs_report_records_task request opcode = %x,response code value = %x",
+ plxs_racp.ctrl_point.op_code, PLXS_RACP_RESP_PROC_NOT_COMPLETED);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code,
+ PLXS_RACP_RESP_PROC_NOT_COMPLETED);
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ plxs_abort_by_app_flag = false;
+ plxs_report_records_flags.plxs_send_data_end_flag = true;
+ return ret;
+ }
+ if (plxs_report_records_flags.plxs_send_data_end_flag == true)
+ {
+ PROFILE_PRINT_INFO0("plxs_report_records_task plxs_send_data_end_flag== true");
+ //plxs_send_data_end_flag = false;
+ return ret;
+ }
+ if ((plxs_report_records_flags.plxs_current_record_to_report >=
+ plxs_report_records_flags.plxs_num_records_to_report) &&
+ plxs_racp.ctrl_point.op_code == PLXS_RACP_OPCODE_REPORT_RECS)
+ {
+ PROFILE_PRINT_INFO0("plxs_report_records_task all records send success");
+ plxs_report_records_flags.plxs_send_data_end_flag = true;
+ plxs_report_records_flags.plxs_current_record_to_report = 0;
+ //plxs_records_to_report_offset = 0;
+ //plxs_record_to_report_start_index = 0;
+ plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, PLXS_RACP_RESP_SUCCESS);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ return true;
+ }
+ PROFILE_PRINT_INFO3("plxs_report_records_task current = %d, total = %d,start_index = %d ",
+ plxs_report_records_flags.plxs_current_record_to_report,
+ plxs_report_records_flags.plxs_num_records_to_report,
+ plxs_report_records_flags.plxs_record_to_report_start_index);
+
+ if (plxs_spot_check_measurement_value_store_indicate(conn_id, service_id,
+ plxs_report_records_flags.plxs_current_record_to_report++) == PLXS_APP_RESULT_SUCCESS)
+ {
+ PROFILE_PRINT_INFO1("plxs_report_records_task:record:%d,success",
+ plxs_report_records_flags.plxs_current_record_to_report);
+ }
+ else
+ {
+ ret = false;
+ PROFILE_PRINT_ERROR1("plxs_report_records_task:record:%d,fail",
+ plxs_report_records_flags.plxs_current_record_to_report);
+ }
+ return ret;
+}
+
+/**
+ * @brief plxs report records
+ *
+ * @param[in] conn_id conn_id
+ * @param[in] Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @return None
+ *
+ */
+void plxs_report_records(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ PROFILE_PRINT_INFO2(" plxs_report_records opcode = %x,operator = %x",
+ plxs_racp.ctrl_point.op_code, plxs_racp.ctrl_point.op);
+ if (plxs_racp.ctrl_point.op >= 7)
+ {
+ PROFILE_PRINT_ERROR0("plxs_report_records PLXS_RACP_RESP_INVALID_OPERATOR");
+ plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code,
+ PLXS_RACP_RESP_OPERATOR_NOT_SUPPORTED);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ return;
+ }
+ if (plxs_racp.ctrl_point.op != PLXS_RACP_OPERATOR_ALL_RECS)
+ {
+ PROFILE_PRINT_ERROR0("plxs_report_records PLXS_RACP_RESP_OPERATOR_NOT_SUPPORTED");
+ plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code,
+ PLXS_RACP_RESP_INVALID_OPERATOR);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ return;
+ }
+ if (plxs_racp.record_db.record_num == 0)
+ {
+ PROFILE_PRINT_ERROR0("plxs_report_records PLXS_RACP_RESP_NO_RECS_FOUND");
+ plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, PLXS_RACP_RESP_NO_RECS_FOUND);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ return ;
+ }
+ else
+ {
+
+ plxs_report_records_flags.plxs_record_to_report_start_index = plxs_racp.record_db.head;
+ plxs_report_records_flags.plxs_current_record_to_report =
+ plxs_report_records_flags.plxs_records_to_report_offset;
+ plxs_report_records_flags.plxs_send_data_end_flag = false;
+ plxs_report_records_flags.plxs_num_records_to_report = plxs_racp.record_db.record_num;
+ if (plxs_report_records_flags.plxs_records_to_report_offset >=
+ plxs_report_records_flags.plxs_num_records_to_report)
+ {
+ PROFILE_PRINT_ERROR0("plxs_report_records after first report success no records to be report");
+ plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, PLXS_RACP_RESP_NO_RECS_FOUND);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ return ;
+ }
+ if (false == plxs_report_records_task(conn_id, service_id))
+ {
+ PROFILE_PRINT_ERROR0("plxs_report_records_task false");
+ plxs_racp_response(conn_id, service_id, PLXS_RACP_OPCODE_REPORT_RECS,
+ PLXS_RACP_RESP_PROC_NOT_COMPLETED);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ plxs_report_records_flags.plxs_send_data_end_flag = true;
+ plxs_report_records_flags.plxs_current_record_to_report =
+ plxs_report_records_flags.plxs_records_to_report_offset;
+ };
+ }
+}
+
+/**
+ * @brief plxs_report_num_of_records
+ *
+ * @param[in] conn_id conn_id
+ * @param[in] Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @return None
+ *
+ */
+void plxs_report_num_of_records(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ PROFILE_PRINT_INFO2(" plxs_report_num_of_records opcode = %x,operator = %x",
+ plxs_racp.ctrl_point.op_code, plxs_racp.ctrl_point.op);
+ if (plxs_racp.ctrl_point.op >= 7)
+ {
+ plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code,
+ PLXS_RACP_RESP_OPERATOR_NOT_SUPPORTED);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ return;
+ }
+ if (plxs_racp.ctrl_point.op != PLXS_RACP_OPERATOR_ALL_RECS)
+ {
+ plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code,
+ PLXS_RACP_RESP_INVALID_OPERATOR);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ return;
+ }
+ uint16_t num_of_records;
+ num_of_records = plxs_racp.record_db.record_num;
+ plxs_racp_num_response(conn_id, service_id, num_of_records);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+}
+
+/**
+ * @brief plxs delete records
+ *
+ * @param[in] conn_id conn_id
+ * @param[in] Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @return None
+ *
+ */
+void plxs_delete_records(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ PROFILE_PRINT_INFO2(" plxs_delete_records opcode = %x,operator = %x",
+ plxs_racp.ctrl_point.op_code, plxs_racp.ctrl_point.op);
+ if (plxs_racp.ctrl_point.op >= 7)
+ {
+ plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code,
+ PLXS_RACP_RESP_OPERATOR_NOT_SUPPORTED);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ return;
+ }
+ if (plxs_racp.ctrl_point.op != PLXS_RACP_OPERATOR_ALL_RECS)
+ {
+
+ plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code,
+ PLXS_RACP_RESP_INVALID_OPERATOR);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ return;
+ }
+ delete_all_records_from_database();
+ plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, PLXS_RACP_RESP_SUCCESS);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+}
+
+/**
+ * @brief plxs_ctr_pnt_write_ind_post_proc
+ *
+ * @param[in] conn_id conn_id
+ * @param[in] Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @param[in] attrib_index attribute index
+ * @param[in] write_length write value length
+ * @param[in] p_value write value
+ * @return None
+ *
+ */
+static void plxs_ctr_pnt_write_ind_post_proc(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index, uint16_t write_length, uint8_t *p_value)
+{
+ if (write_length > 2)
+ {
+ PROFILE_PRINT_ERROR1("plxs_ctr_pnt_write_ind_post_proc invalid write length, error: operand = 0x%x",
+ p_value[2]);
+ plxs_racp_response(conn_id, service_id, p_value[0], PLXS_RACP_RESP_OPERAND_NOT_SUPPORTED);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ return;
+ }
+ PROFILE_PRINT_INFO4("plxs_ctr_pnt_write_ind_post_proc,opcode = 0x%x,operator = 0x%x,operand = 0x%x,write_length = 0x%x",
+ p_value[0], p_value[1], p_value[2], write_length);
+ if (p_value[0] != PLXS_RACP_OPCODE_ABORT_OPERATION)
+ {
+ memset(&plxs_racp.ctrl_point, 0, sizeof(T_PLXS_CONTROL_POINT));
+ memcpy(&plxs_racp.ctrl_point, p_value, write_length);
+ plxs_racp.cp_length = write_length;
+ switch (plxs_racp.ctrl_point.op_code)
+ {
+ case PLXS_RACP_OPCODE_REPORT_NBR_OF_RECS:
+ {
+ PROFILE_PRINT_INFO1("plxs_report_num_of_records operator %d", plxs_racp.ctrl_point.op);
+ plxs_report_num_of_records(conn_id, service_id);
+ }
+ break;
+ case PLXS_RACP_OPCODE_REPORT_RECS:
+ {
+ PROFILE_PRINT_INFO1("plxs_report_records operator %d", plxs_racp.ctrl_point.op);
+ plxs_report_records(conn_id, service_id);
+ }
+ break;
+ case PLXS_RACP_OPCODE_DELETE_RECS:
+ {
+ plxs_delete_records(conn_id, service_id);
+ }
+ break;
+ default:
+ {
+ PROFILE_PRINT_INFO0("plxs_ctr_pnt_write_ind_post_proc PLXS_RACP_RESP_OPCODE_NOT_SUPPORTED");
+ plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code,
+ PLXS_RACP_RESP_OPCODE_NOT_SUPPORTED);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ }
+ break;
+ }
+ }
+ else
+ {
+ if (p_value[1] >= 7)
+ {
+ plxs_racp_response(conn_id, service_id, p_value[0], PLXS_RACP_RESP_OPERATOR_NOT_SUPPORTED);
+ /*in this case if abort fail,means that procedure did't end ,and shouldn't set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ //plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ return;
+ }
+ if (p_value[1] != PLXS_RACP_OPERATOR_NULL)
+ {
+ plxs_racp_response(conn_id, service_id, p_value[0], PLXS_RACP_RESP_INVALID_OPERATOR);
+ /*in this case if abort fail,means that procedure did't end ,and shouldn't set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ //plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ return;
+ }
+ if (plxs_racp.ctrl_point.op_code == PLXS_RACP_OPCODE_REPORT_RECS)
+ {
+ //if procedure is doing set plxs_abort_flag is true
+ plxs_abort_flag = true;
+ }
+ else
+ {
+ PROFILE_PRINT_INFO0("plxs_ctr_pnt_write_ind_post_proc PLXS_RACP_OPCODE_ABORT_OPERATION SUCCESS");
+ plxs_racp_response(conn_id, service_id, PLXS_RACP_OPCODE_ABORT_OPERATION, PLXS_RACP_RESP_SUCCESS);
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief clear flags if procedure fail or disconnect
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+ {
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))&& (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+ plxs_flags_clear();//when disconnect clear plxs flags
+ le_adv_start();
+ }
+ break;
+ }
+ }
+ * \endcode
+ */
+void plxs_flags_clear()
+{
+ PROFILE_PRINT_ERROR0("plxs_flags_clear");
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+ /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/
+ plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED;
+ plxs_report_records_flags.plxs_send_data_end_flag = true;
+ plxs_report_records_flags.plxs_current_record_to_report = 0;
+ plxs_abort_flag = false;
+ plxs_abort_by_app_flag = false;
+ if (plxs_report_records_flags.plxs_records_to_report_offset >=
+ plxs_report_records_flags.plxs_num_records_to_report)
+ {
+ plxs_report_records_flags.plxs_records_to_report_offset = 0;
+ }
+#endif
+ plxs_data_send_status_flags.continuous_measurement_notify_status_flag =
+ PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_IDLE;
+ plxs_data_send_status_flags.report_records_indication_status_flag =
+ PLXS_STATUS_REPORT_RECORDS_INDICATION_IDLE;
+ plxs_data_send_status_flags.spot_check_indication_status_flag =
+ PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_IDLE;
+}
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID to be written.
+ * @param[in] attrib_index Attribute index of characteristic.
+ * @param[in] write_type @ref T_WRITE_TYPE
+ * @param[in] length Length of value to be written.
+ * @param[in] p_value Value to be written.
+ * @param[in] p_write_ind_post_proc @ref P_FUN_WRITE_IND_POST_PROC
+ * @return Profile procedure result
+ */
+T_APP_RESULT plxs_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value,
+ P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ PROFILE_PRINT_INFO2("plxs_attr_write_cb: attrib_index %d, length 0x%x ", attrib_index, length);
+ switch (attrib_index)
+ {
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+ case PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_INDEX :
+ {
+ /* Attribute value has variable size, make sure written value size is valid. */
+ if ((length > sizeof(T_PLXS_CONTROL_POINT)) || (p_value == NULL))
+ {
+ PROFILE_PRINT_INFO0("plxs_attr_write_cb APP_RESULT_INVALID_VALUE_SIZE");
+ cause = APP_RESULT_INVALID_VALUE_SIZE;
+ }/* Make sure Control Point is not "Process already in progress". */
+ else if (PLXS_RACP_OPERATION_ACTIVE(plxs_racp.ctrl_point.op_code) &&
+ (p_value[0] != PLXS_RACP_OPCODE_ABORT_OPERATION))
+ {
+ PROFILE_PRINT_INFO0("plxs_attr_write_cb PLXS_ERR_PROC_ALREADY_IN_PROGRESS");
+ cause = (T_APP_RESULT)(ATT_ERR | PLXS_ERR_PROC_ALREADY_IN_PROGRESS);
+ } /* Make sure Control Point is configured indication enable. */
+ else if (!plxs_check_cccd())
+ {
+ PROFILE_PRINT_INFO0("plxs_attr_write_cb PLXS_ERR_CCCD_IMPROPERLY_CONFIGURED");
+ cause = (T_APP_RESULT)(ATT_ERR | PLXS_ERR_CCCD_IMPROPERLY_CONFIGURED);
+ }/*Process already in progress when abort, but abort operator not right*/
+ else if (PLXS_RACP_OPERATION_ACTIVE(plxs_racp.ctrl_point.op_code) &&
+ (p_value[0] == PLXS_RACP_OPCODE_ABORT_OPERATION) &&
+ (p_value[1] != PLXS_RACP_OPERATOR_NULL))
+ {
+ PROFILE_PRINT_INFO0("plxs_attr_write_cb abort operator invalid");
+ cause = (T_APP_RESULT)(ATT_ERR | ATT_ERR_INVALID_VALUE);
+ }
+ else/** handle RACP request after sending write response */
+ {
+ PROFILE_PRINT_INFO2("plxs_attr_write_cb opcode: old = %d, new = %d\n", plxs_racp.ctrl_point.op_code,
+ p_value[0]);
+ *p_write_ind_post_proc = plxs_ctr_pnt_write_ind_post_proc;
+ }
+ }
+ break;
+#endif
+ default:
+ {
+ PROFILE_PRINT_ERROR1("plxs_attr_write_cb attribIndex %d not found", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ break;
+ }
+ return cause;
+}
+/**
+ * @brief plxs check report data send procedure to enable flow control of notification or indication
+ * @param[in] conn_id connection index
+ * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID.
+ * @param[in] attribute_index attribute_index
+ * <b>Example usage</b>
+ * \code{.c}
+ T_APP_RESULT app_handle_profile_message(T_SERVER_ID service_id, void *p_data)
+ {
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_para = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_para->eventId)
+ {
+ ......
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ ......
+ else if (p_para->event_data.send_data_result.service_id == plxs_srv_id)
+ {
+ uint8_t conn_id = p_para->event_data.send_data_result.conn_id;
+ if (p_para->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ plxs_check_report_data_send_procedure(conn_id, plxs_srv_id,p_para->event_data.send_data_result.attrib_idx);
+ }
+ else
+ {
+ APP_PRINT_ERROR1("PROFILE_EVT_SEND_DATA_COMPLETE failed,cause %x", p_para->event_data.send_data_result.cause);
+ }
+ }
+ break;
+ }
+ }
+ }
+ * \endcode
+ */
+void plxs_check_report_data_send_procedure(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attribute_index)
+{
+#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT
+ if (attribute_index == PLXS_CHAR_CONTINUOUS_MEASUREMENT_INDEX &&
+ plxs_data_send_status_flags.continuous_measurement_notify_status_flag ==
+ PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DOING)
+ {
+ PROFILE_PRINT_INFO0("PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DONE");
+ plxs_data_send_status_flags.continuous_measurement_notify_status_flag =
+ PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DONE;
+ }
+#endif
+#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT
+ if (attribute_index == PLXS_CHAR_SPOT_CHECK_MENSUREMENT_INDEX &&
+ plxs_data_send_status_flags.spot_check_indication_status_flag ==
+ PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DOING)
+ {
+ PROFILE_PRINT_INFO0("PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DONE");
+ plxs_data_send_status_flags.spot_check_indication_status_flag =
+ PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DONE;
+ }
+#endif
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+ if (attribute_index == PLXS_CHAR_SPOT_CHECK_MENSUREMENT_INDEX &&
+ plxs_data_send_status_flags.report_records_indication_status_flag ==
+ PLXS_STATUS_REPORT_RECORDS_INDICATION_DOING)
+ {
+ PROFILE_PRINT_INFO0("PLXS_STATUS_REPORT_RECORDS_INDICATION_DONE");
+ plxs_data_send_status_flags.report_records_indication_status_flag =
+ PLXS_STATUS_REPORT_RECORDS_INDICATION_DONE;
+ if (plxs_check_records_report_complete(conn_id, service_id))
+ {
+ APP_PRINT_INFO0("records report complete or condition not allow");
+ }
+ else
+ {
+ if (false == plxs_report_records_task(conn_id, service_id))
+ {
+ PROFILE_PRINT_ERROR0("plxs_report_records_task send fail");
+ plxs_racp_response(conn_id, service_id, PLXS_RACP_OPCODE_REPORT_RECS,
+ PLXS_RACP_RESP_PROC_NOT_COMPLETED);
+ plxs_flags_clear();
+ };
+ }
+ }
+#endif
+}
+/**
+ * @brief plxs_get_data_send_status
+ *
+ * @param[in] conn_id conn_id
+ * @param[in] Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @return plxs data send status
+ * @retval data send status @ref T_PLXS_DATA_SEND_STATUS_FLAGS
+ */
+T_PLXS_DATA_SEND_STATUS_FLAGS plxs_get_data_send_status(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ return plxs_data_send_status_flags;
+}
+/**
+ * @brief plxs_set_data_send_status
+ *
+ * @param[in] conn_id conn_id
+ * @param[in] Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @param[in] data_send_status @ref T_PLXS_DATA_SEND_STATUS_FLAGS
+ * @return None
+ */
+void plxs_set_data_send_status(uint8_t conn_id, T_SERVER_ID service_id,
+ T_PLXS_DATA_SEND_STATUS_FLAGS data_send_status)
+{
+ plxs_data_send_status_flags = data_send_status;
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param[in] index Attribute index of characteristic data.
+ * @param[in] ccc_bits CCCD bits from stack.
+ * @return None
+ */
+void plxs_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ PROFILE_PRINT_INFO1("plxs_cccd_update_cb index = %d ", index);
+ T_PLXS_CALLBACK_DATA plxs_upstream_msg;
+ bool is_handled = false;
+ plxs_upstream_msg.conn_id = conn_id;
+ plxs_upstream_msg.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ switch (index)
+ {
+#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT
+ case PLXS_CHAR_CONTINUOUS_MEASUREMENT_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ plxs_notify_indicate_flag.continuous_measurement_notify_enable = 1;
+ plxs_upstream_msg.msg_data.notify_indicate_index = PLXS_CONTINUOUS_MEASUREMENT_NOTIFY_ENABLE;
+ PROFILE_PRINT_INFO1("PLXS_CHAR_CONTINUOUS_MEASUREMENT_CCCD notify enable index = %d",
+ PLXS_CHAR_CONTINUOUS_MEASUREMENT_CCCD_INDEX);
+ }
+ else
+ {
+ plxs_notify_indicate_flag.continuous_measurement_notify_enable = 0;
+ plxs_upstream_msg.msg_data.notify_indicate_index = PLXS_CONTINUOUS_MEASUREMENT_NOTIFY_DISABLE;
+ PROFILE_PRINT_INFO1("PLXS_CHAR_CONTINUOUS_MEASUREMENT_CCCD notify disable index = %d",
+ PLXS_CHAR_CONTINUOUS_MEASUREMENT_CCCD_INDEX);
+ }
+ is_handled = true;
+ }
+ break;
+#endif
+
+#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT
+ case PLXS_CHAR_SPOT_CHECK_MENSUREMENT_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE)
+ {
+ plxs_notify_indicate_flag.spot_check_measurement_indication_enable = 1;
+ plxs_upstream_msg.msg_data.notify_indicate_index = PLXS_SPOT_CHECK_MEASUREMENT_INDICATION_ENABLE;
+ PROFILE_PRINT_INFO1("PLXS_CHAR_SPOT_CHECK_MENSUREMENT_CCCD indication enable index = %d",
+ PLXS_CHAR_SPOT_CHECK_MENSUREMENT_CCCD_INDEX);
+ }
+ else
+ {
+ plxs_notify_indicate_flag.spot_check_measurement_indication_enable = 0;
+ plxs_upstream_msg.msg_data.notify_indicate_index = PLXS_SPOT_CHECK_MEASUREMENT_INDICATION_DISABLE;
+ PROFILE_PRINT_INFO1("PLXS_CHAR_SPOT_CHECK_MENSUREMENT_CCCD indication disable index = %d",
+ PLXS_CHAR_SPOT_CHECK_MENSUREMENT_CCCD_INDEX);
+ }
+ is_handled = true;
+ }
+ break;
+#endif
+
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+ case PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE)
+ {
+ plxs_notify_indicate_flag.racp_indication_enable = 1;
+ plxs_upstream_msg.msg_data.notify_indicate_index = PLXS_RACP_INDICATION_ENABLE;
+ PROFILE_PRINT_INFO1("PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_CCCD indication enable index = %d",
+ PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_CCCD_INDEX);
+ }
+ else
+ {
+ plxs_notify_indicate_flag.racp_indication_enable = 0;
+ plxs_upstream_msg.msg_data.notify_indicate_index = PLXS_RACP_INDICATION_DISABLE;
+ PROFILE_PRINT_INFO1("PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_CCCD indication disable index = %d",
+ PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_CCCD_INDEX);
+ }
+ is_handled = true;
+ }
+ break;
+#endif
+ default:
+ {
+ PROFILE_PRINT_ERROR1("plxs_cccd_update_cb index = %d not found", index);
+ }
+ break;
+ }
+ /* Notify Application. */
+ if (pfn_plxs_cb && (is_handled == true))
+ {
+ pfn_plxs_cb(service_id, (void *)&plxs_upstream_msg);
+ }
+}
+/**
+ * @brief plx Profile Service Callbacks.
+ */
+const T_FUN_GATT_SERVICE_CBS plxs_cbs =
+{
+ plxs_attr_read_cb,
+ plxs_attr_write_cb,
+ plxs_cccd_update_cb
+};
+
+/**
+ * @brief Add PLX service to the BLE stack database.
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init()
+ {
+ server_init(1);
+ plxs_srv_id = plxs_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID plxs_add_service(void *p_func)
+{
+ plxs_flags_init();
+ T_SERVER_ID service_id = 0xff;
+#if (PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT || PLXS_CONTINUOUS_MEASUREMENT_SUPPORT)
+ {
+ if (false == server_add_service(&service_id,
+ (uint8_t *)plxs_att_tbl,
+ sizeof(plxs_att_tbl),
+ plxs_cbs))
+ {
+ PROFILE_PRINT_ERROR1("plxs_add_service:service_id %d", service_id);
+ service_id = 0xff;
+ return service_id;
+ }
+#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT
+ plxs_racp.record_db.record_num = 0;
+ plxs_racp.record_db.head = 0;
+ plxs_racp.record_db.tail = 0;
+ plxs_racp.cp_length = 0;
+#endif
+ pfn_plxs_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+ }
+#else
+ {
+ PROFILE_PRINT_ERROR0("SPOT_CHECK_MEASUREMENT and CONTINUOUS_MEASUREMENT Mandatory to support at least one ");
+ service_id = 0xff;
+ return service_id;
+ }
+#endif
+}
diff --git a/src/ble/profile/server/rscs.c b/src/ble/profile/server/rscs.c
new file mode 100644
index 0000000..5e8a2f5
--- /dev/null
+++ b/src/ble/profile/server/rscs.c
@@ -0,0 +1,1012 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rscs.c
+* @brief RSC service source file.
+* @details Interfaces to get and put rsc characteristics value and rsc control point procedure.
+* @author ethan_su
+* @date 2017-10-10
+* @version v1.0
+*********************************************************************************************************
+*/
+#include "trace.h"
+#include <string.h>
+#include "gatt.h"
+#include "rscs.h"
+
+#define GATT_UUID_RSC 0x1814
+#define GATT_UUID_CHAR_RSCS_MEASUREMENT 0x2A53
+#define GATT_UUID_CHAR_RSCS_FEATURE 0x2A54
+#define GATT_UUID_CHAR_SC_CONTROL_POINT 0x2A55
+#define GATT_UUID_CHAR_SENSOR_LOCATION 0x2A5D
+
+
+#define RSCS_MULTIPLE_SENSOR_LOCATIONS_SUPPORT
+#define RSCS_SC_CONTROL_POINT_SUPPORT
+/** @brief Index of each characteristic in RSC service database. */
+#define GATT_SVC_RSCS_MEASUREMENT_INDEX 2
+#define GATT_SVC_RSCS_FEATURE_INDEX 5
+#define GATT_SVC_RSCS_SENS_LOC_INDEX 7
+#define GATT_SVC_RSCS_CTL_PNT_INDEX 9
+#define GATT_SVC_RSCS_MEAS_CCCD_INDEX (GATT_SVC_RSCS_MEASUREMENT_INDEX + 1)
+#define GATT_SVC_RSCS_CTL_PNT_CCCD_INDEX (GATT_SVC_RSCS_CTL_PNT_INDEX + 1)
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+typedef struct
+{
+ uint8_t rsc_measurement_notify_enable: 1;
+ uint8_t sc_cp_indicate_enable: 1;
+ uint8_t rfu: 6;
+} RSCS_NOTIFY_INDICATE_FLAG;
+
+/** @brief Judge RSC Control Point operation is available or not. */
+#define RSCS_CTL_PNT_OPERATE_ACTIVE(x) \
+ (((x >= RSCS_CP_OPCODE_SET_CUMULATIVE) && \
+ (x <= RSCS_CP_OPCODE_REQ_SENS_LOC_LIST)) || \
+ x == RSCS_CP_OPCODE_RSP_CODE )
+
+/**< RSC measurement data. */
+static T_RSCS_MEASUREMENT rscs_measurement;
+/**< RSC feature that RSC service supported, can be configured by user. */
+static uint16_t rscs_feature;
+/**< RSC current sensor location, where the RSC sensor located. */
+static uint8_t rscs_cur_sens_location;
+/**< RSC supported sensor location list, can be configured by user. */
+static uint16_t rscs_sens_loc_list;
+/**< RSC control point data. */
+static T_RSCS_CONTROL_POINT rscs_control_point = {0};
+/**< RSC control point indication enable flag. */
+static RSCS_NOTIFY_INDICATE_FLAG rscs_notify_indicate_flag = {0};
+/**< Function pointer used to send event to application from RSC profile. Initiated in rscs_add_service. */
+static P_FUN_SERVER_GENERAL_CB pfn_rscs_cb = NULL;
+
+/**< @brief profile/service definition. */
+const T_ATTRIB_APPL rscs_attr_tbl[] =
+{
+ /*-------------------------- RSC Service ---------------------------*/
+ /* <<Primary Service>>, .. Index 0 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_RSC), /* service UUID */
+ HI_WORD(GATT_UUID_RSC)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. Index 1 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /*--- RSC Measurement characteristic value --- Index 2 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_RSCS_MEASUREMENT),
+ HI_WORD(GATT_UUID_CHAR_RSCS_MEASUREMENT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_NONE /* wPermissions */
+ },
+ /* client characteristic configuration Index 3 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* wFlags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. Index 4 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /*--- RSC Features characteristic value --- Index 5 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_RSCS_FEATURE),
+ HI_WORD(GATT_UUID_CHAR_RSCS_FEATURE),
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ }
+
+#ifdef RSCS_MULTIPLE_SENSOR_LOCATIONS_SUPPORT
+ ,
+ /* <<Characteristic>>, .. Index 6 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /*--- RSC sensor location characteristic value --- Index 7 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_SENSOR_LOCATION),
+ HI_WORD(GATT_UUID_CHAR_SENSOR_LOCATION)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ /* wPermissions */
+ }
+#endif
+
+#ifdef RSCS_SC_CONTROL_POINT_SUPPORT
+ ,
+ /* <<Characteristic>>, .. Index 8 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_WRITE | /* characteristic properties */
+ GATT_CHAR_PROP_INDICATE)
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /*--- RSC SC Control Point value --- Index 9 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_SC_CONTROL_POINT),
+ HI_WORD(GATT_UUID_CHAR_SC_CONTROL_POINT)
+ },
+ 0, /* bValueLen, 0 : variable length */
+ NULL,
+ GATT_PERM_WRITE /* wPermissions */
+ },
+ /* client characteristic configuration Index 10 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* wFlags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ }
+#endif
+};
+/**< @brief RSC service size definition. */
+const int32_t rscs_attr_tbl_size = sizeof(rscs_attr_tbl);
+
+/**
+ * @brief Set a Running Speed and Cadence Service parameter.
+ *
+ * NOTE: You can call this function with a Running Speed and Cadence Service parameter type and it will set the
+ * Running Speed and Cadence Service parameter. Running Speed and Cadence Service parameters are defined
+ * in @ref T_RSCS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Running Speed and Cadence Service parameter type: @ref T_RSCS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint32_t total_distance = p_parse_value->dw_param[0];
+ bool op_result;
+
+ op_result = rscs_set_parameter(RSCS_PARAM_TOTALDISTANCE, 4, (uint8_t*)&total_distance);
+
+ if ( op_result )
+ {
+ rscs_get_parameter( RSCS_PARAM_TOTALDISTANCE, &total_distance );
+ data_uart_print("set total_distance = %d\r\n", total_distance);
+ }
+ else
+ {
+ data_uart_print("rscs_set_parameter total_distance failed\r\n");
+ }
+ }
+ * \endcode
+ */
+bool rscs_set_parameter(T_RSCS_PARAM_TYPE param_type, uint8_t len, void *p_value)
+{
+ bool ret = true;
+ uint8_t inc_flag = rscs_measurement.value[0];
+
+ switch (param_type)
+ {
+ default:
+ ret = false;
+ break;
+ case RSCS_PARAM_CSCS_FEATURE:
+ memcpy(&rscs_feature, p_value, 2);
+ break;
+ case RSCS_PARAM_INC_FLAG:
+ rscs_measurement.value[0] = *(uint8_t *)p_value;
+ inc_flag = rscs_measurement.value[0];
+ rscs_measurement.cur_length = 4;
+ if (inc_flag & RSCS_INC_STRIDE_LENGTH_MASK)
+ {
+ rscs_measurement.cur_length += 2;
+ }
+ if (inc_flag & RSCS_INC_TOTAL_DISTANCE_MASK)
+ {
+ rscs_measurement.cur_length += 4;
+ }
+ break;
+ case RSCS_PARAM_SPEED:
+ LE_UINT16_TO_ARRAY(rscs_measurement.value + 1, *(uint16_t *)p_value);
+ break;
+ case RSCS_PARAM_CADENCE:
+ rscs_measurement.value[3] = *(uint8_t *)p_value;
+ break;
+ case RSCS_PARAM_STRIDE_LENGTH:
+ if (inc_flag & RSCS_INC_STRIDE_LENGTH_MASK)
+ {
+ LE_UINT16_TO_ARRAY(rscs_measurement.value + 4, *(uint16_t *)p_value) ;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case RSCS_PARAM_TOTALDISTANCE:
+ if (inc_flag & RSCS_INC_TOTAL_DISTANCE_MASK)
+ {
+ if (inc_flag & RSCS_INC_STRIDE_LENGTH_MASK)
+ {
+ LE_UINT32_TO_ARRAY(rscs_measurement.value + 6, *(uint32_t *)p_value);
+ }
+ else
+ {
+ LE_UINT32_TO_ARRAY(rscs_measurement.value + 4, *(uint32_t *)p_value);
+ }
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case RSCS_PARAM_SENSOR_LOC:
+ rscs_cur_sens_location = *(uint8_t *)p_value;
+ break;
+ case RSCS_PARAM_CTL_PNT_PROG_CLR:
+ rscs_control_point.value[0] = RSCS_CP_OPCODE_RESERVED;
+ break;
+ }
+
+ if (!ret)
+ {
+ PROFILE_PRINT_INFO0("rscs parameter set failed\n");
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Get a Running Speed and Cadence Service parameter.
+ *
+ * NOTE: You can call this function with a Running Speed and Cadence Service parameter type and it will get the
+ * parameter. Running Speed and Cadence Service parameters are defined in @ref T_RSCS_PARAM_TYPE.
+ *
+ * @param[in] param_type Running Speed and Cadence Service parameter type: @ref T_RSCS_PARAM_TYPE
+ * @param[in] p_value Pointer to data to read.
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t bFlag;
+
+ rscs_get_parameter(RSCS_PARAM_INC_FLAG, &bFlag);
+ }
+ * \endcode
+ */
+bool rscs_get_parameter(T_RSCS_PARAM_TYPE param_type, void *p_value)
+{
+ bool ret = true;
+ uint8_t inc_flag = rscs_measurement.value[0];
+
+ switch (param_type)
+ {
+ default:
+ ret = false;
+ break;
+ case RSCS_PARAM_INC_FLAG:
+ *(uint8_t *)p_value = rscs_measurement.value[0];
+ break;
+ case RSCS_PARAM_SPEED:
+ LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, rscs_measurement.value + 1);
+ break;
+ case RSCS_PARAM_CADENCE:
+ *(uint8_t *)p_value = rscs_measurement.value[3];
+ break;
+ case RSCS_PARAM_STRIDE_LENGTH:
+ if (inc_flag & RSCS_INC_STRIDE_LENGTH_MASK)
+ {
+ LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, rscs_measurement.value + 4);
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case RSCS_PARAM_TOTALDISTANCE:
+ if (inc_flag & RSCS_INC_TOTAL_DISTANCE_MASK)
+ {
+ if (inc_flag & RSCS_INC_STRIDE_LENGTH_MASK)
+ {
+ LE_ARRAY_TO_UINT32(*(uint32_t *)p_value, rscs_measurement.value + 6);
+ }
+ else
+ {
+ LE_ARRAY_TO_UINT32(*(uint32_t *)p_value, rscs_measurement.value + 4);
+ }
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ case RSCS_PARAM_SENSOR_LOC:
+ *(uint8_t *)p_value = rscs_cur_sens_location;
+ break;
+ }
+
+ if (!ret)
+ {
+ PROFILE_PRINT_INFO0("rscs parameter get failed\n");
+ }
+
+ return ret;
+}
+
+/**
+ * @brief display control point response.
+ *
+ * @param RSCS_ctl_pnt_ptr pointer to RSC control point data.
+ * @return none
+ * @retval void
+*/
+static void rscs_ctl_pnt_display_rsp(T_RSCS_CONTROL_POINT *rscs_ctl_pnt_ptr)
+{
+ PROFILE_PRINT_INFO1("RSCCP response: ReqOpCode=0x%x", rscs_ctl_pnt_ptr->value[1]);
+ PROFILE_PRINT_INFO1("rsp_code=0x%x", rscs_ctl_pnt_ptr->value[2]);
+}
+
+/**
+ * @brief whether the sensor location supported.
+ *
+ * @param sens_location sensor location to be judged(RSC sensor support or not).
+ * @return support result.
+ * @retval 1 support
+ * @retval 0 not support
+*/
+static bool rscs_sens_loc_supported(uint8_t sens_location)
+{
+ uint8_t result = false;
+ if ((rscs_sens_loc_list >> sens_location) & 0x0001)
+ {
+ result = true;
+ }
+ return (result);
+}
+
+/**
+ * @brief send response to client, control point indication procedure.
+ *
+ * @param service_id service ID of service.
+ * @param op_code control point request opcode type.
+ * @param rsp_code control point response code to indicate to client.
+ * @return indication action result
+ * @retval 1 TRUE
+ * @retval 0 FALSE
+*/
+bool rscs_ctl_pnt_indicate(uint8_t conn_id, T_SERVER_ID service_id, uint8_t op_code,
+ uint8_t rsp_code)
+{
+ uint16_t attrib_index = GATT_SVC_RSCS_CTL_PNT_INDEX;
+ uint8_t sens_location;
+ uint8_t param_offset;
+ uint8_t *p_data;
+ uint16_t dataLen;
+
+ rscs_control_point.value[1] = rscs_control_point.value[0]; /* Control Point request opcode. */
+ rscs_control_point.value[2] = rsp_code;
+ rscs_control_point.value[0] = RSCS_CP_OPCODE_RSP_CODE;
+ rscs_control_point.cur_length = 3 * sizeof(uint8_t);
+
+ /* Diff RspType, different indication contents. */
+ if (op_code == RSCS_CP_OPCODE_REQ_SENS_LOC_LIST)
+ {
+ /* get sensor location list */
+ for (sens_location = RSCS_SENSOR_LOC_OTHER, param_offset = 3; sens_location < RSCS_SENSOR_LOC_MAX;
+ sens_location++)
+ {
+ if (rscs_sens_loc_supported(sens_location))
+ {
+ rscs_control_point.value[param_offset] = sens_location;
+ param_offset++;
+ }
+ }
+ rscs_control_point.cur_length = param_offset;
+ }
+
+ rscs_ctl_pnt_display_rsp(&rscs_control_point);
+ p_data = rscs_control_point.value;
+ dataLen = rscs_control_point.cur_length;
+
+ // send indication to client
+ return server_send_data(conn_id, service_id, attrib_index, p_data, dataLen,
+ GATT_PDU_TYPE_INDICATION);
+}
+
+
+/**
+ * @brief set cumulative response.
+ *
+ * @param service_id
+ * @return none
+ * @retval void
+*/
+static void rscs_ctl_pnt_set_cumulative(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code)
+{
+ uint8_t op_code = RSCS_CP_OPCODE_SET_CUMULATIVE;
+ rscs_ctl_pnt_indicate(conn_id, service_id, op_code, rsp_code);
+}
+
+
+static void rscs_ctl_pnt_start_calib(uint8_t conn_id, T_SERVER_ID service_id, bool result)
+{
+ uint8_t op_code = RSCS_CP_OPCODE_SET_CUMULATIVE;
+ uint8_t rsp_code;
+ if (result == true)
+ {
+ rsp_code = RSCS_CP_RSPCODE_SUCCESS;
+ }
+ else
+ {
+ rsp_code = RSCS_CP_RSPCODE_OPERATION_FAILED;
+ }
+ rscs_ctl_pnt_indicate(conn_id, service_id, op_code, rsp_code);
+}
+
+/**
+ * @brief Send Running Speed and Cadence Service value indication data,
+ * send indication of result of calibration to client.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @param[in] result calibration result.
+ *
+ * @return none;
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint8_t result = p_parse_value->dw_param[1];
+ rscs_calib_result_indicate(conn_id, rscs_id, result);
+ data_uart_print("cmd_rscs_calib_result_indicate result= %d\r\n", result);
+ }
+ * \endcode
+ */
+void rscs_calib_result_indicate(uint8_t conn_id, T_SERVER_ID service_id, bool result)
+{
+ rscs_ctl_pnt_start_calib(conn_id, service_id, result);
+}
+
+/**
+ * @brief update sensor location response.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param[in] rsp_code Response Code.
+ * @return none
+ * @retval void
+*/
+static void rscs_ctl_pnt_update_sens_loc(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code)
+{
+
+ uint8_t op_code = RSCS_CP_OPCODE_UPDATE_SENS_LOC;
+ rscs_ctl_pnt_indicate(conn_id, service_id, op_code, rsp_code);
+}
+
+/**
+ * @brief supported sensor location response.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param[in] rsp_code Response Code.
+ * @return none
+ * @retval void
+*/
+static void rscs_ctl_pnt_req_sens_loc_list(uint8_t conn_id, T_SERVER_ID service_id,
+ uint8_t rsp_code)
+{
+ uint8_t op_code = RSCS_CP_OPCODE_REQ_SENS_LOC_LIST;
+ rscs_ctl_pnt_indicate(conn_id, service_id, op_code, rsp_code);
+}
+
+
+static uint8_t rscs_handle_ctl_pnt_proc_2(uint8_t service_id, uint16_t write_length,
+ uint8_t *value_ptr)
+{
+ T_RSCS_CALLBACK_DATA callback_data;
+ uint8_t resp_code = RSCS_CP_RSPCODE_SUCCESS;
+ uint16_t parameter_length = 0;
+ memcpy(rscs_control_point.value, value_ptr, write_length);
+ if (write_length >= 1)
+ {
+ parameter_length = write_length - 1;
+ }
+
+ PROFILE_PRINT_INFO1("rscs_handle_ctl_pnt_proc_2 request: OpCode=0x%x", rscs_control_point.value[0]);
+
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write.opcode = rscs_control_point.value[0];
+
+ switch (rscs_control_point.value[0])
+ {
+
+ case RSCS_CP_OPCODE_SET_CUMULATIVE:
+ {
+ if (parameter_length == 4)
+ {
+ memcpy(&callback_data.msg_data.write.cp_parameter.cumulative_value,
+ &rscs_control_point.value[1], 4);
+ }
+ else
+ {
+ resp_code = RSCS_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+
+ break;
+
+ case RSCS_CP_OPCODE_START_CALIBRATION:
+ {
+ if (parameter_length == 0)
+ {
+ }
+ else
+ {
+ resp_code = RSCS_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+ break;
+ case RSCS_CP_OPCODE_UPDATE_SENS_LOC:
+ {
+ if (parameter_length == 1)
+ {
+ memcpy(&callback_data.msg_data.write.cp_parameter.sensor_location_value,
+ &rscs_control_point.value[1], 1);
+ if (callback_data.msg_data.write.cp_parameter.sensor_location_value >= RSCS_SENSOR_LOC_MAX)
+ {
+ resp_code = RSCS_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+ else
+ {
+ resp_code = RSCS_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+ break;
+
+ case RSCS_CP_OPCODE_REQ_SENS_LOC_LIST:
+ {
+ if (parameter_length == 0)
+ {
+ }
+ else
+ {
+ resp_code = RSCS_CP_RSPCODE_INVALID_PARAMETER;
+ }
+ }
+ break;
+
+ default:
+ {
+ resp_code = RSCS_CP_RSPCODE_OPCODE_UNSUPPORT;
+ }
+ break;
+ }
+
+ if (resp_code == RSCS_CP_RSPCODE_SUCCESS)
+ {
+ pfn_rscs_cb(service_id, (void *)&callback_data);
+ }
+ return resp_code;
+}
+
+
+
+/**
+ * @brief handle control point write (request).
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param[in] write_length write request data length.
+ * @param[in] value_ptr pointer to write request data.
+ * @return none
+ * @retval void
+*/
+static void rscs_ctl_pnt_handle_req(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t write_length, uint8_t *value_ptr)
+{
+ uint8_t resp_code = RSCS_CP_RSPCODE_SUCCESS;
+ memcpy(rscs_control_point.value, value_ptr, write_length);
+ rscs_control_point.cur_length = write_length;
+
+ PROFILE_PRINT_INFO1("rscscp request: op_code=0x%x", rscs_control_point.value[0]);
+
+ resp_code = rscs_handle_ctl_pnt_proc_2(service_id, write_length, value_ptr);
+
+ if (resp_code == RSCS_CP_RSPCODE_SUCCESS)
+ {
+
+ switch (rscs_control_point.value[0])
+ {
+ default:
+ break;
+ case RSCS_CP_OPCODE_SET_CUMULATIVE:
+ if ((rscs_feature & RSCS_SUPPORT_TOTAL_DISTANCE_MASK) &&
+ (rscs_measurement.value[0] & RSCS_INC_TOTAL_DISTANCE_MASK))
+ {
+ rscs_ctl_pnt_set_cumulative(conn_id, service_id, resp_code);
+ return;
+ }
+ break;
+ case RSCS_CP_OPCODE_START_CALIBRATION:
+ if (rscs_feature & RSCS_SUPPORT_CALIBRATE_MASK)
+ {
+
+ return;
+ }
+ break;
+ case RSCS_CP_OPCODE_UPDATE_SENS_LOC:
+ if (rscs_feature & RSCS_SUPPORT_MULTI_SENSOR_MASK)
+ {
+ rscs_ctl_pnt_update_sens_loc(conn_id, service_id, resp_code);
+ return;
+ }
+ break;
+ case RSCS_CP_OPCODE_REQ_SENS_LOC_LIST:
+ if (rscs_feature & RSCS_SUPPORT_MULTI_SENSOR_MASK)
+ {
+ rscs_ctl_pnt_req_sens_loc_list(conn_id, service_id, resp_code);
+ return;
+ }
+ break;
+ }
+ }
+
+ /* Send indication to client when request opcode not supported. */
+ rscs_ctl_pnt_indicate(conn_id, service_id, rscs_control_point.value[0], resp_code);
+}
+
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID of characteristic data.
+ * @param[in] attrib_index Attribute index of getting characteristic data.
+ * @param[in] offset Used for Blob Read.
+ * @param[in,out] p_length length of getting characteristic data.
+ * @param[in,out] pp_value data got from service.
+ * @return Profile procedure result
+*/
+T_APP_RESULT rscs_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+
+ switch (attrib_index)
+ {
+ default:
+ PROFILE_PRINT_ERROR1("rscs_attr_read_cb, Attr not found, index = %d", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+ case GATT_SVC_RSCS_FEATURE_INDEX:
+ {
+ T_RSCS_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = RSCS_READ_RSCS_FEATURE;
+ pfn_rscs_cb(service_id, &callback_data);
+
+ *pp_value = (uint8_t *)&rscs_feature;
+ *p_length = sizeof(rscs_feature);
+
+ }
+ break;
+ case GATT_SVC_RSCS_SENS_LOC_INDEX:
+ if (rscs_feature & RSCS_SUPPORT_MULTI_SENSOR_MASK)
+ {
+ T_RSCS_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = RSCS_READ_SENSOR_LOCATION;
+ pfn_rscs_cb(service_id, &callback_data);
+ *pp_value = (uint8_t *)&rscs_cur_sens_location;
+ *p_length = sizeof(rscs_cur_sens_location);
+ }
+ else
+ {
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ break;
+ }
+
+ return cause;
+}
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID to be written.
+ * @param[in] attrib_index Attribute index of characteristic.
+ * @param[in] length length of value to be written.
+ * @param[in] p_value value to be written.
+ * @param[in] p_write_ind_post_proc pointer of a function to handle control point write.
+ * @return Profile procedure result
+*/
+T_APP_RESULT rscs_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value,
+ P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ if (GATT_SVC_RSCS_CTL_PNT_INDEX == attrib_index)
+ {
+ /* Attribute value has variable size, make sure written value size is valid. */
+ if ((length > RSCS_MAX_CTL_PNT_VALUE) || (p_value == NULL))
+ {
+ cause = APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ /* Make sure Control Point is not "Process already in progress". */
+ else if (RSCS_CTL_PNT_OPERATE_ACTIVE(rscs_control_point.value[0]))
+ {
+ cause = (T_APP_RESULT)0x80;//ProfileResult_AppErr_ProcAlreadyInProgress
+ }
+ /* Make sure Control Point is configured indication enable. */
+ else if (!rscs_notify_indicate_flag.sc_cp_indicate_enable)
+ {
+ cause = (T_APP_RESULT)0x81;//ProfileResult_AppErr_CccdImproperlyConfigured
+ }
+ else
+ {
+ /* handle SCCP request after sending write response */
+ *p_write_ind_post_proc = rscs_ctl_pnt_handle_req;
+ }
+ }
+ else
+ {
+ PROFILE_PRINT_ERROR2("rscs_attr_write_cb Error attrib_index = 0x%x length=%d", attrib_index,
+ length);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+
+ return cause;
+}
+
+/**
+ * @brief Send Running Speed and Cadence Service value notification data.
+ * Application shall call @ref rscs_set_parameter to set value first,
+ * and then call this api to send the notication value.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ *
+ * @return service id @ref T_SERVER_ID.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ bool op_result;
+ uint8_t flag = RSCS_INC_ALL_PRESENTS;
+
+ rscs_set_parameter(RSCS_PARAM_INC_FLAG, 1, &flag);
+
+ op_result = rscs_meas_value_notify(p_parse_value->dw_param[0], rscs_id);
+
+ if ( op_result )
+ {
+ data_uart_print("Notify RSC measurement value succeed\r\n");
+ }
+ else
+ {
+ data_uart_print("Notify RSC measurement value failed\r\n");
+ }
+
+ }
+ * \endcode
+ */
+bool rscs_meas_value_notify(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ uint16_t attrib_index = GATT_SVC_RSCS_MEASUREMENT_INDEX;
+ uint8_t *p_data = rscs_measurement.value;
+ uint16_t dataLen = rscs_measurement.cur_length;
+
+ PROFILE_PRINT_INFO0("rscs measurement notification");
+ return server_send_data(conn_id, service_id, attrib_index, p_data, dataLen,
+ GATT_PDU_TYPE_NOTIFICATION);
+}
+
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param[in] index Attribute index of characteristic data.
+ * @param[in] ccc_bits CCCD bits from stack.
+ * @return None
+*/
+void rscs_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ T_RSCS_CALLBACK_DATA callback_data;
+ bool handle = false;
+ PROFILE_PRINT_INFO2("rscs_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits);
+ switch (index)
+ {
+ case GATT_SVC_RSCS_MEAS_CCCD_INDEX:
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = RSCS_NOTIFY_INDICATE_MEASUREMENT_ENABLE;
+ rscs_notify_indicate_flag.rsc_measurement_notify_enable = true;
+ }
+ else
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = RSCS_NOTIFY_INDICATE_MEASUREMENT_ENABLE;
+ rscs_notify_indicate_flag.rsc_measurement_notify_enable = false;
+ }
+ handle = true;
+ break;
+
+ case GATT_SVC_RSCS_CTL_PNT_CCCD_INDEX:
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE)
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = RSCS_NOTIFY_INDICATE_SC_CP_ENABLE;
+ rscs_notify_indicate_flag.sc_cp_indicate_enable = true;
+ }
+ else
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = RSCS_NOTIFY_INDICATE_SC_CP_DISABLE;
+ rscs_notify_indicate_flag.sc_cp_indicate_enable = false;
+ }
+ handle = true;
+ break;
+ default:
+ break;
+ }
+ /* Notify Application. */
+ if (pfn_rscs_cb && (handle == true))
+ {
+ pfn_rscs_cb(service_id, (void *)&callback_data);
+ }
+}
+
+/**
+ * @brief RSC Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS rscs_cbs =
+{
+ rscs_attr_read_cb, // Read callback function pointer
+ rscs_attr_write_cb, // Write callback function pointer
+ rscs_cccd_update_cb // CCCD update callback function pointer
+};
+
+/**
+ * @brief Add Running Speed and Cadence Service.
+ *
+ * @param[in] p_func Callback when service attribute was read/write.
+ *
+ * @return service id @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ rscs_id = rscs_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID rscs_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+
+ /* Initiate RSC service related data, modify according to user's demand. */
+ rscs_feature = RSCS_ALL_FEATURE_SUPPORTED;
+ rscs_measurement.value[0] = RSCS_INC_ALL_PRESENTS;
+ rscs_measurement.cur_length = RSCS_MAX_MEASUREMENT_VALUE;
+ rscs_sens_loc_list = RSCS_ALL_SENS_LOC_SUPPORTED;
+ rscs_cur_sens_location = RSCS_SENSOR_LOC_TOP_OF_SHOE;
+
+ /* register RSC service to profile layer. */
+ if (false == server_add_service(&service_id,
+ (uint8_t *)rscs_attr_tbl,
+ rscs_attr_tbl_size,
+ rscs_cbs))
+ {
+ PROFILE_PRINT_ERROR1("rscs_add_service: service_id %d", service_id);
+ service_id = 0xff;
+ return service_id;
+ }
+
+ /* register callback for profile to inform application that some events happened. */
+ pfn_rscs_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
+
diff --git a/src/ble/profile/server/simple_ble_service.c b/src/ble/profile/server/simple_ble_service.c
new file mode 100644
index 0000000..4776994
--- /dev/null
+++ b/src/ble/profile/server/simple_ble_service.c
@@ -0,0 +1,478 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file simple_ble_service.c
+* @brief simple BLE profile source file.
+* @details Demonstration of how to implement a self-definition profile.
+* @author
+* @date
+* @version
+*********************************************************************************************************
+*/
+
+#include <string.h>
+#include <trace.h>
+#include <simple_ble_service.h>
+#include <gap.h>
+
+
+#define SIMPLE_BLE_SERVICE_CHAR_V1_READ_INDEX 0x02
+#define SIMPLE_BLE_SERVICE_CHAR_V2_WRITE_INDEX 0x05
+#define SIMPLE_BLE_SERVICE_CHAR_V3_NOTIFY_INDEX 0x07
+#define SIMPLE_BLE_SERVICE_CHAR_V4_INDICATE_INDEX 0x0a
+#define SIMPLE_BLE_SERVICE_CHAR_NOTIFY_CCCD_INDEX (SIMPLE_BLE_SERVICE_CHAR_V3_NOTIFY_INDEX + 1)
+#define SIMPLE_BLE_SERVICE_CHAR_INDICATE_CCCD_INDEX (SIMPLE_BLE_SERVICE_CHAR_V4_INDICATE_INDEX + 1)
+
+
+
+T_SERVER_ID simp_service_id;
+/**< Value of simple read characteristic. */
+static uint8_t simple_char_read_value[SIMP_READ_V1_MAX_LEN];
+static uint16_t simple_char_read_len = 1;
+char v1_user_descr[] = "V1 read characteristic";
+
+/**< Function pointer used to send event to application from simple profile. Initiated in simp_ble_service_add_service. */
+static P_FUN_SERVER_GENERAL_CB pfn_simp_ble_service_cb = NULL;
+
+/**< @brief profile/service definition. */
+const T_ATTRIB_APPL simple_ble_service_tbl[] =
+{
+ /* <<Primary Service>>, .. */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE), /* service UUID */
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* p_value_context */
+ GATT_PERM_READ /* permissions */
+ },
+ /* <<Characteristic>> demo for read */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_SIMPLE_V1_READ),
+ HI_WORD(GATT_UUID_CHAR_SIMPLE_V1_READ)
+ },
+ 0, /* bValueLen */
+ NULL,
+#if SIMP_SRV_AUTHEN_EN
+ GATT_PERM_READ_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_READ /* permissions */
+#endif
+ },
+ {
+ ATTRIB_FLAG_VOID | ATTRIB_FLAG_ASCII_Z, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_USER_DESCR),
+ HI_WORD(GATT_UUID_CHAR_USER_DESCR),
+ },
+ (sizeof(v1_user_descr) - 1), /* bValueLen */
+ (void *)v1_user_descr,
+ GATT_PERM_READ /* permissions */
+ },
+ /* <<Characteristic>> demo for write */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP) /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_SIMPLE_V2_WRITE),
+ HI_WORD(GATT_UUID_CHAR_SIMPLE_V2_WRITE)
+ },
+ 0, /* bValueLen */
+ NULL,
+#if SIMP_SRV_AUTHEN_EN
+ GATT_PERM_WRITE_AUTHEN_REQ /* permissions */
+#else
+ GATT_PERM_WRITE /* permissions */
+#endif
+ },
+ /* <<Characteristic>>, demo for notify */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_NOTIFY) /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_SIMPLE_V3_NOTIFY),
+ HI_WORD(GATT_UUID_CHAR_SIMPLE_V3_NOTIFY)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_NONE /* permissions */
+ },
+ /* client characteristic configuration */
+ {
+ ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+#if SIMP_SRV_AUTHEN_EN
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */
+#endif
+ },
+ /* <<Characteristic>> demo for indicate */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_INDICATE) /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_SIMPLE_V4_INDICATE),
+ HI_WORD(GATT_UUID_CHAR_SIMPLE_V4_INDICATE)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_NONE /* permissions */
+ },
+ /* client characteristic configuration */
+ {
+ ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+#if SIMP_SRV_AUTHEN_EN
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */
+#endif
+ },
+};
+
+/**
+ * @brief Set service related data from application.
+ *
+ * @param[in] param_type parameter type to set.
+ * @param[in] len value length to be set.
+ * @param[in] p_value value to set.
+ * @return parameter set result.
+ * @retval 0 false
+ * @retval 1 true
+ */
+bool simp_ble_service_set_parameter(T_SIMP_PARAM_TYPE param_type, uint16_t len, void *p_value)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ default:
+ ret = false;
+ break;
+ case SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL:
+ if (len <= SIMP_READ_V1_MAX_LEN)
+ {
+ memcpy(simple_char_read_value, p_value, len);
+ simple_char_read_len = len;
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ }
+
+ if (!ret)
+ {
+ APP_PRINT_ERROR0("simp_ble_service_set_parameter failed");
+ }
+
+ return ret;
+}
+
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param service_id ServiceID of characteristic data.
+ * @param attrib_index Attribute index of getting characteristic data.
+ * @param offset Used for Blob Read.
+ * @param p_length length of getting characteristic data.
+ * @param pp_value data got from service.
+ * @return Profile procedure result
+*/
+T_APP_RESULT simp_ble_service_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index, uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+
+ switch (attrib_index)
+ {
+ default:
+ APP_PRINT_ERROR1("simp_ble_service_attr_read_cb, Attr not found, index %d", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+ case SIMPLE_BLE_SERVICE_CHAR_V1_READ_INDEX:
+ {
+ TSIMP_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = SIMP_READ_V1;
+ callback_data.conn_id = conn_id;
+ if (pfn_simp_ble_service_cb)
+ {
+ pfn_simp_ble_service_cb(service_id, (void *)&callback_data);
+ }
+ *pp_value = simple_char_read_value;
+ *p_length = simple_char_read_len;
+ }
+ break;
+
+ }
+
+ return (cause);
+}
+
+
+void simple_write_post_callback(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t length, uint8_t *p_value)
+{
+ APP_PRINT_INFO4("simple_write_post_callback: conn_id %d, service_id %d, attrib_index 0x%x, length %d",
+ conn_id, service_id, attrib_index, length);
+}
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param conn_id
+ * @param service_id ServiceID to be written.
+ * @param attrib_index Attribute index of characteristic.
+ * @param length length of value to be written.
+ * @param p_value value to be written.
+ * @return Profile procedure result
+*/
+T_APP_RESULT simp_ble_service_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id,
+ uint16_t attrib_index, T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value,
+ P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ TSIMP_CALLBACK_DATA callback_data;
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ APP_PRINT_INFO1("simp_ble_service_attr_write_cb write_type = 0x%x", write_type);
+ *p_write_ind_post_proc = simple_write_post_callback;
+ if (SIMPLE_BLE_SERVICE_CHAR_V2_WRITE_INDEX == attrib_index)
+ {
+ /* Make sure written value size is valid. */
+ if (p_value == NULL)
+ {
+ cause = APP_RESULT_INVALID_VALUE_SIZE;
+ }
+ else
+ {
+ /* Notify Application. */
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_data.write.opcode = SIMP_WRITE_V2;
+ callback_data.msg_data.write.write_type = write_type;
+ callback_data.msg_data.write.len = length;
+ callback_data.msg_data.write.p_value = p_value;
+
+ if (pfn_simp_ble_service_cb)
+ {
+ pfn_simp_ble_service_cb(service_id, (void *)&callback_data);
+ }
+ }
+ }
+ else
+ {
+ APP_PRINT_ERROR2("simp_ble_service_attr_write_cb Error: attrib_index 0x%x, length %d",
+ attrib_index,
+ length);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ return cause;
+}
+
+/**
+ * @brief send notification of simple notify characteristic value.
+ *
+ * @param[in] conn_id connection id
+ * @param[in] service_id service ID of service.
+ * @param[in] p_value characteristic value to notify
+ * @param[in] length characteristic value length to notify
+ * @return notification action result
+ * @retval 1 true
+ * @retval 0 false
+ */
+bool simp_ble_service_send_v3_notify(uint8_t conn_id, T_SERVER_ID service_id, void *p_value,
+ uint16_t length)
+{
+ APP_PRINT_INFO0("simp_ble_service_send_v3_notify");
+ // send notification to client
+ return server_send_data(conn_id, service_id, SIMPLE_BLE_SERVICE_CHAR_V3_NOTIFY_INDEX, p_value,
+ length,
+ GATT_PDU_TYPE_ANY);
+}
+
+/**
+ * @brief send indication of simple indicate characteristic value.
+ *
+ * @param[in] conn_id connection id
+ * @param[in] service_id service ID of service.
+ * @param[in] p_value characteristic value to notify
+ * @param[in] length characteristic value length to notify
+ * @return notification action result
+ * @retval 1 true
+ * @retval 0 false
+ */
+bool simp_ble_service_send_v4_indicate(uint8_t conn_id, T_SERVER_ID service_id, void *p_value,
+ uint16_t length)
+{
+ APP_PRINT_INFO0("simp_ble_service_send_v4_indicate");
+ // send indication to client
+ return server_send_data(conn_id, service_id, SIMPLE_BLE_SERVICE_CHAR_V4_INDICATE_INDEX, p_value,
+ length, GATT_PDU_TYPE_ANY);
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param conn_id connection id.
+ * @param service_id Service ID.
+ * @param index Attribute index of characteristic data.
+ * @param cccbits CCCD bits from stack.
+ * @return None
+*/
+void simp_ble_service_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index,
+ uint16_t cccbits)
+{
+ TSIMP_CALLBACK_DATA callback_data;
+ bool is_handled = false;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ APP_PRINT_INFO2("simp_ble_service_cccd_update_cb: index = %d, cccbits 0x%x", index, cccbits);
+ switch (index)
+ {
+ case SIMPLE_BLE_SERVICE_CHAR_NOTIFY_CCCD_INDEX:
+ {
+ if (cccbits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ // Enable Notification
+ callback_data.msg_data.notification_indification_index = SIMP_NOTIFY_INDICATE_V3_ENABLE;
+ }
+ else
+ {
+ // Disable Notification
+ callback_data.msg_data.notification_indification_index = SIMP_NOTIFY_INDICATE_V3_DISABLE;
+ }
+ is_handled = true;
+ }
+ break;
+ case SIMPLE_BLE_SERVICE_CHAR_INDICATE_CCCD_INDEX:
+ {
+ if (cccbits & GATT_CLIENT_CHAR_CONFIG_INDICATE)
+ {
+ // Enable Indication
+ callback_data.msg_data.notification_indification_index = SIMP_NOTIFY_INDICATE_V4_ENABLE;
+ }
+ else
+ {
+ // Disable Indication
+ callback_data.msg_data.notification_indification_index = SIMP_NOTIFY_INDICATE_V4_DISABLE;
+ }
+ is_handled = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ /* Notify Application. */
+ if (pfn_simp_ble_service_cb && (is_handled == true))
+ {
+ pfn_simp_ble_service_cb(service_id, (void *)&callback_data);
+ }
+}
+
+/**
+ * @brief Simple ble Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS simp_ble_service_cbs =
+{
+ simp_ble_service_attr_read_cb, // Read callback function pointer
+ simp_ble_service_attr_write_cb, // Write callback function pointer
+ simp_ble_service_cccd_update_cb // CCCD update callback function pointer
+};
+
+/**
+ * @brief Add simple BLE service to the BLE stack database.
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ */
+T_SERVER_ID simp_ble_service_add_service(void *p_func)
+{
+ if (false == server_add_service(&simp_service_id,
+ (uint8_t *)simple_ble_service_tbl,
+ sizeof(simple_ble_service_tbl),
+ simp_ble_service_cbs))
+ {
+ APP_PRINT_ERROR0("simp_ble_service_add_service: fail");
+ simp_service_id = 0xff;
+ return simp_service_id;
+ }
+
+ pfn_simp_ble_service_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return simp_service_id;
+}
+
diff --git a/src/ble/profile/server/sps.c b/src/ble/profile/server/sps.c
new file mode 100644
index 0000000..20e07ff
--- /dev/null
+++ b/src/ble/profile/server/sps.c
@@ -0,0 +1,337 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file sps.c
+* @brief SPS service source file.
+* @details Interfaces to access SPS service.
+* @author
+* @date
+* @version v1.0
+*********************************************************************************************************
+*/
+#include "stdint.h"
+#include "string.h"
+#include "trace.h"
+#include "profile_server.h"
+#include "sps.h"
+#include "sps_config.h"
+
+
+///@cond
+/** @brief ScanParameters service related UUIDs. */
+#define GATT_UUID_SPS 0x1813
+#define GATT_UUID_CHAR_SCAN_INTERVAL_WINDOW 0x2A4F
+#define GATT_UUID_CHAR_SCAN_REFRESH 0x2A31
+
+/** @brief defines for Characteristic Index in Scan parameters Service */
+#define GATT_SVC_SPS_SCAN_INTERVAL_INDEX 2 /**< @brief Index for Scan Interval chars's value */
+#define GATT_SVC_SPS_SCAN_REFRESH_INDEX 4 /**< @brief Index for Scan refresh chars's value */
+#define GATT_SVC_SPS_SCAN_REFRESH_CCCD_INDEX 5/**< @brief CCCD Index for Scan Interval chars's value */
+///@endcond
+
+
+/**< SPS Refresh Value. */
+static uint8_t sps_refresh_value __attribute__((unused)) = 0;
+/**< Function pointer used to send event to application from sps profile. */
+static P_FUN_SERVER_GENERAL_CB pfn_sps_cb = NULL;
+
+/**< @brief profile/service definition. */
+const T_ATTRIB_APPL sps_attr_tbl[] =
+{
+ /*--------------------------ScanParameters Service------------------*/
+ /* <<Primary Service>>, .. */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_SPS), /* service UUID */
+ HI_WORD(GATT_UUID_SPS)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic>>, .. */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* Scan Interval Window Char value */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_SCAN_INTERVAL_WINDOW),
+ HI_WORD(GATT_UUID_CHAR_SCAN_INTERVAL_WINDOW)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_NONE /* wPermissions */
+ },
+ /* <<Characteristic>>, .. */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_NOTIFY /* characteristic properties */
+ )
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ }
+#if SPS_CHAR_SCAN_REFRESH_SUPPORT
+ ,
+ /* Scan Refresh Char value */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_SCAN_REFRESH),
+ HI_WORD(GATT_UUID_CHAR_SCAN_REFRESH)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_NONE /* wPermissions */
+ },
+ /* client characteristic configuration */
+ {
+ ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ }
+#endif
+};
+/**< @brief SPS service size definition. */
+const uint16_t sps_attr_tbl_size = sizeof(sps_attr_tbl);
+
+/**
+ * @brief Set a scan parameter service parameter.
+ *
+ * NOTE: You can call this function with a scan parameter service parameter type and it will set the
+ * scan parameter service parameter. Scan parameter service parameters are defined in @ref T_SPS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Scan parameter service parameter type: @ref T_SPS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t refresh_value = 10;
+ sps_set_parameter(SPS_PARAM_SCAN_REFRESH, 1, &refresh_value);
+ }
+ * \endcode
+ */
+bool sps_set_parameter(T_SPS_PARAM_TYPE param_type, uint8_t len, void *p_value)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ default:
+ /* invalid param to set. */
+ ret = false;
+ break;
+ case SPS_PARAM_SCAN_REFRESH:
+ sps_refresh_value = *((uint8_t *)p_value);
+ break;
+ }
+
+ if (!ret)
+ {
+ PROFILE_PRINT_ERROR0("sps_set_parameter: SPS parameter set failed");
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief send notification.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID of service.
+ * @param[in] sps_refresh_value characteristic value to notify
+ * @return notification action result
+ * @retval 1 TRUE
+ * @retval 0 FALSE
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t sps_refresh_value = 10;
+ sps_scan_interval_window_value_notify(conn_id, sps_id, sps_refresh_value);
+ }
+ * \endcode
+ */
+bool sps_scan_interval_window_value_notify(uint8_t conn_id, uint8_t service_id,
+ uint8_t sps_refresh_value)
+{
+ return server_send_data(conn_id, service_id, GATT_SVC_SPS_SCAN_REFRESH_INDEX,
+ (uint8_t *)&sps_refresh_value, sizeof(sps_refresh_value), GATT_PDU_TYPE_ANY);
+}
+
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID to be written.
+ * @param[in] attrib_index Attribute index of characteristic.
+ * @param[in] write_type Write type.
+ * @param[in] length Length of value to be written.
+ * @param[in] p_value Value to be written.
+ * @return Profile procedure result
+*/
+T_APP_RESULT sps_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ if ((GATT_SVC_SPS_SCAN_INTERVAL_INDEX == attrib_index) && (length == 4) && p_value)
+ {
+ uint16_t scan_interval = ((uint16_t)p_value[1] << 8) && (0xff00) + p_value[0];
+ uint16_t scan_window = ((uint16_t)p_value[2] << 8) && (0xff00) + p_value[3];
+
+ T_SPS_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.conn_id = conn_id;
+ callback_data.msg_data.write.write_type = SPS_WRITE_SCAN_INTERVAL_WINDOW;
+ callback_data.msg_data.write.write_parameter.scan.scan_interval = scan_interval;
+ callback_data.msg_data.write.write_parameter.scan.scan_window = scan_window;
+
+ if (pfn_sps_cb)
+ {
+ pfn_sps_cb(service_id, (void *)&callback_data);
+ }
+ }
+ else
+ {
+ PROFILE_PRINT_ERROR2("sps_attr_write_cb: attrib_index 0x%x, length %d", attrib_index, length);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ return cause;
+
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param[in] index Attribute index of characteristic data.
+ * @param[in] ccc_bits CCCD bits from stack.
+ * @return None
+*/
+void sps_cccd_update_cb(uint8_t conn_id, uint8_t service_id, uint16_t index, uint16_t ccc_bits)
+{
+ T_SPS_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.conn_id = conn_id;
+ bool handle = false;
+ PROFILE_PRINT_INFO2("sps_cccd_update_cb: index %d ccc_bits %x", index, ccc_bits);
+
+ switch (index)
+ {
+ case GATT_SVC_SPS_SCAN_REFRESH_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_data.notification_indification_index = SPS_NOTIFY_INDICATE_SCAN_REFRESH_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.notification_indification_index = SPS_NOTIFY_INDICATE_SCAN_REFRESH_DISABLE;
+ }
+ handle = true;
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (pfn_sps_cb && (handle == true))
+ {
+ pfn_sps_cb(service_id, (void *)&callback_data);
+ }
+
+ return;
+}
+
+/**
+ * @brief SPS Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS sps_cbs =
+{
+ NULL, // Read callback function pointer
+ sps_attr_write_cb, // Write callback function pointer
+ sps_cccd_update_cb // CCCD update callback function pointer
+};
+
+/**
+ * @brief Add scan parameters service to the BLE stack database.
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ sps_id = sps_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID sps_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)sps_attr_tbl,
+ sps_attr_tbl_size,
+ sps_cbs))
+ {
+ PROFILE_PRINT_ERROR1("sps_add_service: service_id %d", service_id);
+ service_id = 0xff;
+ return service_id;
+ }
+ pfn_sps_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
diff --git a/src/ble/profile/server/tps.c b/src/ble/profile/server/tps.c
new file mode 100644
index 0000000..9875bcc
--- /dev/null
+++ b/src/ble/profile/server/tps.c
@@ -0,0 +1,210 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file tps.c
+* @brief Tx Power service source file.
+* @details Interfaces to access Tx Power service.
+* @author
+* @date
+* @version v1.0
+*********************************************************************************************************
+*/
+#include "string.h"
+#include "trace.h"
+#include "profile_server.h"
+#include "tps.h"
+
+
+#define GATT_UUID_TX_POWER_SERVICE 0x1804
+#define GATT_UUID_CHAR_TX_LEVEL 0x2A07
+
+#define TPS_TX_POWER_VALUE_INDEX 2
+
+
+
+static uint8_t tx_power_value = 0;
+
+static P_FUN_SERVER_GENERAL_CB pfn_tps_cb = NULL;
+
+/**< @brief profile/service definition. */
+const T_ATTRIB_APPL tps_attr_tbl[] =
+{
+ /*----------------- TX Power Service -------------------*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_TX_POWER_SERVICE), /* service UUID */
+ HI_WORD(GATT_UUID_TX_POWER_SERVICE)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* Alert Level Characteristic */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ, /* characteristic properties */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* Alert Level Characteristic value */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_TX_LEVEL),
+ HI_WORD(GATT_UUID_CHAR_TX_LEVEL)
+ },
+ 0, /* variable size */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ }
+};
+
+/**< @brief TPS profile related services size definition. */
+const static int tps_attr_tbl_size = sizeof(tps_attr_tbl);
+
+/**
+ * @brief Set a Tx power service parameter.
+ *
+ * NOTE: You can call this function with a tx power service parameter type and it will set the
+ * tx power service parameter. Tx power service parameters are defined in @ref T_TPS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Tx power service parameter type: @ref T_TPS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (example: data type of uint16 will be cast to
+ * uint16 pointer).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t tx_power = 0;
+ tps_set_parameter(TPS_PARAM_TX_POWER, 1, &tx_power);
+ }
+ * \endcode
+ */
+bool tps_set_parameter(T_TPS_PARAM_TYPE param_type, uint8_t len, void *p_value)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ default:
+ /* invalid param to set. */
+ ret = false;
+ break;
+
+ case TPS_PARAM_TX_POWER:
+ tx_power_value = *(uint8_t *)p_value;
+ break;
+ }
+
+ if (!ret)
+ {
+ PROFILE_PRINT_ERROR0("tps_set_parameter: TPS parameter set failed");
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID to be read.
+ * @param[in] attrib_index Attribute index of getting characteristic data.
+ * @param[in] offset offset of characteritic to be read.
+ * @param[in,out] length_ptr length of getting characteristic data.
+ * @param[in,out] pp_value pointer to pointer of characteristic value to be read.
+ * @return TProfileResult
+*/
+T_APP_RESULT tps_attr_read_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *length_ptr, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ *length_ptr = 0;
+ T_TPS_CALLBACK_DATA callback_data;
+ switch (attrib_index)
+ {
+ default:
+ PROFILE_PRINT_ERROR1("tps_attr_read_cb: attrib_index %d", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+
+ case TPS_TX_POWER_VALUE_INDEX:
+ callback_data.conn_id = conn_id;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = TPS_READ_TX_POWER_VALUE;
+ pfn_tps_cb(service_id, (void *)&callback_data);
+
+ *pp_value = (uint8_t *)&tx_power_value;
+ *length_ptr = sizeof(tx_power_value);
+ break;
+ }
+
+ PROFILE_PRINT_INFO2("tps_attr_read_cb: attrib_index %d, *length_ptr %d", attrib_index, *length_ptr);
+
+ return (cause);
+}
+
+
+// TPS related Service Callbacks
+const T_FUN_GATT_SERVICE_CBS tps_cbs =
+{
+ tps_attr_read_cb, // Read callback function pointer
+ NULL, // Write callback function pointer
+ NULL // CCCD update callback function pointer
+};
+
+/**
+ * @brief Add tx power service to the BLE stack database.
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ tps_id = tps_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID tps_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)tps_attr_tbl,
+ tps_attr_tbl_size,
+ tps_cbs))
+ {
+ PROFILE_PRINT_ERROR1("tps_add_service: service_id %d", service_id);
+ service_id = 0xff;
+ }
+
+ pfn_tps_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
diff --git a/src/ble/profile/server/vendor_service.c b/src/ble/profile/server/vendor_service.c
new file mode 100644
index 0000000..7da9528
--- /dev/null
+++ b/src/ble/profile/server/vendor_service.c
@@ -0,0 +1,282 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file vendor_service.c
+* @brief Vendor service source file.
+* @details Interfaces to access Vendor service.
+* @author
+* @date 2020-03-11
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "board.h"
+#include "string.h"
+#include "trace.h"
+#include "gatt.h"
+#include "profile_server.h"
+#include "vendor_service.h"
+#include "gap.h"
+#include "mem_config.h"
+#include "app_section.h"
+#include "overlay_mgr.h"
+
+/*============================================================================*
+ * Global Variables
+ *============================================================================*/
+uint8_t vendor_svc_handshake_values[16] = {0};
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+static P_FUN_SERVER_GENERAL_CB pfn_vendor_svc_cb = NULL;
+static const uint8_t GATT_UUID_VENDOR_SERVICE[16] = {0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0xFF, 0xD1, 0x00, 0x00};
+
+/**< @brief profile/service definition.
+* here is an example of OTA service table
+* including Write
+*/
+const T_ATTRIB_APPL vendor_svc_bas_attr_tbl[] =
+{
+ /*--------------------------Vendor Service ---------------------------*/
+ /* <<Primary Service>>, .. 0*/
+ {
+ (ATTRIB_FLAG_VOID | ATTRIB_FLAG_LE), /* wFlags */
+ {
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE), /* bTypeValue */
+ },
+ UUID_128BIT_SIZE, /* bValueLen */
+ (void *)GATT_UUID_VENDOR_SERVICE, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic>> 1 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE_NO_RSP | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* characteristic value 2 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_VENDOR_HANDSHAKE),
+ HI_WORD(GATT_UUID_CHAR_VENDOR_HANDSHAKE),
+ },
+ 1, /* variable size */
+ (void *)NULL,
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+ },
+
+ /* client characteristic configuration 3 */
+ {
+ ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ },
+
+ /* <<Characteristic>> 4 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP) /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* characteristic value 5 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_CHAR_VENDOR_TEST_MODE),
+ HI_WORD(GATT_UUID_CHAR_VENDOR_TEST_MODE)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_WRITE /* permissions */
+ },
+};
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param ServiceID ServiceID to be written.
+ * @param iAttribIndex Attribute index of characteristic.
+ * @param wLength length of value to be written.
+ * @param pValue value to be written.
+ * @return Profile procedure result
+*/
+T_APP_RESULT vendor_svc_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ bool handle = true;
+ T_VENDOR_CALLBACK_DATA callback_data;
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+
+ APP_PRINT_INFO1("[vendor_svc_attr_write_cb] attrib_index is %d", attrib_index);
+
+ if (BLE_SERVICE_CHAR_VENDOR_HANDSHAKE_INDEX == attrib_index)
+ {
+ /* Make sure written value size is valid. */
+ if ((length != 16) || (p_value == NULL))
+ {
+ handle = false;
+ cause = APP_RESULT_APP_ERR;
+ }
+ else
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write_msg.write_type = VENDOR_WRITE_HANDSHAKE;
+ callback_data.msg_data.write_msg.write_parameter.report_data.len = length;
+ callback_data.msg_data.write_msg.write_parameter.report_data.report = p_value;
+ }
+ }
+ else if (BLE_SERVICE_CHAR_VENDOR_TEST_MODE_INDEX == attrib_index)
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE;
+ callback_data.msg_data.write_msg.write_type = VENDOR_WRITE_TEST_MODE;
+ callback_data.msg_data.write_msg.write_parameter.report_data.len = length;
+ callback_data.msg_data.write_msg.write_parameter.report_data.report = p_value;
+ }
+ else
+ {
+ handle = false;
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+
+ if ((pfn_vendor_svc_cb) && (handle == true))
+ {
+ pfn_vendor_svc_cb(service_id, (void *)&callback_data);
+ }
+
+ return cause;
+
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param ServiceId Service ID.
+ * @param Index Attribute index of characteristic data.
+ * @param wCCCBits CCCD bits from stack.
+ * @return None
+*/
+void vendor_svc_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index,
+ uint16_t ccc_bits)
+{
+ bool handle = true;
+ T_VENDOR_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+
+ APP_PRINT_INFO2("[vendor_svc_cccd_update_cb] index = %d, ccc_bits %x", index, ccc_bits);
+ switch (index)
+ {
+ case GATT_SVC_VENDOR_HANDSHAKE_CHAR_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = VENDOR_NOTIFY_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indification_index = VENDOR_NOTIFY_DISABLE;
+ }
+ break;
+ }
+ default:
+ {
+ handle = false;
+ break;
+ }
+ }
+
+ if (pfn_vendor_svc_cb && (handle == true))
+ {
+ /* Notify Application */
+ pfn_vendor_svc_cb(service_id, (void *)&callback_data);
+ }
+
+ return;
+}
+
+/**
+ * @brief Vendor Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS vendor_svc_cbs =
+{
+ NULL, // Read callback function pointer
+ vendor_svc_attr_write_cb, // Write callback function pointer
+ vendor_svc_cccd_update_cb // CCCD update callback function pointer
+};
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/**
+ * @brief Add vendor service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ bas_id = vendor_svc_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+uint8_t vendor_svc_add_service(void *p_func)
+{
+ uint8_t service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)vendor_svc_bas_attr_tbl,
+ sizeof(vendor_svc_bas_attr_tbl),
+ vendor_svc_cbs))
+ {
+ APP_PRINT_INFO1("vendor_svc_add_service: service_id %d", service_id);
+ service_id = 0xff;
+ return service_id;
+ }
+ pfn_vendor_svc_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/ble/profile/server/voice_service.c b/src/ble/profile/server/voice_service.c
new file mode 100644
index 0000000..5c9abd1
--- /dev/null
+++ b/src/ble/profile/server/voice_service.c
@@ -0,0 +1,327 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file voice_service.c
+* @brief This file provides a vendor defined voice profile.
+* @details
+* @author
+* @date 2020-03-11
+* @version v1.1
+******************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2015 Realtek Semiconductor Corporation</center></h2>
+******************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "trace.h"
+#include "gatt.h"
+#include "gap.h"
+#include "string.h"
+#include "gap_conn_le.h"
+#include "gap_msg.h"
+#include "voice_service.h"
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+const uint8_t GATT_UUID128_VOICE_SRV[16] = { 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0xFD, 0x03, 0x00, 0x00};
+
+static P_FUN_SERVER_GENERAL_CB pfn_voice_cb = NULL;
+
+/**@brief profile/service definition.
+* here is the Voice Service table
+*/
+const T_ATTRIB_APPL VOICE_SERVICE_GATT_TABLE[] =
+{
+ /*--------------------------Voice Service ---------------------------*/
+ /* <<Primary Service>>, 0 */
+ {
+ (ATTRIB_FLAG_VOID | ATTRIB_FLAG_LE), /* wFlags */
+ {
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE), /* bTypeValue */
+ },
+ UUID_128BIT_SIZE, /* bValueLen */
+ (void *)GATT_UUID128_VOICE_SRV, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* VOICE_CHAR_TX */
+ /* Characteristic Definition, 1 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_WRITE, /* characteristic properties */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* Characteristic Value, 2 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_VOICE_CHAR_CTL),
+ HI_WORD(GATT_UUID_VOICE_CHAR_CTL)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_WRITE /* permissions */
+ },
+
+ /* VOICE_CHAR_DATA */
+ /* Characteristic, 3 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* Characteristic Value, 4 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_VOICE_CHAR_DATA),
+ HI_WORD(GATT_UUID_VOICE_CHAR_DATA)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* client characteristic configuration, 5 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* wFlags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ },
+
+ /* VOICE_CHAR_CMD */
+ /* Characteristic, 6 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* Characteristic Value, 7 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* flags */
+ { /* type_value */
+ LO_WORD(GATT_UUID_VOICE_CHAR_CMD),
+ HI_WORD(GATT_UUID_VOICE_CHAR_CMD)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* permissions */
+ },
+
+ /* client characteristic configuration, 8 */
+ {
+ (ATTRIB_FLAG_VALUE_INCL | /* wFlags */
+ ATTRIB_FLAG_CCCD_APPL),
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ },
+};
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param conn_id Connection ID.
+ * @param service_id ServiceID to be read.
+ * @param attrib_index Attribute index of getting characteristic data.
+ * @param offset Offset of characteritic to be read.
+ * @param p_length Length of getting characteristic data.
+ * @param pp_value Pointer to pointer of characteristic value to be read.
+ * @return T_APP_RESULT
+*/
+T_APP_RESULT voice_attr_read_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+ *p_length = 0;
+
+ PROFILE_PRINT_INFO2("voice_attr_read_cb attrib_index = %d offset %x", attrib_index, offset);
+
+ switch (attrib_index)
+ {
+ default:
+ {
+ PROFILE_PRINT_ERROR1("voice_attr_read_cb attrib_index = %d not found", attrib_index);
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+ break;
+ }
+ return (cause);
+}
+
+/**
+ * @brief write characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID to be written.
+ * @param[in] attrib_index Attribute index of characteristic.
+ * @param[in] write_type Write type.
+ * @param[in] length Length of writing characteristic data.
+ * @param[in] p_value Pointer to characteristic data.
+ * @param[in] p_write_ind_post_proc Function pointer after ias_attr_write_cb.
+ * @return TProfileResult
+*/
+T_APP_RESULT voice_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index,
+ T_WRITE_TYPE write_type,
+ uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
+{
+ T_APP_RESULT cause = APP_RESULT_SUCCESS;
+
+ APP_PRINT_INFO1("voice_attr_write_cb write_type = 0x%x", write_type);
+
+ if (!p_value)
+ {
+ cause = APP_RESULT_INVALID_PDU;
+ }
+ else if (attrib_index == GATT_SRV_VOICE_CHAR_CTL_VALUE_INDEX)
+ {
+ cause = APP_RESULT_SUCCESS;
+ }
+ else
+ {
+ cause = APP_RESULT_ATTR_NOT_FOUND;
+ }
+
+ return cause;
+
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param conn_id Connection ID.
+ * @param service_id Service ID.
+ * @param index Attribute index of characteristic data.
+ * @param ccc_bits CCCD bits from stack.
+ * @return None
+*/
+void voice_cccd_update_cb(uint8_t conn_id, uint8_t service_id, uint16_t index, uint16_t ccc_bits)
+{
+ T_VOICE_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ bool handle = true;
+
+ PROFILE_PRINT_INFO2("voice_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits);
+ switch (index)
+ {
+ case GATT_SRV_VOICE_CHAR_DATA_CCCD_INDEX:
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_data.notification_indification_index = VOICE_NOTIFY_DATA_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.notification_indification_index = VOICE_NOTIFY_DATA_DISABLE;
+ }
+ break;
+
+ case GATT_SRV_VOICE_CHAR_CMD_CCCD_INDEX:
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY)
+ {
+ callback_data.msg_data.notification_indification_index = VOICE_NOTIFY_CMD_ENABLE;
+ }
+ else
+ {
+ callback_data.msg_data.notification_indification_index = VOICE_NOTIFY_CMD_DISABLE;
+ }
+ break;
+
+ default:
+ handle = false;
+ break;
+ }
+ /* Notify Application. */
+ if (pfn_voice_cb && (handle == true))
+ {
+ pfn_voice_cb(service_id, (void *)&callback_data);
+ }
+
+ return;
+}
+
+/**
+ * @brief Vendor ble Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS VOICE_SERVICE_CBS =
+{
+ voice_attr_read_cb, /*Read callback function pointer*/
+ voice_attr_write_cb, /*Write callback function pointer*/
+ voice_cccd_update_cb, /*CCCD update callback function pointer*/
+};
+
+/*============================================================================*
+ * Global Functions
+ *============================================================================*/
+/**
+ * @brief add Vendor ble service to application.
+ *
+ * @param p_func pointer of app callback function called by profile.
+ * @return service ID auto generated by profile layer.
+ * @retval service_id
+*/
+uint8_t voice_service_add_service(void *p_func)
+{
+ uint8_t service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)VOICE_SERVICE_GATT_TABLE,
+ sizeof(VOICE_SERVICE_GATT_TABLE),
+ VOICE_SERVICE_CBS))
+ {
+ APP_PRINT_ERROR1("[voice_service_add_service]failed, service_id = %d", service_id);
+ service_id = 0xff;
+ return service_id;
+ }
+ pfn_voice_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ APP_PRINT_INFO1("[voice_service_add_service] service_id = %d", service_id);
+ return service_id;
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/ble/profile/server/wss.c b/src/ble/profile/server/wss.c
new file mode 100644
index 0000000..1486fad
--- /dev/null
+++ b/src/ble/profile/server/wss.c
@@ -0,0 +1,502 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file wss.c
+* @brief weight scale service source file.
+* @details Interface to access the weight scale service.
+* @author Vera
+* @date
+* @version v1.0
+*********************************************************************************************************
+*/
+#include "trace.h"
+#include <string.h>
+#include "gatt.h"
+#include "wss.h"
+
+
+/* Weight scale service UUID */
+#define GATT_UUID_WEIGHT_SCALE_SERVICE 0x181D
+/* Weight scale feature characteristic UUID*/
+#define GATT_UUID_CHAR_WEIGHT_SCALE_FEATURE_READ 0x2A9E
+/* Weight measurement characteristic UUID*/
+#define GATT_UUID_CHAR_WEIGHT_MEASUREMENT_INDICATE 0x2A9D
+
+/** @brief The Maximum Length of Weight Measurement Value*/
+#define WSS_MEASUREMENT_VALUE_MAX_LEN 15
+
+
+/** @brief Index of each characteristic in weight scale service database. */
+#define WEIGHT_SCALE_SERVICE_CHAR_FEATURE_READ_INDEX 0x02
+#define WEIGHT_SCALE_SERVICE_CHAR_MEASUREMENT_INDICATE_INDEX 0x04
+#define WEIGHT_SCALE_SERVICE_CHAR_INDICATE_CCCD_INDEX (WEIGHT_SCALE_SERVICE_CHAR_MEASUREMENT_INDICATE_INDEX + 1)
+
+#define WSS_FEATURE_TIMESTAMP_SUPPORTED 1
+#define WSS_FEATURE_MULTIUSERS_SUPPORTED 1
+#define WSS_FEATURE_BMI_SUPPORTED 1
+#define WSS_FEATURE_WEIGHTMEASUREMENT_RESOLUTION 1
+#define WSS_FEATURE_HEIGHTMEASUREMENT_RESOLUTION 1
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+/**< Value of weight scale feature read characteristic. */
+static T_WEIGHT_SCALE_FEATURE_VALUE weight_scale_char_read_value =
+{
+ WSS_FEATURE_TIMESTAMP_SUPPORTED,
+ WSS_FEATURE_MULTIUSERS_SUPPORTED,
+ WSS_FEATURE_BMI_SUPPORTED,
+ WSS_FEATURE_WEIGHTMEASUREMENT_RESOLUTION,
+ WSS_FEATURE_HEIGHTMEASUREMENT_RESOLUTION,
+ 0
+};
+
+/**< Function pointer used to send event to application from Weight Scale Service. Initiated in wss_add_service. */
+static P_FUN_SERVER_GENERAL_CB pfn_wss_cb = NULL;
+/**< Measurement Related Value. */
+static T_WSS_MEASUREMENT wss_measurement = {0};
+static uint8_t wss_measurement_value_for_indicate[WSS_MEASUREMENT_VALUE_MAX_LEN];
+static uint8_t wss_measurement_value_actual_length = 0;
+
+/**< @brief service definition. */
+/**< Attribute Table */
+static const T_ATTRIB_APPL wss_tbl[] =
+{
+ /* <<Primary Service>>, .. 0*/
+ {
+ (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_PRIMARY_SERVICE),
+ HI_WORD(GATT_UUID_PRIMARY_SERVICE),
+ LO_WORD(GATT_UUID_WEIGHT_SCALE_SERVICE), /* service UUID */
+ HI_WORD(GATT_UUID_WEIGHT_SCALE_SERVICE)
+ },
+ UUID_16BIT_SIZE, /* bValueLen */
+ NULL, /* pValueContext */
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* <<Characteristic>> for read , .. 1*/
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ GATT_CHAR_PROP_READ /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* Weight Scale Feature value , .. 2 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_WEIGHT_SCALE_FEATURE_READ),
+ HI_WORD(GATT_UUID_CHAR_WEIGHT_SCALE_FEATURE_READ)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+
+ /* <<Characteristic>> for indicate , .. 3 */
+ {
+ ATTRIB_FLAG_VALUE_INCL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHARACTERISTIC),
+ HI_WORD(GATT_UUID_CHARACTERISTIC),
+ (GATT_CHAR_PROP_INDICATE) /* characteristic properties */
+ /* characteristic UUID not needed here, is UUID of next attrib. */
+ },
+ 1, /* bValueLen */
+ NULL,
+ GATT_PERM_READ /* wPermissions */
+ },
+ /* Weight Measurement value , .. 4 */
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_WEIGHT_MEASUREMENT_INDICATE),
+ HI_WORD(GATT_UUID_CHAR_WEIGHT_MEASUREMENT_INDICATE)
+ },
+ 0, /* bValueLen */
+ NULL,
+ GATT_PERM_NONE /* wPermissions */
+ },
+ /* client characteristic configuration , .. 5 */
+ {
+ ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG),
+ /* NOTE: this value has an instantiation for each client, a write to */
+ /* this attribute does not modify this default value: */
+ LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */
+ HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT)
+ },
+ 2, /* bValueLen */
+ NULL,
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+ },
+
+};
+
+/**
+ * @brief Set a weight scale service parameter.
+ *
+ * NOTE: You can call this function with a weight scale service parameter type and it will set the
+ * weight scale service parameter. Weight scale service parameters are defined in @ref T_WSS_PARAM_TYPE.
+ * If the "len" field sets to the size of a "uint16_t" ,the
+ * "p_value" field must point to a data with type of "uint16_t".
+ *
+ * @param[in] param_type Weight scale service parameter type: @ref T_WSS_PARAM_TYPE
+ * @param[in] len Length of data to write
+ * @param[in] p_value Pointer to data to write. This is dependent on
+ * the parameter type and WILL be cast to the appropriate
+ * data type (For example: if data type of param is uint16_t, p_value will be cast to
+ * pointer of uint16_t).
+ *
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint32_t weight_feature = 0x0000001f;
+ wss_set_parameter(WSS_PARAM_FEATURE_READ_CHAR_VAL, 4, &weight_feature);
+ }
+ * \endcode
+ */
+bool wss_set_parameter(T_WSS_PARAM_TYPE param_type, uint8_t len, void *p_value)
+{
+ bool ret = true;
+
+ switch (param_type)
+ {
+ default:
+ {
+ ret = false;
+ PROFILE_PRINT_ERROR0("wss_set_parameter failed\n");
+ }
+ break;
+ case WSS_PARAM_MEASUREMENT_WEIGHTPARAM_FLAG:
+ {
+ if (len != 1)
+ {
+ PROFILE_PRINT_ERROR0("wss_set_parameter measurement weightParam Flag \n");
+ }
+ memcpy(&wss_measurement.flag, p_value, len);
+ }
+ break;
+ case WSS_PARAM_MEASUREMENT_WEIGHT_VALUE:
+ {
+ if (len != 2)
+ {
+ PROFILE_PRINT_ERROR0("wss_set_parameter measurement weight value \n");
+ break;
+ }
+ if (wss_measurement.flag.measurement_units == 0)
+ {
+ memcpy(&wss_measurement.weight_si_value, p_value, len);
+ }
+ else
+ {
+ memcpy(&wss_measurement.weight_imperial_value, p_value, len);
+ }
+ }
+ break;
+ case WSS_PARAM_MEASUREMENT_TIME_STAMP:
+ {
+ if (len != sizeof(T_WSS_TIME_STAMP))
+ {
+ PROFILE_PRINT_ERROR0("wss_set_parameter weight measurement time stamp \n");
+ break;
+ }
+
+ memcpy(&wss_measurement.time_stamp, p_value, len);
+
+ }
+ break;
+ case WSS_PARAM_MEASUREMENT_USERID:
+ {
+ if (len != 1)
+ {
+ PROFILE_PRINT_ERROR0("wss_set_parameter weight measurement user_id \n");
+ break;
+ }
+
+ memcpy(&wss_measurement.user_id, p_value, len);
+ }
+ break;
+ case WSS_PARAM_MEASUREMENT_BMI:
+ {
+ if (len != 2)
+ {
+ PROFILE_PRINT_ERROR0("wss_set_parameter weight measurement bmi \n");
+ break;
+ }
+
+ memcpy(&wss_measurement.bmi, p_value, len);
+
+ }
+ break;
+ case WSS_PARAM_MEASUREMENT_HEIGHT_VALUE:
+ {
+ if (len != 2)
+ {
+ PROFILE_PRINT_ERROR0("wss_set_parameter height value \n");
+ break;
+ }
+ if (wss_measurement.flag.measurement_units == 0)
+ {
+ memcpy(&wss_measurement.height_si_value, p_value, len);
+ }
+ else
+ {
+ memcpy(&wss_measurement.height_imperial_value, p_value, len);
+ }
+
+ }
+ break;
+ case WSS_PARAM_FEATURE_READ_CHAR_VAL:
+ {
+ if (len != 4)
+ {
+ PROFILE_PRINT_ERROR0("wss_set_parameter feature value \n");
+ break;
+ }
+ memcpy(&weight_scale_char_read_value, p_value, len);
+
+ }
+ }
+
+ if (!ret)
+ {
+ PROFILE_PRINT_ERROR0("wss_set_parameter failed\n");
+ }
+ if (ret)
+ {
+ PROFILE_PRINT_INFO0("wss_set_parameter success\n");
+ }
+
+ return ret;
+}
+
+
+void wss_format_measurement_value()
+{
+ uint8_t cur_offset = 0;
+
+ memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.flag, 1);
+ cur_offset += 1;
+
+ if (wss_measurement.flag.measurement_units == 0)
+ {
+ memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.weight_si_value, 2);
+ }
+ else
+ {
+ memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.weight_imperial_value, 2);
+ }
+ cur_offset += 2;
+
+ if (wss_measurement.flag.time_stamp_present)
+ {
+ memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.time_stamp, 7);
+ cur_offset += 7;
+ }
+
+ if (wss_measurement.flag.user_id_present)
+ {
+ memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.user_id, 1);
+ cur_offset += 1;
+ }
+ if (wss_measurement.flag.bmi_and_height_present)
+ {
+ memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.bmi, 2);
+ cur_offset += 2;
+ if (wss_measurement.flag.measurement_units == 0)
+ {
+ memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.height_si_value, 2);
+ }
+ else
+ {
+ memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.height_imperial_value, 2);
+ }
+ cur_offset += 2;
+ }
+
+ wss_measurement_value_actual_length = cur_offset;
+
+}
+
+
+/**
+ * @brief read characteristic data from service.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id ServiceID of characteristic data.
+ * @param[in] attrib_index Attribute index of getting characteristic data.
+ * @param[in] offset Used for Blob Read.
+ * @param[in,out] p_length Length of getting characteristic data.
+ * @param[in,out] pp_value Data got from service.
+ * @return Profile procedure result
+*/
+T_APP_RESULT wss_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index,
+ uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
+{
+ T_APP_RESULT wCause = APP_RESULT_SUCCESS;
+
+ switch (attrib_index)
+ {
+ default:
+ PROFILE_PRINT_ERROR1("wss_attr_read_cb, Attr not found, index=%d", attrib_index);
+ wCause = APP_RESULT_ATTR_NOT_FOUND;
+ break;
+ case WEIGHT_SCALE_SERVICE_CHAR_FEATURE_READ_INDEX:
+ {
+ PROFILE_PRINT_INFO1("wss_attr_read_cb, index = %d", attrib_index);
+
+ T_WSS_CALLBACK_DATA callback_data;
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE;
+ callback_data.msg_data.read_value_index = WEIGHT_SCALE_READ_FEATURE;
+ pfn_wss_cb(service_id, (void *)&callback_data);
+ *pp_value = (uint8_t *)&weight_scale_char_read_value;
+ *p_length = sizeof(weight_scale_char_read_value);
+ PROFILE_PRINT_INFO2("wss_attr_read_cb weight_scale_char_read_value = %x,Length = %d",
+ weight_scale_char_read_value, *p_length);
+ }
+ break;
+ }
+
+ return (wCause);
+}
+
+/**
+ * @brief Send measurement indication data.
+ *
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service id.
+ * @return Operation result.
+ * @retval true Operation success.
+ * @retval false Operation failure.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ uint8_t wm_flag = WSS_FLAG_MEASUREMENT_UINT_BIT
+ | WSS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT
+ | WSS_FLAG_MEASUREMENT_USERID_PRESENT_BIT
+ | WSS_FLAG_MEASUREMENT_BMI_PRESENT_BIT;
+
+ wss_set_parameter(WSS_PARAM_MEASUREMENT_WEIGHTPARAM_FLAG, sizeof(wm_flag), &wm_flag);
+ wss_set_parameter(WSS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(wss_measure_time_stamp),
+ &wss_measure_time_stamp);
+ wss_measurement_indicate(p_parse_value->dw_param[0], wss_id);
+ }
+ * \endcode
+ */
+bool wss_measurement_indicate(uint8_t conn_id, T_SERVER_ID service_id)
+{
+ wss_format_measurement_value();
+
+ PROFILE_PRINT_INFO0("WeightScaleService_Measurement_Indicate");
+ // send indication to client
+ return server_send_data(conn_id, service_id, WEIGHT_SCALE_SERVICE_CHAR_MEASUREMENT_INDICATE_INDEX,
+ (uint8_t *)&wss_measurement_value_for_indicate, wss_measurement_value_actual_length,
+ GATT_PDU_TYPE_INDICATION);
+}
+
+/**
+ * @brief update CCCD bits from stack.
+ *
+ * @param[in] conn_id Connection id.
+ * @param[in] service_id Service ID.
+ * @param[in] index Attribute index of characteristic data.
+ * @param[in] ccc_bits CCCD bits from stack.
+ * @return None
+*/
+void wss_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits)
+{
+ T_WSS_CALLBACK_DATA callback_data;
+ bool handle = false;
+ PROFILE_PRINT_INFO2("wss_cccd_update_cb Index = %d wCCCDBits %x", index, ccc_bits);
+ switch (index)
+ {
+ case WEIGHT_SCALE_SERVICE_CHAR_INDICATE_CCCD_INDEX:
+ {
+ if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE)
+ {
+ // Enable Indication
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indication_index = WSS_INDICATE_WEIGHT_MEASUREMENT_ENABLE;
+ }
+ else
+ {
+ // Disable Indication
+ callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
+ callback_data.msg_data.notification_indication_index = WSS_INDICATE_WEIGHT_MEASUREMENT_DISABLE;
+ }
+ handle = true;
+ }
+ break;
+ default:
+ break;
+ }
+ if (pfn_wss_cb && (handle == true))
+ {
+ pfn_wss_cb(service_id, (void *)&callback_data);
+ }
+}
+
+/**
+ * @brief Weight Scale Service Callbacks.
+*/
+const T_FUN_GATT_SERVICE_CBS wss_cbs =
+{
+ wss_attr_read_cb, // Read callback function pointer
+ NULL, // Write callback function pointer
+ wss_cccd_update_cb // CCCD update callback function pointer
+};
+
+/**
+ * @brief Add Weight scale service to the BLE stack database.
+ *
+ *
+ * @param[in] p_func Callback when service attribute was read, write or cccd update.
+ * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
+ * @retval 0xFF Operation failure.
+ * @retval Others Service id assigned by stack.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void profile_init()
+ {
+ server_init(1);
+ wss_id = wss_add_service(app_handle_profile_message);
+ }
+ * \endcode
+ */
+T_SERVER_ID wss_add_service(void *p_func)
+{
+ T_SERVER_ID service_id;
+ if (false == server_add_service(&service_id,
+ (uint8_t *)wss_tbl,
+ sizeof(wss_tbl),
+ wss_cbs))
+ {
+ PROFILE_PRINT_ERROR1("wss_add_service: ServiceId %d", service_id);
+ service_id = 0xff;
+ return service_id;
+ }
+ PROFILE_PRINT_INFO1("wss_add_service: ServiceId %d", service_id);
+ pfn_wss_cb = (P_FUN_SERVER_GENERAL_CB)p_func;
+ return service_id;
+}
+
diff --git a/src/ble/sample/ams.c b/src/ble/sample/ams.c
new file mode 100644
index 0000000..6aa4c9c
--- /dev/null
+++ b/src/ble/sample/ams.c
@@ -0,0 +1,142 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ams.c
+ * @brief This file handles AMS Client routines.
+ * @author
+ * @date
+ * @version
+ **************************************************************************************
+*/
+#include "app_flags.h"
+#if F_BT_AMS_CLIENT_SUPPORT
+#include <trace.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ams.h>
+#include <ams_client.h>
+
+T_CLIENT_ID ams_client;
+
+/**
+ * @brief ams client callback handle message from upperstack
+ */
+T_APP_RESULT ams_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_AMS_CB_DATA *p_cb_data = (T_AMS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case AMS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case AMS_DISC_DONE:
+ APP_PRINT_INFO0("ams_client_cb: discover procedure done.");
+ ams_subscribe_remote_cmd(conn_id, true);
+ break;
+ case AMS_DISC_FAILED:
+ APP_PRINT_ERROR0("ams_client_cb: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case AMS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case AMS_NOTIFY_FROM_REMOTE_CMD:
+ APP_PRINT_INFO2("AMS_NOTIFY_FROM_REMOTE_CMD: data[%d]: %b",
+ p_cb_data->cb_content.notify_data.value_size,
+ TRACE_BINARY(p_cb_data->cb_content.notify_data.value_size,
+ p_cb_data->cb_content.notify_data.p_value));
+ break;
+ case AMS_NOTIFY_FROM_ENTITY_UPD:
+ APP_PRINT_INFO2("AMS_NOTIFY_FROM_ENTITY_UPD: data[%d]: %b",
+ p_cb_data->cb_content.notify_data.value_size,
+ TRACE_BINARY(p_cb_data->cb_content.notify_data.value_size,
+ p_cb_data->cb_content.notify_data.p_value));
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case AMS_CLIENT_CB_TYPE_READ_RESULT:
+ switch (p_cb_data->cb_content.read_data.type)
+ {
+ case AMS_READ_FROM_ENTITY_UPD:
+ APP_PRINT_INFO3("AMS_READ_FROM_ENTITY_UPD: cause 0x%x, data[%d]: %b",
+ p_cb_data->cb_content.read_data.cause,
+ p_cb_data->cb_content.read_data.value_size,
+ TRACE_BINARY(p_cb_data->cb_content.read_data.value_size, p_cb_data->cb_content.read_data.p_value));
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case AMS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("AMS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case AMS_WRITE_REMOTE_CMD_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("AMS_WRITE_REMOTE_CMD_NOTIFY_ENABLE");
+ ams_subscribe_entity_upd(conn_id, true);
+ break;
+
+ case AMS_WRITE_REMOTE_CMD_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("AMS_WRITE_REMOTE_CMD_NOTIFY_DISABLE");
+ break;
+
+ case AMS_WRITE_ENTITY_UPD_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("AMS_WRITE_ENTITY_UPD_NOTIFY_ENABLE");
+
+ break;
+ case AMS_WRITE_ENTITY_UPD_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("AMS_WRITE_ENTITY_UPD_NOTIFY_DISABLE");
+ break;
+
+ case AMS_WRITE_ENTITY_ATTR_VALUE:
+ APP_PRINT_INFO0("AMS_WRITE_ENTITY_ATTR_VALUE");
+ break;
+
+ case AMS_WRITE_REMOTE_CMD_VALUE:
+ APP_PRINT_INFO0("AMS_WRITE_REMOTE_CMD_VALUE");
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case AMS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ APP_PRINT_INFO1("AMS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+/**
+ * @brief App register ams client to upperstack.
+ */
+void ams_init(uint8_t link_num)
+{
+ ams_client = ams_add_client(ams_client_cb, link_num);
+}
+
+#endif
+
diff --git a/src/ble/sample/ams.h b/src/ble/sample/ams.h
new file mode 100644
index 0000000..bc2a8a1
--- /dev/null
+++ b/src/ble/sample/ams.h
@@ -0,0 +1,33 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ams.h
+* @brief
+* @details
+* @author
+* @date
+* @version
+* *********************************************************************************************************
+*/
+
+
+#ifndef _AMS_H__
+#define _AMS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <gap_le.h>
+
+#define AMS_LINK_NUM 1
+
+void ams_init(uint8_t link_num);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/ble/upperstack_lib.c b/src/ble/upperstack_lib.c
new file mode 100644
index 0000000..9a4dec8
--- /dev/null
+++ b/src/ble/upperstack_lib.c
@@ -0,0 +1,9970 @@
+/* http://srecord.sourceforge.net/ */
+#include "mem_config.h"
+__attribute__((at(UPPERSTACK_FLASH_ADDR))) __attribute__((used)) const unsigned char
+upperstack_lib_img[] =
+{
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x10, 0x00, 0x90, 0x5A, 0x51, 0xFF, 0x97, 0x64, 0x65, 0x76, 0x23,
+ 0x23, 0x23, 0x23, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB5, 0xF6, 0xF7,
+ 0x61, 0xDF, 0x07, 0x4B, 0x07, 0xA2, 0x0A, 0xA1, 0x4F, 0xF0, 0x04, 0x50,
+ 0xF9, 0xF7, 0x9C, 0xDD, 0x00, 0xF0, 0xB2, 0xF8, 0x00, 0xF0, 0xB5, 0xF8,
+ 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0x9E, 0xB8, 0x5A, 0x51, 0xFF, 0x97,
+ 0x30, 0x2E, 0x30, 0x2E, 0x31, 0x2E, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x55, 0x70, 0x70, 0x65, 0x72, 0x73, 0x74, 0x61, 0x63, 0x6B, 0x20, 0x56,
+ 0x65, 0x72, 0x3A, 0x20, 0x25, 0x73, 0x2C, 0x20, 0x47, 0x43, 0x49, 0x44,
+ 0x3A, 0x20, 0x30, 0x78, 0x25, 0x78, 0x00, 0x00, 0x40, 0xBA, 0x70, 0x47,
+ 0xC0, 0xBA, 0x70, 0x47, 0x4F, 0xEA, 0x30, 0x00, 0x70, 0x47, 0x43, 0x1A,
+ 0x28, 0xBF, 0x9A, 0x42, 0x40, 0xF2, 0xAA, 0x80, 0x03, 0x2A, 0x10, 0x44,
+ 0x11, 0x44, 0x40, 0xF2, 0x26, 0x80, 0x10, 0xF0, 0x03, 0x0F, 0x1E, 0xBF,
+ 0x11, 0xF8, 0x01, 0x3D, 0x52, 0x1E, 0x00, 0xF8, 0x01, 0x3D, 0x10, 0xF0,
+ 0x03, 0x0F, 0x7F, 0xF4, 0xF6, 0xAF, 0x11, 0xF0, 0x03, 0x03, 0x00, 0xF0,
+ 0x3B, 0x80, 0x08, 0x3A, 0xC0, 0xF0, 0x0B, 0x80, 0x51, 0xF8, 0x04, 0x3D,
+ 0x08, 0x3A, 0x51, 0xF8, 0x04, 0xCD, 0x40, 0xF8, 0x04, 0x3D, 0x40, 0xF8,
+ 0x04, 0xCD, 0xFF, 0xF7, 0xF3, 0xBF, 0x12, 0x1D, 0x5C, 0xBF, 0x51, 0xF8,
+ 0x04, 0x3D, 0x40, 0xF8, 0x04, 0x3D, 0xAF, 0xF3, 0x00, 0x80, 0xD2, 0x07,
+ 0x24, 0xBF, 0x11, 0xF8, 0x01, 0x3D, 0x11, 0xF8, 0x01, 0xCD, 0x48, 0xBF,
+ 0x11, 0xF8, 0x01, 0x2C, 0x24, 0xBF, 0x00, 0xF8, 0x01, 0x3D, 0x00, 0xF8,
+ 0x01, 0xCD, 0x48, 0xBF, 0x00, 0xF8, 0x01, 0x2C, 0x70, 0x47, 0x43, 0x1A,
+ 0x28, 0xBF, 0x9A, 0x42, 0x40, 0xF2, 0x6A, 0x80, 0x10, 0x44, 0x10, 0xF0,
+ 0x03, 0x0F, 0x11, 0x44, 0x1E, 0xBF, 0x11, 0xF8, 0x01, 0x3D, 0x52, 0x1E,
+ 0x00, 0xF8, 0x01, 0x3D, 0x10, 0xF0, 0x03, 0x0F, 0x7F, 0xF4, 0xF6, 0xAF,
+ 0x10, 0x3A, 0xC0, 0xF0, 0x0A, 0x80, 0x10, 0xB5, 0x31, 0xE9, 0x18, 0x50,
+ 0x10, 0x3A, 0x20, 0xE9, 0x18, 0x50, 0xBF, 0xF4, 0xF9, 0xAF, 0xBD, 0xE8,
+ 0x10, 0x40, 0x53, 0x07, 0x24, 0xBF, 0x31, 0xE9, 0x08, 0x10, 0x20, 0xE9,
+ 0x08, 0x10, 0x44, 0xBF, 0x51, 0xF8, 0x04, 0x3D, 0x40, 0xF8, 0x04, 0x3D,
+ 0x12, 0xF0, 0x03, 0x0F, 0x08, 0xBF, 0x70, 0x47, 0xD2, 0x07, 0x28, 0xBF,
+ 0x31, 0xF8, 0x02, 0x3D, 0x48, 0xBF, 0x11, 0xF8, 0x01, 0x2C, 0x28, 0xBF,
+ 0x20, 0xF8, 0x02, 0x3D, 0x48, 0xBF, 0x00, 0xF8, 0x01, 0x2C, 0x70, 0x47,
+ 0x10, 0xB5, 0x00, 0x22, 0x03, 0x49, 0x04, 0x48, 0xF9, 0xF7, 0x47, 0xDD,
+ 0xBD, 0xE8, 0x10, 0x40, 0x01, 0xF0, 0x84, 0xBE, 0x00, 0x00, 0xC0, 0x08,
+ 0x02, 0x30, 0x10, 0x21, 0x08, 0x48, 0x09, 0x49, 0x09, 0x4A, 0x2B, 0xF4,
+ 0x4E, 0xB6, 0x10, 0xB5, 0x08, 0x48, 0x09, 0x49, 0x09, 0x4A, 0x2B, 0xF4,
+ 0x48, 0xF6, 0xBD, 0xE8, 0x10, 0x40, 0x08, 0x48, 0x08, 0x49, 0x2B, 0xF4,
+ 0xC1, 0xB6, 0x00, 0x00, 0x00, 0x74, 0x20, 0x00, 0xD0, 0xB5, 0x82, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x20, 0x00, 0xD0, 0xB5, 0x82, 0x00,
+ 0xD0, 0x00, 0x00, 0x00, 0xD0, 0x74, 0x20, 0x00, 0x40, 0x05, 0x00, 0x00,
+ 0x2B, 0xF4, 0x2F, 0xB6, 0x2B, 0xF4, 0x72, 0xB6, 0x30, 0xB5, 0x89, 0xB0,
+ 0x04, 0x46, 0x01, 0x25, 0x20, 0x22, 0x0C, 0xA1, 0x68, 0x46, 0x2B, 0xF4,
+ 0x69, 0xF6, 0x22, 0x46, 0x69, 0x46, 0x10, 0x46, 0xFA, 0xF7, 0x1D, 0xDF,
+ 0x00, 0x21, 0x60, 0x5C, 0x40, 0x1C, 0x60, 0x54, 0x49, 0x1C, 0xC9, 0xB2,
+ 0x10, 0x29, 0xF8, 0xD3, 0x22, 0x46, 0x69, 0x46, 0x10, 0x46, 0xFA, 0xF7,
+ 0xE2, 0xDE, 0x09, 0xB0, 0x28, 0x46, 0x30, 0xBD, 0x97, 0x86, 0xC1, 0x98,
+ 0x70, 0xD3, 0x4D, 0xCF, 0xAF, 0xDA, 0x11, 0x3A, 0x80, 0xBC, 0xD1, 0x2A,
+ 0x4B, 0x1F, 0x9B, 0xD6, 0x4B, 0xA7, 0x4E, 0xA2, 0x96, 0x41, 0xB1, 0x35,
+ 0xFD, 0xC4, 0x27, 0x6B, 0x1C, 0xB5, 0x01, 0x24, 0x04, 0x23, 0x12, 0x28,
+ 0x24, 0xD0, 0x12, 0xDC, 0x09, 0x28, 0x48, 0xD0, 0x08, 0xDC, 0x01, 0x28,
+ 0x39, 0xD0, 0x03, 0x28, 0x3A, 0xD0, 0x05, 0x28, 0x3B, 0xD0, 0x07, 0x28,
+ 0x2A, 0xD1, 0x3B, 0xE0, 0x0B, 0x28, 0x3F, 0xD0, 0x0D, 0x28, 0x3D, 0xD0,
+ 0x11, 0x28, 0x23, 0xD1, 0x31, 0xE0, 0x1B, 0x28, 0x3E, 0xD0, 0x06, 0xDC,
+ 0x16, 0x28, 0x1F, 0xD0, 0x17, 0x28, 0x36, 0xD0, 0x18, 0x28, 0x19, 0xD1,
+ 0x1D, 0xE0, 0x1D, 0x28, 0x34, 0xD0, 0x52, 0x28, 0x02, 0xD0, 0xD2, 0x28,
+ 0x12, 0xD1, 0x06, 0xE0, 0x03, 0x29, 0x0F, 0xD2, 0x00, 0x24, 0x12, 0x28,
+ 0x04, 0xD1, 0x13, 0x60, 0x02, 0xE0, 0x0F, 0x29, 0x08, 0xDA, 0x00, 0x24,
+ 0xCD, 0xE9, 0x00, 0x12, 0x03, 0x46, 0x03, 0x22, 0x12, 0x49, 0x13, 0x48,
+ 0xF9, 0xF7, 0xAF, 0xDC, 0x20, 0x46, 0x1C, 0xBD, 0x05, 0x29, 0x02, 0xD3,
+ 0xFA, 0xE7, 0x02, 0x29, 0xF8, 0xD0, 0x00, 0x24, 0xE9, 0xE7, 0x05, 0x29,
+ 0xEB, 0xD1, 0xF3, 0xE7, 0x03, 0x29, 0xE8, 0xD1, 0xF0, 0xE7, 0x06, 0x29,
+ 0xE5, 0xDB, 0xED, 0xE7, 0x05, 0x29, 0xE2, 0xDB, 0xEA, 0xE7, 0x04, 0x29,
+ 0xDF, 0xDB, 0xE7, 0xE7, 0x00, 0x29, 0xDC, 0xD0, 0xE4, 0xE7, 0x05, 0x29,
+ 0xD9, 0xD3, 0xE1, 0xE7, 0x03, 0x29, 0xD6, 0xD3, 0xDE, 0xE7, 0x00, 0x00,
+ 0xA4, 0x47, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21, 0x38, 0xB5, 0x04, 0x46,
+ 0x03, 0x29, 0x29, 0xD0, 0x14, 0x29, 0x27, 0xD0, 0x15, 0x29, 0x25, 0xD0,
+ 0x60, 0x68, 0x82, 0x79, 0x50, 0x1C, 0xC3, 0xB2, 0x19, 0x29, 0x1F, 0xD8,
+ 0xC8, 0x07, 0x1D, 0xD0, 0x0F, 0x48, 0x01, 0x2B, 0x12, 0xD0, 0x01, 0x29,
+ 0x18, 0xD0, 0x8B, 0x42, 0x16, 0xD0, 0x0B, 0x46, 0x00, 0x92, 0x02, 0x22,
+ 0x0B, 0x49, 0xF9, 0xF7, 0x6C, 0xDC, 0x00, 0x21, 0x20, 0x46, 0x00, 0xF0,
+ 0x75, 0xFF, 0x61, 0x68, 0x00, 0x20, 0x88, 0x71, 0x00, 0x20, 0x38, 0xBD,
+ 0x0B, 0x46, 0x05, 0x49, 0x00, 0x92, 0x02, 0x22, 0x54, 0x39, 0xF9, 0xF7,
+ 0x5C, 0xDC, 0xF5, 0xE7, 0x01, 0x20, 0x38, 0xBD, 0x00, 0x38, 0x10, 0x21,
+ 0x50, 0x47, 0xC0, 0x08, 0x10, 0xB5, 0x04, 0x46, 0x01, 0x21, 0x00, 0xF0,
+ 0x5D, 0xFF, 0x00, 0x21, 0x20, 0x46, 0x0A, 0xF0, 0x19, 0xFC, 0x00, 0x20,
+ 0x10, 0xBD, 0x70, 0xB5, 0x05, 0x46, 0x48, 0x78, 0x0C, 0x46, 0x02, 0x28,
+ 0x0E, 0xD0, 0x00, 0x21, 0x28, 0x46, 0x00, 0xF0, 0x4D, 0xFF, 0x69, 0x68,
+ 0x00, 0x20, 0x88, 0x71, 0x01, 0x46, 0x23, 0x79, 0x62, 0x78, 0x28, 0x46,
+ 0xBD, 0xE8, 0x70, 0x40, 0x09, 0xF0, 0x58, 0xBF, 0x69, 0x68, 0xC8, 0x79,
+ 0x00, 0x28, 0x01, 0xD0, 0x40, 0x1E, 0xC8, 0x71, 0x70, 0xBD, 0x10, 0xB5,
+ 0x82, 0x68, 0x00, 0x24, 0x32, 0xF8, 0x08, 0x3F, 0x0B, 0xB1, 0x0E, 0x24,
+ 0x06, 0xE0, 0x44, 0xF2, 0x05, 0x03, 0x13, 0x80, 0x49, 0x78, 0x00, 0x8E,
+ 0x03, 0xF0, 0xC0, 0xF8, 0x20, 0x46, 0x10, 0xBD, 0x70, 0xB5, 0x04, 0x46,
+ 0x00, 0x21, 0x00, 0xF0, 0x25, 0xFF, 0x60, 0x68, 0x00, 0x25, 0x85, 0x71,
+ 0x21, 0x8E, 0x28, 0x46, 0x03, 0xF0, 0xE4, 0xFE, 0x60, 0x68, 0x05, 0x81,
+ 0x70, 0xBD, 0x7C, 0xB5, 0x05, 0x46, 0x04, 0x20, 0x14, 0x46, 0x08, 0x2A,
+ 0x10, 0xD3, 0x48, 0x78, 0x8A, 0x78, 0x0B, 0x79, 0x00, 0xEB, 0x02, 0x20,
+ 0xCA, 0x78, 0x00, 0x04, 0x02, 0xEB, 0x03, 0x22, 0x00, 0x0C, 0x92, 0xB2,
+ 0x01, 0xD0, 0x90, 0x42, 0x03, 0xD9, 0x01, 0x21, 0x41, 0xEA, 0x00, 0x40,
+ 0x7C, 0xBD, 0x4B, 0x79, 0x8E, 0x79, 0xC9, 0x1D, 0xE4, 0x1F, 0xCD, 0xE9,
+ 0x00, 0x41, 0x03, 0xEB, 0x06, 0x23, 0x01, 0x46, 0x9B, 0xB2, 0x28, 0x46,
+ 0x0A, 0xF0, 0x9E, 0xFD, 0x7C, 0xBD, 0x0B, 0x46, 0x52, 0x1E, 0x91, 0x08,
+ 0x04, 0x22, 0x5B, 0x1C, 0x00, 0xF0, 0x4F, 0xB9, 0x30, 0xB4, 0x04, 0x46,
+ 0x04, 0x20, 0x0B, 0x46, 0x05, 0x2A, 0x10, 0xD1, 0x58, 0x78, 0x99, 0x78,
+ 0x1A, 0x79, 0x00, 0xEB, 0x01, 0x20, 0x01, 0x04, 0xD8, 0x78, 0x09, 0x0C,
+ 0x00, 0xEB, 0x02, 0x20, 0x82, 0xB2, 0x01, 0xD0, 0x91, 0x42, 0x04, 0xD9,
+ 0x01, 0x20, 0x40, 0xEA, 0x01, 0x40, 0x30, 0xBC, 0x70, 0x47, 0x20, 0x46,
+ 0x30, 0xBC, 0x0A, 0xF0, 0xA9, 0xBD, 0x30, 0xB4, 0x94, 0x1E, 0x4A, 0x78,
+ 0x01, 0x2A, 0x07, 0xD0, 0x12, 0x22, 0x94, 0xFB, 0xF2, 0xF4, 0x8B, 0x1C,
+ 0x21, 0x46, 0x30, 0xBC, 0x00, 0xF0, 0x25, 0xB9, 0x04, 0x22, 0xF6, 0xE7,
+ 0xF8, 0xB5, 0x05, 0x46, 0x03, 0x20, 0x0C, 0x46, 0x16, 0x46, 0x13, 0x46,
+ 0x00, 0x90, 0x02, 0x22, 0x0A, 0x49, 0x0B, 0x48, 0xF9, 0xF7, 0xA9, 0xDB,
+ 0x03, 0x2E, 0x01, 0xD2, 0x04, 0x20, 0xF8, 0xBD, 0x29, 0x8D, 0x28, 0x46,
+ 0x00, 0xF0, 0x8F, 0xFB, 0x60, 0x78, 0xA1, 0x78, 0x00, 0xEB, 0x01, 0x20,
+ 0x81, 0xB2, 0x28, 0x46, 0x00, 0xF0, 0x02, 0xFE, 0x00, 0x20, 0xF8, 0xBD,
+ 0xC4, 0x46, 0xC0, 0x08, 0x02, 0x38, 0x10, 0x21, 0x42, 0x68, 0xD3, 0x79,
+ 0x00, 0x2B, 0x08, 0xD0, 0x5B, 0x1E, 0xD3, 0x71, 0x4A, 0x78, 0x89, 0x78,
+ 0x02, 0xEB, 0x01, 0x21, 0x89, 0xB2, 0x00, 0xF0, 0xEF, 0xBD, 0x70, 0x47,
+ 0x38, 0xB5, 0xD3, 0x1E, 0x4A, 0x78, 0x8C, 0x78, 0x02, 0xEB, 0x04, 0x22,
+ 0xCC, 0x1C, 0x00, 0x94, 0x09, 0x78, 0x92, 0xB2, 0x1B, 0x29, 0x03, 0xD0,
+ 0x00, 0x21, 0x0B, 0xF0, 0x51, 0xF8, 0x38, 0xBD, 0x01, 0x21, 0xFA, 0xE7,
+ 0x7C, 0xB5, 0x01, 0x24, 0x1C, 0x70, 0x4C, 0x78, 0x8E, 0x78, 0x4D, 0x1D,
+ 0x04, 0xEB, 0x06, 0x24, 0xCE, 0x78, 0x09, 0x79, 0x24, 0x04, 0x06, 0xEB,
+ 0x01, 0x21, 0x24, 0x0C, 0x89, 0xB2, 0xA2, 0xF1, 0x05, 0x02, 0x06, 0xD0,
+ 0xCD, 0xE9, 0x00, 0x53, 0x0B, 0x46, 0x21, 0x46, 0x0B, 0xF0, 0x56, 0xF8,
+ 0x7C, 0xBD, 0x01, 0x20, 0x7C, 0xBD, 0x70, 0xB5, 0x0C, 0x46, 0x16, 0x46,
+ 0x05, 0x46, 0x00, 0x21, 0x00, 0xF0, 0x5E, 0xFE, 0x69, 0x68, 0x00, 0x20,
+ 0x72, 0x1F, 0x88, 0x71, 0xE0, 0x78, 0x21, 0x79, 0x63, 0x1D, 0x00, 0xEB,
+ 0x01, 0x20, 0x81, 0xB2, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x0B, 0xF0,
+ 0x7B, 0xB8, 0x03, 0x46, 0x04, 0x20, 0x05, 0x2A, 0x0C, 0xD1, 0x48, 0x78,
+ 0x8A, 0x78, 0x00, 0xEB, 0x02, 0x20, 0x00, 0x04, 0x00, 0x0C, 0x04, 0xD0,
+ 0x0A, 0x46, 0x02, 0x21, 0x18, 0x46, 0x0B, 0xF0, 0xE3, 0xB9, 0x01, 0x20,
+ 0x70, 0x47, 0x70, 0xB5, 0x0E, 0x46, 0x15, 0x46, 0x04, 0x46, 0x00, 0x21,
+ 0x00, 0xF0, 0x36, 0xFE, 0x61, 0x68, 0x00, 0x20, 0x73, 0x1C, 0x88, 0x71,
+ 0x6A, 0x1E, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x02, 0x21, 0x0B, 0xF0,
+ 0x7F, 0xBA, 0x38, 0xB5, 0x04, 0x46, 0x04, 0x20, 0x53, 0x1F, 0x02, 0x2B,
+ 0x01, 0xD0, 0x10, 0x2B, 0x10, 0xD1, 0x48, 0x78, 0x8A, 0x78, 0x0D, 0x79,
+ 0x00, 0xEB, 0x02, 0x20, 0xCA, 0x78, 0x00, 0x04, 0x02, 0xEB, 0x05, 0x22,
+ 0x00, 0x0C, 0x92, 0xB2, 0x01, 0xD0, 0x90, 0x42, 0x03, 0xD9, 0x01, 0x21,
+ 0x41, 0xEA, 0x00, 0x40, 0x38, 0xBD, 0x49, 0x1D, 0x00, 0x91, 0x01, 0x46,
+ 0x20, 0x46, 0x0B, 0xF0, 0x4B, 0xF8, 0x38, 0xBD, 0x30, 0xB4, 0x13, 0x46,
+ 0x4A, 0x78, 0x9B, 0x1E, 0xB3, 0xFB, 0xF2, 0xF4, 0x8B, 0x1C, 0x21, 0x46,
+ 0x30, 0xBC, 0x00, 0xF0, 0x60, 0xB8, 0x38, 0xB5, 0x04, 0x46, 0x04, 0x20,
+ 0x53, 0x1F, 0x02, 0x2B, 0x01, 0xD0, 0x10, 0x2B, 0x10, 0xD1, 0x48, 0x78,
+ 0x8A, 0x78, 0x0D, 0x79, 0x00, 0xEB, 0x02, 0x20, 0xCA, 0x78, 0x00, 0x04,
+ 0x02, 0xEB, 0x05, 0x22, 0x00, 0x0C, 0x92, 0xB2, 0x01, 0xD0, 0x90, 0x42,
+ 0x03, 0xD9, 0x01, 0x21, 0x41, 0xEA, 0x00, 0x40, 0x38, 0xBD, 0x49, 0x1D,
+ 0x00, 0x91, 0x01, 0x46, 0x20, 0x46, 0x0B, 0xF0, 0x57, 0xF8, 0x38, 0xBD,
+ 0xF8, 0xB5, 0x0C, 0x46, 0x16, 0x46, 0x05, 0x46, 0x00, 0x21, 0x00, 0xF0,
+ 0xD7, 0xFD, 0x69, 0x68, 0x00, 0x20, 0xB6, 0x1E, 0x88, 0x71, 0x62, 0x78,
+ 0xB6, 0xFB, 0xF2, 0xF0, 0xB6, 0xFB, 0xF2, 0xF1, 0x02, 0xFB, 0x10, 0x63,
+ 0x0B, 0xB1, 0xD3, 0x1A, 0x49, 0x1C, 0xA4, 0x1C, 0x28, 0x46, 0x00, 0x94,
+ 0x0B, 0xF0, 0x72, 0xF8, 0xF8, 0xBD, 0x03, 0x46, 0x04, 0x20, 0x03, 0x2A,
+ 0x0C, 0xD1, 0x48, 0x78, 0x8A, 0x78, 0x00, 0xEB, 0x02, 0x20, 0x00, 0x04,
+ 0x00, 0x0C, 0x04, 0xD0, 0x0A, 0x46, 0x01, 0x21, 0x18, 0x46, 0x0B, 0xF0,
+ 0x57, 0xB9, 0x01, 0x20, 0x70, 0x47, 0x70, 0xB5, 0x0E, 0x46, 0x15, 0x46,
+ 0x04, 0x46, 0x00, 0x21, 0x00, 0xF0, 0xAA, 0xFD, 0x61, 0x68, 0x00, 0x20,
+ 0x73, 0x1C, 0x88, 0x71, 0x6A, 0x1E, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40,
+ 0x01, 0x21, 0x0B, 0xF0, 0xF3, 0xB9, 0x2D, 0xE9, 0xF0, 0x41, 0x0F, 0x46,
+ 0x1D, 0x46, 0x16, 0x46, 0x04, 0x46, 0x00, 0x21, 0x00, 0xF0, 0x96, 0xFD,
+ 0x61, 0x68, 0x00, 0x20, 0x2B, 0x46, 0x88, 0x71, 0x32, 0x46, 0x39, 0x46,
+ 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0x0A, 0xF0, 0x7D, 0xBC, 0x00, 0x00,
+ 0x2D, 0xE9, 0xFF, 0x4F, 0x89, 0xB0, 0x91, 0x46, 0x01, 0xEB, 0x09, 0x04,
+ 0x00, 0x25, 0x4F, 0xF0, 0x01, 0x0B, 0x01, 0x95, 0x8D, 0xF8, 0x08, 0xB0,
+ 0x20, 0x78, 0x8A, 0x46, 0x80, 0x46, 0x00, 0xF0, 0x40, 0x06, 0x2F, 0x46,
+ 0x43, 0x46, 0x5A, 0x46, 0x7F, 0x49, 0x80, 0x48, 0xF9, 0xF7, 0x65, 0xDA,
+ 0x41, 0x46, 0x09, 0x98, 0xFF, 0xF7, 0xD8, 0xFD, 0x00, 0x28, 0x6E, 0xD0,
+ 0x01, 0xAA, 0x40, 0x46, 0x0C, 0x99, 0xFF, 0xF7, 0x6F, 0xFD, 0x00, 0x28,
+ 0x01, 0x98, 0x01, 0xD0, 0x18, 0xB1, 0xC1, 0xE0, 0x00, 0x28, 0xF2, 0xD0,
+ 0xBE, 0xE0, 0x40, 0x46, 0xB8, 0xF1, 0x10, 0x0F, 0x39, 0xD0, 0x0B, 0xDC,
+ 0xB8, 0xF1, 0x0E, 0x0F, 0x23, 0xD2, 0xDF, 0xE8, 0x08, 0xF0, 0x22, 0x71,
+ 0x2E, 0x76, 0x46, 0x8E, 0x3A, 0x82, 0x40, 0x88, 0x4C, 0x94, 0x52, 0x9A,
+ 0x19, 0x28, 0x71, 0xD0, 0x09, 0xDC, 0xA8, 0xF1, 0x11, 0x00, 0x08, 0x28,
+ 0x13, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x6C, 0x49, 0x90, 0x12, 0x12, 0x50,
+ 0x94, 0x57, 0x1E, 0x28, 0x55, 0xD0, 0x05, 0xDC, 0x1B, 0x28, 0x02, 0xD0,
+ 0xB8, 0xF1, 0x1D, 0x0F, 0x05, 0xD1, 0x90, 0xE0, 0x52, 0x28, 0x39, 0xD0,
+ 0xB8, 0xF1, 0xD2, 0x0F, 0x36, 0xD0, 0x5E, 0x49, 0x5E, 0x48, 0x43, 0x46,
+ 0x02, 0x22, 0x28, 0x31, 0x80, 0x1E, 0x00, 0x96, 0xF9, 0xF7, 0x1D, 0xDA,
+ 0x00, 0x2E, 0x2A, 0xD1, 0x8B, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98,
+ 0xFF, 0xF7, 0x60, 0xFE, 0x3A, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98,
+ 0xFF, 0xF7, 0xF1, 0xFE, 0x34, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98,
+ 0xFF, 0xF7, 0xFB, 0xFD, 0x2E, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98,
+ 0xFF, 0xF7, 0x11, 0xFF, 0x28, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98,
+ 0xFF, 0xF7, 0x1C, 0xFE, 0x22, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98,
+ 0xFF, 0xF7, 0x41, 0xFF, 0x1C, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98,
+ 0xFF, 0xF7, 0xAF, 0xFE, 0x16, 0xE0, 0x80, 0xE0, 0x02, 0xAB, 0x21, 0x46,
+ 0x0C, 0x9A, 0x09, 0x98, 0x00, 0xF0, 0x84, 0xF8, 0x0E, 0xE0, 0x02, 0xAB,
+ 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, 0xFF, 0xF7, 0x6F, 0xFE, 0x07, 0xE0,
+ 0x21, 0x46, 0x09, 0x98, 0xFF, 0xF7, 0xAF, 0xFD, 0x02, 0xE0, 0x09, 0x98,
+ 0xFF, 0xF7, 0x84, 0xFD, 0x01, 0x90, 0x43, 0xE0, 0x21, 0x46, 0x09, 0x98,
+ 0xFF, 0xF7, 0x89, 0xFD, 0x3E, 0xE0, 0x21, 0x46, 0x09, 0x98, 0xFF, 0xF7,
+ 0x3B, 0xFE, 0x39, 0xE0, 0x2D, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98,
+ 0xFF, 0xF7, 0xCA, 0xFE, 0x32, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98,
+ 0xFF, 0xF7, 0xD9, 0xFD, 0x2C, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98,
+ 0xFF, 0xF7, 0xEA, 0xFE, 0x26, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98,
+ 0xFF, 0xF7, 0xF1, 0xFD, 0x20, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98,
+ 0xFF, 0xF7, 0x0B, 0xFF, 0x1A, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98,
+ 0xFF, 0xF7, 0x79, 0xFE, 0x14, 0xE0, 0x09, 0x98, 0x00, 0xF0, 0x66, 0xF8,
+ 0x10, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, 0xFF, 0xF7, 0x47, 0xFE,
+ 0x0A, 0xE0, 0x09, 0x98, 0xFF, 0xF7, 0x7E, 0xFD, 0x06, 0xE0, 0x21, 0x46,
+ 0x0C, 0x9A, 0x09, 0x98, 0xFF, 0xF7, 0x10, 0xFE, 0x8D, 0xF8, 0x08, 0x70,
+ 0x01, 0x98, 0xC0, 0xB2, 0x05, 0x28, 0x02, 0xD0, 0x16, 0xE0, 0x06, 0x20,
+ 0xB2, 0xE7, 0x09, 0x98, 0x00, 0x8E, 0x17, 0xF0, 0xE3, 0xF8, 0x78, 0xB1,
+ 0x0C, 0x98, 0xAD, 0xF8, 0x12, 0x90, 0xAD, 0xF8, 0x14, 0x00, 0xAD, 0xF8,
+ 0x10, 0xB0, 0xCD, 0xF8, 0x18, 0xA0, 0x03, 0xA9, 0x09, 0x98, 0x0B, 0xF0,
+ 0xA1, 0xFE, 0x01, 0x25, 0x8D, 0xF8, 0x08, 0x70, 0x01, 0x98, 0x30, 0xB1,
+ 0x2D, 0xB9, 0xC3, 0xB2, 0x02, 0x0C, 0x21, 0x78, 0x09, 0x98, 0x00, 0xF0,
+ 0xBF, 0xF8, 0x9D, 0xF8, 0x08, 0x00, 0x0D, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F,
+ 0xF0, 0x47, 0xC0, 0x08, 0x02, 0x38, 0x10, 0x21, 0xFE, 0xB5, 0x1D, 0x46,
+ 0xD6, 0x1E, 0x01, 0x22, 0x2A, 0x70, 0x0A, 0x78, 0xCB, 0x1C, 0x52, 0x2A,
+ 0x03, 0xD0, 0xD2, 0x2A, 0x03, 0xD0, 0x01, 0x24, 0x02, 0xE0, 0x02, 0x24,
+ 0x00, 0xE0, 0x05, 0x24, 0x4A, 0x78, 0x89, 0x78, 0x02, 0xEB, 0x01, 0x21,
+ 0x0A, 0x04, 0x12, 0x0C, 0x0C, 0xD0, 0x00, 0x21, 0x8D, 0xE8, 0x2A, 0x00,
+ 0x33, 0x46, 0x21, 0x46, 0x0B, 0xF0, 0x86, 0xF9, 0x02, 0x2C, 0x01, 0xD0,
+ 0x05, 0x2C, 0x00, 0xD1, 0x00, 0x20, 0xFE, 0xBD, 0x01, 0x20, 0xF7, 0xE7,
+ 0x10, 0xB5, 0x04, 0x46, 0x00, 0x21, 0x00, 0xF0, 0x47, 0xFC, 0x61, 0x68,
+ 0x00, 0x20, 0x88, 0x71, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x01, 0x21,
+ 0x0B, 0xF0, 0x98, 0xBA, 0x2D, 0xE9, 0xF0, 0x5F, 0x04, 0x46, 0xDD, 0xE9,
+ 0x0B, 0x98, 0x90, 0xF8, 0x2D, 0x00, 0x9B, 0x46, 0x16, 0x46, 0x0F, 0x46,
+ 0x00, 0x28, 0x6D, 0xD1, 0xDF, 0xF8, 0xDC, 0xA0, 0x40, 0xF2, 0x29, 0x13,
+ 0x36, 0x4A, 0xBA, 0xF8, 0x08, 0x00, 0x30, 0x44, 0x81, 0xB2, 0x35, 0x48,
+ 0x00, 0x78, 0x00, 0xF0, 0xAD, 0xFE, 0x05, 0x00, 0x5E, 0xD0, 0xBA, 0xF8,
+ 0x08, 0x00, 0x07, 0x2F, 0x28, 0x44, 0x38, 0xD0, 0x0F, 0xDC, 0x4F, 0xF0,
+ 0x01, 0x0C, 0x09, 0xF0, 0xFF, 0x02, 0x4F, 0xEA, 0x19, 0x21, 0x01, 0x2F,
+ 0x0F, 0xD0, 0x02, 0x23, 0x02, 0x2F, 0x15, 0xD0, 0x03, 0x2F, 0x1E, 0xD0,
+ 0x05, 0x2F, 0x06, 0xD1, 0x37, 0xE0, 0x0B, 0x2F, 0x42, 0xD0, 0x0D, 0x2F,
+ 0x40, 0xD0, 0x11, 0x2F, 0x1A, 0xD0, 0x07, 0x70, 0x26, 0xE0, 0x80, 0xF8,
+ 0x00, 0xC0, 0x80, 0xF8, 0x01, 0xB0, 0x0A, 0x9B, 0x03, 0x71, 0x82, 0x70,
+ 0xC1, 0x70, 0x1D, 0xE0, 0x61, 0x68, 0xCA, 0x79, 0x52, 0x1C, 0xCA, 0x71,
+ 0x03, 0x70, 0x94, 0xF8, 0x28, 0x10, 0x41, 0x70, 0x21, 0x8D, 0x09, 0x0A,
+ 0x02, 0xE0, 0x03, 0x23, 0x03, 0x70, 0x42, 0x70, 0x81, 0x70, 0x0D, 0xE0,
+ 0x11, 0x21, 0x00, 0xF8, 0x01, 0x1B, 0xB2, 0x1E, 0x00, 0xF8, 0x01, 0x8B,
+ 0x03, 0xE0, 0x07, 0x21, 0x00, 0xF8, 0x01, 0x1B, 0x1A, 0xE0, 0x0D, 0x99,
+ 0x2B, 0xF4, 0xE5, 0xF1, 0xBA, 0xF8, 0x08, 0x30, 0x32, 0x46, 0x29, 0x46,
+ 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x5F, 0x0B, 0xF0, 0x40, 0xBC, 0x05, 0x21,
+ 0x01, 0x70, 0xB8, 0xF1, 0x04, 0x0F, 0x04, 0xD0, 0x43, 0x70, 0xB2, 0x1E,
+ 0x80, 0x1C, 0x0D, 0x99, 0xEA, 0xE7, 0x80, 0xF8, 0x01, 0xC0, 0xF8, 0xE7,
+ 0x00, 0xF8, 0x01, 0x7B, 0x42, 0x46, 0xE2, 0xE7, 0xBD, 0xE8, 0xF0, 0x9F,
+ 0x98, 0x77, 0x20, 0x00, 0x3D, 0xAB, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00,
+ 0x2D, 0xE9, 0xFF, 0x41, 0x1C, 0x46, 0x15, 0x46, 0x07, 0x46, 0x0E, 0x46,
+ 0x0B, 0x46, 0x03, 0x22, 0x09, 0x49, 0x0A, 0x48, 0xCD, 0xE9, 0x00, 0x45,
+ 0xF9, 0xF7, 0xA1, 0xD8, 0x00, 0x20, 0x00, 0x94, 0xCD, 0xE9, 0x01, 0x50,
+ 0x03, 0x90, 0x33, 0x46, 0x05, 0x22, 0x01, 0x21, 0x38, 0x46, 0xFF, 0xF7,
+ 0x65, 0xFF, 0xBD, 0xE8, 0xFF, 0x81, 0x00, 0x00, 0x28, 0x46, 0xC0, 0x08,
+ 0x00, 0x38, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, 0x90, 0xF8,
+ 0x2D, 0x00, 0x0F, 0x46, 0x00, 0x24, 0x10, 0xB1, 0x40, 0xF6, 0x0E, 0x44,
+ 0x1E, 0xE0, 0x11, 0x4E, 0x4F, 0xF0, 0x02, 0x08, 0x40, 0xF2, 0xEF, 0x23,
+ 0x30, 0x89, 0x0F, 0x4A, 0x80, 0x1C, 0x81, 0xB2, 0x0E, 0x48, 0x00, 0x78,
+ 0x00, 0xF0, 0x0C, 0xFE, 0x01, 0x00, 0x0F, 0xD0, 0x68, 0x68, 0x18, 0x22,
+ 0x82, 0x71, 0x30, 0x89, 0x08, 0x44, 0x02, 0x70, 0x47, 0x70, 0x33, 0x89,
+ 0x42, 0x46, 0x28, 0x46, 0x0B, 0xF0, 0xE1, 0xFB, 0x00, 0x21, 0x28, 0x46,
+ 0x00, 0xF0, 0x30, 0xFB, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00,
+ 0x98, 0x77, 0x20, 0x00, 0x6F, 0xAB, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00,
+ 0x1F, 0xB5, 0x00, 0x21, 0x00, 0x91, 0x01, 0x91, 0x02, 0x91, 0x0B, 0x46,
+ 0x03, 0x91, 0x01, 0x22, 0x19, 0x21, 0xFF, 0xF7, 0x1F, 0xFF, 0x1F, 0xBD,
+ 0x3E, 0xB5, 0x1C, 0x46, 0x06, 0x9B, 0x8D, 0xE8, 0x1C, 0x00, 0x0B, 0x46,
+ 0x06, 0x22, 0xE1, 0x1D, 0x00, 0xF0, 0xB2, 0xF9, 0x3E, 0xBD, 0x1F, 0xB5,
+ 0x51, 0x43, 0x00, 0x22, 0x03, 0x93, 0x00, 0x92, 0xCD, 0xE9, 0x01, 0x21,
+ 0x4A, 0x1C, 0x00, 0x23, 0x07, 0x21, 0xFF, 0xF7, 0x07, 0xFF, 0x1F, 0xBD,
+ 0x3E, 0xB5, 0x00, 0x24, 0xCD, 0xE9, 0x00, 0x24, 0x0B, 0x46, 0x04, 0x22,
+ 0x05, 0x21, 0x02, 0x94, 0x00, 0xF0, 0x9A, 0xF9, 0x3E, 0xBD, 0x1F, 0xB5,
+ 0x14, 0x46, 0x00, 0x22, 0x03, 0x93, 0x00, 0x92, 0xCD, 0xE9, 0x01, 0x24,
+ 0x61, 0x43, 0x8A, 0x1C, 0x00, 0x23, 0x05, 0x21, 0xFF, 0xF7, 0xEE, 0xFE,
+ 0x1F, 0xBD, 0x1F, 0xB5, 0x00, 0x21, 0x00, 0x91, 0x01, 0x91, 0x02, 0x91,
+ 0x0B, 0x46, 0x03, 0x91, 0x03, 0x22, 0x02, 0x21, 0xFF, 0xF7, 0xE2, 0xFE,
+ 0x1F, 0xBD, 0x1F, 0xB5, 0x00, 0x22, 0xCD, 0xE9, 0x00, 0x21, 0x02, 0x92,
+ 0x13, 0x46, 0x03, 0x92, 0x03, 0x22, 0x11, 0x46, 0xFF, 0xF7, 0xD6, 0xFE,
+ 0x1F, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xFF, 0x4F, 0x81, 0xB0, 0x9C, 0x46,
+ 0xDD, 0xE9, 0x0E, 0xA8, 0x14, 0x00, 0x0E, 0x46, 0x01, 0xD0, 0x01, 0x27,
+ 0x00, 0xE0, 0x00, 0x27, 0x01, 0x98, 0xD8, 0xF8, 0x00, 0x50, 0x90, 0xF8,
+ 0x2D, 0x00, 0xED, 0x1C, 0x18, 0xB1, 0x01, 0x20, 0x05, 0xB0, 0xBD, 0xE8,
+ 0xF0, 0x8F, 0x4F, 0xF0, 0xFF, 0x3B, 0x87, 0xB1, 0xBC, 0xF8, 0x00, 0x30,
+ 0x03, 0x2B, 0x05, 0xD2, 0x01, 0x22, 0x29, 0x49, 0x29, 0x48, 0xF8, 0xF7,
+ 0xE2, 0xDF, 0x1C, 0xE0, 0xE0, 0x1E, 0x18, 0x44, 0xDB, 0x1E, 0x99, 0xB2,
+ 0xAC, 0xF8, 0x00, 0x10, 0x11, 0xE0, 0xDF, 0xF8, 0x94, 0x90, 0x4F, 0xF4,
+ 0x77, 0x73, 0x24, 0x4A, 0xB9, 0xF8, 0x08, 0x00, 0x28, 0x44, 0x81, 0xB2,
+ 0x22, 0x48, 0x00, 0x78, 0x00, 0xF0, 0x62, 0xFD, 0x04, 0x00, 0x06, 0xD0,
+ 0xB9, 0xF8, 0x08, 0x10, 0x08, 0x19, 0x89, 0x46, 0x1E, 0xB1, 0x1B, 0x21,
+ 0x02, 0xE0, 0x58, 0x46, 0xD0, 0xE7, 0x1D, 0x21, 0x01, 0x70, 0x80, 0xF8,
+ 0x01, 0xA0, 0x4F, 0xEA, 0x1A, 0x21, 0x81, 0x70, 0x8F, 0xB1, 0xB6, 0xB1,
+ 0x4F, 0xF4, 0x7B, 0x70, 0x00, 0x90, 0x14, 0x4B, 0x15, 0x49, 0x20, 0x46,
+ 0x01, 0x9A, 0x00, 0xF0, 0x0B, 0xFD, 0x60, 0xB9, 0x0D, 0x49, 0x00, 0x22,
+ 0x30, 0x31, 0x0D, 0x48, 0xF8, 0xF7, 0xA9, 0xDF, 0x05, 0xE0, 0xD8, 0xF8,
+ 0x00, 0x20, 0xC0, 0x1C, 0x10, 0x99, 0x2B, 0xF4, 0xB6, 0xF0, 0x4B, 0x46,
+ 0x2A, 0x46, 0x21, 0x46, 0x01, 0x98, 0x0B, 0xF0, 0x14, 0xFB, 0x1E, 0xB9,
+ 0x01, 0x21, 0x01, 0x98, 0x00, 0xF0, 0x62, 0xFA, 0x00, 0x20, 0xC8, 0xF8,
+ 0x00, 0x50, 0xA1, 0xE7, 0x70, 0x46, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21,
+ 0x98, 0x77, 0x20, 0x00, 0xB9, 0xAB, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00,
+ 0xC5, 0xF6, 0x80, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, 0x9C, 0x46,
+ 0x13, 0x46, 0xDD, 0xE9, 0x06, 0x07, 0x95, 0xF8, 0x2D, 0x20, 0x00, 0x26,
+ 0x12, 0xB1, 0x40, 0xF6, 0x0E, 0x46, 0x1B, 0xE0, 0x3A, 0x88, 0x54, 0x1D,
+ 0x3C, 0x80, 0x04, 0x88, 0x16, 0x27, 0x64, 0x1F, 0xA4, 0xB2, 0x04, 0x80,
+ 0x64, 0x44, 0x52, 0x1D, 0x27, 0x70, 0x63, 0x70, 0x1B, 0x0A, 0xA3, 0x70,
+ 0xE1, 0x70, 0x09, 0x0A, 0x21, 0x71, 0x03, 0x88, 0x61, 0x46, 0x28, 0x46,
+ 0x0B, 0xF0, 0xDB, 0xFA, 0x68, 0x68, 0x00, 0x21, 0x87, 0x71, 0x28, 0x46,
+ 0x00, 0xF0, 0x28, 0xFA, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00,
+ 0x2D, 0xE9, 0xF0, 0x5F, 0x82, 0x46, 0x90, 0xF8, 0x2D, 0x00, 0xDD, 0xF8,
+ 0x28, 0xB0, 0x99, 0x46, 0x16, 0x46, 0x0F, 0x46, 0x00, 0x28, 0x2D, 0xD1,
+ 0xDF, 0xF8, 0x5C, 0x80, 0x09, 0xF1, 0x05, 0x05, 0x40, 0xF2, 0x9D, 0x33,
+ 0xB8, 0xF8, 0x08, 0x00, 0x14, 0x4A, 0x28, 0x44, 0x81, 0xB2, 0x14, 0x48,
+ 0x00, 0x78, 0x00, 0xF0, 0xD3, 0xFC, 0x04, 0x00, 0x1C, 0xD0, 0xB8, 0xF8,
+ 0x08, 0x00, 0x17, 0x21, 0x20, 0x44, 0x4A, 0x46, 0x00, 0xF8, 0x01, 0x1B,
+ 0x39, 0x0A, 0x00, 0xF8, 0x01, 0x7B, 0x00, 0xF8, 0x02, 0x1B, 0x31, 0x0A,
+ 0x00, 0xF8, 0x01, 0x6C, 0x00, 0xF8, 0x01, 0x1B, 0x59, 0x46, 0x2B, 0xF4,
+ 0x3C, 0xF0, 0xB8, 0xF8, 0x08, 0x30, 0x2A, 0x46, 0x21, 0x46, 0x50, 0x46,
+ 0xBD, 0xE8, 0xF0, 0x5F, 0x0B, 0xF0, 0x97, 0xBA, 0xBD, 0xE8, 0xF0, 0x9F,
+ 0x98, 0x77, 0x20, 0x00, 0xA1, 0xAB, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00,
+ 0x3E, 0xB5, 0x00, 0x24, 0xCD, 0xE9, 0x00, 0x24, 0x0B, 0x46, 0x0C, 0x22,
+ 0x05, 0x21, 0x02, 0x94, 0x00, 0xF0, 0x7A, 0xF8, 0x3E, 0xBD, 0x3E, 0xB5,
+ 0x06, 0x9C, 0x8D, 0xE8, 0x1C, 0x00, 0x0B, 0x46, 0x10, 0x22, 0x61, 0x1D,
+ 0x00, 0xF0, 0x70, 0xF8, 0x3E, 0xBD, 0x1F, 0xB5, 0x14, 0x46, 0x00, 0x22,
+ 0x03, 0x93, 0x00, 0x92, 0xCD, 0xE9, 0x01, 0x24, 0x61, 0x43, 0x8A, 0x1C,
+ 0x00, 0x23, 0x11, 0x21, 0xFF, 0xF7, 0xC4, 0xFD, 0x1F, 0xBD, 0x3E, 0xB5,
+ 0x1C, 0x46, 0x06, 0x9B, 0x8D, 0xE8, 0x1C, 0x00, 0x0B, 0x46, 0x08, 0x22,
+ 0x61, 0x1D, 0x00, 0xF0, 0x57, 0xF8, 0x3E, 0xBD, 0x2D, 0xE9, 0xF0, 0x5F,
+ 0x81, 0x46, 0x90, 0xF8, 0x2D, 0x00, 0x9B, 0x46, 0x90, 0x46, 0x00, 0x28,
+ 0x2E, 0xD1, 0x01, 0xFB, 0x08, 0xF7, 0xB9, 0xF8, 0x2A, 0x00, 0xBC, 0x1C,
+ 0x25, 0x1A, 0x00, 0x2D, 0x01, 0xDD, 0x64, 0x1B, 0x00, 0xE0, 0x00, 0x25,
+ 0xDF, 0xF8, 0x48, 0xA0, 0x40, 0xF2, 0x67, 0x33, 0x11, 0x4A, 0xBA, 0xF8,
+ 0x08, 0x00, 0x20, 0x44, 0x81, 0xB2, 0x10, 0x48, 0x00, 0x78, 0x00, 0xF0,
+ 0x5D, 0xFC, 0x06, 0x00, 0x14, 0xD0, 0xBA, 0xF8, 0x08, 0x00, 0x09, 0x21,
+ 0x30, 0x44, 0x7A, 0x1B, 0x00, 0xF8, 0x01, 0x1B, 0x59, 0x46, 0x00, 0xF8,
+ 0x01, 0x8B, 0x2A, 0xF4, 0xCE, 0xF7, 0xBA, 0xF8, 0x08, 0x30, 0x22, 0x46,
+ 0x31, 0x46, 0x48, 0x46, 0xBD, 0xE8, 0xF0, 0x5F, 0x0B, 0xF0, 0x29, 0xBA,
+ 0xBD, 0xE8, 0xF0, 0x9F, 0x98, 0x77, 0x20, 0x00, 0x87, 0xAB, 0x82, 0x00,
+ 0x00, 0x74, 0x20, 0x00, 0x0E, 0xB5, 0x00, 0x22, 0x00, 0x92, 0x01, 0x92,
+ 0x0B, 0x46, 0x02, 0x92, 0x0A, 0x22, 0x03, 0x21, 0x00, 0xF0, 0x0C, 0xF8,
+ 0x0E, 0xBD, 0x1F, 0xB5, 0x00, 0x24, 0xCD, 0xE9, 0x02, 0x23, 0x00, 0x94,
+ 0x01, 0x94, 0x23, 0x46, 0x52, 0x1C, 0xFF, 0xF7, 0x63, 0xFD, 0x1F, 0xBD,
+ 0x2D, 0xE9, 0xF0, 0x5F, 0x80, 0x46, 0x90, 0xF8, 0x2D, 0x00, 0xDD, 0xF8,
+ 0x28, 0x90, 0x1F, 0x46, 0x14, 0x46, 0x8B, 0x46, 0x00, 0x26, 0x10, 0xB1,
+ 0x40, 0xF6, 0x0E, 0x46, 0x5E, 0xE0, 0xDF, 0xF8, 0xC4, 0xA0, 0x40, 0xF2,
+ 0x93, 0x13, 0x30, 0x4A, 0xBA, 0xF8, 0x08, 0x10, 0x01, 0xEB, 0x0B, 0x00,
+ 0x81, 0xB2, 0x2E, 0x48, 0x00, 0x78, 0x00, 0xF0, 0x0B, 0xFC, 0x05, 0x00,
+ 0x4E, 0xD0, 0xD8, 0xF8, 0x04, 0x10, 0xBA, 0xF8, 0x08, 0x00, 0x3A, 0x0A,
+ 0x8C, 0x71, 0xF9, 0xB2, 0x28, 0x44, 0x09, 0xF0, 0xFF, 0x07, 0x4F, 0xEA,
+ 0x19, 0x23, 0x0A, 0x2C, 0x32, 0xD0, 0x06, 0xDC, 0x04, 0x2C, 0x29, 0xD0,
+ 0x06, 0x2C, 0x07, 0xD0, 0x08, 0x2C, 0x2E, 0xD1, 0x19, 0xE0, 0x0C, 0x2C,
+ 0x22, 0xD0, 0x10, 0x2C, 0x29, 0xD1, 0x14, 0xE0, 0x00, 0xF8, 0x01, 0x4B,
+ 0x00, 0xF8, 0x01, 0x1B, 0x00, 0x21, 0x00, 0xF8, 0x01, 0x2B, 0x00, 0xF8,
+ 0x03, 0x7B, 0x00, 0xF8, 0x02, 0x3C, 0x00, 0xF8, 0x01, 0x1C, 0x28, 0x21,
+ 0x00, 0xF8, 0x01, 0x1B, 0xDD, 0xE9, 0x0B, 0x12, 0x2A, 0xF4, 0x59, 0xF7,
+ 0x13, 0xE0, 0x00, 0xF8, 0x01, 0x4B, 0x00, 0xF8, 0x01, 0x1B, 0x00, 0xF8,
+ 0x02, 0x2B, 0x00, 0xF8, 0x01, 0x7C, 0x00, 0xF8, 0x01, 0x3B, 0xEF, 0xE7,
+ 0x04, 0x70, 0x41, 0x70, 0x82, 0x70, 0xC7, 0x70, 0x03, 0x71, 0x02, 0xE0,
+ 0x04, 0x70, 0x41, 0x70, 0x82, 0x70, 0xBA, 0xF8, 0x08, 0x30, 0x5A, 0x46,
+ 0x29, 0x46, 0x40, 0x46, 0x0B, 0xF0, 0xA1, 0xF9, 0x00, 0x21, 0x40, 0x46,
+ 0x00, 0xF0, 0xF0, 0xF8, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x9F, 0x00, 0x00,
+ 0x98, 0x77, 0x20, 0x00, 0x4B, 0xAB, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00,
+ 0x2D, 0xE9, 0xFF, 0x4F, 0x85, 0xB0, 0x05, 0x46, 0xDD, 0xE9, 0x12, 0xA3,
+ 0x90, 0xF8, 0x2D, 0x00, 0x4F, 0xF0, 0x00, 0x08, 0x10, 0xB1, 0x40, 0xF6,
+ 0x0E, 0x48, 0x69, 0xE0, 0x1E, 0x88, 0x00, 0x27, 0xF0, 0x1C, 0x18, 0x80,
+ 0xBA, 0xF8, 0x00, 0x00, 0xF6, 0x1C, 0xC0, 0x1E, 0x80, 0xB2, 0xAA, 0xF8,
+ 0x00, 0x00, 0x08, 0x9B, 0xC4, 0x18, 0x10, 0x0A, 0x62, 0x70, 0xA0, 0x70,
+ 0x01, 0x29, 0x04, 0xD0, 0x02, 0x29, 0x05, 0xD0, 0x05, 0x29, 0x44, 0xD1,
+ 0x06, 0xE0, 0x12, 0x20, 0x20, 0x70, 0x40, 0xE0, 0x52, 0x20, 0x20, 0x70,
+ 0x01, 0x27, 0x2D, 0xE0, 0x00, 0x20, 0x00, 0x90, 0x01, 0x90, 0x02, 0x90,
+ 0x03, 0x90, 0xD2, 0x20, 0x20, 0x70, 0xA9, 0x7E, 0x05, 0xF1, 0x13, 0x00,
+ 0x01, 0x27, 0x04, 0x90, 0x16, 0xF0, 0x46, 0xFF, 0x5F, 0xEA, 0x00, 0x09,
+ 0x1A, 0xD0, 0xA9, 0x7E, 0x04, 0x98, 0x16, 0xF0, 0x57, 0xFF, 0x04, 0xEB,
+ 0x06, 0x0B, 0x42, 0x1C, 0xCB, 0xF8, 0x00, 0x00, 0xA9, 0x7E, 0x04, 0x98,
+ 0x1A, 0xF0, 0x3E, 0xFF, 0x6B, 0x46, 0x32, 0x1D, 0x21, 0x46, 0x48, 0x46,
+ 0x27, 0xF4, 0x64, 0xF6, 0x02, 0x98, 0xCB, 0xF8, 0x04, 0x00, 0x03, 0x98,
+ 0xCB, 0xF8, 0x08, 0x00, 0x0C, 0x36, 0x01, 0xE0, 0x40, 0xF6, 0x0F, 0x48,
+ 0x40, 0xF2, 0xB1, 0x20, 0x00, 0x90, 0x0F, 0x4B, 0x2A, 0x46, 0x0F, 0x49,
+ 0x08, 0x98, 0x00, 0xF0, 0x13, 0xFB, 0x20, 0xB9, 0x00, 0x22, 0x0D, 0x49,
+ 0x0D, 0x48, 0xF8, 0xF7, 0xB2, 0xDD, 0xBA, 0xF8, 0x00, 0x30, 0x32, 0x46,
+ 0x28, 0x46, 0x08, 0x99, 0x0B, 0xF0, 0x23, 0xF9, 0x37, 0xB9, 0x69, 0x68,
+ 0x20, 0x78, 0x88, 0x71, 0x00, 0x21, 0x28, 0x46, 0x00, 0xF0, 0x6E, 0xF8,
+ 0x09, 0xB0, 0x40, 0x46, 0xBD, 0xE8, 0xF0, 0x8F, 0x58, 0xAB, 0x82, 0x00,
+ 0xC5, 0xF6, 0x80, 0x00, 0x00, 0x46, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21,
+ 0x10, 0xB5, 0x04, 0x46, 0x42, 0x8D, 0x00, 0x8D, 0x88, 0x42, 0x03, 0xD9,
+ 0x17, 0x29, 0x02, 0xD3, 0x61, 0x85, 0x00, 0xE0, 0x60, 0x85, 0x61, 0x8D,
+ 0x91, 0x42, 0x03, 0xD1, 0x94, 0xF8, 0x2C, 0x00, 0x00, 0x28, 0x05, 0xD1,
+ 0x20, 0x8E, 0x02, 0xF0, 0x4E, 0xFA, 0x01, 0x20, 0x84, 0xF8, 0x2C, 0x00,
+ 0x10, 0xBD, 0x00, 0x00, 0xF8, 0xB5, 0x0E, 0x46, 0x1E, 0x49, 0xC0, 0xEB,
+ 0xC0, 0x02, 0x02, 0xEB, 0x00, 0x10, 0x49, 0x68, 0x01, 0xEB, 0x80, 0x04,
+ 0x04, 0xF1, 0x13, 0x01, 0x1A, 0x48, 0xF8, 0xF7, 0x3D, 0xDF, 0x00, 0x90,
+ 0x33, 0x46, 0x02, 0x22, 0x18, 0x49, 0x19, 0x48, 0xF8, 0xF7, 0x67, 0xDD,
+ 0x26, 0xB1, 0xA0, 0x68, 0x05, 0x46, 0x44, 0x30, 0x40, 0x35, 0x03, 0xE0,
+ 0x60, 0x68, 0x05, 0x46, 0x40, 0x1D, 0x20, 0x35, 0x00, 0x28, 0x1C, 0xD0,
+ 0x01, 0x78, 0x00, 0x29, 0x19, 0xD0, 0x00, 0x27, 0x07, 0x70, 0x01, 0x20,
+ 0x84, 0xF8, 0x2D, 0x00, 0x2E, 0xB1, 0x40, 0xF6, 0x0D, 0x41, 0x20, 0x46,
+ 0x09, 0xF0, 0x1A, 0xFD, 0x08, 0xE0, 0x60, 0x68, 0x00, 0x23, 0x01, 0x21,
+ 0x82, 0x79, 0x20, 0x46, 0x09, 0xF0, 0x68, 0xF8, 0x60, 0x68, 0x87, 0x71,
+ 0x28, 0x46, 0xBD, 0xE8, 0xF8, 0x40, 0x01, 0xF0, 0xE7, 0xBA, 0xF8, 0xBD,
+ 0x98, 0x77, 0x20, 0x00, 0x00, 0x00, 0x30, 0x21, 0xCC, 0x45, 0xC0, 0x08,
+ 0x00, 0x38, 0x10, 0x21, 0xF8, 0xB5, 0x0F, 0x00, 0x06, 0x46, 0x04, 0xD0,
+ 0xB4, 0x68, 0x25, 0x46, 0x44, 0x34, 0x40, 0x35, 0x03, 0xE0, 0x74, 0x68,
+ 0x25, 0x46, 0x64, 0x1D, 0x20, 0x35, 0x00, 0x2C, 0x24, 0xD0, 0x20, 0x78,
+ 0x00, 0x28, 0x21, 0xD1, 0x06, 0xF1, 0x13, 0x01, 0x10, 0x48, 0xF8, 0xF7,
+ 0xED, 0xDE, 0x00, 0x90, 0x3B, 0x46, 0x02, 0x22, 0x0E, 0x49, 0x0F, 0x48,
+ 0xF8, 0xF7, 0x17, 0xDD, 0x00, 0x20, 0x28, 0x60, 0x0D, 0x48, 0x31, 0x78,
+ 0x00, 0x78, 0x00, 0x06, 0x40, 0xEA, 0x01, 0x42, 0x0B, 0x48, 0x3A, 0x43,
+ 0x4F, 0xF4, 0x7A, 0x71, 0x90, 0xF8, 0x30, 0x00, 0x10, 0xFB, 0x01, 0xF3,
+ 0x08, 0xA1, 0x28, 0x46, 0x01, 0xF0, 0x94, 0xFA, 0x01, 0x20, 0x20, 0x70,
+ 0xF8, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0x6C, 0x45, 0xC0, 0x08,
+ 0x00, 0x38, 0x10, 0x21, 0x94, 0x77, 0x20, 0x00, 0x98, 0x77, 0x20, 0x00,
+ 0x61, 0x74, 0x74, 0x00, 0xF8, 0xB5, 0x0E, 0x00, 0x04, 0xD0, 0x84, 0x68,
+ 0x25, 0x46, 0x44, 0x34, 0x40, 0x35, 0x03, 0xE0, 0x44, 0x68, 0x25, 0x46,
+ 0x64, 0x1D, 0x20, 0x35, 0x00, 0x2C, 0x13, 0xD0, 0x21, 0x78, 0x00, 0x29,
+ 0x10, 0xD0, 0x00, 0xF1, 0x13, 0x01, 0x08, 0x48, 0xF8, 0xF7, 0xAC, 0xDE,
+ 0x00, 0x90, 0x33, 0x46, 0x02, 0x22, 0x06, 0x49, 0x06, 0x48, 0xF8, 0xF7,
+ 0xD6, 0xDC, 0x28, 0x46, 0x01, 0xF0, 0x7C, 0xFA, 0x00, 0x20, 0x20, 0x70,
+ 0xF8, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0x98, 0x45, 0xC0, 0x08,
+ 0x00, 0x38, 0x10, 0x21, 0x00, 0x21, 0xAF, 0xF3, 0x00, 0x80, 0x2D, 0xE9,
+ 0xF8, 0x43, 0x05, 0x46, 0x40, 0x78, 0x88, 0x46, 0x00, 0x28, 0x46, 0xD0,
+ 0x68, 0x7E, 0x05, 0x28, 0x01, 0xD0, 0x03, 0x28, 0x41, 0xD1, 0x00, 0x26,
+ 0x01, 0x27, 0x03, 0x28, 0x02, 0xD0, 0xB8, 0xF1, 0x00, 0x0F, 0x01, 0xD0,
+ 0x40, 0xF6, 0x04, 0x46, 0x05, 0xF1, 0x50, 0x09, 0xB8, 0xF1, 0x00, 0x0F,
+ 0x00, 0xD1, 0x00, 0x27, 0x48, 0x46, 0x03, 0xF4, 0x1C, 0xF4, 0x04, 0x00,
+ 0x2D, 0xD0, 0x20, 0x79, 0x90, 0xB1, 0x01, 0x28, 0x17, 0xD0, 0x02, 0x28,
+ 0x20, 0xD1, 0xA6, 0x82, 0x3E, 0xB1, 0x00, 0x96, 0xD4, 0xE9, 0x02, 0x12,
+ 0xE3, 0x8A, 0x00, 0x20, 0x01, 0xF0, 0x64, 0xFE, 0x16, 0xE0, 0x04, 0xF1,
+ 0x08, 0x00, 0x08, 0xF0, 0xA7, 0xFD, 0x11, 0xE0, 0xE3, 0x88, 0x29, 0x8E,
+ 0x02, 0x22, 0x30, 0x46, 0x02, 0xF0, 0xCE, 0xFC, 0x0A, 0xE0, 0xE3, 0x88,
+ 0x29, 0x8E, 0x05, 0x22, 0x30, 0x46, 0x02, 0xF0, 0xC7, 0xFC, 0x29, 0x8E,
+ 0x01, 0x22, 0x30, 0x46, 0x05, 0xF0, 0xE9, 0xFA, 0x21, 0x46, 0x05, 0xF1,
+ 0x44, 0x00, 0x03, 0xF4, 0xD8, 0xF3, 0x00, 0x2F, 0xC8, 0xD1, 0xBD, 0xE8,
+ 0xF8, 0x83, 0x00, 0x00, 0x06, 0x48, 0x10, 0xB5, 0x41, 0x68, 0x08, 0x78,
+ 0x08, 0xB1, 0x08, 0x5C, 0x10, 0xBD, 0x00, 0x22, 0x03, 0x49, 0x04, 0x48,
+ 0xF8, 0xF7, 0x69, 0xDC, 0xFF, 0x20, 0x10, 0xBD, 0xC4, 0x78, 0x20, 0x00,
+ 0x54, 0x79, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x08, 0x48, 0x08, 0xB5,
+ 0x40, 0x68, 0x03, 0x78, 0x8B, 0x42, 0x07, 0xD2, 0x00, 0x91, 0x02, 0x22,
+ 0x05, 0x49, 0x06, 0x48, 0xF8, 0xF7, 0x55, 0xDC, 0xFF, 0x20, 0x08, 0xBD,
+ 0x59, 0x1A, 0x08, 0x44, 0x40, 0x78, 0x08, 0xBD, 0xC4, 0x78, 0x20, 0x00,
+ 0x14, 0x79, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x10, 0x4D,
+ 0x03, 0x46, 0x01, 0x22, 0x0D, 0x49, 0x28, 0x46, 0xF8, 0xF7, 0x41, 0xDC,
+ 0x0D, 0x48, 0x40, 0x68, 0x01, 0x78, 0x49, 0xB1, 0x44, 0x78, 0x09, 0x49,
+ 0x23, 0x46, 0x01, 0x22, 0x44, 0x31, 0x28, 0x46, 0xF8, 0xF7, 0x35, 0xDC,
+ 0x20, 0x46, 0x70, 0xBD, 0x04, 0x49, 0x05, 0x48, 0x00, 0x22, 0x20, 0x31,
+ 0xC0, 0x1E, 0xF8, 0xF7, 0x2C, 0xDC, 0xFF, 0x20, 0x70, 0xBD, 0x00, 0x00,
+ 0xA8, 0x78, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xC4, 0x78, 0x20, 0x00,
+ 0xF8, 0xB5, 0x0E, 0x46, 0x05, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22,
+ 0x1C, 0x49, 0x1D, 0x48, 0xF8, 0xF7, 0x19, 0xDC, 0x1C, 0x4C, 0x31, 0x46,
+ 0x28, 0x46, 0x27, 0x78, 0x00, 0xF0, 0x9A, 0xF8, 0xFF, 0x28, 0x05, 0xD0,
+ 0x31, 0x46, 0x28, 0x46, 0xBD, 0xE8, 0xF8, 0x40, 0x00, 0xF0, 0xD6, 0xB8,
+ 0x61, 0x68, 0x08, 0x78, 0xB8, 0x42, 0x08, 0xD1, 0x11, 0x49, 0x12, 0x48,
+ 0x00, 0x22, 0x2C, 0x31, 0xC0, 0x1E, 0xF8, 0xF7, 0x00, 0xDC, 0x00, 0x20,
+ 0xF8, 0xBD, 0x49, 0x1C, 0x46, 0x54, 0x62, 0x68, 0x13, 0x21, 0x10, 0x78,
+ 0x40, 0x1C, 0x02, 0xF8, 0x01, 0x0B, 0x0C, 0x48, 0xF8, 0xF7, 0x5F, 0xDE,
+ 0x00, 0x90, 0x60, 0x68, 0x06, 0x49, 0x02, 0x22, 0x03, 0x78, 0x06, 0x48,
+ 0x54, 0x31, 0x40, 0x1E, 0xF8, 0xF7, 0xE9, 0xDB, 0x28, 0x46, 0x61, 0x68,
+ 0x07, 0xF0, 0xA6, 0xF9, 0x01, 0x20, 0xF8, 0xBD, 0xEC, 0x76, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0xC4, 0x78, 0x20, 0x00, 0x00, 0x00, 0x50, 0x21,
+ 0x10, 0xB5, 0x03, 0x46, 0x01, 0x22, 0x06, 0x49, 0x06, 0x48, 0xF8, 0xF7,
+ 0xD4, 0xDB, 0x06, 0x49, 0x00, 0x20, 0x08, 0x70, 0xBD, 0xE8, 0x10, 0x40,
+ 0x01, 0x20, 0x07, 0xF0, 0x8D, 0xB9, 0x00, 0x00, 0xB8, 0x75, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0xCC, 0x78, 0x20, 0x00, 0xF8, 0xB5, 0x0F, 0x46,
+ 0x05, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22, 0x1E, 0x49, 0x1F, 0x48,
+ 0xF8, 0xF7, 0xBB, 0xDB, 0x1E, 0x4C, 0x1D, 0x4E, 0x60, 0x68, 0xF6, 0x1E,
+ 0x00, 0x78, 0x38, 0xB1, 0x39, 0x46, 0x28, 0x46, 0x00, 0xF0, 0x38, 0xF8,
+ 0xFF, 0x28, 0x25, 0xD0, 0x62, 0x68, 0x08, 0xE0, 0x15, 0x49, 0x00, 0x22,
+ 0x2C, 0x31, 0x22, 0xE0, 0x11, 0x18, 0x40, 0x1C, 0x8B, 0x78, 0x4B, 0x70,
+ 0xC0, 0xB2, 0x11, 0x78, 0x81, 0x42, 0xF7, 0xD8, 0xC8, 0xB2, 0x40, 0x1E,
+ 0x02, 0xF8, 0x01, 0x0B, 0x13, 0x21, 0x10, 0x48, 0xF8, 0xF7, 0x05, 0xDE,
+ 0x00, 0x90, 0x60, 0x68, 0x0A, 0x49, 0x02, 0x22, 0x03, 0x78, 0x0A, 0x48,
+ 0x60, 0x31, 0x40, 0x1E, 0xF8, 0xF7, 0x8F, 0xDB, 0x28, 0x46, 0x61, 0x68,
+ 0x07, 0xF0, 0x4C, 0xF9, 0x01, 0x20, 0xF8, 0xBD, 0x03, 0x49, 0x00, 0x22,
+ 0xA0, 0x31, 0x30, 0x46, 0xF8, 0xF7, 0x83, 0xDB, 0x00, 0x20, 0xF8, 0xBD,
+ 0x1C, 0x76, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xC4, 0x78, 0x20, 0x00,
+ 0x00, 0x00, 0x50, 0x21, 0x38, 0xB5, 0x0B, 0x4A, 0x03, 0x46, 0x00, 0x20,
+ 0x52, 0x68, 0x14, 0x78, 0x05, 0xE0, 0x15, 0x18, 0x6D, 0x78, 0x8D, 0x42,
+ 0x0A, 0xD0, 0x40, 0x1C, 0xC0, 0xB2, 0x84, 0x42, 0xF7, 0xD8, 0x00, 0x91,
+ 0x02, 0x22, 0x04, 0x49, 0x04, 0x48, 0xF8, 0xF7, 0x64, 0xDB, 0xFF, 0x20,
+ 0x38, 0xBD, 0x00, 0x00, 0xC4, 0x78, 0x20, 0x00, 0xE0, 0x75, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x0D, 0x46, 0x0E, 0x49, 0x01, 0x20,
+ 0x06, 0xF0, 0x4A, 0xFF, 0x0C, 0x4C, 0x88, 0xB9, 0x23, 0x78, 0x01, 0x22,
+ 0x0B, 0x49, 0x0C, 0x48, 0xF8, 0xF7, 0x4D, 0xDB, 0x20, 0x78, 0x13, 0x28,
+ 0x08, 0xD9, 0x08, 0x49, 0x08, 0x48, 0x00, 0x22, 0x30, 0x31, 0x80, 0x1E,
+ 0xF8, 0xF7, 0x43, 0xDB, 0x00, 0x20, 0x20, 0x70, 0x02, 0x48, 0x08, 0x38,
+ 0x44, 0x60, 0x05, 0x70, 0x70, 0xBD, 0x00, 0x00, 0xCC, 0x78, 0x20, 0x00,
+ 0x54, 0x75, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0xF8, 0xB5, 0x0C, 0x46,
+ 0x06, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22, 0x1D, 0x49, 0x1E, 0x48,
+ 0xF8, 0xF7, 0x2B, 0xDB, 0x21, 0x46, 0x30, 0x46, 0xFF, 0xF7, 0xAE, 0xFF,
+ 0xFF, 0x28, 0x25, 0xD0, 0x1A, 0x4D, 0x6A, 0x68, 0x11, 0x78, 0x49, 0x1E,
+ 0x81, 0x42, 0x06, 0xD1, 0x01, 0x20, 0xF8, 0xBD, 0x11, 0x18, 0x40, 0x1C,
+ 0x8B, 0x78, 0x4B, 0x70, 0xC0, 0xB2, 0x11, 0x78, 0x81, 0x42, 0xF7, 0xD8,
+ 0xC8, 0xB2, 0x13, 0x21, 0x14, 0x54, 0x12, 0x48, 0x52, 0x1C, 0xF8, 0xF7,
+ 0x7A, 0xDD, 0x00, 0x90, 0x68, 0x68, 0x0C, 0x49, 0x02, 0x22, 0x03, 0x78,
+ 0x0B, 0x48, 0x28, 0x31, 0x40, 0x1E, 0xF8, 0xF7, 0x04, 0xDB, 0x30, 0x46,
+ 0x69, 0x68, 0x07, 0xF0, 0xC1, 0xF8, 0xDF, 0xE7, 0x05, 0x49, 0x06, 0x48,
+ 0x33, 0x46, 0x02, 0x22, 0x64, 0x31, 0xC0, 0x1E, 0x00, 0x94, 0xF8, 0xF7,
+ 0xF6, 0xDA, 0x00, 0x20, 0xF8, 0xBD, 0x00, 0x00, 0x7C, 0x77, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0xC4, 0x78, 0x20, 0x00, 0x00, 0x00, 0x50, 0x21,
+ 0xF8, 0xB5, 0x0C, 0x46, 0x06, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22,
+ 0x1B, 0x49, 0x1C, 0x48, 0xF8, 0xF7, 0xE1, 0xDA, 0x21, 0x46, 0x30, 0x46,
+ 0xFF, 0xF7, 0x64, 0xFF, 0xFF, 0x28, 0x21, 0xD0, 0x10, 0xB1, 0x18, 0x4D,
+ 0x6A, 0x68, 0x06, 0xE0, 0x01, 0x20, 0xF8, 0xBD, 0x11, 0x5C, 0x13, 0x18,
+ 0x40, 0x1E, 0x59, 0x70, 0xC0, 0xB2, 0x00, 0x28, 0xF8, 0xD1, 0x02, 0xF8,
+ 0x01, 0x4F, 0x13, 0x21, 0x11, 0x48, 0xF8, 0xF7, 0x34, 0xDD, 0x00, 0x90,
+ 0x68, 0x68, 0x0C, 0x49, 0x02, 0x22, 0x03, 0x78, 0x0B, 0x48, 0x28, 0x31,
+ 0x40, 0x1E, 0xF8, 0xF7, 0xBE, 0xDA, 0x30, 0x46, 0x69, 0x68, 0x07, 0xF0,
+ 0x7B, 0xF8, 0xE1, 0xE7, 0x05, 0x49, 0x06, 0x48, 0x33, 0x46, 0x02, 0x22,
+ 0x60, 0x31, 0xC0, 0x1E, 0x00, 0x94, 0xF8, 0xF7, 0xB0, 0xDA, 0x00, 0x20,
+ 0xF8, 0xBD, 0x00, 0x00, 0x14, 0x78, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21,
+ 0xC4, 0x78, 0x20, 0x00, 0x00, 0x00, 0x50, 0x21, 0x2D, 0xE9, 0xFC, 0x41,
+ 0x05, 0x00, 0x19, 0x4F, 0x08, 0x9E, 0x4F, 0xF0, 0x05, 0x50, 0x01, 0xD0,
+ 0xAC, 0x07, 0x06, 0xD0, 0x19, 0x46, 0xF8, 0xF7, 0xB2, 0xDC, 0x03, 0x46,
+ 0x03, 0x22, 0x14, 0x49, 0x16, 0xE0, 0x55, 0xF8, 0x04, 0xCC, 0xA5, 0xF1,
+ 0x10, 0x04, 0x4F, 0xEA, 0x5C, 0x7C, 0x5F, 0xEA, 0xCC, 0x7C, 0x06, 0xD0,
+ 0xC4, 0xE9, 0x01, 0x12, 0xE0, 0x68, 0x89, 0xB1, 0x40, 0xF0, 0x80, 0x40,
+ 0x10, 0xE0, 0x19, 0x46, 0xF8, 0xF7, 0x9B, 0xDC, 0x09, 0x49, 0x03, 0x22,
+ 0x03, 0x46, 0x3C, 0x31, 0xCD, 0xE9, 0x00, 0x65, 0x38, 0x46, 0xF8, 0xF7,
+ 0x78, 0xDA, 0x00, 0x20, 0xBD, 0xE8, 0xFC, 0x81, 0x20, 0xF0, 0x80, 0x40,
+ 0xE0, 0x60, 0x01, 0x20, 0xF8, 0xE7, 0x00, 0x00, 0x00, 0x36, 0x10, 0x21,
+ 0x88, 0x01, 0xC0, 0x08, 0x2D, 0xE9, 0xFF, 0x4F, 0x85, 0xB0, 0x1D, 0x46,
+ 0x0C, 0x46, 0x06, 0x46, 0x03, 0xF4, 0xFC, 0xF2, 0x01, 0x46, 0x4F, 0xF0,
+ 0x05, 0x5B, 0x08, 0x2E, 0x09, 0xD3, 0x03, 0xF4, 0x02, 0xF3, 0x58, 0x46,
+ 0x07, 0x99, 0xF8, 0xF7, 0x72, 0xDC, 0x03, 0x46, 0x03, 0x22, 0x67, 0x49,
+ 0x20, 0xE0, 0x67, 0x48, 0x00, 0xEB, 0xC6, 0x03, 0x18, 0x78, 0xC0, 0x07,
+ 0x0F, 0xD0, 0xD8, 0x88, 0x9A, 0x88, 0x90, 0x42, 0x1A, 0xD3, 0x08, 0x46,
+ 0x03, 0xF4, 0xED, 0xF2, 0x58, 0x46, 0x07, 0x99, 0xF8, 0xF7, 0x5D, 0xDC,
+ 0x5D, 0x49, 0x03, 0x22, 0x03, 0x46, 0x6C, 0x31, 0x4B, 0xE0, 0x08, 0x46,
+ 0x03, 0xF4, 0xE1, 0xF2, 0x58, 0x46, 0x07, 0x99, 0xF8, 0xF7, 0x51, 0xDC,
+ 0x57, 0x49, 0x03, 0x22, 0x03, 0x46, 0x34, 0x31, 0xCD, 0xE9, 0x00, 0x56,
+ 0x56, 0x48, 0x3F, 0xE0, 0x84, 0xB1, 0x10, 0x34, 0xA4, 0xB2, 0xE0, 0x06,
+ 0x03, 0xD0, 0x4F, 0xF6, 0xE0, 0x70, 0x1F, 0x34, 0x04, 0x40, 0x3C, 0xB1,
+ 0xDF, 0xF8, 0x3C, 0xC1, 0xAC, 0xF1, 0x18, 0x0C, 0xDC, 0xF8, 0x04, 0x00,
+ 0x84, 0x42, 0x0B, 0xD9, 0x08, 0x46, 0x03, 0xF4, 0xC0, 0xF2, 0x58, 0x46,
+ 0x07, 0x99, 0xF8, 0xF7, 0x30, 0xDC, 0x47, 0x49, 0x03, 0x22, 0x03, 0x46,
+ 0xA0, 0x31, 0x1E, 0xE0, 0x45, 0x4A, 0x40, 0x32, 0x10, 0x46, 0x00, 0x68,
+ 0x01, 0xE0, 0x02, 0x46, 0x38, 0x46, 0xC7, 0x68, 0x27, 0xF0, 0x7F, 0x47,
+ 0xA7, 0x42, 0x02, 0xD2, 0x07, 0x68, 0x00, 0x2F, 0xF5, 0xD1, 0xDC, 0xF8,
+ 0x0C, 0x70, 0xE1, 0x46, 0xB8, 0x42, 0x13, 0xD1, 0x08, 0x46, 0x03, 0xF4,
+ 0xA0, 0xF2, 0x58, 0x46, 0x07, 0x99, 0xF8, 0xF7, 0x10, 0xDC, 0x37, 0x49,
+ 0x03, 0x22, 0x03, 0x46, 0xD8, 0x31, 0xCD, 0xE9, 0x00, 0x54, 0x36, 0x48,
+ 0xF8, 0xF7, 0xED, 0xD9, 0x00, 0x20, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F,
+ 0xD0, 0xF8, 0x0C, 0xC0, 0x17, 0x68, 0x2C, 0xF0, 0x7F, 0x4C, 0xAC, 0xEB,
+ 0x04, 0x0C, 0x07, 0xF1, 0x10, 0x0A, 0xBC, 0xF1, 0x40, 0x0F, 0x19, 0xDB,
+ 0x27, 0x44, 0xD0, 0xF8, 0x00, 0xC0, 0xC7, 0xF8, 0x00, 0xC0, 0xD0, 0xF8,
+ 0x0C, 0xC0, 0xAC, 0xEB, 0x04, 0x08, 0xD7, 0xF8, 0x0C, 0xC0, 0x68, 0xF3,
+ 0x17, 0x0C, 0x2C, 0xF0, 0x60, 0x4C, 0xC7, 0xF8, 0x0C, 0xC0, 0x17, 0x60,
+ 0xC2, 0x68, 0x64, 0xF3, 0x17, 0x02, 0xC2, 0x60, 0xD9, 0xF8, 0x04, 0x70,
+ 0x3F, 0x1B, 0x08, 0xE0, 0x07, 0x68, 0x17, 0x60, 0xC2, 0x68, 0xD9, 0xF8,
+ 0x04, 0xC0, 0x22, 0xF0, 0x7F, 0x47, 0xAC, 0xEB, 0x07, 0x07, 0x00, 0x22,
+ 0xC9, 0xF8, 0x04, 0x70, 0x02, 0x60, 0x42, 0x60, 0x82, 0x60, 0xC2, 0x68,
+ 0x22, 0xF0, 0x60, 0x42, 0x02, 0xF1, 0x00, 0x52, 0x66, 0xF3, 0x1C, 0x62,
+ 0xC2, 0x60, 0xD8, 0x88, 0x40, 0x1C, 0xD8, 0x80, 0xD9, 0xE9, 0x01, 0x03,
+ 0x98, 0x42, 0x01, 0xD2, 0xC9, 0xF8, 0x08, 0x00, 0x08, 0x46, 0x03, 0xF4,
+ 0x46, 0xF2, 0x0F, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x00, 0x07, 0x11, 0xD5,
+ 0x58, 0x46, 0x07, 0x99, 0xF8, 0xF7, 0xB1, 0xDB, 0xCD, 0xF8, 0x0C, 0xA0,
+ 0x00, 0x95, 0xCD, 0xE9, 0x01, 0x64, 0x03, 0x46, 0x05, 0x22, 0x08, 0x49,
+ 0x05, 0x48, 0xF8, 0xF7, 0x8C, 0xD9, 0x30, 0x46, 0x00, 0xF0, 0xD2, 0xFB,
+ 0x50, 0x46, 0x9A, 0xE7, 0x00, 0x02, 0xC0, 0x08, 0x94, 0x75, 0x20, 0x00,
+ 0x00, 0x36, 0x10, 0x21, 0x64, 0x01, 0x20, 0x00, 0x14, 0x03, 0xC0, 0x08,
+ 0x2D, 0xE9, 0xF7, 0x4F, 0x4F, 0xF0, 0x00, 0x0A, 0x82, 0xB0, 0x16, 0x46,
+ 0x05, 0x46, 0x57, 0x46, 0x03, 0xF4, 0x0C, 0xF2, 0x00, 0x90, 0x0D, 0xB1,
+ 0xA8, 0x07, 0x0B, 0xD0, 0x00, 0x98, 0x03, 0xF4, 0x12, 0xF2, 0x4F, 0xF0,
+ 0x05, 0x50, 0x03, 0x99, 0xF8, 0xF7, 0x81, 0xDB, 0x03, 0x46, 0x03, 0x22,
+ 0x55, 0x49, 0x53, 0xE0, 0x28, 0x46, 0x00, 0xF0, 0x43, 0xFB, 0xC8, 0xB1,
+ 0xA5, 0xF1, 0x10, 0x04, 0xE0, 0x68, 0xC0, 0xF3, 0x04, 0x61, 0x08, 0x29,
+ 0x1B, 0xD3, 0x00, 0x98, 0x03, 0xF4, 0xFB, 0xF1, 0x4F, 0xF0, 0x05, 0x50,
+ 0x03, 0x99, 0xF8, 0xF7, 0x6A, 0xDB, 0x03, 0x46, 0xE0, 0x68, 0x4A, 0x49,
+ 0xC0, 0xF3, 0x04, 0x60, 0xCD, 0xE9, 0x00, 0x60, 0x03, 0x22, 0x30, 0x31,
+ 0x47, 0x48, 0x38, 0xE0, 0x00, 0x98, 0x03, 0xF4, 0xE8, 0xF1, 0x05, 0xB0,
+ 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x4F, 0x0C, 0xF0, 0x45, 0xBF, 0x41, 0x0F,
+ 0xCA, 0x07, 0x1D, 0xD0, 0x20, 0xF0, 0x60, 0x40, 0xE0, 0x60, 0x89, 0x46,
+ 0x88, 0x07, 0x04, 0xD5, 0xD4, 0xE9, 0x01, 0x7A, 0x00, 0x20, 0x60, 0x60,
+ 0xA0, 0x60, 0x3C, 0x4A, 0xE0, 0x68, 0x53, 0x68, 0x20, 0xF0, 0x7F, 0x41,
+ 0x19, 0x44, 0x51, 0x60, 0xC0, 0xF3, 0x04, 0x61, 0x02, 0xF1, 0x18, 0x00,
+ 0x00, 0xEB, 0xC1, 0x00, 0xC1, 0x88, 0x49, 0x1E, 0xC1, 0x80, 0x02, 0xF1,
+ 0x58, 0x00, 0x15, 0xE0, 0x00, 0x98, 0x03, 0xF4, 0xBE, 0xF1, 0x4F, 0xF0,
+ 0x05, 0x50, 0x03, 0x99, 0xF8, 0xF7, 0x2D, 0xDB, 0x2C, 0x49, 0x03, 0x22,
+ 0x03, 0x46, 0x64, 0x31, 0xCD, 0xE9, 0x00, 0x65, 0x2A, 0x48, 0xF8, 0xF7,
+ 0x0A, 0xD9, 0x00, 0x20, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x08, 0x46,
+ 0x01, 0x68, 0xA1, 0x42, 0xFB, 0xD3, 0xD0, 0xF8, 0x0C, 0xC0, 0x2C, 0xF0,
+ 0x7F, 0x43, 0x03, 0xEB, 0x00, 0x08, 0xA0, 0x45, 0x06, 0xD1, 0xE4, 0x68,
+ 0x23, 0x44, 0x63, 0xF3, 0x17, 0x0C, 0x04, 0x46, 0xC0, 0xF8, 0x0C, 0xC0,
+ 0xE3, 0x68, 0x23, 0xF0, 0x7F, 0x4B, 0x0B, 0xEB, 0x04, 0x0C, 0x8C, 0x45,
+ 0x09, 0xD1, 0xD2, 0x68, 0x91, 0x42, 0x2D, 0xD0, 0xC9, 0x68, 0x59, 0x44,
+ 0x61, 0xF3, 0x17, 0x03, 0xE3, 0x60, 0x01, 0x68, 0x09, 0x68, 0x21, 0x60,
+ 0xA0, 0x42, 0x00, 0xD0, 0x04, 0x60, 0x00, 0x98, 0x03, 0xF4, 0x81, 0xF1,
+ 0x5F, 0xEA, 0x89, 0x70, 0x02, 0xD5, 0x0F, 0xB1, 0x50, 0x46, 0xB8, 0x47,
+ 0x10, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x00, 0x07, 0x12, 0xD5, 0x4F, 0xF0,
+ 0x05, 0x50, 0x03, 0x99, 0xF8, 0xF7, 0xE5, 0xDA, 0x08, 0x49, 0xCD, 0xE9,
+ 0x00, 0x65, 0x03, 0x46, 0x03, 0x22, 0x98, 0x31, 0x06, 0x48, 0xF8, 0xF7,
+ 0xC2, 0xD8, 0xE0, 0x68, 0xC0, 0xF3, 0x04, 0x60, 0x00, 0xF0, 0x06, 0xFB,
+ 0x01, 0x20, 0xB1, 0xE7, 0x22, 0x60, 0xD7, 0xE7, 0x58, 0x03, 0xC0, 0x08,
+ 0x00, 0x36, 0x10, 0x21, 0x7C, 0x75, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x70, 0xB5, 0x16, 0x4C, 0x00, 0x23, 0x03, 0xEB, 0x83, 0x05, 0x04, 0xEB,
+ 0x85, 0x05, 0xAD, 0x7C, 0xED, 0x07, 0x0E, 0xD0, 0x5B, 0x1C, 0xDB, 0xB2,
+ 0x05, 0x2B, 0xF4, 0xD3, 0x05, 0x2B, 0x14, 0xD0, 0x03, 0xEB, 0x83, 0x00,
+ 0x44, 0xF8, 0x20, 0x10, 0x04, 0xEB, 0x80, 0x00, 0x42, 0x60, 0x01, 0x20,
+ 0x70, 0xBD, 0x03, 0xEB, 0x83, 0x05, 0x04, 0xEB, 0x85, 0x05, 0x6E, 0x8A,
+ 0x46, 0xF0, 0x01, 0x06, 0x6E, 0x82, 0x03, 0xF1, 0x10, 0x05, 0x05, 0x70,
+ 0xE8, 0xE7, 0x00, 0x22, 0x04, 0x49, 0x05, 0x48, 0xF8, 0xF7, 0x87, 0xD8,
+ 0x00, 0xF0, 0x44, 0xF8, 0x00, 0x20, 0x70, 0xBD, 0xD0, 0x74, 0x20, 0x00,
+ 0xB4, 0x08, 0xC0, 0x08, 0x00, 0x36, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41,
+ 0xA0, 0xF1, 0x10, 0x01, 0x05, 0x29, 0x0A, 0xD3, 0x03, 0x46, 0x01, 0x22,
+ 0x16, 0x49, 0x17, 0x48, 0xF8, 0xF7, 0x71, 0xD8, 0x00, 0xF0, 0x2E, 0xF8,
+ 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0xC8, 0xB2, 0x13, 0x49, 0x00, 0xEB,
+ 0x80, 0x00, 0x01, 0xEB, 0x80, 0x04, 0x03, 0xF4, 0xFD, 0xF0, 0x07, 0x46,
+ 0xA0, 0x7C, 0xC0, 0x07, 0x12, 0xD0, 0x00, 0x20, 0x60, 0x82, 0x0D, 0x4E,
+ 0x20, 0x60, 0x04, 0xF1, 0x08, 0x05, 0x70, 0x36, 0x60, 0x60, 0x06, 0xE0,
+ 0x28, 0x46, 0x02, 0xF4, 0xC8, 0xF7, 0x01, 0x46, 0x30, 0x46, 0x02, 0xF4,
+ 0xAE, 0xF7, 0x20, 0x8A, 0x00, 0x28, 0xF5, 0xD1, 0x38, 0x46, 0x03, 0xF4,
+ 0xF0, 0xF0, 0x01, 0x20, 0xD9, 0xE7, 0x00, 0x00, 0xE4, 0x08, 0xC0, 0x08,
+ 0x00, 0x36, 0x10, 0x21, 0xD0, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x41,
+ 0x03, 0xF4, 0xD6, 0xF0, 0x1B, 0x4D, 0x07, 0x46, 0x1C, 0x4E, 0xB5, 0xF8,
+ 0x9E, 0x00, 0xB5, 0xF8, 0x98, 0x30, 0x35, 0xF8, 0x78, 0x1F, 0x03, 0x22,
+ 0x59, 0x1A, 0xCD, 0xE9, 0x00, 0x10, 0x16, 0x49, 0x30, 0x46, 0xF8, 0xF7,
+ 0x2C, 0xD8, 0x6B, 0x8C, 0xA9, 0x89, 0x28, 0x8D, 0x59, 0x1A, 0xCD, 0xE9,
+ 0x00, 0x10, 0x11, 0x49, 0x03, 0x22, 0x40, 0x31, 0x30, 0x46, 0x78, 0x3D,
+ 0xF8, 0xF7, 0x1F, 0xD8, 0x00, 0x24, 0x04, 0xEB, 0x84, 0x00, 0x05, 0xEB,
+ 0x80, 0x00, 0x23, 0x46, 0x01, 0x8A, 0x40, 0x8A, 0xCD, 0xE9, 0x00, 0x01,
+ 0x08, 0x49, 0x03, 0x22, 0x84, 0x31, 0x30, 0x46, 0xF8, 0xF7, 0x0F, 0xD8,
+ 0x64, 0x1C, 0xE4, 0xB2, 0x05, 0x2C, 0xEC, 0xD3, 0x38, 0x46, 0x03, 0xF4,
+ 0xAE, 0xF0, 0x01, 0x20, 0xBD, 0xE8, 0xFC, 0x81, 0xD0, 0x74, 0x20, 0x00,
+ 0x18, 0x06, 0xC0, 0x08, 0x00, 0x36, 0x10, 0x21, 0x2D, 0xE9, 0xFC, 0x41,
+ 0x04, 0x46, 0x1E, 0x46, 0x10, 0x38, 0x1E, 0x4F, 0x88, 0x46, 0x4F, 0xF0,
+ 0x05, 0x53, 0x05, 0x28, 0x07, 0xD3, 0x11, 0x46, 0x18, 0x46, 0xF8, 0xF7,
+ 0x0A, 0xDA, 0x03, 0x46, 0x03, 0x22, 0x19, 0x49, 0x24, 0xE0, 0xC0, 0xB2,
+ 0x00, 0xEB, 0x80, 0x01, 0x17, 0x48, 0x00, 0xEB, 0x81, 0x05, 0xA8, 0x7C,
+ 0xC0, 0x07, 0x13, 0xD0, 0x03, 0xF4, 0x7A, 0xF0, 0x06, 0x46, 0x05, 0xF1,
+ 0x08, 0x00, 0x02, 0xF4, 0x67, 0xF7, 0x04, 0x46, 0x30, 0x46, 0x03, 0xF4,
+ 0x7E, 0xF0, 0xB4, 0xB1, 0x14, 0x22, 0x21, 0x1D, 0x40, 0x46, 0x2A, 0xF4,
+ 0x2B, 0xF1, 0x01, 0x20, 0xBD, 0xE8, 0xFC, 0x81, 0x11, 0x46, 0x18, 0x46,
+ 0xF8, 0xF7, 0xE5, 0xD9, 0x07, 0x49, 0x03, 0x22, 0x03, 0x46, 0x38, 0x31,
+ 0xCD, 0xE9, 0x00, 0x64, 0x38, 0x46, 0xF7, 0xF7, 0xC2, 0xDF, 0xFF, 0xF7,
+ 0x7F, 0xFF, 0x00, 0x20, 0xEC, 0xE7, 0x00, 0x00, 0x00, 0x36, 0x10, 0x21,
+ 0x40, 0x08, 0xC0, 0x08, 0xD0, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x41,
+ 0x04, 0x46, 0x1E, 0x46, 0x10, 0x38, 0x23, 0x4F, 0x88, 0x46, 0x4F, 0xF0,
+ 0x05, 0x53, 0x05, 0x28, 0x07, 0xD3, 0x11, 0x46, 0x18, 0x46, 0xF8, 0xF7,
+ 0xC2, 0xD9, 0x03, 0x46, 0x03, 0x22, 0x1E, 0x49, 0x2F, 0xE0, 0xC0, 0xB2,
+ 0x00, 0xEB, 0x80, 0x01, 0x1C, 0x48, 0x00, 0xEB, 0x81, 0x05, 0xA8, 0x7C,
+ 0xC0, 0x07, 0x1E, 0xD0, 0x03, 0xF4, 0x32, 0xF0, 0x06, 0x46, 0x05, 0xF1,
+ 0x08, 0x00, 0x02, 0xF4, 0x08, 0xF7, 0x04, 0x46, 0x30, 0x46, 0x03, 0xF4,
+ 0x36, 0xF0, 0x0C, 0xB3, 0x14, 0x22, 0x21, 0x1D, 0x40, 0x46, 0x2A, 0xF4,
+ 0xE3, 0xF0, 0x03, 0xF4, 0x21, 0xF0, 0x05, 0x46, 0x0F, 0x48, 0x21, 0x46,
+ 0x70, 0x30, 0x02, 0xF4, 0xE0, 0xF6, 0x28, 0x46, 0x03, 0xF4, 0x25, 0xF0,
+ 0x01, 0x20, 0xBD, 0xE8, 0xFC, 0x81, 0x11, 0x46, 0x18, 0x46, 0xF8, 0xF7,
+ 0x92, 0xD9, 0x07, 0x49, 0x03, 0x22, 0x03, 0x46, 0x38, 0x31, 0xCD, 0xE9,
+ 0x00, 0x64, 0x38, 0x46, 0xF7, 0xF7, 0x6F, 0xDF, 0xFF, 0xF7, 0x2C, 0xFF,
+ 0x00, 0x20, 0xEC, 0xE7, 0x00, 0x36, 0x10, 0x21, 0xCC, 0x07, 0xC0, 0x08,
+ 0xD0, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x4F, 0x04, 0x46, 0x00, 0x27,
+ 0x10, 0x38, 0xDF, 0xF8, 0x28, 0xB1, 0x83, 0xB0, 0x1D, 0x46, 0x4F, 0xF0,
+ 0x05, 0x5A, 0x05, 0x28, 0x07, 0xD3, 0x50, 0x46, 0x05, 0x99, 0xF8, 0xF7,
+ 0x6E, 0xD9, 0x03, 0x46, 0x03, 0x22, 0x44, 0x49, 0x6A, 0xE0, 0xC0, 0xB2,
+ 0x00, 0xEB, 0x80, 0x01, 0x42, 0x48, 0x00, 0xEB, 0x81, 0x06, 0xB1, 0x7C,
+ 0xC9, 0x07, 0x47, 0xD0, 0x80, 0x46, 0x02, 0xF4, 0xDD, 0xF7, 0x00, 0x90,
+ 0x3D, 0x48, 0x70, 0x30, 0x02, 0xF4, 0xB3, 0xF6, 0x81, 0x46, 0x00, 0x98,
+ 0x02, 0xF4, 0xE1, 0xF7, 0xB9, 0xF1, 0x00, 0x0F, 0x41, 0xD0, 0xB8, 0xF8,
+ 0x98, 0x00, 0xB8, 0xF8, 0x78, 0x20, 0xB8, 0xF8, 0x9E, 0x10, 0x80, 0x1A,
+ 0x88, 0x42, 0x01, 0xDD, 0xA8, 0xF8, 0x9E, 0x00, 0x14, 0x22, 0x09, 0xF1,
+ 0x04, 0x00, 0x04, 0x99, 0x2A, 0xF4, 0x80, 0xF0, 0x02, 0xF4, 0xBE, 0xF7,
+ 0x00, 0x90, 0x49, 0x46, 0x06, 0xF1, 0x08, 0x00, 0x02, 0xF4, 0x7D, 0xF6,
+ 0x2B, 0x48, 0x7C, 0x30, 0x02, 0xF4, 0x8F, 0xF6, 0x81, 0x46, 0x00, 0x98,
+ 0x02, 0xF4, 0xBD, 0xF7, 0xB9, 0xF1, 0x00, 0x0F, 0x26, 0xD0, 0xB8, 0xF8,
+ 0x9A, 0x00, 0xB8, 0xF8, 0x84, 0x10, 0x44, 0x46, 0x40, 0x1A, 0xB8, 0xF8,
+ 0xA0, 0x10, 0x88, 0x42, 0x01, 0xDD, 0xA4, 0xF8, 0xA0, 0x00, 0xC9, 0xF8,
+ 0x04, 0x60, 0x02, 0xF4, 0x9D, 0xF7, 0x05, 0x46, 0xB4, 0xF8, 0x90, 0x00,
+ 0x28, 0xB3, 0x25, 0xE0, 0x50, 0x46, 0x05, 0x99, 0xF8, 0xF7, 0x15, 0xD9,
+ 0x18, 0x49, 0x03, 0x22, 0x03, 0x46, 0x38, 0x31, 0x10, 0xE0, 0x50, 0x46,
+ 0x05, 0x99, 0xF8, 0xF7, 0x0C, 0xD9, 0x14, 0x49, 0x03, 0x22, 0x03, 0x46,
+ 0x74, 0x31, 0x07, 0xE0, 0x50, 0x46, 0x05, 0x99, 0xF8, 0xF7, 0x03, 0xD9,
+ 0x0F, 0x49, 0x03, 0x22, 0x03, 0x46, 0xB4, 0x31, 0xCD, 0xE9, 0x00, 0x54,
+ 0x58, 0x46, 0xF7, 0xF7, 0xE0, 0xDE, 0xFF, 0xF7, 0x9D, 0xFE, 0x00, 0x20,
+ 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x01, 0x27, 0x08, 0x48, 0x49, 0x46,
+ 0x88, 0x30, 0x02, 0xF4, 0x32, 0xF6, 0x28, 0x46, 0x02, 0xF4, 0x77, 0xF7,
+ 0x0F, 0xB1, 0x00, 0xF0, 0xBB, 0xFB, 0x01, 0x20, 0xEE, 0xE7, 0x00, 0x00,
+ 0x00, 0x36, 0x10, 0x21, 0xD4, 0x06, 0xC0, 0x08, 0xD0, 0x74, 0x20, 0x00,
+ 0x01, 0x48, 0x90, 0xF8, 0x95, 0x00, 0x70, 0x47, 0xD0, 0x74, 0x20, 0x00,
+ 0x70, 0xB5, 0x12, 0x4D, 0x95, 0xF8, 0x95, 0x00, 0x30, 0xB1, 0x00, 0x22,
+ 0x10, 0x49, 0x11, 0x48, 0xF7, 0xF7, 0xB5, 0xDE, 0x01, 0x20, 0x70, 0xBD,
+ 0x00, 0xF0, 0x0E, 0xFB, 0x04, 0x00, 0x0B, 0xD0, 0x00, 0xF0, 0xC2, 0xFB,
+ 0x04, 0x00, 0x07, 0xD0, 0x00, 0xF0, 0xA6, 0xFB, 0x04, 0x00, 0x03, 0xD0,
+ 0x0D, 0xF0, 0x08, 0xFD, 0x04, 0x00, 0x05, 0xD1, 0x05, 0x49, 0x00, 0x22,
+ 0x20, 0x31, 0x06, 0x48, 0xF7, 0xF7, 0x9D, 0xDE, 0x85, 0xF8, 0x95, 0x40,
+ 0x20, 0x46, 0x70, 0xBD, 0xD0, 0x74, 0x20, 0x00, 0x14, 0x00, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x00, 0x36, 0x10, 0x21, 0x7C, 0xB5, 0x36, 0x4D,
+ 0x36, 0x4C, 0x95, 0xF8, 0x8D, 0x31, 0x53, 0xB1, 0x48, 0x20, 0xCD, 0xE9,
+ 0x00, 0x40, 0xB5, 0xF8, 0x96, 0x21, 0x01, 0x21, 0x32, 0x48, 0x00, 0xF0,
+ 0x73, 0xF8, 0x00, 0x28, 0x5A, 0xD0, 0x95, 0xF8, 0x9C, 0x31, 0x73, 0xB1,
+ 0xB5, 0xF8, 0xA4, 0x01, 0x58, 0xB1, 0x51, 0x21, 0x1E, 0x30, 0x82, 0xB2,
+ 0xCD, 0xE9, 0x00, 0x41, 0x2A, 0x48, 0x01, 0x21, 0x80, 0x1C, 0x00, 0xF0,
+ 0x61, 0xF8, 0x00, 0x28, 0x48, 0xD0, 0x95, 0xF8, 0x9A, 0x31, 0x73, 0xB1,
+ 0xB5, 0xF8, 0xA0, 0x01, 0x58, 0xB1, 0x5B, 0x21, 0x1E, 0x30, 0x82, 0xB2,
+ 0xCD, 0xE9, 0x00, 0x41, 0x21, 0x48, 0x01, 0x21, 0xC0, 0x1C, 0x00, 0xF0,
+ 0x4F, 0xF8, 0x00, 0x28, 0x36, 0xD0, 0x95, 0xF8, 0x9B, 0x21, 0x72, 0xB1,
+ 0xB5, 0xF8, 0xA2, 0x01, 0x58, 0xB1, 0x65, 0x21, 0x1E, 0x30, 0x00, 0x91,
+ 0x81, 0xB2, 0x19, 0x48, 0x17, 0x4B, 0xC0, 0x1E, 0x80, 0x79, 0x00, 0xF0,
+ 0xEF, 0xF8, 0x00, 0x28, 0x24, 0xD0, 0x95, 0xF8, 0x9D, 0x31, 0x73, 0xB1,
+ 0xB5, 0xF8, 0xA6, 0x01, 0x58, 0xB1, 0x6F, 0x21, 0x1E, 0x30, 0x82, 0xB2,
+ 0xCD, 0xE9, 0x00, 0x41, 0x0F, 0x48, 0x01, 0x21, 0x40, 0x1C, 0x00, 0xF0,
+ 0x2B, 0xF8, 0x00, 0x28, 0x12, 0xD0, 0x95, 0xF8, 0x9E, 0x31, 0x73, 0xB1,
+ 0xB5, 0xF8, 0xA8, 0x01, 0x58, 0xB1, 0x79, 0x21, 0x1E, 0x30, 0x82, 0xB2,
+ 0xCD, 0xE9, 0x00, 0x41, 0x06, 0x48, 0x01, 0x21, 0x00, 0x1D, 0x00, 0xF0,
+ 0x19, 0xF8, 0x00, 0x28, 0x00, 0xD0, 0x01, 0x20, 0x7C, 0xBD, 0x00, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0xAC, 0xA6, 0x82, 0x00, 0x03, 0x74, 0x20, 0x00,
+ 0x05, 0x49, 0x0A, 0x69, 0x82, 0x42, 0x04, 0xD8, 0x49, 0x69, 0x81, 0x42,
+ 0x01, 0xD3, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00,
+ 0x7C, 0x75, 0x20, 0x00, 0x2D, 0xE9, 0xFE, 0x4F, 0x8B, 0x46, 0xDD, 0xE9,
+ 0x0C, 0x16, 0x14, 0x00, 0x82, 0x46, 0xDF, 0xF8, 0x94, 0x90, 0x1D, 0x46,
+ 0x4F, 0xF0, 0x00, 0x02, 0x4F, 0xF0, 0x05, 0x50, 0x24, 0xD0, 0x1D, 0xB3,
+ 0x00, 0x23, 0x21, 0x4F, 0x9C, 0x46, 0x17, 0xF8, 0x33, 0x80, 0x5F, 0xEA,
+ 0xC8, 0x78, 0x27, 0xD0, 0x5B, 0x1C, 0xDB, 0xB2, 0x08, 0x2B, 0xF6, 0xD3,
+ 0x08, 0x2B, 0x26, 0xD0, 0x8A, 0xF8, 0x00, 0x30, 0x10, 0x88, 0x40, 0xF0,
+ 0x01, 0x00, 0x40, 0xEA, 0x0B, 0x20, 0x10, 0x80, 0x16, 0x48, 0x54, 0x80,
+ 0x95, 0x80, 0x18, 0x38, 0xA2, 0xF8, 0x06, 0xC0, 0x01, 0x68, 0x10, 0x34,
+ 0x04, 0xFB, 0x05, 0x11, 0x01, 0x60, 0x01, 0x20, 0xBD, 0xE8, 0xFE, 0x8F,
+ 0xF7, 0xF7, 0xF3, 0xDF, 0x03, 0x46, 0x00, 0x96, 0x04, 0x22, 0x0E, 0x49,
+ 0x48, 0x46, 0xCD, 0xE9, 0x01, 0x45, 0xF7, 0xF7, 0xD0, 0xDD, 0x0E, 0xE0,
+ 0x07, 0xEB, 0xC3, 0x02, 0xA2, 0xF8, 0x00, 0xC0, 0xD6, 0xE7, 0xF7, 0xF7,
+ 0xE2, 0xDF, 0x07, 0x49, 0x03, 0x46, 0x02, 0x22, 0x44, 0x31, 0x48, 0x46,
+ 0x00, 0x96, 0xF7, 0xF7, 0xC0, 0xDD, 0x00, 0x20, 0xE0, 0xE7, 0x00, 0x00,
+ 0x00, 0x36, 0x10, 0x21, 0x94, 0x75, 0x20, 0x00, 0x50, 0x00, 0xC0, 0x08,
+ 0x2D, 0xE9, 0xFF, 0x41, 0x08, 0x28, 0x02, 0xD3, 0x00, 0x24, 0x08, 0x25,
+ 0x02, 0xE0, 0x04, 0x46, 0x40, 0x1C, 0xC5, 0xB2, 0x24, 0x48, 0x26, 0x4E,
+ 0xD0, 0xE9, 0x01, 0x12, 0xCD, 0xE9, 0x00, 0x12, 0x03, 0x68, 0x03, 0x22,
+ 0x21, 0x49, 0x30, 0x46, 0xF7, 0xF7, 0xA1, 0xDD, 0x02, 0xF4, 0x38, 0xF6,
+ 0x1D, 0x4F, 0x80, 0x46, 0x18, 0x37, 0x15, 0xE0, 0x37, 0xF8, 0x34, 0x10,
+ 0xC8, 0x07, 0x0F, 0xD0, 0x07, 0xEB, 0xC4, 0x00, 0xC2, 0x88, 0x83, 0x88,
+ 0x40, 0x88, 0x00, 0x91, 0x03, 0x92, 0xCD, 0xE9, 0x01, 0x03, 0x16, 0x49,
+ 0x23, 0x46, 0x05, 0x22, 0x44, 0x31, 0x30, 0x46, 0xF7, 0xF7, 0x87, 0xDD,
+ 0x64, 0x1C, 0xE4, 0xB2, 0xAC, 0x42, 0xE7, 0xD3, 0x0F, 0x48, 0x58, 0x30,
+ 0x04, 0x68, 0x12, 0xE0, 0xE1, 0x68, 0x23, 0x68, 0x4A, 0x0F, 0xC1, 0xF3,
+ 0x04, 0x60, 0x21, 0xF0, 0x7F, 0x41, 0xCD, 0xE9, 0x00, 0x31, 0xCD, 0xE9,
+ 0x02, 0x02, 0x09, 0x49, 0x23, 0x46, 0x05, 0x22, 0x90, 0x31, 0x30, 0x46,
+ 0xF7, 0xF7, 0x6D, 0xDD, 0x24, 0x68, 0x00, 0x2C, 0xEA, 0xD1, 0x04, 0xB0,
+ 0x40, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0x02, 0xF4, 0x0A, 0xB6, 0x00, 0x00,
+ 0x7C, 0x75, 0x20, 0x00, 0x20, 0x04, 0xC0, 0x08, 0x00, 0x36, 0x10, 0x21,
+ 0x2D, 0xE9, 0xFE, 0x43, 0x04, 0x46, 0xDF, 0xF8, 0x90, 0x80, 0x0A, 0x9F,
+ 0x16, 0x46, 0x0D, 0x00, 0x4F, 0xF0, 0x05, 0x50, 0x0C, 0xD0, 0x5E, 0xB1,
+ 0x08, 0x2C, 0x17, 0xD3, 0x19, 0x46, 0xF7, 0xF7, 0x66, 0xDF, 0xCD, 0xE9,
+ 0x00, 0x74, 0x03, 0x46, 0x03, 0x22, 0x1C, 0x49, 0x40, 0x46, 0x2F, 0xE0,
+ 0x19, 0x46, 0xF7, 0xF7, 0x5C, 0xDF, 0x00, 0x97, 0x18, 0x49, 0xCD, 0xE9,
+ 0x01, 0x56, 0x03, 0x46, 0x04, 0x22, 0x44, 0x39, 0x40, 0x46, 0xF7, 0xF7,
+ 0x38, 0xDD, 0x23, 0xE0, 0x14, 0x49, 0x01, 0xEB, 0xC4, 0x04, 0x21, 0x78,
+ 0xC9, 0x07, 0x10, 0xD0, 0x60, 0x88, 0xA8, 0x42, 0x00, 0xD2, 0x65, 0x80,
+ 0xA0, 0x88, 0x30, 0x44, 0xA0, 0x80, 0x0E, 0x48, 0x18, 0x38, 0x10, 0x35,
+ 0x01, 0x68, 0x05, 0xFB, 0x02, 0x11, 0x01, 0x60, 0x01, 0x20, 0xBD, 0xE8,
+ 0xFE, 0x83, 0x19, 0x46, 0xF7, 0xF7, 0x37, 0xDF, 0x03, 0x46, 0x20, 0x88,
+ 0x05, 0x49, 0xCD, 0xE9, 0x00, 0x70, 0x03, 0x22, 0x3C, 0x31, 0x40, 0x46,
+ 0xF7, 0xF7, 0x13, 0xDD, 0x00, 0x20, 0xEE, 0xE7, 0x00, 0x36, 0x10, 0x21,
+ 0x10, 0x01, 0xC0, 0x08, 0x94, 0x75, 0x20, 0x00, 0x70, 0xB5, 0x1D, 0x4C,
+ 0x09, 0xB1, 0x21, 0x60, 0x04, 0xE0, 0x21, 0x68, 0x91, 0x42, 0x01, 0xD9,
+ 0x89, 0x1A, 0xF8, 0xE7, 0x0D, 0x46, 0xF2, 0x23, 0x18, 0x4A, 0x02, 0xF4,
+ 0x91, 0xF2, 0x00, 0x28, 0x29, 0xD0, 0x02, 0x46, 0xC1, 0x06, 0x04, 0xD0,
+ 0x1F, 0x32, 0x22, 0xF0, 0x1F, 0x02, 0x10, 0x1A, 0x2D, 0x1A, 0x11, 0x4B,
+ 0x00, 0x21, 0x58, 0x33, 0x1A, 0x60, 0xD8, 0x68, 0x00, 0xF0, 0x7F, 0x40,
+ 0xD8, 0x60, 0x50, 0x19, 0x10, 0x38, 0x20, 0xF0, 0x1F, 0x00, 0xE0, 0x60,
+ 0x01, 0x60, 0xE1, 0x68, 0xCD, 0x68, 0x05, 0xF0, 0x7F, 0x45, 0xCD, 0x60,
+ 0x81, 0x1A, 0x10, 0x60, 0xD0, 0x68, 0x61, 0xF3, 0x17, 0x00, 0xD0, 0x60,
+ 0x20, 0xF0, 0x7F, 0x40, 0x60, 0x60, 0xA0, 0x60, 0x18, 0x68, 0x20, 0x61,
+ 0xE0, 0x68, 0x60, 0x61, 0x01, 0x20, 0x70, 0xBD, 0x7C, 0x75, 0x20, 0x00,
+ 0x78, 0xA6, 0x82, 0x00, 0x02, 0x68, 0x82, 0xB1, 0x8A, 0x42, 0x06, 0xD1,
+ 0x11, 0x68, 0x01, 0x60, 0x71, 0xB9, 0x00, 0x21, 0x41, 0x60, 0x0B, 0xE0,
+ 0x1A, 0x46, 0x13, 0x68, 0x2B, 0xB1, 0x8B, 0x42, 0xFA, 0xD1, 0x19, 0x68,
+ 0x11, 0x60, 0x11, 0xB1, 0x02, 0xE0, 0x00, 0x20, 0x70, 0x47, 0x42, 0x60,
+ 0x01, 0x20, 0x70, 0x47, 0x00, 0x22, 0x0A, 0x60, 0x42, 0x68, 0x12, 0xB1,
+ 0x11, 0x60, 0x41, 0x60, 0x70, 0x47, 0x01, 0x60, 0xFB, 0xE7, 0x00, 0x21,
+ 0x01, 0x60, 0x41, 0x60, 0x70, 0x47, 0x03, 0x68, 0x23, 0xB1, 0x41, 0xB1,
+ 0x08, 0x68, 0x10, 0x60, 0x0A, 0x60, 0x70, 0x47, 0x02, 0x60, 0x42, 0x60,
+ 0x00, 0x20, 0x10, 0x60, 0x70, 0x47, 0x13, 0x60, 0x02, 0x60, 0x70, 0x47,
+ 0x1C, 0xB5, 0x08, 0x48, 0x03, 0x22, 0xB0, 0xF8, 0x9C, 0x10, 0xB0, 0xF8,
+ 0x96, 0x30, 0xB0, 0xF8, 0x6C, 0x00, 0x18, 0x1A, 0xCD, 0xE9, 0x00, 0x01,
+ 0x03, 0x49, 0x04, 0x48, 0xF7, 0xF7, 0x87, 0xDC, 0x1C, 0xBD, 0x00, 0x00,
+ 0xD0, 0x74, 0x20, 0x00, 0xF8, 0x04, 0xC0, 0x08, 0x00, 0x36, 0x10, 0x21,
+ 0x38, 0xB5, 0x1C, 0x46, 0x0B, 0x46, 0x40, 0xB1, 0x01, 0x68, 0xA1, 0xB1,
+ 0x14, 0x22, 0x18, 0x46, 0x09, 0x1D, 0x29, 0xF4, 0xCD, 0xF5, 0x01, 0x20,
+ 0x38, 0xBD, 0x11, 0x46, 0x4F, 0xF0, 0x05, 0x50, 0xF7, 0xF7, 0x87, 0xDE,
+ 0x03, 0x46, 0x02, 0x22, 0x04, 0x49, 0x05, 0x48, 0x00, 0x94, 0xF7, 0xF7,
+ 0x66, 0xDC, 0xFF, 0xF7, 0xCD, 0xFF, 0x00, 0x20, 0x38, 0xBD, 0x00, 0x00,
+ 0xE0, 0x05, 0xC0, 0x08, 0x00, 0x36, 0x10, 0x21, 0x38, 0xB5, 0x1C, 0x46,
+ 0x0B, 0x46, 0x70, 0xB1, 0x00, 0xF0, 0x70, 0xF8, 0x04, 0x00, 0x18, 0xD0,
+ 0x14, 0x22, 0x21, 0x1D, 0x18, 0x46, 0x29, 0xF4, 0xA9, 0xF5, 0x21, 0x46,
+ 0x0A, 0x48, 0x02, 0xF4, 0xAA, 0xF3, 0x01, 0x20, 0x38, 0xBD, 0x11, 0x46,
+ 0x4F, 0xF0, 0x05, 0x50, 0xF7, 0xF7, 0x5F, 0xDE, 0x03, 0x46, 0x02, 0x22,
+ 0x05, 0x49, 0x06, 0x48, 0x00, 0x94, 0xF7, 0xF7, 0x3E, 0xDC, 0xFF, 0xF7,
+ 0xA5, 0xFF, 0x00, 0x20, 0x38, 0xBD, 0x00, 0x00, 0x34, 0x75, 0x20, 0x00,
+ 0xA8, 0x05, 0xC0, 0x08, 0x00, 0x36, 0x10, 0x21, 0x2D, 0xE9, 0xFC, 0x47,
+ 0xDF, 0xF8, 0x84, 0x80, 0x1E, 0x46, 0x8A, 0x46, 0x05, 0x00, 0x91, 0x46,
+ 0x4F, 0xF0, 0x05, 0x57, 0x1D, 0xD0, 0x1E, 0x48, 0x02, 0xF4, 0x99, 0xF3,
+ 0x04, 0x00, 0x24, 0xD0, 0x1B, 0x49, 0x64, 0x39, 0xB1, 0xF8, 0x96, 0x00,
+ 0xB1, 0xF8, 0x6C, 0x20, 0x80, 0x1A, 0xB1, 0xF8, 0x9C, 0x20, 0x90, 0x42,
+ 0x01, 0xDD, 0xA1, 0xF8, 0x9C, 0x00, 0x14, 0x22, 0x51, 0x46, 0x20, 0x1D,
+ 0x29, 0xF4, 0x6A, 0xF5, 0x21, 0x46, 0x28, 0x46, 0xFF, 0xF7, 0x5A, 0xFF,
+ 0x01, 0x20, 0xBD, 0xE8, 0xFC, 0x87, 0x11, 0x46, 0x38, 0x46, 0xF7, 0xF7,
+ 0x20, 0xDE, 0x03, 0x46, 0x02, 0x22, 0x0D, 0x49, 0x40, 0x46, 0x00, 0x96,
+ 0xF7, 0xF7, 0xFF, 0xDB, 0x0C, 0xE0, 0x49, 0x46, 0x38, 0x46, 0xF7, 0xF7,
+ 0x14, 0xDE, 0x08, 0x49, 0xCD, 0xE9, 0x00, 0x65, 0x03, 0x46, 0x03, 0x22,
+ 0x38, 0x31, 0x40, 0x46, 0xF7, 0xF7, 0xF1, 0xDB, 0xFF, 0xF7, 0x58, 0xFF,
+ 0x00, 0x20, 0xE0, 0xE7, 0x00, 0x36, 0x10, 0x21, 0x34, 0x75, 0x20, 0x00,
+ 0x34, 0x05, 0xC0, 0x08, 0x01, 0x46, 0x00, 0x68, 0x00, 0x28, 0x04, 0xD0,
+ 0x02, 0x68, 0x0A, 0x60, 0x00, 0x2A, 0x00, 0xD1, 0x4A, 0x60, 0x70, 0x47,
+ 0x00, 0x68, 0x70, 0x47, 0x01, 0x48, 0xB0, 0xF8, 0x78, 0x00, 0x70, 0x47,
+ 0xD0, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x02, 0xF4, 0x6A, 0xF4,
+ 0x15, 0x4F, 0x04, 0x46, 0x97, 0xF8, 0x94, 0x00, 0x01, 0x28, 0x07, 0xD0,
+ 0x01, 0x20, 0x87, 0xF8, 0x94, 0x00, 0x07, 0xF1, 0x88, 0x09, 0x07, 0xF1,
+ 0x7C, 0x08, 0x16, 0xE0, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x02, 0xF4,
+ 0x64, 0xB4, 0x48, 0x46, 0x02, 0xF4, 0x2F, 0xF3, 0x01, 0x46, 0x40, 0x68,
+ 0xD0, 0xE9, 0x00, 0x56, 0x40, 0x46, 0x02, 0xF4, 0x12, 0xF3, 0x20, 0x46,
+ 0x02, 0xF4, 0x57, 0xF4, 0x30, 0x46, 0xA8, 0x47, 0x02, 0xF4, 0x46, 0xF4,
+ 0x04, 0x46, 0xB7, 0xF8, 0x90, 0x00, 0x00, 0x28, 0xE9, 0xD1, 0x87, 0xF8,
+ 0x94, 0x00, 0xE1, 0xE7, 0xD0, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x41,
+ 0x3C, 0x4E, 0x3D, 0x4D, 0x4F, 0xF4, 0xE6, 0x73, 0xB6, 0xF8, 0x7A, 0x01,
+ 0xA5, 0xF8, 0x96, 0x00, 0xB6, 0xF8, 0x7E, 0x11, 0xA5, 0xF8, 0x98, 0x10,
+ 0xB6, 0xF8, 0x7C, 0x11, 0xA5, 0xF8, 0x9A, 0x10, 0x00, 0xEB, 0x40, 0x00,
+ 0xC1, 0x00, 0x35, 0x4A, 0x00, 0x20, 0x02, 0xF4, 0x1F, 0xF1, 0x04, 0x1E,
+ 0x5E, 0xD0, 0x00, 0x27, 0x05, 0xF1, 0x64, 0x08, 0x06, 0xE0, 0x21, 0x46,
+ 0x18, 0x34, 0x40, 0x46, 0x02, 0xF4, 0xDD, 0xF2, 0x7F, 0x1C, 0xBF, 0xB2,
+ 0xB5, 0xF8, 0x96, 0x00, 0xB8, 0x42, 0xF4, 0xD8, 0xB5, 0xF8, 0x98, 0x00,
+ 0x40, 0xF2, 0xD9, 0x13, 0x00, 0xEB, 0x40, 0x00, 0xC1, 0x00, 0x27, 0x4A,
+ 0x00, 0x20, 0x02, 0xF4, 0x03, 0xF1, 0x04, 0x1E, 0x42, 0xD0, 0x00, 0x27,
+ 0x05, 0xF1, 0x70, 0x08, 0x06, 0xE0, 0x21, 0x46, 0x18, 0x34, 0x40, 0x46,
+ 0x02, 0xF4, 0xC1, 0xF2, 0x7F, 0x1C, 0xBF, 0xB2, 0xB5, 0xF8, 0x98, 0x00,
+ 0xB8, 0x42, 0xF4, 0xD8, 0xB5, 0xF8, 0x9A, 0x00, 0x4F, 0xF4, 0xF3, 0x73,
+ 0xC1, 0x00, 0x1A, 0x4A, 0x00, 0x20, 0x02, 0xF4, 0xE9, 0xF0, 0x04, 0x1E,
+ 0x28, 0xD0, 0x00, 0x27, 0x05, 0xF1, 0x7C, 0x08, 0x06, 0xE0, 0x21, 0x46,
+ 0x08, 0x34, 0x40, 0x46, 0x02, 0xF4, 0xA7, 0xF2, 0x7F, 0x1C, 0xBF, 0xB2,
+ 0xB5, 0xF8, 0x9A, 0x00, 0xB8, 0x42, 0xF4, 0xD8, 0xB6, 0xF8, 0x80, 0x01,
+ 0x25, 0xF8, 0xA2, 0x0F, 0xB6, 0xF8, 0x82, 0x11, 0x69, 0x80, 0xCD, 0xE9,
+ 0x00, 0x01, 0x0A, 0x48, 0x0B, 0x4B, 0x0C, 0x4A, 0x0C, 0xA1, 0xA8, 0x30,
+ 0x02, 0xF4, 0x8C, 0xF4, 0x0E, 0x49, 0x04, 0x46, 0x09, 0x68, 0x21, 0xB9,
+ 0x01, 0x22, 0x11, 0x46, 0x0B, 0x48, 0x02, 0xF4, 0xDF, 0xF3, 0x20, 0x46,
+ 0xBD, 0xE8, 0xFC, 0x81, 0x64, 0x01, 0x20, 0x00, 0xD0, 0x74, 0x20, 0x00,
+ 0x8B, 0xA6, 0x82, 0x00, 0xAD, 0x08, 0x81, 0x00, 0x21, 0x0B, 0x81, 0x00,
+ 0x55, 0x70, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x54, 0x61,
+ 0x73, 0x6B, 0x00, 0x00, 0xE4, 0x75, 0x20, 0x00, 0x04, 0x48, 0x00, 0x68,
+ 0x08, 0xB1, 0x02, 0xF4, 0xFC, 0xB3, 0x00, 0x22, 0x02, 0x49, 0x03, 0x48,
+ 0xF7, 0xF7, 0x09, 0x9B, 0xE4, 0x75, 0x20, 0x00, 0x10, 0x09, 0xC0, 0x08,
+ 0x00, 0x36, 0x10, 0x21, 0x10, 0xB5, 0x0C, 0xF0, 0x4D, 0xF9, 0x00, 0x28,
+ 0x0F, 0xD0, 0x0E, 0xF0, 0x9B, 0xFC, 0x00, 0x28, 0x0B, 0xD0, 0x17, 0xF0,
+ 0xED, 0xFC, 0x00, 0x28, 0x07, 0xD0, 0x09, 0xF0, 0x69, 0xFC, 0x00, 0x28,
+ 0x03, 0xD0, 0xBD, 0xE8, 0x10, 0x40, 0x02, 0xF0, 0x2B, 0xBE, 0x10, 0xBD,
+ 0x0D, 0xF0, 0x4E, 0xB9, 0x10, 0xB5, 0x00, 0xF0, 0x11, 0xF8, 0x00, 0x28,
+ 0x0B, 0xD0, 0xFF, 0xF7, 0x53, 0xFC, 0x00, 0x28, 0x07, 0xD0, 0x04, 0x48,
+ 0xD0, 0xE9, 0x61, 0x12, 0xBD, 0xE8, 0x10, 0x40, 0x01, 0x20, 0xFF, 0xF7,
+ 0xCF, 0xBD, 0x10, 0xBD, 0x64, 0x01, 0x20, 0x00, 0x7C, 0xB5, 0x1A, 0x4C,
+ 0x1A, 0x4D, 0x94, 0xF8, 0x8F, 0x31, 0x5B, 0xB1, 0xB4, 0xF8, 0x92, 0x21,
+ 0x42, 0xB1, 0x24, 0x20, 0xCD, 0xE9, 0x00, 0x50, 0x01, 0x21, 0x16, 0x48,
+ 0xFF, 0xF7, 0xB8, 0xFC, 0x00, 0x28, 0x22, 0xD0, 0x94, 0xF8, 0x8C, 0x31,
+ 0x63, 0xB1, 0xB4, 0xF8, 0x94, 0x21, 0x4A, 0xB1, 0x2D, 0x20, 0xCD, 0xE9,
+ 0x00, 0x50, 0x0F, 0x48, 0x01, 0x21, 0x80, 0x1C, 0xFF, 0xF7, 0xA8, 0xFC,
+ 0x00, 0x28, 0x12, 0xD0, 0xB4, 0xF8, 0x90, 0x01, 0x70, 0xB1, 0x94, 0xF8,
+ 0x8E, 0x31, 0x5B, 0xB1, 0x37, 0x21, 0x22, 0x30, 0x82, 0xB2, 0xCD, 0xE9,
+ 0x00, 0x51, 0x06, 0x48, 0x01, 0x21, 0x40, 0x1C, 0xFF, 0xF7, 0x96, 0xFC,
+ 0x00, 0x28, 0x00, 0xD0, 0x01, 0x20, 0x7C, 0xBD, 0x64, 0x01, 0x20, 0x00,
+ 0x9A, 0xA6, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x05, 0x4D, 0x04, 0x46,
+ 0x4F, 0xF0, 0xFF, 0x36, 0x28, 0x68, 0x10, 0xB1, 0x31, 0x46, 0x02, 0xF4,
+ 0x6D, 0xF3, 0xA0, 0x47, 0xF8, 0xE7, 0x00, 0x00, 0xE4, 0x75, 0x20, 0x00,
+ 0x01, 0xB5, 0x86, 0xB0, 0x05, 0xA9, 0x06, 0xA8, 0x02, 0xF4, 0xA8, 0xF4,
+ 0x00, 0x28, 0x11, 0xD0, 0x4F, 0xF4, 0xC0, 0x60, 0xAD, 0xF8, 0x00, 0x00,
+ 0x05, 0x99, 0x18, 0x23, 0x08, 0x0E, 0x8D, 0xF8, 0x04, 0x00, 0x0A, 0x0C,
+ 0x8D, 0xF8, 0x05, 0x20, 0xAD, 0xF8, 0x06, 0x10, 0x02, 0x4A, 0x69, 0x46,
+ 0xFF, 0xF7, 0x0E, 0xFB, 0x07, 0xB0, 0x00, 0xBD, 0xBD, 0xA6, 0x82, 0x00,
+ 0x7C, 0xB5, 0x04, 0x00, 0x02, 0xD0, 0x20, 0x68, 0x10, 0xB1, 0x0A, 0xE0,
+ 0x00, 0x20, 0x7C, 0xBD, 0x06, 0x4D, 0x00, 0x20, 0xCD, 0xE9, 0x00, 0x05,
+ 0x20, 0x46, 0x02, 0xF4, 0x9C, 0xF4, 0x00, 0x28, 0xF5, 0xD0, 0x20, 0x46,
+ 0xBD, 0xE8, 0x7C, 0x40, 0x02, 0xF4, 0xB8, 0xB4, 0x3D, 0x0B, 0x81, 0x00,
+ 0x02, 0xF4, 0xE9, 0xB4, 0x10, 0xB5, 0x8C, 0xB0, 0x08, 0x24, 0x8D, 0xF8,
+ 0x0B, 0x20, 0xAD, 0xF8, 0x02, 0x40, 0x8D, 0xF8, 0x0A, 0x10, 0x01, 0x68,
+ 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x1B, 0xB1, 0x18, 0x68,
+ 0x03, 0x90, 0x58, 0x68, 0x01, 0xE0, 0x00, 0x20, 0x03, 0x90, 0x04, 0x90,
+ 0x01, 0x21, 0x68, 0x46, 0x04, 0xF0, 0xB4, 0xFA, 0x0C, 0xB0, 0x10, 0xBD,
+ 0x00, 0xB5, 0x0C, 0x49, 0x93, 0xB0, 0x09, 0x7A, 0x00, 0x29, 0x11, 0xD0,
+ 0x05, 0x21, 0xAD, 0xF8, 0x0A, 0x00, 0xAD, 0xF8, 0x02, 0x10, 0x0C, 0xA8,
+ 0x0B, 0xF0, 0xFE, 0xFD, 0x0C, 0x98, 0x01, 0x90, 0xBD, 0xF8, 0x34, 0x00,
+ 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0x04, 0xF0, 0x9A, 0xFA,
+ 0x13, 0xB0, 0x00, 0xBD, 0xD0, 0x77, 0x20, 0x00, 0x70, 0xB5, 0x12, 0x4A,
+ 0x12, 0x4B, 0x05, 0x46, 0x00, 0x20, 0xD2, 0x68, 0x93, 0xF8, 0x98, 0x31,
+ 0x05, 0xE0, 0x02, 0xEB, 0x40, 0x14, 0x26, 0x7D, 0x56, 0xB1, 0x40, 0x1C,
+ 0x80, 0xB2, 0x83, 0x42, 0xF7, 0xD8, 0x00, 0x24, 0x22, 0x46, 0x0B, 0x49,
+ 0x0B, 0x48, 0xF7, 0xF7, 0x06, 0xDA, 0x0A, 0xE0, 0x4C, 0xB1, 0x28, 0x68,
+ 0xC4, 0xF8, 0x16, 0x00, 0xA8, 0x88, 0x60, 0x83, 0x61, 0x75, 0x01, 0x20,
+ 0x20, 0x75, 0x20, 0x77, 0x60, 0x77, 0x20, 0x46, 0x70, 0xBD, 0x00, 0x00,
+ 0xD0, 0x77, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0xC0, 0x57, 0xC0, 0x08,
+ 0x00, 0x37, 0x10, 0x21, 0x70, 0xB5, 0x90, 0xB0, 0x1A, 0x26, 0xDD, 0xE9,
+ 0x14, 0x54, 0xAD, 0xF8, 0x00, 0x60, 0x00, 0xB9, 0x0E, 0x48, 0x03, 0xB9,
+ 0x0D, 0x4B, 0x1C, 0x2A, 0x00, 0xD9, 0x1C, 0x22, 0x8D, 0xF8, 0x0A, 0x10,
+ 0x8D, 0xF8, 0x28, 0x50, 0x8D, 0xF8, 0x0B, 0x20, 0x8D, 0xF8, 0x29, 0x40,
+ 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x19, 0x46,
+ 0x03, 0xA8, 0x29, 0xF4, 0xE4, 0xF2, 0x01, 0x21, 0x68, 0x46, 0x04, 0xF0,
+ 0xED, 0xF9, 0x10, 0xB0, 0x70, 0xBD, 0x00, 0x00, 0x8A, 0xAD, 0x82, 0x00,
+ 0x10, 0xB5, 0x90, 0xB0, 0x18, 0x24, 0xAD, 0xF8, 0x00, 0x40, 0x00, 0xB9,
+ 0x08, 0x48, 0x8D, 0xF8, 0x0A, 0x10, 0x8D, 0xF8, 0x0C, 0x30, 0x8D, 0xF8,
+ 0x0B, 0x20, 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00,
+ 0x01, 0x21, 0x68, 0x46, 0x04, 0xF0, 0xD2, 0xF9, 0x10, 0xB0, 0x10, 0xBD,
+ 0x8A, 0xAD, 0x82, 0x00, 0x70, 0xB5, 0x8C, 0xB0, 0x17, 0x26, 0xDD, 0xE9,
+ 0x10, 0x54, 0xAD, 0xF8, 0x02, 0x60, 0x06, 0x68, 0x01, 0x96, 0x80, 0x88,
+ 0xAD, 0xF8, 0x08, 0x00, 0x8D, 0xF8, 0x0A, 0x10, 0x8D, 0xF8, 0x0B, 0x20,
+ 0x0D, 0xF1, 0x0D, 0x00, 0x1B, 0xB1, 0x19, 0x46, 0x29, 0xF4, 0xAB, 0xF2,
+ 0x02, 0xE0, 0x11, 0x46, 0x29, 0xF4, 0x26, 0xF3, 0x8D, 0xF8, 0x0C, 0x50,
+ 0xAD, 0xF8, 0x2A, 0x40, 0x01, 0x21, 0x68, 0x46, 0x04, 0xF0, 0x04, 0xFA,
+ 0x0C, 0xB0, 0x70, 0xBD, 0x1C, 0x2A, 0x01, 0xD2, 0x00, 0x20, 0x70, 0x47,
+ 0x11, 0x44, 0x89, 0xB2, 0xC0, 0xB2, 0x4F, 0xF4, 0xB9, 0x73, 0x01, 0x4A,
+ 0xFE, 0xF7, 0x12, 0xBF, 0xB8, 0xAD, 0x82, 0x00, 0x40, 0xF2, 0x95, 0x12,
+ 0x01, 0x49, 0xFE, 0xF7, 0xF9, 0xBF, 0x00, 0x00, 0xC8, 0xAD, 0x82, 0x00,
+ 0x01, 0x00, 0x4F, 0xF0, 0x00, 0x00, 0x40, 0xF2, 0x05, 0x22, 0x06, 0xD0,
+ 0x09, 0x7D, 0x0B, 0x29, 0x04, 0xD0, 0x0C, 0x29, 0x03, 0xD0, 0x0D, 0x29,
+ 0x01, 0xD0, 0x10, 0x46, 0x70, 0x47, 0x4F, 0xF4, 0x3D, 0x70, 0x70, 0x47,
+ 0x10, 0xB5, 0x00, 0xF0, 0xE1, 0xF8, 0x20, 0xB1, 0x01, 0x7D, 0x0B, 0x29,
+ 0x03, 0xD0, 0x03, 0x29, 0x01, 0xD0, 0x00, 0x20, 0x10, 0xBD, 0x00, 0x8A,
+ 0x10, 0xBD, 0x00, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x00, 0xF0, 0xD2, 0xF8,
+ 0x10, 0xB1, 0x01, 0x7D, 0x0B, 0x29, 0x07, 0xD0, 0x23, 0x46, 0x01, 0x22,
+ 0x03, 0x49, 0x04, 0x48, 0xF7, 0xF7, 0x45, 0xD9, 0x00, 0x20, 0x10, 0xBD,
+ 0x00, 0x8A, 0x10, 0xBD, 0x44, 0x58, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21,
+ 0xFF, 0xF7, 0x76, 0xBA, 0x01, 0x28, 0x03, 0xD0, 0x03, 0x28, 0x01, 0xD0,
+ 0x00, 0x20, 0x70, 0x47, 0x01, 0x20, 0x70, 0x47, 0x00, 0xB5, 0x8D, 0xB0,
+ 0x2C, 0x22, 0xAD, 0xF8, 0x00, 0x00, 0x01, 0xA8, 0x29, 0xF4, 0x84, 0xF2,
+ 0x68, 0x46, 0x15, 0xF0, 0xD7, 0xFA, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5,
+ 0x8D, 0xB0, 0x2C, 0x22, 0xAD, 0xF8, 0x00, 0x00, 0x01, 0xA8, 0x29, 0xF4,
+ 0x77, 0xF2, 0x9D, 0xF8, 0x0B, 0x00, 0x01, 0x28, 0x06, 0xD0, 0x07, 0x28,
+ 0x02, 0xD3, 0x68, 0x46, 0x15, 0xF0, 0x20, 0xFC, 0x0D, 0xB0, 0x00, 0xBD,
+ 0x00, 0x22, 0x69, 0x46, 0x04, 0x20, 0x08, 0xF0, 0x6D, 0xF9, 0xF7, 0xE7,
+ 0x2D, 0xE9, 0xF0, 0x41, 0x15, 0x46, 0x0E, 0x46, 0x00, 0xF0, 0x8A, 0xF8,
+ 0x07, 0x46, 0xD6, 0xB1, 0xCF, 0xB1, 0x1C, 0x48, 0x40, 0xF2, 0xFF, 0x23,
+ 0x19, 0x4A, 0x08, 0x21, 0x00, 0x78, 0xFE, 0xF7, 0x91, 0xFE, 0x04, 0x1E,
+ 0x10, 0xD0, 0xC5, 0xB1, 0x17, 0x48, 0x40, 0xF2, 0x07, 0x33, 0x14, 0x4A,
+ 0x30, 0x21, 0x00, 0x78, 0xFE, 0xF7, 0x86, 0xFE, 0x05, 0x00, 0x07, 0xD0,
+ 0x30, 0x22, 0x31, 0x46, 0x29, 0xF4, 0xFF, 0xF1, 0x0A, 0xE0, 0x00, 0x20,
+ 0xBD, 0xE8, 0xF0, 0x81, 0x73, 0x88, 0x01, 0x22, 0x0E, 0x49, 0x0F, 0x48,
+ 0xF7, 0xF7, 0xE1, 0xD8, 0xF5, 0xE7, 0x35, 0x46, 0x0B, 0x49, 0x0C, 0x48,
+ 0x73, 0x88, 0x01, 0x22, 0x2C, 0x31, 0x80, 0x1C, 0xF7, 0xF7, 0xD7, 0xD8,
+ 0x00, 0x20, 0xC4, 0xE9, 0x00, 0x05, 0x21, 0x46, 0x38, 0x1D, 0x02, 0xF4,
+ 0x2E, 0xF0, 0x01, 0x20, 0xE4, 0xE7, 0x00, 0x00, 0xE2, 0xAE, 0x82, 0x00,
+ 0x00, 0x74, 0x20, 0x00, 0x02, 0x74, 0x20, 0x00, 0x94, 0x53, 0xC0, 0x08,
+ 0x00, 0x37, 0x10, 0x21, 0x00, 0xB5, 0x10, 0x48, 0x85, 0xB0, 0x21, 0x23,
+ 0x0D, 0x4A, 0x69, 0x46, 0x00, 0x78, 0xFF, 0xF7, 0x03, 0xF9, 0x00, 0x28,
+ 0x0D, 0xD0, 0xBD, 0xF8, 0x00, 0x00, 0xB0, 0xF5, 0x80, 0x7F, 0x0A, 0xD0,
+ 0xB0, 0xF5, 0xC0, 0x6F, 0x05, 0xD1, 0xBD, 0xF8, 0x06, 0x10, 0x9D, 0xF8,
+ 0x05, 0x00, 0x02, 0xF0, 0x23, 0xFB, 0x05, 0xB0, 0x00, 0xBD, 0x03, 0x98,
+ 0x01, 0xF0, 0x18, 0xF9, 0xF9, 0xE7, 0x00, 0x00, 0x8D, 0xAE, 0x82, 0x00,
+ 0xCC, 0x77, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x80, 0x46, 0x00, 0x24,
+ 0x0C, 0x4E, 0x0D, 0x4F, 0x0D, 0xE0, 0xF0, 0x68, 0x00, 0xEB, 0x44, 0x15,
+ 0x28, 0x7D, 0x30, 0xB1, 0x06, 0x22, 0x41, 0x46, 0x05, 0xF1, 0x16, 0x00,
+ 0x29, 0xF4, 0x56, 0xF1, 0x40, 0xB1, 0x64, 0x1C, 0xA4, 0xB2, 0x97, 0xF8,
+ 0x98, 0x01, 0xA0, 0x42, 0xED, 0xD8, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81,
+ 0x28, 0x46, 0xFB, 0xE7, 0xD0, 0x77, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x70, 0xB5, 0x0E, 0x49, 0x03, 0x46, 0x00, 0x20, 0xCA, 0x68, 0x0D, 0x49,
+ 0x91, 0xF8, 0x98, 0x41, 0x0A, 0xE0, 0x02, 0xEB, 0x40, 0x11, 0x0D, 0x7D,
+ 0x25, 0xB1, 0x0D, 0x8A, 0x9D, 0x42, 0x01, 0xD1, 0x08, 0x46, 0x70, 0xBD,
+ 0x40, 0x1C, 0x80, 0xB2, 0x84, 0x42, 0xF2, 0xD8, 0x01, 0x22, 0x05, 0x49,
+ 0x05, 0x48, 0xF7, 0xF7, 0x62, 0xD8, 0x00, 0x20, 0x70, 0xBD, 0x00, 0x00,
+ 0xD0, 0x77, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0x58, 0x57, 0xC0, 0x08,
+ 0x01, 0x37, 0x10, 0x21, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x21, 0x11,
+ 0xAD, 0xF8, 0x00, 0x10, 0xAD, 0xF8, 0x04, 0x00, 0x01, 0x21, 0x68, 0x46,
+ 0x04, 0xF0, 0x6C, 0xF8, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0,
+ 0x40, 0xF2, 0x0F, 0x13, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10,
+ 0xAD, 0xF8, 0x00, 0x30, 0xAD, 0xF8, 0x08, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0x04, 0xF0, 0x5A, 0xF8, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0,
+ 0x4F, 0xF4, 0x8F, 0x72, 0xAD, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10,
+ 0xAD, 0xF8, 0x00, 0x20, 0x01, 0x21, 0x68, 0x46, 0x04, 0xF0, 0x4A, 0xF8,
+ 0x11, 0xB0, 0x00, 0xBD, 0x2D, 0xE9, 0xF0, 0x47, 0x05, 0x46, 0xDD, 0xE9,
+ 0x08, 0xA7, 0x04, 0x1D, 0x98, 0x46, 0x91, 0x46, 0x0E, 0x46, 0x38, 0x46,
+ 0xFF, 0xF7, 0xC8, 0xFE, 0xB9, 0xF1, 0x00, 0x0F, 0x02, 0xD0, 0x4F, 0xF4,
+ 0x91, 0x71, 0x01, 0xE0, 0x4F, 0xF4, 0x90, 0x71, 0x69, 0x80, 0x27, 0x80,
+ 0xA4, 0xF8, 0x02, 0x80, 0xA4, 0xF8, 0x04, 0xA0, 0x0C, 0x3E, 0xE6, 0x80,
+ 0x20, 0xB1, 0x00, 0x21, 0x28, 0x46, 0x04, 0xF0, 0x7F, 0xF8, 0x04, 0xE0,
+ 0x00, 0x22, 0x29, 0x46, 0x38, 0x46, 0xFF, 0xF7, 0xF3, 0xFE, 0x00, 0x20,
+ 0xBD, 0xE8, 0xF0, 0x87, 0x2D, 0xE9, 0xF8, 0x43, 0x1D, 0x46, 0xDD, 0xE9,
+ 0x09, 0x43, 0xDD, 0xF8, 0x20, 0x80, 0x16, 0x46, 0x0F, 0x46, 0x5C, 0xB1,
+ 0x08, 0xB1, 0x12, 0x2B, 0x16, 0xD2, 0x02, 0x22, 0x12, 0x49, 0x13, 0x48,
+ 0x00, 0x94, 0xF6, 0xF7, 0xEA, 0xDF, 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x83,
+ 0x08, 0xB1, 0xFF, 0xF7, 0x69, 0xFE, 0x10, 0x48, 0x40, 0xF2, 0x2D, 0x43,
+ 0x0D, 0x4A, 0x40, 0x21, 0x00, 0x78, 0xFE, 0xF7, 0x71, 0xFD, 0x00, 0x28,
+ 0xF0, 0xD0, 0x00, 0x23, 0x40, 0xF2, 0x0D, 0x11, 0x01, 0x80, 0x07, 0x81,
+ 0x46, 0x60, 0x45, 0x81, 0xA0, 0xF8, 0x0C, 0x80, 0xC4, 0x81, 0x03, 0x82,
+ 0xBD, 0xE8, 0xF8, 0x43, 0x00, 0x21, 0x03, 0xF0, 0xEB, 0xBF, 0x00, 0x00,
+ 0xB0, 0x50, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, 0x39, 0xAE, 0x82, 0x00,
+ 0x02, 0x74, 0x20, 0x00, 0xF8, 0xB5, 0xDD, 0xE9, 0x06, 0x54, 0x38, 0xB1,
+ 0x10, 0x2C, 0x05, 0xD3, 0x0E, 0x4E, 0xB6, 0xF8, 0xAE, 0x61, 0x76, 0x1F,
+ 0x9E, 0x42, 0x08, 0xDA, 0x00, 0x93, 0x23, 0x46, 0x02, 0x22, 0x0B, 0x49,
+ 0x0B, 0x48, 0xF6, 0xF7, 0xAE, 0xDF, 0x00, 0x20, 0xF8, 0xBD, 0x4F, 0xF4,
+ 0x8E, 0x76, 0x06, 0x80, 0x81, 0x80, 0x03, 0x21, 0x81, 0x71, 0x02, 0x81,
+ 0x43, 0x81, 0x85, 0x81, 0xC4, 0x81, 0xBD, 0xE8, 0xF8, 0x40, 0x00, 0x21,
+ 0x03, 0xF0, 0xBE, 0xBF, 0x64, 0x01, 0x20, 0x00, 0xF4, 0x50, 0xC0, 0x08,
+ 0x00, 0x37, 0x10, 0x21, 0xF0, 0xB4, 0x04, 0x46, 0xDD, 0xE9, 0x04, 0x56,
+ 0x40, 0xF2, 0x1D, 0x10, 0x60, 0x80, 0xA6, 0x80, 0xE5, 0x80, 0x23, 0x81,
+ 0x62, 0x81, 0x0E, 0x39, 0xA1, 0x81, 0x20, 0x46, 0xF0, 0xBC, 0x00, 0x21,
+ 0x03, 0xF0, 0xFE, 0xBF, 0x2D, 0xE9, 0xF8, 0x43, 0x1D, 0x46, 0xDD, 0xE9,
+ 0x09, 0x43, 0xDD, 0xF8, 0x20, 0x80, 0x16, 0x46, 0x0F, 0x46, 0x8C, 0xB1,
+ 0x38, 0xB1, 0x12, 0x2B, 0x05, 0xD3, 0x16, 0x49, 0xB1, 0xF8, 0xAE, 0x11,
+ 0x49, 0x1E, 0xA1, 0x42, 0x16, 0xDA, 0x02, 0x22, 0x13, 0x49, 0x14, 0x48,
+ 0x00, 0x94, 0xF6, 0xF7, 0x6C, 0xDF, 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x83,
+ 0x08, 0xB1, 0xFF, 0xF7, 0xEB, 0xFD, 0x11, 0x48, 0x40, 0xF2, 0xF1, 0x33,
+ 0x0E, 0x4A, 0x40, 0x21, 0x00, 0x78, 0xFE, 0xF7, 0xF3, 0xFC, 0x00, 0x28,
+ 0xF0, 0xD0, 0x00, 0x23, 0x40, 0xF2, 0x09, 0x11, 0x01, 0x80, 0x07, 0x81,
+ 0x46, 0x60, 0x45, 0x81, 0xA0, 0xF8, 0x0C, 0x80, 0xC4, 0x81, 0x03, 0x82,
+ 0xBD, 0xE8, 0xF8, 0x43, 0x00, 0x21, 0x03, 0xF0, 0x6D, 0xBF, 0x00, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x74, 0x50, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21,
+ 0x21, 0xAE, 0x82, 0x00, 0x02, 0x74, 0x20, 0x00, 0xF0, 0xB5, 0x07, 0x46,
+ 0x8D, 0xB0, 0x15, 0x46, 0x0E, 0x46, 0x1C, 0x46, 0x18, 0x46, 0xFF, 0xF7,
+ 0xE5, 0xFD, 0x4F, 0xF4, 0x84, 0x71, 0xAD, 0xF8, 0x0C, 0x60, 0xAD, 0xF8,
+ 0x02, 0x10, 0xAD, 0xF8, 0x04, 0x40, 0x02, 0x97, 0xAD, 0xF8, 0x0E, 0x50,
+ 0x28, 0xB1, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0xA1, 0xFF, 0x0D, 0xB0,
+ 0xF0, 0xBD, 0x01, 0x22, 0x69, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0x14, 0xFE,
+ 0xF7, 0xE7, 0x00, 0x00, 0xF0, 0xB5, 0x91, 0xB0, 0x0C, 0x46, 0xDD, 0xE9,
+ 0x17, 0x51, 0x4F, 0xF4, 0x8B, 0x77, 0x16, 0x9E, 0xAD, 0xF8, 0x00, 0x70,
+ 0x01, 0xB9, 0x0B, 0x49, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x08, 0x20,
+ 0xAD, 0xF8, 0x0C, 0x60, 0x8D, 0xF8, 0x06, 0x40, 0xAD, 0xF8, 0x0A, 0x30,
+ 0xAD, 0xF8, 0x0E, 0x50, 0x10, 0x22, 0x04, 0xA8, 0x29, 0xF4, 0x17, 0xF0,
+ 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0x20, 0xFF, 0x11, 0xB0, 0xF0, 0xBD,
+ 0x8A, 0xAD, 0x82, 0x00, 0x2D, 0xE9, 0xF0, 0x5F, 0x99, 0x46, 0xDD, 0xE9,
+ 0x0E, 0xA6, 0xDD, 0xE9, 0x0C, 0x8B, 0x17, 0x46, 0x0D, 0x46, 0x04, 0x00,
+ 0x01, 0xD0, 0x02, 0x46, 0x09, 0xE0, 0x1F, 0x48, 0x40, 0xF2, 0xE9, 0x43,
+ 0x1C, 0x4A, 0x30, 0x21, 0x00, 0x78, 0xFE, 0xF7, 0x7B, 0xFC, 0x02, 0x00,
+ 0x0B, 0xD0, 0x40, 0xF2, 0x17, 0x10, 0x50, 0x80, 0xA2, 0xF8, 0x04, 0xA0,
+ 0x97, 0x71, 0x10, 0x1D, 0xA2, 0xF8, 0x08, 0xB0, 0x24, 0xB1, 0x14, 0x2D,
+ 0x15, 0xD2, 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x9F, 0x00, 0x21, 0xC1, 0x80,
+ 0x01, 0x81, 0x41, 0x81, 0x81, 0x81, 0xC1, 0x81, 0x01, 0x2F, 0x14, 0xD1,
+ 0xB8, 0xF1, 0x01, 0x0F, 0x11, 0xD1, 0x02, 0x21, 0x01, 0x81, 0x01, 0x21,
+ 0x81, 0x81, 0x06, 0x74, 0x31, 0x0A, 0x41, 0x74, 0x09, 0xE0, 0xA0, 0xF8,
+ 0x06, 0x90, 0x0A, 0x99, 0x01, 0x81, 0x0B, 0x99, 0x41, 0x81, 0xA0, 0xF8,
+ 0x0C, 0x80, 0x14, 0x3D, 0xC5, 0x81, 0x00, 0x21, 0x10, 0x46, 0x03, 0xF0,
+ 0x2D, 0xFF, 0x00, 0x20, 0xDA, 0xE7, 0x00, 0x00, 0x0E, 0xAF, 0x82, 0x00,
+ 0x02, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x8C, 0xB0, 0x80, 0x46,
+ 0xDD, 0xE9, 0x15, 0x94, 0x1D, 0x46, 0x17, 0x46, 0x0E, 0x46, 0x20, 0x46,
+ 0xDD, 0xF8, 0x50, 0xA0, 0xFF, 0xF7, 0x4C, 0xFD, 0x4F, 0xF4, 0x83, 0x71,
+ 0xAD, 0xF8, 0x02, 0x10, 0xCD, 0xE9, 0x01, 0x67, 0xAD, 0xF8, 0x0C, 0x40,
+ 0xAD, 0xF8, 0x0E, 0x80, 0xAD, 0xF8, 0x10, 0x90, 0x8D, 0xF8, 0x18, 0x50,
+ 0xDA, 0xF8, 0x00, 0x20, 0xCD, 0xF8, 0x12, 0x20, 0xBA, 0xF8, 0x04, 0x10,
+ 0xAD, 0xF8, 0x16, 0x10, 0x30, 0xB1, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0,
+ 0xFD, 0xFE, 0x0C, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x01, 0x22, 0x69, 0x46,
+ 0x20, 0x46, 0xFF, 0xF7, 0x6F, 0xFD, 0xF6, 0xE7, 0x2D, 0xE9, 0xF8, 0x43,
+ 0x1D, 0x46, 0xDD, 0xE9, 0x09, 0x43, 0xDD, 0xF8, 0x2C, 0x90, 0xDD, 0xF8,
+ 0x20, 0x80, 0x16, 0x46, 0x0F, 0x46, 0x8C, 0xB1, 0x38, 0xB1, 0x16, 0x2B,
+ 0x05, 0xD3, 0x17, 0x49, 0xB1, 0xF8, 0xAE, 0x11, 0xC9, 0x1E, 0xA1, 0x42,
+ 0x16, 0xDA, 0x02, 0x22, 0x14, 0x49, 0x15, 0x48, 0x00, 0x94, 0xF6, 0xF7,
+ 0x60, 0xDE, 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x83, 0x08, 0xB1, 0xFF, 0xF7,
+ 0xDF, 0xFC, 0x12, 0x48, 0x40, 0xF2, 0xA6, 0x33, 0x0F, 0x4A, 0x40, 0x21,
+ 0x00, 0x78, 0xFE, 0xF7, 0xE7, 0xFB, 0x00, 0x28, 0xF0, 0xD0, 0x00, 0x23,
+ 0x4F, 0xF4, 0x82, 0x71, 0x01, 0x80, 0x85, 0x60, 0xA0, 0xF8, 0x10, 0x80,
+ 0xC7, 0x81, 0x46, 0x60, 0x44, 0x82, 0x80, 0xF8, 0x0C, 0x90, 0x83, 0x82,
+ 0xBD, 0xE8, 0xF8, 0x43, 0x00, 0x21, 0x03, 0xF0, 0x5F, 0xBE, 0x00, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x34, 0x50, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21,
+ 0x07, 0xAE, 0x82, 0x00, 0x02, 0x74, 0x20, 0x00, 0x30, 0xB5, 0x8D, 0xB0,
+ 0x40, 0xF2, 0x05, 0x15, 0x10, 0x9C, 0xAD, 0xF8, 0x0C, 0x00, 0x01, 0x91,
+ 0xAD, 0xF8, 0x02, 0x50, 0xAD, 0xF8, 0x10, 0x40, 0xAD, 0xF8, 0x0E, 0x30,
+ 0x01, 0x21, 0x68, 0x46, 0x02, 0x92, 0x03, 0xF0, 0x99, 0xFE, 0x0D, 0xB0,
+ 0x30, 0xBD, 0x10, 0xB5, 0x90, 0xB0, 0x40, 0xF2, 0x07, 0x14, 0xAD, 0xF8,
+ 0x00, 0x40, 0xCD, 0xE9, 0x01, 0x12, 0xAD, 0xF8, 0x0E, 0x30, 0xAD, 0xF8,
+ 0x0C, 0x00, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0x2F, 0xFE, 0x10, 0xB0,
+ 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x5F, 0x05, 0x46, 0xDD, 0xE9, 0x0A, 0xAB,
+ 0xDD, 0xF8, 0x34, 0x80, 0x04, 0x1D, 0x1F, 0x46, 0x91, 0x46, 0x0E, 0x46,
+ 0x40, 0x46, 0xFF, 0xF7, 0xAB, 0xFC, 0x01, 0x46, 0x16, 0x2E, 0x02, 0xD2,
+ 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x9F, 0x48, 0x46, 0xB9, 0xF1, 0x01, 0x0F,
+ 0x1E, 0xD0, 0x02, 0x28, 0x05, 0xD0, 0x03, 0x28, 0x1D, 0xD0, 0xB9, 0xF1,
+ 0x05, 0x0F, 0x06, 0xD1, 0x02, 0xE0, 0x4F, 0xF4, 0x88, 0x70, 0x01, 0xE0,
+ 0x40, 0xF2, 0xB7, 0x10, 0x68, 0x80, 0xA4, 0xF8, 0x00, 0x80, 0x67, 0x60,
+ 0xA4, 0xF8, 0x08, 0xA0, 0xA4, 0xF8, 0x0A, 0xB0, 0x0C, 0x98, 0xE0, 0x81,
+ 0x16, 0x3E, 0x26, 0x82, 0x51, 0xB1, 0x00, 0x21, 0x28, 0x46, 0x03, 0xF0,
+ 0x4F, 0xFE, 0x0A, 0xE0, 0x4F, 0xF4, 0x85, 0x70, 0xEA, 0xE7, 0x4F, 0xF4,
+ 0x86, 0x70, 0xE7, 0xE7, 0x00, 0x22, 0x29, 0x46, 0x40, 0x46, 0xFF, 0xF7,
+ 0xBD, 0xFC, 0x00, 0x20, 0xCD, 0xE7, 0x00, 0x00, 0xF8, 0xB5, 0x1D, 0x46,
+ 0xDD, 0xE9, 0x06, 0x43, 0x38, 0xB1, 0x10, 0x2B, 0x05, 0xD3, 0x0E, 0x4E,
+ 0xB6, 0xF8, 0xAE, 0x61, 0xF6, 0x1E, 0xA6, 0x42, 0x07, 0xDA, 0x02, 0x22,
+ 0x0B, 0x49, 0x0C, 0x48, 0x00, 0x94, 0xF6, 0xF7, 0xB4, 0xDD, 0x00, 0x20,
+ 0xF8, 0xBD, 0x4F, 0xF4, 0x8D, 0x76, 0x06, 0x80, 0x81, 0x80, 0x82, 0x71,
+ 0x05, 0x81, 0x44, 0x81, 0x00, 0x21, 0x81, 0x81, 0xC3, 0x81, 0xBD, 0xE8,
+ 0xF8, 0x40, 0x03, 0xF0, 0xC5, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x38, 0x51, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, 0x10, 0xB5, 0x90, 0xB0,
+ 0x40, 0xF2, 0x0B, 0x14, 0xAD, 0xF8, 0x04, 0x00, 0x02, 0x91, 0xAD, 0xF8,
+ 0x0C, 0x20, 0xAD, 0xF8, 0x00, 0x40, 0xAD, 0xF8, 0x0E, 0x30, 0x01, 0x21,
+ 0x68, 0x46, 0x03, 0xF0, 0xAD, 0xFD, 0x10, 0xB0, 0x10, 0xBD, 0x10, 0xB5,
+ 0x8C, 0xB0, 0x40, 0xF2, 0x1B, 0x14, 0xAD, 0xF8, 0x02, 0x40, 0xAD, 0xF8,
+ 0x04, 0x00, 0x00, 0x24, 0xAD, 0xF8, 0x0C, 0x40, 0x8D, 0xF8, 0x06, 0x10,
+ 0xAD, 0xF8, 0x08, 0x20, 0xAD, 0xF8, 0x0E, 0x40, 0xAD, 0xF8, 0x0A, 0x30,
+ 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0xEC, 0xFD, 0x0C, 0xB0, 0x10, 0xBD,
+ 0x2D, 0xE9, 0xF0, 0x47, 0x05, 0x46, 0xDD, 0xF8, 0x20, 0x90, 0x04, 0x1D,
+ 0x98, 0x46, 0x17, 0x46, 0x0E, 0x46, 0x48, 0x46, 0xFF, 0xF7, 0x12, 0xFC,
+ 0x40, 0xF2, 0x11, 0x11, 0x69, 0x80, 0xA4, 0xF8, 0x00, 0x90, 0x67, 0x60,
+ 0xA4, 0xF8, 0x08, 0x80, 0x10, 0x3E, 0x66, 0x81, 0x20, 0xB1, 0x00, 0x21,
+ 0x28, 0x46, 0x03, 0xF0, 0xCF, 0xFD, 0x04, 0xE0, 0x00, 0x22, 0x29, 0x46,
+ 0x48, 0x46, 0xFF, 0xF7, 0x43, 0xFC, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87,
+ 0x2D, 0xE9, 0xF0, 0x43, 0x87, 0xB0, 0x1D, 0x46, 0x91, 0x46, 0x0F, 0x46,
+ 0x80, 0x46, 0xFF, 0xF7, 0xA5, 0xFC, 0x04, 0x00, 0x4F, 0xF0, 0x00, 0x06,
+ 0x06, 0xD1, 0x00, 0x96, 0x68, 0x46, 0x01, 0x96, 0xFF, 0xF7, 0x9C, 0xFC,
+ 0x04, 0x00, 0x2B, 0xD0, 0x41, 0x46, 0x39, 0x48, 0xF6, 0xF7, 0x04, 0xDF,
+ 0x03, 0x46, 0x20, 0x7D, 0x00, 0x97, 0xCD, 0xE9, 0x01, 0x40, 0x04, 0x22,
+ 0x35, 0x49, 0x36, 0x48, 0xF6, 0xF7, 0x2B, 0xDD, 0x27, 0x82, 0xD5, 0xF8,
+ 0x01, 0x00, 0xC4, 0xF8, 0x16, 0x00, 0xB5, 0xF8, 0x05, 0x00, 0x60, 0x83,
+ 0xE8, 0x79, 0x60, 0x75, 0x20, 0x46, 0xFF, 0xF7, 0xC7, 0xFA, 0x23, 0x7D,
+ 0x03, 0x2B, 0x14, 0xD0, 0x08, 0x2B, 0x12, 0xD0, 0x09, 0x2B, 0x2B, 0xD0,
+ 0x07, 0xB0, 0x29, 0x49, 0xBD, 0xE8, 0xF0, 0x43, 0x28, 0x48, 0x01, 0x22,
+ 0x48, 0x31, 0x80, 0x1E, 0xF6, 0xF7, 0x0D, 0x9D, 0x07, 0xB0, 0x40, 0x46,
+ 0xBD, 0xE8, 0xF0, 0x43, 0x13, 0x21, 0x07, 0xF0, 0xE7, 0xBD, 0xE8, 0x89,
+ 0xA9, 0x89, 0x6A, 0x89, 0x05, 0x96, 0x02, 0x92, 0xCD, 0xE9, 0x03, 0x10,
+ 0x29, 0x78, 0x28, 0x7A, 0xCD, 0xE9, 0x00, 0x01, 0x62, 0x7D, 0x4B, 0x46,
+ 0x04, 0xF1, 0x16, 0x01, 0x20, 0x46, 0x02, 0xF0, 0xA3, 0xFA, 0x0B, 0x20,
+ 0x20, 0x75, 0x20, 0x8A, 0x07, 0xB0, 0x01, 0x21, 0xBD, 0xE8, 0xF0, 0x43,
+ 0x03, 0xF0, 0x14, 0xBC, 0xE9, 0x89, 0xA8, 0x89, 0x6A, 0x89, 0x03, 0xAB,
+ 0x02, 0x92, 0x83, 0xE8, 0x43, 0x00, 0x29, 0x78, 0x28, 0x7A, 0xCD, 0xE9,
+ 0x00, 0x01, 0x62, 0x7D, 0x4B, 0x46, 0x04, 0xF1, 0x16, 0x01, 0x20, 0x46,
+ 0x02, 0xF0, 0x88, 0xFA, 0x20, 0x8A, 0x01, 0x21, 0x03, 0xF0, 0xFE, 0xFB,
+ 0x61, 0x8A, 0x20, 0x8A, 0x02, 0xF0, 0x4C, 0xFD, 0x00, 0x22, 0x20, 0x8A,
+ 0x11, 0x46, 0x06, 0xF0, 0x25, 0xFF, 0x07, 0xB0, 0x20, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x43, 0x03, 0xF0, 0x91, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21,
+ 0xF0, 0x58, 0xC0, 0x08, 0x02, 0x37, 0x10, 0x21, 0xF8, 0xB5, 0x0E, 0x46,
+ 0x05, 0x46, 0x01, 0x46, 0x14, 0x46, 0x14, 0x48, 0xF6, 0xF7, 0x86, 0xDE,
+ 0x00, 0x90, 0x33, 0x46, 0x02, 0x22, 0x12, 0x49, 0x12, 0x48, 0xF6, 0xF7,
+ 0xB0, 0xDC, 0x28, 0x46, 0xFF, 0xF7, 0x0E, 0xFC, 0x38, 0xB1, 0x0E, 0x49,
+ 0x0E, 0x48, 0x00, 0x22, 0x30, 0x31, 0x80, 0x1E, 0xF6, 0xF7, 0xA5, 0xDC,
+ 0x0B, 0xE0, 0x31, 0x46, 0x28, 0x46, 0xFF, 0xF7, 0x83, 0xFA, 0x30, 0xB1,
+ 0x02, 0x21, 0x01, 0x75, 0x04, 0x82, 0xBD, 0xE8, 0xF8, 0x40, 0x02, 0xF0,
+ 0x8B, 0xBA, 0x28, 0x46, 0xBD, 0xE8, 0xF8, 0x40, 0x00, 0x21, 0x07, 0xF0,
+ 0x72, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0x6C, 0x59, 0xC0, 0x08,
+ 0x03, 0x37, 0x10, 0x21, 0x7C, 0xB5, 0x0D, 0x46, 0x06, 0x46, 0xFF, 0xF7,
+ 0xE7, 0xFB, 0x04, 0x00, 0x05, 0xD1, 0x00, 0x90, 0x01, 0x90, 0x68, 0x46,
+ 0xFF, 0xF7, 0xE0, 0xFB, 0x04, 0x46, 0x31, 0x46, 0x14, 0x48, 0xF6, 0xF7,
+ 0x49, 0xDE, 0x15, 0x4E, 0xCD, 0xE9, 0x00, 0x54, 0x03, 0x46, 0x03, 0x22,
+ 0x11, 0x49, 0x30, 0x46, 0xF6, 0xF7, 0x71, 0xDC, 0x00, 0x2C, 0x1A, 0xD0,
+ 0x0E, 0x49, 0x23, 0x7D, 0x01, 0x22, 0x3C, 0x31, 0x30, 0x46, 0xF6, 0xF7,
+ 0x68, 0xDC, 0x15, 0xB1, 0x20, 0x46, 0xFF, 0xF7, 0x0D, 0xFA, 0x07, 0x20,
+ 0x20, 0x75, 0x22, 0x8A, 0x61, 0x7D, 0x2B, 0x46, 0x04, 0xF1, 0x16, 0x00,
+ 0x02, 0xF0, 0xAE, 0xFA, 0x00, 0x2D, 0x04, 0xD0, 0x20, 0x46, 0xBD, 0xE8,
+ 0x7C, 0x40, 0x03, 0xF0, 0x1F, 0xBC, 0x7C, 0xBD, 0x00, 0x00, 0x30, 0x21,
+ 0x88, 0x58, 0xC0, 0x08, 0x02, 0x37, 0x10, 0x21, 0x70, 0xB5, 0x05, 0x46,
+ 0x86, 0xB0, 0x0E, 0x46, 0x08, 0x46, 0xFF, 0xF7, 0xA7, 0xFB, 0x04, 0x46,
+ 0x31, 0x46, 0x30, 0x48, 0xF6, 0xF7, 0x10, 0xDE, 0x30, 0x4E, 0xCD, 0xE9,
+ 0x00, 0x54, 0x03, 0x46, 0x03, 0x22, 0x2D, 0x49, 0x30, 0x46, 0xF6, 0xF7,
+ 0x38, 0xDC, 0x00, 0x2C, 0x32, 0xD0, 0x2A, 0x49, 0x23, 0x7D, 0x01, 0x22,
+ 0x3C, 0x31, 0x30, 0x46, 0xF6, 0xF7, 0x2F, 0xDC, 0x23, 0x7D, 0x98, 0x1E,
+ 0x0B, 0x28, 0x34, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x06, 0x06, 0x33, 0x33,
+ 0x33, 0x14, 0x24, 0x33, 0x28, 0x0B, 0x2E, 0x00, 0x20, 0x8A, 0x00, 0x21,
+ 0x03, 0xF0, 0x48, 0xFB, 0x2E, 0xE0, 0x20, 0x8A, 0x01, 0x21, 0x03, 0xF0,
+ 0x43, 0xFB, 0x20, 0x8A, 0x29, 0x46, 0x02, 0xF0, 0x91, 0xFC, 0x25, 0xE0,
+ 0x00, 0x20, 0x0E, 0x21, 0xCD, 0xE9, 0x04, 0x01, 0x02, 0x90, 0x03, 0x90,
+ 0x00, 0x90, 0x01, 0x90, 0x03, 0x46, 0x62, 0x7D, 0x04, 0xF1, 0x16, 0x01,
+ 0x20, 0x46, 0x02, 0xF0, 0xB5, 0xF9, 0x15, 0xE0, 0x09, 0x20, 0x20, 0x75,
+ 0x06, 0xB0, 0x70, 0xBD, 0x20, 0x8A, 0x2A, 0x46, 0x00, 0x21, 0x02, 0xF0,
+ 0x97, 0xFC, 0x0B, 0xE0, 0x20, 0x8A, 0x00, 0x21, 0x03, 0xF0, 0x20, 0xFB,
+ 0xF4, 0xE7, 0x0A, 0x49, 0x0A, 0x48, 0x01, 0x22, 0x68, 0x31, 0x80, 0x1E,
+ 0xF6, 0xF7, 0xEF, 0xDB, 0x00, 0x22, 0x20, 0x8A, 0x11, 0x46, 0x06, 0xF0,
+ 0x43, 0xFE, 0x06, 0xB0, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x03, 0xF0,
+ 0xAF, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0xC8, 0x59, 0xC0, 0x08,
+ 0x02, 0x37, 0x10, 0x21, 0x10, 0xB5, 0x90, 0xB0, 0x40, 0xF2, 0x15, 0x14,
+ 0xAD, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x08, 0x20,
+ 0xAD, 0xF8, 0x00, 0x40, 0xAD, 0xF8, 0x0A, 0x30, 0x01, 0x21, 0x68, 0x46,
+ 0x03, 0xF0, 0xEC, 0xFB, 0x10, 0xB0, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x47,
+ 0x05, 0x46, 0xDD, 0xE9, 0x09, 0x90, 0x1E, 0x46, 0x17, 0x46, 0x88, 0x46,
+ 0x2C, 0x1D, 0xDD, 0xF8, 0x20, 0xA0, 0xFF, 0xF7, 0x69, 0xFA, 0x01, 0x00,
+ 0x06, 0xD0, 0x06, 0x2F, 0x04, 0xD2, 0xDF, 0xE8, 0x07, 0xF0, 0x03, 0x06,
+ 0x08, 0x0A, 0x0C, 0x0E, 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0x01, 0x20,
+ 0x06, 0xE0, 0x02, 0x20, 0x04, 0xE0, 0x03, 0x20, 0x02, 0xE0, 0x04, 0x20,
+ 0x00, 0xE0, 0x05, 0x20, 0x4F, 0xF4, 0x8A, 0x72, 0x6A, 0x80, 0x21, 0x80,
+ 0xA0, 0x70, 0xA4, 0xF8, 0x04, 0x90, 0xE6, 0x80, 0xA4, 0xF8, 0x08, 0xA0,
+ 0xA8, 0xF1, 0x10, 0x00, 0x60, 0x81, 0x00, 0x21, 0x28, 0x46, 0x03, 0xF0,
+ 0x0F, 0xFC, 0x00, 0x20, 0xE1, 0xE7, 0x00, 0x00, 0x70, 0xB5, 0x90, 0xB0,
+ 0x0C, 0x46, 0xDD, 0xE9, 0x14, 0x51, 0x4F, 0xF4, 0x89, 0x76, 0xAD, 0xF8,
+ 0x00, 0x60, 0x01, 0xB9, 0x0A, 0x49, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8,
+ 0x08, 0x20, 0x8D, 0xF8, 0x06, 0x40, 0xAD, 0xF8, 0x0A, 0x30, 0xAD, 0xF8,
+ 0x0C, 0x50, 0x10, 0x22, 0x0D, 0xF1, 0x0E, 0x00, 0x28, 0xF4, 0x8D, 0xF4,
+ 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0x96, 0xFB, 0x10, 0xB0, 0x70, 0xBD,
+ 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x13, 0x13,
+ 0xAD, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x30,
+ 0xAD, 0xF8, 0x08, 0x20, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0xDA, 0xFB,
+ 0x0D, 0xB0, 0x00, 0xBD, 0x30, 0xB5, 0x8D, 0xB0, 0x0D, 0x46, 0x04, 0x46,
+ 0xFF, 0xF7, 0x06, 0xFA, 0x4F, 0xF4, 0x87, 0x71, 0xAD, 0xF8, 0x04, 0x40,
+ 0xAD, 0xF8, 0x02, 0x10, 0x8D, 0xF8, 0x06, 0x50, 0x28, 0xB1, 0x01, 0x21,
+ 0x68, 0x46, 0x03, 0xF0, 0xC5, 0xFB, 0x0D, 0xB0, 0x30, 0xBD, 0x01, 0x22,
+ 0x69, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0x38, 0xFA, 0xF7, 0xE7, 0x00, 0xB5,
+ 0x8D, 0xB0, 0x40, 0xF2, 0x1F, 0x12, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8,
+ 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0,
+ 0xAF, 0xFB, 0x0D, 0xB0, 0x00, 0xBD, 0x30, 0xB5, 0x8D, 0xB0, 0x0D, 0x46,
+ 0x04, 0x46, 0xFF, 0xF7, 0xDB, 0xF9, 0x40, 0xF2, 0x27, 0x11, 0xAD, 0xF8,
+ 0x04, 0x40, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x06, 0x50, 0x28, 0xB1,
+ 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0x9A, 0xFB, 0x0D, 0xB0, 0x30, 0xBD,
+ 0x01, 0x22, 0x69, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0x0D, 0xFA, 0xF7, 0xE7,
+ 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x23, 0x13, 0xAD, 0xF8, 0x04, 0x00,
+ 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x00, 0x30, 0x8D, 0xF8, 0x08, 0x20,
+ 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0x2A, 0xFB, 0x11, 0xB0, 0x00, 0xBD,
+ 0x10, 0xB5, 0x8C, 0xB0, 0x4F, 0xF4, 0x92, 0x74, 0xAD, 0xF8, 0x04, 0x00,
+ 0x8D, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x40, 0x8D, 0xF8, 0x07, 0x20,
+ 0xAD, 0xF8, 0x08, 0x30, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0x6E, 0xFB,
+ 0x0C, 0xB0, 0x10, 0xBD, 0x70, 0xB5, 0x1C, 0x46, 0x1C, 0x4B, 0x90, 0xB0,
+ 0xDD, 0xE9, 0x14, 0x56, 0x93, 0xF8, 0xC1, 0x31, 0xB4, 0xEB, 0x83, 0x0F,
+ 0x08, 0xD9, 0x23, 0x46, 0x01, 0x22, 0x18, 0x49, 0x18, 0x48, 0xF6, 0xF7,
+ 0xE2, 0xDA, 0x00, 0x20, 0x10, 0xB0, 0x70, 0xBD, 0x4F, 0xF4, 0x93, 0x73,
+ 0xAD, 0xF8, 0x00, 0x30, 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x0B, 0x20,
+ 0x8D, 0xF8, 0x0C, 0x40, 0x08, 0x68, 0xCD, 0xF8, 0x05, 0x00, 0x88, 0x88,
+ 0xAD, 0xF8, 0x09, 0x00, 0x7D, 0xB1, 0x74, 0xB1, 0x0E, 0x48, 0x40, 0xF2,
+ 0x23, 0x33, 0x0C, 0x4A, 0x21, 0x46, 0x00, 0x78, 0xFE, 0xF7, 0x5A, 0xF8,
+ 0x04, 0x90, 0x00, 0x28, 0xE0, 0xD0, 0x22, 0x46, 0x29, 0x46, 0x28, 0xF4,
+ 0xD2, 0xF3, 0x8D, 0xF8, 0x14, 0x60, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0,
+ 0xD9, 0xFA, 0xD5, 0xE7, 0x64, 0x01, 0x20, 0x00, 0x00, 0x50, 0xC0, 0x08,
+ 0x00, 0x37, 0x10, 0x21, 0xEC, 0xAD, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00,
+ 0x30, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x25, 0x15, 0x10, 0x9C, 0x8D, 0xF8,
+ 0x04, 0x00, 0xAD, 0xF8, 0x02, 0x50, 0x8D, 0xF8, 0x05, 0x20, 0x08, 0x68,
+ 0xCD, 0xF8, 0x06, 0x00, 0x88, 0x88, 0xAD, 0xF8, 0x0A, 0x00, 0x8D, 0xF8,
+ 0x0C, 0x30, 0x01, 0x21, 0x68, 0x46, 0x04, 0x94, 0x03, 0xF0, 0x0E, 0xFB,
+ 0x0D, 0xB0, 0x30, 0xBD, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0xBD, 0x13,
+ 0xAD, 0xF8, 0x04, 0x00, 0x02, 0x91, 0xAD, 0xF8, 0x00, 0x30, 0xAD, 0xF8,
+ 0x0C, 0x20, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0xA5, 0xFA, 0x11, 0xB0,
+ 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x03, 0x12, 0x01, 0x90,
+ 0xAD, 0xF8, 0x08, 0x10, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0x03, 0xF0, 0xEE, 0xFA, 0x0D, 0xB0, 0x00, 0xBD, 0x01, 0x88, 0x40, 0xF2,
+ 0x41, 0x12, 0xA1, 0xF2, 0x41, 0x10, 0x91, 0x42, 0x48, 0xD0, 0x5E, 0xDC,
+ 0x40, 0xF2, 0x15, 0x12, 0xA1, 0xF2, 0x15, 0x10, 0x91, 0x42, 0x17, 0xD0,
+ 0x32, 0xDC, 0x1D, 0x29, 0x14, 0xD0, 0x14, 0xDC, 0x13, 0x29, 0x11, 0xD0,
+ 0x08, 0xDC, 0x01, 0x29, 0x38, 0xD0, 0x0B, 0x29, 0x3F, 0xD0, 0x0D, 0x29,
+ 0x34, 0xD0, 0x10, 0x29, 0x70, 0xD1, 0xCC, 0xE0, 0x14, 0x29, 0x6E, 0xD0,
+ 0x18, 0x29, 0x6D, 0xD0, 0x1A, 0x29, 0x6C, 0xD0, 0x1C, 0x29, 0x67, 0xD1,
+ 0xB7, 0xE0, 0x40, 0xF2, 0x09, 0x12, 0xA1, 0xF2, 0x09, 0x10, 0x91, 0x42,
+ 0x60, 0xD0, 0x0A, 0xDC, 0x23, 0x29, 0x28, 0xD0, 0xA1, 0xF5, 0x80, 0x71,
+ 0x01, 0x39, 0x73, 0xD0, 0x03, 0x29, 0x57, 0xD0, 0x06, 0x29, 0x55, 0xD1,
+ 0xAB, 0xE0, 0x02, 0x28, 0x6D, 0xD0, 0x04, 0x28, 0x50, 0xD0, 0x06, 0x28,
+ 0x6A, 0xD0, 0x09, 0x28, 0x4C, 0xD1, 0xA4, 0xE0, 0x18, 0x28, 0x0B, 0xD0,
+ 0x14, 0xDC, 0x0C, 0x28, 0x78, 0xD0, 0x08, 0xDC, 0x01, 0x28, 0x76, 0xD0,
+ 0x05, 0x28, 0x7C, 0xD0, 0x07, 0x28, 0x7A, 0xD0, 0x09, 0x28, 0x78, 0xD1,
+ 0x9D, 0xE0, 0x0E, 0x28, 0x39, 0xD0, 0x11, 0x28, 0x7B, 0xD0, 0x13, 0x28,
+ 0x71, 0xD0, 0x16, 0x28, 0x6F, 0xD1, 0x86, 0xE0, 0x1B, 0x38, 0x0F, 0x28,
+ 0x6B, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x92, 0x7E, 0x6A, 0x8A, 0x6A, 0x80,
+ 0x6A, 0x92, 0x6A, 0x80, 0x6A, 0x6A, 0x80, 0x6A, 0x76, 0x00, 0x36, 0x28,
+ 0x77, 0xD0, 0x2E, 0xDC, 0x1B, 0x28, 0x66, 0xD0, 0x14, 0xDC, 0x0F, 0x28,
+ 0x7B, 0xD0, 0x08, 0xDC, 0x07, 0x28, 0x64, 0xD0, 0x0A, 0x28, 0x70, 0xD0,
+ 0x0B, 0x28, 0x78, 0xD0, 0x0E, 0x28, 0x50, 0xD1, 0x75, 0xE0, 0x11, 0x28,
+ 0x4D, 0xD0, 0x14, 0x28, 0x6D, 0xD0, 0x17, 0x28, 0x6B, 0xD0, 0x19, 0x28,
+ 0x47, 0xD1, 0x6C, 0xE0, 0x2D, 0x28, 0x6A, 0xD0, 0x0C, 0xDC, 0x1D, 0x28,
+ 0x69, 0xD0, 0x1F, 0x28, 0x53, 0xD0, 0x21, 0x28, 0x61, 0xD0, 0x27, 0x28,
+ 0x3B, 0xD1, 0x5C, 0xE0, 0x39, 0xE0, 0x58, 0xE0, 0x3B, 0xE0, 0x3C, 0xE0,
+ 0x2F, 0x28, 0x56, 0xD0, 0x32, 0x28, 0x44, 0xD0, 0x34, 0x28, 0x30, 0xD1,
+ 0x47, 0xE0, 0x4C, 0x28, 0x4F, 0xD0, 0x17, 0xDC, 0x42, 0x28, 0x42, 0xD0,
+ 0x0B, 0xDC, 0x38, 0x28, 0x3B, 0xD0, 0x3A, 0x28, 0x4D, 0xD0, 0x3C, 0x28,
+ 0x33, 0xD0, 0x3E, 0x28, 0x21, 0xD1, 0x36, 0xE0, 0x21, 0xE0, 0x3A, 0xE0,
+ 0x1E, 0xE0, 0x44, 0x28, 0x35, 0xD0, 0x46, 0x28, 0x35, 0xD0, 0x48, 0x28,
+ 0x35, 0xD0, 0x4A, 0x28, 0x15, 0xD1, 0x34, 0xE0, 0x5A, 0x28, 0x3A, 0xD0,
+ 0x0B, 0xDC, 0x4E, 0x28, 0x33, 0xD0, 0x50, 0x28, 0x2F, 0xD0, 0x52, 0x28,
+ 0x2F, 0xD0, 0x54, 0x28, 0x09, 0xD1, 0x2E, 0xE0, 0x2F, 0xE0, 0x20, 0xE0,
+ 0x0D, 0xE0, 0x5C, 0x28, 0x2B, 0xD0, 0x79, 0x28, 0x17, 0xD0, 0x7C, 0x28,
+ 0x1B, 0xD0, 0x3C, 0x20, 0x70, 0x47, 0x18, 0x20, 0x70, 0x47, 0x09, 0x20,
+ 0x70, 0x47, 0x26, 0x20, 0x70, 0x47, 0x14, 0x20, 0x70, 0x47, 0x05, 0x20,
+ 0x70, 0x47, 0x0E, 0x20, 0x70, 0x47, 0x0A, 0x20, 0x70, 0x47, 0x11, 0x20,
+ 0x70, 0x47, 0x28, 0x20, 0x70, 0x47, 0x01, 0x20, 0x70, 0x47, 0x08, 0x20,
+ 0x70, 0x47, 0x07, 0x20, 0x70, 0x47, 0x1C, 0x20, 0x70, 0x47, 0x0C, 0x20,
+ 0x70, 0x47, 0x1A, 0x20, 0x70, 0x47, 0x10, 0x20, 0x70, 0x47, 0x06, 0x20,
+ 0x70, 0x47, 0x03, 0x20, 0x70, 0x47, 0x04, 0x20, 0x70, 0x47, 0x02, 0x20,
+ 0x70, 0x47, 0x00, 0x00, 0xFF, 0x22, 0x02, 0x70, 0x39, 0xB1, 0x01, 0x29,
+ 0x07, 0xD0, 0x10, 0x29, 0x0A, 0xD0, 0x11, 0x29, 0x0A, 0xD0, 0x00, 0x20,
+ 0x70, 0x47, 0x05, 0x49, 0x00, 0xE0, 0x05, 0x49, 0x09, 0x78, 0x01, 0x70,
+ 0x01, 0x20, 0x70, 0x47, 0x03, 0x49, 0xF9, 0xE7, 0x03, 0x49, 0xF7, 0xE7,
+ 0x00, 0x74, 0x20, 0x00, 0x01, 0x74, 0x20, 0x00, 0x05, 0x74, 0x20, 0x00,
+ 0x06, 0x74, 0x20, 0x00, 0x06, 0xF0, 0x70, 0xBE, 0x0A, 0x46, 0x01, 0x46,
+ 0x01, 0x48, 0x00, 0x78, 0xFE, 0xF7, 0xD0, 0xBF, 0x00, 0x74, 0x20, 0x00,
+ 0x40, 0x88, 0xB0, 0xF5, 0xA1, 0x7F, 0x7D, 0xD0, 0x58, 0xDC, 0x40, 0xF2,
+ 0x11, 0x12, 0xA0, 0xF2, 0x11, 0x11, 0x90, 0x42, 0x77, 0xD0, 0x35, 0xDC,
+ 0x1E, 0x28, 0x75, 0xD0, 0x12, 0xDC, 0xA0, 0xF1, 0x02, 0x00, 0x1A, 0x28,
+ 0x6F, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0xD9, 0xE8, 0xE8, 0xD9, 0xE8, 0xE8,
+ 0xE5, 0xE8, 0xE8, 0xE8, 0xD3, 0xE8, 0xE8, 0xE8, 0xE8, 0xE1, 0xD9, 0xE8,
+ 0xE8, 0xE1, 0xD3, 0xC3, 0xE8, 0xD9, 0xE8, 0xD3, 0xB0, 0xF5, 0x83, 0x7F,
+ 0x7E, 0xD0, 0x11, 0xDC, 0xB0, 0xF5, 0x80, 0x7F, 0x7B, 0xD0, 0x06, 0xDC,
+ 0x1F, 0x28, 0x55, 0xD0, 0x20, 0x28, 0x77, 0xD0, 0x24, 0x28, 0x52, 0xD1,
+ 0xC8, 0xE0, 0xA0, 0xF5, 0x80, 0x70, 0x03, 0x38, 0x4C, 0xD0, 0x02, 0x28,
+ 0x4B, 0xD1, 0xC1, 0xE0, 0xA0, 0xF5, 0x84, 0x70, 0x07, 0x28, 0x46, 0xD2,
+ 0xDF, 0xE8, 0x00, 0xF0, 0xAA, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xB6, 0x00,
+ 0x89, 0x1E, 0x2E, 0x29, 0x3D, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, 0xAB, 0xB6,
+ 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0x99, 0xB6, 0xB6, 0xB6, 0xAD, 0xB6,
+ 0xB6, 0xA5, 0xB6, 0xAB, 0xB3, 0xB6, 0xAD, 0xB6, 0xA1, 0x9B, 0xB6, 0x9D,
+ 0xB6, 0xAB, 0xAD, 0xB6, 0xB6, 0xAD, 0xB6, 0xAF, 0xB6, 0xAD, 0xB6, 0xAF,
+ 0xB6, 0xAF, 0x9F, 0xB6, 0xAD, 0xB6, 0xAD, 0xA5, 0xB0, 0xF5, 0xBF, 0x7F,
+ 0x78, 0xD0, 0x38, 0xDC, 0x40, 0xF2, 0x61, 0x12, 0xA0, 0xF2, 0x61, 0x11,
+ 0x90, 0x42, 0x72, 0xD0, 0x11, 0xDC, 0xA0, 0xF2, 0x49, 0x10, 0x17, 0x28,
+ 0x15, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x83, 0x85, 0x8E, 0x8E, 0x83, 0x83,
+ 0x8E, 0x8E, 0x83, 0x8E, 0x83, 0x8E, 0x8E, 0x79, 0x85, 0x8E, 0x87, 0x8E,
+ 0x85, 0x8E, 0x87, 0x8E, 0x7D, 0x00, 0x11, 0x29, 0x6E, 0xD0, 0x12, 0xDC,
+ 0x08, 0x29, 0x75, 0xD0, 0x0A, 0xDC, 0x02, 0xE0, 0x49, 0xE0, 0x77, 0xE0,
+ 0x66, 0xE0, 0x02, 0x29, 0x6E, 0xD0, 0x04, 0x29, 0x6A, 0xD0, 0x06, 0x29,
+ 0x71, 0xD1, 0x67, 0xE0, 0x0E, 0x29, 0x67, 0xD0, 0x10, 0x29, 0x6C, 0xD1,
+ 0x62, 0xE0, 0x13, 0x39, 0x09, 0x29, 0x68, 0xD2, 0xDF, 0xE8, 0x01, 0xF0,
+ 0x5E, 0x67, 0x58, 0x67, 0x58, 0x67, 0x60, 0x67, 0x60, 0x00, 0xB0, 0xF5,
+ 0xCB, 0x7F, 0x57, 0xD0, 0x14, 0xDC, 0xA0, 0xF5, 0xC0, 0x70, 0x15, 0x28,
+ 0x59, 0xD2, 0x02, 0xE0, 0x38, 0xE0, 0x3B, 0xE0, 0x34, 0xE0, 0xDF, 0xE8,
+ 0x00, 0xF0, 0x4D, 0x51, 0x4D, 0x54, 0x43, 0x54, 0x4B, 0x54, 0x4B, 0x54,
+ 0x4B, 0x54, 0x4D, 0x54, 0x4D, 0x54, 0x4D, 0x54, 0x4B, 0x54, 0x4D, 0x00,
+ 0xB0, 0xF5, 0xD9, 0x7F, 0x36, 0xD0, 0x15, 0xDC, 0x40, 0xF2, 0xAB, 0x12,
+ 0xA0, 0xF2, 0xAB, 0x11, 0x90, 0x42, 0x33, 0xD0, 0x09, 0xDC, 0xB0, 0xF5,
+ 0xCD, 0x7F, 0x31, 0xD0, 0xB0, 0xF5, 0xCE, 0x7F, 0x30, 0xD0, 0xB0, 0xF5,
+ 0xCF, 0x7F, 0x34, 0xD1, 0x2A, 0xE0, 0x01, 0x29, 0x24, 0xD0, 0x06, 0x29,
+ 0x2F, 0xD1, 0x1F, 0xE0, 0xA0, 0xF2, 0xB3, 0x10, 0x07, 0x28, 0x2A, 0xD2,
+ 0xDF, 0xE8, 0x00, 0xF0, 0x24, 0x29, 0x1E, 0x29, 0x29, 0x26, 0x0E, 0x00,
+ 0x28, 0x20, 0x70, 0x47, 0x0E, 0xE0, 0x19, 0xE0, 0x01, 0x20, 0xFA, 0xE7,
+ 0x18, 0x20, 0xF8, 0xE7, 0x0E, 0x20, 0xF6, 0xE7, 0x07, 0x20, 0xF4, 0xE7,
+ 0x1A, 0x20, 0xF2, 0xE7, 0x29, 0x20, 0xF0, 0xE7, 0x0C, 0x20, 0xEE, 0xE7,
+ 0x14, 0x20, 0xEC, 0xE7, 0x0A, 0x20, 0xEA, 0xE7, 0x08, 0x20, 0xE8, 0xE7,
+ 0x20, 0x20, 0xE6, 0xE7, 0x06, 0x20, 0xE4, 0xE7, 0x04, 0x20, 0xE2, 0xE7,
+ 0x02, 0x20, 0xE0, 0xE7, 0x12, 0x20, 0xDE, 0xE7, 0x10, 0x20, 0xDC, 0xE7,
+ 0xFF, 0xE7, 0x2C, 0x20, 0xD9, 0xE7, 0x00, 0x00, 0x38, 0xB5, 0x0C, 0x46,
+ 0x01, 0x46, 0x0E, 0x48, 0xF6, 0xF7, 0x20, 0xDA, 0x03, 0x46, 0x02, 0x22,
+ 0x0C, 0x49, 0x0D, 0x48, 0x00, 0x94, 0xF6, 0xF7, 0x4A, 0xD8, 0x0C, 0x48,
+ 0x01, 0x78, 0x5C, 0xB1, 0x21, 0xF0, 0x01, 0x01, 0x01, 0x70, 0x20, 0x46,
+ 0xFE, 0xF7, 0x08, 0xFE, 0x00, 0x2C, 0x06, 0xD1, 0xBD, 0xE8, 0x38, 0x40,
+ 0x02, 0xF0, 0x32, 0xBB, 0x41, 0xF0, 0x01, 0x01, 0xF2, 0xE7, 0x38, 0xBD,
+ 0x00, 0x00, 0x30, 0x21, 0xE0, 0x57, 0xC0, 0x08, 0x03, 0x37, 0x10, 0x21,
+ 0xD0, 0x77, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x47, 0x81, 0x46, 0xDD, 0xE9,
+ 0x0A, 0x78, 0x9A, 0x46, 0x16, 0x46, 0x08, 0x46, 0xFE, 0xF7, 0xD2, 0xFE,
+ 0x05, 0x00, 0x1A, 0xD0, 0xF0, 0x19, 0x81, 0xB2, 0x0E, 0x48, 0x40, 0xF2,
+ 0x9E, 0x23, 0x0C, 0x4A, 0x00, 0x78, 0xFD, 0xF7, 0xAF, 0xFD, 0x04, 0x00,
+ 0x0F, 0xD0, 0xB8, 0xF1, 0x00, 0x0F, 0x04, 0xD0, 0xA0, 0x19, 0x3A, 0x46,
+ 0x41, 0x46, 0x28, 0xF4, 0x24, 0xF1, 0xCD, 0xE9, 0x00, 0x95, 0xBA, 0xB2,
+ 0x53, 0x46, 0x31, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0x71, 0xF8, 0xBD, 0xE8,
+ 0xFC, 0x87, 0x00, 0x00, 0xEB, 0xAF, 0x82, 0x00, 0x04, 0x74, 0x20, 0x00,
+ 0x2D, 0xE9, 0xF0, 0x4F, 0x87, 0xB0, 0x83, 0x46, 0xDD, 0xE9, 0x11, 0x09,
+ 0xDD, 0xE9, 0x13, 0x87, 0x1C, 0x46, 0x15, 0x46, 0x0E, 0x46, 0xDD, 0xF8,
+ 0x40, 0xA0, 0xFE, 0xF7, 0x9F, 0xFE, 0xB8, 0xB1, 0x04, 0x2E, 0x01, 0xD0,
+ 0x01, 0x22, 0x00, 0xE0, 0x02, 0x22, 0x00, 0x26, 0xCD, 0xE9, 0x04, 0x06,
+ 0xA1, 0xB2, 0x01, 0xAE, 0x00, 0x91, 0xBB, 0xB2, 0x1F, 0xFA, 0x88, 0xF0,
+ 0x86, 0xE8, 0x09, 0x04, 0x1F, 0xFA, 0x89, 0xF3, 0xA9, 0xB2, 0x58, 0x46,
+ 0xFF, 0xF7, 0xE0, 0xF8, 0x00, 0x28, 0x08, 0xD0, 0x07, 0xB0, 0x58, 0x46,
+ 0xBD, 0xE8, 0xF0, 0x4F, 0x40, 0xF2, 0x25, 0x32, 0x02, 0x49, 0xFD, 0xF7,
+ 0x53, 0xBE, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x0B, 0xB0, 0x82, 0x00,
+ 0xF8, 0xB5, 0x1D, 0x46, 0x16, 0x46, 0x0F, 0x46, 0x06, 0x9C, 0xFE, 0xF7,
+ 0x71, 0xFE, 0x2B, 0x46, 0x32, 0x46, 0x39, 0x46, 0x00, 0x94, 0xFF, 0xF7,
+ 0x8B, 0xF9, 0xF8, 0xBD, 0x70, 0xB5, 0x06, 0x46, 0x1D, 0x46, 0x14, 0x46,
+ 0x08, 0x46, 0xFE, 0xF7, 0x63, 0xFE, 0x01, 0x21, 0x01, 0x2C, 0x04, 0xD0,
+ 0x02, 0x2C, 0x04, 0xD0, 0x05, 0x2C, 0x09, 0xD1, 0x03, 0xE0, 0x38, 0xB1,
+ 0x02, 0xE0, 0x02, 0x21, 0x00, 0xE0, 0x04, 0x21, 0x33, 0x46, 0x2A, 0x46,
+ 0xFF, 0xF7, 0x1B, 0xFA, 0x01, 0x20, 0x70, 0xBD, 0x00, 0xB5, 0x8B, 0xB0,
+ 0xC1, 0x79, 0x8D, 0xF8, 0x07, 0x10, 0x01, 0x68, 0x00, 0x91, 0x81, 0x88,
+ 0xAD, 0xF8, 0x04, 0x10, 0x81, 0x79, 0x8D, 0xF8, 0x06, 0x10, 0x00, 0x21,
+ 0xAD, 0xF8, 0x08, 0x10, 0x00, 0x7A, 0x69, 0x46, 0xFE, 0xF7, 0x69, 0xFE,
+ 0x0B, 0xB0, 0x00, 0xBD, 0x70, 0xB5, 0x05, 0x00, 0x05, 0xF1, 0x04, 0x00,
+ 0x4F, 0xF0, 0x01, 0x04, 0x77, 0xD0, 0x2B, 0x88, 0x40, 0xF2, 0x4B, 0x16,
+ 0x1A, 0x46, 0xA3, 0xF2, 0x4B, 0x11, 0xB3, 0x42, 0x70, 0xD0, 0x74, 0xDC,
+ 0x40, 0xF2, 0x15, 0x16, 0xA3, 0xF2, 0x15, 0x11, 0xB3, 0x42, 0x6B, 0xD0,
+ 0x36, 0xDC, 0x21, 0x2B, 0x69, 0xD0, 0x18, 0xDC, 0x14, 0x2B, 0x67, 0xD0,
+ 0x0C, 0xDC, 0x0D, 0x2B, 0x76, 0xD0, 0x04, 0xDC, 0x01, 0x2B, 0x74, 0xD0,
+ 0x0B, 0x2B, 0x73, 0xD1, 0xF5, 0xE0, 0x10, 0x2B, 0x71, 0xD0, 0x13, 0x2B,
+ 0x6E, 0xD1, 0xFF, 0xE0, 0x18, 0x2B, 0x6D, 0xD0, 0x1A, 0x2B, 0x6C, 0xD0,
+ 0x1C, 0x2B, 0x6B, 0xD0, 0x1D, 0x2B, 0x65, 0xD1, 0x0B, 0xE1, 0x40, 0xF2,
+ 0x09, 0x16, 0xA3, 0xF2, 0x09, 0x11, 0xB3, 0x42, 0x71, 0xD0, 0x0A, 0xDC,
+ 0x23, 0x2B, 0x6F, 0xD0, 0xA3, 0xF5, 0x80, 0x73, 0x01, 0x3B, 0x6C, 0xD0,
+ 0x03, 0x2B, 0x6B, 0xD0, 0x06, 0x2B, 0x53, 0xD1, 0xC5, 0xE0, 0x02, 0x29,
+ 0x67, 0xD0, 0x04, 0x29, 0x72, 0xD0, 0x06, 0x29, 0x71, 0xD0, 0x09, 0x29,
+ 0x4A, 0xD1, 0x2A, 0xE1, 0x1B, 0x29, 0x50, 0xD0, 0x18, 0xDC, 0x0E, 0x29,
+ 0x6A, 0xD0, 0x0C, 0xDC, 0x07, 0x29, 0x04, 0xD0, 0x04, 0xDC, 0x01, 0x29,
+ 0x7D, 0xD0, 0x05, 0x29, 0x3C, 0xD1, 0x28, 0xE1, 0x09, 0x29, 0x79, 0xD0,
+ 0x0C, 0x29, 0x37, 0xD1, 0x27, 0xE1, 0x11, 0x29, 0x75, 0xD0, 0x13, 0x29,
+ 0x74, 0xD0, 0x16, 0x29, 0x73, 0xD0, 0x18, 0x29, 0x2E, 0xD1, 0xE5, 0xE0,
+ 0x24, 0x29, 0x6F, 0xD0, 0x08, 0xDC, 0x1C, 0x29, 0x6D, 0xD0, 0x1E, 0x29,
+ 0x6C, 0xD0, 0x20, 0x29, 0x6B, 0xD0, 0x22, 0x29, 0x22, 0xD1, 0x30, 0xE1,
+ 0x27, 0x29, 0x67, 0xD0, 0x29, 0x29, 0x6F, 0xD0, 0x2C, 0x29, 0x6E, 0xD0,
+ 0x33, 0x29, 0x19, 0xD1, 0x4D, 0xE1, 0x90, 0xE0, 0x4E, 0xE1, 0x02, 0xE0,
+ 0xF9, 0xE0, 0xBF, 0xE0, 0xA7, 0xE0, 0x30, 0x29, 0x70, 0xD0, 0x3F, 0xDC,
+ 0x17, 0x29, 0x6E, 0xD0, 0x24, 0xDC, 0x0D, 0x29, 0x6C, 0xD0, 0x13, 0xDC,
+ 0x05, 0x29, 0x6A, 0xD0, 0x0B, 0xDC, 0x01, 0x29, 0x68, 0xD0, 0x04, 0x29,
+ 0x6F, 0xD1, 0x3F, 0xE1, 0x86, 0xE0, 0x7E, 0xE0, 0x6B, 0xE0, 0x8B, 0xE0,
+ 0x94, 0xE0, 0x9C, 0xE0, 0x9E, 0xE0, 0x07, 0x29, 0x73, 0xD0, 0x0A, 0x29,
+ 0x63, 0xD1, 0x68, 0xE0, 0x0F, 0x29, 0x6F, 0xD0, 0x11, 0x29, 0x6E, 0xD0,
+ 0x13, 0x29, 0x6D, 0xD0, 0x15, 0x29, 0x5A, 0xD1, 0x0E, 0xE1, 0xB7, 0xE0,
+ 0x99, 0xE0, 0xE6, 0xE0, 0xAB, 0xE0, 0xB7, 0xE0, 0x25, 0x29, 0x6F, 0xD0,
+ 0x0B, 0xDC, 0x19, 0x29, 0x6D, 0xD0, 0x1B, 0x29, 0x6C, 0xD0, 0x1D, 0x29,
+ 0x6B, 0xD0, 0x23, 0x29, 0x49, 0xD1, 0x43, 0xE1, 0xAE, 0xE0, 0xB2, 0xE0,
+ 0xCD, 0xE0, 0x28, 0x29, 0x71, 0xD0, 0x2A, 0x29, 0x70, 0xD0, 0x2C, 0x29,
+ 0x6F, 0xD0, 0x2E, 0x29, 0x3D, 0xD1, 0x2B, 0xE1, 0x46, 0x29, 0x6B, 0xD0,
+ 0x20, 0xDC, 0x3C, 0x29, 0x69, 0xD0, 0x12, 0xDC, 0x32, 0x29, 0x67, 0xD0,
+ 0x34, 0x29, 0x6F, 0xD0, 0x38, 0x29, 0x6E, 0xD0, 0x3A, 0x29, 0x2E, 0xD1,
+ 0x49, 0xE1, 0xA8, 0xE0, 0x9B, 0xE0, 0xB6, 0xE0, 0xD1, 0xE0, 0xBB, 0xE0,
+ 0xCC, 0xE0, 0xBC, 0xE0, 0xBE, 0xE0, 0xC0, 0xE0, 0xE2, 0xE0, 0x3E, 0x29,
+ 0x6F, 0xD0, 0x40, 0x29, 0x6E, 0xD0, 0x42, 0x29, 0x6D, 0xD0, 0x44, 0x29,
+ 0x1B, 0xD1, 0x18, 0xE1, 0xDB, 0xE0, 0xC4, 0xE0, 0x52, 0x29, 0x67, 0xD0,
+ 0x0D, 0xDC, 0x48, 0x29, 0x6F, 0xD0, 0x4A, 0x29, 0x6E, 0xD0, 0x4E, 0x29,
+ 0x6D, 0xD0, 0x50, 0x29, 0x0D, 0xD1, 0x19, 0xE1, 0xFD, 0xE0, 0xC3, 0xE0,
+ 0xE4, 0xE0, 0xDC, 0xE0, 0xD5, 0xE0, 0x69, 0x29, 0x70, 0xD0, 0x6F, 0x29,
+ 0x48, 0xD0, 0x71, 0x29, 0x49, 0xD0, 0x72, 0x29, 0x51, 0xD0, 0x13, 0x46,
+ 0x01, 0x22, 0x93, 0x49, 0x93, 0x48, 0xF5, 0xF7, 0x82, 0xDE, 0x41, 0xF2,
+ 0x16, 0x52, 0x92, 0x49, 0x28, 0x46, 0xFD, 0xF7, 0xFF, 0xFC, 0x20, 0x46,
+ 0x70, 0xBD, 0xC7, 0xE0, 0xCE, 0xE0, 0x9D, 0xE0, 0x9F, 0xE0, 0x28, 0x46,
+ 0x01, 0xF0, 0x9E, 0xF8, 0xEF, 0xE7, 0x01, 0xF0, 0x98, 0xF8, 0xEC, 0xE7,
+ 0x28, 0x46, 0x01, 0xF0, 0x17, 0xF9, 0xE8, 0xE7, 0xD9, 0xE0, 0x9C, 0xE0,
+ 0x7E, 0xE0, 0xA3, 0xE0, 0x28, 0x46, 0x01, 0xF0, 0x4E, 0xF8, 0xE0, 0xE7,
+ 0x01, 0xF0, 0x73, 0xF8, 0xDD, 0xE7, 0x01, 0xF0, 0x79, 0xF8, 0xDA, 0xE7,
+ 0xFF, 0xF7, 0xB8, 0xFE, 0xD7, 0xE7, 0xB6, 0xE0, 0xB8, 0xE0, 0xBA, 0xE0,
+ 0xCE, 0xE0, 0xEB, 0xE0, 0xAE, 0xE0, 0x00, 0xF0, 0x9A, 0xFB, 0xCE, 0xE7,
+ 0x01, 0xF0, 0xF2, 0xF8, 0xCB, 0xE7, 0x00, 0xF0, 0xC1, 0xFB, 0xC8, 0xE7,
+ 0xB6, 0xE0, 0xD6, 0xE0, 0x01, 0xF0, 0xB7, 0xF8, 0xC3, 0xE7, 0x01, 0xF0,
+ 0x69, 0xF8, 0xC0, 0xE7, 0x00, 0xF0, 0x85, 0xFB, 0xBD, 0xE7, 0x01, 0xF0,
+ 0xE5, 0xF8, 0xBA, 0xE7, 0x00, 0xF0, 0xB8, 0xFD, 0xB7, 0xE7, 0xC9, 0xE0,
+ 0xC2, 0xE0, 0xBE, 0xE0, 0xCF, 0xE0, 0x28, 0x46, 0x00, 0xF0, 0x6E, 0xFB,
+ 0x02, 0xE0, 0x28, 0x46, 0x00, 0xF0, 0x00, 0xFA, 0x04, 0x00, 0xAA, 0xD1,
+ 0xAF, 0xE7, 0xA6, 0xE0, 0xA8, 0xE0, 0xAA, 0xE0, 0x28, 0x46, 0x00, 0xF0,
+ 0x59, 0xF9, 0xF5, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0x38, 0xFA, 0x9E, 0xE7,
+ 0x28, 0x46, 0x00, 0xF0, 0x38, 0xF9, 0xED, 0xE7, 0xB8, 0xE0, 0x28, 0x46,
+ 0x00, 0xF0, 0x08, 0xF9, 0x95, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0x16, 0xF9,
+ 0x91, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0xAD, 0xFA, 0x8D, 0xE7, 0x28, 0x46,
+ 0x00, 0xF0, 0x96, 0xFA, 0x89, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0x70, 0xF9,
+ 0x85, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0x2E, 0xFA, 0xD4, 0xE7, 0x28, 0x46,
+ 0x00, 0xF0, 0xE1, 0xF8, 0x7D, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0xD1, 0xFA,
+ 0x79, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0xE6, 0xFA, 0x75, 0xE7, 0x01, 0xF0,
+ 0x4B, 0xF8, 0x72, 0xE7, 0x00, 0xF0, 0xFE, 0xFB, 0x6F, 0xE7, 0x00, 0xF0,
+ 0x9A, 0xFB, 0x6C, 0xE7, 0x00, 0xF0, 0x70, 0xFB, 0x69, 0xE7, 0x00, 0xF0,
+ 0x63, 0xFB, 0x66, 0xE7, 0x00, 0xF0, 0x79, 0xFE, 0x63, 0xE7, 0x00, 0xF0,
+ 0x06, 0xFF, 0x60, 0xE7, 0x00, 0xF0, 0xEF, 0xFE, 0x5D, 0xE7, 0x28, 0x46,
+ 0x00, 0xF0, 0x7E, 0xFC, 0x59, 0xE7, 0x00, 0xF0, 0xBD, 0xFB, 0x56, 0xE7,
+ 0x00, 0xF0, 0x1D, 0xFF, 0x53, 0xE7, 0x00, 0xF0, 0x81, 0xFE, 0x50, 0xE7,
+ 0x00, 0x78, 0x09, 0xF0, 0xF1, 0xFC, 0x4C, 0xE7, 0x00, 0xF0, 0x90, 0xFF,
+ 0x49, 0xE7, 0x09, 0xF0, 0x1C, 0xFF, 0x46, 0xE7, 0x00, 0xF0, 0x38, 0xFE,
+ 0x43, 0xE7, 0x00, 0xF0, 0xBB, 0xFB, 0x40, 0xE7, 0x0B, 0xF0, 0x40, 0xFB,
+ 0x3D, 0xE7, 0x00, 0xF0, 0xAD, 0xFC, 0x3A, 0xE7, 0x00, 0xF0, 0x98, 0xFC,
+ 0x37, 0xE7, 0x00, 0xF0, 0x1F, 0xFD, 0x34, 0xE7, 0x00, 0xF0, 0x0D, 0xFD,
+ 0x31, 0xE7, 0x00, 0xF0, 0xE1, 0xFD, 0x2E, 0xE7, 0x28, 0x46, 0x00, 0xF0,
+ 0xD0, 0xFC, 0x7D, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0x29, 0xFE, 0x26, 0xE7,
+ 0x28, 0x46, 0x00, 0xF0, 0xB2, 0xFC, 0x22, 0xE7, 0x00, 0xF0, 0x73, 0xFB,
+ 0x1F, 0xE7, 0x00, 0xF0, 0xE9, 0xFD, 0x1C, 0xE7, 0x00, 0xF0, 0x72, 0xFE,
+ 0x19, 0xE7, 0x00, 0xF0, 0x5F, 0xFE, 0x16, 0xE7, 0x00, 0xF0, 0xC9, 0xFE,
+ 0x13, 0xE7, 0x00, 0xF0, 0x46, 0xFF, 0x10, 0xE7, 0x00, 0xF0, 0x2F, 0xFF,
+ 0x0D, 0xE7, 0x00, 0xF0, 0xE2, 0xFE, 0x0A, 0xE7, 0x00, 0xF0, 0x53, 0xFF,
+ 0x07, 0xE7, 0x00, 0xF0, 0xF3, 0xFE, 0x04, 0xE7, 0x00, 0xF0, 0x01, 0xFF,
+ 0x01, 0xE7, 0x00, 0xF0, 0x4D, 0xFD, 0xFE, 0xE6, 0x00, 0xF0, 0x4F, 0xFD,
+ 0xFB, 0xE6, 0x00, 0xF0, 0x79, 0xFE, 0xF8, 0xE6, 0x00, 0xF0, 0x4F, 0xFF,
+ 0xF5, 0xE6, 0x00, 0xF0, 0x93, 0xFD, 0xF2, 0xE6, 0x00, 0xF0, 0x7D, 0xFD,
+ 0xEF, 0xE6, 0x00, 0xF0, 0xB1, 0xFE, 0xEC, 0xE6, 0x00, 0xF0, 0x4B, 0xFD,
+ 0xE9, 0xE6, 0x00, 0xF0, 0x55, 0xFD, 0xE6, 0xE6, 0x00, 0xF0, 0x3D, 0xFD,
+ 0xE3, 0xE6, 0x00, 0xF0, 0xA9, 0xFD, 0xE0, 0xE6, 0x00, 0xF0, 0x1A, 0xFD,
+ 0xDD, 0xE6, 0x00, 0x00, 0xB4, 0x56, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21,
+ 0xD7, 0xAF, 0x82, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x08, 0x46, 0xFE, 0xF7,
+ 0x01, 0xFC, 0x00, 0x28, 0x04, 0xD0, 0x21, 0x46, 0xBD, 0xE8, 0x10, 0x40,
+ 0x01, 0xF0, 0x1A, 0xBC, 0x10, 0xBD, 0x70, 0xB5, 0x05, 0x46, 0x14, 0x46,
+ 0x08, 0x46, 0xFE, 0xF7, 0xF3, 0xFB, 0x00, 0x28, 0x15, 0xD0, 0x02, 0x2C,
+ 0x07, 0xD0, 0x03, 0x2C, 0x09, 0xD0, 0x04, 0x2C, 0x09, 0xD0, 0x05, 0x2C,
+ 0x03, 0xD0, 0x01, 0x21, 0x06, 0xE0, 0x02, 0x21, 0x04, 0xE0, 0x05, 0x21,
+ 0x02, 0xE0, 0x03, 0x21, 0x00, 0xE0, 0x04, 0x21, 0x2A, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0xFF, 0xF7, 0xBD, 0xB9, 0x70, 0xBD, 0x10, 0xB5, 0x04, 0x46,
+ 0x08, 0x46, 0xFE, 0xF7, 0xD5, 0xFB, 0x00, 0x28, 0x04, 0xD0, 0x21, 0x46,
+ 0xBD, 0xE8, 0x10, 0x40, 0xFF, 0xF7, 0xDD, 0xB9, 0x10, 0xBD, 0x10, 0xB5,
+ 0x80, 0x88, 0xFE, 0xF7, 0x9F, 0xFC, 0x00, 0x28, 0x07, 0xD0, 0x01, 0x7D,
+ 0x0B, 0x29, 0x04, 0xD1, 0x00, 0x8A, 0xBD, 0xE8, 0x10, 0x40, 0x06, 0xF0,
+ 0x8B, 0xBA, 0x10, 0xBD, 0x10, 0xB5, 0x04, 0x1D, 0x80, 0x88, 0xFE, 0xF7,
+ 0x8F, 0xFC, 0x00, 0x28, 0x09, 0xD0, 0x01, 0x7D, 0x0B, 0x29, 0x06, 0xD1,
+ 0xA2, 0x88, 0x61, 0x88, 0x00, 0x8A, 0xBD, 0xE8, 0x10, 0x40, 0x06, 0xF0,
+ 0x78, 0xBE, 0x10, 0xBD, 0x10, 0xB5, 0x04, 0x1D, 0x80, 0x88, 0xFE, 0xF7,
+ 0x7D, 0xFC, 0x58, 0xB1, 0x01, 0x7D, 0x0B, 0x29, 0x02, 0xD0, 0x40, 0xF6,
+ 0x04, 0x41, 0x07, 0xE0, 0xA1, 0x78, 0x00, 0x8A, 0xBD, 0xE8, 0x10, 0x40,
+ 0x06, 0xF0, 0x74, 0xBE, 0x40, 0xF6, 0x07, 0x41, 0x20, 0x88, 0xBD, 0xE8,
+ 0x10, 0x40, 0xFF, 0xF7, 0xA2, 0xB9, 0xF8, 0xB5, 0x05, 0x46, 0x04, 0x1D,
+ 0x00, 0x26, 0x00, 0x89, 0xFE, 0xF7, 0x62, 0xFC, 0x10, 0xB1, 0x01, 0x7D,
+ 0x0B, 0x29, 0x02, 0xD0, 0x01, 0x26, 0x30, 0x46, 0xF8, 0xBD, 0x62, 0x89,
+ 0x0A, 0xB9, 0x01, 0x26, 0x00, 0x25, 0x00, 0x95, 0xA3, 0x89, 0xE1, 0x88,
+ 0x00, 0x8A, 0x06, 0xF0, 0xF3, 0xFB, 0xF2, 0xE7, 0x2D, 0xE9, 0xF0, 0x41,
+ 0x05, 0x46, 0x04, 0x1D, 0x00, 0x27, 0x00, 0x89, 0xFE, 0xF7, 0x48, 0xFC,
+ 0x06, 0x00, 0x02, 0xD0, 0x30, 0x7D, 0x0B, 0x28, 0x03, 0xD0, 0x01, 0x27,
+ 0x38, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0xA0, 0x89, 0x61, 0x89, 0x09, 0xB1,
+ 0xBD, 0xB1, 0x0B, 0xE0, 0x0D, 0x48, 0x01, 0x27, 0x40, 0xF6, 0x19, 0x43,
+ 0x0A, 0x4A, 0x1C, 0x21, 0x00, 0x78, 0xFD, 0xF7, 0x43, 0xFA, 0x05, 0x00,
+ 0x0B, 0xD0, 0x1C, 0x20, 0x21, 0x68, 0x80, 0x1F, 0x29, 0x60, 0xA8, 0x80,
+ 0x2B, 0x46, 0x62, 0x89, 0xE1, 0x88, 0x30, 0x8A, 0x06, 0xF0, 0x2A, 0xFA,
+ 0xE0, 0xE7, 0x01, 0x20, 0xDF, 0xE7, 0x00, 0x00, 0x96, 0xAF, 0x82, 0x00,
+ 0x02, 0x74, 0x20, 0x00, 0x30, 0xB5, 0x04, 0x1D, 0x87, 0xB0, 0x80, 0x88,
+ 0xFE, 0xF7, 0x16, 0xFC, 0x00, 0x25, 0x01, 0x22, 0x40, 0xF6, 0x07, 0x41,
+ 0x18, 0xB1, 0x03, 0x7D, 0x0B, 0x2B, 0x04, 0xD0, 0xC9, 0x1E, 0xA0, 0x78,
+ 0x01, 0x28, 0x2F, 0xD0, 0x04, 0xE0, 0xA3, 0x78, 0x01, 0x2B, 0x10, 0xD0,
+ 0x02, 0x2B, 0x14, 0xD0, 0x20, 0x88, 0xCD, 0xE9, 0x04, 0x05, 0xCD, 0xE9,
+ 0x02, 0x51, 0x00, 0x95, 0x01, 0x95, 0xA2, 0x78, 0x00, 0x23, 0x00, 0x21,
+ 0x08, 0x46, 0xFE, 0xF7, 0x79, 0xFD, 0x07, 0xB0, 0x30, 0xBD, 0xA1, 0x88,
+ 0x09, 0xB1, 0x02, 0x21, 0x02, 0xE0, 0x01, 0x21, 0x00, 0xE0, 0x04, 0x21,
+ 0x00, 0x8A, 0x04, 0x29, 0xAD, 0xF8, 0x00, 0x00, 0x18, 0xD0, 0xA0, 0x88,
+ 0x70, 0xB3, 0x02, 0x20, 0xAD, 0xF8, 0x02, 0x00, 0xE0, 0x88, 0xAD, 0xF8,
+ 0x04, 0x00, 0xA0, 0x88, 0xAD, 0xF8, 0x06, 0x00, 0x68, 0x46, 0x06, 0xF0,
+ 0xF7, 0xF9, 0xE2, 0xE7, 0xE0, 0x88, 0x23, 0x88, 0x00, 0x95, 0xCD, 0xE9,
+ 0x04, 0x30, 0xCD, 0xE9, 0x02, 0x21, 0x01, 0x95, 0x00, 0x23, 0xD4, 0xE7,
+ 0x04, 0x20, 0xAD, 0xF8, 0x02, 0x00, 0xE0, 0x88, 0xAD, 0xF8, 0x04, 0x00,
+ 0x20, 0x89, 0xAD, 0xF8, 0x06, 0x00, 0x60, 0x89, 0x30, 0xB1, 0x10, 0x20,
+ 0xAD, 0xF8, 0x08, 0x00, 0x60, 0x89, 0xAD, 0xF8, 0x0C, 0x00, 0xDF, 0xE7,
+ 0x80, 0x20, 0x0C, 0x34, 0xAD, 0xF8, 0x08, 0x00, 0x03, 0x94, 0xD9, 0xE7,
+ 0xAD, 0xF8, 0x02, 0x20, 0xE0, 0x88, 0xAD, 0xF8, 0x04, 0x00, 0xD3, 0xE7,
+ 0x2D, 0xE9, 0xFF, 0x41, 0x06, 0x46, 0x04, 0x1D, 0x00, 0x27, 0xC0, 0x89,
+ 0xFE, 0xF7, 0xAA, 0xFB, 0x05, 0x00, 0x28, 0xD0, 0x28, 0x7D, 0x0B, 0x28,
+ 0x02, 0xD0, 0x40, 0xF6, 0x04, 0x40, 0x24, 0xE0, 0x20, 0x8A, 0xE1, 0x89,
+ 0x09, 0xB1, 0xD6, 0xB1, 0x0B, 0xE0, 0x16, 0x48, 0x01, 0x27, 0x40, 0xF6,
+ 0xDC, 0x33, 0x13, 0x4A, 0x1C, 0x21, 0x00, 0x78, 0xFD, 0xF7, 0xA6, 0xF9,
+ 0x06, 0x00, 0x0E, 0xD0, 0x1C, 0x20, 0xE2, 0x89, 0x21, 0x7A, 0xA3, 0x89,
+ 0xCD, 0xE9, 0x00, 0x32, 0xCD, 0xE9, 0x02, 0x01, 0xD4, 0xE9, 0x00, 0x32,
+ 0x29, 0x8A, 0x30, 0x46, 0x06, 0xF0, 0xF2, 0xF9, 0x0D, 0xE0, 0x01, 0x20,
+ 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x40, 0xF6, 0x07, 0x40, 0x00, 0x90,
+ 0xD4, 0xE9, 0x00, 0x12, 0xA3, 0x89, 0x60, 0x89, 0xFE, 0xF7, 0xC0, 0xFD,
+ 0x01, 0x27, 0x38, 0x46, 0xF0, 0xE7, 0x00, 0x00, 0x75, 0xAF, 0x82, 0x00,
+ 0x00, 0x74, 0x20, 0x00, 0x70, 0x47, 0x38, 0xB5, 0x04, 0x1D, 0x80, 0x88,
+ 0xFE, 0xF7, 0x68, 0xFB, 0x00, 0x28, 0x0A, 0xD0, 0x01, 0x7D, 0x0B, 0x29,
+ 0x07, 0xD1, 0x00, 0x21, 0x00, 0x91, 0x00, 0x23, 0x21, 0x89, 0x00, 0x8A,
+ 0x1A, 0x46, 0x06, 0xF0, 0xFD, 0xFA, 0x38, 0xBD, 0x2D, 0xE9, 0xFC, 0x41,
+ 0x07, 0x46, 0x04, 0x1D, 0x01, 0x25, 0x80, 0x88, 0xFE, 0xF7, 0x52, 0xFB,
+ 0x06, 0x46, 0xA0, 0x78, 0x01, 0x28, 0x0A, 0xD0, 0x02, 0x28, 0x0F, 0xD0,
+ 0x03, 0x28, 0x0F, 0xD0, 0x04, 0x28, 0x0F, 0xD0, 0x00, 0x22, 0x1A, 0x49,
+ 0x1A, 0x48, 0xF5, 0xF7, 0xC0, 0xDB, 0xC6, 0xB1, 0x30, 0x7D, 0x0B, 0x28,
+ 0x08, 0xD0, 0x40, 0xF6, 0x04, 0x43, 0x14, 0xE0, 0x02, 0x25, 0xF6, 0xE7,
+ 0x03, 0x25, 0xF4, 0xE7, 0x05, 0x25, 0xF2, 0xE7, 0x60, 0x89, 0x29, 0x46,
+ 0x00, 0x1F, 0x78, 0x80, 0x20, 0x89, 0x38, 0x80, 0x00, 0x97, 0xE3, 0x88,
+ 0xA2, 0x88, 0x30, 0x8A, 0x06, 0xF0, 0xE8, 0xFA, 0x14, 0xE0, 0x40, 0xF6,
+ 0x07, 0x43, 0xA1, 0x78, 0x03, 0x29, 0x06, 0xD0, 0xA2, 0x88, 0x20, 0x88,
+ 0xFE, 0xF7, 0x13, 0xFE, 0x01, 0x20, 0xBD, 0xE8, 0xFC, 0x81, 0x20, 0x88,
+ 0x18, 0x21, 0xCD, 0xE9, 0x00, 0x30, 0x00, 0x23, 0x1A, 0x46, 0x38, 0x46,
+ 0xFE, 0xF7, 0xFA, 0xFB, 0x00, 0x20, 0xF2, 0xE7, 0xE8, 0x54, 0xC0, 0x08,
+ 0x00, 0x37, 0x10, 0x21, 0x70, 0xB5, 0x1C, 0x46, 0x15, 0x46, 0x0E, 0x46,
+ 0xFE, 0xF7, 0xE6, 0xFA, 0x00, 0x28, 0x0A, 0xD0, 0x01, 0x7D, 0x0B, 0x29,
+ 0x07, 0xD1, 0x00, 0x8A, 0x23, 0x46, 0x2A, 0x46, 0x31, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0xFF, 0xF7, 0x71, 0xB8, 0x70, 0xBD, 0x10, 0xB5, 0x04, 0x1D,
+ 0x80, 0x88, 0xFE, 0xF7, 0xF5, 0xFA, 0x00, 0x28, 0x0A, 0xD0, 0x01, 0x7D,
+ 0x0B, 0x29, 0x07, 0xD1, 0xE3, 0x88, 0xA2, 0x88, 0xA1, 0x78, 0x00, 0x8A,
+ 0xBD, 0xE8, 0x10, 0x40, 0x06, 0xF0, 0x66, 0xBC, 0x10, 0xBD, 0x1F, 0xB5,
+ 0x04, 0x1D, 0x80, 0x88, 0xFE, 0xF7, 0xE2, 0xFA, 0x40, 0xF6, 0x07, 0x42,
+ 0x30, 0xB1, 0x01, 0x7D, 0x0B, 0x29, 0xA1, 0x78, 0x04, 0xD0, 0x20, 0x88,
+ 0xD2, 0x1E, 0x11, 0xE0, 0xA1, 0x78, 0x0E, 0xE0, 0x69, 0xB1, 0x00, 0x8A,
+ 0xAD, 0xF8, 0x00, 0x00, 0xAD, 0xF8, 0x02, 0x10, 0xA0, 0x88, 0xAD, 0xF8,
+ 0x04, 0x00, 0xE0, 0x88, 0xAD, 0xF8, 0x06, 0x00, 0x02, 0x29, 0x14, 0xD1,
+ 0x05, 0xE0, 0x20, 0x88, 0x04, 0xB0, 0xBD, 0xE8, 0x10, 0x40, 0xFE, 0xF7,
+ 0xCD, 0xBF, 0x20, 0x89, 0x30, 0xB1, 0x10, 0x20, 0xAD, 0xF8, 0x08, 0x00,
+ 0x20, 0x89, 0xAD, 0xF8, 0x0C, 0x00, 0x04, 0xE0, 0x80, 0x20, 0x0A, 0x34,
+ 0xAD, 0xF8, 0x08, 0x00, 0x03, 0x94, 0x68, 0x46, 0x06, 0xF0, 0x71, 0xFC,
+ 0x1F, 0xBD, 0x10, 0xB5, 0x04, 0x1D, 0x80, 0x88, 0xFE, 0xF7, 0xAA, 0xFA,
+ 0x10, 0xB1, 0x01, 0x7D, 0x0B, 0x29, 0x07, 0xD0, 0x20, 0x88, 0x04, 0x23,
+ 0x00, 0x22, 0xBD, 0xE8, 0x10, 0x40, 0x11, 0x46, 0xFF, 0xF7, 0x14, 0xB8,
+ 0x41, 0x7D, 0x23, 0x79, 0x62, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0x16, 0x30,
+ 0x15, 0xF0, 0xC4, 0xBD, 0x10, 0xB5, 0x04, 0x1D, 0x00, 0x20, 0x21, 0x78,
+ 0x8C, 0xB0, 0x01, 0x22, 0x40, 0xF6, 0x08, 0x43, 0x11, 0xB1, 0x01, 0x29,
+ 0x30, 0xD1, 0x1A, 0xE0, 0x21, 0x7C, 0x01, 0xB1, 0x18, 0x46, 0xAD, 0xF8,
+ 0x00, 0x00, 0x8D, 0xF8, 0x0B, 0x20, 0x20, 0x7A, 0x69, 0x46, 0x80, 0x08,
+ 0xAD, 0xF8, 0x0C, 0x00, 0xD4, 0xF8, 0x01, 0x00, 0x01, 0x90, 0xB4, 0xF8,
+ 0x05, 0x00, 0xAD, 0xF8, 0x08, 0x00, 0xE0, 0x79, 0x8D, 0xF8, 0x0A, 0x00,
+ 0x02, 0x20, 0xE2, 0x68, 0x06, 0xF0, 0x4C, 0xFB, 0x14, 0xE0, 0x21, 0x7C,
+ 0x01, 0xB1, 0x18, 0x46, 0x00, 0x21, 0x8D, 0xF8, 0x07, 0x20, 0xAD, 0xF8,
+ 0x08, 0x10, 0xD4, 0xF8, 0x01, 0x10, 0x00, 0x91, 0xB4, 0xF8, 0x05, 0x10,
+ 0xAD, 0xF8, 0x04, 0x10, 0xE1, 0x79, 0x8D, 0xF8, 0x06, 0x10, 0x69, 0x46,
+ 0xFE, 0xF7, 0xB1, 0xF9, 0xE0, 0x68, 0x00, 0x28, 0x0A, 0xD0, 0x21, 0x7A,
+ 0x00, 0x29, 0x07, 0xD0, 0x0C, 0xB0, 0x40, 0xF6, 0xF4, 0x52, 0xBD, 0xE8,
+ 0x10, 0x40, 0x02, 0x49, 0xFD, 0xF7, 0x4C, 0xB9, 0x0C, 0xB0, 0x10, 0xBD,
+ 0xB5, 0xAF, 0x82, 0x00, 0x10, 0xB5, 0x83, 0x88, 0x82, 0x89, 0x81, 0x68,
+ 0x18, 0x46, 0x07, 0xF0, 0x9B, 0xFA, 0x01, 0x20, 0x10, 0xBD, 0xC2, 0x79,
+ 0x81, 0x79, 0x15, 0xF0, 0xFF, 0xBC, 0x30, 0xB5, 0x04, 0x46, 0x90, 0xF8,
+ 0x24, 0x00, 0x8B, 0xB0, 0x11, 0x38, 0x05, 0x28, 0x22, 0xD8, 0xA0, 0x79,
+ 0x8D, 0xF8, 0x06, 0x00, 0x94, 0xF8, 0x24, 0x00, 0x8D, 0xF8, 0x07, 0x00,
+ 0xE0, 0x79, 0x00, 0x25, 0x00, 0xB1, 0x01, 0x20, 0xAD, 0xF8, 0x08, 0x00,
+ 0x20, 0x68, 0x00, 0x90, 0xA0, 0x88, 0xAD, 0xF8, 0x04, 0x00, 0xE2, 0x79,
+ 0x04, 0xF1, 0x08, 0x01, 0x03, 0xA8, 0x27, 0xF4, 0xAC, 0xF3, 0x94, 0xF8,
+ 0x25, 0x00, 0x18, 0xB1, 0x01, 0x28, 0x01, 0xD0, 0x40, 0xF6, 0x08, 0x45,
+ 0x69, 0x46, 0x28, 0x46, 0xFE, 0xF7, 0x5A, 0xF9, 0x0B, 0xB0, 0x30, 0xBD,
+ 0xC2, 0x79, 0x81, 0x79, 0x15, 0xF0, 0x00, 0xBD, 0x01, 0x78, 0x02, 0x23,
+ 0x01, 0x29, 0x00, 0xD1, 0x03, 0x23, 0x41, 0x78, 0x42, 0x68, 0x18, 0x46,
+ 0x06, 0xF0, 0xAC, 0xBC, 0x1F, 0xB5, 0x04, 0x46, 0x80, 0x7B, 0xFE, 0xF7,
+ 0x3D, 0xF9, 0x8D, 0xF8, 0x0E, 0x00, 0xA0, 0x68, 0x02, 0x90, 0xA0, 0x89,
+ 0xAD, 0xF8, 0x0C, 0x00, 0x20, 0x78, 0x8D, 0xF8, 0x00, 0x00, 0xA0, 0x78,
+ 0x8D, 0xF8, 0x01, 0x00, 0xA0, 0x88, 0xAD, 0xF8, 0x04, 0x00, 0xE0, 0x88,
+ 0xAD, 0xF8, 0x06, 0x00, 0x60, 0x78, 0x8D, 0xF8, 0x02, 0x00, 0xE0, 0x7B,
+ 0x8D, 0xF8, 0x0F, 0x00, 0xE0, 0x7B, 0x01, 0xF0, 0xCB, 0xFF, 0x6A, 0x46,
+ 0x10, 0x21, 0x01, 0x20, 0x06, 0xF0, 0x86, 0xFC, 0x1F, 0xBD, 0x00, 0x78,
+ 0x20, 0xB1, 0x01, 0x28, 0x06, 0xD0, 0x04, 0x21, 0x00, 0xF0, 0x44, 0xBF,
+ 0x00, 0x22, 0x11, 0x46, 0x05, 0x20, 0x02, 0xE0, 0x00, 0x22, 0x11, 0x46,
+ 0x04, 0x20, 0x06, 0xF0, 0x75, 0xBC, 0x06, 0x28, 0x12, 0xD2, 0xDF, 0xE8,
+ 0x00, 0xF0, 0x11, 0x03, 0x07, 0x09, 0x0C, 0x0E, 0x4F, 0xF4, 0x9A, 0x70,
+ 0x02, 0xF0, 0x4F, 0xBA, 0x00, 0x20, 0x00, 0xE0, 0x01, 0x20, 0x00, 0xF0,
+ 0xE5, 0xBE, 0x01, 0x20, 0x00, 0xE0, 0x00, 0x20, 0x00, 0xF0, 0x26, 0xBF,
+ 0x70, 0x47, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x78, 0x20, 0xB1, 0xBD, 0xE8,
+ 0x10, 0x40, 0x00, 0x20, 0x17, 0xF0, 0xEA, 0xBA, 0x60, 0x1C, 0x17, 0xF0,
+ 0xE7, 0xFA, 0x62, 0x1C, 0x00, 0x21, 0xBD, 0xE8, 0x10, 0x40, 0x08, 0x46,
+ 0x00, 0xF0, 0x38, 0xBF, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFE, 0xF7,
+ 0x9B, 0xF9, 0x00, 0x28, 0x0B, 0xD0, 0xA1, 0x78, 0x01, 0x29, 0x06, 0xD0,
+ 0x4F, 0xF4, 0x40, 0x61, 0x00, 0x8A, 0xBD, 0xE8, 0x10, 0x40, 0x06, 0xF0,
+ 0x13, 0xBD, 0x00, 0x21, 0xF8, 0xE7, 0x10, 0xBD, 0x10, 0xB5, 0x04, 0x46,
+ 0x00, 0x88, 0xFE, 0xF7, 0x87, 0xF9, 0x28, 0xB1, 0x00, 0x8A, 0x21, 0x46,
+ 0xBD, 0xE8, 0x10, 0x40, 0x06, 0xF0, 0x3A, 0xBD, 0x20, 0x88, 0xBD, 0xE8,
+ 0x10, 0x40, 0x40, 0xF6, 0x07, 0x41, 0x01, 0xF0, 0xC3, 0xB8, 0x00, 0x00,
+ 0x2D, 0xE9, 0xF0, 0x41, 0x86, 0xB0, 0x05, 0x46, 0xFE, 0xF7, 0x50, 0xF9,
+ 0x43, 0x4E, 0x44, 0x4F, 0x04, 0x00, 0x14, 0xD0, 0x23, 0x7D, 0x01, 0x22,
+ 0x42, 0x49, 0x78, 0x1C, 0xF5, 0xF7, 0xE5, 0xD9, 0x23, 0x7D, 0x07, 0xF1,
+ 0x02, 0x08, 0x02, 0x2B, 0x24, 0xD0, 0x04, 0x2B, 0x42, 0xD0, 0x01, 0x22,
+ 0x06, 0xB0, 0x78, 0x1E, 0xBD, 0xE8, 0xF0, 0x41, 0x3B, 0x49, 0xF5, 0xF7,
+ 0xD6, 0x99, 0x29, 0x46, 0x30, 0x46, 0xF5, 0xF7, 0xA1, 0xDB, 0x37, 0x49,
+ 0x03, 0x46, 0x01, 0x22, 0x3C, 0x39, 0x38, 0x46, 0xF5, 0xF7, 0xCB, 0xD9,
+ 0x00, 0x20, 0x07, 0x21, 0xCD, 0xE9, 0x04, 0x01, 0x02, 0x90, 0x03, 0x90,
+ 0x00, 0x90, 0x03, 0x46, 0x02, 0x46, 0x29, 0x46, 0x01, 0x90, 0x00, 0xF0,
+ 0x6D, 0xFF, 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0xA8, 0x79, 0x01, 0x28,
+ 0x0A, 0xD0, 0x04, 0xF1, 0x16, 0x01, 0x0D, 0x46, 0x30, 0x46, 0xF5, 0xF7,
+ 0x81, 0xDB, 0x27, 0x49, 0x01, 0x22, 0x03, 0x46, 0x70, 0x31, 0x26, 0xE0,
+ 0x03, 0x20, 0x20, 0x75, 0x04, 0xF1, 0x16, 0x01, 0x0C, 0x46, 0x30, 0x46,
+ 0xF5, 0xF7, 0x74, 0xDB, 0x20, 0x49, 0x03, 0x46, 0x01, 0x22, 0x34, 0x31,
+ 0x40, 0x46, 0xF5, 0xF7, 0x9E, 0xD9, 0x01, 0x21, 0x20, 0x46, 0x2D, 0xE0,
+ 0x60, 0x8A, 0x1C, 0x49, 0x00, 0x90, 0x02, 0x22, 0x80, 0x39, 0x38, 0x46,
+ 0xF5, 0xF7, 0x93, 0xD9, 0xA8, 0x79, 0x01, 0x28, 0x1F, 0xD0, 0x04, 0xF1,
+ 0x16, 0x01, 0x0D, 0x46, 0x30, 0x46, 0xF5, 0xF7, 0x59, 0xDB, 0x14, 0x49,
+ 0x01, 0x22, 0x03, 0x46, 0x3C, 0x39, 0x40, 0x46, 0xF5, 0xF7, 0x83, 0xD9,
+ 0x20, 0x8A, 0x00, 0x21, 0x02, 0xF0, 0xA8, 0xF8, 0x00, 0x21, 0x28, 0x46,
+ 0x06, 0xF0, 0x5B, 0xF9, 0x00, 0x22, 0x20, 0x8A, 0x11, 0x46, 0x05, 0xF0,
+ 0xCF, 0xFB, 0x06, 0xB0, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0x02, 0xF0,
+ 0x3B, 0xB9, 0x01, 0x21, 0x04, 0xF1, 0x16, 0x00, 0x06, 0xB0, 0xBD, 0xE8,
+ 0xF0, 0x41, 0x06, 0xF0, 0x48, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21,
+ 0x01, 0x37, 0x10, 0x21, 0x4C, 0x55, 0xC0, 0x08, 0x78, 0x56, 0xC0, 0x08,
+ 0x70, 0xB5, 0x04, 0x1D, 0x40, 0x1D, 0xFE, 0xF7, 0xBB, 0xF8, 0x01, 0x46,
+ 0xE0, 0x79, 0x01, 0x28, 0x06, 0xD0, 0x03, 0x28, 0x04, 0xD0, 0x00, 0x20,
+ 0xE0, 0x71, 0x19, 0xB1, 0x05, 0x23, 0x1E, 0xE0, 0x01, 0x20, 0xF9, 0xE7,
+ 0xC1, 0xB2, 0x60, 0x1C, 0xFD, 0xF7, 0x2C, 0xFF, 0xB0, 0xB1, 0x06, 0x21,
+ 0x01, 0x75, 0x61, 0x89, 0x69, 0xB1, 0x0D, 0x4B, 0x02, 0x8A, 0x4F, 0xF4,
+ 0x80, 0x35, 0x1B, 0x78, 0x01, 0xEB, 0x81, 0x01, 0x45, 0xEA, 0x03, 0x63,
+ 0x1A, 0x43, 0x4B, 0x00, 0x08, 0xA1, 0xFD, 0xF7, 0xC7, 0xFE, 0x20, 0x46,
+ 0xBD, 0xE8, 0x70, 0x40, 0x06, 0xF0, 0x21, 0xB9, 0x03, 0x23, 0x00, 0x22,
+ 0xE1, 0x79, 0x60, 0x1C, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, 0x7C, 0xBF,
+ 0xCC, 0x77, 0x20, 0x00, 0x62, 0x74, 0x69, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x38, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFE, 0xF7, 0xA1, 0xF8, 0xFD, 0xF7,
+ 0xA9, 0xFF, 0x00, 0x28, 0x07, 0xD1, 0xA0, 0x7A, 0x00, 0x90, 0x23, 0x89,
+ 0xE2, 0x88, 0xA1, 0x88, 0x60, 0x88, 0x0D, 0xF0, 0xA1, 0xF9, 0x38, 0xBD,
+ 0x38, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFE, 0xF7, 0x8F, 0xF8, 0x05, 0x00,
+ 0x09, 0xD0, 0xFD, 0xF7, 0x95, 0xFF, 0x02, 0x00, 0x08, 0xD0, 0x28, 0x8A,
+ 0xBD, 0xE8, 0x38, 0x40, 0x00, 0x21, 0x00, 0xF0, 0x26, 0xBD, 0x20, 0x88,
+ 0x04, 0x22, 0xF7, 0xE7, 0x20, 0x89, 0x00, 0x90, 0xE3, 0x88, 0xA2, 0x88,
+ 0x61, 0x88, 0x28, 0x8A, 0x0D, 0xF0, 0xBC, 0xF9, 0x38, 0xBD, 0x10, 0xB5,
+ 0x04, 0x1D, 0x80, 0x79, 0x08, 0xB1, 0x01, 0x22, 0x00, 0xE0, 0x00, 0x22,
+ 0x21, 0x88, 0x00, 0x20, 0x0D, 0xF0, 0x84, 0xF8, 0x00, 0x28, 0x20, 0x88,
+ 0x04, 0xD0, 0x00, 0x21, 0xBD, 0xE8, 0x10, 0x40, 0x01, 0xF0, 0x96, 0xB8,
+ 0x03, 0x21, 0xF9, 0xE7, 0x70, 0x47, 0xF0, 0xB5, 0x06, 0x46, 0x04, 0x1D,
+ 0x85, 0xB0, 0x01, 0x27, 0x80, 0x88, 0xFE, 0xF7, 0x59, 0xF8, 0xFD, 0xF7,
+ 0x61, 0xFF, 0x05, 0x00, 0x03, 0x96, 0xE0, 0x88, 0xAD, 0xF8, 0x06, 0x00,
+ 0x38, 0x46, 0xAD, 0xF8, 0x04, 0x00, 0x60, 0x88, 0xAD, 0xF8, 0x0A, 0x00,
+ 0xA0, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x06, 0xD1, 0x68, 0x46, 0x0D, 0xF0,
+ 0xDD, 0xF8, 0x00, 0xB9, 0x05, 0x25, 0x00, 0x27, 0x25, 0xB1, 0x61, 0x88,
+ 0x20, 0x88, 0x2A, 0x46, 0x01, 0xF0, 0xE2, 0xF8, 0x05, 0xB0, 0x38, 0x46,
+ 0xF0, 0xBD, 0x70, 0xB5, 0x14, 0x46, 0x0D, 0x46, 0xFD, 0xF7, 0x50, 0xFF,
+ 0x00, 0x28, 0x05, 0xD0, 0x22, 0x46, 0x29, 0x46, 0xBD, 0xE8, 0x70, 0x40,
+ 0x01, 0xF0, 0xD2, 0xB8, 0x70, 0xBD, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88,
+ 0xFE, 0xF7, 0x26, 0xF8, 0xFD, 0xF7, 0x2E, 0xFF, 0x00, 0x28, 0x04, 0xD1,
+ 0x60, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0x0D, 0xF0, 0x1D, 0xB9, 0x10, 0xBD,
+ 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFE, 0xF7, 0x17, 0xF8, 0xFD, 0xF7,
+ 0x1F, 0xFF, 0x02, 0x00, 0x04, 0xD1, 0x60, 0x88, 0x0D, 0xF0, 0xC8, 0xF9,
+ 0x02, 0x00, 0x05, 0xD0, 0x60, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0x21,
+ 0x00, 0xF0, 0xE5, 0xBC, 0x10, 0xBD, 0x70, 0x47, 0x70, 0xB5, 0x05, 0x46,
+ 0x00, 0x88, 0xFE, 0xF7, 0x01, 0xF8, 0x04, 0x00, 0x06, 0xD0, 0x20, 0x7D,
+ 0x06, 0x28, 0x0D, 0xD0, 0xA9, 0x78, 0x06, 0x29, 0x06, 0xD1, 0x17, 0xE0,
+ 0x2B, 0x88, 0x01, 0x22, 0x13, 0x49, 0x14, 0x48, 0xF5, 0xF7, 0x6F, 0xD8,
+ 0x00, 0x22, 0x28, 0x88, 0x04, 0x21, 0x1B, 0xE0, 0x0F, 0x49, 0x10, 0x48,
+ 0x2B, 0x88, 0x01, 0x22, 0x48, 0x31, 0x80, 0x1C, 0xF5, 0xF7, 0x63, 0xD8,
+ 0x0A, 0x20, 0x20, 0x75, 0x20, 0x46, 0xFD, 0xF7, 0x07, 0xFE, 0x03, 0xE0,
+ 0x0C, 0x28, 0x08, 0xD0, 0x0C, 0x20, 0x20, 0x75, 0x04, 0xF1, 0x16, 0x00,
+ 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x21, 0x06, 0xF0, 0x33, 0xB9, 0x20, 0x8A,
+ 0x00, 0x22, 0x05, 0x21, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0, 0xE6, 0xB8,
+ 0x58, 0x54, 0xC0, 0x08, 0x01, 0x37, 0x10, 0x21, 0x10, 0xB5, 0x10, 0x21,
+ 0x01, 0x20, 0x08, 0xF0, 0x6D, 0xFC, 0x20, 0xB1, 0xBD, 0xE8, 0x10, 0x40,
+ 0x00, 0x20, 0x09, 0xF0, 0xF9, 0xBA, 0xBD, 0xE8, 0x10, 0x40, 0xFE, 0x21,
+ 0x40, 0xF2, 0xB5, 0x10, 0x02, 0xF0, 0x49, 0xB8, 0x82, 0x78, 0x41, 0x78,
+ 0x00, 0x78, 0x08, 0xF0, 0x7C, 0xBE, 0xC3, 0x78, 0x82, 0x78, 0x41, 0x78,
+ 0x00, 0x78, 0x08, 0xF0, 0x84, 0xBE, 0x01, 0x46, 0x02, 0x20, 0x0A, 0x78,
+ 0x01, 0x2A, 0x00, 0xD1, 0x03, 0x20, 0x06, 0xF0, 0xCB, 0xBB, 0x01, 0x46,
+ 0x00, 0x78, 0x20, 0xB1, 0x01, 0x28, 0x04, 0xD0, 0x04, 0x21, 0x01, 0xF0,
+ 0x83, 0xB9, 0x05, 0x20, 0x00, 0xE0, 0x04, 0x20, 0x06, 0xF0, 0xBE, 0xBB,
+ 0x01, 0x46, 0x01, 0x20, 0x06, 0xF0, 0xBA, 0xBB, 0x0B, 0x46, 0x06, 0x28,
+ 0x16, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x15, 0x03, 0x07, 0x0A, 0x0E, 0x11,
+ 0x11, 0x46, 0x18, 0x46, 0x01, 0xF0, 0xBC, 0xB9, 0x19, 0x46, 0x00, 0x20,
+ 0x01, 0xE0, 0x19, 0x46, 0x01, 0x20, 0x01, 0xF0, 0x39, 0xB9, 0x19, 0x46,
+ 0x01, 0x20, 0x01, 0xE0, 0x19, 0x46, 0x00, 0x20, 0x01, 0xF0, 0x60, 0xB9,
+ 0x70, 0x47, 0x10, 0xB5, 0x04, 0x78, 0x82, 0x78, 0x41, 0x78, 0x03, 0x1D,
+ 0x20, 0x46, 0x09, 0xF0, 0x71, 0xF8, 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8,
+ 0x10, 0x40, 0x4F, 0xF4, 0xB4, 0x71, 0x4F, 0xF4, 0xC6, 0x70, 0x01, 0xF0,
+ 0xF8, 0xBF, 0x10, 0xBD, 0x10, 0xB5, 0x83, 0x88, 0x42, 0x88, 0x41, 0x78,
+ 0x00, 0x78, 0x09, 0xF0, 0x49, 0xF8, 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8,
+ 0x10, 0x40, 0x4F, 0xF4, 0xB4, 0x71, 0x4F, 0xF4, 0xC7, 0x70, 0x01, 0xF0,
+ 0xE6, 0xBF, 0x10, 0xBD, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFD, 0xF7,
+ 0x4F, 0xFF, 0xFD, 0xF7, 0x57, 0xFE, 0x02, 0x00, 0x05, 0xD1, 0xA1, 0x88,
+ 0x60, 0x88, 0x0D, 0xF0, 0xD5, 0xF8, 0x02, 0x00, 0x05, 0xD0, 0x61, 0x88,
+ 0x20, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0x01, 0xF0, 0x19, 0xBD, 0x10, 0xBD,
+ 0x41, 0x78, 0x00, 0x78, 0x06, 0xF0, 0x0E, 0xBC, 0x70, 0xB5, 0x04, 0x46,
+ 0x00, 0x78, 0x00, 0x25, 0x28, 0xB1, 0x01, 0x28, 0x06, 0xD0, 0x02, 0x28,
+ 0x0D, 0xD0, 0x04, 0x25, 0x12, 0xE0, 0x08, 0xF0, 0x56, 0xFD, 0x0C, 0xE0,
+ 0x60, 0x78, 0x04, 0xF1, 0x18, 0x03, 0x04, 0xF1, 0x08, 0x02, 0xA1, 0x1C,
+ 0x08, 0xF0, 0x24, 0xFD, 0x03, 0xE0, 0x60, 0x78, 0xA1, 0x1C, 0x08, 0xF0,
+ 0xC7, 0xFE, 0x38, 0xB1, 0x00, 0x2D, 0x08, 0xD0, 0x20, 0x78, 0x29, 0x46,
+ 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0, 0x14, 0xBB, 0x4F, 0xF4, 0xB4, 0x75,
+ 0xF6, 0xE7, 0x70, 0xBD, 0x10, 0xB5, 0x04, 0x46, 0xC0, 0x79, 0xFF, 0x28,
+ 0x01, 0xD0, 0xFD, 0xF7, 0x4D, 0xFE, 0x02, 0x46, 0x20, 0x78, 0x61, 0x1C,
+ 0xBD, 0xE8, 0x10, 0x40, 0x06, 0xF0, 0x08, 0xBC, 0x1C, 0xB5, 0x81, 0x88,
+ 0xAD, 0xF8, 0x04, 0x10, 0x81, 0x79, 0x8D, 0xF8, 0x00, 0x10, 0xC1, 0x79,
+ 0x8D, 0xF8, 0x01, 0x10, 0x00, 0x7A, 0x8D, 0xF8, 0x02, 0x00, 0x68, 0x46,
+ 0x12, 0xF0, 0xC4, 0xFD, 0x01, 0xF0, 0x4C, 0xFB, 0x1C, 0xBD, 0x10, 0xB5,
+ 0x08, 0xF0, 0x65, 0xFE, 0x00, 0x28, 0x06, 0xD1, 0xBD, 0xE8, 0x10, 0x40,
+ 0x00, 0x21, 0x4F, 0xF4, 0xB4, 0x70, 0x01, 0xF0, 0x59, 0xBB, 0x10, 0xBD,
+ 0x70, 0xB5, 0x14, 0x46, 0x0D, 0x46, 0xFD, 0xF7, 0x09, 0xFE, 0x00, 0x28,
+ 0x05, 0xD0, 0x22, 0x46, 0x29, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0,
+ 0x69, 0xBB, 0x70, 0xBD, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFD, 0xF7,
+ 0xD1, 0xFE, 0x60, 0xB1, 0x00, 0x8A, 0x08, 0xF0, 0x48, 0xFE, 0x00, 0x28,
+ 0x0B, 0xD1, 0x20, 0x88, 0x00, 0x22, 0x4F, 0xF4, 0xB4, 0x71, 0xBD, 0xE8,
+ 0x10, 0x40, 0x01, 0xF0, 0x55, 0xBB, 0x00, 0x22, 0x20, 0x88, 0x04, 0x21,
+ 0xF7, 0xE7, 0x10, 0xBD, 0x1C, 0xB5, 0x02, 0x78, 0x41, 0x1C, 0x10, 0x46,
+ 0x08, 0xF0, 0x38, 0xFE, 0x00, 0x28, 0x06, 0xD1, 0x00, 0x90, 0x01, 0x90,
+ 0x69, 0x46, 0x4F, 0xF4, 0xB4, 0x70, 0x01, 0xF0, 0x71, 0xFB, 0x1C, 0xBD,
+ 0x1C, 0xB5, 0x02, 0x78, 0x41, 0x1C, 0x10, 0x46, 0x08, 0xF0, 0x2E, 0xFE,
+ 0x00, 0x28, 0x06, 0xD1, 0x00, 0x90, 0x01, 0x90, 0x69, 0x46, 0x4F, 0xF4,
+ 0xB4, 0x70, 0x01, 0xF0, 0x8D, 0xFB, 0x1C, 0xBD, 0x7C, 0xB5, 0x14, 0x46,
+ 0x0D, 0x46, 0xCD, 0xE9, 0x00, 0x54, 0x06, 0x46, 0x03, 0x46, 0x03, 0x22,
+ 0x05, 0x49, 0x06, 0x48, 0xF4, 0xF7, 0x0F, 0xDF, 0x30, 0x46, 0xFD, 0xF7,
+ 0x8F, 0xFE, 0x00, 0x28, 0x01, 0xD0, 0x05, 0x77, 0x44, 0x77, 0x7C, 0xBD,
+ 0x64, 0x5A, 0xC0, 0x08, 0x02, 0x37, 0x10, 0x21, 0x10, 0xB5, 0x08, 0xF0,
+ 0x14, 0xFE, 0x00, 0x28, 0x07, 0xD1, 0x00, 0x22, 0xBD, 0xE8, 0x10, 0x40,
+ 0x11, 0x46, 0x4F, 0xF4, 0xB4, 0x70, 0x01, 0xF0, 0x87, 0xBB, 0x10, 0xBD,
+ 0x00, 0x78, 0x08, 0xF0, 0x13, 0xBE, 0x08, 0xB5, 0x81, 0x79, 0x00, 0x91,
+ 0xC3, 0x79, 0x82, 0x88, 0x41, 0x88, 0x00, 0x78, 0x08, 0xF0, 0xFC, 0xFF,
+ 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8, 0x08, 0x40, 0x4F, 0xF4, 0xB4, 0x71,
+ 0x4F, 0xF4, 0x9D, 0x70, 0x01, 0xF0, 0xF3, 0xBE, 0x08, 0xBD, 0x10, 0xB5,
+ 0x41, 0x78, 0x00, 0x78, 0x08, 0xF0, 0xE0, 0xFF, 0x00, 0x28, 0x07, 0xD1,
+ 0xBD, 0xE8, 0x10, 0x40, 0x4F, 0xF4, 0xB4, 0x71, 0x4F, 0xF4, 0x9C, 0x70,
+ 0x01, 0xF0, 0xE3, 0xBE, 0x10, 0xBD, 0x10, 0xB5, 0x00, 0x78, 0x08, 0xF0,
+ 0xFB, 0xFD, 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8, 0x10, 0x40, 0x4F, 0xF4,
+ 0xB4, 0x71, 0x4F, 0xF4, 0xBD, 0x70, 0x01, 0xF0, 0xD4, 0xBE, 0x10, 0xBD,
+ 0x02, 0x78, 0x41, 0x1C, 0x10, 0x46, 0x0A, 0xF0, 0x13, 0xBC, 0x10, 0xB5,
+ 0x08, 0xF0, 0x72, 0xFF, 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8, 0x10, 0x40,
+ 0x4F, 0xF4, 0xB4, 0x71, 0x40, 0xF2, 0x5D, 0x10, 0x01, 0xF0, 0xC1, 0xBE,
+ 0x10, 0xBD, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFD, 0xF7, 0x2A, 0xFE,
+ 0x48, 0xB1, 0xA2, 0x88, 0x61, 0x88, 0x00, 0x8A, 0x08, 0xF0, 0x3A, 0xFE,
+ 0x00, 0x28, 0x08, 0xD1, 0x4F, 0xF4, 0xB4, 0x70, 0x00, 0xE0, 0x04, 0x20,
+ 0x21, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0x01, 0xF0, 0x5A, 0xBC, 0x10, 0xBD,
+ 0x10, 0xB5, 0x82, 0x78, 0x41, 0x78, 0x00, 0x78, 0x08, 0xF0, 0x3F, 0xFE,
+ 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8, 0x10, 0x40, 0x4F, 0xF4, 0xB4, 0x71,
+ 0x4F, 0xF4, 0xC8, 0x70, 0x01, 0xF0, 0x99, 0xBE, 0x10, 0xBD, 0x38, 0xB5,
+ 0x04, 0x46, 0x40, 0x79, 0x00, 0x90, 0x23, 0x79, 0xE2, 0x78, 0xA1, 0x78,
+ 0x20, 0x88, 0x08, 0xF0, 0x47, 0xFF, 0x00, 0x28, 0x06, 0xD1, 0x21, 0x88,
+ 0xBD, 0xE8, 0x38, 0x40, 0x4F, 0xF4, 0xB4, 0x70, 0x01, 0xF0, 0x81, 0xBC,
+ 0x38, 0xBD, 0x70, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0xFD, 0xF7, 0x18, 0xFD,
+ 0x00, 0x28, 0x05, 0xD0, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40,
+ 0x01, 0xF0, 0x73, 0xBC, 0x70, 0xBD, 0x10, 0xB5, 0x03, 0x78, 0xC2, 0x79,
+ 0x41, 0x1C, 0x18, 0x46, 0x08, 0xF0, 0x41, 0xFF, 0x00, 0x28, 0x07, 0xD1,
+ 0xBD, 0xE8, 0x10, 0x40, 0x4F, 0xF4, 0xB4, 0x71, 0x4F, 0xF4, 0xC0, 0x70,
+ 0x01, 0xF0, 0x65, 0xBE, 0x10, 0xBD, 0x0A, 0xF0, 0xCD, 0xBB, 0x10, 0xB5,
+ 0x00, 0x88, 0x08, 0xF0, 0x4C, 0xFF, 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8,
+ 0x10, 0x40, 0x4F, 0xF4, 0xB4, 0x71, 0x4F, 0xF4, 0xBE, 0x70, 0x01, 0xF0,
+ 0x54, 0xBE, 0x10, 0xBD, 0x08, 0xF0, 0x8F, 0xBF, 0x82, 0x78, 0x41, 0x78,
+ 0x00, 0x78, 0x08, 0xF0, 0x8E, 0xBF, 0x10, 0xB5, 0x41, 0x88, 0x00, 0x88,
+ 0x08, 0xF0, 0xAB, 0xFF, 0x00, 0x28, 0x05, 0xD1, 0xBD, 0xE8, 0x10, 0x40,
+ 0x4F, 0xF4, 0xB4, 0x70, 0x01, 0xF0, 0x0E, 0xBD, 0x10, 0xBD, 0x10, 0xB5,
+ 0x90, 0xF9, 0x01, 0x10, 0x90, 0xF9, 0x00, 0x00, 0x89, 0xB2, 0x80, 0xB2,
+ 0x08, 0xF0, 0x87, 0xFF, 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8, 0x10, 0x40,
+ 0x4F, 0xF4, 0xB4, 0x71, 0x4F, 0xF4, 0xCE, 0x70, 0x01, 0xF0, 0x2B, 0xBE,
+ 0x10, 0xBD, 0x08, 0xB5, 0xC1, 0x88, 0x00, 0x1D, 0x89, 0x0A, 0x1C, 0xD1,
+ 0x01, 0x79, 0x04, 0x29, 0x19, 0xD8, 0x00, 0x21, 0x00, 0x91, 0x02, 0x78,
+ 0x9D, 0xF8, 0x03, 0x10, 0x62, 0xF3, 0x04, 0x11, 0x8D, 0xF8, 0x03, 0x10,
+ 0x42, 0x88, 0xAD, 0xF8, 0x00, 0x20, 0x02, 0x79, 0x62, 0xF3, 0x02, 0x01,
+ 0x8D, 0xF8, 0x03, 0x10, 0x40, 0x79, 0x60, 0xF3, 0xC3, 0x01, 0x8D, 0xF8,
+ 0x03, 0x10, 0x68, 0x46, 0x12, 0xF0, 0x26, 0xFC, 0x08, 0xBD, 0x04, 0x21,
+ 0xBD, 0xE8, 0x08, 0x40, 0x11, 0x20, 0x01, 0xF0, 0x02, 0xBE, 0xC1, 0x79,
+ 0x01, 0x29, 0x01, 0xD0, 0x01, 0x22, 0x00, 0xE0, 0x00, 0x22, 0x81, 0x79,
+ 0x15, 0xF0, 0xA6, 0xBA, 0x01, 0x7B, 0x83, 0x68, 0x01, 0x29, 0x01, 0xD0,
+ 0x01, 0x22, 0x00, 0xE0, 0x00, 0x22, 0x81, 0x79, 0x15, 0xF0, 0xB6, 0xBA,
+ 0x81, 0x79, 0x0A, 0xF0, 0x9B, 0xB9, 0x81, 0x79, 0x0A, 0xF0, 0xE8, 0xB9,
+ 0x10, 0xB5, 0x8C, 0xB0, 0x02, 0x21, 0xAD, 0xF8, 0x02, 0x10, 0x11, 0x4C,
+ 0x4F, 0xF0, 0x01, 0x11, 0x01, 0x91, 0x21, 0x7A, 0x00, 0x1D, 0x41, 0xB1,
+ 0x03, 0x20, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0,
+ 0x3B, 0xFE, 0x0C, 0xB0, 0x10, 0xBD, 0x01, 0x21, 0x21, 0x72, 0x00, 0x68,
+ 0x60, 0x60, 0x00, 0x20, 0xAD, 0xF8, 0x08, 0x00, 0x68, 0x46, 0x01, 0xF0,
+ 0x2F, 0xFE, 0x20, 0x78, 0xC0, 0x07, 0xF0, 0xD0, 0x00, 0x20, 0xFD, 0xF7,
+ 0x77, 0xFB, 0x01, 0xF0, 0xA5, 0xF8, 0xEA, 0xE7, 0xD0, 0x77, 0x20, 0x00,
+ 0x08, 0xB5, 0x81, 0x7D, 0x01, 0x29, 0x01, 0xD0, 0x01, 0x21, 0x00, 0xE0,
+ 0x00, 0x21, 0x00, 0x91, 0xC1, 0x7D, 0x00, 0x23, 0x82, 0x1D, 0x15, 0xF0,
+ 0x77, 0xFB, 0x08, 0xBD, 0x1C, 0xB5, 0x14, 0x68, 0x00, 0x94, 0x92, 0x88,
+ 0xAD, 0xF8, 0x04, 0x20, 0x8D, 0xF8, 0x06, 0x30, 0x6B, 0x46, 0x09, 0x22,
+ 0xFD, 0xF7, 0x3C, 0xFB, 0x1C, 0xBD, 0x00, 0x78, 0x01, 0x28, 0x03, 0xD0,
+ 0x02, 0x21, 0x22, 0x20, 0x01, 0xF0, 0x9D, 0xBD, 0x0A, 0xF0, 0xB4, 0xB9,
+ 0xF8, 0xB5, 0x13, 0x4D, 0x04, 0x46, 0x0E, 0x46, 0x0B, 0x46, 0x00, 0x90,
+ 0x02, 0x22, 0x0F, 0x49, 0x28, 0x46, 0xF4, 0xF7, 0x7C, 0xDD, 0x01, 0x2C,
+ 0x17, 0xD1, 0x30, 0x46, 0xFD, 0xF7, 0xFA, 0xFC, 0x04, 0x00, 0x12, 0xD0,
+ 0xFD, 0xF7, 0x1C, 0xFB, 0x08, 0x49, 0x23, 0x7D, 0x01, 0x22, 0x34, 0x31,
+ 0x28, 0x46, 0xF4, 0xF7, 0x6C, 0xDD, 0x20, 0x7D, 0x07, 0x28, 0x06, 0xD1,
+ 0x04, 0xF1, 0x16, 0x00, 0xBD, 0xE8, 0xF8, 0x40, 0x00, 0x21, 0x05, 0xF0,
+ 0x43, 0xBE, 0xF8, 0xBD, 0xE8, 0x56, 0xC0, 0x08, 0x03, 0x37, 0x10, 0x21,
+ 0xC2, 0x79, 0x81, 0x79, 0x16, 0xF0, 0xD6, 0xBE, 0xC2, 0x79, 0x81, 0x79,
+ 0x16, 0xF0, 0x28, 0xBF, 0x38, 0xB5, 0x04, 0x1D, 0x82, 0x79, 0x80, 0x88,
+ 0xE1, 0x1C, 0x08, 0xF0, 0x96, 0xFF, 0x00, 0x28, 0x06, 0xD1, 0x00, 0x90,
+ 0x21, 0x88, 0x03, 0x46, 0x4F, 0xF4, 0xB4, 0x72, 0x00, 0xF0, 0x02, 0xF8,
+ 0x38, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x07, 0x46, 0x1D, 0x46,
+ 0x17, 0x48, 0x8A, 0x46, 0x91, 0x46, 0x05, 0xF1, 0x0A, 0x01, 0x40, 0xF2,
+ 0x0D, 0x23, 0x13, 0x4A, 0x88, 0x46, 0x00, 0x78, 0x08, 0x9E, 0xFC, 0xF7,
+ 0xC7, 0xFA, 0x04, 0x00, 0x15, 0xD0, 0x20, 0x1D, 0x0E, 0x21, 0x61, 0x80,
+ 0xA4, 0xF8, 0x04, 0xA0, 0xA4, 0xF8, 0x06, 0x90, 0x27, 0x72, 0x65, 0x72,
+ 0x2E, 0xB1, 0x25, 0xB1, 0x2A, 0x46, 0x31, 0x46, 0x80, 0x1D, 0x26, 0xF4,
+ 0x34, 0xF6, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x00, 0x21, 0x01, 0xF0,
+ 0x93, 0xBD, 0x43, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x01, 0x22, 0x04, 0x49,
+ 0x04, 0x48, 0xF4, 0xF7, 0x12, 0x9D, 0x00, 0x00, 0xB2, 0xAE, 0x82, 0x00,
+ 0x00, 0x74, 0x20, 0x00, 0xF0, 0x52, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21,
+ 0x70, 0xB5, 0x06, 0x46, 0x12, 0x48, 0x0C, 0x46, 0x40, 0xF2, 0x2D, 0x23,
+ 0x0F, 0x4A, 0x49, 0x1D, 0x00, 0x78, 0xFC, 0xF7, 0x93, 0xFA, 0x88, 0xB1,
+ 0x03, 0x1D, 0x0F, 0x21, 0x41, 0x80, 0x05, 0x46, 0x04, 0x71, 0x2E, 0xB1,
+ 0x24, 0xB1, 0x22, 0x46, 0x31, 0x46, 0x58, 0x1C, 0x26, 0xF4, 0x05, 0xF6,
+ 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x21, 0x01, 0xF0, 0x64, 0xBD,
+ 0x63, 0x1D, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0x22, 0x03, 0x49, 0x04, 0x48,
+ 0xF4, 0xF7, 0xE3, 0x9C, 0xCA, 0xAE, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00,
+ 0x2C, 0x53, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, 0x10, 0xB5, 0x04, 0x46,
+ 0x03, 0x46, 0x8C, 0xB0, 0x01, 0x22, 0x07, 0x49, 0x07, 0x48, 0xF4, 0xF7,
+ 0xD2, 0xDC, 0x20, 0x21, 0xAD, 0xF8, 0x02, 0x10, 0x8D, 0xF8, 0x04, 0x40,
+ 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x42, 0xFD, 0x0C, 0xB0, 0x10, 0xBD,
+ 0x68, 0x53, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, 0x0D, 0x48, 0x10, 0xB5,
+ 0x90, 0xF8, 0x98, 0x01, 0x48, 0xB1, 0x41, 0x01, 0x3C, 0x23, 0x0B, 0x4A,
+ 0x00, 0x20, 0xFF, 0xF7, 0x4D, 0xDA, 0x0A, 0x49, 0x00, 0x28, 0xC8, 0x60,
+ 0x0B, 0xD0, 0x08, 0x4A, 0x08, 0x49, 0x10, 0x1F, 0xFC, 0xF7, 0xFE, 0xFB,
+ 0x00, 0x28, 0x04, 0xD0, 0x04, 0x48, 0x14, 0x30, 0xFF, 0xF7, 0x02, 0xDC,
+ 0x01, 0x20, 0x10, 0xBD, 0x64, 0x01, 0x20, 0x00, 0x98, 0xAE, 0x82, 0x00,
+ 0xD0, 0x77, 0x20, 0x00, 0xD1, 0x0E, 0x81, 0x00, 0x00, 0xB5, 0x91, 0xB0,
+ 0x4F, 0xF4, 0xDD, 0x73, 0xAD, 0xF8, 0x00, 0x30, 0x00, 0xB9, 0x08, 0x48,
+ 0x8D, 0xF8, 0x0B, 0x20, 0x8D, 0xF8, 0x0A, 0x10, 0x01, 0x68, 0x01, 0x91,
+ 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0,
+ 0xAB, 0xFC, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0x8A, 0xAD, 0x82, 0x00,
+ 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0xB9, 0x12, 0xAD, 0xF8, 0x02, 0x20,
+ 0x02, 0x68, 0x01, 0x92, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x8D, 0xF8,
+ 0x0A, 0x10, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0xED, 0xFC, 0x0D, 0xB0,
+ 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0x19, 0x23, 0xAD, 0xF8, 0x02, 0x30,
+ 0x03, 0x68, 0x01, 0x93, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x8D, 0xF8,
+ 0x0A, 0x10, 0x8D, 0xF8, 0x0B, 0x20, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0,
+ 0xD9, 0xFC, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0x1F, 0x23,
+ 0xAD, 0xF8, 0x02, 0x30, 0x03, 0x68, 0x01, 0x93, 0x80, 0x88, 0xAD, 0xF8,
+ 0x08, 0x00, 0x8D, 0xF8, 0x0A, 0x20, 0x8D, 0xF8, 0x0B, 0x10, 0x01, 0x21,
+ 0x68, 0x46, 0x01, 0xF0, 0xC5, 0xFC, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0x00,
+ 0x00, 0xB5, 0x91, 0xB0, 0x1D, 0x23, 0xAD, 0xF8, 0x00, 0x30, 0x00, 0xB9,
+ 0x07, 0x48, 0x8D, 0xF8, 0x0A, 0x10, 0x8D, 0xF8, 0x0B, 0x20, 0x01, 0x68,
+ 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46,
+ 0x01, 0xF0, 0x56, 0xFC, 0x11, 0xB0, 0x00, 0xBD, 0x8A, 0xAD, 0x82, 0x00,
+ 0x00, 0xB5, 0x8D, 0xB0, 0x1E, 0x23, 0xAD, 0xF8, 0x02, 0x30, 0x0B, 0x68,
+ 0xCD, 0xF8, 0x06, 0x30, 0x89, 0x88, 0xAD, 0xF8, 0x0A, 0x10, 0xAD, 0xF8,
+ 0x04, 0x00, 0x8D, 0xF8, 0x0C, 0x20, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0,
+ 0x97, 0xFC, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0xF0, 0xB5, 0x8D, 0xB0,
+ 0x1C, 0x46, 0x15, 0x46, 0x0E, 0x46, 0x12, 0x9F, 0xFD, 0xF7, 0xB2, 0xFA,
+ 0x00, 0x28, 0x16, 0xD0, 0xAD, 0xF8, 0x04, 0x70, 0xAD, 0xF8, 0x06, 0x00,
+ 0x4F, 0xF4, 0xAB, 0x71, 0x09, 0x48, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8,
+ 0x08, 0x60, 0xAD, 0xF8, 0x0A, 0x50, 0xAD, 0xF8, 0x0C, 0x40, 0x90, 0xF8,
+ 0x9B, 0x01, 0xAD, 0xF8, 0x0E, 0x00, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0,
+ 0x73, 0xFC, 0x0D, 0xB0, 0xF0, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x30, 0xB5, 0x8D, 0xB0, 0x0D, 0x46, 0x04, 0x46, 0xFD, 0xF7, 0x8E, 0xFA,
+ 0x4F, 0xF4, 0xA5, 0x71, 0xAD, 0xF8, 0x04, 0x40, 0xAD, 0xF8, 0x02, 0x10,
+ 0xAD, 0xF8, 0x06, 0x50, 0x28, 0xB1, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0,
+ 0x5B, 0xFC, 0x0D, 0xB0, 0x30, 0xBD, 0x01, 0x22, 0x69, 0x46, 0x20, 0x46,
+ 0xFD, 0xF7, 0xCE, 0xFA, 0xF7, 0xE7, 0x30, 0xB5, 0x8D, 0xB0, 0x14, 0x46,
+ 0x0D, 0x46, 0xFD, 0xF7, 0x73, 0xFA, 0x00, 0x28, 0x0D, 0xD0, 0x40, 0xF2,
+ 0x49, 0x11, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8,
+ 0x06, 0x50, 0xAD, 0xF8, 0x08, 0x40, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0,
+ 0x3D, 0xFC, 0x0D, 0xB0, 0x30, 0xBD, 0x30, 0xB5, 0x8D, 0xB0, 0x14, 0x46,
+ 0x0D, 0x46, 0xFD, 0xF7, 0x3F, 0xFB, 0x00, 0x28, 0x17, 0xD0, 0x03, 0x7D,
+ 0x0B, 0x2B, 0x03, 0xD0, 0x0C, 0x2B, 0x01, 0xD0, 0x03, 0x2B, 0x10, 0xD1,
+ 0x00, 0x8A, 0x00, 0x28, 0x0D, 0xD0, 0x4F, 0xF4, 0xA7, 0x71, 0xAD, 0xF8,
+ 0x04, 0x00, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x06, 0x50, 0xAD, 0xF8,
+ 0x08, 0x40, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x1B, 0xFC, 0x0D, 0xB0,
+ 0x30, 0xBD, 0x30, 0xB5, 0x8D, 0xB0, 0x14, 0x46, 0x0D, 0x46, 0xFD, 0xF7,
+ 0x39, 0xFA, 0x00, 0x28, 0x0D, 0xD0, 0x40, 0xF2, 0x4D, 0x11, 0xAD, 0xF8,
+ 0x04, 0x00, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x06, 0x50, 0xAD, 0xF8,
+ 0x08, 0x40, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x03, 0xFC, 0x0D, 0xB0,
+ 0x30, 0xBD, 0x00, 0x00, 0x70, 0xB5, 0x90, 0xB0, 0x15, 0x46, 0x06, 0x46,
+ 0x0C, 0x46, 0x1F, 0x29, 0x06, 0xD9, 0x0B, 0x46, 0x01, 0x22, 0x12, 0x49,
+ 0x12, 0x48, 0xF4, 0xF7, 0x7A, 0xDB, 0x1F, 0x24, 0x40, 0xF2, 0x35, 0x10,
+ 0xAD, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x04, 0x60, 0x00, 0x20, 0x8D, 0xF8,
+ 0x05, 0x40, 0x02, 0x90, 0x74, 0xB1, 0x0D, 0x48, 0x40, 0xF2, 0x56, 0x53,
+ 0x0A, 0x4A, 0x21, 0x46, 0x00, 0x78, 0xFC, 0xF7, 0xFB, 0xF8, 0x02, 0x90,
+ 0x00, 0x28, 0x07, 0xD0, 0x22, 0x46, 0x29, 0x46, 0x26, 0xF4, 0x73, 0xF4,
+ 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x7C, 0xFB, 0x10, 0xB0, 0x70, 0xBD,
+ 0x74, 0x51, 0xC0, 0x08, 0x01, 0x37, 0x10, 0x21, 0x57, 0xAE, 0x82, 0x00,
+ 0x02, 0x74, 0x20, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0x9B, 0x72,
+ 0x8D, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20,
+ 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0xBC, 0xFB, 0x0D, 0xB0, 0x00, 0xBD,
+ 0xF0, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x33, 0x1C, 0xDD, 0xE9, 0x17, 0x46,
+ 0x16, 0x9F, 0x19, 0x9D, 0xAD, 0xF8, 0x00, 0xC0, 0x04, 0xB9, 0x0D, 0x4C,
+ 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8, 0x08, 0x20,
+ 0x8D, 0xF8, 0x12, 0x60, 0xAD, 0xF8, 0x0A, 0x30, 0x8D, 0xF8, 0x13, 0x70,
+ 0x8D, 0xF8, 0x06, 0x50, 0x20, 0x68, 0x03, 0x90, 0xA0, 0x88, 0xAD, 0xF8,
+ 0x10, 0x00, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x3F, 0xFB, 0x11, 0xB0,
+ 0xF0, 0xBD, 0x00, 0x00, 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x91, 0xB0,
+ 0x40, 0xF2, 0x31, 0x11, 0xAD, 0xF8, 0x00, 0x10, 0x8D, 0xF8, 0x04, 0x00,
+ 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x2E, 0xFB, 0x11, 0xB0, 0x00, 0xBD,
+ 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0x99, 0x72, 0x8D, 0xF8, 0x04, 0x00,
+ 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0x01, 0xF0, 0x76, 0xFB, 0x0D, 0xB0, 0x00, 0xBD, 0x10, 0xB5, 0x8C, 0xB0,
+ 0x40, 0xF2, 0xB1, 0x14, 0xAD, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10,
+ 0xAD, 0xF8, 0x08, 0x20, 0xAD, 0xF8, 0x02, 0x40, 0x8D, 0xF8, 0x0A, 0x30,
+ 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x62, 0xFB, 0x0C, 0xB0, 0x10, 0xBD,
+ 0x16, 0xF0, 0x44, 0xBB, 0x10, 0xB5, 0x8C, 0xB0, 0x4F, 0xF4, 0xBF, 0x74,
+ 0xAD, 0xF8, 0x04, 0x00, 0x13, 0x00, 0xAD, 0xF8, 0x02, 0x40, 0x8D, 0xF8,
+ 0x06, 0x10, 0x05, 0xD0, 0x10, 0x22, 0x19, 0x46, 0x0D, 0xF1, 0x07, 0x00,
+ 0x26, 0xF4, 0xE7, 0xF3, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x48, 0xFB,
+ 0x0C, 0xB0, 0x10, 0xBD, 0x16, 0xF0, 0x60, 0xBB, 0x10, 0xB5, 0x00, 0x28,
+ 0x02, 0xDA, 0x20, 0xF0, 0x00, 0x40, 0x01, 0xE0, 0x4F, 0xF0, 0xFF, 0x30,
+ 0x12, 0xF0, 0x2E, 0xF9, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x01, 0x20,
+ 0x10, 0xBD, 0x12, 0xF0, 0x41, 0xB9, 0x12, 0xF0, 0x45, 0xB9, 0x04, 0xF0,
+ 0x55, 0xBC, 0x00, 0x00, 0x7C, 0xB5, 0x0D, 0x46, 0xFD, 0xF7, 0x12, 0xFA,
+ 0x04, 0x00, 0x06, 0xD1, 0x00, 0x90, 0x01, 0x90, 0x68, 0x46, 0xFD, 0xF7,
+ 0x0B, 0xFA, 0x04, 0x00, 0x0B, 0xD0, 0x23, 0x7D, 0x01, 0x22, 0x05, 0x49,
+ 0x05, 0x48, 0xF4, 0xF7, 0xA2, 0xDA, 0x20, 0x7D, 0x04, 0x28, 0x01, 0xD0,
+ 0x08, 0x20, 0x20, 0x75, 0x25, 0x82, 0x7C, 0xBD, 0x10, 0x58, 0xC0, 0x08,
+ 0x02, 0x37, 0x10, 0x21, 0x70, 0xB5, 0x07, 0x4C, 0x40, 0xF2, 0x36, 0x45,
+ 0x20, 0x46, 0xFF, 0xF7, 0x04, 0xDA, 0x00, 0x28, 0x04, 0xD0, 0x2A, 0x46,
+ 0x03, 0x49, 0xFC, 0xF7, 0x0D, 0xF9, 0xF5, 0xE7, 0x70, 0xBD, 0x00, 0x00,
+ 0xE4, 0x77, 0x20, 0x00, 0x8E, 0xB0, 0x82, 0x00, 0x00, 0xB5, 0x91, 0xB0,
+ 0x40, 0xF2, 0x7D, 0x11, 0xAD, 0xF8, 0x00, 0x10, 0x70, 0xB1, 0x00, 0x21,
+ 0x8D, 0xF8, 0x04, 0x10, 0x01, 0x46, 0x10, 0x22, 0x0D, 0xF1, 0x05, 0x00,
+ 0x26, 0xF4, 0x87, 0xF3, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x90, 0xFA,
+ 0x11, 0xB0, 0x00, 0xBD, 0x01, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0xF5, 0xE7,
+ 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x2B, 0x12, 0xAD, 0xF8, 0x00, 0x20,
+ 0x00, 0xB9, 0x07, 0x48, 0x8D, 0xF8, 0x0A, 0x10, 0x01, 0x68, 0x01, 0x91,
+ 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0,
+ 0x77, 0xFA, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0x8A, 0xAD, 0x82, 0x00,
+ 0x2D, 0xE9, 0xF0, 0x43, 0x8D, 0xB0, 0x04, 0x00, 0xDD, 0xE9, 0x18, 0x95,
+ 0xDD, 0xE9, 0x14, 0xC7, 0xDD, 0xE9, 0x16, 0x60, 0x4F, 0xF4, 0x96, 0x78,
+ 0xAD, 0xF8, 0x02, 0x80, 0x0F, 0xD0, 0xB4, 0xF8, 0x10, 0x80, 0xAD, 0xF8,
+ 0x06, 0x80, 0x94, 0xF8, 0x1C, 0x80, 0x8D, 0xF8, 0x1A, 0x80, 0x94, 0xF8,
+ 0x1D, 0x80, 0x8D, 0xF8, 0x1B, 0x80, 0x94, 0xF8, 0x1E, 0x80, 0x8D, 0xF8,
+ 0x1C, 0x80, 0xAD, 0xF8, 0x08, 0x30, 0xAD, 0xF8, 0x04, 0x50, 0x8D, 0xF8,
+ 0x0A, 0xC0, 0xAD, 0xF8, 0x14, 0x60, 0x8D, 0xF8, 0x0B, 0x70, 0x8D, 0xF8,
+ 0x0C, 0x20, 0xAD, 0xF8, 0x16, 0x00, 0xAD, 0xF8, 0x18, 0x90, 0x08, 0x68,
+ 0xCD, 0xF8, 0x0D, 0x00, 0x88, 0x88, 0xAD, 0xF8, 0x11, 0x00, 0x01, 0x21,
+ 0x68, 0x46, 0x01, 0xF0, 0x91, 0xFA, 0x00, 0x2D, 0x05, 0xD1, 0x00, 0x2C,
+ 0x03, 0xD0, 0x20, 0x8A, 0x01, 0x21, 0x01, 0xF0, 0x39, 0xF9, 0x0D, 0xB0,
+ 0xBD, 0xE8, 0xF0, 0x83, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0x95, 0x71,
+ 0xAD, 0xF8, 0x02, 0x10, 0x41, 0x7D, 0x8D, 0xF8, 0x0A, 0x10, 0xD0, 0xF8,
+ 0x16, 0x10, 0x01, 0x91, 0x40, 0x8B, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21,
+ 0x68, 0x46, 0x01, 0xF0, 0x73, 0xFA, 0x0D, 0xB0, 0x00, 0xBD, 0x10, 0xB5,
+ 0x8C, 0xB0, 0x4F, 0xF4, 0xA1, 0x74, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8,
+ 0x06, 0x10, 0xAD, 0xF8, 0x08, 0x20, 0xAD, 0xF8, 0x02, 0x40, 0xAD, 0xF8,
+ 0x0A, 0x30, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x5F, 0xFA, 0x0C, 0xB0,
+ 0x10, 0xBD, 0x00, 0x00, 0xF0, 0xB5, 0x91, 0xB0, 0x0D, 0x00, 0xDD, 0xE9,
+ 0x17, 0x71, 0x4F, 0xF4, 0x94, 0x7C, 0x16, 0x9E, 0x4F, 0xF0, 0x01, 0x04,
+ 0xAD, 0xF8, 0x00, 0xC0, 0x8D, 0xF8, 0x04, 0x00, 0x00, 0xD1, 0x12, 0x4D,
+ 0x8D, 0xF8, 0x0C, 0x30, 0x8D, 0xF8, 0x0B, 0x20, 0xAD, 0xF8, 0x0E, 0x70,
+ 0x2A, 0x68, 0xCD, 0xF8, 0x05, 0x20, 0xAA, 0x88, 0xAD, 0xF8, 0x09, 0x20,
+ 0x8D, 0xF8, 0x0D, 0x60, 0x06, 0xF0, 0x07, 0x02, 0x38, 0xB1, 0x00, 0x24,
+ 0x03, 0xE0, 0x64, 0x1C, 0x50, 0x1E, 0xE4, 0xB2, 0x02, 0x40, 0x00, 0x2A,
+ 0xF9, 0xD1, 0x22, 0x01, 0x04, 0xA8, 0x26, 0xF4, 0xCA, 0xF2, 0x01, 0x21,
+ 0x68, 0x46, 0x01, 0xF0, 0xD3, 0xF9, 0x11, 0xB0, 0xF0, 0xBD, 0x00, 0x00,
+ 0x8A, 0xAD, 0x82, 0x00, 0x10, 0xB5, 0x8C, 0xB0, 0x40, 0xF2, 0x29, 0x14,
+ 0xAD, 0xF8, 0x0C, 0x20, 0xAD, 0xF8, 0x02, 0x40, 0xAD, 0xF8, 0x0E, 0x30,
+ 0x8D, 0xF8, 0x0A, 0x10, 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8,
+ 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x11, 0xFA, 0x0C, 0xB0,
+ 0x10, 0xBD, 0x2D, 0xE9, 0xF8, 0x43, 0x1F, 0x46, 0xDD, 0xE9, 0x08, 0x64,
+ 0x90, 0x46, 0x0D, 0x46, 0xFD, 0xF7, 0x10, 0xF9, 0x00, 0x28, 0x11, 0xD0,
+ 0x01, 0x2D, 0x08, 0xD0, 0x00, 0x8A, 0x01, 0xB0, 0x23, 0x46, 0x32, 0x46,
+ 0x41, 0x46, 0xBD, 0xE8, 0xF0, 0x43, 0xFF, 0xF7, 0x88, 0xBF, 0x00, 0x94,
+ 0x00, 0x8A, 0x33, 0x46, 0x3A, 0x46, 0x41, 0x46, 0x00, 0xF0, 0x12, 0xF8,
+ 0xBD, 0xE8, 0xF8, 0x83, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x41, 0x12,
+ 0xAD, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x00, 0x20,
+ 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x8A, 0xF9, 0x11, 0xB0, 0x00, 0xBD,
+ 0x30, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xA0, 0x75, 0x10, 0x9C, 0xAD, 0xF8,
+ 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x08, 0x20, 0xAD, 0xF8,
+ 0x02, 0x50, 0xAD, 0xF8, 0x0A, 0x30, 0xAD, 0xF8, 0x0C, 0x40, 0x01, 0x21,
+ 0x68, 0x46, 0x01, 0xF0, 0xCB, 0xF9, 0x0D, 0xB0, 0x30, 0xBD, 0xF0, 0xB5,
+ 0x91, 0xB0, 0x16, 0xAC, 0x94, 0xE8, 0xE0, 0x00, 0xAD, 0xF8, 0x04, 0x00,
+ 0x4F, 0xF4, 0x9F, 0x74, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x08, 0x20,
+ 0xAD, 0xF8, 0x0C, 0x50, 0xAD, 0xF8, 0x00, 0x40, 0xAD, 0xF8, 0x0A, 0x30,
+ 0xAD, 0xF8, 0x0E, 0x60, 0xAD, 0xF8, 0x10, 0x70, 0x01, 0x21, 0x68, 0x46,
+ 0x01, 0xF0, 0x56, 0xF9, 0x11, 0xB0, 0xF0, 0xBD, 0x00, 0xB5, 0x8D, 0xB0,
+ 0x40, 0xF2, 0x3F, 0x12, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10,
+ 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x9E, 0xF9,
+ 0x0D, 0xB0, 0x00, 0xBD, 0x10, 0xB5, 0x8C, 0xB0, 0x0C, 0x46, 0xFC, 0xF7,
+ 0xBD, 0xFF, 0x00, 0x28, 0x0B, 0xD0, 0x40, 0xF2, 0x57, 0x11, 0xAD, 0xF8,
+ 0x04, 0x00, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x06, 0x40, 0x01, 0x21,
+ 0x68, 0x46, 0x01, 0xF0, 0x89, 0xF9, 0x0C, 0xB0, 0x10, 0xBD, 0x00, 0x00,
+ 0x70, 0xB5, 0x1C, 0x46, 0x13, 0x4B, 0x92, 0xB0, 0xDD, 0xE9, 0x16, 0x65,
+ 0xB3, 0xF8, 0xA6, 0x31, 0x93, 0x42, 0x09, 0xD2, 0x00, 0x93, 0x13, 0x46,
+ 0x02, 0x22, 0x0F, 0x49, 0x0F, 0x48, 0xF4, 0xF7, 0xFC, 0xD8, 0x00, 0x20,
+ 0x12, 0xB0, 0x70, 0xBD, 0xAD, 0xF8, 0x08, 0x00, 0x40, 0xF2, 0x4B, 0x13,
+ 0xAD, 0xF8, 0x0A, 0x10, 0xAD, 0xF8, 0x0C, 0x20, 0xAD, 0xF8, 0x10, 0x60,
+ 0xAD, 0xF8, 0x04, 0x30, 0xAD, 0xF8, 0x0E, 0x40, 0xAD, 0xF8, 0x12, 0x50,
+ 0x01, 0x21, 0x01, 0xA8, 0x01, 0xF0, 0x06, 0xF9, 0xE8, 0xE7, 0x00, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0xF4, 0x51, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21,
+ 0x30, 0xB5, 0x1C, 0x46, 0x11, 0x4B, 0x91, 0xB0, 0xB3, 0xF8, 0xA6, 0x31,
+ 0x14, 0x9D, 0x93, 0x42, 0x09, 0xD2, 0x00, 0x93, 0x13, 0x46, 0x02, 0x22,
+ 0x0D, 0x49, 0x0E, 0x48, 0xF4, 0xF7, 0xCD, 0xD8, 0x00, 0x20, 0x11, 0xB0,
+ 0x30, 0xBD, 0xAD, 0xF8, 0x08, 0x00, 0x4F, 0xF4, 0xA4, 0x73, 0xAD, 0xF8,
+ 0x0A, 0x10, 0xAD, 0xF8, 0x0C, 0x20, 0xAD, 0xF8, 0x04, 0x30, 0xAD, 0xF8,
+ 0x0E, 0x40, 0xAD, 0xF8, 0x10, 0x50, 0x01, 0x21, 0x01, 0xA8, 0x01, 0xF0,
+ 0xD9, 0xF8, 0xEA, 0xE7, 0x64, 0x01, 0x20, 0x00, 0xB4, 0x51, 0xC0, 0x08,
+ 0x00, 0x37, 0x10, 0x21, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x55, 0x13,
+ 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x00, 0x30,
+ 0x8D, 0xF8, 0x08, 0x20, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0xC2, 0xF8,
+ 0x11, 0xB0, 0x00, 0xBD, 0x38, 0xB5, 0x04, 0x9C, 0x13, 0xB1, 0x08, 0xB1,
+ 0x0C, 0x2C, 0x08, 0xD2, 0x00, 0x93, 0x23, 0x46, 0x02, 0x22, 0x09, 0x49,
+ 0x09, 0x48, 0xF4, 0xF7, 0x92, 0xD8, 0x00, 0x20, 0x38, 0xBD, 0x4F, 0xF4,
+ 0xA9, 0x75, 0x05, 0x80, 0x81, 0x80, 0xC2, 0x80, 0x03, 0x81, 0x44, 0x81,
+ 0xBD, 0xE8, 0x38, 0x40, 0x00, 0x21, 0x01, 0xF0, 0xA5, 0xB8, 0x00, 0x00,
+ 0x34, 0x52, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, 0x00, 0xB5, 0x91, 0xB0,
+ 0x40, 0xF2, 0x4F, 0x12, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10,
+ 0xAD, 0xF8, 0x00, 0x20, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x92, 0xF8,
+ 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0xA6, 0x72,
+ 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x00, 0x20,
+ 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x82, 0xF8, 0x11, 0xB0, 0x00, 0xBD,
+ 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0xAD, 0x72, 0xAD, 0xF8, 0x00, 0x20,
+ 0xFF, 0x28, 0x02, 0xD9, 0x00, 0x20, 0x11, 0xB0, 0x00, 0xBD, 0xAD, 0xF8,
+ 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0,
+ 0x6D, 0xF8, 0xF4, 0xE7, 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x5B, 0x12,
+ 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x02, 0x20,
+ 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0xB6, 0xF8, 0x0D, 0xB0, 0x00, 0xBD,
+ 0x10, 0xB5, 0x90, 0xB0, 0x4F, 0xF4, 0xAC, 0x74, 0xAD, 0xF8, 0x00, 0x40,
+ 0xFF, 0x28, 0x02, 0xD9, 0x00, 0x20, 0x10, 0xB0, 0x10, 0xBD, 0xAD, 0xF8,
+ 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10, 0x8D, 0xF8, 0x07, 0x20, 0x8D, 0xF8,
+ 0x08, 0x30, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x45, 0xF8, 0xF0, 0xE7,
+ 0x10, 0xB5, 0x0C, 0x46, 0xFC, 0xF7, 0xA2, 0xFF, 0x00, 0x28, 0x00, 0xD0,
+ 0x84, 0x77, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x1E, 0x46, 0x15, 0x46,
+ 0x0F, 0x46, 0x14, 0x1D, 0xDD, 0xF8, 0x18, 0x80, 0xFC, 0xF7, 0xB0, 0xFE,
+ 0x00, 0x28, 0x0E, 0xD0, 0x4F, 0xF4, 0xAA, 0x71, 0x69, 0x80, 0x20, 0x80,
+ 0x67, 0x80, 0x0C, 0x3E, 0xA4, 0xF8, 0x04, 0x80, 0xE6, 0x80, 0x28, 0x46,
+ 0xBD, 0xE8, 0xF0, 0x41, 0x00, 0x21, 0x01, 0xF0, 0x79, 0xB8, 0xBD, 0xE8,
+ 0xF0, 0x81, 0x2D, 0xE9, 0xF0, 0x41, 0x8C, 0xB0, 0x1C, 0x46, 0x15, 0x46,
+ 0x0E, 0x46, 0x07, 0x46, 0xDD, 0xF8, 0x48, 0x80, 0xFC, 0xF7, 0xA0, 0xFE,
+ 0x4F, 0xF4, 0xB9, 0x71, 0xAD, 0xF8, 0x04, 0x70, 0xAD, 0xF8, 0x08, 0x50,
+ 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x06, 0x60, 0xAD, 0xF8, 0x0A, 0x40,
+ 0xAD, 0xF8, 0x0C, 0x80, 0x30, 0xB1, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0,
+ 0x59, 0xF8, 0x0C, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x01, 0x22, 0x69, 0x46,
+ 0x38, 0x46, 0xFC, 0xF7, 0xCB, 0xFE, 0xF6, 0xE7, 0x00, 0xB5, 0x8D, 0xB0,
+ 0x40, 0xF2, 0x53, 0x13, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10,
+ 0xAD, 0xF8, 0x02, 0x30, 0xAD, 0xF8, 0x08, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0x01, 0xF0, 0x40, 0xF8, 0x0D, 0xB0, 0x00, 0xBD, 0x2D, 0xE9, 0xF0, 0x47,
+ 0x07, 0x46, 0x16, 0x48, 0xDD, 0xE9, 0x08, 0x98, 0x1C, 0x46, 0x15, 0x46,
+ 0x0E, 0x46, 0x40, 0xF2, 0x34, 0x73, 0x11, 0x4A, 0x14, 0x21, 0x00, 0x78,
+ 0xFB, 0xF7, 0x4A, 0xFD, 0x00, 0x28, 0x18, 0xD0, 0x40, 0xF2, 0x81, 0x11,
+ 0x41, 0x80, 0x86, 0x72, 0x87, 0x74, 0x80, 0xF8, 0x13, 0x80, 0x44, 0x74,
+ 0x29, 0x68, 0x41, 0x60, 0xA9, 0x88, 0x01, 0x81, 0xD9, 0xF8, 0x00, 0x20,
+ 0xC0, 0xF8, 0x0B, 0x20, 0xB9, 0xF8, 0x04, 0x10, 0xA0, 0xF8, 0x0F, 0x10,
+ 0xBD, 0xE8, 0xF0, 0x47, 0x00, 0x21, 0x01, 0xF0, 0x13, 0xB8, 0xBD, 0xE8,
+ 0xF0, 0x87, 0x00, 0x00, 0x26, 0xAF, 0x82, 0x00, 0x03, 0x74, 0x20, 0x00,
+ 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0x98, 0x71, 0xAD, 0xF8, 0x00, 0x10,
+ 0xAD, 0xF8, 0x04, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xA8, 0xFF,
+ 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x2F, 0x12,
+ 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xF0, 0xFF, 0x0D, 0xB0, 0x00, 0xBD,
+ 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x2D, 0x12, 0xAD, 0xF8, 0x04, 0x00,
+ 0x8D, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x00, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0x88, 0xFF, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0,
+ 0x4F, 0xF4, 0x97, 0x73, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10,
+ 0xAD, 0xF8, 0x02, 0x30, 0xAD, 0xF8, 0x08, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0xCE, 0xFF, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0,
+ 0x4F, 0xF4, 0xDA, 0x70, 0xAD, 0xF8, 0x00, 0x00, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0x6A, 0xFF, 0x11, 0xB0, 0x00, 0xBD, 0x10, 0xB5, 0x92, 0xB0,
+ 0x04, 0x46, 0x0C, 0xA8, 0x08, 0xF0, 0x14, 0xFB, 0xAD, 0xF8, 0x04, 0x40,
+ 0xBD, 0xF8, 0x44, 0x00, 0xAD, 0xF8, 0x06, 0x00, 0x40, 0xF2, 0xB5, 0x11,
+ 0x9D, 0xF8, 0x40, 0x00, 0xAD, 0xF8, 0x02, 0x10, 0x8D, 0xF8, 0x08, 0x00,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xA8, 0xFF, 0x12, 0xB0, 0x10, 0xBD,
+ 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x93, 0x13, 0x8D, 0xF8, 0x04, 0x00,
+ 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8, 0x00, 0x30, 0x8D, 0xF8, 0x06, 0x20,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x3E, 0xFF, 0x11, 0xB0, 0x00, 0xBD,
+ 0x10, 0xB5, 0x90, 0xB0, 0x40, 0xF2, 0x95, 0x14, 0x8D, 0xF8, 0x04, 0x00,
+ 0x8D, 0xF8, 0x05, 0x10, 0x8D, 0xF8, 0x06, 0x20, 0xAD, 0xF8, 0x00, 0x40,
+ 0x8D, 0xF8, 0x07, 0x30, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x2A, 0xFF,
+ 0x10, 0xB0, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x43, 0x91, 0xB0, 0x1D, 0x46,
+ 0xDD, 0xE9, 0x18, 0x49, 0x16, 0x46, 0x0F, 0x46, 0x80, 0x46, 0xFB, 0x2C,
+ 0x06, 0xD9, 0x23, 0x46, 0x01, 0x22, 0x16, 0x49, 0x16, 0x48, 0xF3, 0xF7,
+ 0xF6, 0xDE, 0xFB, 0x24, 0x40, 0xF2, 0x87, 0x10, 0x8D, 0xF8, 0x04, 0x80,
+ 0xAD, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x05, 0x70, 0x8D, 0xF8, 0x06, 0x60,
+ 0x00, 0x20, 0x8D, 0xF8, 0x07, 0x50, 0x8D, 0xF8, 0x08, 0x40, 0x03, 0x90,
+ 0x74, 0xB1, 0x0E, 0x48, 0x40, 0xF6, 0x49, 0x03, 0x0B, 0x4A, 0x21, 0x46,
+ 0x00, 0x78, 0xFB, 0xF7, 0x71, 0xFC, 0x03, 0x90, 0x00, 0x28, 0x07, 0xD0,
+ 0x22, 0x46, 0x49, 0x46, 0x25, 0xF4, 0xE9, 0xF7, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0xF2, 0xFE, 0x11, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x00, 0x00,
+ 0x74, 0x52, 0xC0, 0x08, 0x01, 0x37, 0x10, 0x21, 0x70, 0xAE, 0x82, 0x00,
+ 0x02, 0x74, 0x20, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xC4, 0x72,
+ 0x8D, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x30, 0xFF, 0x0D, 0xB0, 0x00, 0xBD,
+ 0x00, 0xB5, 0x91, 0xB0, 0x13, 0x46, 0x04, 0x29, 0x02, 0xD9, 0x00, 0x20,
+ 0x11, 0xB0, 0x00, 0xBD, 0x40, 0xF2, 0x89, 0x12, 0x8D, 0xF8, 0x04, 0x00,
+ 0xAD, 0xF8, 0x00, 0x20, 0x8D, 0xF8, 0x05, 0x10, 0x39, 0xB1, 0x01, 0xEB,
+ 0x41, 0x00, 0x42, 0x00, 0x19, 0x46, 0x0D, 0xF1, 0x06, 0x00, 0x25, 0xF4,
+ 0xB0, 0xF7, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xB9, 0xFE, 0xE7, 0xE7,
+ 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xC5, 0x72, 0x8D, 0xF8, 0x04, 0x00,
+ 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0x02, 0xFF, 0x0D, 0xB0, 0x00, 0xBD, 0x2D, 0xE9, 0xF0, 0x4F,
+ 0x91, 0xB0, 0x40, 0xF2, 0x85, 0x18, 0xDD, 0xE9, 0x1E, 0xEB, 0xDD, 0xE9,
+ 0x1C, 0x64, 0xDD, 0xE9, 0x20, 0x95, 0xDD, 0xE9, 0x1A, 0xC7, 0xDD, 0xF8,
+ 0x8C, 0xA0, 0xAD, 0xF8, 0x00, 0x80, 0x04, 0xB9, 0x14, 0x4C, 0x8D, 0xF8,
+ 0x04, 0x00, 0x8D, 0xF8, 0x10, 0xC0, 0xAD, 0xF8, 0x06, 0x10, 0x8D, 0xF8,
+ 0x11, 0x70, 0xCD, 0xE9, 0x02, 0x23, 0x8D, 0xF8, 0x12, 0x60, 0x20, 0x68,
+ 0xCD, 0xF8, 0x13, 0x00, 0xA0, 0x88, 0xAD, 0xF8, 0x17, 0x00, 0x8D, 0xF8,
+ 0x19, 0xE0, 0x8D, 0xF8, 0x1C, 0x50, 0x22, 0x98, 0x8D, 0xF8, 0x1A, 0xB0,
+ 0x8D, 0xF8, 0x1D, 0x00, 0x8D, 0xF8, 0x1B, 0x90, 0x8D, 0xF8, 0x1E, 0xA0,
+ 0x24, 0x98, 0x8D, 0xF8, 0x1F, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0,
+ 0x6F, 0xFE, 0x11, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x8A, 0xAD, 0x82, 0x00,
+ 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xC3, 0x72, 0x8D, 0xF8, 0x04, 0x10,
+ 0xAD, 0xF8, 0x06, 0x00, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0xB4, 0xFE, 0x0D, 0xB0, 0x00, 0xBD, 0x2D, 0xE9, 0xF0, 0x5F,
+ 0x2B, 0x4E, 0x9A, 0x46, 0x17, 0x46, 0x88, 0x46, 0x81, 0x46, 0x40, 0xF2,
+ 0x91, 0x73, 0x27, 0x4A, 0x24, 0x21, 0x30, 0x78, 0xDD, 0xF8, 0x40, 0xB0,
+ 0x12, 0x9D, 0xFB, 0xF7, 0xBD, 0xFB, 0x04, 0x00, 0x41, 0xD0, 0x4F, 0xF4,
+ 0xD6, 0x70, 0x60, 0x80, 0xA4, 0xF8, 0x04, 0x90, 0x84, 0xF8, 0x06, 0x80,
+ 0xE7, 0x71, 0xDA, 0xF8, 0x00, 0x10, 0xA1, 0x60, 0xBA, 0xF8, 0x04, 0x00,
+ 0xA0, 0x81, 0x0A, 0x98, 0xA0, 0x73, 0x0B, 0x98, 0xE0, 0x73, 0x0C, 0x98,
+ 0x20, 0x74, 0x0D, 0x98, 0x60, 0x74, 0x0E, 0x98, 0xA0, 0x74, 0x0F, 0x98,
+ 0xA0, 0x82, 0x84, 0xF8, 0x16, 0xB0, 0x11, 0x98, 0x01, 0x68, 0xC4, 0xF8,
+ 0x17, 0x10, 0x80, 0x88, 0xA4, 0xF8, 0x1B, 0x00, 0x65, 0x77, 0x00, 0x20,
+ 0x20, 0x62, 0x65, 0xB1, 0x40, 0xF2, 0xA9, 0x73, 0x0D, 0x4A, 0x29, 0x46,
+ 0x30, 0x78, 0xFB, 0xF7, 0x8D, 0xFB, 0x20, 0x62, 0x48, 0xB1, 0x2A, 0x46,
+ 0x13, 0x99, 0x25, 0xF4, 0x06, 0xF7, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x5F,
+ 0x00, 0x21, 0x00, 0xF0, 0x65, 0xBE, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x5F,
+ 0x40, 0xF2, 0xAD, 0x72, 0x02, 0x49, 0xFB, 0xF7, 0x67, 0xBC, 0xBD, 0xE8,
+ 0xF0, 0x9F, 0x00, 0x00, 0x3E, 0xAF, 0x82, 0x00, 0x03, 0x74, 0x20, 0x00,
+ 0x70, 0xB5, 0x04, 0x46, 0x0F, 0x48, 0x0D, 0x46, 0x40, 0x69, 0x05, 0xE0,
+ 0x01, 0x79, 0xA1, 0x42, 0x01, 0xD1, 0x45, 0x71, 0x70, 0xBD, 0x00, 0x68,
+ 0x00, 0x28, 0xF7, 0xD1, 0x0B, 0x48, 0x40, 0xF2, 0x0B, 0x43, 0x09, 0x4A,
+ 0x10, 0x21, 0x00, 0x78, 0xFB, 0xF7, 0x5C, 0xFB, 0x01, 0x00, 0xF1, 0xD0,
+ 0x0C, 0x71, 0x4D, 0x71, 0x00, 0x20, 0x88, 0x81, 0xBD, 0xE8, 0x70, 0x40,
+ 0x01, 0x48, 0x14, 0x30, 0xFE, 0xF7, 0x19, 0x9D, 0xD0, 0x77, 0x20, 0x00,
+ 0x4A, 0xB0, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x70, 0xB5, 0x04, 0x46,
+ 0x14, 0x48, 0x0D, 0x46, 0x40, 0x69, 0x09, 0xE0, 0x01, 0x79, 0xA1, 0x42,
+ 0x05, 0xD1, 0x29, 0x68, 0xC0, 0xF8, 0x06, 0x10, 0xA9, 0x88, 0x41, 0x81,
+ 0x70, 0xBD, 0x00, 0x68, 0x00, 0x28, 0xF3, 0xD1, 0x0E, 0x48, 0x40, 0xF2,
+ 0xEB, 0x33, 0x0C, 0x4A, 0x10, 0x21, 0x00, 0x78, 0xFB, 0xF7, 0x30, 0xFB,
+ 0x01, 0x00, 0xF1, 0xD0, 0x0C, 0x71, 0x01, 0x20, 0x48, 0x71, 0x28, 0x68,
+ 0xC1, 0xF8, 0x06, 0x00, 0xA8, 0x88, 0x48, 0x81, 0x00, 0x20, 0x88, 0x81,
+ 0xBD, 0xE8, 0x70, 0x40, 0x01, 0x48, 0x14, 0x30, 0xFE, 0xF7, 0xE7, 0x9C,
+ 0xD0, 0x77, 0x20, 0x00, 0x25, 0xB0, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00,
+ 0x10, 0xB5, 0x90, 0xB0, 0x40, 0xF2, 0x8B, 0x14, 0x8D, 0xF8, 0x04, 0x00,
+ 0x8D, 0xF8, 0x05, 0x10, 0x8D, 0xF8, 0x06, 0x20, 0x02, 0xF0, 0x05, 0x00,
+ 0xAD, 0xF8, 0x00, 0x40, 0x00, 0x22, 0x03, 0xE0, 0x52, 0x1C, 0x41, 0x1E,
+ 0xD2, 0xB2, 0x08, 0x40, 0x00, 0x28, 0xF9, 0xD1, 0x02, 0xEB, 0x42, 0x00,
+ 0x42, 0x00, 0x19, 0x46, 0x02, 0xA8, 0x25, 0xF4, 0x7A, 0xF6, 0x01, 0x21,
+ 0x68, 0x46, 0x00, 0xF0, 0x83, 0xFD, 0x10, 0xB0, 0x10, 0xBD, 0x00, 0xB5,
+ 0x8D, 0xB0, 0x4F, 0xF4, 0xC6, 0x71, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8,
+ 0x04, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xCD, 0xFD, 0x0D, 0xB0,
+ 0x00, 0xBD, 0x10, 0xB5, 0x90, 0xB0, 0x40, 0xF2, 0x8D, 0x14, 0x8D, 0xF8,
+ 0x04, 0x00, 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8, 0x00, 0x40, 0xAD, 0xF8,
+ 0x06, 0x20, 0xAD, 0xF8, 0x08, 0x30, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0,
+ 0x61, 0xFD, 0x10, 0xB0, 0x10, 0xBD, 0x11, 0xF0, 0xC5, 0xBD, 0x00, 0x00,
+ 0x01, 0x48, 0x00, 0x7C, 0x70, 0x47, 0x00, 0x00, 0xD0, 0x77, 0x20, 0x00,
+ 0x01, 0x48, 0x40, 0x7C, 0x70, 0x47, 0x00, 0x00, 0xD0, 0x77, 0x20, 0x00,
+ 0x10, 0xB5, 0x08, 0x4A, 0x00, 0x24, 0x52, 0x69, 0x07, 0xE0, 0x93, 0x89,
+ 0x83, 0x42, 0x03, 0xD1, 0x50, 0x79, 0x08, 0x70, 0x01, 0x24, 0x02, 0xE0,
+ 0x12, 0x68, 0x00, 0x2A, 0xF5, 0xD1, 0x20, 0x46, 0x10, 0xBD, 0x00, 0x00,
+ 0xD0, 0x77, 0x20, 0x00, 0x01, 0x46, 0x07, 0x48, 0x00, 0x23, 0x40, 0x69,
+ 0x05, 0xE0, 0x82, 0x89, 0x8A, 0x42, 0x01, 0xD1, 0x83, 0x1D, 0x02, 0xE0,
+ 0x00, 0x68, 0x00, 0x28, 0xF7, 0xD1, 0x18, 0x46, 0x70, 0x47, 0x00, 0x00,
+ 0xD0, 0x77, 0x20, 0x00, 0x00, 0xB5, 0x93, 0xB0, 0x40, 0xF2, 0xB3, 0x10,
+ 0xAD, 0xF8, 0x02, 0x00, 0x0C, 0xA8, 0x08, 0xF0, 0xD3, 0xF8, 0xDD, 0xF8,
+ 0x36, 0x00, 0x01, 0x90, 0xDD, 0xF8, 0x3A, 0x00, 0x02, 0x90, 0x11, 0x48,
+ 0x01, 0x21, 0x00, 0x78, 0xAD, 0xF8, 0x0C, 0x00, 0x1C, 0x20, 0xAD, 0xF8,
+ 0x0E, 0x00, 0x0E, 0x48, 0x90, 0xF8, 0xAB, 0x01, 0x8D, 0xF8, 0x10, 0x00,
+ 0x9D, 0xF8, 0x3F, 0x00, 0x8D, 0xF8, 0x11, 0x00, 0x9D, 0xF8, 0x3E, 0x00,
+ 0x8D, 0xF8, 0x12, 0x00, 0x9D, 0xF8, 0x41, 0x00, 0x8D, 0xF8, 0x13, 0x00,
+ 0x9D, 0xF8, 0x42, 0x00, 0x8D, 0xF8, 0x14, 0x00, 0x68, 0x46, 0x00, 0xF0,
+ 0x53, 0xFD, 0x13, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0x06, 0x74, 0x20, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x9D, 0x12,
+ 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8, 0x00, 0x20,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xE6, 0xFC, 0x11, 0xB0, 0x00, 0xBD,
+ 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xCF, 0x72, 0x8D, 0xF8, 0x04, 0x00,
+ 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0x2E, 0xFD, 0x0D, 0xB0, 0x00, 0xBD, 0x30, 0xB5, 0x91, 0xB0,
+ 0x40, 0xF2, 0x73, 0x14, 0x14, 0x9D, 0xAD, 0xF8, 0x00, 0x40, 0x8D, 0xF8,
+ 0x04, 0x00, 0x8D, 0xF8, 0x05, 0x10, 0x00, 0x24, 0x32, 0xB1, 0x10, 0x68,
+ 0xCD, 0xF8, 0x06, 0x00, 0x90, 0x88, 0xAD, 0xF8, 0x0A, 0x00, 0x03, 0xE0,
+ 0xCD, 0xF8, 0x06, 0x40, 0xAD, 0xF8, 0x0A, 0x40, 0x2B, 0xB1, 0x10, 0x22,
+ 0x19, 0x46, 0x03, 0xA8, 0x25, 0xF4, 0xA9, 0xF5, 0x03, 0xE0, 0x03, 0x94,
+ 0x04, 0x94, 0x05, 0x94, 0x06, 0x94, 0x2D, 0xB1, 0x10, 0x22, 0x29, 0x46,
+ 0x07, 0xA8, 0x25, 0xF4, 0x9E, 0xF5, 0x03, 0xE0, 0x07, 0x94, 0x08, 0x94,
+ 0x09, 0x94, 0x0A, 0x94, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xA2, 0xFC,
+ 0x11, 0xB0, 0x30, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xBA, 0x72,
+ 0x8D, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xEA, 0xFC, 0x0D, 0xB0, 0x00, 0xBD,
+ 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0x9E, 0x73, 0xAD, 0xF8, 0x00, 0x30,
+ 0x01, 0xB9, 0x08, 0x49, 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x0B, 0x20,
+ 0x08, 0x68, 0xCD, 0xF8, 0x05, 0x00, 0x88, 0x88, 0xAD, 0xF8, 0x09, 0x00,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x7A, 0xFC, 0x11, 0xB0, 0x00, 0xBD,
+ 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x3D, 0x12,
+ 0x8D, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xC0, 0xFC, 0x0D, 0xB0, 0x00, 0xBD,
+ 0xF0, 0xB5, 0x07, 0x46, 0x8D, 0xB0, 0x1D, 0x46, 0x16, 0x46, 0x0C, 0x46,
+ 0x08, 0x46, 0xFC, 0xF7, 0xE9, 0xFA, 0x40, 0xF2, 0xAB, 0x11, 0xAD, 0xF8,
+ 0x04, 0x70, 0x8D, 0xF8, 0x08, 0x60, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8,
+ 0x06, 0x40, 0x8D, 0xF8, 0x09, 0x50, 0x28, 0xB1, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0xA4, 0xFC, 0x0D, 0xB0, 0xF0, 0xBD, 0x01, 0x22, 0x69, 0x46,
+ 0x20, 0x46, 0xFC, 0xF7, 0x17, 0xFB, 0xF7, 0xE7, 0x00, 0xB5, 0x8D, 0xB0,
+ 0x40, 0xF2, 0x59, 0x11, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x04, 0x00,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x90, 0xFC, 0x0D, 0xB0, 0x00, 0xBD,
+ 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0xB3, 0x70, 0xAD, 0xF8, 0x00, 0x00,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x2C, 0xFC, 0x11, 0xB0, 0x00, 0xBD,
+ 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x67, 0x12, 0xAD, 0xF8, 0x04, 0x00,
+ 0x8D, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0x74, 0xFC, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0,
+ 0x4F, 0xF4, 0xAF, 0x71, 0xAD, 0xF8, 0x00, 0x10, 0xAD, 0xF8, 0x04, 0x00,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x0E, 0xFC, 0x11, 0xB0, 0x00, 0xBD,
+ 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x5F, 0x13, 0xAD, 0xF8, 0x04, 0x00,
+ 0xAD, 0xF8, 0x02, 0x30, 0xAD, 0xF8, 0x06, 0x10, 0x2A, 0xB1, 0x21, 0xB9,
+ 0x10, 0x68, 0x02, 0x90, 0x10, 0x79, 0x8D, 0xF8, 0x0C, 0x00, 0x01, 0x21,
+ 0x68, 0x46, 0x00, 0xF0, 0x4F, 0xFC, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0x00,
+ 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x77, 0x12, 0xAD, 0xF8, 0x00, 0x20,
+ 0x8D, 0xF8, 0x04, 0x00, 0x01, 0xB9, 0x06, 0x49, 0x08, 0x68, 0xCD, 0xF8,
+ 0x05, 0x00, 0x88, 0x88, 0xAD, 0xF8, 0x09, 0x00, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0xE0, 0xFB, 0x11, 0xB0, 0x00, 0xBD, 0x8A, 0xAD, 0x82, 0x00,
+ 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xBC, 0x72, 0xAD, 0xF8, 0x02, 0x20,
+ 0xAD, 0xF8, 0x04, 0x00, 0x08, 0x68, 0xCD, 0xF8, 0x06, 0x00, 0x88, 0x88,
+ 0xAD, 0xF8, 0x0A, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x22, 0xFC,
+ 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x75, 0x12,
+ 0xAD, 0xF8, 0x00, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x01, 0xB9, 0x06, 0x49,
+ 0x08, 0x68, 0xCD, 0xF8, 0x05, 0x00, 0x88, 0x88, 0xAD, 0xF8, 0x09, 0x00,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xB4, 0xFB, 0x11, 0xB0, 0x00, 0xBD,
+ 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xBB, 0x72,
+ 0xAD, 0xF8, 0x02, 0x20, 0xAD, 0xF8, 0x04, 0x00, 0x08, 0x68, 0xCD, 0xF8,
+ 0x06, 0x00, 0x88, 0x88, 0xAD, 0xF8, 0x0A, 0x00, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0xF6, 0xFB, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0,
+ 0x40, 0xF2, 0x99, 0x10, 0xAD, 0xF8, 0x00, 0x00, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0x92, 0xFB, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0,
+ 0x4F, 0xF4, 0xCD, 0x73, 0xAD, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x07, 0x10,
+ 0xAD, 0xF8, 0x02, 0x30, 0x8D, 0xF8, 0x06, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0xD8, 0xFB, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0,
+ 0x4F, 0xF4, 0xB0, 0x71, 0xAD, 0xF8, 0x00, 0x10, 0x8D, 0xF8, 0x04, 0x00,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x72, 0xFB, 0x11, 0xB0, 0x00, 0xBD,
+ 0x70, 0xB5, 0x8C, 0xB0, 0x0E, 0x46, 0x05, 0x46, 0x07, 0xF0, 0x3C, 0xFF,
+ 0x04, 0x46, 0x28, 0x46, 0xFC, 0xF7, 0xF2, 0xF9, 0x4F, 0xF4, 0xDB, 0x71,
+ 0xAD, 0xF8, 0x06, 0x50, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x04, 0x60,
+ 0x1C, 0xB1, 0x21, 0x68, 0x02, 0x91, 0x61, 0x68, 0x03, 0x91, 0x28, 0xB1,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xAC, 0xFB, 0x0C, 0xB0, 0x70, 0xBD,
+ 0x01, 0x22, 0x69, 0x46, 0x28, 0x46, 0xFC, 0xF7, 0x1F, 0xFA, 0xF7, 0xE7,
+ 0x0C, 0x49, 0x10, 0xB5, 0x4C, 0x69, 0x03, 0xE0, 0x21, 0x79, 0x81, 0x42,
+ 0x03, 0xD0, 0x24, 0x68, 0x00, 0x2C, 0xF9, 0xD1, 0x10, 0xBD, 0x00, 0x2C,
+ 0xFC, 0xD0, 0x06, 0x48, 0x21, 0x46, 0x14, 0x30, 0xFE, 0xF7, 0xC3, 0xDA,
+ 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x40, 0xF2, 0x29, 0x42, 0x02, 0x49,
+ 0xFB, 0xF7, 0x94, 0xB9, 0xD0, 0x77, 0x20, 0x00, 0x73, 0xB0, 0x82, 0x00,
+ 0x30, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x39, 0x15, 0x8D, 0xF8, 0x04, 0x00,
+ 0x14, 0x9C, 0xAD, 0xF8, 0x08, 0x20, 0xAD, 0xF8, 0x06, 0x10, 0x8D, 0xF8,
+ 0x0A, 0x30, 0xAD, 0xF8, 0x00, 0x50, 0x8D, 0xF8, 0x0B, 0x40, 0x01, 0x21,
+ 0x68, 0x46, 0x00, 0xF0, 0x19, 0xFB, 0x11, 0xB0, 0x30, 0xBD, 0x00, 0xB5,
+ 0x91, 0xB0, 0x40, 0xF2, 0x37, 0x12, 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8,
+ 0x05, 0x10, 0xAD, 0xF8, 0x00, 0x20, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0,
+ 0x09, 0xFB, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0x70, 0xB5, 0x06, 0x46,
+ 0x0E, 0x48, 0x14, 0x46, 0x0D, 0x46, 0x40, 0xF6, 0x1B, 0x03, 0x0B, 0x4A,
+ 0x0C, 0x21, 0x00, 0x78, 0xFB, 0xF7, 0x6E, 0xF8, 0x00, 0x28, 0x0E, 0xD0,
+ 0x4F, 0xF4, 0xD9, 0x71, 0x41, 0x80, 0x06, 0x71, 0x45, 0x71, 0x21, 0x68,
+ 0xC0, 0xF8, 0x06, 0x10, 0xA1, 0x88, 0x41, 0x81, 0xBD, 0xE8, 0x70, 0x40,
+ 0x00, 0x21, 0x00, 0xF0, 0x41, 0xBB, 0x70, 0xBD, 0x5A, 0xAF, 0x82, 0x00,
+ 0x03, 0x74, 0x20, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0x9C, 0x71,
+ 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x04, 0x00, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0x30, 0xFB, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0,
+ 0x4F, 0xF4, 0xA8, 0x73, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10,
+ 0xAD, 0xF8, 0x00, 0x30, 0xAD, 0xF8, 0x08, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0xC6, 0xFA, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0,
+ 0x40, 0xF2, 0x51, 0x13, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10,
+ 0xAD, 0xF8, 0x02, 0x30, 0xAD, 0xF8, 0x08, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0x0C, 0xFB, 0x0D, 0xB0, 0x00, 0xBD, 0x01, 0x49, 0x08, 0x74,
+ 0x70, 0x47, 0x00, 0x00, 0xD0, 0x77, 0x20, 0x00, 0x00, 0xB5, 0x91, 0xB0,
+ 0x40, 0xF2, 0x83, 0x12, 0xAD, 0xF8, 0x00, 0x20, 0x00, 0x28, 0x0B, 0xD0,
+ 0x8D, 0xF8, 0x04, 0x10, 0x01, 0x68, 0xCD, 0xF8, 0x05, 0x10, 0x80, 0x88,
+ 0xAD, 0xF8, 0x09, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x98, 0xFA,
+ 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xC2, 0x73,
+ 0xAD, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x30,
+ 0x10, 0x68, 0xCD, 0xF8, 0x07, 0x00, 0x90, 0x88, 0xAD, 0xF8, 0x0B, 0x00,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xDA, 0xFA, 0x0D, 0xB0, 0x00, 0xBD,
+ 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0xAE, 0x71, 0xAD, 0xF8, 0x00, 0x10,
+ 0x01, 0x68, 0x01, 0x91, 0x00, 0x79, 0x8D, 0xF8, 0x08, 0x00, 0x01, 0x21,
+ 0x68, 0x46, 0x00, 0xF0, 0x71, 0xFA, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5,
+ 0x91, 0xB0, 0x4F, 0xF4, 0xB8, 0x73, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8,
+ 0x06, 0x10, 0xAD, 0xF8, 0x00, 0x30, 0xAD, 0xF8, 0x08, 0x20, 0x01, 0x21,
+ 0x68, 0x46, 0x00, 0xF0, 0x5F, 0xFA, 0x11, 0xB0, 0x00, 0xBD, 0x30, 0xB5,
+ 0x05, 0x46, 0x8D, 0xB0, 0x0C, 0x46, 0x08, 0x46, 0xFC, 0xF7, 0xE2, 0xF8,
+ 0x40, 0xF2, 0x71, 0x11, 0xAD, 0xF8, 0x04, 0x50, 0xAD, 0xF8, 0x02, 0x10,
+ 0xAD, 0xF8, 0x06, 0x40, 0x28, 0xB1, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0,
+ 0xA1, 0xFA, 0x0D, 0xB0, 0x30, 0xBD, 0x01, 0x22, 0x69, 0x46, 0x20, 0x46,
+ 0xFC, 0xF7, 0x14, 0xF9, 0xF7, 0xE7, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2,
+ 0x8F, 0x13, 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8,
+ 0x00, 0x30, 0x8D, 0xF8, 0x06, 0x20, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0,
+ 0x31, 0xFA, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0x01, 0x49, 0x48, 0x74,
+ 0x70, 0x47, 0x00, 0x00, 0xD0, 0x77, 0x20, 0x00, 0x30, 0xB5, 0x91, 0xB0,
+ 0x40, 0xF2, 0x91, 0x15, 0xAD, 0xF8, 0x04, 0x00, 0x14, 0x9C, 0x8D, 0xF8,
+ 0x06, 0x10, 0x8D, 0xF8, 0x08, 0x30, 0xAD, 0xF8, 0x00, 0x50, 0x8D, 0xF8,
+ 0x07, 0x20, 0x8D, 0xF8, 0x09, 0x40, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0,
+ 0x13, 0xFA, 0x11, 0xB0, 0x30, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4,
+ 0xC9, 0x72, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8,
+ 0x02, 0x20, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x5B, 0xFA, 0x0D, 0xB0,
+ 0x00, 0xBD, 0x00, 0x00, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x7F, 0x13,
+ 0xAD, 0xF8, 0x00, 0x30, 0x8D, 0xF8, 0x04, 0x00, 0x01, 0xB9, 0x07, 0x49,
+ 0x08, 0x68, 0xCD, 0xF8, 0x05, 0x00, 0x88, 0x88, 0xAD, 0xF8, 0x09, 0x00,
+ 0x8D, 0xF8, 0x0B, 0x20, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xEA, 0xF9,
+ 0x11, 0xB0, 0x00, 0xBD, 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x91, 0xB0,
+ 0x4F, 0xF4, 0xB4, 0x71, 0xAD, 0xF8, 0x00, 0x10, 0x00, 0x28, 0x08, 0xD0,
+ 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21,
+ 0x68, 0x46, 0x00, 0xF0, 0xD5, 0xF9, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5,
+ 0x91, 0xB0, 0x40, 0xF2, 0x79, 0x11, 0xAD, 0xF8, 0x00, 0x10, 0x8D, 0xF8,
+ 0x04, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xC7, 0xF9, 0x11, 0xB0,
+ 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x7B, 0x11, 0xAD, 0xF8,
+ 0x00, 0x10, 0xAD, 0xF8, 0x04, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0,
+ 0xB9, 0xF9, 0x11, 0xB0, 0x00, 0xBD, 0x2D, 0xE9, 0xF0, 0x43, 0x80, 0x46,
+ 0x8D, 0xB0, 0x17, 0x46, 0x0E, 0x46, 0x08, 0x46, 0xFC, 0xF7, 0x10, 0xF9,
+ 0x04, 0x00, 0x4F, 0xF4, 0xDC, 0x70, 0xAD, 0xF8, 0x02, 0x00, 0x19, 0xD0,
+ 0x20, 0x7D, 0x0B, 0x28, 0x16, 0xD1, 0x04, 0xF1, 0x16, 0x00, 0x61, 0x7D,
+ 0x81, 0x46, 0x11, 0xF0, 0x0D, 0xFB, 0x05, 0x46, 0x61, 0x7D, 0x48, 0x46,
+ 0x11, 0xF0, 0xF6, 0xFA, 0xAD, 0xF8, 0x04, 0x60, 0x8D, 0xF8, 0x08, 0x70,
+ 0xCD, 0xE9, 0x03, 0x05, 0xAD, 0xF8, 0x06, 0x80, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0xE6, 0xF9, 0x0D, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x00, 0xB5,
+ 0x91, 0xB0, 0x4F, 0xF4, 0xB2, 0x70, 0xAD, 0xF8, 0x00, 0x00, 0x01, 0x21,
+ 0x68, 0x46, 0x00, 0xF0, 0x81, 0xF9, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5,
+ 0x8D, 0xB0, 0x40, 0xF2, 0x65, 0x12, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8,
+ 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0,
+ 0xC9, 0xF9, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4,
+ 0xB1, 0x73, 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8,
+ 0x00, 0x30, 0x8D, 0xF8, 0x06, 0x20, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0,
+ 0x5F, 0xF9, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0x05, 0x4A, 0x52, 0x69,
+ 0x05, 0xE0, 0x13, 0x79, 0x83, 0x42, 0x01, 0xD1, 0x91, 0x81, 0x70, 0x47,
+ 0x12, 0x68, 0x00, 0x2A, 0xF7, 0xD1, 0x70, 0x47, 0xD0, 0x77, 0x20, 0x00,
+ 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0xB7, 0x72, 0xAD, 0xF8, 0x04, 0x00,
+ 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x00, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0x40, 0xF9, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0,
+ 0x40, 0xF2, 0x6F, 0x11, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x04, 0x00,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x8A, 0xF9, 0x0D, 0xB0, 0x00, 0xBD,
+ 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x9B, 0x12, 0x8D, 0xF8, 0x04, 0x00,
+ 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8, 0x00, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0x22, 0xF9, 0x11, 0xB0, 0x00, 0xBD, 0x10, 0xB5, 0x90, 0xB0,
+ 0x10, 0x24, 0x8D, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0x8D, 0xF8,
+ 0x08, 0x20, 0xAD, 0xF8, 0x00, 0x40, 0x8D, 0xF8, 0x09, 0x30, 0x01, 0x21,
+ 0x68, 0x46, 0x00, 0xF0, 0x0F, 0xF9, 0x10, 0xB0, 0x10, 0xBD, 0x00, 0xB5,
+ 0x8D, 0xB0, 0x12, 0x23, 0xAD, 0xF8, 0x02, 0x30, 0x03, 0x68, 0x01, 0x93,
+ 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x8D, 0xF8, 0x0A, 0x10, 0x8D, 0xF8,
+ 0x0B, 0x20, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x53, 0xF9, 0x0D, 0xB0,
+ 0x00, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x0F, 0x46, 0x04, 0x46,
+ 0xFC, 0xF7, 0x54, 0xF8, 0x05, 0x00, 0x07, 0xD0, 0xDF, 0xF8, 0x60, 0x80,
+ 0x40, 0xF2, 0x36, 0x39, 0x40, 0xF2, 0x39, 0x3A, 0x6C, 0x68, 0x21, 0xE0,
+ 0x23, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x13, 0x48, 0x01, 0x22, 0x13, 0x49,
+ 0x80, 0x1E, 0xF3, 0xF7, 0xBE, 0x98, 0x66, 0x68, 0x10, 0x49, 0x01, 0x22,
+ 0x73, 0x88, 0x40, 0x31, 0x40, 0x46, 0xF3, 0xF7, 0xB6, 0xD8, 0x27, 0xB1,
+ 0x00, 0x21, 0x30, 0x46, 0x00, 0xF0, 0x2A, 0xF9, 0x04, 0xE0, 0x4A, 0x46,
+ 0x0A, 0x49, 0x30, 0x46, 0xFA, 0xF7, 0x2E, 0xFF, 0x52, 0x46, 0x08, 0x49,
+ 0x20, 0x46, 0xFA, 0xF7, 0x29, 0xFF, 0x24, 0x68, 0x00, 0x2C, 0xE4, 0xD1,
+ 0x28, 0x1D, 0xBD, 0xE8, 0xF0, 0x47, 0xFD, 0xF7, 0xF7, 0x9F, 0x00, 0x00,
+ 0x02, 0x37, 0x10, 0x21, 0xE8, 0x53, 0xC0, 0x08, 0xF4, 0xAE, 0x82, 0x00,
+ 0x00, 0xB5, 0x91, 0xB0, 0x23, 0x22, 0xAD, 0xF8, 0x00, 0x20, 0x8D, 0xF8,
+ 0x0A, 0x10, 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xA8, 0xF8, 0x11, 0xB0, 0x00, 0xBD,
+ 0x70, 0xB5, 0x8C, 0xB0, 0x24, 0x26, 0xDD, 0xE9, 0x10, 0x45, 0xAD, 0xF8,
+ 0x0C, 0x00, 0xAD, 0xF8, 0x10, 0x40, 0xAD, 0xF8, 0x02, 0x60, 0x8D, 0xF8,
+ 0x0A, 0x20, 0x8D, 0xF8, 0x0E, 0x30, 0xAD, 0xF8, 0x12, 0x50, 0x08, 0x68,
+ 0x01, 0x90, 0x88, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0xE4, 0xF8, 0x0C, 0xB0, 0x70, 0xBD, 0x00, 0xB5, 0x91, 0xB0,
+ 0x0B, 0x22, 0xAD, 0xF8, 0x00, 0x20, 0x8D, 0xF8, 0x0A, 0x10, 0x01, 0x68,
+ 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46,
+ 0x00, 0xF0, 0x7A, 0xF8, 0x11, 0xB0, 0x00, 0xBD, 0x10, 0xB5, 0x8C, 0xB0,
+ 0x0C, 0x24, 0xAD, 0xF8, 0x0C, 0x00, 0xAD, 0xF8, 0x02, 0x40, 0x8D, 0xF8,
+ 0x0A, 0x20, 0x8D, 0xF8, 0x0E, 0x30, 0x08, 0x68, 0x01, 0x90, 0x88, 0x88,
+ 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xBC, 0xF8,
+ 0x0C, 0xB0, 0x10, 0xBD, 0x00, 0xB5, 0x91, 0xB0, 0x01, 0x21, 0x01, 0x90,
+ 0xAD, 0xF8, 0x00, 0x10, 0x68, 0x46, 0x00, 0xF0, 0x59, 0xF8, 0x11, 0xB0,
+ 0x00, 0xBD, 0x00, 0x00, 0x10, 0xB5, 0x04, 0x00, 0x0B, 0xD0, 0x23, 0x7D,
+ 0x01, 0x22, 0x05, 0x49, 0x05, 0x48, 0xF3, 0xF7, 0x2C, 0xD8, 0x20, 0x46,
+ 0xBD, 0xE8, 0x10, 0x40, 0x20, 0x21, 0x25, 0xF4, 0xDB, 0xB1, 0x10, 0xBD,
+ 0x98, 0x57, 0xC0, 0x08, 0x03, 0x37, 0x10, 0x21, 0x10, 0xB5, 0x90, 0xB0,
+ 0x14, 0x46, 0x40, 0xF2, 0x01, 0x12, 0xAD, 0xF8, 0x00, 0x20, 0x00, 0xB9,
+ 0x0B, 0x48, 0x04, 0xB9, 0x0A, 0x4C, 0x8D, 0xF8, 0x1B, 0x10, 0x8D, 0xF8,
+ 0x1A, 0x30, 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00,
+ 0x10, 0x22, 0x21, 0x46, 0x0D, 0xF1, 0x0A, 0x00, 0x25, 0xF4, 0x1B, 0xF1,
+ 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x24, 0xF8, 0x10, 0xB0, 0x10, 0xBD,
+ 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0x80, 0x72,
+ 0xAD, 0xF8, 0x02, 0x20, 0x8D, 0xF8, 0x0A, 0x10, 0x01, 0x68, 0x01, 0x91,
+ 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0,
+ 0x67, 0xF8, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0xAD, 0xF8,
+ 0x02, 0x00, 0xAD, 0xF8, 0x04, 0x10, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0,
+ 0x5B, 0xF8, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0x30, 0xB5, 0x87, 0xB0,
+ 0x0C, 0x46, 0x05, 0x46, 0xFB, 0xF7, 0x14, 0xF9, 0xC8, 0xB1, 0x28, 0x46,
+ 0xFC, 0xF7, 0x62, 0xFD, 0x03, 0x1D, 0x02, 0x22, 0x1F, 0x49, 0x20, 0x48,
+ 0x00, 0x95, 0xF2, 0xF7, 0xCE, 0xDF, 0xBC, 0xB1, 0x1F, 0x48, 0x4F, 0xF4,
+ 0xA8, 0x73, 0x1D, 0x4A, 0x40, 0x21, 0x00, 0x78, 0xFA, 0xF7, 0x5A, 0xFD,
+ 0x04, 0x00, 0x0A, 0xD0, 0x40, 0x22, 0x29, 0x46, 0x25, 0xF4, 0x18, 0xF1,
+ 0x09, 0xE0, 0x15, 0x49, 0x00, 0x22, 0x2C, 0x39, 0x17, 0x48, 0xF2, 0xF7,
+ 0xB8, 0xDF, 0x00, 0x20, 0x07, 0xB0, 0x30, 0xBD, 0x2C, 0x46, 0x4F, 0xF4,
+ 0x80, 0x70, 0xAD, 0xF8, 0x04, 0x00, 0x01, 0x20, 0xAD, 0xF8, 0x08, 0x00,
+ 0x00, 0x20, 0xAD, 0xF8, 0x0A, 0x00, 0x40, 0x20, 0xAD, 0xF8, 0x0C, 0x00,
+ 0x0E, 0x48, 0x04, 0x94, 0x4F, 0xF4, 0xB1, 0x73, 0x09, 0x4A, 0x01, 0xA9,
+ 0x00, 0x78, 0xFB, 0xF7, 0x39, 0xF8, 0x08, 0xB1, 0x01, 0x20, 0xE3, 0xE7,
+ 0x4F, 0xF4, 0xB2, 0x72, 0x04, 0x49, 0x04, 0x98, 0xFA, 0xF7, 0x18, 0xFE,
+ 0xDB, 0xE7, 0x00, 0x00, 0xFC, 0x4F, 0xC0, 0x08, 0x03, 0x3E, 0x11, 0x21,
+ 0xAA, 0xAD, 0x82, 0x00, 0x02, 0x74, 0x20, 0x00, 0x00, 0x37, 0x10, 0x21,
+ 0xCC, 0x77, 0x20, 0x00, 0xF8, 0xB5, 0x1B, 0x4E, 0x04, 0x46, 0x0D, 0x46,
+ 0x30, 0x7A, 0x36, 0x1D, 0xC8, 0xB1, 0x20, 0x46, 0xFC, 0xF7, 0x26, 0xFE,
+ 0x03, 0x1D, 0x02, 0x22, 0x16, 0x49, 0x17, 0x48, 0x00, 0x94, 0xF2, 0xF7,
+ 0x76, 0xDF, 0xB5, 0xB1, 0x16, 0x48, 0x4F, 0xF4, 0xD8, 0x73, 0x14, 0x4A,
+ 0x30, 0x21, 0x00, 0x78, 0xFA, 0xF7, 0x02, 0xFD, 0x05, 0x1E, 0x12, 0xD0,
+ 0x30, 0x22, 0x21, 0x46, 0x25, 0xF4, 0xC0, 0xF0, 0x08, 0xE0, 0x0C, 0x49,
+ 0x63, 0x88, 0x01, 0x22, 0x38, 0x39, 0x0E, 0x48, 0xF2, 0xF7, 0x5F, 0xDF,
+ 0x0C, 0xE0, 0x25, 0x46, 0x31, 0x68, 0x19, 0xB1, 0x28, 0x46, 0x88, 0x47,
+ 0x01, 0x20, 0xF8, 0xBD, 0x4F, 0xF4, 0xE3, 0x72, 0x05, 0x49, 0x28, 0x46,
+ 0xFA, 0xF7, 0xD4, 0xFD, 0x00, 0x20, 0xF8, 0xBD, 0xD0, 0x77, 0x20, 0x00,
+ 0xEC, 0x52, 0xC0, 0x08, 0x03, 0x3E, 0x12, 0x21, 0xA2, 0xAE, 0x82, 0x00,
+ 0x02, 0x74, 0x20, 0x00, 0x00, 0x37, 0x10, 0x21, 0x00, 0xB5, 0x91, 0xB0,
+ 0x21, 0x21, 0xAD, 0xF8, 0x00, 0x10, 0x8D, 0xF8, 0x04, 0x00, 0x01, 0x21,
+ 0x68, 0x46, 0xFF, 0xF7, 0x59, 0xFF, 0x11, 0xB0, 0x00, 0xBD, 0x10, 0xB5,
+ 0x04, 0x00, 0x01, 0xD1, 0x05, 0xF0, 0x50, 0xFC, 0x21, 0x46, 0xBD, 0xE8,
+ 0x10, 0x40, 0x22, 0x20, 0xFF, 0xF7, 0x3F, 0xBF, 0x00, 0xB5, 0x91, 0xB0,
+ 0x1C, 0x23, 0xAD, 0xF8, 0x00, 0x30, 0x00, 0xB9, 0x07, 0x48, 0x8D, 0xF8,
+ 0x0B, 0x20, 0x8D, 0xF8, 0x0A, 0x10, 0x01, 0x68, 0x01, 0x91, 0x80, 0x88,
+ 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0xFF, 0xF7, 0x38, 0xFF,
+ 0x11, 0xB0, 0x00, 0xBD, 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x8D, 0xB0,
+ 0x1B, 0x23, 0xAD, 0xF8, 0x02, 0x30, 0x03, 0x68, 0x01, 0x93, 0x80, 0x88,
+ 0xAD, 0xF8, 0x08, 0x00, 0x8D, 0xF8, 0x0A, 0x10, 0x03, 0x92, 0x01, 0x21,
+ 0x68, 0x46, 0xFF, 0xF7, 0x7B, 0xFF, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0x00,
+ 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0xDE, 0x73, 0xAD, 0xF8, 0x00, 0x30,
+ 0x00, 0xB9, 0x08, 0x48, 0x8D, 0xF8, 0x0B, 0x20, 0x8D, 0xF8, 0x0A, 0x10,
+ 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21,
+ 0x68, 0x46, 0xFF, 0xF7, 0x0B, 0xFF, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0x00,
+ 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0xBB, 0x13,
+ 0xAD, 0xF8, 0x02, 0x30, 0x03, 0x68, 0x01, 0x93, 0x80, 0x88, 0xAD, 0xF8,
+ 0x08, 0x00, 0x03, 0x91, 0x8D, 0xF8, 0x0A, 0x20, 0x01, 0x21, 0x68, 0x46,
+ 0xFF, 0xF7, 0x4C, 0xFF, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0,
+ 0x16, 0x23, 0xAD, 0xF8, 0x02, 0x30, 0x03, 0x68, 0x01, 0x93, 0x80, 0x88,
+ 0xAD, 0xF8, 0x08, 0x00, 0x03, 0x91, 0x8D, 0xF8, 0x0A, 0x20, 0x01, 0x21,
+ 0x68, 0x46, 0xFF, 0xF7, 0x39, 0xFF, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0x00,
+ 0x00, 0xB5, 0x91, 0xB0, 0x13, 0x23, 0xAD, 0xF8, 0x00, 0x30, 0x00, 0xB9,
+ 0x07, 0x48, 0x8D, 0xF8, 0x0A, 0x10, 0x8D, 0xF8, 0x0B, 0x20, 0x01, 0x68,
+ 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46,
+ 0xFF, 0xF7, 0xCA, 0xFE, 0x11, 0xB0, 0x00, 0xBD, 0x8A, 0xAD, 0x82, 0x00,
+ 0x10, 0xB5, 0x90, 0xB0, 0x14, 0x24, 0xAD, 0xF8, 0x00, 0x40, 0x00, 0xB9,
+ 0x08, 0x48, 0x8D, 0xF8, 0x0A, 0x10, 0x03, 0x92, 0x8D, 0xF8, 0x10, 0x30,
+ 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21,
+ 0x68, 0x46, 0xFF, 0xF7, 0xB1, 0xFE, 0x10, 0xB0, 0x10, 0xBD, 0x00, 0x00,
+ 0x8A, 0xAD, 0x82, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x06, 0x46, 0x10, 0x48,
+ 0x17, 0x46, 0x0D, 0x46, 0x4F, 0xF4, 0xE1, 0x73, 0x0C, 0x4A, 0xC9, 0x1D,
+ 0x00, 0x78, 0xFA, 0xF7, 0x13, 0xFC, 0x00, 0x28, 0x10, 0xD0, 0x04, 0x46,
+ 0x0D, 0x20, 0x20, 0x80, 0xA6, 0x80, 0xA5, 0x71, 0x25, 0xB1, 0x2A, 0x46,
+ 0x39, 0x46, 0xE0, 0x1D, 0x24, 0xF4, 0x85, 0xF7, 0x20, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x41, 0x00, 0x21, 0xFF, 0xF7, 0x8C, 0xBE, 0xBD, 0xE8, 0xF0, 0x81,
+ 0xD8, 0xAD, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x41,
+ 0x1C, 0x46, 0x15, 0x46, 0x0E, 0x46, 0x07, 0x46, 0x00, 0xF0, 0xA8, 0xFA,
+ 0x68, 0xB1, 0x00, 0x20, 0x03, 0x94, 0x00, 0x90, 0xCD, 0xE9, 0x01, 0x05,
+ 0x33, 0x46, 0x09, 0x22, 0x04, 0x21, 0x38, 0x46, 0x01, 0xF0, 0xF4, 0xF8,
+ 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x02, 0x20, 0xFA, 0xE7, 0x00, 0x00,
+ 0x2D, 0xE9, 0xFF, 0x41, 0x1D, 0x46, 0x16, 0x46, 0x0F, 0x46, 0x04, 0x46,
+ 0x00, 0xF0, 0x8E, 0xFA, 0xA0, 0xB1, 0x0B, 0x4A, 0x04, 0xEB, 0x84, 0x01,
+ 0x00, 0x20, 0x92, 0x68, 0x3B, 0x46, 0x02, 0xEB, 0xC1, 0x01, 0x05, 0x22,
+ 0x48, 0x71, 0x03, 0x95, 0x00, 0x90, 0xCD, 0xE9, 0x01, 0x06, 0x03, 0x21,
+ 0x20, 0x46, 0x01, 0xF0, 0xD3, 0xF8, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81,
+ 0x02, 0x20, 0xFA, 0xE7, 0xA0, 0x78, 0x20, 0x00, 0x7F, 0xB5, 0x0D, 0x46,
+ 0x04, 0x46, 0xFF, 0x29, 0x00, 0xD1, 0x00, 0x21, 0x00, 0xF0, 0x6C, 0xFA,
+ 0x70, 0xB1, 0x00, 0x20, 0x01, 0xAE, 0x01, 0x21, 0x4F, 0xF6, 0xFF, 0x72,
+ 0x00, 0x90, 0x86, 0xE8, 0x07, 0x00, 0x2B, 0x46, 0x0A, 0x46, 0x20, 0x46,
+ 0x01, 0xF0, 0xB6, 0xF8, 0x04, 0xB0, 0x70, 0xBD, 0x02, 0x20, 0xFB, 0xE7,
+ 0x10, 0xB5, 0x04, 0x46, 0x01, 0x46, 0x0A, 0x48, 0x0E, 0xF0, 0x60, 0xFA,
+ 0x58, 0xB1, 0x09, 0x49, 0x04, 0xEB, 0x44, 0x00, 0x09, 0x68, 0x01, 0xEB,
+ 0x00, 0x10, 0x00, 0x8A, 0xFB, 0xF7, 0xA8, 0xFD, 0x18, 0xB1, 0x00, 0x20,
+ 0x10, 0xBD, 0x02, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, 0x00, 0x00,
+ 0x8D, 0xB2, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xF3, 0x4F,
+ 0xDF, 0xF8, 0xC0, 0xA0, 0x2E, 0x49, 0x00, 0xEB, 0x80, 0x09, 0xDA, 0xF8,
+ 0x08, 0x30, 0x0A, 0x88, 0x03, 0xEB, 0xC9, 0x04, 0x03, 0x26, 0x21, 0x8C,
+ 0xE3, 0x8B, 0x00, 0xEB, 0x40, 0x08, 0xC9, 0x1A, 0x29, 0x4B, 0x0D, 0x04,
+ 0x83, 0xB0, 0x19, 0x68, 0x2D, 0x0C, 0x01, 0xEB, 0x08, 0x10, 0x2F, 0xD0,
+ 0x40, 0x8A, 0x9B, 0x46, 0x40, 0x1F, 0xA8, 0x42, 0x00, 0xDA, 0x85, 0xB2,
+ 0x52, 0x1D, 0x96, 0xB2, 0x31, 0x46, 0x28, 0x46, 0xFC, 0xF7, 0x6E, 0xFC,
+ 0x07, 0x00, 0x33, 0xD0, 0xE1, 0x8B, 0x60, 0x6A, 0x2A, 0x46, 0x01, 0x44,
+ 0xB8, 0x19, 0x24, 0xF4, 0xD8, 0xF6, 0xE0, 0x8B, 0xCD, 0xE9, 0x00, 0x06,
+ 0xDB, 0xF8, 0x00, 0x10, 0xA2, 0x8B, 0x01, 0xEB, 0x08, 0x10, 0x2B, 0x46,
+ 0x01, 0x8A, 0x38, 0x46, 0xFB, 0xF7, 0xF6, 0xFD, 0x88, 0xB1, 0xE0, 0x8B,
+ 0x00, 0x26, 0x28, 0x44, 0xE0, 0x83, 0x04, 0x98, 0xE0, 0x70, 0xDA, 0xF8,
+ 0x08, 0x10, 0x01, 0x22, 0x01, 0xEB, 0xC9, 0x00, 0x02, 0x71, 0x0D, 0xE0,
+ 0x00, 0x8A, 0x01, 0x21, 0xFB, 0xF7, 0x6E, 0xFD, 0x08, 0xE0, 0x07, 0x26,
+ 0x38, 0x46, 0xFB, 0xF7, 0x25, 0xFC, 0x0A, 0x49, 0x00, 0x22, 0x0A, 0x48,
+ 0xF2, 0xF7, 0x9B, 0xDD, 0x05, 0xB0, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x8F,
+ 0x05, 0x49, 0x08, 0x26, 0x00, 0x22, 0x38, 0x31, 0xF3, 0xE7, 0x00, 0x00,
+ 0x46, 0x78, 0x20, 0x00, 0xA0, 0x78, 0x20, 0x00, 0x64, 0x78, 0x20, 0x00,
+ 0x4C, 0x64, 0xC0, 0x08, 0x00, 0x33, 0x10, 0x21, 0xFE, 0xB5, 0x15, 0x46,
+ 0x0E, 0x46, 0x04, 0x46, 0x00, 0xF0, 0xCC, 0xF9, 0xD0, 0xB1, 0x00, 0x22,
+ 0x11, 0x49, 0x00, 0x92, 0x01, 0x92, 0x02, 0x92, 0x09, 0x68, 0x04, 0xEB,
+ 0x44, 0x00, 0x01, 0xEB, 0x00, 0x10, 0x2B, 0x46, 0x00, 0x8A, 0x01, 0x21,
+ 0xFB, 0xF7, 0x52, 0xFE, 0x60, 0xB1, 0x0B, 0x48, 0x04, 0xEB, 0x84, 0x01,
+ 0x00, 0x25, 0x80, 0x68, 0x00, 0xEB, 0xC1, 0x00, 0x01, 0x21, 0x86, 0x70,
+ 0x01, 0x71, 0x07, 0xE0, 0x02, 0x20, 0xFE, 0xBD, 0x07, 0x25, 0x00, 0x22,
+ 0x04, 0x49, 0x05, 0x48, 0xF2, 0xF7, 0x5D, 0xDD, 0x28, 0x46, 0xFE, 0xBD,
+ 0x64, 0x78, 0x20, 0x00, 0xA0, 0x78, 0x20, 0x00, 0xF0, 0x63, 0xC0, 0x08,
+ 0x00, 0x33, 0x10, 0x21, 0x2D, 0xE9, 0xFE, 0x4F, 0x1C, 0x46, 0xDD, 0xE9,
+ 0x0C, 0xA9, 0x17, 0x46, 0x0E, 0x46, 0x05, 0x46, 0x4F, 0xF0, 0x02, 0x08,
+ 0x00, 0xF0, 0x92, 0xF9, 0x08, 0xB1, 0x1F, 0xB1, 0x03, 0xE0, 0x40, 0x46,
+ 0xBD, 0xE8, 0xFE, 0x8F, 0x01, 0x27, 0x0C, 0xB9, 0x4F, 0xF6, 0xFF, 0x74,
+ 0x11, 0x49, 0xCD, 0xE9, 0x00, 0x4A, 0xCD, 0xF8, 0x08, 0x90, 0x09, 0x68,
+ 0x05, 0xEB, 0x45, 0x00, 0x01, 0xEB, 0x00, 0x10, 0x3B, 0x46, 0x00, 0x8A,
+ 0x00, 0x22, 0x02, 0x21, 0xFB, 0xF7, 0x0E, 0xFE, 0x50, 0xB1, 0x0A, 0x48,
+ 0x05, 0xEB, 0x85, 0x01, 0x00, 0x24, 0x80, 0x68, 0x00, 0xEB, 0xC1, 0x00,
+ 0x01, 0x21, 0x86, 0x70, 0x01, 0x71, 0x05, 0xE0, 0x07, 0x24, 0x00, 0x22,
+ 0x04, 0x49, 0x05, 0x48, 0xF2, 0xF7, 0x1B, 0xDD, 0x20, 0x46, 0xD5, 0xE7,
+ 0x64, 0x78, 0x20, 0x00, 0xA0, 0x78, 0x20, 0x00, 0x18, 0x64, 0xC0, 0x08,
+ 0x00, 0x33, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x4F, 0x83, 0xB0, 0x83, 0x46,
+ 0x15, 0x46, 0x4F, 0xF0, 0x03, 0x09, 0x59, 0x46, 0x5E, 0x48, 0x10, 0x9C,
+ 0x0E, 0xF0, 0x5C, 0xF9, 0x40, 0xB1, 0x5D, 0x48, 0x0B, 0xEB, 0x8B, 0x06,
+ 0x01, 0x2D, 0x07, 0xD0, 0x5B, 0x49, 0x09, 0x78, 0xD9, 0xB1, 0x09, 0xE0,
+ 0x02, 0x20, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x81, 0x68, 0x01, 0xEB,
+ 0xC6, 0x01, 0x09, 0x79, 0x01, 0x29, 0x09, 0xD0, 0x82, 0x46, 0x80, 0x68,
+ 0x54, 0x49, 0x00, 0xEB, 0xC6, 0x07, 0x0B, 0xEB, 0x4B, 0x08, 0x04, 0x2D,
+ 0x0F, 0xD0, 0x15, 0xE0, 0x5B, 0x46, 0x01, 0x22, 0x50, 0x49, 0x51, 0x48,
+ 0xF2, 0xF7, 0xE1, 0xDC, 0xE4, 0xE7, 0x4E, 0x49, 0x00, 0x22, 0x2C, 0x31,
+ 0x4D, 0x48, 0xF2, 0xF7, 0xDA, 0xDC, 0x06, 0x20, 0xDD, 0xE7, 0x0A, 0x68,
+ 0x02, 0xEB, 0x08, 0x10, 0x40, 0x8A, 0x0F, 0x38, 0xA0, 0x42, 0x0B, 0xDB,
+ 0x45, 0x49, 0x09, 0x68, 0x01, 0xEB, 0x08, 0x10, 0x40, 0x8A, 0xC0, 0x1E,
+ 0xA0, 0x42, 0x23, 0xDA, 0x4F, 0xF4, 0x00, 0x71, 0x8C, 0x42, 0x01, 0xD9,
+ 0x09, 0x20, 0xC8, 0xE7, 0x01, 0x2D, 0x01, 0xD0, 0x48, 0x46, 0xC4, 0xE7,
+ 0x40, 0xF2, 0xC1, 0x23, 0x38, 0x4A, 0x00, 0x20, 0xFD, 0xF7, 0x4E, 0xDA,
+ 0x78, 0x62, 0x78, 0xB1, 0x22, 0x46, 0x11, 0x99, 0x24, 0xF4, 0xC7, 0xF5,
+ 0x3C, 0x84, 0x00, 0x20, 0xF8, 0x83, 0x06, 0x98, 0xB8, 0x83, 0x04, 0x99,
+ 0x07, 0xB0, 0x58, 0x46, 0xBD, 0xE8, 0xF0, 0x4F, 0xFF, 0xF7, 0xB4, 0xBE,
+ 0x08, 0x20, 0xAA, 0xE7, 0x32, 0x48, 0x01, 0x88, 0x32, 0x48, 0xC9, 0x1C,
+ 0x89, 0xB2, 0x00, 0x88, 0x89, 0x46, 0x04, 0x2D, 0x2A, 0xD0, 0x0A, 0x46,
+ 0x21, 0x46, 0xFB, 0xF7, 0x0F, 0xFB, 0x07, 0x00, 0x44, 0xD0, 0x07, 0xEB,
+ 0x09, 0x00, 0x22, 0x46, 0x11, 0x99, 0x24, 0xF4, 0xA4, 0xF5, 0x25, 0x49,
+ 0xCD, 0xE9, 0x00, 0x49, 0x09, 0x68, 0x2A, 0x46, 0x01, 0xEB, 0x08, 0x10,
+ 0x06, 0x9B, 0x01, 0x8A, 0x38, 0x46, 0xFB, 0xF7, 0xBD, 0xFE, 0x28, 0xB3,
+ 0x00, 0x24, 0x02, 0x2D, 0x13, 0xD0, 0x04, 0x2D, 0x11, 0xD0, 0xDA, 0xF8,
+ 0x08, 0x00, 0x01, 0x21, 0x00, 0xEB, 0xC6, 0x00, 0x01, 0x71, 0xDA, 0xF8,
+ 0x08, 0x10, 0x04, 0x98, 0x01, 0xEB, 0xC6, 0x01, 0xC8, 0x70, 0x1D, 0xE0,
+ 0x04, 0xF1, 0x0C, 0x01, 0x89, 0xB2, 0x4A, 0x46, 0xD1, 0xE7, 0x12, 0x49,
+ 0x5B, 0x46, 0x02, 0x22, 0x08, 0x78, 0x40, 0x1E, 0xC0, 0xB2, 0x08, 0x70,
+ 0x00, 0x90, 0x10, 0x49, 0x10, 0x48, 0x5C, 0x31, 0xC0, 0x1C, 0xF2, 0xF7,
+ 0x5E, 0xDC, 0xE4, 0xE7, 0x07, 0x24, 0x38, 0x46, 0xFB, 0xF7, 0xDE, 0xFA,
+ 0x0A, 0x49, 0x00, 0x22, 0x90, 0x31, 0x0A, 0x48, 0xF2, 0xF7, 0x53, 0xDC,
+ 0x20, 0x46, 0x56, 0xE7, 0x06, 0x49, 0x08, 0x24, 0x00, 0x22, 0xBC, 0x31,
+ 0xF5, 0xE7, 0x00, 0x00, 0x7B, 0xB2, 0x82, 0x00, 0xA0, 0x78, 0x20, 0x00,
+ 0x60, 0x78, 0x20, 0x00, 0x64, 0x78, 0x20, 0x00, 0xC0, 0x64, 0xC0, 0x08,
+ 0x00, 0x33, 0x10, 0x21, 0x46, 0x78, 0x20, 0x00, 0x44, 0x78, 0x20, 0x00,
+ 0x2D, 0xE9, 0xFF, 0x41, 0x1D, 0x46, 0x16, 0x46, 0x88, 0x46, 0x07, 0x46,
+ 0x0A, 0x9C, 0x00, 0xF0, 0x7D, 0xF8, 0xC8, 0xB1, 0x0D, 0x48, 0x07, 0xEB,
+ 0x87, 0x02, 0x02, 0x21, 0x80, 0x68, 0x00, 0xEB, 0xC2, 0x00, 0x10, 0x22,
+ 0x41, 0x71, 0x21, 0x46, 0x80, 0x1D, 0x24, 0xF4, 0x38, 0xF5, 0x00, 0x20,
+ 0x03, 0x95, 0x8D, 0xE8, 0x51, 0x00, 0x43, 0x46, 0x05, 0x22, 0x03, 0x21,
+ 0x38, 0x46, 0x00, 0xF0, 0xBD, 0xFE, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81,
+ 0x02, 0x20, 0xFA, 0xE7, 0xA0, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x41,
+ 0x15, 0x46, 0x0E, 0x46, 0x07, 0x46, 0x00, 0xF0, 0x57, 0xF8, 0x80, 0xB1,
+ 0x01, 0x20, 0x4F, 0xF6, 0xFF, 0x74, 0x00, 0x21, 0xCD, 0xE9, 0x00, 0x15,
+ 0xCD, 0xE9, 0x02, 0x04, 0x02, 0x46, 0x33, 0x46, 0x02, 0x21, 0x38, 0x46,
+ 0x00, 0xF0, 0xA0, 0xFE, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x02, 0x20,
+ 0xFA, 0xE7, 0x00, 0x00, 0x2D, 0xE9, 0xFF, 0x41, 0x1D, 0x46, 0x16, 0x46,
+ 0x88, 0x46, 0x07, 0x46, 0x0A, 0x9C, 0x00, 0xF0, 0x39, 0xF8, 0xB0, 0xB1,
+ 0x0C, 0x48, 0x07, 0xEB, 0x87, 0x02, 0x01, 0x21, 0x80, 0x68, 0x43, 0x46,
+ 0x00, 0xEB, 0xC2, 0x00, 0x05, 0x22, 0x41, 0x71, 0xC4, 0x82, 0x00, 0x20,
+ 0xCD, 0xE9, 0x00, 0x40, 0xCD, 0xE9, 0x02, 0x65, 0x03, 0x21, 0x38, 0x46,
+ 0x00, 0xF0, 0x7C, 0xFE, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x02, 0x20,
+ 0xFA, 0xE7, 0x00, 0x00, 0xA0, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x41,
+ 0x15, 0x46, 0x0E, 0x46, 0x07, 0x46, 0x00, 0xF0, 0x15, 0xF8, 0x80, 0xB1,
+ 0x4F, 0xF6, 0xFF, 0x70, 0x01, 0x24, 0x03, 0x90, 0x00, 0x21, 0x00, 0x95,
+ 0xCD, 0xE9, 0x01, 0x14, 0x33, 0x46, 0x22, 0x46, 0x02, 0x21, 0x38, 0x46,
+ 0x00, 0xF0, 0x5E, 0xFE, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x02, 0x20,
+ 0xFA, 0xE7, 0x00, 0x00, 0x38, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x01, 0x46,
+ 0x11, 0x48, 0x0E, 0xF0, 0x05, 0xF8, 0x00, 0x28, 0x13, 0xD0, 0x10, 0x49,
+ 0x10, 0x48, 0x4A, 0x78, 0x95, 0x42, 0x05, 0xD3, 0x2B, 0x46, 0x01, 0x22,
+ 0x0E, 0x49, 0xF2, 0xF7, 0xA2, 0xDB, 0x10, 0xE0, 0x89, 0x68, 0x04, 0xEB,
+ 0x84, 0x02, 0x01, 0xEB, 0xC2, 0x01, 0x09, 0x79, 0x01, 0x29, 0x01, 0xD0,
+ 0x01, 0x20, 0x38, 0xBD, 0x07, 0x49, 0x23, 0x46, 0x02, 0x22, 0x2C, 0x31,
+ 0x00, 0x95, 0xF2, 0xF7, 0x90, 0xDB, 0x00, 0x20, 0x38, 0xBD, 0x00, 0x00,
+ 0x68, 0xB2, 0x82, 0x00, 0xA0, 0x78, 0x20, 0x00, 0x00, 0x33, 0x10, 0x21,
+ 0x1C, 0x63, 0xC0, 0x08, 0x08, 0x49, 0x10, 0xB5, 0x4A, 0x78, 0x90, 0x42,
+ 0x03, 0xD2, 0xC9, 0x68, 0x01, 0xEB, 0xC0, 0x00, 0x10, 0xBD, 0x03, 0x46,
+ 0x01, 0x22, 0x04, 0x49, 0x04, 0x48, 0xF2, 0xF7, 0x76, 0xDB, 0x00, 0x20,
+ 0x10, 0xBD, 0x00, 0x00, 0xA0, 0x78, 0x20, 0x00, 0xE8, 0x62, 0xC0, 0x08,
+ 0x00, 0x33, 0x10, 0x21, 0x70, 0xB5, 0x0E, 0x46, 0x04, 0x46, 0x01, 0x46,
+ 0x15, 0x46, 0x0A, 0x48, 0x0D, 0xF0, 0xBC, 0xFF, 0x00, 0x28, 0x0D, 0xD0,
+ 0x08, 0x49, 0x04, 0xEB, 0x44, 0x00, 0x0A, 0x68, 0x02, 0xEB, 0x00, 0x12,
+ 0x52, 0x6A, 0x32, 0x60, 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x40, 0x8C,
+ 0x28, 0x80, 0x01, 0x20, 0x70, 0xBD, 0x00, 0x00, 0xED, 0xB2, 0x82, 0x00,
+ 0x64, 0x78, 0x20, 0x00, 0x29, 0x49, 0x10, 0xB5, 0x09, 0x78, 0x01, 0x24,
+ 0x29, 0xB3, 0x43, 0x88, 0x40, 0xF2, 0x1F, 0x12, 0xA3, 0xF2, 0x1F, 0x11,
+ 0x93, 0x42, 0x41, 0xD0, 0x12, 0xDC, 0x40, 0xF2, 0x17, 0x12, 0xA3, 0xF2,
+ 0x17, 0x11, 0x93, 0x42, 0x20, 0xD0, 0x06, 0xDC, 0xA3, 0xF5, 0x80, 0x73,
+ 0x13, 0x3B, 0x13, 0xD0, 0x01, 0x2B, 0x36, 0xD1, 0x14, 0xE0, 0x04, 0x29,
+ 0x21, 0xD0, 0x06, 0x29, 0x31, 0xD1, 0x29, 0xE0, 0x01, 0x29, 0x20, 0xD0,
+ 0x03, 0x29, 0x1E, 0xD0, 0x0F, 0x29, 0x01, 0xD0, 0x10, 0x29, 0x28, 0xD1,
+ 0x80, 0x88, 0x00, 0xF0, 0x2B, 0xF8, 0x24, 0xE0, 0x00, 0x1D, 0x00, 0xF0,
+ 0x17, 0xFD, 0x20, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x95, 0xFA, 0x1C, 0xE0,
+ 0x81, 0x79, 0x00, 0xF1, 0x04, 0x00, 0x02, 0x29, 0x02, 0xD0, 0x00, 0xF0,
+ 0x49, 0xF8, 0x14, 0xE0, 0x00, 0xF0, 0xA2, 0xF9, 0x11, 0xE0, 0x00, 0x1D,
+ 0x00, 0xF0, 0x3A, 0xFA, 0x0D, 0xE0, 0x02, 0x46, 0x01, 0x1D, 0x18, 0x46,
+ 0x00, 0xF0, 0x12, 0xF9, 0x04, 0x46, 0x06, 0xE0, 0x00, 0x1D, 0x00, 0xF0,
+ 0x6F, 0xF9, 0x02, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0xD5, 0xF8, 0x20, 0x46,
+ 0x10, 0xBD, 0x00, 0x00, 0xA0, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x0D, 0xF0,
+ 0xEB, 0xFF, 0x00, 0x28, 0x24, 0xD0, 0x13, 0x4E, 0xC5, 0x78, 0xB0, 0x68,
+ 0x05, 0xEB, 0x85, 0x04, 0x00, 0xEB, 0xC4, 0x00, 0x40, 0x6A, 0x30, 0xB1,
+ 0xFD, 0xF7, 0xDD, 0xD8, 0xB1, 0x68, 0x00, 0x20, 0x01, 0xEB, 0xC4, 0x01,
+ 0x48, 0x62, 0xB0, 0x68, 0x28, 0x21, 0x00, 0xEB, 0xC4, 0x00, 0x24, 0xF4,
+ 0x93, 0xF4, 0x00, 0x24, 0x09, 0xE0, 0xF0, 0x68, 0x00, 0xEB, 0xC4, 0x00,
+ 0x40, 0x68, 0x41, 0x69, 0x09, 0xB1, 0x28, 0x46, 0x88, 0x47, 0x64, 0x1C,
+ 0xE4, 0xB2, 0x70, 0x78, 0x84, 0x42, 0xF2, 0xD3, 0x70, 0xBD, 0x00, 0x00,
+ 0xA0, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xFE, 0x4F, 0x04, 0x46, 0x00, 0x88,
+ 0x0D, 0xF0, 0xBA, 0xFF, 0x07, 0x00, 0x5D, 0xD0, 0x49, 0x49, 0x97, 0xF8,
+ 0x03, 0xB0, 0x89, 0x68, 0x0B, 0xEB, 0x8B, 0x00, 0x01, 0xEB, 0xC0, 0x05,
+ 0xA8, 0x78, 0xFF, 0xF7, 0x33, 0xFF, 0x80, 0x46, 0xA1, 0x88, 0x04, 0xF1,
+ 0x10, 0x00, 0x39, 0xB1, 0x21, 0x89, 0x00, 0x22, 0x00, 0x29, 0x69, 0xD0,
+ 0xA1, 0x89, 0x01, 0x29, 0x5E, 0xD0, 0x65, 0xE0, 0x21, 0x89, 0x00, 0x29,
+ 0x70, 0xD0, 0xE1, 0x89, 0x66, 0x89, 0x01, 0xEB, 0x00, 0x09, 0xA1, 0x89,
+ 0xE0, 0x88, 0x09, 0xEB, 0x41, 0x0A, 0x4F, 0xF4, 0x00, 0x71, 0xA8, 0xB1,
+ 0x28, 0x8C, 0x82, 0x19, 0x8A, 0x42, 0x35, 0xD8, 0x69, 0x6A, 0x32, 0x46,
+ 0x08, 0x44, 0x51, 0x46, 0x24, 0xF4, 0xA7, 0xF3, 0x28, 0x8C, 0x30, 0x44,
+ 0x80, 0xB2, 0x28, 0x84, 0x79, 0x8A, 0x49, 0x1E, 0xB1, 0x42, 0x14, 0xD0,
+ 0x06, 0x46, 0xD5, 0xF8, 0x24, 0xA0, 0x27, 0xE0, 0x78, 0x8A, 0x40, 0x1E,
+ 0xB0, 0x42, 0x23, 0xD1, 0x40, 0xF2, 0xF9, 0x53, 0x29, 0x4A, 0x00, 0x20,
+ 0xFD, 0xF7, 0x12, 0xD8, 0x68, 0x62, 0xD8, 0xB1, 0x32, 0x46, 0x51, 0x46,
+ 0x24, 0xF4, 0x8B, 0xF3, 0x2E, 0x84, 0x00, 0x20, 0x00, 0x90, 0x01, 0x90,
+ 0x02, 0x90, 0x23, 0x49, 0x0B, 0xEB, 0x4B, 0x00, 0xB9, 0xF8, 0x00, 0x30,
+ 0x09, 0x68, 0x2A, 0x8C, 0x01, 0xEB, 0x00, 0x10, 0x01, 0x21, 0x00, 0x8A,
+ 0xFB, 0xF7, 0x46, 0xFB, 0xBD, 0xE8, 0xFE, 0x8F, 0x40, 0xF6, 0x11, 0x40,
+ 0xA0, 0x80, 0x00, 0x26, 0x00, 0x20, 0x28, 0x71, 0xB8, 0xF1, 0x00, 0x0F,
+ 0x22, 0xD0, 0xD8, 0xF8, 0x04, 0x00, 0x87, 0x68, 0x3F, 0xB1, 0xCD, 0xF8,
+ 0x00, 0xA0, 0xB9, 0xF8, 0x00, 0x20, 0xA1, 0x88, 0x33, 0x46, 0x58, 0x46,
+ 0xB8, 0x47, 0x15, 0xE0, 0xE1, 0x89, 0x0A, 0x5C, 0x04, 0xF1, 0x11, 0x00,
+ 0x08, 0x5C, 0x02, 0xEB, 0x00, 0x20, 0x82, 0xB2, 0x00, 0x20, 0x28, 0x71,
+ 0xB8, 0xF1, 0x00, 0x0F, 0x08, 0xD0, 0xD8, 0xF8, 0x04, 0x10, 0x8E, 0x68,
+ 0x26, 0xB1, 0x00, 0x90, 0xA1, 0x88, 0x00, 0x23, 0x58, 0x46, 0xB0, 0x47,
+ 0x68, 0x6A, 0x00, 0x28, 0xCE, 0xD0, 0xFD, 0xF7, 0x26, 0xD8, 0x00, 0x20,
+ 0x68, 0x62, 0xC9, 0xE7, 0xA0, 0x78, 0x20, 0x00, 0xCA, 0xB2, 0x82, 0x00,
+ 0x64, 0x78, 0x20, 0x00, 0xF8, 0xB5, 0x05, 0x46, 0x00, 0x88, 0x0D, 0xF0,
+ 0x19, 0xFF, 0x00, 0x28, 0x27, 0xD0, 0x14, 0x49, 0xC6, 0x78, 0x89, 0x68,
+ 0x06, 0xEB, 0x86, 0x00, 0x01, 0xEB, 0xC0, 0x04, 0xE0, 0x78, 0xFF, 0xF7,
+ 0x93, 0xFE, 0x69, 0x88, 0x21, 0xB9, 0xE1, 0x8B, 0x11, 0xB9, 0x40, 0xF6,
+ 0x11, 0x41, 0x69, 0x80, 0x00, 0x27, 0x27, 0x71, 0x68, 0xB1, 0x40, 0x68,
+ 0xD0, 0xF8, 0x0C, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, 0x07, 0xD0, 0x08, 0x48,
+ 0x01, 0x21, 0x00, 0x78, 0x00, 0x90, 0x6B, 0x88, 0xA2, 0x8B, 0x30, 0x46,
+ 0xE0, 0x47, 0x60, 0x6A, 0x00, 0x28, 0x02, 0xD0, 0xFC, 0xF7, 0xEF, 0xDF,
+ 0x67, 0x62, 0xF8, 0xBD, 0xA0, 0x78, 0x20, 0x00, 0x60, 0x78, 0x20, 0x00,
+ 0x2D, 0xE9, 0xFF, 0x5F, 0x14, 0x46, 0xB0, 0xF5, 0x91, 0x7F, 0x1B, 0xD0,
+ 0x00, 0x26, 0x88, 0x88, 0x01, 0x90, 0x48, 0x88, 0x02, 0x90, 0xCA, 0x88,
+ 0x01, 0xF1, 0x08, 0x00, 0x02, 0xEB, 0x00, 0x08, 0x08, 0x88, 0x00, 0x27,
+ 0x4F, 0xF0, 0x01, 0x09, 0x03, 0x90, 0x0D, 0xF0, 0xD3, 0xFE, 0x88, 0xB3,
+ 0x90, 0xF8, 0x03, 0xB0, 0xA8, 0xEB, 0x04, 0x01, 0x44, 0x62, 0x41, 0x84,
+ 0x00, 0x24, 0xDF, 0xF8, 0x78, 0xA0, 0x21, 0xE0, 0x01, 0x26, 0xE2, 0xE7,
+ 0xDA, 0xF8, 0x0C, 0x00, 0x00, 0xEB, 0xC4, 0x00, 0x40, 0x68, 0x05, 0x69,
+ 0xB5, 0xB1, 0xCD, 0xF8, 0x00, 0x80, 0xDD, 0xE9, 0x01, 0x32, 0x31, 0x46,
+ 0x58, 0x46, 0xA8, 0x47, 0x05, 0x46, 0xA0, 0xF5, 0x50, 0x60, 0x01, 0x38,
+ 0x05, 0xD1, 0x00, 0x22, 0x12, 0x49, 0x13, 0x48, 0xF2, 0xF7, 0xB9, 0xD9,
+ 0x01, 0x27, 0x1E, 0xB1, 0xA5, 0xF5, 0x50, 0x60, 0x05, 0x38, 0x08, 0xD0,
+ 0x64, 0x1C, 0xE4, 0xB2, 0x9A, 0xF8, 0x01, 0x10, 0x8C, 0x42, 0xDB, 0xD3,
+ 0x3E, 0x43, 0x09, 0xD0, 0x0B, 0xE0, 0x09, 0x49, 0x00, 0x22, 0x2C, 0x31,
+ 0x08, 0x48, 0xF2, 0xF7, 0xA4, 0xD9, 0x4F, 0xF0, 0x00, 0x09, 0xF3, 0xE7,
+ 0x03, 0x98, 0xFB, 0xF7, 0x47, 0xF9, 0x04, 0xB0, 0x48, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x9F, 0x00, 0x00, 0xA0, 0x78, 0x20, 0x00, 0x6C, 0x69, 0xC0, 0x08,
+ 0x03, 0x33, 0x10, 0x21, 0x70, 0xB5, 0x05, 0x46, 0x00, 0x88, 0x0D, 0xF0,
+ 0x83, 0xFE, 0x00, 0x28, 0x0E, 0xD0, 0xC4, 0x78, 0x68, 0x88, 0x0C, 0x4E,
+ 0x58, 0xB1, 0x28, 0x88, 0x00, 0x21, 0xFB, 0xF7, 0x4D, 0xF9, 0xB2, 0x68,
+ 0x04, 0xEB, 0x84, 0x01, 0x02, 0xEB, 0xC1, 0x01, 0x00, 0x20, 0xC8, 0x83,
+ 0x70, 0xBD, 0xB1, 0x68, 0x04, 0xEB, 0x84, 0x00, 0x01, 0xEB, 0xC0, 0x00,
+ 0xC1, 0x78, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xFF, 0xF7, 0x7E, 0xBB,
+ 0xA0, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x5F, 0x04, 0x46, 0x00, 0x88,
+ 0x0D, 0xF0, 0x5E, 0xFE, 0x5F, 0xEA, 0x00, 0x0B, 0x23, 0xD0, 0x9B, 0xF8,
+ 0x03, 0x00, 0x45, 0x4E, 0x00, 0xEB, 0x80, 0x05, 0xCD, 0xE9, 0x02, 0x50,
+ 0xB0, 0x68, 0x00, 0xEB, 0xC5, 0x00, 0x80, 0x78, 0xFF, 0xF7, 0xD4, 0xFD,
+ 0x80, 0x46, 0xB0, 0x68, 0xA1, 0x88, 0x00, 0xEB, 0xC5, 0x0A, 0x91, 0xB1,
+ 0x00, 0x21, 0x8A, 0xF8, 0x04, 0x10, 0xB8, 0xF1, 0x00, 0x0F, 0x0A, 0xD0,
+ 0xD8, 0xF8, 0x04, 0x00, 0x85, 0x68, 0x00, 0x2D, 0x05, 0xD0, 0x00, 0x91,
+ 0x00, 0x23, 0xA1, 0x88, 0x1A, 0x46, 0x03, 0x98, 0xA8, 0x47, 0xBD, 0xE8,
+ 0xFF, 0x9F, 0x21, 0x89, 0x00, 0x29, 0xFA, 0xD0, 0x65, 0x89, 0xA0, 0x89,
+ 0xAA, 0x1C, 0x42, 0x43, 0x51, 0x1A, 0x89, 0xB2, 0x01, 0x91, 0xE2, 0x89,
+ 0x04, 0xF1, 0x10, 0x01, 0x57, 0x18, 0x07, 0xEB, 0x40, 0x09, 0x00, 0x26,
+ 0x4F, 0xE0, 0x01, 0x99, 0x29, 0xB1, 0x41, 0x1E, 0xB1, 0x42, 0x02, 0xD1,
+ 0x01, 0x99, 0x69, 0x1A, 0x8D, 0xB2, 0x01, 0x28, 0x29, 0xD1, 0xBB, 0xF8,
+ 0x12, 0x00, 0x00, 0x1F, 0xA8, 0x42, 0x24, 0xD1, 0x40, 0xF2, 0x99, 0x53,
+ 0x22, 0x4A, 0x4F, 0xF4, 0x00, 0x71, 0x00, 0x20, 0xFC, 0xF7, 0xAC, 0xDE,
+ 0xCA, 0xF8, 0x24, 0x00, 0xC8, 0xB1, 0x2A, 0x46, 0x49, 0x46, 0xDA, 0xF8,
+ 0x24, 0x00, 0x24, 0xF4, 0x22, 0xF2, 0xAA, 0xF8, 0x20, 0x50, 0x00, 0x20,
+ 0x00, 0x90, 0x01, 0x90, 0x02, 0x90, 0x19, 0x49, 0x03, 0x98, 0x3B, 0x88,
+ 0x09, 0x68, 0x00, 0xEB, 0x40, 0x00, 0x01, 0xEB, 0x00, 0x10, 0x2A, 0x46,
+ 0x00, 0x8A, 0x01, 0x21, 0xFB, 0xF7, 0xDC, 0xF9, 0xB7, 0xE7, 0x10, 0x4A,
+ 0x02, 0x99, 0x00, 0x20, 0x92, 0x68, 0xB8, 0xF1, 0x00, 0x0F, 0x02, 0xEB,
+ 0xC1, 0x01, 0x08, 0x71, 0x0D, 0xD0, 0xD8, 0xF8, 0x04, 0x00, 0xD0, 0xF8,
+ 0x08, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, 0x06, 0xD0, 0xCD, 0xF8, 0x00, 0x90,
+ 0x3A, 0x88, 0xA1, 0x88, 0x2B, 0x46, 0x03, 0x98, 0xE0, 0x47, 0x76, 0x1C,
+ 0xA9, 0x44, 0xF6, 0xB2, 0xBF, 0x1C, 0xA0, 0x89, 0xB0, 0x42, 0xAC, 0xD8,
+ 0x97, 0xE7, 0x00, 0x00, 0xA0, 0x78, 0x20, 0x00, 0xA5, 0xB2, 0x82, 0x00,
+ 0x64, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x04, 0x46, 0x00, 0x88,
+ 0x0D, 0xF0, 0xC2, 0xFD, 0x1E, 0x4E, 0x30, 0xB3, 0xDF, 0xF8, 0x78, 0x90,
+ 0xC7, 0x78, 0xD9, 0xF8, 0x08, 0x10, 0x07, 0xEB, 0x87, 0x08, 0x01, 0xEB,
+ 0xC8, 0x00, 0xC0, 0x78, 0xFF, 0xF7, 0x3A, 0xFD, 0x05, 0x46, 0xA0, 0x78,
+ 0x02, 0x28, 0x1F, 0xD0, 0x04, 0x28, 0x1D, 0xD0, 0xD9, 0xF8, 0x08, 0x10,
+ 0x00, 0x22, 0x01, 0xEB, 0xC8, 0x00, 0x02, 0x71, 0x00, 0x2D, 0x0A, 0xD0,
+ 0x68, 0x68, 0xC5, 0x68, 0x00, 0x2D, 0x06, 0xD0, 0x30, 0x78, 0x00, 0x90,
+ 0xE3, 0x88, 0xA2, 0x88, 0xA1, 0x78, 0x38, 0x46, 0xA8, 0x47, 0xBD, 0xE8,
+ 0xF8, 0x83, 0xA0, 0x78, 0x02, 0x28, 0x01, 0xD0, 0x04, 0x28, 0xF8, 0xD1,
+ 0x30, 0x78, 0x40, 0x1C, 0x30, 0x70, 0xF4, 0xE7, 0x30, 0x78, 0x3B, 0x46,
+ 0x40, 0x1C, 0xC0, 0xB2, 0x30, 0x70, 0x00, 0x90, 0x02, 0x22, 0x04, 0x49,
+ 0x04, 0x48, 0xF2, 0xF7, 0x90, 0xD8, 0xDB, 0xE7, 0x60, 0x78, 0x20, 0x00,
+ 0xA0, 0x78, 0x20, 0x00, 0x28, 0x69, 0xC0, 0x08, 0x03, 0x33, 0x10, 0x21,
+ 0x2D, 0xE9, 0xF0, 0x4F, 0x8D, 0xB0, 0x4F, 0xF0, 0x00, 0x0A, 0x04, 0x46,
+ 0xCD, 0xF8, 0x2C, 0xA0, 0x00, 0x88, 0x0D, 0xF0, 0x71, 0xFD, 0x00, 0x28,
+ 0x78, 0xD0, 0xC0, 0x78, 0xDF, 0xF8, 0x40, 0xB4, 0x00, 0xEB, 0x80, 0x01,
+ 0x0A, 0x90, 0xDB, 0xF8, 0x08, 0x00, 0x00, 0xEB, 0xC1, 0x06, 0x70, 0x78,
+ 0xFF, 0xF7, 0xE8, 0xFC, 0x05, 0x46, 0xA0, 0x88, 0x00, 0x28, 0x68, 0xD1,
+ 0xA1, 0x78, 0x00, 0x27, 0x04, 0xF1, 0x0C, 0x00, 0x06, 0x29, 0x3D, 0xD2,
+ 0xDF, 0xE8, 0x01, 0xF0, 0x3C, 0x03, 0x7A, 0xFD, 0xFC, 0x9E, 0x21, 0x89,
+ 0x06, 0x29, 0x61, 0x89, 0x01, 0xEB, 0x00, 0x08, 0x4F, 0xF0, 0x00, 0x00,
+ 0x2C, 0xD0, 0x68, 0xE0, 0xB8, 0xF8, 0x04, 0x10, 0xB8, 0xF8, 0x02, 0x00,
+ 0xCD, 0xE9, 0x00, 0x01, 0xB8, 0xF8, 0x00, 0x30, 0x03, 0x22, 0xFB, 0x49,
+ 0xFB, 0x48, 0xF2, 0xF7, 0x48, 0xD8, 0xB8, 0xF8, 0x02, 0x70, 0x3D, 0xB1,
+ 0x68, 0x68, 0x43, 0x68, 0x23, 0xB1, 0x00, 0x21, 0x42, 0x46, 0x0A, 0x98,
+ 0x98, 0x47, 0x0E, 0xE0, 0xDB, 0xF8, 0x04, 0x30, 0x5B, 0xB1, 0x01, 0x20,
+ 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x6A, 0x46,
+ 0xCD, 0xF8, 0x08, 0x80, 0xFF, 0x20, 0x0A, 0x99, 0x98, 0x47, 0x09, 0xF1,
+ 0x01, 0x00, 0x08, 0xF1, 0x06, 0x08, 0xC0, 0xB2, 0xE1, 0x88, 0x81, 0x46,
+ 0x49, 0x45, 0xCF, 0xD8, 0x97, 0xE1, 0x10, 0x22, 0x08, 0xF1, 0x04, 0x01,
+ 0x06, 0xA8, 0x24, 0xF4, 0x32, 0xF1, 0x06, 0xAF, 0x97, 0xE8, 0x0F, 0x00,
+ 0xCD, 0xE9, 0x03, 0x10, 0xCD, 0xE9, 0x01, 0x32, 0xB8, 0xF8, 0x02, 0x00,
+ 0x00, 0x90, 0xDF, 0x49, 0xB8, 0xF8, 0x00, 0x30, 0x06, 0x22, 0x38, 0x31,
+ 0xDD, 0x48, 0xF2, 0xF7, 0x0C, 0xD8, 0xB8, 0xF8, 0x02, 0x70, 0x4D, 0xB1,
+ 0x68, 0x68, 0x43, 0x68, 0x33, 0xB1, 0x01, 0x21, 0x42, 0x46, 0x0A, 0x98,
+ 0x98, 0x47, 0x0F, 0xE0, 0xEF, 0xE1, 0x82, 0xE1, 0xDB, 0xF8, 0x04, 0x30,
+ 0x53, 0xB1, 0x01, 0x20, 0x8D, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x04, 0x00,
+ 0x6A, 0x46, 0xCD, 0xF8, 0x08, 0x80, 0xFF, 0x20, 0x0A, 0x99, 0x98, 0x47,
+ 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1, 0x14, 0x08, 0xC0, 0xB2, 0xE1, 0x88,
+ 0x81, 0x46, 0x49, 0x45, 0xC3, 0xD8, 0x5A, 0xE1, 0x61, 0x89, 0x01, 0xEB,
+ 0x00, 0x08, 0x00, 0x20, 0x19, 0xE0, 0xB8, 0xF8, 0x02, 0x00, 0x00, 0x90,
+ 0xC4, 0x49, 0xB8, 0xF8, 0x00, 0x30, 0x02, 0x22, 0x7C, 0x31, 0xC3, 0x48,
+ 0xF1, 0xF7, 0xD7, 0xDF, 0xB8, 0xF8, 0x02, 0x70, 0x35, 0xB1, 0x68, 0x68,
+ 0x43, 0x68, 0x1B, 0xB1, 0x02, 0x21, 0x42, 0x46, 0x0A, 0x98, 0x98, 0x47,
+ 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1, 0x04, 0x08, 0xC0, 0xB2, 0xE1, 0x88,
+ 0x81, 0x46, 0x49, 0x45, 0xE1, 0xD8, 0x36, 0xE1, 0x21, 0x89, 0x08, 0x29,
+ 0x61, 0x89, 0x01, 0xEB, 0x00, 0x08, 0x4F, 0xF0, 0x00, 0x00, 0x1F, 0xD0,
+ 0x63, 0xE0, 0xB8, 0xF8, 0x02, 0x00, 0xB8, 0xF8, 0x06, 0x20, 0xB8, 0xF8,
+ 0x04, 0x10, 0x8D, 0xE8, 0x07, 0x00, 0xAE, 0x49, 0xB8, 0xF8, 0x00, 0x30,
+ 0x04, 0x22, 0xA0, 0x31, 0xAC, 0x48, 0xF1, 0xF7, 0xAA, 0xDF, 0xB8, 0xF8,
+ 0x00, 0x70, 0x35, 0xB1, 0x68, 0x68, 0x43, 0x68, 0x1B, 0xB1, 0x07, 0x21,
+ 0x42, 0x46, 0x0A, 0x98, 0x98, 0x47, 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1,
+ 0x08, 0x08, 0xC0, 0xB2, 0xE1, 0x88, 0x81, 0x46, 0x49, 0x45, 0xDC, 0xD8,
+ 0x09, 0xE1, 0x10, 0x22, 0x08, 0xF1, 0x06, 0x01, 0x06, 0xA8, 0x24, 0xF4,
+ 0xA4, 0xF0, 0x06, 0xAF, 0x97, 0xE8, 0x0F, 0x00, 0xCD, 0xE9, 0x02, 0x32,
+ 0xCD, 0xE9, 0x04, 0x10, 0xB8, 0xF8, 0x04, 0x10, 0xB8, 0xF8, 0x02, 0x00,
+ 0xCD, 0xE9, 0x00, 0x01, 0x96, 0x49, 0x97, 0x4F, 0xB8, 0xF8, 0x00, 0x30,
+ 0x07, 0x22, 0xE8, 0x31, 0x38, 0x46, 0xF1, 0xF7, 0x7A, 0xDF, 0x00, 0x20,
+ 0x08, 0xEB, 0x00, 0x01, 0x89, 0x79, 0x19, 0xB9, 0x40, 0x1C, 0xC0, 0xB2,
+ 0x10, 0x28, 0xF7, 0xD3, 0x10, 0x28, 0x06, 0xD1, 0xB8, 0xF8, 0x02, 0x30,
+ 0x01, 0x22, 0x8D, 0x49, 0x38, 0x46, 0xF1, 0xF7, 0x68, 0xDF, 0xB8, 0xF8,
+ 0x00, 0x70, 0x01, 0xE0, 0x88, 0xE0, 0x11, 0xE0, 0x35, 0xB1, 0x68, 0x68,
+ 0x43, 0x68, 0x1B, 0xB1, 0x08, 0x21, 0x42, 0x46, 0x0A, 0x98, 0x98, 0x47,
+ 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1, 0x16, 0x08, 0xC0, 0xB2, 0xE1, 0x88,
+ 0x81, 0x46, 0x49, 0x45, 0xBB, 0xD8, 0xC4, 0xE0, 0x21, 0x89, 0x08, 0x29,
+ 0x61, 0x89, 0x01, 0xEB, 0x00, 0x08, 0x4F, 0xF0, 0x00, 0x00, 0x28, 0xD0,
+ 0x65, 0xE0, 0xB8, 0xF8, 0x02, 0x00, 0xB8, 0xF8, 0x06, 0x20, 0xB8, 0xF8,
+ 0x04, 0x10, 0x8D, 0xE8, 0x07, 0x00, 0x77, 0x49, 0xB8, 0xF8, 0x00, 0x30,
+ 0x04, 0x22, 0x38, 0x31, 0x73, 0x48, 0xF1, 0xF7, 0x38, 0xDF, 0xB8, 0xF8,
+ 0x04, 0x70, 0x70, 0x79, 0xC0, 0xB1, 0x01, 0x28, 0x0C, 0xD1, 0xF1, 0x8A,
+ 0xB8, 0xF8, 0x06, 0x00, 0x81, 0x42, 0x07, 0xD1, 0x09, 0x21, 0x2D, 0xB1,
+ 0x68, 0x68, 0x43, 0x68, 0x13, 0xB1, 0x42, 0x46, 0x0A, 0x98, 0x98, 0x47,
+ 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1, 0x08, 0x08, 0xC0, 0xB2, 0xE1, 0x88,
+ 0x81, 0x46, 0x49, 0x45, 0xD3, 0xD8, 0x8E, 0xE0, 0x03, 0x21, 0xEC, 0xE7,
+ 0x10, 0x22, 0x08, 0xF1, 0x06, 0x01, 0x06, 0xA8, 0x24, 0xF4, 0x27, 0xF0,
+ 0x06, 0xAF, 0x97, 0xE8, 0x0F, 0x00, 0xCD, 0xE9, 0x02, 0x32, 0xCD, 0xE9,
+ 0x04, 0x10, 0xB8, 0xF8, 0x04, 0x10, 0xB8, 0xF8, 0x02, 0x00, 0xCD, 0xE9,
+ 0x00, 0x01, 0x5A, 0x49, 0xB8, 0xF8, 0x00, 0x30, 0x07, 0x22, 0x94, 0x31,
+ 0x56, 0x48, 0xF1, 0xF7, 0xFE, 0xDE, 0xB8, 0xF8, 0x04, 0x70, 0x70, 0x79,
+ 0xE0, 0xB1, 0x02, 0x28, 0x10, 0xD1, 0x10, 0x22, 0x08, 0xF1, 0x06, 0x01,
+ 0xB0, 0x1D, 0x23, 0xF4, 0xBB, 0xF7, 0x48, 0xB9, 0x70, 0x79, 0x88, 0xB1,
+ 0x0A, 0x21, 0x2D, 0xB1, 0x68, 0x68, 0x43, 0x68, 0x13, 0xB1, 0x42, 0x46,
+ 0x0A, 0x98, 0x98, 0x47, 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1, 0x16, 0x08,
+ 0xC0, 0xB2, 0xE1, 0x88, 0x81, 0x46, 0x49, 0x45, 0xC4, 0xD8, 0x50, 0xE0,
+ 0x04, 0x21, 0xEC, 0xE7, 0x21, 0x89, 0x04, 0x29, 0x61, 0x89, 0x01, 0xEB,
+ 0x00, 0x08, 0x4F, 0xF0, 0x00, 0x00, 0x19, 0xD0, 0x41, 0xE0, 0xB8, 0xF8,
+ 0x02, 0x00, 0x00, 0x90, 0xB8, 0xF8, 0x00, 0x30, 0x02, 0x22, 0x3E, 0x49,
+ 0x3B, 0x48, 0xF1, 0xF7, 0xC8, 0xDE, 0xB8, 0xF8, 0x00, 0x70, 0x35, 0xB1,
+ 0x68, 0x68, 0x43, 0x68, 0x1B, 0xB1, 0x05, 0x21, 0x42, 0x46, 0x0A, 0x98,
+ 0x98, 0x47, 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1, 0x04, 0x08, 0xC0, 0xB2,
+ 0xE1, 0x88, 0x81, 0x46, 0x49, 0x45, 0xE2, 0xD8, 0x27, 0xE0, 0x10, 0x22,
+ 0x08, 0xF1, 0x02, 0x01, 0x06, 0xA8, 0x23, 0xF4, 0xC2, 0xF7, 0x06, 0xAF,
+ 0x97, 0xE8, 0x0F, 0x00, 0xCD, 0xE9, 0x02, 0x10, 0xCD, 0xE9, 0x00, 0x32,
+ 0x2B, 0x49, 0xB8, 0xF8, 0x00, 0x30, 0x05, 0x22, 0x30, 0x31, 0x27, 0x48,
+ 0xF1, 0xF7, 0x9F, 0xDE, 0xB8, 0xF8, 0x00, 0x70, 0x35, 0xB1, 0x68, 0x68,
+ 0x43, 0x68, 0x1B, 0xB1, 0x06, 0x21, 0x42, 0x46, 0x0A, 0x98, 0x98, 0x47,
+ 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1, 0x12, 0x08, 0xC0, 0xB2, 0xE1, 0x88,
+ 0x81, 0x46, 0x49, 0x45, 0xD7, 0xD8, 0x78, 0x1C, 0x30, 0x83, 0x1F, 0xB1,
+ 0x70, 0x8B, 0xB8, 0x42, 0x09, 0xD9, 0x0D, 0xE0, 0x01, 0x20, 0x0B, 0x90,
+ 0x19, 0x49, 0x17, 0x48, 0x00, 0x22, 0x70, 0x31, 0x80, 0x1E, 0xF1, 0xF7,
+ 0x7C, 0xDE, 0x00, 0x20, 0x30, 0x83, 0x70, 0x83, 0x4F, 0xF0, 0x01, 0x0A,
+ 0x73, 0x8B, 0x32, 0x8B, 0xA1, 0x78, 0x20, 0x88, 0xFB, 0xF7, 0x94, 0xFA,
+ 0xBA, 0xF1, 0x00, 0x0F, 0x5D, 0xD0, 0x33, 0x78, 0x01, 0x2B, 0x1D, 0xD0,
+ 0x03, 0x2B, 0x1D, 0xD0, 0x05, 0x2B, 0x1D, 0xD0, 0x09, 0x2B, 0x27, 0xD0,
+ 0x0A, 0x49, 0x08, 0x48, 0x01, 0x22, 0xAC, 0x31, 0x80, 0x1E, 0xF1, 0xF7,
+ 0x5E, 0xDE, 0xA0, 0x88, 0xA0, 0xF5, 0x80, 0x61, 0x0A, 0x39, 0x1D, 0xD0,
+ 0xF0, 0xB9, 0x1B, 0xE0, 0xA0, 0x78, 0x20, 0x00, 0xA8, 0x65, 0xC0, 0x08,
+ 0x02, 0x33, 0x10, 0x21, 0xE8, 0x66, 0xC0, 0x08, 0xE8, 0x67, 0xC0, 0x08,
+ 0x02, 0x20, 0x07, 0xE0, 0x04, 0x20, 0x05, 0xE0, 0x70, 0x79, 0x01, 0x28,
+ 0x04, 0xD0, 0x02, 0x28, 0x04, 0xD0, 0x06, 0x20, 0x30, 0x70, 0xE2, 0xE7,
+ 0x07, 0x20, 0xFB, 0xE7, 0x08, 0x20, 0xF9, 0xE7, 0x0A, 0x20, 0xF7, 0xE7,
+ 0x0B, 0x98, 0x38, 0xB1, 0x0B, 0x20, 0x30, 0x70, 0xA3, 0x88, 0x01, 0x22,
+ 0x13, 0x49, 0x14, 0x48, 0xF1, 0xF7, 0x31, 0xDE, 0x11, 0x49, 0x12, 0x48,
+ 0x33, 0x78, 0x01, 0x22, 0x34, 0x31, 0xC0, 0x1C, 0xF1, 0xF7, 0x29, 0xDE,
+ 0x00, 0x20, 0x30, 0x71, 0x45, 0xB1, 0x69, 0x68, 0x0A, 0x68, 0x2A, 0xB1,
+ 0x31, 0x78, 0x0A, 0x98, 0x0D, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0x10, 0x47,
+ 0xDB, 0xF8, 0x04, 0x30, 0x00, 0x2B, 0x08, 0xD0, 0x8D, 0xF8, 0x00, 0x00,
+ 0x30, 0x78, 0x8D, 0xF8, 0x04, 0x00, 0x6A, 0x46, 0xFF, 0x20, 0x0A, 0x99,
+ 0x98, 0x47, 0x0D, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xC8, 0x68, 0xC0, 0x08,
+ 0x00, 0x33, 0x10, 0x21, 0xFE, 0xB5, 0x81, 0x88, 0x00, 0x29, 0x2D, 0xD0,
+ 0x00, 0x88, 0x0D, 0xF0, 0xF7, 0xFA, 0x00, 0x28, 0x28, 0xD0, 0x15, 0x4D,
+ 0xC6, 0x78, 0x00, 0x27, 0xA8, 0x68, 0x06, 0xEB, 0x86, 0x04, 0x00, 0xEB,
+ 0xC4, 0x01, 0x0B, 0x22, 0x0F, 0x71, 0x00, 0xF8, 0x34, 0x20, 0x48, 0x78,
+ 0xFF, 0xF7, 0x6C, 0xFA, 0x50, 0xB1, 0x40, 0x68, 0x02, 0x68, 0x3A, 0xB1,
+ 0xA8, 0x68, 0x10, 0xF8, 0x34, 0x10, 0x03, 0xB0, 0x30, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x40, 0x10, 0x47, 0x6B, 0x68, 0x00, 0x2B, 0x0A, 0xD0, 0x8D, 0xF8,
+ 0x00, 0x70, 0xA8, 0x68, 0x6A, 0x46, 0x31, 0x46, 0x10, 0xF8, 0x34, 0x00,
+ 0x8D, 0xF8, 0x04, 0x00, 0xFF, 0x20, 0x98, 0x47, 0xFE, 0xBD, 0x00, 0x00,
+ 0xA0, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x04, 0x46, 0x10, 0x48, 0x00, 0x78,
+ 0x00, 0xEB, 0x80, 0x00, 0xC5, 0x00, 0xFA, 0xF7, 0x8D, 0xFC, 0x90, 0xB1,
+ 0x4E, 0x23, 0x0D, 0x4A, 0x29, 0x46, 0x00, 0x20, 0xFC, 0xF7, 0x58, 0xDB,
+ 0x0B, 0x4D, 0x00, 0x28, 0xA8, 0x60, 0x07, 0xD0, 0xE1, 0x00, 0x2C, 0x70,
+ 0x55, 0x23, 0x07, 0x4A, 0x00, 0x20, 0xFC, 0xF7, 0x4D, 0xDB, 0xE8, 0x60,
+ 0x70, 0xBD, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x22, 0x04, 0x49, 0x05, 0x48,
+ 0xF1, 0xF7, 0xAF, 0x9D, 0x61, 0x78, 0x20, 0x00, 0x5C, 0xB2, 0x82, 0x00,
+ 0xA0, 0x78, 0x20, 0x00, 0x68, 0x62, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0x01, 0x49, 0x48, 0x60, 0x70, 0x47, 0x00, 0x00, 0xA0, 0x78, 0x20, 0x00,
+ 0x38, 0xB5, 0x10, 0x4A, 0x53, 0x78, 0x03, 0x70, 0x53, 0x78, 0x14, 0x78,
+ 0xA3, 0x42, 0x07, 0xD3, 0x02, 0x22, 0x0D, 0x49, 0x0D, 0x48, 0x00, 0x94,
+ 0xF1, 0xF7, 0x91, 0xDD, 0x00, 0x20, 0x38, 0xBD, 0xD4, 0x68, 0x01, 0x25,
+ 0x04, 0xF8, 0x33, 0x50, 0x53, 0x78, 0x00, 0x78, 0x04, 0xEB, 0xC3, 0x03,
+ 0x58, 0x70, 0x50, 0x78, 0x04, 0xEB, 0xC0, 0x00, 0x41, 0x60, 0x50, 0x78,
+ 0x40, 0x1C, 0x50, 0x70, 0x28, 0x46, 0x38, 0xBD, 0xA0, 0x78, 0x20, 0x00,
+ 0x90, 0x62, 0xC0, 0x08, 0x00, 0x33, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x41,
+ 0x1C, 0x46, 0x15, 0x46, 0x0E, 0x46, 0x07, 0x46, 0xFF, 0xF7, 0xBA, 0xF9,
+ 0x68, 0xB1, 0x00, 0x20, 0x03, 0x94, 0x00, 0x90, 0xCD, 0xE9, 0x01, 0x05,
+ 0x33, 0x46, 0x03, 0x22, 0x05, 0x21, 0x38, 0x46, 0x00, 0xF0, 0x06, 0xF8,
+ 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x02, 0x20, 0xFA, 0xE7, 0x00, 0x00,
+ 0x2D, 0xE9, 0xFC, 0x5F, 0x99, 0x46, 0xDD, 0xE9, 0x0E, 0x58, 0xDD, 0xE9,
+ 0x0C, 0xAB, 0x16, 0x46, 0x0C, 0x46, 0x07, 0x46, 0x0B, 0x46, 0x01, 0x22,
+ 0x17, 0x49, 0x18, 0x48, 0xF1, 0xF7, 0x4D, 0xDD, 0x17, 0x49, 0xCD, 0xE9,
+ 0x00, 0xAB, 0x07, 0xEB, 0x47, 0x00, 0x09, 0x68, 0x43, 0x46, 0x01, 0xEB,
+ 0x00, 0x10, 0x2A, 0x46, 0x00, 0x8A, 0x21, 0x46, 0xFB, 0xF7, 0xAC, 0xF9,
+ 0x80, 0xB1, 0x11, 0x49, 0x07, 0xEB, 0x87, 0x00, 0x00, 0x24, 0x89, 0x68,
+ 0x01, 0xF8, 0x30, 0x60, 0x01, 0xEB, 0xC0, 0x01, 0x01, 0x20, 0x0D, 0x83,
+ 0xA1, 0xF8, 0x1A, 0x80, 0x81, 0xF8, 0x01, 0x90, 0x08, 0x71, 0x07, 0xE0,
+ 0x05, 0x49, 0x06, 0x48, 0x07, 0x24, 0x00, 0x22, 0x34, 0x31, 0xC0, 0x1E,
+ 0xF1, 0xF7, 0x25, 0xDD, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x9F, 0x00, 0x00,
+ 0x84, 0x63, 0xC0, 0x08, 0x03, 0x33, 0x10, 0x21, 0x64, 0x78, 0x20, 0x00,
+ 0xA0, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x41, 0x07, 0x46, 0x13, 0x48,
+ 0x0C, 0x46, 0x1D, 0x46, 0x90, 0xF8, 0xC2, 0x11, 0x16, 0x46, 0x49, 0x06,
+ 0x02, 0xD4, 0x02, 0x20, 0xBD, 0xE8, 0xFC, 0x81, 0x90, 0xF8, 0xCB, 0x01,
+ 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0xF6, 0xE7, 0xCD, 0xE9,
+ 0x00, 0x65, 0x23, 0x46, 0x03, 0x22, 0x09, 0x49, 0x09, 0x48, 0xF1, 0xF7,
+ 0xFC, 0xDC, 0x00, 0x94, 0x08, 0x4C, 0x33, 0x46, 0x20, 0x8A, 0xA1, 0x89,
+ 0xE2, 0x89, 0x08, 0x44, 0x28, 0x44, 0x81, 0xB2, 0x38, 0x46, 0x07, 0xF0,
+ 0xBE, 0xFB, 0xE1, 0xE7, 0x64, 0x01, 0x20, 0x00, 0x10, 0x7D, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, 0x1C, 0xB5, 0x04, 0x46,
+ 0x00, 0x20, 0x01, 0x90, 0x10, 0x48, 0x90, 0xF8, 0xC2, 0x11, 0xC9, 0x06,
+ 0x01, 0xD4, 0x02, 0x20, 0x1C, 0xBD, 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E,
+ 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0x1C, 0xBD, 0x23, 0x46, 0x01, 0x22,
+ 0x09, 0x49, 0x0A, 0x48, 0xF1, 0xF7, 0xCF, 0xDC, 0x09, 0x48, 0x00, 0x94,
+ 0x04, 0x23, 0x01, 0x8A, 0x02, 0x89, 0x11, 0x44, 0x14, 0x31, 0xC2, 0x89,
+ 0x89, 0xB2, 0x01, 0xA8, 0x07, 0xF0, 0x91, 0xFB, 0x1C, 0xBD, 0x00, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0xE0, 0x7B, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21,
+ 0xE0, 0x78, 0x20, 0x00, 0x1C, 0xB5, 0x04, 0x46, 0x00, 0x20, 0x01, 0x90,
+ 0x10, 0x48, 0x90, 0xF8, 0xC2, 0x11, 0x89, 0x06, 0x01, 0xD4, 0x02, 0x20,
+ 0x1C, 0xBD, 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA,
+ 0x01, 0x20, 0x1C, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, 0x0A, 0x48,
+ 0xF1, 0xF7, 0xA1, 0xDC, 0x09, 0x48, 0x00, 0x94, 0x04, 0x23, 0x01, 0x8A,
+ 0x42, 0x89, 0x11, 0x44, 0x14, 0x31, 0xC2, 0x89, 0x89, 0xB2, 0x01, 0xA8,
+ 0x07, 0xF0, 0x63, 0xFB, 0x1C, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0xA4, 0x7C, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00,
+ 0x1C, 0xB5, 0x04, 0x46, 0x00, 0x20, 0x01, 0x90, 0x10, 0x48, 0x90, 0xF8,
+ 0xC2, 0x11, 0x09, 0x07, 0x01, 0xD4, 0x02, 0x20, 0x1C, 0xBD, 0x90, 0xF8,
+ 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0x1C, 0xBD,
+ 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, 0x0A, 0x48, 0xF1, 0xF7, 0x73, 0xDC,
+ 0x09, 0x48, 0x00, 0x94, 0x04, 0x23, 0x01, 0x8A, 0xC2, 0x88, 0x11, 0x44,
+ 0x14, 0x31, 0xC2, 0x89, 0x89, 0xB2, 0x01, 0xA8, 0x07, 0xF0, 0x35, 0xFB,
+ 0x1C, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0x74, 0x7B, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, 0x30, 0xB5, 0x24, 0x4C,
+ 0x24, 0x4A, 0x87, 0xB0, 0x14, 0x20, 0x20, 0x80, 0xB2, 0xF8, 0xC2, 0x11,
+ 0x1C, 0x20, 0x8B, 0x07, 0x01, 0xD5, 0x60, 0x80, 0x3C, 0x20, 0x4B, 0x07,
+ 0x01, 0xD5, 0xA0, 0x80, 0x20, 0x30, 0x0B, 0x07, 0x01, 0xD5, 0xE0, 0x80,
+ 0x18, 0x30, 0xCB, 0x06, 0x01, 0xD5, 0x20, 0x81, 0x18, 0x30, 0x8B, 0x06,
+ 0x01, 0xD5, 0x60, 0x81, 0x18, 0x30, 0x49, 0x06, 0x06, 0xD5, 0x92, 0xF8,
+ 0xC1, 0x11, 0x04, 0x23, 0x03, 0xEB, 0x81, 0x01, 0xA0, 0x81, 0x08, 0x44,
+ 0x14, 0x38, 0x83, 0xB2, 0xE3, 0x81, 0x50, 0x20, 0x20, 0x82, 0x92, 0xF8,
+ 0xCB, 0x11, 0x11, 0x4D, 0xCD, 0xE9, 0x00, 0x01, 0x03, 0x22, 0x0E, 0x49,
+ 0x28, 0x46, 0xF1, 0xF7, 0x28, 0xDC, 0xE0, 0x88, 0x0D, 0xF1, 0x08, 0x0C,
+ 0xA3, 0x89, 0x62, 0x89, 0x21, 0x89, 0x8C, 0xE8, 0x0F, 0x00, 0xA1, 0x88,
+ 0x60, 0x88, 0xCD, 0xE9, 0x00, 0x01, 0x06, 0x49, 0x23, 0x88, 0x07, 0x22,
+ 0x60, 0x31, 0x28, 0x46, 0xF1, 0xF7, 0x15, 0xDC, 0x07, 0xB0, 0x30, 0xBD,
+ 0xE0, 0x78, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0xB8, 0x7D, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0x38, 0xB5, 0x0C, 0x46, 0x03, 0x46, 0x01, 0x22,
+ 0x06, 0x49, 0x07, 0x48, 0xF1, 0xF7, 0x03, 0xDC, 0x00, 0x20, 0x02, 0x46,
+ 0x00, 0x90, 0x05, 0x48, 0x14, 0x23, 0x01, 0x8A, 0x20, 0x46, 0x07, 0xF0,
+ 0xB5, 0xFA, 0x38, 0xBD, 0x34, 0x7A, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21,
+ 0xE0, 0x78, 0x20, 0x00, 0xF8, 0xB5, 0x05, 0x46, 0x18, 0x48, 0x0C, 0x46,
+ 0x04, 0x22, 0x90, 0xF8, 0xC1, 0x11, 0x02, 0xEB, 0x81, 0x01, 0xCE, 0xB2,
+ 0x90, 0xF8, 0xC2, 0x11, 0x49, 0x06, 0x01, 0xD4, 0x02, 0x20, 0xF8, 0xBD,
+ 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20,
+ 0xF8, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x0E, 0x49, 0x0E, 0x48, 0xF1, 0xF7,
+ 0xD6, 0xDB, 0x20, 0x46, 0x00, 0xF0, 0x5A, 0xF9, 0x00, 0x1D, 0xC3, 0xB2,
+ 0x04, 0x2B, 0x01, 0xD0, 0xB3, 0x42, 0x02, 0xD9, 0x00, 0x20, 0x28, 0x70,
+ 0xE4, 0xE7, 0x08, 0x48, 0x00, 0x94, 0x01, 0x8A, 0x82, 0x89, 0x11, 0x44,
+ 0xC2, 0x89, 0x89, 0xB2, 0x28, 0x46, 0x07, 0xF0, 0x7B, 0xFA, 0xF8, 0xBD,
+ 0x64, 0x01, 0x20, 0x00, 0x40, 0x7D, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21,
+ 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x05, 0x46, 0x10, 0x48, 0x0C, 0x46,
+ 0x90, 0xF8, 0xC2, 0x11, 0xC9, 0x06, 0x01, 0xD4, 0x02, 0x20, 0x38, 0xBD,
+ 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20,
+ 0x38, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, 0x09, 0x48, 0xF1, 0xF7,
+ 0xA0, 0xDB, 0x09, 0x4A, 0x00, 0x94, 0x18, 0x23, 0x10, 0x8A, 0x11, 0x89,
+ 0xD2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x28, 0x46, 0x07, 0xF0, 0x50, 0xFA,
+ 0x38, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0x5C, 0x7C, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x05, 0x46,
+ 0x10, 0x48, 0x0C, 0x46, 0x90, 0xF8, 0xC2, 0x11, 0x89, 0x07, 0x01, 0xD4,
+ 0x02, 0x20, 0x38, 0xBD, 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42,
+ 0x01, 0xDA, 0x01, 0x20, 0x38, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49,
+ 0x09, 0x48, 0xF1, 0xF7, 0x74, 0xDB, 0x09, 0x4A, 0x00, 0x94, 0x20, 0x23,
+ 0x10, 0x8A, 0x51, 0x88, 0xD2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x28, 0x46,
+ 0x07, 0xF0, 0x24, 0xFA, 0x38, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0xE8, 0x7A, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00,
+ 0x38, 0xB5, 0x05, 0x46, 0x0D, 0x48, 0x0C, 0x46, 0x90, 0xF8, 0xCB, 0x01,
+ 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0x38, 0xBD, 0x0B, 0x46,
+ 0x01, 0x22, 0x09, 0x49, 0x09, 0x48, 0xF1, 0xF7, 0x4E, 0xDB, 0x09, 0x4A,
+ 0x00, 0x94, 0x08, 0x23, 0x10, 0x8A, 0x11, 0x88, 0xD2, 0x89, 0x08, 0x44,
+ 0x81, 0xB2, 0x28, 0x46, 0x07, 0xF0, 0xFE, 0xF9, 0x38, 0xBD, 0x00, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0xA8, 0x7A, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21,
+ 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x05, 0x46, 0x10, 0x48, 0x0C, 0x46,
+ 0x90, 0xF8, 0xC2, 0x11, 0x89, 0x06, 0x01, 0xD4, 0x02, 0x20, 0x38, 0xBD,
+ 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20,
+ 0x38, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, 0x09, 0x48, 0xF1, 0xF7,
+ 0x22, 0xDB, 0x09, 0x4A, 0x00, 0x94, 0x18, 0x23, 0x10, 0x8A, 0x51, 0x89,
+ 0xD2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x28, 0x46, 0x07, 0xF0, 0xD2, 0xF9,
+ 0x38, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0xC8, 0x7C, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x05, 0x46,
+ 0x10, 0x48, 0x0C, 0x46, 0x90, 0xF8, 0xC2, 0x11, 0x09, 0x07, 0x01, 0xD4,
+ 0x02, 0x20, 0x38, 0xBD, 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42,
+ 0x01, 0xDA, 0x01, 0x20, 0x38, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49,
+ 0x09, 0x48, 0xF1, 0xF7, 0xF6, 0xDA, 0x09, 0x4A, 0x00, 0x94, 0x18, 0x23,
+ 0x10, 0x8A, 0xD1, 0x88, 0xD2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x28, 0x46,
+ 0x07, 0xF0, 0xA6, 0xF9, 0x38, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x98, 0x7B, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00,
+ 0x38, 0xB5, 0x05, 0x46, 0x10, 0x48, 0x0C, 0x46, 0x90, 0xF8, 0xC2, 0x11,
+ 0x49, 0x07, 0x01, 0xD4, 0x02, 0x20, 0x38, 0xBD, 0x90, 0xF8, 0xCB, 0x01,
+ 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0x38, 0xBD, 0x23, 0x46,
+ 0x01, 0x22, 0x09, 0x49, 0x09, 0x48, 0xF1, 0xF7, 0xCA, 0xDA, 0x09, 0x4A,
+ 0x00, 0x94, 0x20, 0x23, 0x10, 0x8A, 0x91, 0x88, 0xD2, 0x89, 0x08, 0x44,
+ 0x81, 0xB2, 0x28, 0x46, 0x07, 0xF0, 0x7A, 0xF9, 0x38, 0xBD, 0x00, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x2C, 0x7B, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21,
+ 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x04, 0x46, 0x00, 0x22, 0x06, 0x49,
+ 0x06, 0x48, 0xF1, 0xF7, 0xAE, 0xDA, 0x00, 0x21, 0x0A, 0x46, 0x00, 0x91,
+ 0x04, 0x23, 0x28, 0x21, 0x20, 0x46, 0x07, 0xF0, 0x61, 0xF9, 0x38, 0xBD,
+ 0xC4, 0x79, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x38, 0xB5, 0x04, 0x46,
+ 0x00, 0x22, 0x06, 0x49, 0x06, 0x48, 0xF1, 0xF7, 0x9A, 0xDA, 0x00, 0x21,
+ 0x0A, 0x46, 0x00, 0x91, 0x10, 0x23, 0x2C, 0x21, 0x20, 0x46, 0x07, 0xF0,
+ 0x4D, 0xF9, 0x38, 0xBD, 0xF8, 0x79, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21,
+ 0x38, 0xB5, 0x04, 0x46, 0x00, 0x22, 0x06, 0x49, 0x06, 0x48, 0xF1, 0xF7,
+ 0x86, 0xDA, 0x00, 0x21, 0x28, 0x23, 0x0A, 0x46, 0x20, 0x46, 0x00, 0x91,
+ 0x07, 0xF0, 0x3A, 0xF9, 0x38, 0xBD, 0x00, 0x00, 0x90, 0x79, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0x7C, 0xB5, 0x04, 0x46, 0x17, 0x48, 0x90, 0xF8,
+ 0xC2, 0x11, 0x49, 0x06, 0x01, 0xD4, 0x02, 0x20, 0x7C, 0xBD, 0x90, 0xF8,
+ 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0x7C, 0xBD,
+ 0x11, 0x4A, 0x00, 0x94, 0x04, 0x23, 0x10, 0x8A, 0x91, 0x89, 0xD2, 0x89,
+ 0x08, 0x44, 0x81, 0xB2, 0x01, 0xA8, 0x07, 0xF0, 0x19, 0xF9, 0x0D, 0x4D,
+ 0x38, 0xB1, 0x23, 0x46, 0x01, 0x22, 0x0C, 0x49, 0x28, 0x46, 0xF1, 0xF7,
+ 0x56, 0xDA, 0x00, 0x20, 0x7C, 0xBD, 0x9D, 0xF8, 0x04, 0x00, 0x08, 0x49,
+ 0x00, 0x90, 0x23, 0x46, 0x02, 0x22, 0x2C, 0x39, 0x28, 0x46, 0xF1, 0xF7,
+ 0x4A, 0xDA, 0x9D, 0xF8, 0x04, 0x00, 0x7C, 0xBD, 0x64, 0x01, 0x20, 0x00,
+ 0xE0, 0x78, 0x20, 0x00, 0x03, 0x35, 0x10, 0x21, 0x88, 0x7D, 0xC0, 0x08,
+ 0x38, 0xB5, 0x0C, 0x46, 0x03, 0x46, 0x01, 0x22, 0x06, 0x49, 0x07, 0x48,
+ 0xF1, 0xF7, 0x37, 0xDA, 0x00, 0x20, 0x02, 0x46, 0x00, 0x90, 0x05, 0x48,
+ 0x14, 0x23, 0x01, 0x8A, 0x20, 0x46, 0x07, 0xF0, 0xFC, 0xF8, 0x38, 0xBD,
+ 0x10, 0x7A, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00,
+ 0xF8, 0xB5, 0x06, 0x46, 0x11, 0x48, 0x0C, 0x46, 0x15, 0x46, 0x90, 0xF8,
+ 0xC2, 0x11, 0x49, 0x06, 0x01, 0xD4, 0x02, 0x20, 0xF8, 0xBD, 0x90, 0xF8,
+ 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0xF8, 0xBD,
+ 0x23, 0x46, 0x02, 0x22, 0x09, 0x49, 0x0A, 0x48, 0x00, 0x95, 0xF1, 0xF7,
+ 0x0E, 0xDA, 0x00, 0x94, 0x08, 0x4C, 0x2B, 0x46, 0x20, 0x8A, 0xA1, 0x89,
+ 0xE2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x30, 0x46, 0x07, 0xF0, 0xD1, 0xF8,
+ 0xF8, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0xEC, 0x7C, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x05, 0x46,
+ 0x10, 0x48, 0x0C, 0x46, 0x90, 0xF8, 0xC2, 0x11, 0xC9, 0x06, 0x01, 0xD4,
+ 0x02, 0x20, 0x38, 0xBD, 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42,
+ 0x01, 0xDA, 0x01, 0x20, 0x38, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49,
+ 0x09, 0x48, 0xF1, 0xF7, 0xE2, 0xD9, 0x09, 0x4A, 0x00, 0x94, 0x18, 0x23,
+ 0x10, 0x8A, 0x11, 0x89, 0xD2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x28, 0x46,
+ 0x07, 0xF0, 0xA5, 0xF8, 0x38, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0xBC, 0x7B, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00,
+ 0xF8, 0xB5, 0x06, 0x46, 0x10, 0x48, 0x0C, 0x46, 0x15, 0x46, 0x90, 0xF8,
+ 0xC2, 0x11, 0x89, 0x07, 0x01, 0xD4, 0x02, 0x20, 0xF8, 0xBD, 0x90, 0xF8,
+ 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0xF8, 0xBD,
+ 0x23, 0x46, 0x01, 0x22, 0x08, 0x49, 0x09, 0x48, 0xF1, 0xF7, 0xB5, 0xD9,
+ 0x00, 0x94, 0x08, 0x4C, 0x2B, 0x46, 0x20, 0x8A, 0x61, 0x88, 0xE2, 0x89,
+ 0x08, 0x44, 0x81, 0xB2, 0x30, 0x46, 0x07, 0xF0, 0x78, 0xF8, 0xF8, 0xBD,
+ 0x64, 0x01, 0x20, 0x00, 0xC8, 0x7A, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21,
+ 0xE0, 0x78, 0x20, 0x00, 0x3E, 0xB5, 0x04, 0x46, 0x11, 0x48, 0x0D, 0x46,
+ 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA8, 0x42, 0x01, 0xDA, 0x01, 0x20,
+ 0x3E, 0xBD, 0x21, 0x46, 0x0D, 0x48, 0xF1, 0xF7, 0x61, 0xDB, 0xA2, 0x79,
+ 0xE1, 0x79, 0xCD, 0xE9, 0x00, 0x02, 0x02, 0x91, 0x2B, 0x46, 0x04, 0x22,
+ 0x09, 0x49, 0x0A, 0x48, 0xF1, 0xF7, 0x87, 0xD9, 0x09, 0x48, 0x00, 0x95,
+ 0x08, 0x23, 0x01, 0x8A, 0x02, 0x88, 0x11, 0x44, 0xC2, 0x89, 0x89, 0xB2,
+ 0x20, 0x46, 0x07, 0xF0, 0x4A, 0xF8, 0x3E, 0xBD, 0x64, 0x01, 0x20, 0x00,
+ 0x00, 0x00, 0x30, 0x21, 0x58, 0x7A, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21,
+ 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x05, 0x46, 0x10, 0x48, 0x0C, 0x46,
+ 0x90, 0xF8, 0xC2, 0x11, 0x89, 0x06, 0x01, 0xD4, 0x02, 0x20, 0x38, 0xBD,
+ 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20,
+ 0x38, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, 0x09, 0x48, 0xF1, 0xF7,
+ 0x5A, 0xD9, 0x09, 0x4A, 0x00, 0x94, 0x18, 0x23, 0x10, 0x8A, 0x51, 0x89,
+ 0xD2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x28, 0x46, 0x07, 0xF0, 0x1D, 0xF8,
+ 0x38, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0x80, 0x7C, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x05, 0x46,
+ 0x10, 0x48, 0x0C, 0x46, 0x90, 0xF8, 0xC2, 0x11, 0x09, 0x07, 0x01, 0xD4,
+ 0x02, 0x20, 0x38, 0xBD, 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42,
+ 0x01, 0xDA, 0x01, 0x20, 0x38, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49,
+ 0x09, 0x48, 0xF1, 0xF7, 0x2E, 0xD9, 0x09, 0x4A, 0x00, 0x94, 0x18, 0x23,
+ 0x10, 0x8A, 0xD1, 0x88, 0xD2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x28, 0x46,
+ 0x06, 0xF0, 0xF1, 0xFF, 0x38, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x50, 0x7B, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00,
+ 0xF8, 0xB5, 0x06, 0x46, 0x10, 0x48, 0x0C, 0x46, 0x15, 0x46, 0x90, 0xF8,
+ 0xC2, 0x11, 0x49, 0x07, 0x01, 0xD4, 0x02, 0x20, 0xF8, 0xBD, 0x90, 0xF8,
+ 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0xF8, 0xBD,
+ 0x23, 0x46, 0x01, 0x22, 0x08, 0x49, 0x09, 0x48, 0xF1, 0xF7, 0x01, 0xD9,
+ 0x00, 0x94, 0x08, 0x4C, 0x2B, 0x46, 0x20, 0x8A, 0xA1, 0x88, 0xE2, 0x89,
+ 0x08, 0x44, 0x81, 0xB2, 0x30, 0x46, 0x06, 0xF0, 0xC4, 0xFF, 0xF8, 0xBD,
+ 0x64, 0x01, 0x20, 0x00, 0x08, 0x7B, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21,
+ 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x04, 0x46, 0x00, 0x22, 0x06, 0x49,
+ 0x06, 0x48, 0xF1, 0xF7, 0xE6, 0xD8, 0x00, 0x21, 0x0A, 0x46, 0x00, 0x91,
+ 0x04, 0x23, 0x28, 0x21, 0x20, 0x46, 0x06, 0xF0, 0xAC, 0xFF, 0x38, 0xBD,
+ 0xA8, 0x79, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x38, 0xB5, 0x04, 0x46,
+ 0x00, 0x22, 0x06, 0x49, 0x06, 0x48, 0xF1, 0xF7, 0xD2, 0xD8, 0x00, 0x21,
+ 0x0A, 0x46, 0x00, 0x91, 0x10, 0x23, 0x2C, 0x21, 0x20, 0x46, 0x06, 0xF0,
+ 0x98, 0xFF, 0x38, 0xBD, 0xE0, 0x79, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21,
+ 0x38, 0xB5, 0x04, 0x46, 0x00, 0x22, 0x06, 0x49, 0x06, 0x48, 0xF1, 0xF7,
+ 0xBE, 0xD8, 0x00, 0x21, 0x28, 0x23, 0x0A, 0x46, 0x20, 0x46, 0x00, 0x91,
+ 0x06, 0xF0, 0x85, 0xFF, 0x38, 0xBD, 0x00, 0x00, 0x78, 0x79, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0x13, 0xB5, 0x04, 0x46, 0x11, 0x48, 0x82, 0xB0,
+ 0x90, 0xF8, 0xC2, 0x11, 0xC9, 0x06, 0x02, 0xD4, 0x02, 0x20, 0x04, 0xB0,
+ 0x10, 0xBD, 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA,
+ 0x01, 0x20, 0xF6, 0xE7, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, 0x0A, 0x48,
+ 0xF1, 0xF7, 0x99, 0xD8, 0x09, 0x48, 0x00, 0x94, 0x04, 0x23, 0x01, 0x8A,
+ 0x02, 0x89, 0x11, 0x44, 0x10, 0x31, 0xC2, 0x89, 0x89, 0xB2, 0x03, 0xA8,
+ 0x06, 0xF0, 0x5B, 0xFF, 0xE3, 0xE7, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x04, 0x7C, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00,
+ 0x13, 0xB5, 0x04, 0x46, 0x11, 0x48, 0x82, 0xB0, 0x90, 0xF8, 0xC2, 0x11,
+ 0x89, 0x06, 0x02, 0xD4, 0x02, 0x20, 0x04, 0xB0, 0x10, 0xBD, 0x90, 0xF8,
+ 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0xF6, 0xE7,
+ 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, 0x0A, 0x48, 0xF1, 0xF7, 0x6B, 0xD8,
+ 0x09, 0x48, 0x00, 0x94, 0x04, 0x23, 0x01, 0x8A, 0x42, 0x89, 0x11, 0x44,
+ 0x10, 0x31, 0xC2, 0x89, 0x89, 0xB2, 0x03, 0xA8, 0x06, 0xF0, 0x2D, 0xFF,
+ 0xE3, 0xE7, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0x30, 0x7C, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, 0x31, 0xB5, 0x82, 0xB0,
+ 0x01, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x13, 0x4C, 0x3E, 0x20, 0x00, 0x90,
+ 0x10, 0x4B, 0x00, 0x22, 0x02, 0xA9, 0xE0, 0x68, 0xFB, 0xF7, 0x00, 0xDF,
+ 0x0F, 0x4D, 0x78, 0xB1, 0x43, 0x20, 0x00, 0x90, 0x0B, 0x4B, 0x00, 0x22,
+ 0x01, 0xA9, 0x20, 0x69, 0xFB, 0xF7, 0xF6, 0xDE, 0x00, 0x28, 0x04, 0xD1,
+ 0x00, 0x22, 0x0A, 0x49, 0x28, 0x46, 0xF1, 0xF7, 0x36, 0xD8, 0x3E, 0xBD,
+ 0x07, 0x49, 0x00, 0x22, 0x2C, 0x39, 0x28, 0x46, 0xF1, 0xF7, 0x2F, 0xD8,
+ 0x02, 0x98, 0xF9, 0xF7, 0xB1, 0xFE, 0x3E, 0xBD, 0xA8, 0xB0, 0x82, 0x00,
+ 0xF0, 0x77, 0x20, 0x00, 0x00, 0x35, 0x10, 0x21, 0xDC, 0x5A, 0xC0, 0x08,
+ 0x10, 0xB5, 0xF9, 0xF7, 0xA5, 0xFE, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD,
+ 0x07, 0x20, 0x10, 0xBD, 0xC1, 0x88, 0x00, 0x29, 0x06, 0xD1, 0x04, 0x49,
+ 0x02, 0x68, 0x4A, 0x61, 0x80, 0x88, 0x08, 0x83, 0x00, 0xF0, 0xE0, 0xBC,
+ 0x70, 0x47, 0x00, 0x00, 0xF0, 0x77, 0x20, 0x00, 0x70, 0xB5, 0x03, 0x46,
+ 0xA0, 0xF5, 0x00, 0x75, 0x00, 0x24, 0x15, 0x48, 0x15, 0x4A, 0x06, 0x2D,
+ 0x1D, 0xD2, 0xDF, 0xE8, 0x05, 0xF0, 0x03, 0x1C, 0x12, 0x14, 0x17, 0x1A,
+ 0x12, 0x4A, 0x12, 0x78, 0xD2, 0x07, 0x04, 0xD0, 0x42, 0x69, 0x0A, 0x60,
+ 0x00, 0x8B, 0x88, 0x80, 0x15, 0xE0, 0x0F, 0x48, 0x50, 0xF8, 0x33, 0x2F,
+ 0x0A, 0x60, 0x80, 0x88, 0xF7, 0xE7, 0x10, 0x78, 0x03, 0xE0, 0x50, 0x88,
+ 0x08, 0x80, 0x0A, 0xE0, 0x50, 0x78, 0x08, 0x70, 0x07, 0xE0, 0x00, 0x78,
+ 0xFB, 0xE7, 0x03, 0x24, 0x01, 0x22, 0x07, 0x49, 0x07, 0x48, 0xF0, 0xF7,
+ 0xE0, 0xDF, 0x20, 0x46, 0x70, 0xBD, 0x00, 0x00, 0xF0, 0x77, 0x20, 0x00,
+ 0x4A, 0x74, 0x20, 0x00, 0x38, 0x78, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x60, 0x5B, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0xC0, 0x88, 0x00, 0x28,
+ 0x01, 0xD1, 0x00, 0xF0, 0x31, 0xBA, 0x70, 0x47, 0x41, 0x88, 0x05, 0x29,
+ 0x06, 0xD0, 0x0E, 0x29, 0x07, 0xD0, 0x0F, 0x29, 0x08, 0xD1, 0x00, 0x1D,
+ 0x00, 0xF0, 0xDC, 0xB9, 0x00, 0x1D, 0xFF, 0xF7, 0xA3, 0xBF, 0x00, 0x1D,
+ 0x00, 0xF0, 0xB2, 0xB9, 0x70, 0x47, 0x00, 0x00, 0x7F, 0xB5, 0x10, 0x4D,
+ 0x04, 0x46, 0x28, 0x69, 0x00, 0x28, 0x19, 0xD0, 0x20, 0x88, 0x0C, 0xF0,
+ 0xA5, 0xFC, 0x00, 0x28, 0x14, 0xD0, 0xC0, 0x78, 0x8D, 0xF8, 0x00, 0x00,
+ 0xE0, 0x88, 0xAD, 0xF8, 0x06, 0x00, 0x20, 0x89, 0xAD, 0xF8, 0x08, 0x00,
+ 0x60, 0x88, 0xAD, 0xF8, 0x02, 0x00, 0xA0, 0x88, 0xAD, 0xF8, 0x04, 0x00,
+ 0xCD, 0xF8, 0x0C, 0xD0, 0x2A, 0x69, 0x03, 0xA9, 0x14, 0x20, 0x90, 0x47,
+ 0x7F, 0xBD, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, 0x0C, 0x49, 0x10, 0xB5,
+ 0x09, 0x78, 0xC9, 0x07, 0x12, 0xD1, 0x81, 0x78, 0x61, 0xB1, 0xC1, 0x1C,
+ 0x10, 0x22, 0x09, 0x48, 0x23, 0xF4, 0x9D, 0xF0, 0x08, 0x48, 0x90, 0xF8,
+ 0x78, 0x01, 0x00, 0x06, 0x02, 0xD5, 0x05, 0x48, 0xFF, 0xF7, 0xA8, 0xFE,
+ 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0xE2, 0xB9, 0x10, 0xBD, 0x00, 0x00,
+ 0x38, 0x78, 0x20, 0x00, 0x28, 0x78, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x09, 0x49, 0x10, 0xB5, 0x09, 0x78, 0xC9, 0x07, 0x0D, 0xD1, 0x03, 0x88,
+ 0x3B, 0xB1, 0x01, 0x22, 0x06, 0x49, 0x07, 0x48, 0xF0, 0xF7, 0x69, 0xDF,
+ 0x03, 0x49, 0x00, 0x20, 0x48, 0x72, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0,
+ 0xC7, 0xB9, 0x10, 0xBD, 0x38, 0x78, 0x20, 0x00, 0x94, 0x5E, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x05, 0x49, 0x08, 0xB5, 0x0A, 0x68, 0x00, 0x2A,
+ 0x05, 0xD0, 0x00, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0x69, 0x46, 0x73, 0x20,
+ 0x90, 0x47, 0x08, 0xBD, 0x48, 0x78, 0x20, 0x00, 0x05, 0x49, 0x08, 0xB5,
+ 0x0A, 0x68, 0x00, 0x2A, 0x05, 0xD0, 0x00, 0x88, 0xAD, 0xF8, 0x00, 0x00,
+ 0x69, 0x46, 0x74, 0x20, 0x90, 0x47, 0x08, 0xBD, 0x48, 0x78, 0x20, 0x00,
+ 0x09, 0x49, 0x02, 0x89, 0x09, 0x4B, 0x8A, 0x81, 0x42, 0x89, 0xCA, 0x81,
+ 0x02, 0x7B, 0x1A, 0x70, 0x42, 0x7B, 0x4A, 0x71, 0x06, 0x4A, 0xC3, 0x7B,
+ 0x13, 0x70, 0x03, 0x7C, 0x53, 0x70, 0x02, 0x68, 0x0A, 0x62, 0x40, 0x68,
+ 0x48, 0x62, 0x70, 0x47, 0x38, 0x78, 0x20, 0x00, 0x60, 0x78, 0x20, 0x00,
+ 0x50, 0x74, 0x20, 0x00, 0x04, 0x49, 0x08, 0xB5, 0x0A, 0x69, 0x00, 0x2A,
+ 0x03, 0xD0, 0x00, 0x90, 0x69, 0x46, 0x01, 0x20, 0x90, 0x47, 0x08, 0xBD,
+ 0x38, 0x78, 0x20, 0x00, 0x7F, 0xB5, 0x0E, 0x4D, 0x04, 0x46, 0x28, 0x69,
+ 0x00, 0x28, 0x15, 0xD0, 0x20, 0x88, 0x0C, 0xF0, 0x05, 0xFC, 0x00, 0x28,
+ 0x10, 0xD0, 0xC0, 0x78, 0x8D, 0xF8, 0x00, 0x00, 0x60, 0x88, 0xAD, 0xF8,
+ 0x02, 0x00, 0x60, 0x68, 0x01, 0x90, 0x20, 0x7A, 0x8D, 0xF8, 0x08, 0x00,
+ 0xCD, 0xF8, 0x0C, 0xD0, 0x2A, 0x69, 0x03, 0xA9, 0x11, 0x20, 0x90, 0x47,
+ 0x7F, 0xBD, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, 0x05, 0x49, 0x08, 0xB5,
+ 0x0A, 0x68, 0x00, 0x2A, 0x05, 0xD0, 0x00, 0x88, 0xAD, 0xF8, 0x00, 0x00,
+ 0x69, 0x46, 0x70, 0x20, 0x90, 0x47, 0x08, 0xBD, 0x48, 0x78, 0x20, 0x00,
+ 0x7C, 0xB5, 0x0B, 0x4D, 0x04, 0x46, 0x28, 0x69, 0x00, 0x28, 0x10, 0xD0,
+ 0x60, 0x88, 0x0C, 0xF0, 0xD7, 0xFB, 0x00, 0x28, 0x0B, 0xD0, 0xC0, 0x78,
+ 0x8D, 0xF8, 0x00, 0x00, 0x20, 0x88, 0xAD, 0xF8, 0x02, 0x00, 0xCD, 0xF8,
+ 0x04, 0xD0, 0x2A, 0x69, 0x01, 0xA9, 0x13, 0x20, 0x90, 0x47, 0x7C, 0xBD,
+ 0x38, 0x78, 0x20, 0x00, 0x04, 0x49, 0x08, 0xB5, 0x0A, 0x69, 0x00, 0x2A,
+ 0x03, 0xD0, 0x00, 0x90, 0x69, 0x46, 0x03, 0x20, 0x90, 0x47, 0x08, 0xBD,
+ 0x38, 0x78, 0x20, 0x00, 0x04, 0x49, 0x08, 0xB5, 0x0A, 0x68, 0x00, 0x2A,
+ 0x03, 0xD0, 0x00, 0x90, 0x69, 0x46, 0x72, 0x20, 0x90, 0x47, 0x08, 0xBD,
+ 0x48, 0x78, 0x20, 0x00, 0x05, 0x49, 0x08, 0xB5, 0x0A, 0x68, 0x00, 0x2A,
+ 0x05, 0xD0, 0x00, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0x69, 0x46, 0x71, 0x20,
+ 0x90, 0x47, 0x08, 0xBD, 0x48, 0x78, 0x20, 0x00, 0x1C, 0xB5, 0x01, 0x88,
+ 0xA1, 0xF5, 0x7D, 0x42, 0x80, 0x3A, 0x2F, 0xD1, 0x81, 0x79, 0x03, 0x29,
+ 0x2D, 0xD0, 0x0B, 0xDC, 0xD1, 0xB1, 0x01, 0x29, 0x11, 0xD0, 0x02, 0x29,
+ 0x26, 0xD1, 0x40, 0x88, 0xAD, 0xF8, 0x04, 0x00, 0x01, 0xA8, 0x00, 0x90,
+ 0x18, 0x20, 0x24, 0xE0, 0x09, 0x29, 0x12, 0xD0, 0x0C, 0x29, 0x1B, 0xD1,
+ 0x40, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0x1A, 0x20, 0x1B, 0xE0, 0x40, 0x88,
+ 0xAD, 0xF8, 0x04, 0x00, 0x01, 0xA8, 0x00, 0x90, 0x12, 0x20, 0x14, 0xE0,
+ 0x40, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0x42, 0x20, 0x0F, 0xE0, 0x0B, 0x49,
+ 0x09, 0x78, 0xC9, 0x07, 0x04, 0xD0, 0x40, 0x88, 0xAD, 0xF8, 0x00, 0x00,
+ 0xA2, 0x20, 0x06, 0xE0, 0x00, 0xF0, 0xDA, 0xF8, 0x1C, 0xBD, 0x40, 0x88,
+ 0xAD, 0xF8, 0x00, 0x00, 0xA3, 0x20, 0x03, 0x49, 0x0A, 0x69, 0x00, 0x2A,
+ 0xF6, 0xD0, 0x69, 0x46, 0x90, 0x47, 0x1C, 0xBD, 0x38, 0x78, 0x20, 0x00,
+ 0x1C, 0xB5, 0x01, 0x28, 0x1A, 0xD1, 0x13, 0x4C, 0x6C, 0x20, 0x00, 0x90,
+ 0x10, 0x4B, 0x00, 0x22, 0x01, 0xA9, 0xE0, 0x68, 0xFB, 0xF7, 0x44, 0xDD,
+ 0x00, 0x28, 0x0F, 0xD0, 0x01, 0x20, 0x8D, 0xF8, 0x00, 0x00, 0xA2, 0x68,
+ 0x5A, 0xB1, 0x69, 0x46, 0x01, 0x98, 0x90, 0x47, 0x38, 0xB1, 0x9D, 0xF8,
+ 0x00, 0x00, 0x00, 0x28, 0x02, 0xD0, 0x01, 0x98, 0xF9, 0xF7, 0xCE, 0xFC,
+ 0x1C, 0xBD, 0x01, 0x98, 0xFF, 0xF7, 0x7A, 0xFE, 0x01, 0x98, 0x0B, 0xF0,
+ 0x0D, 0xFF, 0x8D, 0xF8, 0x00, 0x00, 0xF0, 0xE7, 0xCB, 0xB0, 0x82, 0x00,
+ 0xF0, 0x77, 0x20, 0x00, 0x7C, 0xB5, 0x0D, 0x4D, 0x04, 0x46, 0x28, 0x69,
+ 0x00, 0x28, 0x14, 0xD0, 0xA1, 0x79, 0x20, 0x46, 0x0C, 0xF0, 0xEE, 0xFA,
+ 0x00, 0x28, 0x0E, 0xD0, 0xC0, 0x78, 0x8D, 0xF8, 0x00, 0x00, 0x20, 0x89,
+ 0xAD, 0xF8, 0x02, 0x00, 0xA0, 0x7A, 0x8D, 0xF8, 0x01, 0x00, 0xCD, 0xF8,
+ 0x04, 0xD0, 0x2A, 0x69, 0x01, 0xA9, 0x10, 0x20, 0x90, 0x47, 0x7C, 0xBD,
+ 0x38, 0x78, 0x20, 0x00, 0x08, 0x49, 0x08, 0xB5, 0x09, 0x78, 0xC9, 0x07,
+ 0x08, 0xD0, 0x06, 0x49, 0x0A, 0x69, 0x00, 0x2A, 0x03, 0xD0, 0x00, 0x90,
+ 0x69, 0x46, 0x02, 0x20, 0x90, 0x47, 0x08, 0xBD, 0xBD, 0xE8, 0x08, 0x40,
+ 0x00, 0xF0, 0x70, 0xB8, 0x38, 0x78, 0x20, 0x00, 0x1C, 0xB5, 0x01, 0x88,
+ 0xA1, 0xF5, 0x7D, 0x42, 0x82, 0x3A, 0x12, 0xD1, 0x81, 0x79, 0x89, 0xB1,
+ 0x01, 0x29, 0x0E, 0xD1, 0x41, 0x88, 0xAD, 0xF8, 0x04, 0x10, 0xC0, 0x79,
+ 0x8D, 0xF8, 0x06, 0x00, 0x01, 0xA8, 0x00, 0x90, 0x01, 0x20, 0x07, 0x49,
+ 0x4A, 0x68, 0x00, 0x2A, 0x01, 0xD0, 0x69, 0x46, 0x90, 0x47, 0x1C, 0xBD,
+ 0x40, 0x88, 0xAD, 0xF8, 0x04, 0x00, 0x01, 0xA8, 0x00, 0x90, 0x00, 0x20,
+ 0xF1, 0xE7, 0x00, 0x00, 0xF0, 0x77, 0x20, 0x00, 0x01, 0x46, 0x05, 0x48,
+ 0x08, 0xB5, 0x42, 0x68, 0x00, 0x2A, 0x03, 0xD0, 0x00, 0x91, 0x04, 0x20,
+ 0x69, 0x46, 0x90, 0x47, 0x08, 0xBD, 0x00, 0x00, 0xF0, 0x77, 0x20, 0x00,
+ 0x09, 0x49, 0x08, 0xB5, 0x09, 0x78, 0xC9, 0x07, 0x0A, 0xD0, 0x07, 0x49,
+ 0x0A, 0x69, 0x00, 0x2A, 0x05, 0xD0, 0x00, 0x88, 0xAD, 0xF8, 0x00, 0x00,
+ 0x69, 0x46, 0x04, 0x20, 0x90, 0x47, 0x08, 0xBD, 0xBD, 0xE8, 0x08, 0x40,
+ 0x00, 0xF0, 0x28, 0xB8, 0x38, 0x78, 0x20, 0x00, 0x0F, 0x48, 0x10, 0xB5,
+ 0x00, 0x78, 0xA0, 0xB1, 0x0E, 0x48, 0x00, 0x24, 0x90, 0xF8, 0x78, 0x01,
+ 0x00, 0x06, 0x10, 0xD5, 0x0C, 0x48, 0xFF, 0xF7, 0x13, 0xFB, 0x60, 0xB9,
+ 0x0A, 0x49, 0x00, 0x20, 0x0A, 0x5C, 0x1A, 0xB9, 0x40, 0x1C, 0xC0, 0xB2,
+ 0x10, 0x28, 0xF9, 0xD3, 0x10, 0x28, 0x00, 0xD1, 0x0C, 0xB1, 0x05, 0x48,
+ 0x00, 0xE0, 0x00, 0x20, 0xBD, 0xE8, 0x10, 0x40, 0xFC, 0xF7, 0x1E, 0xBB,
+ 0x0F, 0x78, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0x28, 0x78, 0x20, 0x00,
+ 0x7C, 0xB5, 0x48, 0x4D, 0x00, 0x24, 0x01, 0x22, 0x2B, 0x89, 0x47, 0x49,
+ 0x47, 0x48, 0xF0, 0xF7, 0x92, 0xDD, 0x28, 0x89, 0x41, 0x07, 0x05, 0xD5,
+ 0xFF, 0xF7, 0xCC, 0xFF, 0x28, 0x89, 0x20, 0xF0, 0x04, 0x00, 0x7D, 0xE0,
+ 0x01, 0x07, 0x0E, 0xD5, 0x40, 0x21, 0x00, 0x20, 0x09, 0xF0, 0xBE, 0xFF,
+ 0x20, 0xB1, 0x3F, 0x48, 0x00, 0x88, 0xFD, 0xF7, 0xDA, 0xFB, 0x00, 0xE0,
+ 0x01, 0x24, 0x28, 0x89, 0x20, 0xF0, 0x08, 0x00, 0x55, 0xE0, 0x3B, 0x4B,
+ 0x01, 0x06, 0x4F, 0xF0, 0x00, 0x06, 0x0D, 0xD5, 0x10, 0x21, 0x01, 0x20,
+ 0x09, 0xF0, 0xAA, 0xFF, 0x10, 0xB1, 0xFC, 0xF7, 0x19, 0xFE, 0x01, 0xE0,
+ 0x5E, 0x72, 0x01, 0x24, 0x28, 0x89, 0x20, 0xF0, 0x80, 0x00, 0x42, 0xE0,
+ 0x81, 0x05, 0x07, 0xD5, 0xE9, 0x88, 0xA8, 0x88, 0xFD, 0xF7, 0x32, 0xFC,
+ 0x28, 0x89, 0x20, 0xF4, 0x00, 0x70, 0x4F, 0xE0, 0x81, 0x06, 0x07, 0xD5,
+ 0x2B, 0x48, 0x14, 0x30, 0xFD, 0xF7, 0x90, 0xFB, 0x28, 0x89, 0x20, 0xF0,
+ 0x20, 0x00, 0x45, 0xE0, 0xC1, 0x07, 0x1B, 0xD0, 0x8D, 0xF8, 0x00, 0x60,
+ 0x69, 0x46, 0x40, 0xF2, 0x12, 0x20, 0x01, 0x96, 0x09, 0xF0, 0x14, 0xFA,
+ 0x01, 0xA9, 0x40, 0xF2, 0x11, 0x20, 0x09, 0xF0, 0x0F, 0xFA, 0x9D, 0xF8,
+ 0x00, 0x00, 0x00, 0x28, 0x01, 0x98, 0x02, 0xD0, 0x40, 0xF0, 0x00, 0x40,
+ 0x01, 0x90, 0xFC, 0xF7, 0x6D, 0xFA, 0x28, 0x89, 0x20, 0xF0, 0x01, 0x00,
+ 0x28, 0x81, 0x98, 0xE7, 0x41, 0x06, 0x12, 0xD5, 0x01, 0x21, 0x08, 0x46,
+ 0x09, 0xF0, 0x68, 0xFF, 0x28, 0xB1, 0x1A, 0x7A, 0xD9, 0x79, 0x98, 0x79,
+ 0xFD, 0xF7, 0x07, 0xFB, 0x00, 0xE0, 0x01, 0x24, 0x28, 0x89, 0x20, 0xF0,
+ 0x40, 0x00, 0x28, 0x81, 0x00, 0x2C, 0x84, 0xD1, 0x7C, 0xBD, 0xC1, 0x05,
+ 0x06, 0xD5, 0xA8, 0x78, 0x0D, 0xF0, 0xAE, 0xFC, 0x28, 0x89, 0x20, 0xF4,
+ 0x80, 0x70, 0x09, 0xE0, 0x80, 0x07, 0xF3, 0xD5, 0x0E, 0xF0, 0x40, 0xF9,
+ 0x08, 0xB9, 0x00, 0xF0, 0x2F, 0xFA, 0x28, 0x89, 0x20, 0xF0, 0x02, 0x00,
+ 0x28, 0x81, 0x7C, 0xBD, 0x50, 0x74, 0x20, 0x00, 0x70, 0x5E, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0x86, 0x74, 0x20, 0x00, 0x38, 0x78, 0x20, 0x00,
+ 0x08, 0xB5, 0x01, 0x20, 0x8D, 0xF8, 0x00, 0x00, 0x01, 0x46, 0x6A, 0x46,
+ 0x4F, 0xF6, 0x82, 0x50, 0xFD, 0xF7, 0x6A, 0xFE, 0x08, 0xB1, 0x00, 0x20,
+ 0x08, 0xBD, 0x07, 0x20, 0x08, 0xBD, 0x00, 0x00, 0x01, 0x49, 0x48, 0x60,
+ 0x70, 0x47, 0x00, 0x00, 0xF0, 0x77, 0x20, 0x00, 0x01, 0x49, 0x88, 0x60,
+ 0x70, 0x47, 0x00, 0x00, 0xF0, 0x77, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x41,
+ 0x15, 0x46, 0x0E, 0x46, 0xCD, 0xE9, 0x00, 0x65, 0x07, 0x46, 0x03, 0x46,
+ 0x00, 0x24, 0x03, 0x22, 0x0A, 0x49, 0x0B, 0x48, 0xF0, 0xF7, 0xD5, 0xDC,
+ 0xAD, 0xF8, 0x08, 0x40, 0x67, 0xF3, 0x07, 0x04, 0x05, 0x20, 0x66, 0xF3,
+ 0x0F, 0x24, 0xAD, 0xF8, 0x0A, 0x00, 0x65, 0xF3, 0x1F, 0x44, 0x02, 0xA8,
+ 0x03, 0x94, 0x00, 0xF0, 0xD1, 0xF8, 0xBD, 0xE8, 0xFF, 0x81, 0x00, 0x00,
+ 0xC4, 0x85, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x41,
+ 0x15, 0x46, 0x0E, 0x46, 0xCD, 0xE9, 0x00, 0x65, 0x07, 0x46, 0x03, 0x46,
+ 0x00, 0x24, 0x03, 0x22, 0x0A, 0x49, 0x0B, 0x48, 0xF0, 0xF7, 0xB1, 0xDC,
+ 0xAD, 0xF8, 0x08, 0x40, 0x67, 0xF3, 0x07, 0x04, 0x03, 0x20, 0x66, 0xF3,
+ 0x0F, 0x24, 0xAD, 0xF8, 0x0A, 0x00, 0x65, 0xF3, 0x1F, 0x44, 0x02, 0xA8,
+ 0x03, 0x94, 0x00, 0xF0, 0xAD, 0xF8, 0xBD, 0xE8, 0xFF, 0x81, 0x00, 0x00,
+ 0xAC, 0x84, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x41,
+ 0x15, 0x46, 0x0E, 0x46, 0xCD, 0xE9, 0x00, 0x65, 0x07, 0x46, 0x03, 0x46,
+ 0x00, 0x24, 0x03, 0x22, 0x0A, 0x49, 0x0B, 0x48, 0xF0, 0xF7, 0x8D, 0xDC,
+ 0xAD, 0xF8, 0x08, 0x40, 0x67, 0xF3, 0x07, 0x04, 0x02, 0x20, 0x66, 0xF3,
+ 0x0F, 0x24, 0xAD, 0xF8, 0x0A, 0x00, 0x65, 0xF3, 0x1F, 0x44, 0x02, 0xA8,
+ 0x03, 0x94, 0x00, 0xF0, 0x89, 0xF8, 0xBD, 0xE8, 0xFF, 0x81, 0x00, 0x00,
+ 0x60, 0x84, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0x7C, 0xB5, 0x04, 0x46,
+ 0x15, 0x48, 0x03, 0x78, 0x40, 0x1E, 0x03, 0xF0, 0x01, 0x01, 0x02, 0x78,
+ 0x02, 0xF0, 0x01, 0x00, 0x81, 0x42, 0x0F, 0xD1, 0xC3, 0xF3, 0x81, 0x00,
+ 0xC2, 0xF3, 0x81, 0x01, 0x88, 0x42, 0x09, 0xD1, 0xC3, 0xF3, 0x01, 0x10,
+ 0xC2, 0xF3, 0x01, 0x11, 0x88, 0x42, 0x03, 0xD1, 0x98, 0x09, 0xB0, 0xEB,
+ 0x92, 0x1F, 0x0F, 0xD0, 0x08, 0x4D, 0x8D, 0xF8, 0x00, 0x20, 0x6D, 0x1E,
+ 0x01, 0x94, 0x03, 0x22, 0x06, 0x49, 0x07, 0x48, 0xF0, 0xF7, 0x51, 0xDC,
+ 0x21, 0x46, 0x28, 0x68, 0x00, 0xF0, 0x0A, 0xF8, 0x28, 0x78, 0x68, 0x70,
+ 0x7C, 0xBD, 0x00, 0x00, 0x39, 0x78, 0x20, 0x00, 0x30, 0x5E, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0xFE, 0xB5, 0x0D, 0x46, 0x06, 0x46, 0x03, 0x46,
+ 0x00, 0x91, 0x00, 0x24, 0x02, 0x22, 0x09, 0x49, 0x09, 0x48, 0xF0, 0xF7,
+ 0x38, 0xDC, 0xAD, 0xF8, 0x04, 0x40, 0x01, 0x20, 0x66, 0xF3, 0x07, 0x04,
+ 0xAD, 0xF8, 0x06, 0x00, 0x65, 0xF3, 0x1F, 0x44, 0x01, 0xA8, 0x02, 0x94,
+ 0x00, 0xF0, 0x36, 0xF8, 0xFE, 0xBD, 0x00, 0x00, 0x2C, 0x84, 0xC0, 0x08,
+ 0x02, 0x35, 0x10, 0x21, 0x1C, 0xB5, 0x03, 0x78, 0x00, 0x21, 0x01, 0x2B,
+ 0x0D, 0xD1, 0xAD, 0xF8, 0x00, 0x10, 0x0B, 0x22, 0xAD, 0xF8, 0x02, 0x20,
+ 0x02, 0x79, 0x62, 0xF3, 0x07, 0x01, 0x42, 0x79, 0x40, 0x88, 0x62, 0xF3,
+ 0x0F, 0x21, 0x60, 0xF3, 0x1F, 0x41, 0x68, 0x46, 0x01, 0x91, 0x00, 0xF0,
+ 0x19, 0xF8, 0x1C, 0xBD, 0x7C, 0xB5, 0x05, 0x46, 0x00, 0x24, 0x22, 0x46,
+ 0x07, 0x49, 0x08, 0x48, 0xF0, 0xF7, 0x05, 0xDC, 0xAD, 0xF8, 0x00, 0x40,
+ 0x0A, 0x20, 0xAD, 0xF8, 0x02, 0x00, 0x65, 0xF3, 0x07, 0x04, 0x68, 0x46,
+ 0x01, 0x94, 0x00, 0xF0, 0x05, 0xF8, 0x7C, 0xBD, 0x08, 0x86, 0xC0, 0x08,
+ 0x02, 0x35, 0x10, 0x21, 0x7C, 0xB5, 0x04, 0x46, 0x17, 0x48, 0x00, 0x78,
+ 0x18, 0xB3, 0x02, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x16, 0x4E, 0x30, 0x20,
+ 0x00, 0x90, 0x14, 0x4B, 0x00, 0x22, 0x21, 0x46, 0x70, 0x68, 0xFB, 0xF7,
+ 0x9D, 0xDA, 0x13, 0x4D, 0x80, 0xB1, 0x34, 0x20, 0x00, 0x90, 0x0F, 0x4B,
+ 0x00, 0x22, 0x01, 0xA9, 0x30, 0x68, 0xFB, 0xF7, 0x93, 0xDA, 0x00, 0x28,
+ 0x05, 0xD1, 0x63, 0x88, 0x0D, 0x49, 0x01, 0x22, 0x28, 0x46, 0xF0, 0xF7,
+ 0xD2, 0xDB, 0x7C, 0xBD, 0x0A, 0x49, 0x01, 0x22, 0x63, 0x88, 0x30, 0x39,
+ 0xF6, 0xE7, 0x09, 0x48, 0x02, 0x68, 0x00, 0x2A, 0xF5, 0xD0, 0x69, 0x46,
+ 0xB0, 0x20, 0x00, 0x94, 0x90, 0x47, 0x7C, 0xBD, 0x53, 0x74, 0x20, 0x00,
+ 0x92, 0xB5, 0x82, 0x00, 0x68, 0x79, 0x20, 0x00, 0x00, 0x35, 0x10, 0x21,
+ 0xFC, 0x83, 0xC0, 0x08, 0x48, 0x78, 0x20, 0x00, 0xFE, 0xB5, 0x0D, 0x46,
+ 0x06, 0x46, 0x03, 0x46, 0x00, 0x91, 0x00, 0x24, 0x02, 0x22, 0x09, 0x49,
+ 0x09, 0x48, 0xF0, 0xF7, 0xAC, 0xDB, 0xAD, 0xF8, 0x04, 0x40, 0x04, 0x20,
+ 0x66, 0xF3, 0x07, 0x04, 0xAD, 0xF8, 0x06, 0x00, 0x65, 0xF3, 0x1F, 0x44,
+ 0x01, 0xA8, 0x02, 0x94, 0xFF, 0xF7, 0xAA, 0xFF, 0xFE, 0xBD, 0x00, 0x00,
+ 0xF4, 0x84, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0x7C, 0xB5, 0x05, 0x46,
+ 0x00, 0x24, 0x22, 0x46, 0x07, 0x49, 0x08, 0x48, 0xF0, 0xF7, 0x91, 0xDB,
+ 0xAD, 0xF8, 0x00, 0x40, 0x08, 0x20, 0xAD, 0xF8, 0x02, 0x00, 0x65, 0xF3,
+ 0x07, 0x04, 0x68, 0x46, 0x01, 0x94, 0xFF, 0xF7, 0x91, 0xFF, 0x7C, 0xBD,
+ 0xA8, 0x85, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0x7C, 0xB5, 0x05, 0x46,
+ 0x03, 0x46, 0x00, 0x24, 0x01, 0x22, 0x08, 0x49, 0x08, 0x48, 0xF0, 0xF7,
+ 0x78, 0xDB, 0xAD, 0xF8, 0x00, 0x40, 0x06, 0x20, 0xAD, 0xF8, 0x02, 0x00,
+ 0x65, 0xF3, 0x07, 0x04, 0x68, 0x46, 0x01, 0x94, 0xFF, 0xF7, 0x78, 0xFF,
+ 0x7C, 0xBD, 0x00, 0x00, 0x2C, 0x85, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21,
+ 0x7C, 0xB5, 0x0D, 0x46, 0x06, 0x46, 0x00, 0x24, 0x22, 0x46, 0x09, 0x49,
+ 0x09, 0x48, 0xF0, 0xF7, 0x5E, 0xDB, 0xAD, 0xF8, 0x00, 0x40, 0x07, 0x20,
+ 0x66, 0xF3, 0x07, 0x04, 0xAD, 0xF8, 0x02, 0x00, 0x65, 0xF3, 0x0F, 0x24,
+ 0x68, 0x46, 0x01, 0x94, 0xFF, 0xF7, 0x5C, 0xFF, 0x7C, 0xBD, 0x00, 0x00,
+ 0x88, 0x85, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0x7C, 0xB5, 0x05, 0x46,
+ 0x03, 0x46, 0x00, 0x24, 0x01, 0x22, 0x08, 0x49, 0x08, 0x48, 0xF0, 0xF7,
+ 0x42, 0xDB, 0xAD, 0xF8, 0x00, 0x40, 0x09, 0x20, 0xAD, 0xF8, 0x02, 0x00,
+ 0x65, 0xF3, 0x07, 0x04, 0x68, 0x46, 0x01, 0x94, 0xFF, 0xF7, 0x42, 0xFF,
+ 0x7C, 0xBD, 0x00, 0x00, 0x58, 0x85, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21,
+ 0x09, 0x48, 0x10, 0xB5, 0x00, 0x78, 0x08, 0xB1, 0x01, 0x23, 0x00, 0xE0,
+ 0x00, 0x23, 0x07, 0x49, 0x08, 0x78, 0x00, 0xB1, 0x01, 0x20, 0x4A, 0x78,
+ 0x49, 0x88, 0xFD, 0xF7, 0x23, 0xFA, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD,
+ 0x07, 0x20, 0x10, 0xBD, 0xF0, 0x77, 0x20, 0x00, 0x4A, 0x74, 0x20, 0x00,
+ 0x70, 0xB5, 0x03, 0x46, 0x00, 0x24, 0xA0, 0xF5, 0x00, 0x70, 0x16, 0x4D,
+ 0x02, 0x38, 0x06, 0xD0, 0x01, 0x28, 0x12, 0xD0, 0x02, 0x28, 0x15, 0xD0,
+ 0x03, 0x28, 0x07, 0xD1, 0x19, 0xE0, 0x01, 0x29, 0x04, 0xD1, 0x11, 0x78,
+ 0x01, 0x29, 0x01, 0xD8, 0x29, 0x70, 0x19, 0xE0, 0x03, 0x24, 0x01, 0x22,
+ 0x0D, 0x49, 0x0E, 0x48, 0xF0, 0xF7, 0xFD, 0xDA, 0x12, 0xE0, 0x02, 0x29,
+ 0xF6, 0xD1, 0x10, 0x88, 0x68, 0x80, 0x0D, 0xE0, 0x01, 0x29, 0xF1, 0xD1,
+ 0x11, 0x78, 0x04, 0x29, 0xEE, 0xD8, 0x69, 0x70, 0x06, 0xE0, 0x01, 0x29,
+ 0xEA, 0xD1, 0x11, 0x78, 0x01, 0x29, 0xE7, 0xD8, 0x04, 0x48, 0x01, 0x70,
+ 0x20, 0x46, 0x70, 0xBD, 0x4A, 0x74, 0x20, 0x00, 0x38, 0x5B, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0xF0, 0x77, 0x20, 0x00, 0x03, 0x48, 0x01, 0x78,
+ 0x41, 0xF0, 0x01, 0x01, 0x01, 0x70, 0x00, 0x20, 0xFF, 0xF7, 0x60, 0xBE,
+ 0x38, 0x78, 0x20, 0x00, 0xF8, 0xB5, 0x15, 0x46, 0x0E, 0x46, 0x04, 0x46,
+ 0xF9, 0xF7, 0x92, 0xF9, 0x98, 0xB1, 0x31, 0x46, 0x20, 0x46, 0x0B, 0xF0,
+ 0xEF, 0xF8, 0x57, 0x20, 0x00, 0x90, 0x0A, 0x4B, 0x04, 0x22, 0x29, 0x46,
+ 0x09, 0x48, 0xFB, 0xF7, 0x03, 0xD9, 0x08, 0x48, 0x0C, 0x38, 0x04, 0x61,
+ 0xBD, 0xE8, 0xF8, 0x40, 0x06, 0x48, 0xFD, 0xF7, 0x79, 0xBA, 0x00, 0x22,
+ 0x05, 0x49, 0x06, 0x48, 0xF0, 0xF7, 0xB5, 0xDA, 0x00, 0x20, 0xF8, 0xBD,
+ 0xB8, 0xB0, 0x82, 0x00, 0xFC, 0x77, 0x20, 0x00, 0xAD, 0x6F, 0x81, 0x00,
+ 0x08, 0x5B, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x08, 0xB5, 0x00, 0x21,
+ 0x8D, 0xF8, 0x00, 0x10, 0x8D, 0xF8, 0x01, 0x00, 0x6A, 0x46, 0x02, 0x21,
+ 0x4F, 0xF6, 0x82, 0x50, 0xFD, 0xF7, 0x12, 0xFC, 0x08, 0xB1, 0x00, 0x20,
+ 0x08, 0xBD, 0x07, 0x20, 0x08, 0xBD, 0x00, 0x00, 0xF8, 0xB5, 0x00, 0x26,
+ 0xDD, 0xE9, 0x06, 0x47, 0x15, 0x46, 0x26, 0x80, 0x03, 0x46, 0x00, 0x92,
+ 0x02, 0x22, 0x0C, 0x49, 0x0C, 0x48, 0xF0, 0xF7, 0x8A, 0xDA, 0x06, 0x2D,
+ 0x05, 0xD0, 0x08, 0x2D, 0x09, 0xD0, 0x40, 0xF2, 0x0A, 0x46, 0x30, 0x46,
+ 0xF8, 0xBD, 0x08, 0x48, 0x38, 0x60, 0x22, 0xF4, 0x73, 0xF3, 0x40, 0x1C,
+ 0x03, 0xE0, 0x05, 0x48, 0x0E, 0x38, 0x38, 0x60, 0x02, 0x20, 0x20, 0x80,
+ 0xF1, 0xE7, 0x00, 0x00, 0x1C, 0x7F, 0xC0, 0x08, 0x02, 0x33, 0x10, 0x21,
+ 0x04, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x86, 0xB0, 0x17, 0x46,
+ 0xDD, 0xE9, 0x0E, 0x46, 0xCD, 0xE9, 0x00, 0x74, 0x8A, 0x46, 0x81, 0x46,
+ 0x03, 0x46, 0x00, 0x25, 0x03, 0x22, 0x28, 0x49, 0x28, 0x48, 0xF0, 0xF7,
+ 0x5E, 0xDA, 0x03, 0x20, 0xDF, 0xF8, 0x9C, 0x80, 0x40, 0xF2, 0x0D, 0x41,
+ 0x06, 0x2F, 0x06, 0xD0, 0x08, 0x2F, 0x27, 0xD0, 0xCD, 0x1E, 0x06, 0xB0,
+ 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x87, 0x28, 0x2C, 0x3A, 0xD8, 0xC6, 0xB3,
+ 0x8D, 0xF8, 0x08, 0x00, 0x01, 0x20, 0x8D, 0xF8, 0x0C, 0x00, 0x8D, 0xF8,
+ 0x09, 0x90, 0xAD, 0xF8, 0x0E, 0x40, 0x04, 0x96, 0xD8, 0xF8, 0x04, 0x20,
+ 0x22, 0xB1, 0x02, 0xA9, 0x50, 0x46, 0x90, 0x47, 0x05, 0x00, 0xE6, 0xD1,
+ 0x27, 0x2C, 0x00, 0xD3, 0x27, 0x24, 0x15, 0x48, 0x22, 0x46, 0x31, 0x46,
+ 0x10, 0x30, 0x22, 0xF4, 0x46, 0xF3, 0x12, 0x49, 0x00, 0x20, 0x10, 0x31,
+ 0x08, 0x55, 0xD8, 0xE7, 0x02, 0x2C, 0x17, 0xD1, 0xAE, 0xB1, 0x8D, 0xF8,
+ 0x08, 0x00, 0x02, 0x20, 0x8D, 0xF8, 0x0C, 0x00, 0x8D, 0xF8, 0x09, 0x90,
+ 0xAD, 0xF8, 0x0E, 0x00, 0x04, 0x96, 0xD8, 0xF8, 0x04, 0x20, 0x22, 0xB1,
+ 0x02, 0xA9, 0x50, 0x46, 0x90, 0x47, 0x05, 0x00, 0xC3, 0xD1, 0x30, 0x88,
+ 0xA8, 0xF8, 0x02, 0x00, 0xBF, 0xE7, 0xFF, 0xE7, 0x0D, 0x46, 0xBC, 0xE7,
+ 0x54, 0x7F, 0xC0, 0x08, 0x02, 0x33, 0x10, 0x21, 0xF4, 0x78, 0x20, 0x00,
+ 0x3E, 0xB5, 0x0C, 0x46, 0x8D, 0xF8, 0x01, 0x00, 0x01, 0x20, 0x8D, 0xF8,
+ 0x00, 0x00, 0x03, 0x2A, 0x0D, 0xD1, 0x98, 0x07, 0x01, 0xD5, 0x03, 0x20,
+ 0x00, 0xE0, 0x04, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x03, 0x48, 0x42, 0x68,
+ 0x00, 0x2A, 0x02, 0xD0, 0x69, 0x46, 0x20, 0x46, 0x90, 0x47, 0x3E, 0xBD,
+ 0xF4, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x16, 0x46, 0x0C, 0x46,
+ 0x03, 0x46, 0x01, 0x25, 0x02, 0x21, 0x0A, 0x22, 0x22, 0x48, 0x05, 0x2B,
+ 0x37, 0xD2, 0xDF, 0xE8, 0x03, 0xF0, 0x03, 0x0F, 0x18, 0x1F, 0x29, 0x00,
+ 0x28, 0x2C, 0x00, 0xD3, 0x27, 0x24, 0x22, 0x46, 0x31, 0x46, 0x1D, 0x48,
+ 0x22, 0xF4, 0xED, 0xF2, 0x1B, 0x49, 0x00, 0x20, 0x08, 0x55, 0x2E, 0xE0,
+ 0x02, 0x2C, 0x21, 0xD1, 0x18, 0x49, 0x30, 0x88, 0x0E, 0x39, 0x08, 0x70,
+ 0x00, 0x0A, 0x48, 0x70, 0x25, 0xE0, 0x01, 0x2C, 0x18, 0xD1, 0x14, 0x49,
+ 0x30, 0x78, 0x10, 0x39, 0x08, 0x70, 0x1E, 0xE0, 0x01, 0x2C, 0x11, 0xD1,
+ 0x33, 0x78, 0x01, 0x2B, 0x0E, 0xD8, 0x01, 0xD1, 0x42, 0x70, 0x16, 0xE0,
+ 0x41, 0x70, 0x14, 0xE0, 0x01, 0x2C, 0x07, 0xD1, 0x33, 0x78, 0x01, 0x2B,
+ 0x04, 0xD8, 0x01, 0xD1, 0x02, 0x70, 0x0C, 0xE0, 0x01, 0x70, 0x0A, 0xE0,
+ 0x4F, 0xF0, 0x00, 0x05, 0x07, 0xE0, 0x4F, 0xF0, 0x00, 0x05, 0x4F, 0xF0,
+ 0x01, 0x02, 0x05, 0x49, 0x05, 0x48, 0xF0, 0xF7, 0xA6, 0xD9, 0x28, 0x46,
+ 0xBD, 0xE8, 0xF0, 0x81, 0x83, 0x74, 0x20, 0x00, 0x04, 0x79, 0x20, 0x00,
+ 0xF0, 0x7E, 0xC0, 0x08, 0x00, 0x33, 0x10, 0x21, 0x10, 0xB5, 0x07, 0x4C,
+ 0x20, 0x70, 0x00, 0x0A, 0x60, 0x70, 0xA1, 0x70, 0x08, 0x0A, 0x21, 0x46,
+ 0xC8, 0x70, 0x22, 0x71, 0x10, 0x0A, 0x48, 0x71, 0xA3, 0x71, 0x18, 0x0A,
+ 0xC8, 0x71, 0x10, 0xBD, 0xFC, 0x78, 0x20, 0x00, 0x1C, 0xB5, 0x0F, 0x48,
+ 0x4F, 0xF4, 0xD2, 0x72, 0x90, 0xF8, 0xB0, 0x01, 0xC0, 0x07, 0x01, 0xD1,
+ 0x4F, 0xF4, 0xB6, 0x72, 0x0B, 0x48, 0xD0, 0xE9, 0x0A, 0x13, 0xCD, 0xE9,
+ 0x00, 0x13, 0xA0, 0xF5, 0xC0, 0x71, 0x43, 0x6A, 0x08, 0x48, 0x0D, 0xF0,
+ 0x22, 0xF9, 0x08, 0xB1, 0x01, 0x20, 0x1C, 0xBD, 0x00, 0x22, 0x06, 0x49,
+ 0x06, 0x48, 0xF0, 0xF7, 0x6C, 0xD9, 0x00, 0x20, 0x1C, 0xBD, 0x00, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x60, 0xB5, 0x82, 0x00, 0xF5, 0x78, 0x20, 0x00,
+ 0x98, 0x7F, 0xC0, 0x08, 0x00, 0x33, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41,
+ 0x23, 0x4D, 0x24, 0x49, 0x00, 0x24, 0x23, 0x46, 0x20, 0x46, 0x49, 0x68,
+ 0x95, 0xF8, 0x98, 0x21, 0x09, 0xE0, 0xC0, 0xEB, 0xC0, 0x04, 0x04, 0xEB,
+ 0x00, 0x14, 0x01, 0xEB, 0x84, 0x04, 0x66, 0x78, 0x26, 0xB1, 0x40, 0x1C,
+ 0xC0, 0xB2, 0x82, 0x42, 0xF3, 0xD8, 0x53, 0xB3, 0x4C, 0x21, 0x04, 0xF1,
+ 0x10, 0x00, 0x22, 0xF4, 0xF7, 0xF2, 0x01, 0x20, 0x60, 0x70, 0xB5, 0xF8,
+ 0xAE, 0x01, 0x20, 0x85, 0x17, 0x20, 0x60, 0x85, 0x00, 0x20, 0x60, 0x76,
+ 0x60, 0x68, 0x20, 0x21, 0x00, 0x1D, 0x22, 0xF4, 0xE9, 0xF2, 0xA0, 0x68,
+ 0x44, 0x21, 0x00, 0x1D, 0x22, 0xF4, 0xE4, 0xF2, 0x00, 0x26, 0x04, 0xF1,
+ 0x44, 0x08, 0xE7, 0x68, 0x06, 0xE0, 0x39, 0x46, 0x40, 0x46, 0xFB, 0xF7,
+ 0x84, 0xD8, 0x76, 0x1C, 0xF6, 0xB2, 0x20, 0x37, 0x95, 0xF8, 0xAB, 0x01,
+ 0xB0, 0x42, 0xF4, 0xD8, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x22,
+ 0x04, 0x49, 0x05, 0x48, 0xF0, 0xF7, 0x17, 0xD9, 0x00, 0x20, 0xF6, 0xE7,
+ 0x64, 0x01, 0x20, 0x00, 0x98, 0x77, 0x20, 0x00, 0x3C, 0x4E, 0xC0, 0x08,
+ 0x00, 0x38, 0x10, 0x21, 0x70, 0xB5, 0x1B, 0x48, 0x00, 0x23, 0x19, 0x4C,
+ 0x02, 0x21, 0x90, 0xF8, 0xAD, 0x01, 0x07, 0xE0, 0x62, 0x68, 0x03, 0xEB,
+ 0x43, 0x05, 0x01, 0xEB, 0x85, 0x05, 0x52, 0x5B, 0x4A, 0xB1, 0x5B, 0x1C,
+ 0x98, 0x42, 0xF5, 0xDC, 0x00, 0x22, 0x13, 0x49, 0x13, 0x48, 0xF0, 0xF7,
+ 0xF6, 0xD8, 0x00, 0x20, 0x70, 0xBD, 0x60, 0x68, 0x03, 0xEB, 0x43, 0x05,
+ 0x00, 0xEB, 0x85, 0x00, 0x00, 0x22, 0x02, 0x60, 0x42, 0x60, 0x82, 0x60,
+ 0x60, 0x68, 0x01, 0xEB, 0x85, 0x01, 0x20, 0xF8, 0x25, 0x30, 0x62, 0x68,
+ 0x01, 0x20, 0x50, 0x52, 0x02, 0x46, 0x07, 0x49, 0x07, 0x48, 0x24, 0x39,
+ 0xC0, 0x1C, 0xF0, 0xF7, 0xDC, 0xD8, 0x60, 0x68, 0x00, 0xEB, 0x85, 0x00,
+ 0x70, 0xBD, 0x00, 0x00, 0xB4, 0x77, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0xD8, 0x4E, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21, 0x30, 0xB5, 0x05, 0x46,
+ 0x88, 0x78, 0xCA, 0x78, 0x01, 0x24, 0x00, 0xEB, 0x02, 0x20, 0x0A, 0x78,
+ 0x80, 0xB2, 0xD3, 0x07, 0x4F, 0xF4, 0x20, 0x52, 0x03, 0xD1, 0x90, 0x42,
+ 0x01, 0xD1, 0x08, 0x46, 0x04, 0xE0, 0x00, 0x23, 0x29, 0x46, 0x58, 0x1E,
+ 0x00, 0xF0, 0xCE, 0xFD, 0x18, 0xB1, 0x00, 0x88, 0x00, 0x05, 0x00, 0xD4,
+ 0x00, 0x24, 0x20, 0x46, 0x30, 0xBD, 0x00, 0x00, 0xF0, 0xB5, 0x16, 0x46,
+ 0x0A, 0x46, 0x05, 0x46, 0x1F, 0x46, 0x00, 0x24, 0x31, 0x46, 0x10, 0x46,
+ 0xFF, 0xF7, 0xD8, 0xFF, 0xF0, 0xB1, 0x22, 0x4A, 0xB0, 0x69, 0x4F, 0xB1,
+ 0x04, 0x21, 0x01, 0xEA, 0x10, 0x11, 0x02, 0xEA, 0x10, 0x10, 0x51, 0xEA,
+ 0x00, 0x02, 0x07, 0xD1, 0x03, 0x24, 0x34, 0xE0, 0x00, 0xF0, 0x04, 0x01,
+ 0x10, 0x40, 0x51, 0xEA, 0x00, 0x02, 0x09, 0xD0, 0x02, 0x28, 0x10, 0xD0,
+ 0x03, 0x28, 0x13, 0xD0, 0x08, 0x28, 0x07, 0xD0, 0xB0, 0xF5, 0x80, 0x3F,
+ 0x15, 0xD1, 0x10, 0xE0, 0x02, 0x24, 0x22, 0xE0, 0x80, 0x24, 0x20, 0xE0,
+ 0x68, 0x79, 0x40, 0x07, 0x0D, 0xD4, 0x0F, 0x24, 0x1B, 0xE0, 0x68, 0x79,
+ 0xC0, 0x07, 0x08, 0xD1, 0x05, 0x24, 0x16, 0xE0, 0x68, 0x79, 0x80, 0x07,
+ 0x01, 0xE0, 0x68, 0x79, 0x00, 0x07, 0x00, 0x28, 0xF6, 0xDA, 0x30, 0x8B,
+ 0xC0, 0xF3, 0x03, 0x30, 0x00, 0x28, 0x00, 0xDD, 0x40, 0x1C, 0xAA, 0x79,
+ 0x82, 0x42, 0x01, 0xDA, 0x0C, 0x24, 0x04, 0xE0, 0x19, 0xB1, 0x30, 0x78,
+ 0x40, 0x07, 0x00, 0xD4, 0x08, 0x24, 0x20, 0x46, 0xF0, 0xBD, 0x00, 0x00,
+ 0x0B, 0x00, 0x01, 0x00, 0x42, 0xF6, 0x03, 0x01, 0x00, 0xF0, 0x14, 0xB8,
+ 0x42, 0xF6, 0x02, 0x11, 0x00, 0xF0, 0x10, 0xB8, 0x10, 0xB5, 0x04, 0x46,
+ 0x4F, 0xF4, 0x20, 0x51, 0x00, 0xF0, 0x0A, 0xF8, 0x30, 0xB9, 0x42, 0xF6,
+ 0x01, 0x01, 0x20, 0x46, 0x00, 0xF0, 0x04, 0xF8, 0x00, 0x28, 0x00, 0xD0,
+ 0x01, 0x20, 0x10, 0xBD, 0x82, 0x78, 0xC3, 0x78, 0x00, 0x78, 0x02, 0xEB,
+ 0x03, 0x22, 0x92, 0xB2, 0xC0, 0x07, 0x03, 0xD1, 0x8A, 0x42, 0x01, 0xD1,
+ 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x2D, 0xE9, 0xFF, 0x41,
+ 0x17, 0x46, 0xDD, 0xE9, 0x0A, 0x4C, 0x01, 0x22, 0x8C, 0xF8, 0x00, 0x20,
+ 0x1D, 0x88, 0x6A, 0x07, 0x0A, 0xD5, 0x62, 0x8A, 0x03, 0x92, 0xA3, 0x8A,
+ 0xA6, 0x68, 0x04, 0xF1, 0x14, 0x02, 0x9D, 0x19, 0x00, 0x23, 0x8C, 0xF8,
+ 0x00, 0x30, 0x08, 0xE0, 0x00, 0x26, 0x32, 0x46, 0xAD, 0x07, 0x01, 0xD5,
+ 0x1D, 0x1D, 0x00, 0xE0, 0x5D, 0x69, 0x5B, 0x8A, 0x03, 0x93, 0x03, 0xAB,
+ 0x00, 0x97, 0xCD, 0xE9, 0x01, 0x35, 0x01, 0x29, 0x00, 0xD0, 0x00, 0x21,
+ 0x13, 0x46, 0x32, 0x46, 0xF7, 0xF7, 0x0A, 0xF8, 0x00, 0x2E, 0x01, 0xD0,
+ 0x03, 0x99, 0x61, 0x82, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x7C, 0xB5,
+ 0x0C, 0x46, 0x45, 0x68, 0x49, 0x88, 0xAD, 0x1D, 0x44, 0xF2, 0x02, 0x06,
+ 0x01, 0x29, 0x06, 0xD0, 0x02, 0x29, 0x0D, 0xD0, 0x04, 0x29, 0x17, 0xD0,
+ 0x40, 0xF6, 0x02, 0x40, 0x7C, 0xBD, 0xA1, 0x88, 0xF7, 0xF7, 0x4C, 0xF9,
+ 0x00, 0x28, 0xF9, 0xD1, 0xA1, 0x88, 0xE9, 0x80, 0x00, 0x21, 0x08, 0xE0,
+ 0xE2, 0x88, 0xA1, 0x88, 0xF7, 0xF7, 0xD4, 0xF8, 0x00, 0x28, 0xEF, 0xD1,
+ 0xA1, 0x88, 0xE9, 0x80, 0xE1, 0x88, 0x29, 0x81, 0x6E, 0x80, 0x0E, 0xE0,
+ 0x21, 0x89, 0x10, 0x29, 0x0E, 0xD0, 0xE1, 0x68, 0x10, 0x23, 0x00, 0x91,
+ 0xE2, 0x88, 0xA1, 0x88, 0xF7, 0xF7, 0xE5, 0xF8, 0x00, 0x28, 0xDD, 0xD1,
+ 0x44, 0xF2, 0x01, 0x01, 0x69, 0x80, 0x61, 0x88, 0xA9, 0x80, 0x7C, 0xBD,
+ 0xA1, 0x89, 0x8D, 0xF8, 0x04, 0x10, 0x09, 0x0A, 0x8D, 0xF8, 0x05, 0x10,
+ 0x01, 0xA9, 0x02, 0x23, 0xE9, 0xE7, 0x00, 0x00, 0x2D, 0xE9, 0xFF, 0x4F,
+ 0x47, 0x48, 0x87, 0xB0, 0x99, 0x46, 0x00, 0x78, 0xDD, 0xE9, 0x16, 0x47,
+ 0x40, 0x1C, 0x20, 0xF0, 0x01, 0x00, 0x00, 0x1F, 0xDD, 0xF8, 0x54, 0xA0,
+ 0x4F, 0xF0, 0x00, 0x0B, 0x06, 0x90, 0x0A, 0x28, 0x7A, 0xD3, 0x48, 0x44,
+ 0x57, 0x45, 0x01, 0xD0, 0x00, 0xEB, 0x44, 0x00, 0x81, 0xB2, 0x3E, 0x48,
+ 0x4F, 0xF4, 0x72, 0x73, 0x3B, 0x4A, 0x00, 0x78, 0xF7, 0xF7, 0x3C, 0xFD,
+ 0x05, 0x90, 0x00, 0x28, 0x6A, 0xD0, 0xB9, 0xF1, 0x00, 0x0F, 0x4E, 0xD0,
+ 0xDD, 0xE9, 0x05, 0x01, 0x45, 0x18, 0x50, 0x46, 0x57, 0x45, 0x2C, 0xD1,
+ 0x74, 0xB1, 0x14, 0x99, 0x4F, 0xF0, 0x00, 0x08, 0x09, 0xEB, 0x01, 0x00,
+ 0x90, 0xFB, 0xF4, 0xF6, 0xB6, 0x1E, 0x05, 0xEB, 0x44, 0x00, 0x00, 0x90,
+ 0x60, 0x1E, 0xB3, 0x46, 0x01, 0x90, 0x19, 0xE0, 0x40, 0xF6, 0x07, 0x40,
+ 0x07, 0x90, 0x3F, 0xE0, 0x3A, 0xF8, 0x02, 0x0B, 0x25, 0xF8, 0x02, 0x0B,
+ 0x14, 0x98, 0x20, 0xB1, 0x01, 0x99, 0x88, 0x45, 0x01, 0xD1, 0x14, 0x98,
+ 0x36, 0x1A, 0x32, 0x46, 0x51, 0x46, 0x00, 0x98, 0x22, 0xF4, 0x8B, 0xF0,
+ 0x00, 0x98, 0xB2, 0x44, 0x30, 0x44, 0x08, 0xF1, 0x01, 0x08, 0x00, 0x90,
+ 0xA0, 0x45, 0xE7, 0xDB, 0x18, 0xE0, 0x1C, 0xB1, 0x99, 0xFB, 0xF4, 0xFB,
+ 0x00, 0x20, 0x0A, 0xE0, 0x01, 0x46, 0x4A, 0x46, 0x28, 0x46, 0x22, 0xF4,
+ 0x78, 0xF0, 0x1B, 0xE0, 0x37, 0xF8, 0x02, 0x1B, 0x25, 0xF8, 0x02, 0x1B,
+ 0x40, 0x1C, 0xA0, 0x42, 0xF8, 0xDB, 0x4A, 0x46, 0x51, 0x46, 0x28, 0x46,
+ 0x22, 0xF4, 0x6B, 0xF0, 0x09, 0xEB, 0x44, 0x09, 0xB9, 0xF1, 0x00, 0x0F,
+ 0x0A, 0xD1, 0x01, 0x2C, 0x08, 0xD1, 0xDD, 0xE9, 0x05, 0x01, 0x08, 0x44,
+ 0x39, 0x88, 0x01, 0x80, 0x4F, 0xF0, 0x02, 0x09, 0x4F, 0xF0, 0x00, 0x0B,
+ 0x18, 0x99, 0x08, 0x9A, 0xCD, 0xE9, 0x01, 0x21, 0xCD, 0xE9, 0x03, 0xB4,
+ 0x07, 0x98, 0x00, 0x90, 0xDD, 0xE9, 0x05, 0x02, 0x4B, 0x46, 0x09, 0x99,
+ 0xF9, 0xF7, 0x38, 0xFF, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x00,
+ 0x48, 0x74, 0x20, 0x00, 0xA3, 0xAC, 0x82, 0x00, 0x04, 0x74, 0x20, 0x00,
+ 0x2D, 0xE9, 0xF0, 0x4F, 0x1F, 0x4A, 0x4F, 0xF0, 0x00, 0x0C, 0x1D, 0x4D,
+ 0x61, 0x46, 0x4F, 0xF0, 0x04, 0x0A, 0x4F, 0xF0, 0x02, 0x0B, 0x08, 0x26,
+ 0x6F, 0xF0, 0x1B, 0x07, 0x92, 0xF8, 0xAD, 0x91, 0x27, 0xE0, 0x6B, 0x68,
+ 0x01, 0xEB, 0x41, 0x02, 0x0B, 0xEB, 0x82, 0x04, 0x1C, 0x5B, 0xFC, 0xB1,
+ 0x0A, 0xEB, 0x82, 0x04, 0x06, 0xEB, 0x82, 0x08, 0x33, 0xF8, 0x08, 0x80,
+ 0x1C, 0x59, 0xC8, 0xEB, 0xC8, 0x08, 0x07, 0xEB, 0x88, 0x08, 0xA0, 0x44,
+ 0x84, 0x42, 0x11, 0xD8, 0x40, 0x45, 0x0F, 0xD8, 0x01, 0xEB, 0x41, 0x05,
+ 0x0A, 0xEB, 0x85, 0x01, 0x59, 0x58, 0x40, 0x1A, 0x1C, 0x21, 0xB0, 0xFB,
+ 0xF1, 0xF0, 0x0A, 0x21, 0x01, 0xEB, 0x82, 0x01, 0x59, 0x5A, 0x00, 0xEB,
+ 0x01, 0x0C, 0x02, 0xE0, 0x49, 0x1C, 0x89, 0x45, 0xD5, 0xDC, 0x1F, 0xFA,
+ 0x8C, 0xF0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x00, 0xB4, 0x77, 0x20, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x08, 0xB5, 0x82, 0x89, 0x01, 0x68, 0x00, 0x92,
+ 0xC3, 0x89, 0x42, 0x68, 0x00, 0x8A, 0xF9, 0xF7, 0x17, 0xFF, 0x08, 0xBD,
+ 0x2D, 0xE9, 0xFC, 0x41, 0x05, 0x46, 0x00, 0x24, 0x08, 0x98, 0x1F, 0x46,
+ 0x16, 0x46, 0x01, 0x29, 0x04, 0xD0, 0x02, 0x29, 0x01, 0xD0, 0x05, 0x29,
+ 0x00, 0xD1, 0x01, 0x24, 0x03, 0x1D, 0x82, 0x1D, 0x01, 0x29, 0x09, 0xD0,
+ 0x02, 0x29, 0x07, 0xD0, 0x03, 0x29, 0x15, 0xD0, 0x05, 0x29, 0x03, 0xD0,
+ 0x40, 0xF6, 0x02, 0x40, 0xBD, 0xE8, 0xFC, 0x81, 0xCD, 0xE9, 0x00, 0x23,
+ 0x03, 0x68, 0x32, 0x46, 0x28, 0x46, 0xF7, 0xF7, 0xA3, 0xF8, 0x04, 0x43,
+ 0xF4, 0xD1, 0x6A, 0x68, 0x44, 0xF2, 0x03, 0x01, 0x11, 0x81, 0x69, 0x68,
+ 0x4E, 0x81, 0xED, 0xE7, 0xCD, 0xE9, 0x00, 0x23, 0x03, 0x68, 0x32, 0x46,
+ 0x39, 0x46, 0x28, 0x46, 0xF6, 0xF7, 0x26, 0xFF, 0x00, 0x28, 0xE3, 0xD1,
+ 0x6A, 0x68, 0x44, 0xF2, 0x04, 0x01, 0x11, 0x81, 0xDE, 0xE7, 0x02, 0x46,
+ 0x10, 0xF4, 0x7F, 0x41, 0x4F, 0xF0, 0x0E, 0x00, 0x4F, 0xF4, 0x80, 0x63,
+ 0x01, 0xD0, 0x99, 0x42, 0x05, 0xD1, 0xD0, 0xB2, 0xA0, 0xF1, 0x12, 0x01,
+ 0x6E, 0x29, 0x00, 0xD2, 0x0E, 0x20, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x43,
+ 0x05, 0x46, 0x00, 0x20, 0x04, 0x46, 0x15, 0x4F, 0x06, 0x46, 0xDF, 0xF8,
+ 0x54, 0x90, 0x1F, 0xE0, 0xBB, 0x69, 0x9B, 0x68, 0x03, 0xEB, 0xC4, 0x03,
+ 0x93, 0xF8, 0x00, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, 0x15, 0xD0, 0xB3, 0xF8,
+ 0x02, 0xC0, 0xB1, 0xF8, 0x30, 0x80, 0xC4, 0x45, 0x0F, 0xD1, 0x40, 0x1C,
+ 0x15, 0xB1, 0x02, 0x2D, 0x0B, 0xD1, 0x03, 0xE0, 0x1E, 0x70, 0x5E, 0x70,
+ 0xDE, 0x80, 0x06, 0xE0, 0xB3, 0xF8, 0x04, 0xC0, 0x22, 0xF8, 0x02, 0xCB,
+ 0xDB, 0x88, 0x22, 0xF8, 0x02, 0x3B, 0x64, 0x1C, 0x99, 0xF8, 0xAC, 0x31,
+ 0xA3, 0x42, 0xDB, 0xDC, 0xBD, 0xE8, 0xF0, 0x83, 0x98, 0x77, 0x20, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x01, 0x49, 0x88, 0x72, 0x70, 0x47, 0x00, 0x00,
+ 0x98, 0x77, 0x20, 0x00, 0x41, 0x76, 0x70, 0x47, 0x00, 0x78, 0x52, 0x28,
+ 0x07, 0xD0, 0x00, 0xF0, 0x3F, 0x00, 0x1B, 0x28, 0x03, 0xD0, 0x02, 0x28,
+ 0x01, 0xD0, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0xF0, 0xB5,
+ 0x06, 0x46, 0x0D, 0x46, 0x01, 0x24, 0x08, 0x46, 0x01, 0xF0, 0x48, 0xFE,
+ 0x07, 0x00, 0x1D, 0xD0, 0x02, 0x46, 0x01, 0x23, 0x29, 0x46, 0x30, 0x46,
+ 0xFF, 0xF7, 0x8C, 0xFD, 0x04, 0x00, 0x15, 0xD1, 0x38, 0x46, 0xFF, 0xF7,
+ 0xDD, 0xFD, 0x08, 0xB1, 0x80, 0x24, 0x0F, 0xE0, 0xA7, 0xF1, 0x1C, 0x00,
+ 0x05, 0x46, 0xFF, 0xF7, 0xD1, 0xFD, 0x48, 0xB1, 0x28, 0x78, 0x80, 0x07,
+ 0x01, 0xD5, 0x28, 0x79, 0x01, 0xE0, 0x68, 0x69, 0x00, 0x78, 0x00, 0x07,
+ 0x00, 0xD4, 0x03, 0x24, 0x20, 0x46, 0xF0, 0xBD, 0x70, 0xB5, 0x06, 0x46,
+ 0x0D, 0x46, 0x01, 0x24, 0x08, 0x46, 0x01, 0xF0, 0x1F, 0xFE, 0x30, 0xB1,
+ 0x02, 0x46, 0x00, 0x23, 0x29, 0x46, 0x30, 0x46, 0xFF, 0xF7, 0x64, 0xFD,
+ 0x04, 0x46, 0x20, 0x46, 0x70, 0xBD, 0x70, 0xB5, 0x00, 0x25, 0x10, 0xB1,
+ 0x09, 0xB1, 0x00, 0x22, 0x1D, 0xE0, 0x40, 0xF6, 0x07, 0x40, 0x70, 0xBD,
+ 0x04, 0x88, 0xE3, 0x07, 0x14, 0xD1, 0x83, 0x78, 0xC6, 0x78, 0x03, 0xEB,
+ 0x06, 0x23, 0x9B, 0xB2, 0xA3, 0xF6, 0x02, 0x13, 0xB3, 0xF5, 0x00, 0x53,
+ 0x0A, 0xD0, 0x03, 0x2B, 0x08, 0xD0, 0xA3, 0x07, 0x06, 0xD5, 0x03, 0x7E,
+ 0x13, 0xF0, 0x70, 0x0F, 0x02, 0xD0, 0x40, 0xF6, 0x05, 0x45, 0x04, 0xE0,
+ 0x1D, 0xB9, 0x1C, 0x30, 0x52, 0x1C, 0x8A, 0x42, 0xE2, 0xDB, 0x28, 0x46,
+ 0x70, 0xBD, 0xF0, 0xB5, 0x8D, 0xB0, 0x05, 0x46, 0x00, 0x20, 0x0A, 0x90,
+ 0x0B, 0x90, 0x0C, 0x46, 0xCF, 0x79, 0x01, 0x21, 0x28, 0x46, 0xFF, 0xF7,
+ 0x83, 0xFF, 0x06, 0x22, 0x0A, 0xA9, 0x05, 0xF1, 0x13, 0x00, 0x21, 0xF4,
+ 0xA1, 0xF6, 0x08, 0xB1, 0x00, 0x26, 0x00, 0xE0, 0x01, 0x26, 0x55, 0xF8,
+ 0x13, 0x0F, 0x08, 0x90, 0xA8, 0x88, 0xAD, 0xF8, 0x24, 0x00, 0x20, 0x7A,
+ 0xFC, 0xF7, 0xBE, 0xFB, 0x20, 0x78, 0x60, 0xB1, 0x04, 0xF1, 0x0C, 0x01,
+ 0x60, 0x7A, 0xCD, 0xE9, 0x00, 0x01, 0x21, 0x7A, 0x08, 0xAB, 0x3A, 0x46,
+ 0x30, 0x46, 0x03, 0xF0, 0x28, 0xFC, 0x0D, 0xB0, 0xF0, 0xBD, 0xA0, 0x8A,
+ 0x04, 0xAD, 0x63, 0x8B, 0x22, 0x8B, 0xE1, 0x8A, 0x85, 0xE8, 0x0F, 0x00,
+ 0x63, 0x8A, 0x22, 0x8A, 0x21, 0x7A, 0x08, 0xA8, 0x8D, 0xE8, 0x0F, 0x00,
+ 0xE1, 0x89, 0xA0, 0x89, 0x3B, 0x46, 0x32, 0x46, 0x03, 0xF0, 0x8F, 0xFB,
+ 0xE9, 0xE7, 0x00, 0x00, 0xF8, 0xB5, 0x16, 0x46, 0x04, 0x46, 0x0D, 0x46,
+ 0x0B, 0x46, 0x00, 0x90, 0x02, 0x22, 0x09, 0x49, 0x09, 0x48, 0xEF, 0xF7,
+ 0x9C, 0xDD, 0x20, 0x46, 0x00, 0xF0, 0x64, 0xF9, 0x00, 0x28, 0x07, 0xD0,
+ 0x01, 0xB0, 0x32, 0x46, 0x29, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x00, 0x23,
+ 0x02, 0xF0, 0xDC, 0xB8, 0xF8, 0xBD, 0x00, 0x00, 0x98, 0x49, 0xC0, 0x08,
+ 0x03, 0x38, 0x10, 0x21, 0x7C, 0xB5, 0x05, 0x46, 0x19, 0xB1, 0x88, 0x88,
+ 0xCE, 0x88, 0x4C, 0x88, 0x03, 0xE0, 0x52, 0xB1, 0x50, 0x88, 0x96, 0x88,
+ 0x14, 0x88, 0x28, 0x21, 0x03, 0x2C, 0x09, 0xD0, 0x05, 0x2C, 0x05, 0xD0,
+ 0x04, 0x2C, 0x17, 0xD0, 0x09, 0xE0, 0x40, 0xF6, 0x07, 0x40, 0x7C, 0xBD,
+ 0x02, 0x22, 0x00, 0xE0, 0x03, 0x22, 0x8D, 0xF8, 0x04, 0x20, 0x8D, 0xF8,
+ 0x05, 0x10, 0x01, 0xA9, 0x00, 0x91, 0x01, 0x46, 0x02, 0x23, 0x32, 0x46,
+ 0x28, 0x46, 0xF6, 0xF7, 0x70, 0xFE, 0x00, 0x28, 0xED, 0xD1, 0x69, 0x68,
+ 0x0C, 0x81, 0x7C, 0xBD, 0x01, 0x46, 0x32, 0x46, 0x28, 0x46, 0xF6, 0xF7,
+ 0x23, 0xFD, 0xF4, 0xE7, 0x2D, 0xE9, 0xFC, 0x5F, 0x82, 0x46, 0x09, 0xB1,
+ 0x4E, 0x88, 0x01, 0xE0, 0xD2, 0xB1, 0x16, 0x88, 0xDA, 0xF8, 0x04, 0x40,
+ 0x4F, 0xF0, 0x00, 0x0B, 0xA4, 0x1D, 0x01, 0x2E, 0x16, 0xD0, 0x89, 0xB3,
+ 0x31, 0xF8, 0x04, 0x8F, 0x88, 0x88, 0xB1, 0xF8, 0x02, 0x90, 0x10, 0x28,
+ 0x21, 0xD0, 0x8D, 0x68, 0x10, 0x27, 0x88, 0x88, 0xE0, 0x80, 0x3A, 0x46,
+ 0x29, 0x46, 0x04, 0xF1, 0x08, 0x00, 0x21, 0xF4, 0x4C, 0xF6, 0x29, 0xE0,
+ 0x40, 0xF6, 0x07, 0x40, 0xBD, 0xE8, 0xFC, 0x9F, 0x11, 0xB1, 0x88, 0x88,
+ 0xCA, 0x88, 0x01, 0xE0, 0x50, 0x88, 0x92, 0x88, 0x8D, 0xF8, 0x04, 0xB0,
+ 0x28, 0x21, 0x8D, 0xF8, 0x05, 0x10, 0x02, 0x21, 0x00, 0x91, 0x01, 0x46,
+ 0x01, 0xAB, 0x50, 0x46, 0xF6, 0xF7, 0x15, 0xFE, 0x19, 0xE0, 0x08, 0x89,
+ 0x8D, 0xF8, 0x04, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x05, 0x00, 0x01, 0xAD,
+ 0x02, 0x27, 0xD6, 0xE7, 0xFF, 0xE7, 0xD0, 0x88, 0xB2, 0xF8, 0x02, 0x80,
+ 0xB2, 0xF8, 0x04, 0x90, 0x95, 0x68, 0x10, 0x28, 0x0D, 0xD0, 0x10, 0x27,
+ 0x3B, 0x46, 0x4A, 0x46, 0x41, 0x46, 0x50, 0x46, 0x00, 0x95, 0xF6, 0xF7,
+ 0xB7, 0xFC, 0x00, 0x28, 0xCE, 0xD1, 0xA4, 0xF8, 0x04, 0xB0, 0x66, 0x80,
+ 0xCA, 0xE7, 0x02, 0x27, 0xF0, 0xE7, 0x00, 0x00, 0x00, 0xB5, 0x0E, 0x48,
+ 0x85, 0xB0, 0x25, 0x23, 0x0B, 0x4A, 0x69, 0x46, 0x00, 0x78, 0xF7, 0xF7,
+ 0x3D, 0xFD, 0x00, 0x28, 0x0E, 0xD0, 0xBD, 0xF8, 0x00, 0x00, 0xB0, 0xF5,
+ 0xC0, 0x6F, 0x09, 0xD1, 0xBD, 0xF8, 0x06, 0x00, 0x08, 0xB1, 0x01, 0x21,
+ 0x00, 0xE0, 0x00, 0x21, 0x9D, 0xF8, 0x05, 0x00, 0xF6, 0xF7, 0x66, 0xFF,
+ 0x05, 0xB0, 0x00, 0xBD, 0xCD, 0xAB, 0x82, 0x00, 0x94, 0x77, 0x20, 0x00,
+ 0x70, 0xB5, 0x86, 0xB0, 0x04, 0x46, 0x11, 0xB1, 0x40, 0xF6, 0x0D, 0x40,
+ 0x01, 0xE0, 0x43, 0xF4, 0x80, 0x60, 0x00, 0x25, 0x0C, 0x2A, 0x11, 0xD0,
+ 0x08, 0xDC, 0x04, 0x2A, 0x0E, 0xD0, 0x06, 0x2A, 0x0C, 0xD0, 0x08, 0x2A,
+ 0x0A, 0xD0, 0x0A, 0x2A, 0x45, 0xD1, 0x07, 0xE0, 0x10, 0x2A, 0x05, 0xD0,
+ 0x12, 0x2A, 0x03, 0xD0, 0x16, 0x2A, 0x01, 0xD0, 0x18, 0x2A, 0x3C, 0xD1,
+ 0x61, 0x68, 0x0A, 0x89, 0x0A, 0xB3, 0x6F, 0xF4, 0x80, 0x43, 0x13, 0x44,
+ 0x05, 0x2B, 0x04, 0xD2, 0xDF, 0xE8, 0x03, 0xF0, 0x0B, 0x0B, 0x21, 0x27,
+ 0x30, 0x00, 0x00, 0x95, 0x01, 0x95, 0x02, 0x95, 0x21, 0x8E, 0x00, 0x23,
+ 0x02, 0xF0, 0x8C, 0xFD, 0x27, 0xE0, 0x4A, 0x89, 0x04, 0x2A, 0x0D, 0xD0,
+ 0x03, 0x2A, 0x0B, 0xD0, 0x01, 0x23, 0xCD, 0xE9, 0x01, 0x53, 0x0C, 0x31,
+ 0xCD, 0xE9, 0x03, 0x15, 0x00, 0x95, 0x21, 0x8E, 0x00, 0x23, 0xFF, 0xF7,
+ 0xD3, 0xFC, 0x16, 0xE0, 0x01, 0x95, 0x02, 0x95, 0x03, 0x95, 0x04, 0x95,
+ 0xF4, 0xE7, 0x4B, 0x89, 0x21, 0x8E, 0x01, 0x22, 0xF9, 0xF7, 0xD2, 0xFC,
+ 0x0B, 0xE0, 0x08, 0x4A, 0x00, 0x95, 0x01, 0x95, 0x21, 0x8E, 0x00, 0x23,
+ 0x12, 0x78, 0xF9, 0xF7, 0x57, 0xFC, 0x02, 0xE0, 0x21, 0x8E, 0xF9, 0xF7,
+ 0x55, 0xFF, 0x60, 0x68, 0x05, 0x81, 0x06, 0xB0, 0x70, 0xBD, 0x00, 0x00,
+ 0x48, 0x74, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, 0xF6, 0xF7, 0xE8, 0xFB,
+ 0x00, 0x28, 0x03, 0xD1, 0x62, 0x68, 0x44, 0xF2, 0x05, 0x01, 0x11, 0x81,
+ 0x10, 0xBD, 0x70, 0xB5, 0x84, 0x68, 0x15, 0x46, 0x61, 0xB1, 0x08, 0x46,
+ 0xFF, 0xF7, 0xC3, 0xFD, 0x03, 0x00, 0x07, 0xD0, 0x2A, 0x46, 0x18, 0x21,
+ 0x20, 0x68, 0xF6, 0xF7, 0xB3, 0xFB, 0x00, 0x20, 0x20, 0x81, 0x70, 0xBD,
+ 0x20, 0x68, 0xF6, 0xF7, 0x01, 0xFC, 0xF8, 0xE7, 0x2D, 0xE9, 0xF0, 0x41,
+ 0x80, 0x46, 0x00, 0x24, 0x0E, 0x4D, 0x0F, 0x4E, 0x11, 0xE0, 0xC4, 0xEB,
+ 0xC4, 0x01, 0x68, 0x68, 0x01, 0xEB, 0x04, 0x11, 0x00, 0xEB, 0x81, 0x07,
+ 0x78, 0x78, 0x30, 0xB1, 0x06, 0x22, 0x41, 0x46, 0x07, 0xF1, 0x13, 0x00,
+ 0x21, 0xF4, 0x0E, 0xF5, 0x40, 0xB1, 0x64, 0x1C, 0xE4, 0xB2, 0x96, 0xF8,
+ 0x98, 0x01, 0xA0, 0x42, 0xE9, 0xD8, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81,
+ 0x38, 0x46, 0xFB, 0xE7, 0x98, 0x77, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x70, 0xB5, 0x10, 0x49, 0x03, 0x46, 0x00, 0x20, 0x4A, 0x68, 0x0F, 0x49,
+ 0x91, 0xF8, 0x98, 0x41, 0x0E, 0xE0, 0xC0, 0xEB, 0xC0, 0x01, 0x01, 0xEB,
+ 0x00, 0x11, 0x02, 0xEB, 0x81, 0x01, 0x4D, 0x78, 0x25, 0xB1, 0x0D, 0x8E,
+ 0x9D, 0x42, 0x01, 0xD1, 0x08, 0x46, 0x70, 0xBD, 0x40, 0x1C, 0xC0, 0xB2,
+ 0x84, 0x42, 0xEE, 0xD8, 0x01, 0x22, 0x05, 0x49, 0x05, 0x48, 0xEF, 0xF7,
+ 0x16, 0xDC, 0x00, 0x20, 0x70, 0xBD, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x7C, 0x4E, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21,
+ 0x38, 0xB5, 0x04, 0x46, 0x03, 0x78, 0x01, 0x22, 0x19, 0x49, 0x1A, 0x48,
+ 0xEF, 0xF7, 0x03, 0xDC, 0x01, 0x21, 0x20, 0x46, 0xF6, 0xF7, 0x39, 0xFF,
+ 0xA0, 0x68, 0x00, 0x25, 0xB0, 0xB1, 0x00, 0x6B, 0x30, 0xB1, 0x4F, 0xF4,
+ 0x53, 0x72, 0x14, 0x49, 0xF7, 0xF7, 0x78, 0xFA, 0xA0, 0x68, 0x05, 0x63,
+ 0xA0, 0x68, 0x05, 0x81, 0xA0, 0x68, 0xC0, 0x79, 0x40, 0xB1, 0x23, 0x46,
+ 0x00, 0x22, 0x01, 0x21, 0x03, 0x20, 0x00, 0x95, 0x02, 0xF0, 0x54, 0xFC,
+ 0xA0, 0x68, 0xC5, 0x71, 0x01, 0x21, 0x20, 0x46, 0x00, 0xF0, 0x14, 0xF8,
+ 0x00, 0x20, 0x60, 0x76, 0x94, 0xF8, 0x2E, 0x00, 0x00, 0x28, 0x05, 0xD1,
+ 0x00, 0x22, 0x21, 0x46, 0x10, 0x46, 0xFF, 0xF7, 0x41, 0xFD, 0x65, 0x70,
+ 0x38, 0xBD, 0x00, 0x00, 0x60, 0x4E, 0xC0, 0x08, 0x03, 0x38, 0x10, 0x21,
+ 0x09, 0xAD, 0x82, 0x00, 0x10, 0xB5, 0x04, 0x46, 0xC0, 0x69, 0x00, 0x28,
+ 0x0B, 0xD0, 0x41, 0xB1, 0x94, 0xF8, 0x20, 0x10, 0xC9, 0x07, 0x04, 0xD0,
+ 0x40, 0xF6, 0x99, 0x02, 0x02, 0x49, 0xF7, 0xF7, 0x41, 0xFA, 0x00, 0x20,
+ 0xE0, 0x61, 0x10, 0xBD, 0x19, 0xAD, 0x82, 0x00, 0x01, 0x46, 0x00, 0x20,
+ 0x0A, 0x88, 0x93, 0x07, 0x01, 0xD5, 0x08, 0x1D, 0x70, 0x47, 0x52, 0x07,
+ 0xFC, 0xD4, 0x48, 0x69, 0x70, 0x47, 0x00, 0x00, 0xF8, 0xB5, 0x16, 0x46,
+ 0x00, 0x25, 0x40, 0xB9, 0x6B, 0x46, 0x42, 0xF6, 0x02, 0x12, 0x01, 0x20,
+ 0x00, 0xF0, 0xB8, 0xF8, 0xC8, 0xB1, 0xBD, 0xF8, 0x00, 0x10, 0xB1, 0xB1,
+ 0x0C, 0x48, 0x00, 0x23, 0x82, 0x69, 0x0C, 0x48, 0x90, 0xF8, 0xAC, 0x01,
+ 0x0D, 0xE0, 0x94, 0x68, 0x04, 0xEB, 0xC3, 0x04, 0x27, 0x78, 0x3F, 0xB1,
+ 0xA7, 0x88, 0x8F, 0x42, 0x04, 0xD1, 0x67, 0x88, 0xB7, 0x42, 0x01, 0xD1,
+ 0xE5, 0x88, 0x02, 0xE0, 0x5B, 0x1C, 0x98, 0x42, 0xEF, 0xDC, 0x28, 0x46,
+ 0xF8, 0xBD, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0xF0, 0xB5, 0x0D, 0x4B, 0x00, 0x22, 0x9D, 0x69, 0x0C, 0x4B, 0x93, 0xF8,
+ 0xAC, 0x41, 0x0E, 0xE0, 0xAB, 0x68, 0x03, 0xEB, 0xC2, 0x03, 0x1E, 0x78,
+ 0x46, 0xB1, 0x9E, 0x88, 0x8E, 0x42, 0x05, 0xD1, 0x5E, 0x88, 0x07, 0x8E,
+ 0xBE, 0x42, 0x01, 0xD1, 0x58, 0x78, 0xF0, 0xBD, 0x52, 0x1C, 0x94, 0x42,
+ 0xEE, 0xDC, 0x4F, 0xF0, 0xFF, 0x30, 0xF0, 0xBD, 0x98, 0x77, 0x20, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x81, 0x78, 0xC2, 0x78, 0x01, 0xEB, 0x02, 0x21,
+ 0x89, 0xB2, 0xA1, 0xF5, 0x20, 0x52, 0x03, 0x3A, 0x02, 0xD0, 0x4F, 0xF0,
+ 0xFF, 0x30, 0x70, 0x47, 0x01, 0x78, 0x89, 0x07, 0x01, 0xD5, 0x00, 0x79,
+ 0x70, 0x47, 0x40, 0x69, 0x00, 0x78, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x4F,
+ 0x2B, 0x4F, 0x15, 0x46, 0x00, 0x24, 0xD7, 0xF8, 0x18, 0xC0, 0x2A, 0x4F,
+ 0x9B, 0x46, 0x02, 0x46, 0x6F, 0xF0, 0x01, 0x0A, 0x56, 0x46, 0x20, 0x46,
+ 0x23, 0x46, 0x4F, 0xF0, 0xFF, 0x39, 0x97, 0xF8, 0xAD, 0x71, 0x15, 0xE0,
+ 0xDC, 0xF8, 0x04, 0x40, 0x03, 0xEB, 0x43, 0x08, 0x04, 0xEB, 0x88, 0x04,
+ 0xB4, 0xF8, 0x02, 0x80, 0xB8, 0xF1, 0x00, 0x0F, 0x09, 0xD0, 0xD4, 0xF8,
+ 0x04, 0x80, 0x88, 0x45, 0x05, 0xD1, 0x02, 0xB3, 0xA8, 0x42, 0x01, 0xD1,
+ 0x4E, 0x46, 0x04, 0xE0, 0x40, 0x1C, 0x5B, 0x1C, 0x9F, 0x42, 0xE7, 0xDC,
+ 0x02, 0xB1, 0x00, 0x25, 0x56, 0x45, 0x25, 0xDD, 0x20, 0x89, 0x40, 0x1E,
+ 0xA8, 0x42, 0x21, 0xDD, 0x60, 0x68, 0xC5, 0xEB, 0xC5, 0x01, 0x00, 0xEB,
+ 0x81, 0x07, 0x38, 0x46, 0xFF, 0xF7, 0xBA, 0xFA, 0xC0, 0xB1, 0x60, 0x89,
+ 0x07, 0xF1, 0x1C, 0x06, 0x28, 0x44, 0xAB, 0xF8, 0x00, 0x00, 0x6D, 0x1C,
+ 0x07, 0xE0, 0x4E, 0x46, 0xE8, 0xE7, 0x30, 0x46, 0xFF, 0xF7, 0xAC, 0xFA,
+ 0x20, 0xB9, 0x6D, 0x1C, 0x1C, 0x36, 0x20, 0x89, 0xA8, 0x42, 0xF6, 0xDC,
+ 0x60, 0x89, 0x6D, 0x1E, 0x09, 0x99, 0x28, 0x44, 0x00, 0x26, 0x08, 0x80,
+ 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x00, 0x28, 0x00, 0xD0, 0x40, 0x89, 0x70, 0x47,
+ 0x2D, 0xE9, 0xF0, 0x4F, 0x07, 0x46, 0x99, 0x46, 0x16, 0x46, 0x88, 0x46,
+ 0x00, 0x24, 0x01, 0x20, 0x01, 0xF0, 0xEA, 0xFA, 0x2A, 0x49, 0x91, 0xF8,
+ 0xAD, 0x11, 0x81, 0x42, 0x4C, 0xDD, 0x29, 0x49, 0x00, 0xEB, 0x40, 0x00,
+ 0x89, 0x69, 0x49, 0x68, 0x01, 0xEB, 0x80, 0x05, 0x68, 0x88, 0x98, 0xB3,
+ 0x41, 0x46, 0x00, 0x20, 0x01, 0xF0, 0xD8, 0xFA, 0xB5, 0xF8, 0x08, 0x80,
+ 0x80, 0x45, 0x3B, 0xDD, 0xD5, 0xF8, 0x04, 0xC0, 0xC0, 0xEB, 0xC0, 0x01,
+ 0x1C, 0xEB, 0x81, 0x04, 0x34, 0xD0, 0x00, 0x2F, 0x32, 0xD0, 0x02, 0xDD,
+ 0x4F, 0xF0, 0x01, 0x02, 0x01, 0xE0, 0x4F, 0xF0, 0xFF, 0x32, 0x10, 0x44,
+ 0x4F, 0xF4, 0x20, 0x57, 0x42, 0xF6, 0x01, 0x0A, 0x42, 0xF6, 0x03, 0x0B,
+ 0x20, 0xE0, 0xC0, 0xEB, 0xC0, 0x01, 0x0C, 0xEB, 0x81, 0x04, 0x21, 0x78,
+ 0xC9, 0x07, 0x18, 0xD1, 0xA1, 0x78, 0xE3, 0x78, 0x01, 0xEB, 0x03, 0x21,
+ 0x89, 0xB2, 0xB1, 0x42, 0x07, 0xD1, 0xB9, 0xF1, 0x00, 0x0F, 0x13, 0xD0,
+ 0x69, 0x89, 0x08, 0x44, 0xA9, 0xF8, 0x00, 0x00, 0x0E, 0xE0, 0xB9, 0x42,
+ 0x05, 0xD0, 0x51, 0x45, 0x03, 0xD0, 0xBE, 0x42, 0x03, 0xD0, 0x59, 0x45,
+ 0x01, 0xD1, 0x00, 0x24, 0x04, 0xE0, 0x10, 0x44, 0x00, 0x28, 0x01, 0xDB,
+ 0x80, 0x45, 0xDA, 0xDC, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x98, 0x77, 0x20, 0x00, 0x1F, 0xB5, 0xFF, 0xF7,
+ 0x4F, 0xFE, 0x00, 0x28, 0x09, 0xD0, 0x00, 0x21, 0x00, 0x91, 0x01, 0x91,
+ 0x02, 0x91, 0x0B, 0x46, 0x03, 0x91, 0x01, 0x22, 0x1E, 0x21, 0xF6, 0xF7,
+ 0x47, 0xF9, 0x1F, 0xBD, 0x70, 0xB5, 0x1C, 0x46, 0x15, 0x46, 0x0E, 0x46,
+ 0xFF, 0xF7, 0x3C, 0xFE, 0x20, 0xB1, 0x23, 0x46, 0x2A, 0x46, 0x31, 0x46,
+ 0x01, 0xF0, 0xAE, 0xFE, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x40, 0xF2,
+ 0x8A, 0x22, 0x01, 0x49, 0xF7, 0xF7, 0xE6, 0xB8, 0x56, 0xAC, 0x82, 0x00,
+ 0x30, 0xB5, 0x04, 0x46, 0x40, 0x88, 0x85, 0xB0, 0x04, 0x28, 0x04, 0xD1,
+ 0x20, 0x89, 0x80, 0x28, 0x01, 0xD1, 0xE0, 0x68, 0x40, 0xB1, 0x20, 0x88,
+ 0xFF, 0xF7, 0x1E, 0xFE, 0x02, 0x00, 0x2A, 0xD0, 0x50, 0x7E, 0x05, 0x28,
+ 0x06, 0xD1, 0x02, 0xE0, 0x40, 0xF6, 0x01, 0x40, 0x25, 0xE0, 0x50, 0x68,
+ 0x80, 0x79, 0x10, 0xB1, 0x40, 0xF6, 0x04, 0x40, 0x1F, 0xE0, 0x61, 0x88,
+ 0x40, 0xF6, 0x07, 0x40, 0x01, 0x29, 0x04, 0xD0, 0x02, 0x29, 0x02, 0xD0,
+ 0x04, 0x29, 0x16, 0xD1, 0x02, 0xE0, 0xA1, 0x88, 0x99, 0xB1, 0x07, 0xE0,
+ 0xA1, 0x88, 0x81, 0xB1, 0xE1, 0x88, 0x00, 0x23, 0x49, 0xB1, 0x00, 0x21,
+ 0x8B, 0x42, 0x0A, 0xD8, 0x21, 0x46, 0x10, 0x46, 0xFF, 0xF7, 0x23, 0xFA,
+ 0x28, 0xB9, 0x05, 0xB0, 0x30, 0xBD, 0x01, 0x21, 0xF4, 0xE7, 0x40, 0xF6,
+ 0x08, 0x40, 0x00, 0x23, 0x62, 0x88, 0x19, 0x46, 0x01, 0x2A, 0x01, 0xD0,
+ 0x02, 0x2A, 0x01, 0xD1, 0x01, 0x23, 0x21, 0x1D, 0x00, 0x25, 0xCD, 0xE9,
+ 0x01, 0x53, 0xCD, 0xE9, 0x03, 0x15, 0x00, 0x95, 0x21, 0x88, 0x2B, 0x46,
+ 0xFF, 0xF7, 0x4A, 0xFA, 0xE5, 0xE7, 0x00, 0x00, 0x2D, 0xE9, 0xFF, 0x4F,
+ 0x8F, 0xB0, 0x1F, 0x46, 0x1C, 0xAB, 0x00, 0x26, 0x93, 0xE8, 0x03, 0x40,
+ 0x01, 0x23, 0x06, 0x96, 0x8D, 0xF8, 0x34, 0x30, 0xC0, 0xEB, 0xC0, 0x0C,
+ 0x6F, 0xF0, 0x1B, 0x08, 0x7B, 0x68, 0x08, 0xEB, 0x8C, 0x0C, 0x03, 0xEB,
+ 0x0C, 0x08, 0x7B, 0x89, 0x82, 0x46, 0x03, 0x44, 0x9B, 0xB2, 0x05, 0x93,
+ 0xCD, 0xE9, 0x07, 0x72, 0xAD, 0xF8, 0x2A, 0x00, 0xAD, 0xF8, 0x2E, 0x10,
+ 0x0F, 0x98, 0x09, 0x90, 0x10, 0x98, 0xAD, 0xF8, 0x2C, 0x00, 0xAD, 0xF8,
+ 0x30, 0xE0, 0xB7, 0xF8, 0x08, 0xC0, 0x00, 0x97, 0xCD, 0xE9, 0x01, 0xA3,
+ 0xCD, 0xE9, 0x03, 0xCE, 0x13, 0x46, 0x75, 0x1E, 0x40, 0xF6, 0x05, 0x44,
+ 0x0D, 0xF1, 0x1C, 0x0B, 0xB1, 0x46, 0x06, 0x22, 0x79, 0x49, 0x7A, 0x48,
+ 0xEF, 0xF7, 0xD5, 0xD9, 0x39, 0x89, 0x51, 0x45, 0x01, 0xDC, 0xA4, 0x1C,
+ 0x3D, 0xE0, 0x40, 0x46, 0xFF, 0xF7, 0x6C, 0xFE, 0x06, 0x90, 0x00, 0x28,
+ 0x37, 0xDB, 0x34, 0xDD, 0x10, 0xF0, 0x30, 0x0F, 0x31, 0xD0, 0x4F, 0xF0,
+ 0x00, 0x04, 0x08, 0xF1, 0x1C, 0x08, 0x10, 0x98, 0xFF, 0xF7, 0x8A, 0xFD,
+ 0x06, 0x00, 0x2A, 0xD0, 0x70, 0x7E, 0x05, 0x28, 0x27, 0xD1, 0x32, 0x8E,
+ 0x00, 0x20, 0x05, 0x99, 0xFF, 0xF7, 0x08, 0xFE, 0x05, 0x00, 0x20, 0xD4,
+ 0xD8, 0xF8, 0x18, 0x00, 0x40, 0xF6, 0x0F, 0x42, 0xC0, 0xF3, 0x01, 0x21,
+ 0x02, 0x29, 0x02, 0xD0, 0x03, 0x29, 0x0A, 0xD1, 0x04, 0xE0, 0xB1, 0x68,
+ 0x49, 0x79, 0xC9, 0x07, 0x04, 0xD0, 0x04, 0xE0, 0xB1, 0x68, 0x49, 0x79,
+ 0x89, 0x07, 0x00, 0xD4, 0x14, 0x46, 0x00, 0x0A, 0x00, 0x07, 0x08, 0xD5,
+ 0xB0, 0x68, 0x40, 0x79, 0x40, 0x07, 0x04, 0xD4, 0x4F, 0xF4, 0x41, 0x64,
+ 0x01, 0xE0, 0x40, 0xF6, 0x09, 0x44, 0x58, 0x48, 0x90, 0xF8, 0xB0, 0x01,
+ 0x80, 0x07, 0x10, 0xD5, 0x00, 0x2D, 0x0E, 0xDB, 0x06, 0x98, 0xC0, 0xF3,
+ 0x01, 0x10, 0x03, 0x28, 0x10, 0xD0, 0x06, 0x98, 0x80, 0x06, 0x01, 0xD5,
+ 0x02, 0x25, 0x16, 0xE0, 0x06, 0x98, 0xC0, 0x06, 0x01, 0xD5, 0x01, 0x25,
+ 0x0D, 0xE0, 0x03, 0x2D, 0x04, 0xD0, 0x01, 0x2D, 0x09, 0xD0, 0x02, 0x2D,
+ 0x0B, 0xD0, 0x0E, 0xE0, 0x1F, 0x98, 0x02, 0x28, 0x01, 0xD0, 0x01, 0x25,
+ 0x09, 0xE0, 0x02, 0x25, 0x07, 0xE0, 0x1F, 0x98, 0x02, 0x28, 0x03, 0xD0,
+ 0x03, 0xE0, 0x1F, 0x98, 0x01, 0x28, 0x00, 0xD1, 0x00, 0x25, 0x94, 0xBB,
+ 0x45, 0xB1, 0x40, 0xF6, 0x04, 0x41, 0xCF, 0x1E, 0x02, 0x2D, 0x06, 0xD0,
+ 0x00, 0x2D, 0x0C, 0xDA, 0x0C, 0x46, 0x4D, 0xE0, 0x40, 0xF6, 0x0A, 0x44,
+ 0x4A, 0xE0, 0xB0, 0x68, 0x40, 0xF6, 0x0C, 0x44, 0x90, 0xF8, 0x34, 0x00,
+ 0x00, 0x28, 0xF3, 0xD1, 0x10, 0xE0, 0x06, 0xF1, 0x44, 0x00, 0xFA, 0xF7,
+ 0xC0, 0xD8, 0x5F, 0xEA, 0x00, 0x09, 0x17, 0xD0, 0x02, 0x21, 0x89, 0xF8,
+ 0x04, 0x10, 0x09, 0xF1, 0x08, 0x00, 0x83, 0x46, 0x18, 0x22, 0x07, 0xA9,
+ 0x21, 0xF4, 0x98, 0xF2, 0x0D, 0xA9, 0xCD, 0xE9, 0x00, 0xB1, 0xA9, 0xB2,
+ 0x43, 0x46, 0x30, 0x46, 0x05, 0x9A, 0xFF, 0xF7, 0xFD, 0xF8, 0x00, 0x28,
+ 0x0C, 0xDA, 0x3C, 0x46, 0x0D, 0xE0, 0x23, 0xE0, 0x25, 0x49, 0x4F, 0xF0,
+ 0x00, 0x02, 0x01, 0xF1, 0x78, 0x01, 0x26, 0x48, 0xEF, 0xF7, 0x29, 0xD9,
+ 0x3C, 0x46, 0x19, 0xE0, 0x06, 0xDD, 0x40, 0xF6, 0x0E, 0x44, 0x4F, 0xF0,
+ 0x01, 0x00, 0x8D, 0xF8, 0x34, 0x00, 0x11, 0xE0, 0x02, 0x2D, 0x0E, 0xD1,
+ 0xB1, 0x68, 0x01, 0x20, 0x81, 0xF8, 0x34, 0x00, 0xB1, 0x68, 0xA1, 0xF8,
+ 0x36, 0xA0, 0xB1, 0x68, 0xDB, 0xF8, 0x04, 0x00, 0xC8, 0x63, 0xB1, 0x68,
+ 0xDB, 0xF8, 0x00, 0x00, 0x88, 0x63, 0x04, 0xB3, 0x13, 0x49, 0x23, 0x46,
+ 0x01, 0x22, 0xAC, 0x31, 0x14, 0x48, 0xEF, 0xF7, 0x06, 0xD9, 0x58, 0x46,
+ 0xAB, 0xF8, 0x0C, 0x40, 0xFF, 0xF7, 0x16, 0xFA, 0xB9, 0xF1, 0x00, 0x00,
+ 0x04, 0xD0, 0x01, 0x46, 0x06, 0xF1, 0x44, 0x00, 0xFA, 0xF7, 0x57, 0xD8,
+ 0x9D, 0xF8, 0x34, 0x00, 0x00, 0x28, 0x05, 0xD0, 0x40, 0xF2, 0x79, 0x22,
+ 0x0A, 0x49, 0x0F, 0x98, 0xF6, 0xF7, 0x72, 0xFF, 0x13, 0xB0, 0xBD, 0xE8,
+ 0xF0, 0x8F, 0xB9, 0xF1, 0x00, 0x00, 0xEF, 0xD0, 0x01, 0x46, 0x06, 0xF1,
+ 0x50, 0x00, 0xE9, 0xE7, 0x58, 0x4B, 0xC0, 0x08, 0x03, 0x38, 0x10, 0x21,
+ 0x64, 0x01, 0x20, 0x00, 0x00, 0x38, 0x10, 0x21, 0x3A, 0xAC, 0x82, 0x00,
+ 0xF8, 0xB5, 0x1D, 0x46, 0x16, 0x46, 0x0F, 0x46, 0x06, 0x9C, 0xFF, 0xF7,
+ 0x9F, 0xFC, 0x28, 0xB1, 0x2B, 0x46, 0x32, 0x46, 0x39, 0x46, 0x00, 0x94,
+ 0x02, 0xF0, 0x6E, 0xFC, 0x00, 0x2C, 0x07, 0xD0, 0x20, 0x46, 0xBD, 0xE8,
+ 0xF8, 0x40, 0x40, 0xF2, 0x9B, 0x22, 0x02, 0x49, 0xF6, 0xF7, 0x46, 0xBF,
+ 0xF8, 0xBD, 0x00, 0x00, 0x70, 0xAC, 0x82, 0x00, 0x2D, 0xE9, 0xFE, 0x4F,
+ 0x9A, 0x46, 0x91, 0x46, 0x0E, 0x46, 0x83, 0x46, 0x00, 0x25, 0xDD, 0xF8,
+ 0x30, 0x80, 0xFF, 0xF7, 0x7F, 0xFC, 0x04, 0x00, 0x57, 0xD0, 0x60, 0x7E,
+ 0x01, 0xAF, 0x05, 0x28, 0x06, 0xD1, 0x02, 0x2E, 0x0D, 0xD0, 0x05, 0x2E,
+ 0x05, 0xD0, 0x60, 0x68, 0x80, 0x79, 0x40, 0xB1, 0x40, 0xF6, 0x04, 0x40,
+ 0x4B, 0xE0, 0xA1, 0x7E, 0x04, 0xF1, 0x13, 0x00, 0x0D, 0xF0, 0x04, 0xFA,
+ 0xB0, 0xB1, 0x40, 0xF6, 0x07, 0x40, 0xB9, 0xF1, 0x00, 0x0F, 0x40, 0xD0,
+ 0xAD, 0xF8, 0x08, 0xA0, 0xCD, 0xF8, 0x04, 0x80, 0xB8, 0xF8, 0x02, 0x10,
+ 0x09, 0x1D, 0xAD, 0xF8, 0x0A, 0x10, 0x01, 0x2E, 0x1D, 0xD0, 0x02, 0x2E,
+ 0x07, 0xD0, 0x03, 0x2E, 0x19, 0xD0, 0x05, 0x2E, 0x31, 0xD1, 0x02, 0xE0,
+ 0x40, 0xF6, 0x0F, 0x40, 0x2D, 0xE0, 0x04, 0xF1, 0x44, 0x00, 0xF9, 0xF7,
+ 0xF4, 0xDF, 0x05, 0x00, 0x17, 0xD0, 0x02, 0x2E, 0x01, 0xD0, 0x01, 0x20,
+ 0x00, 0xE0, 0x00, 0x20, 0x28, 0x71, 0xA5, 0xF8, 0x06, 0x90, 0xDD, 0xE9,
+ 0x01, 0x01, 0x05, 0xF1, 0x08, 0x07, 0xC7, 0xE9, 0x00, 0x01, 0x00, 0x97,
+ 0xB8, 0xF8, 0x00, 0x30, 0x4A, 0x46, 0x31, 0x46, 0x20, 0x46, 0xFF, 0xF7,
+ 0x87, 0xF9, 0x18, 0xB1, 0x0D, 0xE0, 0x40, 0xF6, 0x01, 0x40, 0x0A, 0xE0,
+ 0x00, 0x2D, 0x04, 0xD0, 0x29, 0x46, 0x04, 0xF1, 0x50, 0x00, 0xF9, 0xF7,
+ 0xBA, 0xDF, 0xBD, 0xE8, 0xFE, 0x8F, 0x40, 0xF6, 0x08, 0x40, 0x03, 0x2E,
+ 0x13, 0xD0, 0x4B, 0x46, 0x32, 0x46, 0x59, 0x46, 0xF9, 0xF7, 0x94, 0xF8,
+ 0x25, 0xB1, 0x29, 0x46, 0x04, 0xF1, 0x44, 0x00, 0xF9, 0xF7, 0xA9, 0xDF,
+ 0x03, 0xB0, 0x40, 0x46, 0xBD, 0xE8, 0xF0, 0x4F, 0x40, 0xF2, 0x91, 0x52,
+ 0x06, 0x49, 0xF6, 0xF7, 0xC5, 0xBE, 0x00, 0x21, 0x00, 0x91, 0x0B, 0x46,
+ 0x01, 0x91, 0x04, 0x49, 0x0A, 0x78, 0x59, 0x46, 0xF9, 0xF7, 0x0A, 0xF8,
+ 0xE6, 0xE7, 0x00, 0x00, 0xB7, 0xAC, 0x82, 0x00, 0x48, 0x74, 0x20, 0x00,
+ 0x3E, 0xB5, 0x84, 0x68, 0x00, 0x22, 0x84, 0xF8, 0x34, 0x20, 0x02, 0x8E,
+ 0x20, 0x68, 0x02, 0x92, 0x00, 0xF1, 0x13, 0x03, 0xCD, 0xE9, 0x00, 0x31,
+ 0xD4, 0xE9, 0x0E, 0x12, 0x83, 0x7E, 0xE0, 0x8E, 0xF8, 0xF7, 0x74, 0xF9,
+ 0x3E, 0xBD, 0x10, 0xB5, 0x0C, 0x46, 0xFF, 0xF7, 0xC1, 0xFB, 0x00, 0x28,
+ 0x08, 0xD0, 0x0C, 0xB1, 0x00, 0x21, 0x00, 0xE0, 0x04, 0x21, 0x81, 0x74,
+ 0xBD, 0xE8, 0x10, 0x40, 0x01, 0xF0, 0xBA, 0xBA, 0x10, 0xBD, 0x70, 0xB5,
+ 0x04, 0x46, 0x40, 0xF6, 0x01, 0x45, 0xFE, 0xF7, 0xAB, 0xFE, 0x70, 0xB1,
+ 0xD4, 0xF8, 0x01, 0x10, 0xC0, 0xF8, 0x13, 0x10, 0xB4, 0xF8, 0x05, 0x10,
+ 0xA0, 0xF8, 0x17, 0x10, 0xE1, 0x79, 0x81, 0x76, 0x21, 0x46, 0x01, 0xF0,
+ 0xBD, 0xFA, 0x00, 0x28, 0x05, 0xD1, 0x29, 0x46, 0x60, 0x1C, 0xBD, 0xE8,
+ 0x70, 0x40, 0xF8, 0xF7, 0x69, 0xBB, 0x70, 0xBD, 0x2D, 0xE9, 0xF0, 0x41,
+ 0x02, 0x46, 0x0C, 0x46, 0xC8, 0x68, 0xC9, 0x88, 0x46, 0x18, 0x10, 0x46,
+ 0xFF, 0xF7, 0xB4, 0xFB, 0x1F, 0x4F, 0x05, 0x00, 0x35, 0xD0, 0xE8, 0x7E,
+ 0x00, 0xBB, 0x30, 0x46, 0xFF, 0xF7, 0x88, 0xF9, 0x90, 0xF0, 0x01, 0x0F,
+ 0x1A, 0xD1, 0xE8, 0x69, 0x28, 0xB1, 0x1A, 0x49, 0x00, 0x22, 0x38, 0x46,
+ 0xEE, 0xF7, 0xD7, 0xDF, 0x1D, 0xE0, 0xE8, 0x7E, 0x80, 0xB9, 0x30, 0x78,
+ 0x03, 0x28, 0x0D, 0xD0, 0x21, 0x46, 0x28, 0x46, 0x01, 0xF0, 0xF4, 0xFC,
+ 0x33, 0x78, 0xBD, 0xE8, 0xF0, 0x41, 0x11, 0x49, 0x0F, 0x48, 0x01, 0x22,
+ 0x3C, 0x39, 0x40, 0x1C, 0xEE, 0xF7, 0xC3, 0x9F, 0x0E, 0x49, 0xE0, 0x68,
+ 0x08, 0x60, 0xE3, 0x88, 0x22, 0x89, 0x28, 0x46, 0xE1, 0x68, 0x01, 0xF0,
+ 0x21, 0xFB, 0x00, 0x28, 0x0B, 0xD0, 0xE0, 0x68, 0xBD, 0xE8, 0xF0, 0x41,
+ 0x4F, 0xF4, 0xC3, 0x72, 0x07, 0x49, 0xF6, 0xF7, 0x33, 0xBE, 0x04, 0x49,
+ 0x00, 0x22, 0x2C, 0x31, 0xD1, 0xE7, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00,
+ 0x00, 0x38, 0x10, 0x21, 0x04, 0x4A, 0xC0, 0x08, 0x98, 0x77, 0x20, 0x00,
+ 0xE2, 0xAB, 0x82, 0x00, 0x2D, 0xE9, 0xFE, 0x43, 0x3C, 0x4F, 0x3D, 0x4E,
+ 0x90, 0x46, 0x0C, 0x46, 0x02, 0x28, 0x10, 0xD0, 0x21, 0x1D, 0x38, 0x46,
+ 0xEF, 0xF7, 0x64, 0xD9, 0xA1, 0x89, 0xE2, 0x7A, 0x00, 0x92, 0xCD, 0xE9,
+ 0x01, 0x01, 0x23, 0x88, 0x04, 0x22, 0x36, 0x49, 0x30, 0x46, 0xEE, 0xF7,
+ 0x8A, 0xDF, 0xBD, 0xE8, 0xFE, 0x83, 0x20, 0x1D, 0xFF, 0xF7, 0x2A, 0xFB,
+ 0x05, 0x46, 0x21, 0x1D, 0x38, 0x46, 0xEF, 0xF7, 0x4F, 0xD9, 0xA1, 0x89,
+ 0xE2, 0x7A, 0x00, 0x92, 0xCD, 0xE9, 0x01, 0x01, 0x2C, 0x49, 0x23, 0x88,
+ 0x04, 0x22, 0xC4, 0x39, 0x30, 0x46, 0xEE, 0xF7, 0x74, 0xDF, 0x28, 0x4E,
+ 0xF6, 0x1E, 0x85, 0xB1, 0x27, 0x49, 0x6B, 0x7E, 0x01, 0x22, 0x40, 0x39,
+ 0xB0, 0x1C, 0xEE, 0xF7, 0x6A, 0xDF, 0x00, 0x20, 0x85, 0xF8, 0x2E, 0x00,
+ 0x20, 0x88, 0x58, 0xB1, 0xA5, 0xB3, 0x28, 0x46, 0x02, 0xF0, 0x1E, 0xFA,
+ 0x25, 0xE0, 0x1F, 0x49, 0x00, 0x22, 0x68, 0x39, 0x30, 0x46, 0xEE, 0xF7,
+ 0x5A, 0xDF, 0xF1, 0xE7, 0x15, 0xB1, 0x28, 0x46, 0x02, 0xF0, 0x12, 0xFA,
+ 0xE0, 0x7A, 0x01, 0x28, 0x15, 0xD1, 0x00, 0x2D, 0xC5, 0xD0, 0x46, 0x46,
+ 0xA2, 0x89, 0x43, 0x46, 0x00, 0x21, 0x28, 0x46, 0x01, 0xF0, 0x0E, 0xFF,
+ 0x00, 0x27, 0x07, 0xE0, 0x73, 0x88, 0x32, 0x88, 0x00, 0x21, 0x28, 0x46,
+ 0x02, 0xF0, 0x98, 0xF9, 0x36, 0x1D, 0x7F, 0x1C, 0xA0, 0x89, 0xB8, 0x42,
+ 0xF4, 0xDC, 0x00, 0x2D, 0xAF, 0xD0, 0xE8, 0x69, 0x00, 0x28, 0xAC, 0xD0,
+ 0xE8, 0x7E, 0x00, 0x28, 0xA9, 0xD0, 0x28, 0x46, 0xBD, 0xE8, 0xFE, 0x43,
+ 0x01, 0xF0, 0xBA, 0xBA, 0x03, 0xB0, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x43,
+ 0x04, 0x49, 0x00, 0x22, 0x14, 0x39, 0xEE, 0xF7, 0x26, 0x9F, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x21, 0x03, 0x38, 0x10, 0x21, 0x44, 0x4D, 0xC0, 0x08,
+ 0x38, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0x01, 0x46, 0x0A, 0x48, 0xEF, 0xF7,
+ 0xE7, 0xD8, 0x00, 0x90, 0x23, 0x46, 0x02, 0x22, 0x08, 0x49, 0x09, 0x48,
+ 0xEE, 0xF7, 0x11, 0xDF, 0x28, 0x46, 0xFF, 0xF7, 0xB3, 0xFA, 0x00, 0x28,
+ 0x04, 0xD0, 0x21, 0x46, 0xBD, 0xE8, 0x38, 0x40, 0x01, 0xF0, 0x2A, 0xBA,
+ 0x38, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0x64, 0x49, 0xC0, 0x08,
+ 0x03, 0x38, 0x10, 0x21, 0xFE, 0xB5, 0x1D, 0x46, 0x14, 0x46, 0x0E, 0x46,
+ 0xFF, 0xF7, 0xC4, 0xFA, 0x00, 0x28, 0x16, 0xD0, 0x54, 0xEA, 0x05, 0x01,
+ 0x13, 0xD0, 0x41, 0x68, 0x31, 0xF8, 0x0A, 0x2F, 0xA2, 0xF5, 0x7F, 0x43,
+ 0xFF, 0x3B, 0x01, 0xD0, 0x64, 0xB1, 0x0F, 0xE0, 0x00, 0x21, 0x00, 0x91,
+ 0x01, 0x91, 0x02, 0x91, 0x01, 0x8E, 0x00, 0x23, 0x32, 0x46, 0x40, 0xF2,
+ 0x0A, 0x40, 0x01, 0xF0, 0xC1, 0xFF, 0xFE, 0xBD, 0x52, 0x1C, 0x14, 0x04,
+ 0x24, 0x0C, 0xFA, 0xD0, 0xAC, 0x42, 0xF8, 0xD8, 0xAD, 0xF8, 0x00, 0x60,
+ 0xAD, 0xF8, 0x02, 0x40, 0xAD, 0xF8, 0x04, 0x50, 0x4A, 0x88, 0x09, 0x1D,
+ 0xAD, 0xF8, 0x06, 0x20, 0x02, 0x91, 0x06, 0x2E, 0xEB, 0xD2, 0xDF, 0xE8,
+ 0x06, 0xF0, 0x03, 0x04, 0x04, 0x09, 0x09, 0x09, 0xE5, 0xE7, 0x6A, 0x46,
+ 0x00, 0x21, 0xFF, 0xF7, 0x69, 0xF9, 0xFE, 0xBD, 0x6A, 0x46, 0x00, 0x21,
+ 0xFF, 0xF7, 0x34, 0xF9, 0xFE, 0xBD, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88,
+ 0xFF, 0xF7, 0x82, 0xFA, 0x03, 0x00, 0x03, 0xD0, 0x58, 0x7E, 0x05, 0x28,
+ 0x06, 0xD1, 0x02, 0xE0, 0x40, 0xF6, 0x08, 0x40, 0x1F, 0xE0, 0x58, 0x68,
+ 0x80, 0x79, 0x10, 0xB1, 0x40, 0xF6, 0x04, 0x40, 0x19, 0xE0, 0xA1, 0x88,
+ 0x40, 0xF6, 0x07, 0x40, 0xA9, 0xB1, 0xE2, 0x88, 0x91, 0x42, 0x12, 0xD8,
+ 0x61, 0x88, 0x06, 0x29, 0x0F, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, 0x0E, 0x03,
+ 0x03, 0x09, 0x09, 0x09, 0x00, 0x22, 0x21, 0x46, 0x18, 0x46, 0xFF, 0xF7,
+ 0x3B, 0xF9, 0x04, 0xE0, 0x00, 0x22, 0x21, 0x46, 0x18, 0x46, 0xFF, 0xF7,
+ 0x05, 0xF9, 0x62, 0x88, 0x21, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0xF9, 0xF7,
+ 0x3C, 0xB9, 0x70, 0xB5, 0x14, 0x46, 0x0D, 0x46, 0xFF, 0xF7, 0x4E, 0xFA,
+ 0x00, 0x28, 0x05, 0xD0, 0x22, 0x46, 0x29, 0x46, 0xBD, 0xE8, 0x70, 0x40,
+ 0xFF, 0xF7, 0x0B, 0xBA, 0x70, 0xBD, 0x00, 0x00, 0x38, 0xB5, 0x0D, 0x46,
+ 0x04, 0x46, 0xFF, 0xF7, 0x3F, 0xFA, 0xD8, 0xB1, 0x43, 0x7E, 0x05, 0x2B,
+ 0x02, 0xD1, 0x41, 0x68, 0x89, 0x79, 0x51, 0xB1, 0x40, 0x68, 0x02, 0x22,
+ 0x0D, 0x49, 0x80, 0x79, 0x00, 0x90, 0x0D, 0x48, 0xEE, 0xF7, 0x65, 0xDE,
+ 0x40, 0xF6, 0x04, 0x40, 0x0C, 0xE0, 0x25, 0xB1, 0x01, 0x2D, 0x02, 0xD0,
+ 0x40, 0xF6, 0x07, 0x40, 0x06, 0xE0, 0x29, 0x46, 0xFF, 0xF7, 0xDE, 0xF9,
+ 0x10, 0xB9, 0x38, 0xBD, 0x40, 0xF6, 0x08, 0x40, 0x21, 0x46, 0xBD, 0xE8,
+ 0x38, 0x40, 0xF9, 0xF7, 0x23, 0xB9, 0x00, 0x00, 0x34, 0x4C, 0xC0, 0x08,
+ 0x00, 0x38, 0x10, 0x21, 0xF0, 0xB5, 0x87, 0xB0, 0x0C, 0x46, 0x05, 0x46,
+ 0xDD, 0xE9, 0x0C, 0x61, 0x10, 0x20, 0x4F, 0xF4, 0x20, 0x57, 0xBB, 0x42,
+ 0x03, 0xD0, 0x42, 0xF6, 0x01, 0x0C, 0x63, 0x45, 0x19, 0xD1, 0x02, 0x20,
+ 0xAD, 0xF8, 0x00, 0x00, 0xBB, 0x42, 0x01, 0xD1, 0x01, 0x20, 0x00, 0xE0,
+ 0x00, 0x20, 0x8D, 0xF8, 0x02, 0x00, 0x01, 0x20, 0x01, 0x90, 0x09, 0x48,
+ 0xAD, 0xF8, 0x08, 0x40, 0xCD, 0xE9, 0x04, 0x10, 0xAD, 0xF8, 0x0A, 0x20,
+ 0x03, 0x96, 0x69, 0x46, 0x28, 0x46, 0x00, 0xF0, 0x0B, 0xFC, 0x00, 0x28,
+ 0x02, 0xD0, 0x80, 0xB2, 0x40, 0xEA, 0x04, 0x40, 0x07, 0xB0, 0xF0, 0xBD,
+ 0xCF, 0xEF, 0x80, 0x00, 0x10, 0xB5, 0x86, 0xB0, 0x4F, 0xF4, 0x80, 0x43,
+ 0xAD, 0xF8, 0x00, 0x30, 0xAD, 0xF8, 0x08, 0x10, 0x00, 0x23, 0x07, 0x49,
+ 0x8D, 0xF8, 0x02, 0x30, 0xCD, 0xE9, 0x04, 0x31, 0x02, 0x24, 0x01, 0x94,
+ 0xAD, 0xF8, 0x0A, 0x20, 0x03, 0x93, 0x69, 0x46, 0x00, 0xF0, 0xEC, 0xFB,
+ 0x06, 0xB0, 0x10, 0xBD, 0xFF, 0xEF, 0x80, 0x00, 0xFE, 0xB5, 0x44, 0x68,
+ 0x15, 0x46, 0x00, 0x26, 0x34, 0xF8, 0x08, 0x2F, 0xAD, 0xB2, 0x24, 0xF8,
+ 0x02, 0x69, 0x00, 0x95, 0xCD, 0xE9, 0x01, 0x34, 0x8B, 0xB2, 0x01, 0x8E,
+ 0x30, 0x46, 0x01, 0xF0, 0xD1, 0xFE, 0xFE, 0xBD, 0x2D, 0xE9, 0xFC, 0x41,
+ 0x1C, 0x46, 0x16, 0x46, 0x0F, 0x46, 0x08, 0x9D, 0xFF, 0xF7, 0xB2, 0xF9,
+ 0x00, 0x28, 0x11, 0xD0, 0xC7, 0x86, 0x06, 0x87, 0x44, 0x87, 0x85, 0x87,
+ 0x00, 0x21, 0xC1, 0x87, 0xA0, 0xF8, 0x40, 0x10, 0x01, 0x21, 0x80, 0xF8,
+ 0x32, 0x10, 0xCD, 0xE9, 0x00, 0x45, 0x00, 0x8E, 0x33, 0x46, 0x3A, 0x46,
+ 0xFA, 0xF7, 0x3D, 0xFC, 0xBD, 0xE8, 0xFC, 0x81, 0x2D, 0xE9, 0xFF, 0x41,
+ 0x2E, 0x4E, 0x05, 0x46, 0x90, 0x46, 0xB0, 0x89, 0x00, 0x24, 0x60, 0xB1,
+ 0x02, 0x2D, 0x01, 0xD0, 0x03, 0x2D, 0x05, 0xD1, 0x40, 0xF2, 0x35, 0x62,
+ 0x29, 0x49, 0x40, 0x46, 0xF6, 0xF7, 0x42, 0xFC, 0x40, 0xF6, 0x04, 0x41,
+ 0x37, 0xE0, 0xB5, 0x81, 0x06, 0x2D, 0x3E, 0xD2, 0xDF, 0xE8, 0x05, 0xF0,
+ 0x3D, 0x03, 0x12, 0x1C, 0x2A, 0x39, 0x11, 0x46, 0x97, 0x78, 0x53, 0x78,
+ 0x88, 0x7B, 0x08, 0x32, 0x8D, 0xE8, 0x8D, 0x00, 0xCB, 0x7B, 0x0A, 0x78,
+ 0xC9, 0x88, 0xB8, 0xF8, 0x04, 0x00, 0x02, 0xF0, 0x0A, 0xFD, 0x19, 0xE0,
+ 0x0A, 0x46, 0x41, 0x46, 0x42, 0xF2, 0x08, 0x00, 0x02, 0xF0, 0xE8, 0xFC,
+ 0x07, 0x46, 0x40, 0xF2, 0x4E, 0x62, 0x08, 0xE0, 0x0A, 0x46, 0x41, 0x46,
+ 0x42, 0xF2, 0x09, 0x00, 0x02, 0xF0, 0xDE, 0xFC, 0x07, 0x46, 0x40, 0xF2,
+ 0x53, 0x62, 0x11, 0x49, 0x40, 0x46, 0xF6, 0xF7, 0x11, 0xFC, 0x02, 0xE0,
+ 0x01, 0x20, 0x0D, 0xE0, 0x07, 0x46, 0x8F, 0xB1, 0x00, 0x2C, 0x12, 0xD0,
+ 0x00, 0x20, 0xB0, 0x81, 0x21, 0x46, 0x04, 0xB0, 0x28, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x41, 0xF9, 0xF7, 0x38, 0xBB, 0x00, 0x20, 0x02, 0xF0, 0xB2, 0xFC,
+ 0xEE, 0xE7, 0x40, 0xF6, 0x07, 0x44, 0xEF, 0xE7, 0x4F, 0xF4, 0xB4, 0x74,
+ 0xEC, 0xE7, 0xBD, 0xE8, 0xFF, 0x81, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00,
+ 0xD2, 0xAC, 0x82, 0x00, 0x2D, 0xE9, 0xFC, 0x5F, 0x82, 0x46, 0xDD, 0xE9,
+ 0x0D, 0x86, 0x99, 0x46, 0x17, 0x46, 0x0D, 0x46, 0x40, 0x46, 0xDD, 0xF8,
+ 0x3C, 0xB0, 0xFF, 0xF7, 0x05, 0xF9, 0x04, 0x46, 0xB5, 0xF5, 0x9E, 0x7F,
+ 0x05, 0xD0, 0x54, 0xEA, 0x07, 0x00, 0x4F, 0xF0, 0x00, 0x07, 0x07, 0xD0,
+ 0x0C, 0xE0, 0x29, 0x46, 0xBD, 0xE8, 0xFC, 0x5F, 0x4F, 0xF4, 0xC1, 0x70,
+ 0xFB, 0xF7, 0x63, 0xBD, 0x00, 0x97, 0x68, 0x46, 0x01, 0x97, 0xFF, 0xF7,
+ 0xEF, 0xF8, 0x04, 0x46, 0x54, 0xEA, 0x05, 0x00, 0x0C, 0xD0, 0x00, 0x2C,
+ 0x43, 0xD0, 0xAD, 0xB1, 0x04, 0x21, 0x20, 0x46, 0xFE, 0xF7, 0xE4, 0xFE,
+ 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x5F, 0x01, 0xF0, 0x56, 0xB8,
+ 0xFE, 0xF7, 0xD8, 0xFB, 0x04, 0x00, 0xF0, 0xD1, 0x02, 0xB0, 0x00, 0x22,
+ 0xBD, 0xE8, 0xF0, 0x5F, 0x19, 0x49, 0x1A, 0x48, 0xEE, 0xF7, 0x2D, 0x9D,
+ 0xA4, 0xF8, 0x30, 0xA0, 0x0C, 0x98, 0xA0, 0x76, 0xD8, 0xF8, 0x00, 0x10,
+ 0xC4, 0xF8, 0x13, 0x10, 0xB8, 0xF8, 0x04, 0x00, 0xA4, 0xF8, 0x17, 0x00,
+ 0x84, 0xF8, 0x34, 0x90, 0xE6, 0x86, 0x26, 0x87, 0xA4, 0xF8, 0x3A, 0xB0,
+ 0x10, 0x98, 0xA0, 0x87, 0xE7, 0x87, 0xA4, 0xF8, 0x40, 0x70, 0x94, 0xF8,
+ 0x2F, 0x00, 0x48, 0xB1, 0x05, 0x21, 0x20, 0x46, 0xFE, 0xF7, 0xB4, 0xFE,
+ 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x5F, 0x00, 0x21, 0x00, 0xF0, 0xDE, 0xBF,
+ 0x02, 0x21, 0x20, 0x46, 0xFE, 0xF7, 0xAA, 0xFE, 0x20, 0x46, 0xBD, 0xE8,
+ 0xFC, 0x5F, 0x00, 0xF0, 0xBC, 0xBF, 0xBD, 0xE8, 0xFC, 0x9F, 0x00, 0x00,
+ 0x8C, 0x48, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21, 0x1F, 0xB5, 0x0C, 0x46,
+ 0xFF, 0xF7, 0xC0, 0xF8, 0x00, 0x28, 0x15, 0xD0, 0x0C, 0xB1, 0x01, 0x21,
+ 0x00, 0xE0, 0x00, 0x21, 0x90, 0xF8, 0x32, 0x20, 0x00, 0x2A, 0x0D, 0xD0,
+ 0xB0, 0xF8, 0x40, 0x20, 0xC3, 0x8F, 0x84, 0x8F, 0x00, 0x94, 0x03, 0x91,
+ 0xCD, 0xE9, 0x01, 0x32, 0x43, 0x8F, 0x02, 0x8F, 0xC1, 0x8E, 0x00, 0x8E,
+ 0x06, 0xF0, 0x76, 0xFE, 0x1F, 0xBD, 0x7C, 0xB5, 0x1D, 0x46, 0x14, 0x46,
+ 0x06, 0x9E, 0xFF, 0xF7, 0xA1, 0xF8, 0x00, 0x28, 0x0F, 0xD0, 0xC4, 0x86,
+ 0x04, 0x87, 0x45, 0x87, 0x86, 0x87, 0x00, 0x21, 0xC1, 0x87, 0xA0, 0xF8,
+ 0x40, 0x10, 0xCD, 0xE9, 0x00, 0x56, 0x23, 0x46, 0x00, 0x8E, 0x1A, 0x46,
+ 0x02, 0x21, 0xFA, 0xF7, 0x2E, 0xFB, 0x7C, 0xBD, 0x70, 0xB5, 0x0D, 0x46,
+ 0x06, 0x46, 0xFF, 0xF7, 0x89, 0xF8, 0x04, 0x00, 0x0A, 0xD0, 0x20, 0x8E,
+ 0x29, 0x46, 0x06, 0xF0, 0x00, 0xFE, 0x01, 0x00, 0x0B, 0xD0, 0x20, 0x8E,
+ 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, 0x08, 0xB8, 0x31, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0x40, 0xF6, 0x06, 0x40, 0xF8, 0xF7, 0x51, 0xBF, 0x70, 0xBD,
+ 0x70, 0xB5, 0x0D, 0x46, 0xFF, 0xF7, 0x70, 0xF8, 0x04, 0x00, 0x09, 0xD0,
+ 0x94, 0xF8, 0x32, 0x00, 0x18, 0xB9, 0x21, 0x8E, 0x28, 0x46, 0xF8, 0xF7,
+ 0x43, 0xFF, 0x00, 0x20, 0x84, 0xF8, 0x32, 0x00, 0x70, 0xBD, 0x00, 0x00,
+ 0x38, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0x01, 0x46, 0x0C, 0x48, 0xEE, 0xF7,
+ 0x5F, 0xDE, 0x03, 0x46, 0x02, 0x22, 0x0B, 0x49, 0x0B, 0x48, 0x00, 0x94,
+ 0xEE, 0xF7, 0x89, 0xDC, 0x28, 0x46, 0xFF, 0xF7, 0x2B, 0xF8, 0x05, 0x00,
+ 0x09, 0xD0, 0x14, 0xB9, 0x02, 0x21, 0xFE, 0xF7, 0x25, 0xFE, 0x21, 0x46,
+ 0x28, 0x46, 0xBD, 0xE8, 0x38, 0x40, 0x00, 0xF0, 0x40, 0xBF, 0x38, 0xBD,
+ 0x00, 0x00, 0x30, 0x21, 0xD0, 0x48, 0xC0, 0x08, 0x02, 0x38, 0x10, 0x21,
+ 0x70, 0xB5, 0x0D, 0x46, 0xFF, 0xF7, 0x3A, 0xF8, 0x04, 0x00, 0x13, 0xD0,
+ 0xA0, 0x7C, 0x38, 0xB1, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40,
+ 0x01, 0x23, 0x00, 0x22, 0x00, 0xF0, 0xB0, 0xBF, 0x29, 0x46, 0x20, 0x46,
+ 0x00, 0xF0, 0x7C, 0xFF, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x04, 0x21,
+ 0xFE, 0xF7, 0xFE, 0xBD, 0x70, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x41,
+ 0x06, 0x46, 0x47, 0x48, 0x8C, 0xB0, 0x00, 0x25, 0x82, 0x89, 0x40, 0xF6,
+ 0x04, 0x44, 0x62, 0xB1, 0x02, 0x2E, 0x01, 0xD0, 0x03, 0x2E, 0x05, 0xD1,
+ 0x88, 0x68, 0x40, 0xF2, 0x7F, 0x62, 0x41, 0x49, 0xF6, 0xF7, 0xC6, 0xFA,
+ 0x00, 0x22, 0x21, 0x46, 0x5E, 0xE0, 0x80, 0x46, 0x86, 0x81, 0x06, 0x2E,
+ 0x6C, 0xD2, 0xDF, 0xE8, 0x06, 0xF0, 0x6B, 0x03, 0x2D, 0x3E, 0x5F, 0x64,
+ 0x98, 0xF8, 0x0F, 0x20, 0x40, 0x46, 0x00, 0x2A, 0xEE, 0xD1, 0x01, 0x22,
+ 0xC2, 0x73, 0x0A, 0x78, 0x02, 0x74, 0x4A, 0x7B, 0x88, 0xF8, 0x11, 0x20,
+ 0x08, 0x7E, 0x07, 0xAF, 0xCC, 0x7E, 0x8B, 0x7E, 0x4A, 0x7E, 0x87, 0xE8,
+ 0x1D, 0x00, 0x03, 0xAF, 0xCC, 0x7D, 0x8B, 0x7D, 0x4A, 0x7D, 0x01, 0xF1,
+ 0x0F, 0x00, 0x87, 0xE8, 0x1D, 0x00, 0x08, 0x7B, 0x8B, 0x7B, 0x4A, 0x7B,
+ 0x8D, 0xE8, 0x0D, 0x00, 0xD1, 0xE9, 0x01, 0x23, 0x48, 0x88, 0x0C, 0x78,
+ 0x01, 0x46, 0x20, 0x46, 0x02, 0xF0, 0x2F, 0xFC, 0x04, 0x46, 0x23, 0xE0,
+ 0x0F, 0x46, 0x89, 0x68, 0x38, 0x79, 0xCD, 0xE9, 0x00, 0x01, 0xFB, 0x78,
+ 0xBA, 0x78, 0x79, 0x78, 0x42, 0xF2, 0x37, 0x00, 0x02, 0xF0, 0x04, 0xFC,
+ 0x04, 0x46, 0x40, 0xF2, 0xA9, 0x62, 0xB8, 0x68, 0x0F, 0xE0, 0x0F, 0x46,
+ 0x89, 0x68, 0x38, 0x79, 0xCD, 0xE9, 0x00, 0x01, 0xFB, 0x78, 0xBA, 0x78,
+ 0x79, 0x78, 0x42, 0xF2, 0x38, 0x00, 0x02, 0xF0, 0xF3, 0xFB, 0x04, 0x46,
+ 0xB8, 0x68, 0x40, 0xF2, 0xB3, 0x62, 0x14, 0x49, 0xF6, 0xF7, 0x6C, 0xFA,
+ 0xDC, 0xB1, 0x00, 0x2D, 0x1C, 0xD0, 0x00, 0x21, 0xA8, 0xF8, 0x0C, 0x10,
+ 0x0A, 0x46, 0x29, 0x46, 0x0C, 0xB0, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x41,
+ 0xF9, 0xF7, 0xCA, 0xBB, 0x48, 0x78, 0x8A, 0x1C, 0x01, 0x46, 0x01, 0x20,
+ 0x03, 0xE0, 0x48, 0x78, 0x8A, 0x1C, 0x01, 0x46, 0x00, 0x20, 0x02, 0xF0,
+ 0xA9, 0xFB, 0xBF, 0xE7, 0x40, 0xF6, 0x07, 0x45, 0xE5, 0xE7, 0x4F, 0xF4,
+ 0xB4, 0x75, 0xE2, 0xE7, 0x0C, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00,
+ 0x98, 0x77, 0x20, 0x00, 0xE9, 0xAC, 0x82, 0x00, 0x70, 0xB5, 0x05, 0x46,
+ 0x09, 0x48, 0x00, 0x21, 0xC4, 0x7B, 0xC1, 0x73, 0x14, 0xB1, 0x02, 0x2C,
+ 0x04, 0xD0, 0x05, 0xE0, 0x00, 0x7C, 0xFB, 0xF7, 0x89, 0xF8, 0x01, 0xE0,
+ 0xFA, 0xF7, 0x1A, 0xF9, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40,
+ 0xFA, 0xF7, 0xE8, 0xBE, 0x98, 0x77, 0x20, 0x00, 0x70, 0xB5, 0x11, 0x4E,
+ 0x05, 0x46, 0x00, 0x24, 0xF0, 0x7B, 0x08, 0xB1, 0x05, 0x21, 0x12, 0xE0,
+ 0xF5, 0x73, 0x31, 0x74, 0x1D, 0xB1, 0x02, 0x2D, 0x04, 0xD0, 0x04, 0x24,
+ 0x08, 0xE0, 0x02, 0xF0, 0x40, 0xF9, 0x02, 0xE0, 0x08, 0x46, 0x02, 0xF0,
+ 0xBA, 0xFA, 0x48, 0xB1, 0x00, 0x2C, 0x0A, 0xD0, 0x00, 0x20, 0xF0, 0x73,
+ 0x21, 0x46, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xFA, 0xF7, 0xC6, 0xBE,
+ 0x4F, 0xF4, 0xB4, 0x74, 0xF4, 0xE7, 0x70, 0xBD, 0x98, 0x77, 0x20, 0x00,
+ 0x03, 0x4A, 0x01, 0x46, 0x00, 0x23, 0x90, 0x7B, 0x93, 0x73, 0xFA, 0xF7,
+ 0x27, 0xBF, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, 0x70, 0xB5, 0x14, 0x4E,
+ 0x05, 0x46, 0x00, 0x24, 0xB0, 0x7B, 0x08, 0xB1, 0x05, 0x21, 0x17, 0xE0,
+ 0xB5, 0x73, 0x6D, 0xB1, 0x01, 0x2D, 0x03, 0xD0, 0x02, 0x2D, 0x04, 0xD0,
+ 0x04, 0x24, 0x0C, 0xE0, 0x42, 0xF2, 0x11, 0x00, 0x01, 0xE0, 0x42, 0xF2,
+ 0x12, 0x00, 0x02, 0xF0, 0x45, 0xFA, 0x01, 0xE0, 0x02, 0xF0, 0x0F, 0xF9,
+ 0x48, 0xB1, 0x00, 0x2C, 0x0A, 0xD0, 0x00, 0x20, 0xB0, 0x73, 0x21, 0x46,
+ 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xFA, 0xF7, 0xFF, 0xBE, 0x4F, 0xF4,
+ 0xB4, 0x74, 0xF4, 0xE7, 0x70, 0xBD, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00,
+ 0x10, 0xB5, 0x04, 0x4C, 0x01, 0x46, 0xA0, 0x89, 0xF9, 0xF7, 0x01, 0xF9,
+ 0x00, 0x20, 0xA0, 0x81, 0x10, 0xBD, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00,
+ 0x2D, 0xE9, 0xF0, 0x41, 0x0B, 0x4C, 0x06, 0x46, 0x00, 0x25, 0xA0, 0x89,
+ 0x0F, 0x46, 0x01, 0x28, 0x08, 0xD1, 0xE0, 0x7B, 0x01, 0x28, 0x04, 0xD1,
+ 0x1E, 0xB9, 0x61, 0x7C, 0x20, 0x7C, 0xFA, 0xF7, 0x53, 0xFD, 0xE5, 0x73,
+ 0xA0, 0x89, 0x3A, 0x46, 0x31, 0x46, 0xF9, 0xF7, 0x19, 0xFB, 0xA5, 0x81,
+ 0xBD, 0xE8, 0xF0, 0x81, 0x98, 0x77, 0x20, 0x00, 0x7C, 0xB5, 0x0D, 0x46,
+ 0x00, 0x8E, 0x9B, 0xB2, 0x06, 0x99, 0xCD, 0xE9, 0x00, 0x30, 0x0A, 0x4C,
+ 0x13, 0x46, 0x2A, 0x46, 0x20, 0x68, 0x09, 0x1A, 0x89, 0xB2, 0xF7, 0xF7,
+ 0xEF, 0xFA, 0x00, 0x28, 0x08, 0xD0, 0x20, 0x68, 0x02, 0xB0, 0x40, 0xF6,
+ 0x2A, 0x32, 0xBD, 0xE8, 0x70, 0x40, 0x03, 0x49, 0xF6, 0xF7, 0x8E, 0xB9,
+ 0x7C, 0xBD, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, 0x33, 0xAD, 0x82, 0x00,
+ 0x2D, 0xE9, 0xF8, 0x4F, 0x0F, 0x46, 0xDD, 0xE9, 0x0A, 0xA8, 0x84, 0x68,
+ 0x01, 0x21, 0x06, 0x46, 0x88, 0xF8, 0x00, 0x10, 0x34, 0xF8, 0x08, 0x0F,
+ 0x99, 0x46, 0x93, 0x46, 0x08, 0xB1, 0x0E, 0x25, 0x05, 0xE0, 0x39, 0x46,
+ 0xB0, 0x68, 0xFE, 0xF7, 0xA4, 0xFC, 0x05, 0x00, 0x05, 0xD0, 0xA8, 0xB2,
+ 0x40, 0xEA, 0x07, 0x45, 0x28, 0x46, 0xBD, 0xE8, 0xF8, 0x8F, 0x44, 0xF2,
+ 0x04, 0x00, 0x20, 0x80, 0x39, 0x46, 0x01, 0x20, 0x00, 0xF0, 0xEA, 0xFA,
+ 0x0B, 0x49, 0x00, 0xEB, 0x40, 0x00, 0x4B, 0x46, 0x89, 0x69, 0x5A, 0x46,
+ 0x49, 0x68, 0x01, 0xEB, 0x80, 0x00, 0x60, 0x60, 0x27, 0x81, 0x00, 0x27,
+ 0xA7, 0x81, 0xA4, 0xF8, 0x0A, 0x90, 0xCD, 0xF8, 0x00, 0xA0, 0x03, 0x21,
+ 0xB0, 0x68, 0x01, 0xF0, 0x61, 0xFA, 0x88, 0xF8, 0x00, 0x70, 0xDD, 0xE7,
+ 0x98, 0x77, 0x20, 0x00, 0x7C, 0xB5, 0x0D, 0x46, 0xCD, 0xE9, 0x00, 0x23,
+ 0x04, 0x46, 0x01, 0x8E, 0x05, 0x48, 0x2B, 0x46, 0x02, 0x78, 0x00, 0x20,
+ 0xF8, 0xF7, 0x8C, 0xFA, 0x61, 0x68, 0x00, 0x20, 0x08, 0x81, 0x01, 0x20,
+ 0x7C, 0xBD, 0x00, 0x00, 0x48, 0x74, 0x20, 0x00, 0x30, 0xB5, 0x87, 0xB0,
+ 0x0C, 0x46, 0x05, 0x46, 0x04, 0x20, 0x0A, 0x99, 0x02, 0x2B, 0x28, 0xD1,
+ 0x08, 0x78, 0x49, 0x78, 0x4F, 0xF4, 0x20, 0x53, 0x00, 0xEB, 0x01, 0x20,
+ 0x80, 0xB2, 0x98, 0x42, 0x02, 0xD0, 0x59, 0x1C, 0x88, 0x42, 0x1B, 0xD1,
+ 0x01, 0x21, 0xAD, 0xF8, 0x00, 0x10, 0x98, 0x42, 0x01, 0xD1, 0x01, 0x20,
+ 0x00, 0xE0, 0x00, 0x20, 0x8D, 0xF8, 0x02, 0x00, 0x02, 0x20, 0x01, 0x90,
+ 0x00, 0x20, 0x03, 0x90, 0x04, 0x90, 0x09, 0x48, 0xAD, 0xF8, 0x08, 0x40,
+ 0x05, 0x90, 0xAD, 0xF8, 0x0A, 0x20, 0x69, 0x46, 0x28, 0x46, 0x00, 0xF0,
+ 0x6D, 0xF8, 0x10, 0xB9, 0x07, 0xB0, 0x30, 0xBD, 0x10, 0x20, 0x80, 0xB2,
+ 0x40, 0xEA, 0x04, 0x40, 0xF8, 0xE7, 0x00, 0x00, 0x53, 0xF2, 0x80, 0x00,
+ 0xF0, 0xB5, 0x87, 0xB0, 0x0E, 0x46, 0x0C, 0x9D, 0x44, 0xF2, 0x01, 0x04,
+ 0x02, 0x2B, 0x11, 0xD1, 0x29, 0x78, 0x6F, 0x78, 0x01, 0xEB, 0x07, 0x21,
+ 0x89, 0xB2, 0xA1, 0xF6, 0x02, 0x01, 0xB1, 0xF5, 0x00, 0x51, 0x02, 0xD0,
+ 0x01, 0x29, 0x05, 0xD1, 0x01, 0xE0, 0x05, 0x24, 0x00, 0xE0, 0x03, 0x24,
+ 0x00, 0x23, 0x1D, 0x46, 0xAD, 0xF8, 0x00, 0x40, 0x00, 0x21, 0x8D, 0xF8,
+ 0x02, 0x10, 0x02, 0x21, 0x01, 0x91, 0x09, 0x49, 0xAD, 0xF8, 0x08, 0x60,
+ 0xCD, 0xE9, 0x04, 0x51, 0xAD, 0xF8, 0x0A, 0x20, 0x03, 0x93, 0x69, 0x46,
+ 0x00, 0xF0, 0x36, 0xF8, 0x00, 0x28, 0x02, 0xD0, 0x80, 0xB2, 0x40, 0xEA,
+ 0x06, 0x40, 0x07, 0xB0, 0xF0, 0xBD, 0x00, 0x00, 0x85, 0xF2, 0x80, 0x00,
+ 0xF0, 0xB5, 0x44, 0x68, 0x85, 0xB0, 0x16, 0x46, 0x22, 0x89, 0x0A, 0x9F,
+ 0x00, 0x25, 0xA4, 0x1D, 0x05, 0x2A, 0x11, 0xD0, 0x6F, 0xF4, 0x80, 0x4C,
+ 0x12, 0xEB, 0x0C, 0x0F, 0x0F, 0xD1, 0xCD, 0xE9, 0x01, 0x71, 0x00, 0x93,
+ 0xCD, 0xE9, 0x03, 0x75, 0x71, 0x43, 0xCB, 0x1A, 0x01, 0x8E, 0xA2, 0x88,
+ 0x00, 0x20, 0xFE, 0xF7, 0x63, 0xFA, 0x0C, 0xE0, 0x06, 0x2E, 0x00, 0xD1,
+ 0x01, 0x21, 0x65, 0x80, 0xB3, 0xB2, 0xCD, 0xE9, 0x00, 0x37, 0x02, 0x94,
+ 0x8B, 0xB2, 0x01, 0x8E, 0x28, 0x46, 0x01, 0xF0, 0xFD, 0xFA, 0x65, 0x80,
+ 0x05, 0xB0, 0xF0, 0xBD, 0x2D, 0xE9, 0xF0, 0x4F, 0x0C, 0x46, 0x85, 0x68,
+ 0x09, 0x88, 0x00, 0x27, 0x44, 0xF2, 0x01, 0x08, 0x08, 0x35, 0x89, 0xB0,
+ 0x81, 0x46, 0x41, 0x45, 0x0D, 0xD1, 0x20, 0x69, 0x01, 0x78, 0x40, 0x78,
+ 0x01, 0xEB, 0x00, 0x20, 0xE1, 0x68, 0x80, 0xB2, 0x02, 0x29, 0x04, 0xD1,
+ 0xA0, 0xF5, 0x24, 0x51, 0x02, 0x39, 0x00, 0xD1, 0x01, 0x27, 0xB9, 0xF8,
+ 0x2A, 0x00, 0x61, 0x68, 0x40, 0xF6, 0x9B, 0x33, 0x40, 0x1A, 0x81, 0xB2,
+ 0x07, 0x90, 0x51, 0x48, 0x4F, 0x4A, 0x00, 0x78, 0xF5, 0xF7, 0x86, 0xFF,
+ 0x4F, 0x49, 0x00, 0x28, 0xC8, 0x62, 0x7C, 0xD0, 0x07, 0x98, 0x28, 0x84,
+ 0x8A, 0x46, 0xC8, 0x6A, 0x08, 0xA9, 0xCD, 0xE9, 0x03, 0x10, 0x4F, 0xF0,
+ 0xFF, 0x32, 0x07, 0xAB, 0xCD, 0xE9, 0x05, 0x32, 0xD4, 0xE9, 0x03, 0x12,
+ 0x60, 0x89, 0x4F, 0xF0, 0x00, 0x0B, 0x8D, 0xE8, 0x07, 0x00, 0xA2, 0x78,
+ 0x21, 0x88, 0x04, 0xF1, 0x08, 0x03, 0xD9, 0xF8, 0x08, 0x00, 0x00, 0xF0,
+ 0x03, 0xFF, 0x06, 0x46, 0x07, 0x98, 0x00, 0x28, 0x34, 0xDA, 0x40, 0x42,
+ 0x07, 0x90, 0xA5, 0xF8, 0x00, 0x80, 0x07, 0x99, 0x69, 0x84, 0xD8, 0x46,
+ 0xA5, 0xF8, 0x24, 0x80, 0x08, 0x98, 0x40, 0x1E, 0x48, 0x43, 0x80, 0x1C,
+ 0xE8, 0x84, 0x29, 0x8C, 0x08, 0x1A, 0x28, 0x84, 0xA5, 0xF8, 0x0C, 0x80,
+ 0x21, 0x89, 0x01, 0x20, 0x00, 0xF0, 0xC0, 0xF9, 0xDA, 0xF8, 0x18, 0x10,
+ 0x00, 0xEB, 0x40, 0x00, 0x57, 0x46, 0x49, 0x68, 0x01, 0xEB, 0x80, 0x00,
+ 0x68, 0x60, 0x20, 0x89, 0x28, 0x81, 0x60, 0x89, 0x68, 0x81, 0xA0, 0x89,
+ 0xE8, 0x81, 0xE2, 0x68, 0x22, 0xB1, 0x05, 0xF1, 0x10, 0x00, 0x21, 0x69,
+ 0x20, 0xF4, 0xB5, 0xF2, 0xF8, 0x6A, 0xA8, 0x62, 0x48, 0x46, 0xC7, 0xF8,
+ 0x2C, 0x80, 0x01, 0xF0, 0x1F, 0xF9, 0x37, 0xE0, 0x08, 0x98, 0x00, 0x28,
+ 0x29, 0xDD, 0xCF, 0xB1, 0x00, 0x27, 0xDA, 0xF8, 0x2C, 0x50, 0x12, 0xE0,
+ 0x28, 0x78, 0x69, 0x78, 0x05, 0xF1, 0x02, 0x08, 0x00, 0xEB, 0x01, 0x20,
+ 0x81, 0xB2, 0xB9, 0xF8, 0x30, 0x20, 0x01, 0x20, 0xFE, 0xF7, 0xD8, 0xFD,
+ 0x01, 0x0A, 0x88, 0xF8, 0x00, 0x00, 0x2D, 0x1D, 0x88, 0xF8, 0x01, 0x10,
+ 0x7F, 0x1C, 0x08, 0x98, 0x87, 0x42, 0xE9, 0xDB, 0x5B, 0xEA, 0x06, 0x00,
+ 0x06, 0xD1, 0xDD, 0xE9, 0x07, 0x21, 0x65, 0x69, 0xDA, 0xF8, 0x2C, 0x30,
+ 0x48, 0x46, 0xA8, 0x47, 0x00, 0xE0, 0x16, 0xE0, 0xBB, 0xF1, 0x00, 0x0F,
+ 0x0A, 0xD1, 0xDA, 0xF8, 0x2C, 0x00, 0x55, 0x46, 0x30, 0xB1, 0x40, 0xF6,
+ 0xE7, 0x32, 0x08, 0x49, 0xF5, 0xF7, 0xE6, 0xFF, 0x00, 0x20, 0xE8, 0x62,
+ 0x1E, 0xB1, 0x21, 0x89, 0xB0, 0xB2, 0x40, 0xEA, 0x01, 0x46, 0x09, 0xB0,
+ 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x8F, 0x11, 0x26, 0xF5, 0xE7, 0x00, 0x00,
+ 0x4A, 0xAD, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x98, 0x77, 0x20, 0x00,
+ 0x2D, 0xE9, 0xF7, 0x4F, 0x84, 0xB0, 0x07, 0x46, 0x84, 0x68, 0x05, 0x98,
+ 0x4F, 0xF0, 0x00, 0x0A, 0x08, 0x34, 0x55, 0x46, 0x02, 0x28, 0x08, 0xD0,
+ 0x04, 0x28, 0x7D, 0xD0, 0x50, 0x78, 0x91, 0x78, 0x00, 0xEB, 0x01, 0x20,
+ 0x1F, 0xFA, 0x80, 0xF8, 0x09, 0xE0, 0x50, 0x78, 0x91, 0x78, 0x00, 0xEB,
+ 0x01, 0x20, 0x1F, 0xFA, 0x80, 0xF8, 0xD0, 0x78, 0x11, 0x79, 0x00, 0xEB,
+ 0x01, 0x2A, 0x20, 0x88, 0x08, 0xB1, 0x0E, 0x25, 0x7F, 0xE0, 0x78, 0x8D,
+ 0x40, 0xF6, 0xFC, 0x43, 0x40, 0x1E, 0x81, 0xB2, 0x01, 0x90, 0x41, 0x48,
+ 0x3F, 0x4A, 0x00, 0x78, 0xF5, 0xF7, 0xB6, 0xFE, 0x3F, 0x49, 0x00, 0x28,
+ 0xC8, 0x62, 0x73, 0xD0, 0x01, 0x20, 0x02, 0x90, 0x4F, 0xF0, 0x00, 0x0B,
+ 0x01, 0x98, 0x20, 0x84, 0x5E, 0x46, 0x89, 0x46, 0x01, 0xA8, 0x00, 0x90,
+ 0xD9, 0xF8, 0x2C, 0x30, 0x52, 0x46, 0x41, 0x46, 0xB8, 0x68, 0x00, 0xF0,
+ 0xC7, 0xFC, 0x05, 0x00, 0x40, 0xD1, 0x01, 0x98, 0x00, 0x28, 0x39, 0xDA,
+ 0x41, 0x1C, 0x02, 0xD0, 0x80, 0x1C, 0x27, 0xD0, 0x34, 0xE0, 0x05, 0x98,
+ 0x4F, 0xF0, 0x01, 0x0B, 0x02, 0x28, 0x02, 0xD0, 0x44, 0xF2, 0x02, 0x00,
+ 0x01, 0xE0, 0x44, 0xF2, 0x06, 0x00, 0x20, 0x80, 0x00, 0x20, 0x60, 0x84,
+ 0xA4, 0xF8, 0x0C, 0xA0, 0xA4, 0xF8, 0x08, 0x80, 0x41, 0x46, 0x01, 0x20,
+ 0x00, 0xF0, 0xF6, 0xF8, 0xD9, 0xF8, 0x18, 0x20, 0x00, 0xEB, 0x40, 0x01,
+ 0x38, 0x46, 0x52, 0x68, 0x02, 0xEB, 0x81, 0x01, 0x61, 0x60, 0xD9, 0xF8,
+ 0x2C, 0x10, 0xA1, 0x62, 0x00, 0x21, 0xC9, 0xF8, 0x2C, 0x10, 0x01, 0xF0,
+ 0x61, 0xF8, 0x0D, 0xE0, 0x3A, 0x8E, 0x41, 0x46, 0x01, 0x20, 0xFE, 0xF7,
+ 0x29, 0xFD, 0xD9, 0xF8, 0x2C, 0x20, 0x10, 0x70, 0xD9, 0xF8, 0x2C, 0x10,
+ 0x00, 0x0A, 0x48, 0x70, 0x02, 0x20, 0x01, 0x90, 0x02, 0x98, 0x76, 0x1C,
+ 0x86, 0x42, 0xB3, 0xDB, 0x5B, 0xEA, 0x05, 0x00, 0x0D, 0xD1, 0x05, 0x98,
+ 0x02, 0x28, 0x00, 0xE0, 0x18, 0xE0, 0xD9, 0xF8, 0x2C, 0x30, 0x01, 0x9A,
+ 0x01, 0xD0, 0x0B, 0x21, 0x00, 0xE0, 0x0D, 0x21, 0x38, 0x46, 0xF5, 0xF7,
+ 0x1A, 0xFA, 0xD9, 0xF8, 0x2C, 0x00, 0x4C, 0x46, 0x30, 0xB1, 0x40, 0xF6,
+ 0x46, 0x52, 0x06, 0x49, 0xF5, 0xF7, 0x32, 0xFF, 0x00, 0x20, 0xE0, 0x62,
+ 0x15, 0xB1, 0xA8, 0xB2, 0x40, 0xEA, 0x08, 0x45, 0x07, 0xB0, 0x28, 0x46,
+ 0xBD, 0xE8, 0xF0, 0x8F, 0x64, 0xAD, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00,
+ 0x98, 0x77, 0x20, 0x00, 0xF0, 0xB5, 0x00, 0x27, 0x44, 0x68, 0x85, 0xB0,
+ 0xA4, 0x1D, 0x3E, 0x46, 0x3D, 0x46, 0x01, 0x29, 0x04, 0xD0, 0x02, 0x29,
+ 0x01, 0xD0, 0x00, 0x22, 0x02, 0xE0, 0x27, 0x89, 0x01, 0x26, 0xA5, 0x1D,
+ 0xCD, 0xE9, 0x02, 0x65, 0x00, 0x25, 0xCD, 0xE9, 0x00, 0x53, 0x04, 0x97,
+ 0xA6, 0x88, 0x01, 0x8E, 0x13, 0x46, 0x32, 0x46, 0x28, 0x46, 0xFE, 0xF7,
+ 0xBB, 0xF8, 0x65, 0x80, 0x05, 0xB0, 0xF0, 0xBD, 0x2D, 0xE9, 0xFF, 0x41,
+ 0x05, 0x46, 0xDD, 0xE9, 0x0A, 0x46, 0x1F, 0x46, 0x88, 0x46, 0x27, 0x48,
+ 0xEE, 0xF7, 0x44, 0xDA, 0x03, 0x97, 0x00, 0x95, 0xCD, 0xE9, 0x01, 0x64,
+ 0x03, 0x46, 0x05, 0x22, 0x23, 0x49, 0x24, 0x48, 0xEE, 0xF7, 0x6B, 0xD8,
+ 0x00, 0x2F, 0x12, 0xD1, 0x40, 0x46, 0xFE, 0xF7, 0x0B, 0xFC, 0x00, 0x28,
+ 0x0D, 0xD0, 0x80, 0x68, 0x00, 0x28, 0x0A, 0xD0, 0x00, 0x21, 0xED, 0x1E,
+ 0x06, 0x2D, 0x06, 0xD2, 0xDF, 0xE8, 0x05, 0xF0, 0x03, 0x0C, 0x2D, 0x07,
+ 0x05, 0x28, 0x41, 0x71, 0x81, 0x71, 0xBD, 0xE8, 0xFF, 0x81, 0x41, 0x79,
+ 0x41, 0xF0, 0x04, 0x01, 0x41, 0x71, 0x86, 0x71, 0x84, 0xB1, 0x04, 0x2C,
+ 0x0E, 0xD0, 0x05, 0x2C, 0x10, 0xD0, 0x07, 0x2C, 0x01, 0xD0, 0x08, 0x2C,
+ 0xEF, 0xD1, 0x41, 0x79, 0x08, 0x2C, 0x41, 0xF0, 0x09, 0x01, 0x41, 0x71,
+ 0xE9, 0xD1, 0x41, 0xF0, 0x02, 0x01, 0x07, 0xE0, 0x41, 0x79, 0x41, 0xF0,
+ 0x01, 0x01, 0x03, 0xE0, 0x41, 0x79, 0x41, 0xF0, 0x01, 0x01, 0xF4, 0xE7,
+ 0x41, 0x71, 0xDC, 0xE7, 0x42, 0x79, 0x22, 0xF0, 0x04, 0x02, 0x42, 0x71,
+ 0x81, 0x71, 0x41, 0x79, 0x21, 0xF0, 0x03, 0x01, 0xF4, 0xE7, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x21, 0xA0, 0x4D, 0xC0, 0x08, 0x03, 0x38, 0x10, 0x21,
+ 0x2D, 0xE9, 0xF0, 0x47, 0x0F, 0x46, 0x80, 0x46, 0x01, 0x46, 0x91, 0x46,
+ 0x00, 0x24, 0x40, 0xF6, 0x01, 0x46, 0x38, 0x46, 0xFE, 0xF7, 0x05, 0xFA,
+ 0x05, 0x00, 0x11, 0xD1, 0xFD, 0xF7, 0x06, 0xFF, 0x04, 0x00, 0x0C, 0xD0,
+ 0x67, 0x60, 0xA4, 0xF8, 0x08, 0x80, 0xA4, 0xF8, 0x0A, 0x90, 0x20, 0x46,
+ 0x00, 0xF0, 0x54, 0xFA, 0x20, 0xB9, 0xB5, 0x1D, 0x00, 0x20, 0x60, 0x80,
+ 0x00, 0xE0, 0x35, 0x46, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47,
+ 0xF7, 0xF7, 0x7B, 0xBD, 0x00, 0x23, 0x01, 0x46, 0x1A, 0x46, 0x18, 0x46,
+ 0xFE, 0xF7, 0x0C, 0xBD, 0xF0, 0xB5, 0x19, 0x4A, 0x17, 0x4E, 0x00, 0x23,
+ 0x92, 0xF8, 0xAD, 0x51, 0xA6, 0xF1, 0x1C, 0x02, 0x92, 0xF8, 0x31, 0x70,
+ 0x1A, 0xE0, 0x72, 0x68, 0x03, 0xEB, 0x43, 0x04, 0x02, 0xEB, 0x84, 0x02,
+ 0x54, 0x88, 0x94, 0xB1, 0x54, 0x89, 0x27, 0xB1, 0x8C, 0x42, 0x08, 0xD9,
+ 0x0D, 0xE0, 0x20, 0xB9, 0x11, 0xE0, 0x8C, 0x42, 0x03, 0xD3, 0x00, 0x28,
+ 0x00, 0xD0, 0x10, 0x88, 0xF0, 0xBD, 0xB2, 0xF8, 0x08, 0xC0, 0x64, 0x44,
+ 0x64, 0x1E, 0x8C, 0x42, 0xF1, 0xDA, 0x5B, 0x1C, 0x9D, 0x42, 0xE2, 0xDC,
+ 0x20, 0xB1, 0x28, 0x46, 0xF0, 0xBD, 0x50, 0x89, 0x08, 0x1A, 0xF0, 0xBD,
+ 0x4F, 0xF0, 0xFF, 0x30, 0xF0, 0xBD, 0x00, 0x00, 0xB4, 0x77, 0x20, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x8F, 0xB0, 0x89, 0x46,
+ 0x1A, 0x99, 0x06, 0x46, 0x00, 0x27, 0x85, 0x68, 0x01, 0x20, 0x08, 0x70,
+ 0x35, 0xF8, 0x08, 0x0F, 0x98, 0x46, 0x92, 0x46, 0x40, 0xB1, 0xB9, 0xF1,
+ 0x02, 0x0F, 0x04, 0xD0, 0xB9, 0xF1, 0x05, 0x0F, 0x01, 0xD0, 0x0E, 0x24,
+ 0xD4, 0xE0, 0x01, 0x27, 0x09, 0xF0, 0xFF, 0x00, 0x00, 0x90, 0xCD, 0xF8,
+ 0x30, 0x80, 0x0C, 0xAB, 0xB0, 0x68, 0x51, 0x46, 0x19, 0x9A, 0x01, 0xF0,
+ 0x73, 0xFA, 0x04, 0x00, 0x73, 0xD1, 0x0D, 0x90, 0x0C, 0x98, 0xA3, 0x46,
+ 0x00, 0x28, 0x03, 0xDA, 0x41, 0x1C, 0x02, 0xD0, 0x80, 0x1C, 0x40, 0xD0,
+ 0xCF, 0xE0, 0x27, 0xB1, 0x2C, 0x22, 0x29, 0x46, 0x01, 0xA8, 0x20, 0xF4,
+ 0xE5, 0xF0, 0x48, 0x46, 0xB9, 0xF1, 0x01, 0x0F, 0x0D, 0xD0, 0x02, 0x28,
+ 0x03, 0xD0, 0xB9, 0xF1, 0x05, 0x0F, 0x0D, 0xD1, 0x02, 0xE0, 0xA5, 0xF8,
+ 0x00, 0xB0, 0x09, 0xE0, 0xA5, 0xF8, 0x00, 0xB0, 0xA8, 0xF1, 0x0C, 0x08,
+ 0x04, 0xE0, 0x44, 0xF2, 0x03, 0x00, 0x28, 0x80, 0x01, 0x20, 0x0D, 0x90,
+ 0x51, 0x46, 0x01, 0x20, 0xFF, 0xF7, 0x7A, 0xFF, 0x00, 0xEB, 0x40, 0x01,
+ 0x66, 0x48, 0x42, 0x46, 0x80, 0x69, 0x40, 0x68, 0x00, 0xEB, 0x81, 0x00,
+ 0x68, 0x60, 0xA5, 0xF8, 0x08, 0xA0, 0xA5, 0xF8, 0x0C, 0xB0, 0x19, 0x98,
+ 0x00, 0x90, 0xB0, 0x68, 0x49, 0x46, 0x18, 0x9B, 0x00, 0xF0, 0xF2, 0xFE,
+ 0x1A, 0x99, 0x00, 0x2F, 0x81, 0xF8, 0x00, 0xB0, 0x04, 0xD0, 0x2C, 0x22,
+ 0x01, 0xA9, 0x28, 0x46, 0x20, 0xF4, 0xAC, 0xF0, 0x8C, 0xE0, 0x19, 0x98,
+ 0xB8, 0xF1, 0x02, 0x0F, 0x01, 0x78, 0x40, 0x78, 0x01, 0xEB, 0x00, 0x20,
+ 0x87, 0xB2, 0x0A, 0xD0, 0xB8, 0xF1, 0x01, 0x0F, 0x06, 0xD0, 0xCD, 0xF8,
+ 0x30, 0xB0, 0xB8, 0xF1, 0x02, 0x0F, 0x7E, 0xD9, 0x0D, 0x24, 0x63, 0xE0,
+ 0xFF, 0xB2, 0x00, 0x23, 0x42, 0xF6, 0x03, 0x02, 0x51, 0x46, 0x58, 0x1E,
+ 0xFE, 0xF7, 0x4C, 0xFC, 0xF0, 0xB3, 0xFE, 0xF7, 0xD3, 0xFB, 0xB9, 0x08,
+ 0x07, 0xD1, 0xC1, 0x06, 0x01, 0xD4, 0xF9, 0x07, 0x03, 0xD1, 0x80, 0x06,
+ 0x04, 0xD4, 0xB8, 0x07, 0x02, 0xD5, 0xC0, 0x24, 0x4C, 0xE0, 0x4D, 0xE0,
+ 0x3B, 0x46, 0x52, 0x46, 0x01, 0x21, 0x30, 0x46, 0x01, 0xF0, 0x78, 0xF9,
+ 0x00, 0x28, 0x02, 0xDA, 0x4F, 0xF0, 0x11, 0x04, 0x2A, 0xE0, 0x04, 0xDD,
+ 0xB1, 0x68, 0x4F, 0xF0, 0x01, 0x00, 0xC8, 0x71, 0x18, 0xE0, 0x51, 0x46,
+ 0x4F, 0xF0, 0x00, 0x00, 0xFF, 0xF7, 0x1A, 0xFF, 0x1F, 0xFA, 0x80, 0xF8,
+ 0x51, 0x46, 0x01, 0x20, 0xFF, 0xF7, 0x14, 0xFF, 0x34, 0x49, 0x80, 0xB2,
+ 0x00, 0xEB, 0x40, 0x00, 0x09, 0x6A, 0x01, 0xEB, 0x80, 0x00, 0x41, 0x68,
+ 0xC8, 0xEB, 0xC8, 0x00, 0x11, 0xF8, 0x20, 0x00, 0x80, 0x06, 0x0B, 0xD5,
+ 0xAD, 0xF8, 0x00, 0xA0, 0xAD, 0xF8, 0x02, 0x70, 0x6B, 0x46, 0x00, 0xE0,
+ 0x19, 0xE0, 0x01, 0x22, 0x11, 0x46, 0x30, 0x46, 0x00, 0xF0, 0xB6, 0xFE,
+ 0x28, 0x48, 0x90, 0xF8, 0xB0, 0x01, 0x40, 0x07, 0x0D, 0xD4, 0xB0, 0x68,
+ 0xC0, 0x79, 0x50, 0xB1, 0x5F, 0x46, 0x33, 0x46, 0x00, 0x22, 0x01, 0x21,
+ 0x03, 0x20, 0xCD, 0xF8, 0x00, 0xB0, 0x00, 0xF0, 0x4D, 0xFF, 0xB0, 0x68,
+ 0xC7, 0x71, 0xBC, 0xB1, 0x00, 0xE0, 0x0E, 0x24, 0xA5, 0xF8, 0x00, 0xB0,
+ 0xB9, 0xF1, 0x05, 0x0F, 0x25, 0xD0, 0x54, 0xB1, 0xCD, 0xE9, 0x00, 0x4A,
+ 0x4B, 0x46, 0x03, 0x22, 0x19, 0x49, 0x1A, 0x48, 0xED, 0xF7, 0xCD, 0xDE,
+ 0xA0, 0xB2, 0x40, 0xEA, 0x0A, 0x44, 0x0F, 0xB0, 0x20, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x8F, 0x02, 0xE0, 0x0D, 0x98, 0x00, 0x28, 0xE8, 0xD1, 0xB9, 0xF1,
+ 0x01, 0x0F, 0xE5, 0xD1, 0xCD, 0xF8, 0x00, 0xB0, 0xCD, 0xF8, 0x04, 0xB0,
+ 0xCD, 0xF8, 0x08, 0xB0, 0x00, 0x23, 0x01, 0x22, 0x13, 0x21, 0x30, 0x46,
+ 0xCD, 0xF8, 0x0C, 0xB0, 0xF4, 0xF7, 0x80, 0xFD, 0xE5, 0xE7, 0x31, 0x8E,
+ 0x34, 0xB1, 0xA0, 0xB2, 0x40, 0xF4, 0x80, 0x60, 0x00, 0x22, 0xFA, 0xF7,
+ 0x12, 0xFD, 0xD1, 0xE7, 0x00, 0x22, 0x10, 0x46, 0xFA, 0xF7, 0x0D, 0xFD,
+ 0xD7, 0xE7, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x90, 0x4F, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21, 0x10, 0xB5, 0x04, 0x46,
+ 0x40, 0x68, 0x0A, 0x46, 0x21, 0x8E, 0x43, 0x89, 0x00, 0x20, 0xF7, 0xF7,
+ 0xD3, 0xFE, 0x62, 0x68, 0x00, 0x21, 0x11, 0x81, 0x10, 0xBD, 0x00, 0x00,
+ 0x2D, 0xE9, 0xF0, 0x47, 0x65, 0x4A, 0x66, 0x49, 0x10, 0x1F, 0xF5, 0xF7,
+ 0xD3, 0xFD, 0x00, 0x28, 0x7D, 0xD0, 0x62, 0x4F, 0x1C, 0x20, 0x63, 0x4E,
+ 0x38, 0x81, 0x07, 0xF1, 0x1C, 0x05, 0xBD, 0x61, 0x96, 0xF8, 0x78, 0x01,
+ 0x80, 0x07, 0x01, 0xD5, 0x00, 0x20, 0x00, 0xE0, 0x01, 0x20, 0x87, 0xF8,
+ 0x31, 0x00, 0x96, 0xF8, 0x98, 0x01, 0x5C, 0x21, 0x10, 0xFB, 0x01, 0xF1,
+ 0x53, 0x23, 0x5A, 0x4A, 0x00, 0x20, 0xF8, 0xF7, 0xFD, 0xDB, 0x78, 0x60,
+ 0x18, 0xB9, 0x96, 0xF8, 0x98, 0x01, 0x00, 0x28, 0x7E, 0xD1, 0x96, 0xF8,
+ 0x98, 0x01, 0xA8, 0x46, 0x00, 0xEB, 0xC0, 0x00, 0x81, 0x00, 0x5B, 0x23,
+ 0x51, 0x4A, 0x00, 0x20, 0xF8, 0xF7, 0xEC, 0xDB, 0xC8, 0xF8, 0x0C, 0x00,
+ 0x18, 0xB9, 0x96, 0xF8, 0x98, 0x01, 0x00, 0x28, 0x6C, 0xD1, 0x96, 0xF8,
+ 0x98, 0x01, 0x63, 0x23, 0x00, 0xEB, 0xC0, 0x00, 0xC1, 0x00, 0x49, 0x4A,
+ 0x00, 0x20, 0xF8, 0xF7, 0xDB, 0xDB, 0x28, 0x60, 0x10, 0xB9, 0x96, 0xF8,
+ 0x98, 0x01, 0xE8, 0xBB, 0x96, 0xF8, 0xAD, 0x01, 0x6A, 0x23, 0x00, 0xEB,
+ 0x40, 0x00, 0x81, 0x00, 0x41, 0x4A, 0x00, 0x20, 0xF8, 0xF7, 0xCC, 0xDB,
+ 0x68, 0x60, 0x10, 0xB9, 0x96, 0xF8, 0xAD, 0x01, 0x70, 0xBB, 0x96, 0xF8,
+ 0xAC, 0x01, 0x71, 0x23, 0xC1, 0x00, 0x3B, 0x4A, 0x00, 0x20, 0xF8, 0xF7,
+ 0xBF, 0xDB, 0xA8, 0x60, 0x10, 0xB9, 0x96, 0xF8, 0xAC, 0x01, 0x08, 0xBB,
+ 0x00, 0x24, 0xB1, 0x46, 0x43, 0xE0, 0xC4, 0xEB, 0xC4, 0x01, 0x78, 0x68,
+ 0x01, 0xEB, 0x04, 0x16, 0x4F, 0xF0, 0x08, 0x0C, 0x00, 0xF8, 0x26, 0x40,
+ 0x29, 0x68, 0x7A, 0x68, 0x04, 0xEB, 0xC4, 0x00, 0x0C, 0xEB, 0x86, 0x0C,
+ 0x01, 0xEB, 0xC0, 0x01, 0x42, 0xF8, 0x0C, 0x10, 0x79, 0x68, 0x2A, 0x68,
+ 0x01, 0xEB, 0x86, 0x01, 0x42, 0xF8, 0x30, 0x10, 0xD8, 0xF8, 0x0C, 0x10,
+ 0x01, 0xEB, 0x80, 0x01, 0x01, 0xE0, 0x20, 0xE0, 0x1E, 0xE0, 0x4F, 0xF0,
+ 0x04, 0x0C, 0x7A, 0x68, 0x0C, 0xEB, 0x86, 0x0C, 0x84, 0x23, 0x42, 0xF8,
+ 0x0C, 0x10, 0x79, 0x68, 0x01, 0xEB, 0x86, 0x02, 0xD8, 0xF8, 0x0C, 0x10,
+ 0x41, 0xF8, 0x20, 0x20, 0x99, 0xF8, 0xAB, 0x01, 0x1C, 0x4A, 0x41, 0x01,
+ 0x00, 0x20, 0xF8, 0xF7, 0x81, 0xDB, 0x0C, 0x21, 0x7A, 0x68, 0x01, 0xEB,
+ 0x86, 0x01, 0x50, 0x50, 0x28, 0xB9, 0x99, 0xF8, 0xAB, 0x01, 0x10, 0xB1,
+ 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0x64, 0x1C, 0xE4, 0xB2, 0x99, 0xF8,
+ 0x98, 0x01, 0x4B, 0x46, 0xA0, 0x42, 0xB6, 0xD8, 0x93, 0xF8, 0xAD, 0x01,
+ 0x1C, 0x46, 0x00, 0xEB, 0x40, 0x00, 0x81, 0x00, 0x68, 0x68, 0x1F, 0xF4,
+ 0x85, 0xF7, 0x00, 0x20, 0x06, 0xE0, 0x69, 0x68, 0x00, 0xEB, 0x40, 0x02,
+ 0x21, 0xF8, 0x22, 0x00, 0x40, 0x1C, 0xC0, 0xB2, 0x94, 0xF8, 0xAD, 0x11,
+ 0x81, 0x42, 0xF4, 0xD8, 0x1E, 0x20, 0x87, 0xF8, 0x30, 0x00, 0x01, 0x20,
+ 0xDB, 0xE7, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, 0x5D, 0x86, 0x81, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0xD8, 0xAB, 0x82, 0x00, 0x2D, 0xE9, 0xF0, 0x41,
+ 0x29, 0x49, 0x29, 0x4A, 0x01, 0x24, 0x91, 0xF8, 0x78, 0x11, 0x28, 0x4E,
+ 0x92, 0xF8, 0xAD, 0x51, 0x4F, 0xF0, 0x00, 0x03, 0x89, 0x07, 0x1A, 0x46,
+ 0x11, 0xD5, 0x33, 0xE0, 0x71, 0x68, 0x02, 0xEB, 0x42, 0x07, 0x01, 0xEB,
+ 0x87, 0x01, 0x81, 0x42, 0x08, 0xD0, 0x4F, 0x88, 0x37, 0xB1, 0x4F, 0x89,
+ 0x09, 0x89, 0x39, 0x44, 0x49, 0x1E, 0x99, 0x42, 0x00, 0xDD, 0x8B, 0xB2,
+ 0x52, 0x1C, 0x95, 0x42, 0xEC, 0xDC, 0x41, 0x89, 0x03, 0xF1, 0x01, 0x03,
+ 0x19, 0xB1, 0x99, 0x42, 0x03, 0xD2, 0x00, 0x24, 0x20, 0xE0, 0x43, 0x81,
+ 0x1E, 0xE0, 0x15, 0x4A, 0x00, 0x21, 0x1C, 0x3A, 0x82, 0xF8, 0x31, 0x10,
+ 0x18, 0xE0, 0x71, 0x68, 0x02, 0xEB, 0x42, 0x07, 0x01, 0xEB, 0x87, 0x01,
+ 0x81, 0x42, 0x08, 0xD0, 0x4F, 0x88, 0x37, 0xB1, 0x4F, 0x89, 0x09, 0x89,
+ 0x39, 0x44, 0x49, 0x1E, 0x99, 0x42, 0x00, 0xDD, 0x8B, 0xB2, 0x52, 0x1C,
+ 0x95, 0x42, 0xEC, 0xD8, 0x01, 0x21, 0x13, 0xB1, 0x19, 0x09, 0x09, 0x01,
+ 0x10, 0x31, 0x41, 0x81, 0x43, 0x89, 0x01, 0x22, 0x05, 0x49, 0x06, 0x48,
+ 0xED, 0xF7, 0x63, 0xDD, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0xB4, 0x77, 0x20, 0x00, 0xFC, 0x4E, 0xC0, 0x08,
+ 0x03, 0x38, 0x10, 0x21, 0x70, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0x05, 0x21,
+ 0xFD, 0xF7, 0xF6, 0xFE, 0x2C, 0xB1, 0x21, 0x46, 0x28, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0x00, 0xF0, 0x6D, 0xB8, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40,
+ 0x00, 0x21, 0x00, 0xF0, 0x19, 0xB8, 0x02, 0x8E, 0x81, 0x7E, 0x13, 0x30,
+ 0xF7, 0xF7, 0x80, 0xB8, 0x01, 0x22, 0x80, 0xF8, 0x2F, 0x20, 0xFD, 0xF7,
+ 0x50, 0xBF, 0x70, 0xB5, 0x05, 0x46, 0x0C, 0x46, 0x13, 0x30, 0xF7, 0xF7,
+ 0xA9, 0xF8, 0x00, 0x2C, 0x04, 0xD0, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40,
+ 0xFE, 0xF7, 0x22, 0xB9, 0x70, 0xBD, 0x00, 0x00, 0x7F, 0xB5, 0x04, 0x46,
+ 0x00, 0xF1, 0x13, 0x05, 0x00, 0x29, 0x23, 0xDD, 0x94, 0xF8, 0x34, 0x00,
+ 0x8D, 0xF8, 0x00, 0x00, 0xA0, 0x7E, 0x8D, 0xF8, 0x07, 0x00, 0x1B, 0x48,
+ 0x6B, 0x46, 0x90, 0xF8, 0xAB, 0x01, 0x8D, 0xF8, 0x08, 0x00, 0xE0, 0x8E,
+ 0xAD, 0xF8, 0x0A, 0x00, 0x60, 0x8F, 0xAD, 0xF8, 0x0C, 0x00, 0xA0, 0x8F,
+ 0xAD, 0xF8, 0x0E, 0x00, 0xD4, 0xF8, 0x13, 0x00, 0xCD, 0xF8, 0x01, 0x00,
+ 0xB4, 0xF8, 0x17, 0x00, 0xAD, 0xF8, 0x05, 0x00, 0x62, 0x8D, 0x21, 0x8E,
+ 0x28, 0x46, 0xF6, 0xF7, 0xB5, 0xFF, 0x7F, 0xBD, 0x94, 0xF8, 0x2F, 0x00,
+ 0x10, 0xB9, 0x0C, 0x48, 0x80, 0x7A, 0x28, 0xB1, 0x20, 0x8D, 0x17, 0x28,
+ 0x02, 0xD3, 0x20, 0x46, 0xF4, 0xF7, 0xD7, 0xFC, 0x21, 0x8E, 0x28, 0x46,
+ 0xF9, 0xF7, 0x3C, 0xFA, 0x00, 0x20, 0x02, 0x46, 0x01, 0x21, 0x00, 0x90,
+ 0x23, 0x46, 0x08, 0x46, 0x00, 0xF0, 0x56, 0xFD, 0x7F, 0xBD, 0x00, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x98, 0x77, 0x20, 0x00, 0x0A, 0x46, 0x00, 0xF1,
+ 0x13, 0x01, 0x10, 0x46, 0xF7, 0xF7, 0x90, 0xB8, 0x70, 0xB5, 0x13, 0x4D,
+ 0x04, 0x46, 0x43, 0x7E, 0x01, 0x22, 0x10, 0x49, 0x28, 0x46, 0xED, 0xF7,
+ 0xD4, 0xDC, 0x60, 0x7E, 0x05, 0x28, 0x0D, 0xD0, 0x03, 0x28, 0x15, 0xD0,
+ 0x04, 0x28, 0x13, 0xD0, 0x0A, 0x49, 0x00, 0x22, 0x28, 0x31, 0x28, 0x46,
+ 0xED, 0xF7, 0xC7, 0xDC, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0, 0xF0, 0xBA,
+ 0x03, 0x21, 0x20, 0x46, 0xFD, 0xF7, 0x64, 0xFE, 0x20, 0x8E, 0xBD, 0xE8,
+ 0x70, 0x40, 0x13, 0x21, 0x01, 0xF0, 0x26, 0xBA, 0x70, 0xBD, 0x00, 0x00,
+ 0x10, 0x49, 0xC0, 0x08, 0x03, 0x38, 0x10, 0x21, 0x70, 0xB5, 0x1C, 0x46,
+ 0x0B, 0x46, 0x05, 0x46, 0x32, 0xB1, 0x05, 0xF1, 0x13, 0x01, 0x18, 0x46,
+ 0xF7, 0xF7, 0x5C, 0xF8, 0x00, 0x2C, 0x0C, 0xD0, 0x00, 0x21, 0x28, 0x46,
+ 0xF4, 0xF7, 0xB0, 0xFF, 0x01, 0x21, 0x28, 0x46, 0xF4, 0xF7, 0xAC, 0xFF,
+ 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xFE, 0xF7, 0x8F, 0xB8, 0x70, 0xBD,
+ 0x70, 0xB5, 0x15, 0x46, 0x1C, 0x46, 0x01, 0x22, 0x48, 0xB1, 0x43, 0x7E,
+ 0x03, 0x2B, 0x06, 0xD0, 0x04, 0x2B, 0x04, 0xD0, 0xE2, 0xB2, 0x2B, 0x46,
+ 0xF4, 0xF7, 0x0E, 0xFA, 0x02, 0x46, 0x10, 0x46, 0x70, 0xBD, 0x92, 0xB2,
+ 0x00, 0xF0, 0xB4, 0xBE, 0x10, 0xB5, 0xFE, 0xF7, 0x4D, 0xF8, 0x00, 0x28,
+ 0x09, 0xD0, 0xC1, 0x69, 0x00, 0x29, 0x06, 0xD0, 0xC1, 0x7E, 0x00, 0x29,
+ 0x03, 0xD0, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0x01, 0xB8, 0x10, 0xBD,
+ 0x10, 0xB5, 0xC1, 0x69, 0x04, 0x46, 0x00, 0x29, 0x0C, 0xD0, 0x07, 0x48,
+ 0x62, 0x8C, 0xA3, 0x8C, 0x01, 0x60, 0x20, 0x46, 0xFF, 0xF7, 0xD0, 0xFF,
+ 0x01, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0xFE, 0xF7, 0x96, 0xB8,
+ 0x10, 0xBD, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, 0x30, 0xB5, 0x55, 0x89,
+ 0x5C, 0x1E, 0x2C, 0x44, 0xA4, 0xB2, 0x68, 0xB1, 0x10, 0x89, 0x98, 0x42,
+ 0x0A, 0xD1, 0x07, 0x48, 0x13, 0x88, 0x90, 0xF8, 0xAD, 0x01, 0x40, 0x1E,
+ 0x83, 0x42, 0x01, 0xDA, 0xD0, 0x89, 0x08, 0xB9, 0x4F, 0xF6, 0xFF, 0x74,
+ 0x0C, 0x70, 0x20, 0x0A, 0x48, 0x70, 0x30, 0xBD, 0x64, 0x01, 0x20, 0x00,
+ 0x2D, 0xE9, 0xFF, 0x4F, 0x8B, 0xB0, 0x98, 0x46, 0xDD, 0xF8, 0x60, 0xA0,
+ 0x15, 0x46, 0x0F, 0x46, 0xDA, 0xF8, 0x00, 0x00, 0x07, 0x90, 0x01, 0x24,
+ 0x08, 0x46, 0xFF, 0xF7, 0x39, 0xFC, 0x06, 0x00, 0x6B, 0xD0, 0x02, 0x46,
+ 0x00, 0x23, 0x39, 0x46, 0x0B, 0x98, 0xFD, 0xF7, 0x7D, 0xFB, 0x04, 0x00,
+ 0x63, 0xD1, 0x30, 0x46, 0xFD, 0xF7, 0xCE, 0xFB, 0x10, 0xB1, 0xA0, 0x1E,
+ 0x07, 0x90, 0x5C, 0xE0, 0x30, 0x46, 0xFD, 0xF7, 0xC3, 0xFB, 0x4F, 0xF0,
+ 0x00, 0x0B, 0x4F, 0xF0, 0xFF, 0x39, 0x28, 0xB3, 0xCD, 0xE9, 0x00, 0x7B,
+ 0x02, 0xA9, 0xAD, 0xF8, 0x20, 0x70, 0x09, 0xAB, 0x58, 0x46, 0x81, 0xE8,
+ 0x09, 0x01, 0x07, 0xAA, 0xCD, 0xE9, 0x05, 0x29, 0x08, 0xAB, 0x00, 0x22,
+ 0x03, 0x21, 0x0B, 0x98, 0x00, 0xF0, 0x3C, 0xF9, 0x04, 0x00, 0x40, 0xD1,
+ 0x07, 0x98, 0x40, 0x1B, 0x80, 0x1E, 0x07, 0x90, 0x28, 0xD4, 0x00, 0x20,
+ 0x06, 0xE0, 0x42, 0x19, 0x02, 0xEB, 0x08, 0x01, 0x8A, 0x78, 0x08, 0xF8,
+ 0x00, 0x20, 0x40, 0x1C, 0x07, 0x99, 0x88, 0x42, 0xF5, 0xDB, 0x2E, 0xE0,
+ 0x77, 0x8A, 0x8F, 0xB9, 0x30, 0x88, 0x41, 0x07, 0x0C, 0xD4, 0x01, 0x07,
+ 0x0A, 0xD5, 0x80, 0x07, 0x01, 0xD5, 0x30, 0x1D, 0x00, 0xE0, 0x70, 0x69,
+ 0x1F, 0xF4, 0xDE, 0xF4, 0x80, 0xB2, 0x40, 0x1C, 0x87, 0xB2, 0x01, 0xE0,
+ 0xCD, 0xF8, 0x1C, 0x90, 0x07, 0x98, 0x40, 0x1C, 0x17, 0xD0, 0xBD, 0x42,
+ 0x05, 0xDB, 0xCD, 0xF8, 0x1C, 0xB0, 0x12, 0xDD, 0x4F, 0xF0, 0x07, 0x04,
+ 0x0F, 0xE0, 0x30, 0x46, 0xFE, 0xF7, 0x1C, 0xF8, 0x90, 0xB1, 0x07, 0x9A,
+ 0x79, 0x1B, 0x91, 0x42, 0x00, 0xDA, 0x07, 0x91, 0x07, 0x9A, 0x00, 0x2A,
+ 0x03, 0xDD, 0x41, 0x19, 0x40, 0x46, 0x1F, 0xF4, 0xDC, 0xF4, 0x07, 0x99,
+ 0xCA, 0xF8, 0x00, 0x10, 0x0F, 0xB0, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x8F,
+ 0xCD, 0xF8, 0x1C, 0x90, 0xF5, 0xE7, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x41,
+ 0x86, 0x68, 0x8A, 0xB0, 0x15, 0x46, 0x00, 0x27, 0x06, 0xF1, 0x0C, 0x04,
+ 0x6F, 0xF4, 0x80, 0x48, 0x79, 0xB1, 0x08, 0x46, 0xFD, 0xF7, 0x09, 0xFD,
+ 0x03, 0x00, 0x7D, 0xD0, 0x31, 0x89, 0xA2, 0x88, 0x11, 0xEB, 0x08, 0x00,
+ 0x79, 0xD0, 0x01, 0x28, 0x78, 0xD0, 0x05, 0x28, 0x77, 0xD0, 0x00, 0x21,
+ 0xA5, 0xE0, 0x98, 0x88, 0x9B, 0x1D, 0xC1, 0x18, 0x33, 0x89, 0x00, 0x22,
+ 0x13, 0xEB, 0x08, 0x00, 0x1C, 0xD0, 0x01, 0x28, 0x02, 0xD0, 0x05, 0x28,
+ 0x34, 0xD1, 0x0A, 0xE0, 0xA0, 0x8B, 0xA8, 0x42, 0x01, 0xD2, 0x07, 0x90,
+ 0x00, 0xE0, 0x07, 0x95, 0x0B, 0x46, 0x30, 0x68, 0x0B, 0x21, 0x07, 0x9A,
+ 0x09, 0xE0, 0xA0, 0x8B, 0xA8, 0x42, 0x01, 0xD2, 0x07, 0x90, 0x00, 0xE0,
+ 0x07, 0x95, 0x0B, 0x46, 0x30, 0x68, 0x0D, 0x21, 0x07, 0x9A, 0xF4, 0xF7,
+ 0xE0, 0xFC, 0x85, 0xE0, 0x20, 0x8C, 0x30, 0xB1, 0xA8, 0x42, 0x00, 0xD0,
+ 0x01, 0x22, 0xE0, 0x8B, 0x02, 0x28, 0x02, 0xD0, 0x07, 0xE0, 0x25, 0x84,
+ 0xF9, 0xE7, 0xA0, 0x8B, 0xA8, 0x42, 0x00, 0xD2, 0x05, 0x46, 0xA8, 0x1C,
+ 0xE0, 0x83, 0x2A, 0xB1, 0x60, 0x8C, 0x80, 0x1E, 0x60, 0x84, 0xE0, 0x88,
+ 0xA0, 0x80, 0x13, 0xE0, 0x80, 0xB2, 0x80, 0x1E, 0xA8, 0x42, 0x01, 0xD0,
+ 0x0E, 0x23, 0xB1, 0xE7, 0x62, 0x8C, 0x60, 0x6A, 0x10, 0x44, 0x2A, 0x46,
+ 0x1F, 0xF4, 0x6D, 0xF4, 0x60, 0x8C, 0x28, 0x44, 0x60, 0x84, 0xA0, 0x8B,
+ 0x40, 0x1B, 0x80, 0xB2, 0xA0, 0x83, 0x07, 0x90, 0xA0, 0x88, 0xE1, 0x88,
+ 0x88, 0x42, 0x46, 0xD2, 0x40, 0x1C, 0xA0, 0x80, 0x63, 0x8C, 0x60, 0x6A,
+ 0x07, 0xAA, 0x18, 0x44, 0xCD, 0xE9, 0x04, 0x02, 0x08, 0xAB, 0x4F, 0xF0,
+ 0xFF, 0x31, 0x03, 0x93, 0x06, 0x91, 0xE0, 0x88, 0x04, 0xF1, 0x0C, 0x02,
+ 0x61, 0x89, 0x8D, 0xE8, 0x07, 0x00, 0x31, 0x89, 0x23, 0x1D, 0x00, 0x22,
+ 0x30, 0x46, 0x00, 0xF0, 0x65, 0xF8, 0x07, 0x98, 0x00, 0x28, 0x1C, 0xDA,
+ 0xA0, 0x8B, 0x03, 0xE0, 0x34, 0xE0, 0x2F, 0xE0, 0x2A, 0xE0, 0x2B, 0xE0,
+ 0x80, 0x1E, 0xA0, 0x83, 0x60, 0x8C, 0x80, 0x1C, 0x60, 0x84, 0xA1, 0x88,
+ 0x01, 0x20, 0xFF, 0xF7, 0x2B, 0xFB, 0x1B, 0x49, 0x00, 0xEB, 0x40, 0x00,
+ 0x89, 0x69, 0x49, 0x68, 0x01, 0xEB, 0x80, 0x00, 0x20, 0x60, 0x30, 0x68,
+ 0x00, 0xF0, 0x9C, 0xFA, 0x0A, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x60, 0x8C,
+ 0xE1, 0x8B, 0xB0, 0xFB, 0xF1, 0xF0, 0x08, 0x99, 0x08, 0x44, 0x08, 0x90,
+ 0xE2, 0x8B, 0x63, 0x6A, 0x30, 0x68, 0x08, 0x99, 0xF4, 0xF7, 0x1E, 0xFC,
+ 0x0E, 0xE0, 0x60, 0x8C, 0xE1, 0x8B, 0xB0, 0xFB, 0xF1, 0xF0, 0xF2, 0xE7,
+ 0x0A, 0x21, 0x02, 0xE0, 0x0C, 0x21, 0x00, 0xE0, 0x08, 0x21, 0x30, 0x68,
+ 0xF4, 0xF7, 0x4A, 0xFA, 0x00, 0x2F, 0xDF, 0xD1, 0x00, 0x25, 0x35, 0x81,
+ 0x60, 0x6A, 0x00, 0x28, 0xDA, 0xD0, 0x40, 0xF6, 0x3B, 0x72, 0x03, 0x49,
+ 0xF5, 0xF7, 0x70, 0xF9, 0x65, 0x62, 0xD3, 0xE7, 0x98, 0x77, 0x20, 0x00,
+ 0x79, 0xAD, 0x82, 0x00, 0x01, 0x49, 0x48, 0x60, 0x70, 0x47, 0x00, 0x00,
+ 0xF4, 0x78, 0x20, 0x00, 0x02, 0x48, 0x00, 0x21, 0x81, 0x81, 0x81, 0x73,
+ 0x70, 0x47, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, 0xCA, 0x68, 0xC2, 0x61,
+ 0x0A, 0x89, 0x42, 0x84, 0xCA, 0x88, 0x82, 0x84, 0x89, 0x88, 0x01, 0x84,
+ 0x70, 0x47, 0x00, 0x00, 0x2D, 0xE9, 0xFF, 0x4F, 0x89, 0xB0, 0x4F, 0xF0,
+ 0xFF, 0x30, 0x05, 0x90, 0x00, 0x20, 0xDD, 0xE9, 0x1A, 0x59, 0x19, 0x99,
+ 0x1C, 0x9E, 0x02, 0x90, 0x04, 0x90, 0x83, 0x46, 0x82, 0x46, 0x08, 0x60,
+ 0x0C, 0x98, 0x01, 0x88, 0x01, 0x20, 0xFF, 0xF7, 0xC3, 0xFA, 0x03, 0x90,
+ 0x0C, 0x98, 0x01, 0x88, 0x00, 0x20, 0xFF, 0xF7, 0xBD, 0xFA, 0xFE, 0x49,
+ 0x91, 0xF8, 0xAD, 0x21, 0x03, 0x99, 0x8A, 0x42, 0x03, 0xDC, 0x0A, 0x20,
+ 0x0D, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xFA, 0x49, 0x89, 0x69, 0x4A, 0x68,
+ 0x03, 0x99, 0x01, 0xEB, 0x41, 0x01, 0x02, 0xEB, 0x81, 0x08, 0xB8, 0xF8,
+ 0x02, 0x10, 0x00, 0x29, 0x7D, 0xD0, 0xB8, 0xF8, 0x0A, 0x20, 0x16, 0x99,
+ 0x8A, 0x42, 0x78, 0xD8, 0xD8, 0xF8, 0x04, 0x10, 0xC0, 0xEB, 0xC0, 0x02,
+ 0x01, 0xEB, 0x82, 0x04, 0x07, 0x46, 0xD6, 0xE1, 0x05, 0x98, 0x00, 0x28,
+ 0x01, 0xDB, 0x40, 0x1C, 0x05, 0x90, 0x22, 0x88, 0xD0, 0x07, 0x0C, 0xD0,
+ 0x00, 0x20, 0x00, 0x90, 0x0A, 0x98, 0x05, 0x28, 0x7E, 0xD0, 0x0C, 0xDC,
+ 0x01, 0x28, 0x14, 0xD0, 0x02, 0x28, 0x12, 0xD0, 0x03, 0x28, 0x0D, 0xD1,
+ 0xEB, 0xE0, 0xA0, 0x78, 0xE1, 0x78, 0x00, 0xEB, 0x01, 0x20, 0x80, 0xB2,
+ 0xED, 0xE7, 0xB0, 0xF5, 0x80, 0x4F, 0xF5, 0xD0, 0x6F, 0xF4, 0x80, 0x41,
+ 0xC8, 0x42, 0x6A, 0xD0, 0x4F, 0xF0, 0x01, 0x0B, 0xBB, 0xE1, 0x00, 0x98,
+ 0xB0, 0xF5, 0x20, 0x5F, 0x03, 0xD0, 0x42, 0xF6, 0x01, 0x01, 0x88, 0x42,
+ 0x16, 0xD1, 0x02, 0x98, 0x68, 0xB1, 0x3B, 0x46, 0x42, 0x46, 0xA9, 0x1C,
+ 0x0B, 0x98, 0xFF, 0xF7, 0xFD, 0xFD, 0x00, 0x20, 0x02, 0x90, 0xD9, 0xF8,
+ 0x00, 0x00, 0x35, 0x44, 0x81, 0x1B, 0xC9, 0xF8, 0x00, 0x10, 0x0B, 0x98,
+ 0x00, 0x28, 0x00, 0x98, 0x03, 0xD0, 0xB0, 0xF5, 0x20, 0x5F, 0x04, 0xD0,
+ 0x68, 0xE1, 0x42, 0xF6, 0x01, 0x01, 0x88, 0x42, 0xFA, 0xD1, 0x0A, 0x98,
+ 0x01, 0x28, 0x04, 0xD0, 0x20, 0x78, 0x80, 0x07, 0x28, 0xD5, 0x21, 0x1D,
+ 0x27, 0xE0, 0x00, 0x2E, 0x02, 0xDA, 0x66, 0x8A, 0x36, 0x1D, 0x04, 0xE0,
+ 0x60, 0x8A, 0xB1, 0xB2, 0x00, 0x1D, 0x81, 0x42, 0x15, 0xD1, 0xD9, 0xF8,
+ 0x00, 0x00, 0xB0, 0x42, 0x11, 0xDB, 0x98, 0xF8, 0x0A, 0x00, 0x0A, 0xF1,
+ 0x01, 0x0A, 0x38, 0x44, 0x28, 0x70, 0xB8, 0xF8, 0x0A, 0x00, 0x38, 0x44,
+ 0x00, 0x0A, 0x68, 0x70, 0x01, 0x20, 0x02, 0x90, 0x20, 0x78, 0x80, 0x07,
+ 0x02, 0xD5, 0x21, 0x1D, 0x01, 0xE0, 0x89, 0xE1, 0x61, 0x69, 0x62, 0x8A,
+ 0x28, 0x1D, 0x1F, 0xF4, 0x2E, 0xF3, 0x35, 0xE1, 0x61, 0x69, 0xDD, 0xE9,
+ 0x17, 0x20, 0x1F, 0xF4, 0xDD, 0xF2, 0x00, 0x28, 0x74, 0xD1, 0x00, 0x2E,
+ 0x00, 0xDA, 0x04, 0x26, 0xD9, 0xF8, 0x00, 0x00, 0xB0, 0x42, 0xD7, 0xDB,
+ 0x98, 0xF8, 0x0A, 0x00, 0x0A, 0xF1, 0x01, 0x0A, 0x38, 0x44, 0x01, 0xE0,
+ 0x09, 0xE0, 0xC3, 0xE0, 0x28, 0x70, 0xB8, 0xF8, 0x0A, 0x00, 0x38, 0x44,
+ 0x00, 0x0A, 0x68, 0x70, 0x01, 0x20, 0x02, 0x90, 0x16, 0xE1, 0x00, 0x98,
+ 0xA0, 0xF5, 0x20, 0x51, 0x02, 0x39, 0xA7, 0xD1, 0x8C, 0x46, 0x61, 0x69,
+ 0x00, 0x29, 0xA3, 0xD0, 0x50, 0x06, 0x04, 0xD5, 0x4F, 0xF0, 0x01, 0x0C,
+ 0x08, 0x46, 0x01, 0x91, 0x05, 0xE0, 0x60, 0x8A, 0xC0, 0xEB, 0xC0, 0x00,
+ 0x01, 0xEB, 0x80, 0x00, 0x01, 0x90, 0x40, 0x8A, 0x10, 0x28, 0x04, 0xD0,
+ 0x08, 0x20, 0x00, 0x2E, 0x03, 0xDA, 0x06, 0x46, 0x04, 0xE0, 0x06, 0x20,
+ 0xF9, 0xE7, 0x86, 0x42, 0x7F, 0xF4, 0x68, 0xAF, 0xD9, 0xF8, 0x00, 0x00,
+ 0xB0, 0x42, 0xFF, 0xF6, 0x63, 0xAF, 0x07, 0xA8, 0x00, 0x90, 0x62, 0x8A,
+ 0x06, 0xAB, 0x60, 0x46, 0xFD, 0xF7, 0x7E, 0xFE, 0x00, 0x28, 0xEF, 0xD1,
+ 0x98, 0xF8, 0x0A, 0x00, 0x38, 0x44, 0x05, 0xF8, 0x01, 0x0B, 0xB8, 0xF8,
+ 0x0A, 0x00, 0x38, 0x44, 0x00, 0x0A, 0x05, 0xF8, 0x01, 0x0B, 0xBD, 0xF8,
+ 0x18, 0x00, 0x05, 0xF8, 0x01, 0x0B, 0xBD, 0xF8, 0x18, 0x00, 0x00, 0x0A,
+ 0x05, 0xF8, 0x03, 0x0B, 0xBD, 0xF8, 0x1C, 0x00, 0x05, 0xF8, 0x02, 0x0C,
+ 0xBD, 0xF8, 0x1C, 0x00, 0x00, 0x0A, 0x05, 0xF8, 0x01, 0x0C, 0x08, 0x2E,
+ 0x11, 0xD1, 0x01, 0x98, 0x00, 0x78, 0x80, 0x07, 0x01, 0x98, 0x08, 0xD5,
+ 0x00, 0x79, 0x05, 0xF8, 0x01, 0x0B, 0x01, 0x98, 0x40, 0x79, 0x05, 0xF8,
+ 0x01, 0x0B, 0x04, 0xE0, 0xDF, 0xE0, 0x40, 0x69, 0x00, 0x88, 0x25, 0xF8,
+ 0x02, 0x0B, 0xD9, 0xF8, 0x00, 0x00, 0x0A, 0xF1, 0x01, 0x0A, 0x81, 0x1B,
+ 0xC9, 0xF8, 0x00, 0x10, 0xAC, 0xE0, 0x00, 0x98, 0xA0, 0xF5, 0x20, 0x51,
+ 0x03, 0x39, 0x03, 0xD0, 0x0A, 0x98, 0xB0, 0xF5, 0x80, 0x4F, 0x4D, 0xD1,
+ 0x0A, 0x98, 0x03, 0x28, 0x08, 0xD0, 0x21, 0x46, 0x02, 0x20, 0x0A, 0x78,
+ 0xD2, 0x07, 0x07, 0xD0, 0x10, 0x22, 0x10, 0x30, 0x00, 0x92, 0x06, 0xE0,
+ 0x04, 0xF1, 0x1C, 0x01, 0x05, 0x20, 0xF4, 0xE7, 0x02, 0x22, 0x80, 0x1C,
+ 0x00, 0x92, 0x00, 0x2E, 0x01, 0xDA, 0x06, 0x46, 0x01, 0xE0, 0x86, 0x42,
+ 0x94, 0xD1, 0xD9, 0xF8, 0x00, 0x00, 0xB0, 0x42, 0x95, 0xDB, 0x98, 0xF8,
+ 0x0A, 0x00, 0x38, 0x44, 0x05, 0xF8, 0x01, 0x0B, 0xB8, 0xF8, 0x0A, 0x00,
+ 0x38, 0x44, 0x00, 0x0A, 0x05, 0xF8, 0x01, 0x0B, 0x0A, 0x98, 0x03, 0x28,
+ 0x14, 0xD1, 0x20, 0x78, 0x80, 0x07, 0x01, 0xD5, 0x20, 0x79, 0x01, 0xE0,
+ 0x60, 0x69, 0x00, 0x78, 0x05, 0xF8, 0x01, 0x0B, 0x98, 0xF8, 0x0A, 0x20,
+ 0x78, 0x1C, 0x02, 0x44, 0x05, 0xF8, 0x01, 0x2B, 0xB8, 0xF8, 0x0A, 0x20,
+ 0x10, 0x44, 0x00, 0x0A, 0x05, 0xF8, 0x01, 0x0B, 0x28, 0x46, 0x89, 0x1C,
+ 0x00, 0x9A, 0x1F, 0xF4, 0x56, 0xF2, 0x00, 0x98, 0x05, 0x44, 0xA6, 0xE7,
+ 0x00, 0x98, 0x00, 0x28, 0x17, 0x98, 0x02, 0xD0, 0x02, 0x28, 0x02, 0xD0,
+ 0x54, 0xE0, 0x10, 0x28, 0x52, 0xD1, 0x02, 0x46, 0xA1, 0x1C, 0x18, 0x98,
+ 0x1F, 0xF4, 0xFA, 0xF1, 0xF0, 0xBB, 0xB8, 0xF8, 0x0A, 0x00, 0x00, 0x23,
+ 0x38, 0x44, 0x81, 0xB2, 0x22, 0x46, 0x09, 0x98, 0xFD, 0xF7, 0x76, 0xF8,
+ 0x04, 0x90, 0x00, 0x28, 0xB4, 0xD1, 0x20, 0x46, 0xFD, 0xF7, 0x68, 0xFD,
+ 0x01, 0x90, 0x38, 0xB1, 0x20, 0x78, 0x00, 0x07, 0x04, 0xD5, 0x01, 0x98,
+ 0x1F, 0xF4, 0x0E, 0xF2, 0x40, 0x1C, 0x00, 0xE0, 0x60, 0x8A, 0x00, 0x90,
+ 0x80, 0x1C, 0x00, 0x2E, 0x01, 0xDA, 0x06, 0x46, 0x01, 0xE0, 0x86, 0x42,
+ 0x9E, 0xD1, 0xD9, 0xF8, 0x00, 0x00, 0x02, 0x28, 0x7F, 0xF6, 0x9A, 0xAE,
+ 0x98, 0xF8, 0x0A, 0x00, 0x0A, 0xF1, 0x01, 0x0A, 0x38, 0x44, 0x05, 0xF8,
+ 0x01, 0x0B, 0xB8, 0xF8, 0x0A, 0x00, 0x38, 0x44, 0x00, 0x0A, 0x05, 0xF8,
+ 0x01, 0x0B, 0x01, 0x98, 0xD0, 0xB1, 0xD9, 0xF8, 0x00, 0x00, 0x00, 0x9A,
+ 0x81, 0x1E, 0x91, 0x42, 0x01, 0xDA, 0x06, 0x46, 0x00, 0x91, 0x00, 0xE0,
+ 0x0C, 0xE0, 0xDD, 0xE9, 0x00, 0x21, 0x28, 0x46, 0x1F, 0xF4, 0xFF, 0xF1,
+ 0x00, 0x98, 0xD9, 0xF8, 0x00, 0x10, 0x05, 0x44, 0x08, 0x1A, 0x80, 0x1E,
+ 0xC9, 0xF8, 0x00, 0x00, 0xBB, 0xF1, 0x00, 0x0F, 0x2F, 0xD1, 0x06, 0xE0,
+ 0xB8, 0xF8, 0x0A, 0x00, 0x0C, 0x99, 0x38, 0x44, 0x76, 0x42, 0x08, 0x80,
+ 0x68, 0xE6, 0x05, 0x98, 0x01, 0x28, 0x04, 0xDB, 0x02, 0x98, 0xE8, 0xB3,
+ 0xAA, 0xF1, 0x01, 0x0A, 0x3F, 0xE0, 0x01, 0x20, 0x16, 0x99, 0xFF, 0xF7,
+ 0xD5, 0xF8, 0x03, 0x99, 0x88, 0x42, 0x0C, 0xD1, 0x00, 0x20, 0x16, 0x99,
+ 0xFF, 0xF7, 0xCE, 0xF8, 0xB8, 0x42, 0x06, 0xD1, 0x00, 0x20, 0x05, 0x90,
+ 0x0A, 0x98, 0x01, 0x28, 0x01, 0xD0, 0x02, 0x28, 0xE2, 0xD1, 0x1C, 0x34,
+ 0x7F, 0x1C, 0xB8, 0xF8, 0x08, 0x00, 0x03, 0xE0, 0x64, 0x01, 0x20, 0x00,
+ 0x98, 0x77, 0x20, 0x00, 0xB8, 0x42, 0x3F, 0xF7, 0x1F, 0xAE, 0x02, 0x98,
+ 0x68, 0xB1, 0x3B, 0x46, 0x42, 0x46, 0xA9, 0x1C, 0x0B, 0x98, 0xFF, 0xF7,
+ 0x49, 0xFC, 0x00, 0x20, 0x02, 0x90, 0xD9, 0xF8, 0x00, 0x00, 0x35, 0x44,
+ 0x81, 0x1B, 0xC9, 0xF8, 0x00, 0x10, 0xBB, 0xF1, 0x00, 0x0F, 0x0C, 0xD1,
+ 0x0F, 0x48, 0x03, 0x99, 0x90, 0xF8, 0xAD, 0x01, 0x40, 0x1E, 0x88, 0x42,
+ 0x05, 0xDD, 0x00, 0xE0, 0x03, 0xE0, 0x48, 0x1C, 0x03, 0x90, 0x00, 0x20,
+ 0xE5, 0xE5, 0x19, 0x99, 0xBA, 0xF1, 0x00, 0x0F, 0xC1, 0xF8, 0x00, 0xA0,
+ 0x02, 0xDD, 0xC9, 0xF8, 0x00, 0x60, 0x06, 0xE0, 0x00, 0x21, 0xC9, 0xF8,
+ 0x00, 0x10, 0x04, 0x98, 0x08, 0xB9, 0x0A, 0x20, 0x04, 0x90, 0x04, 0x98,
+ 0xD0, 0xE5, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0x70, 0xB5, 0x84, 0x68,
+ 0x05, 0x46, 0x00, 0x20, 0x21, 0x8A, 0xFF, 0xF7, 0x7D, 0xF8, 0x81, 0xB2,
+ 0x2B, 0x8E, 0xA2, 0x8A, 0xE0, 0x68, 0xBD, 0xE8, 0x70, 0x40, 0xF6, 0xF7,
+ 0x2B, 0xB9, 0x00, 0x00, 0x2D, 0xE9, 0xFF, 0x47, 0x88, 0x46, 0x05, 0x46,
+ 0x00, 0xF1, 0x0C, 0x04, 0x01, 0x8A, 0x1E, 0x46, 0x17, 0x46, 0x00, 0x20,
+ 0xDD, 0xF8, 0x30, 0x90, 0xFF, 0xF7, 0x66, 0xF8, 0x29, 0x68, 0x80, 0xB2,
+ 0xBA, 0xB2, 0x09, 0x8E, 0x03, 0x91, 0x8D, 0xE8, 0x45, 0x00, 0x23, 0x68,
+ 0x0A, 0x4C, 0x42, 0x46, 0x20, 0x68, 0xA9, 0xEB, 0x00, 0x01, 0x89, 0xB2,
+ 0xF6, 0xF7, 0x41, 0xFA, 0x00, 0x28, 0x08, 0xD0, 0x20, 0x68, 0x04, 0xB0,
+ 0x4F, 0xF4, 0xAB, 0x72, 0xBD, 0xE8, 0xF0, 0x47, 0x03, 0x49, 0xF4, 0xF7,
+ 0xC5, 0xBE, 0xBD, 0xE8, 0xFF, 0x87, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00,
+ 0x21, 0xAC, 0x82, 0x00, 0x2D, 0xE9, 0xFF, 0x4F, 0x83, 0xB0, 0x1C, 0x46,
+ 0x92, 0x46, 0x88, 0xE0, 0x03, 0x46, 0x01, 0x22, 0x48, 0x49, 0x49, 0x48,
+ 0xED, 0xF7, 0x2F, 0xD8, 0x48, 0x4D, 0x4F, 0xF0, 0x00, 0x0B, 0xD3, 0x23,
+ 0x29, 0x78, 0x47, 0x4A, 0x01, 0xEB, 0x8A, 0x00, 0x81, 0xB2, 0x46, 0x48,
+ 0x00, 0x78, 0xF4, 0xF7, 0xB7, 0xFD, 0x01, 0x90, 0x00, 0x28, 0x76, 0xD0,
+ 0x29, 0x46, 0x00, 0x26, 0x09, 0x78, 0x77, 0x1E, 0x00, 0xEB, 0x01, 0x09,
+ 0xB0, 0x46, 0x4A, 0xE0, 0x21, 0x88, 0x00, 0x20, 0xFF, 0xF7, 0x1C, 0xF8,
+ 0x80, 0xB2, 0x00, 0x90, 0x21, 0x88, 0x01, 0x20, 0xFF, 0xF7, 0x16, 0xF8,
+ 0x85, 0xB2, 0x3A, 0x48, 0x90, 0xF8, 0xAD, 0x01, 0xA8, 0x42, 0x37, 0xD9,
+ 0x21, 0x88, 0x03, 0x98, 0xFD, 0xF7, 0x82, 0xFC, 0x00, 0x28, 0x00, 0xDA,
+ 0x00, 0x20, 0x04, 0x99, 0x88, 0x43, 0xC0, 0x07, 0x2C, 0xD1, 0x33, 0x48,
+ 0x05, 0xEB, 0x45, 0x01, 0x00, 0x6A, 0x00, 0xEB, 0x81, 0x0B, 0x00, 0x98,
+ 0xDB, 0xF8, 0x04, 0x10, 0xC0, 0xEB, 0xC0, 0x00, 0x11, 0xF8, 0x20, 0x00,
+ 0xC0, 0x06, 0x17, 0xD5, 0x00, 0x2F, 0x01, 0xDA, 0x2F, 0x46, 0x08, 0xE0,
+ 0xAF, 0x42, 0x06, 0xD0, 0x28, 0x48, 0x07, 0xEB, 0x47, 0x01, 0x00, 0x6A,
+ 0x00, 0xEB, 0x81, 0x0B, 0x15, 0xE0, 0x00, 0x98, 0xA9, 0xF8, 0x00, 0x00,
+ 0x09, 0xF1, 0x02, 0x00, 0x61, 0x88, 0x20, 0xF8, 0x02, 0x1B, 0x81, 0x46,
+ 0x76, 0x1C, 0x05, 0xE0, 0x19, 0x49, 0x00, 0x22, 0x20, 0x31, 0x19, 0x48,
+ 0xEC, 0xF7, 0xCF, 0xDF, 0x08, 0xF1, 0x01, 0x08, 0x24, 0x1D, 0xD0, 0x45,
+ 0xB2, 0xDB, 0xAA, 0xEB, 0x08, 0x0A, 0x00, 0x2E, 0x20, 0xDD, 0x12, 0x49,
+ 0x12, 0x48, 0x5B, 0x46, 0x02, 0x22, 0x58, 0x31, 0x40, 0x1C, 0x00, 0x96,
+ 0xEC, 0xF7, 0xBD, 0xDF, 0x03, 0x98, 0xB3, 0xB2, 0x5A, 0x46, 0x00, 0x8E,
+ 0x00, 0x90, 0x0D, 0x48, 0x01, 0x78, 0x01, 0x98, 0xF6, 0xF7, 0x42, 0xFA,
+ 0x28, 0xB1, 0x4F, 0xF4, 0x8F, 0x72, 0x0A, 0x49, 0x01, 0x98, 0xF4, 0xF7,
+ 0x2F, 0xFE, 0xBA, 0xF1, 0x00, 0x00, 0x3F, 0xF7, 0x73, 0xAF, 0x07, 0xB0,
+ 0xBD, 0xE8, 0xF0, 0x8F, 0x4F, 0xF4, 0x91, 0x72, 0xF1, 0xE7, 0x00, 0x00,
+ 0xC4, 0x4A, 0xC0, 0x08, 0x02, 0x38, 0x10, 0x21, 0x48, 0x74, 0x20, 0x00,
+ 0x0E, 0xAC, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x98, 0x77, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x41, 0x1F, 0x46, 0x01, 0x29,
+ 0x2A, 0xD1, 0x00, 0x24, 0x07, 0xF1, 0x13, 0x01, 0x88, 0x46, 0x01, 0x28,
+ 0x26, 0xD0, 0x2E, 0x4D, 0x57, 0x23, 0x2E, 0x4A, 0x95, 0xF8, 0xC1, 0x01,
+ 0x81, 0x00, 0x2D, 0x48, 0x00, 0x78, 0xF4, 0xF7, 0x13, 0xFD, 0x06, 0x00,
+ 0x18, 0xD0, 0x74, 0x80, 0x00, 0x22, 0x39, 0x46, 0x01, 0x20, 0xFD, 0xF7,
+ 0xE1, 0xF8, 0x95, 0xF8, 0xC1, 0x11, 0x04, 0x46, 0xA1, 0x42, 0x17, 0xDA,
+ 0x41, 0x46, 0x25, 0x48, 0xED, 0xF7, 0x3C, 0xD9, 0x03, 0x46, 0x95, 0xF8,
+ 0xC1, 0x01, 0x03, 0x22, 0xCD, 0xE9, 0x00, 0x40, 0x21, 0x49, 0x22, 0x48,
+ 0xEC, 0xF7, 0x63, 0xDF, 0xBD, 0xE8, 0xFC, 0x81, 0x01, 0x20, 0x87, 0xF8,
+ 0x2E, 0x00, 0x00, 0x94, 0x00, 0x23, 0xBA, 0x7E, 0x18, 0x46, 0x29, 0xE0,
+ 0x00, 0x2C, 0x04, 0xDD, 0x32, 0x46, 0x39, 0x46, 0x02, 0x20, 0xFD, 0xF7,
+ 0xBD, 0xF8, 0xA5, 0xB2, 0x00, 0x2C, 0x12, 0xDD, 0x00, 0x22, 0x30, 0x46,
+ 0x31, 0x46, 0x0C, 0xE0, 0x43, 0x88, 0x2B, 0xB1, 0x88, 0x42, 0x01, 0xD0,
+ 0x03, 0x68, 0x0B, 0x60, 0x09, 0x1D, 0x01, 0xE0, 0x6D, 0x1E, 0xAD, 0xB2,
+ 0x52, 0x1C, 0x92, 0xB2, 0x00, 0x1D, 0xA2, 0x42, 0xF0, 0xDB, 0x2D, 0xB9,
+ 0x8F, 0x22, 0x08, 0x49, 0x30, 0x46, 0xF4, 0xF7, 0xB9, 0xFD, 0x00, 0x26,
+ 0xA8, 0x06, 0x03, 0x0E, 0x00, 0x96, 0xBA, 0x7E, 0x41, 0x46, 0x01, 0x20,
+ 0xF6, 0xF7, 0x80, 0xFC, 0xC8, 0xE7, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0xF7, 0xAB, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x00, 0x00, 0x30, 0x21,
+ 0x70, 0x4A, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x4F,
+ 0x85, 0xB0, 0x4F, 0xF0, 0x00, 0x07, 0xDD, 0xE9, 0x12, 0x84, 0x5F, 0xEA,
+ 0x03, 0x0B, 0xB9, 0x46, 0x0D, 0xD0, 0x07, 0x98, 0x02, 0x28, 0x0D, 0xD0,
+ 0x03, 0x28, 0x10, 0xD0, 0x04, 0x28, 0x15, 0xD0, 0x05, 0x28, 0x40, 0x46,
+ 0x08, 0xD0, 0x06, 0x28, 0x15, 0xD0, 0x14, 0x20, 0x13, 0xE0, 0x00, 0x20,
+ 0x00, 0x90, 0x11, 0xE0, 0x04, 0x20, 0x0E, 0xE0, 0x08, 0x28, 0x0C, 0xD0,
+ 0x02, 0xE0, 0xB8, 0xF1, 0x07, 0x0F, 0x01, 0xD0, 0x16, 0x20, 0x06, 0xE0,
+ 0x08, 0x20, 0x04, 0xE0, 0x40, 0x46, 0xB8, 0xF1, 0x04, 0x0F, 0x00, 0xD0,
+ 0x12, 0x20, 0x00, 0x90, 0x8C, 0x49, 0x40, 0xF2, 0x15, 0x33, 0x8C, 0x4A,
+ 0x09, 0x78, 0x49, 0x1C, 0x21, 0xF0, 0x01, 0x0A, 0x0B, 0xFB, 0x00, 0xA0,
+ 0x81, 0xB2, 0x89, 0x48, 0x00, 0x78, 0xF4, 0xF7, 0x77, 0xFC, 0x03, 0x90,
+ 0x00, 0x28, 0x7B, 0xD0, 0x00, 0xEB, 0x0A, 0x05, 0x00, 0x26, 0xD7, 0xE0,
+ 0x02, 0x28, 0x3B, 0xD0, 0x03, 0x28, 0x7F, 0xD0, 0x04, 0x28, 0x73, 0xD0,
+ 0x05, 0x28, 0x48, 0xD0, 0x14, 0xF8, 0x01, 0x0B, 0xB8, 0xF1, 0x06, 0x0F,
+ 0x14, 0xF8, 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x21, 0x16, 0xD0, 0x06, 0xEB,
+ 0x86, 0x00, 0x25, 0xF8, 0x20, 0x10, 0x14, 0xF8, 0x01, 0x1B, 0x14, 0xF8,
+ 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21, 0x8F, 0xB2, 0x05, 0xEB, 0x80, 0x01,
+ 0x00, 0x20, 0x4F, 0x80, 0x0B, 0x18, 0x14, 0xF8, 0x01, 0x2B, 0x40, 0x1C,
+ 0x1A, 0x71, 0x10, 0x28, 0xF8, 0xD3, 0xAE, 0xE0, 0x06, 0xEB, 0x46, 0x00,
+ 0x25, 0xF8, 0x10, 0x10, 0x14, 0xF8, 0x01, 0x1B, 0x05, 0xEB, 0x40, 0x00,
+ 0x14, 0xF8, 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21, 0x8F, 0xB2, 0x47, 0x80,
+ 0x14, 0xF8, 0x01, 0x1B, 0x14, 0xF8, 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21,
+ 0x81, 0x80, 0x98, 0xE0, 0x14, 0xF8, 0x01, 0x0B, 0x14, 0xF8, 0x01, 0x1B,
+ 0x00, 0xEB, 0x01, 0x20, 0x25, 0xF8, 0x26, 0x00, 0x14, 0xF8, 0x01, 0x0B,
+ 0x14, 0xF8, 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x20, 0x87, 0xB2, 0x05, 0xEB,
+ 0x86, 0x00, 0x47, 0x80, 0x85, 0xE0, 0x14, 0xF8, 0x01, 0x0B, 0xB8, 0xF1,
+ 0x08, 0x0F, 0x14, 0xF8, 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x20, 0x1F, 0xFA,
+ 0x80, 0xF9, 0x1E, 0xD0, 0x06, 0xEB, 0x46, 0x00, 0x00, 0xEB, 0xC6, 0x00,
+ 0x25, 0xF8, 0x10, 0x90, 0x14, 0xF8, 0x01, 0x1B, 0x05, 0xEB, 0x40, 0x00,
+ 0x14, 0xF8, 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21, 0x41, 0x80, 0x14, 0xF8,
+ 0x01, 0x1B, 0x14, 0xF8, 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21, 0x81, 0x80,
+ 0x10, 0x21, 0x80, 0x1D, 0x1E, 0xF4, 0xF8, 0xF7, 0x10, 0x34, 0x5E, 0xE0,
+ 0x86, 0xE0, 0x09, 0xE0, 0x43, 0xE0, 0x25, 0xF8, 0x36, 0x90, 0x14, 0xF8,
+ 0x01, 0x0B, 0x14, 0xF8, 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x21, 0x28, 0xE0,
+ 0x14, 0xF8, 0x01, 0x0B, 0xB8, 0xF1, 0x07, 0x0F, 0x14, 0xF8, 0x01, 0x1B,
+ 0x00, 0xEB, 0x01, 0x20, 0x87, 0xB2, 0x1A, 0xD0, 0x06, 0xEB, 0x46, 0x00,
+ 0x00, 0xEB, 0xC6, 0x00, 0x05, 0xEB, 0x40, 0x01, 0x25, 0xF8, 0x10, 0x70,
+ 0x14, 0xF8, 0x01, 0x2B, 0x4A, 0x80, 0x14, 0xF8, 0x01, 0x0B, 0x14, 0xF8,
+ 0x01, 0x2B, 0x00, 0xEB, 0x02, 0x20, 0x88, 0x80, 0x00, 0x20, 0x0B, 0x18,
+ 0x14, 0xF8, 0x01, 0x2B, 0x40, 0x1C, 0x9A, 0x71, 0x10, 0x28, 0xF8, 0xD3,
+ 0x2D, 0xE0, 0x25, 0xF8, 0x36, 0x70, 0x14, 0xF8, 0x01, 0x1B, 0x05, 0xEB,
+ 0xC6, 0x00, 0x41, 0x80, 0x14, 0xF8, 0x01, 0x1B, 0x14, 0xF8, 0x01, 0x2B,
+ 0x01, 0xEB, 0x02, 0x21, 0x81, 0x80, 0x14, 0xF8, 0x01, 0x1B, 0x14, 0xF8,
+ 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21, 0xC1, 0x80, 0x17, 0xE0, 0x14, 0xF8,
+ 0x01, 0x0B, 0xB8, 0xF1, 0x04, 0x0F, 0x14, 0xF8, 0x01, 0x1B, 0x00, 0xEB,
+ 0x01, 0x20, 0x87, 0xB2, 0x15, 0xD0, 0x06, 0xEB, 0xC6, 0x01, 0x00, 0x20,
+ 0x25, 0xF8, 0x11, 0x70, 0x05, 0xEB, 0x41, 0x03, 0x03, 0x44, 0x14, 0xF8,
+ 0x01, 0x2B, 0x40, 0x1C, 0x9A, 0x70, 0x10, 0x28, 0xF6, 0xD3, 0x76, 0x1C,
+ 0x07, 0x98, 0x5E, 0x45, 0xFF, 0xF6, 0x24, 0xAF, 0x05, 0x28, 0x0C, 0xD0,
+ 0x0C, 0xE0, 0x25, 0xF8, 0x26, 0x70, 0x14, 0xF8, 0x01, 0x0B, 0x14, 0xF8,
+ 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x20, 0x05, 0xEB, 0x86, 0x01, 0x48, 0x80,
+ 0xEB, 0xE7, 0x4F, 0x46, 0x14, 0x98, 0x00, 0xB1, 0x87, 0x80, 0xDD, 0xE9,
+ 0x05, 0x01, 0xCD, 0xE9, 0x01, 0x01, 0x51, 0x46, 0x5B, 0x46, 0x07, 0x9A,
+ 0x03, 0x98, 0xF6, 0xF7, 0x19, 0xFA, 0x28, 0xB1, 0x40, 0xF2, 0x93, 0x32,
+ 0x04, 0x49, 0x03, 0x98, 0xF4, 0xF7, 0x5E, 0xFC, 0x09, 0xB0, 0x38, 0x46,
+ 0xBD, 0xE8, 0xF0, 0x8F, 0x48, 0x74, 0x20, 0x00, 0x8B, 0xAC, 0x82, 0x00,
+ 0x04, 0x74, 0x20, 0x00, 0xF0, 0xB5, 0x87, 0xB0, 0x04, 0x46, 0x1E, 0x46,
+ 0x00, 0x8E, 0x0F, 0x46, 0x15, 0x46, 0x13, 0x46, 0x00, 0x90, 0x02, 0x22,
+ 0x0C, 0x49, 0x0D, 0x48, 0xEC, 0xF7, 0xC3, 0xDD, 0x4F, 0xF4, 0xA0, 0x60,
+ 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x0A, 0x60, 0x01, 0x20, 0xAD, 0xF8,
+ 0x08, 0x00, 0xAD, 0xF8, 0x0C, 0x50, 0x04, 0x20, 0x04, 0x97, 0xAD, 0xF8,
+ 0x0E, 0x00, 0x20, 0x8E, 0x05, 0x90, 0x01, 0xA8, 0x04, 0xF0, 0xCA, 0xFD,
+ 0x07, 0xB0, 0xF0, 0xBD, 0x60, 0x48, 0xC0, 0x08, 0x03, 0x38, 0x10, 0x21,
+ 0x2D, 0xE9, 0xFC, 0x47, 0x00, 0x24, 0x8A, 0x46, 0x05, 0x46, 0x99, 0x46,
+ 0x16, 0x46, 0x27, 0x46, 0xA0, 0x46, 0x11, 0x46, 0x01, 0x20, 0xFE, 0xF7,
+ 0xA5, 0xFD, 0x28, 0x49, 0x91, 0xF8, 0xAD, 0x21, 0x90, 0x42, 0x2B, 0xDA,
+ 0x26, 0x4A, 0x00, 0x20, 0x91, 0xF8, 0xAC, 0x11, 0x92, 0x69, 0x0F, 0xE0,
+ 0x93, 0x68, 0x03, 0xEB, 0xC0, 0x04, 0x23, 0x78, 0x63, 0xB1, 0xA3, 0x88,
+ 0xB3, 0x42, 0x06, 0xD1, 0x63, 0x88, 0xB5, 0xF8, 0x30, 0xC0, 0x63, 0x45,
+ 0x01, 0xD1, 0x27, 0x46, 0x02, 0xE0, 0x40, 0x1C, 0x81, 0x42, 0xED, 0xDC,
+ 0x2F, 0xB9, 0x81, 0x42, 0x2C, 0xDD, 0x01, 0x20, 0x20, 0x70, 0x80, 0x46,
+ 0x44, 0xB3, 0xBA, 0xF1, 0x00, 0x0F, 0x06, 0xD0, 0xE8, 0x7E, 0x50, 0xB9,
+ 0x60, 0x78, 0x40, 0xF0, 0x01, 0x00, 0x60, 0x70, 0x05, 0xE0, 0x60, 0x78,
+ 0xC0, 0x07, 0x02, 0xD0, 0x00, 0x20, 0xBD, 0xE8, 0xFC, 0x87, 0x01, 0x27,
+ 0xB8, 0xF1, 0x00, 0x0F, 0x03, 0xD0, 0x28, 0x8E, 0x60, 0x80, 0xA6, 0x80,
+ 0x03, 0xE0, 0xE1, 0x88, 0x49, 0x45, 0x00, 0xD1, 0x00, 0x27, 0xA4, 0xF8,
+ 0x06, 0x90, 0x61, 0x78, 0x03, 0x22, 0xCD, 0xE9, 0x00, 0x91, 0x63, 0x88,
+ 0x06, 0x49, 0x07, 0x48, 0xEC, 0xF7, 0x51, 0xDD, 0x38, 0x46, 0xE4, 0xE7,
+ 0x4F, 0xF0, 0xFF, 0x30, 0xE1, 0xE7, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x98, 0x77, 0x20, 0x00, 0xFC, 0x4D, 0xC0, 0x08, 0x03, 0x38, 0x10, 0x21,
+ 0x10, 0xB5, 0x04, 0x46, 0x00, 0x22, 0x08, 0x49, 0x08, 0x48, 0xEC, 0xF7,
+ 0x3C, 0xDD, 0xE0, 0x7E, 0x00, 0x28, 0x07, 0xD1, 0x01, 0x20, 0xE0, 0x76,
+ 0x01, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0xFF, 0xF7, 0x06, 0xB8,
+ 0x10, 0xBD, 0x00, 0x00, 0x58, 0x4A, 0xC0, 0x08, 0x02, 0x38, 0x10, 0x21,
+ 0x2D, 0xE9, 0xFF, 0x4F, 0x85, 0xB0, 0x07, 0x46, 0x08, 0x98, 0x93, 0x46,
+ 0x89, 0x46, 0x04, 0x68, 0x12, 0x9E, 0x01, 0x25, 0x08, 0x46, 0xFE, 0xF7,
+ 0x21, 0xFD, 0x5F, 0xEA, 0x00, 0x08, 0x0C, 0xD0, 0x02, 0x46, 0x01, 0x23,
+ 0x49, 0x46, 0x38, 0x46, 0xFC, 0xF7, 0x64, 0xFC, 0x05, 0x00, 0x04, 0xD1,
+ 0x40, 0x46, 0xFC, 0xF7, 0xB5, 0xFC, 0x08, 0xB1, 0xAC, 0x1E, 0xA1, 0xE0,
+ 0xA8, 0xF1, 0x1C, 0x00, 0x81, 0x46, 0xFC, 0xF7, 0xA9, 0xFC, 0x00, 0x28,
+ 0x7E, 0xD0, 0x99, 0xF8, 0x00, 0x10, 0x89, 0x07, 0x02, 0xD5, 0x99, 0xF8,
+ 0x04, 0x00, 0x02, 0xE0, 0xD9, 0xF8, 0x14, 0x00, 0x00, 0x78, 0x02, 0x2E,
+ 0x04, 0xD0, 0x05, 0x2E, 0x04, 0xD0, 0x01, 0x2E, 0x05, 0xD0, 0x08, 0xE0,
+ 0x40, 0x07, 0x03, 0xE0, 0x40, 0x06, 0x03, 0xD5, 0x05, 0xE0, 0x00, 0x07,
+ 0x00, 0x28, 0x6C, 0xDB, 0x03, 0x25, 0x05, 0x2E, 0x61, 0xD1, 0x0B, 0xEB,
+ 0x04, 0x00, 0x82, 0x46, 0x10, 0xF8, 0x0C, 0x1D, 0x42, 0x78, 0x01, 0xEB,
+ 0x02, 0x21, 0x82, 0x78, 0x1A, 0xF8, 0x09, 0x0C, 0x12, 0x04, 0x02, 0xEB,
+ 0x00, 0x60, 0x0E, 0x18, 0x33, 0x46, 0x01, 0x22, 0x39, 0x49, 0x3A, 0x48,
+ 0xEC, 0xF7, 0xD5, 0xDC, 0x38, 0x68, 0x81, 0x7E, 0x13, 0x30, 0x0A, 0xF0,
+ 0x54, 0xFE, 0x5F, 0xEA, 0x00, 0x09, 0x4A, 0xD0, 0x02, 0x46, 0x10, 0x21,
+ 0x34, 0x48, 0xEC, 0xF7, 0x34, 0xDF, 0x31, 0x49, 0x03, 0x46, 0x01, 0x22,
+ 0x20, 0x31, 0x30, 0x48, 0xEC, 0xF7, 0xC1, 0xDC, 0x01, 0xAB, 0x62, 0x1F,
+ 0xAB, 0xF1, 0x03, 0x01, 0x48, 0x46, 0x1B, 0xF4, 0x53, 0xF5, 0xAA, 0xF1,
+ 0x08, 0x01, 0x03, 0xA8, 0x89, 0x46, 0x08, 0x22, 0x82, 0x46, 0x1E, 0xF4,
+ 0x7B, 0xF5, 0xB0, 0xB1, 0x27, 0x4E, 0x52, 0x46, 0x08, 0x21, 0x30, 0x46,
+ 0xEC, 0xF7, 0x17, 0xDF, 0x05, 0x46, 0x4A, 0x46, 0x08, 0x21, 0x30, 0x46,
+ 0xEC, 0xF7, 0x11, 0xDF, 0x03, 0x46, 0x1F, 0x49, 0x1F, 0x48, 0x02, 0x22,
+ 0x40, 0x31, 0x80, 0x1E, 0x00, 0x95, 0xEC, 0xF7, 0x9C, 0xDC, 0xC2, 0x25,
+ 0x2E, 0xE0, 0x38, 0x68, 0x81, 0x7E, 0x13, 0x30, 0x0A, 0xF0, 0x24, 0xFE,
+ 0x86, 0x42, 0x03, 0xD2, 0x80, 0x1B, 0x10, 0xF5, 0x80, 0x7F, 0x0A, 0xD9,
+ 0x38, 0x68, 0x72, 0x1C, 0x81, 0x7E, 0x13, 0x30, 0x0E, 0xF0, 0xFE, 0xFD,
+ 0x0C, 0x3C, 0x00, 0xE0, 0x05, 0xE0, 0x25, 0xB1, 0x18, 0xE0, 0xC1, 0x25,
+ 0x16, 0xE0, 0x05, 0x25, 0x14, 0xE0, 0x40, 0x46, 0xFD, 0xF7, 0xC4, 0xF8,
+ 0xB8, 0xF8, 0x12, 0x10, 0x29, 0xB1, 0x20, 0xB1, 0xA1, 0x42, 0x05, 0xDA,
+ 0x00, 0x24, 0x0D, 0x25, 0x08, 0xE0, 0x4F, 0xF0, 0xFF, 0x34, 0x05, 0xE0,
+ 0x00, 0x2C, 0x03, 0xDD, 0x22, 0x46, 0x59, 0x46, 0x1E, 0xF4, 0x7F, 0xF5,
+ 0x08, 0x98, 0x04, 0x60, 0x09, 0xB0, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x8F,
+ 0x24, 0x4F, 0xC0, 0x08, 0x02, 0x38, 0x10, 0x21, 0x00, 0x00, 0x50, 0x21,
+ 0x2D, 0xE9, 0xFF, 0x47, 0x84, 0x68, 0xDD, 0xF8, 0x30, 0x90, 0x1F, 0x46,
+ 0x92, 0x46, 0x80, 0x46, 0x04, 0xF1, 0x0C, 0x05, 0x00, 0x26, 0x59, 0xB1,
+ 0x08, 0x46, 0xFC, 0xF7, 0xAA, 0xFD, 0x03, 0x00, 0x06, 0xD0, 0x20, 0x89,
+ 0x00, 0x1F, 0xB0, 0xF5, 0x80, 0x4F, 0x1B, 0xD0, 0x12, 0x21, 0x1A, 0xE0,
+ 0x21, 0x89, 0x09, 0xEB, 0x07, 0x00, 0x09, 0x1F, 0xB1, 0xF5, 0x80, 0x4F,
+ 0x0A, 0xD0, 0x00, 0x96, 0x01, 0x96, 0x02, 0x96, 0x00, 0x23, 0x01, 0x22,
+ 0x13, 0x21, 0x40, 0x46, 0x03, 0x96, 0xF3, 0xF7, 0x05, 0xFB, 0x0C, 0xE0,
+ 0x00, 0x90, 0xEA, 0x88, 0xA9, 0x88, 0x53, 0x46, 0x20, 0x68, 0xF3, 0xF7,
+ 0xD5, 0xFC, 0x04, 0xE0, 0x16, 0x21, 0xAA, 0x88, 0x20, 0x68, 0xF3, 0xF7,
+ 0x79, 0xFB, 0x26, 0x81, 0xBD, 0xE8, 0xFF, 0x87, 0x0E, 0xB5, 0x02, 0xAB,
+ 0x8D, 0xF8, 0x08, 0x10, 0x09, 0x0A, 0x8D, 0xF8, 0x09, 0x10, 0x8D, 0xF8,
+ 0x0A, 0x20, 0x11, 0x0A, 0x8D, 0xF8, 0x0B, 0x10, 0x00, 0x22, 0x04, 0x21,
+ 0xCD, 0xE9, 0x00, 0x12, 0x02, 0x49, 0x02, 0x22, 0x49, 0x78, 0x0A, 0xF0,
+ 0x7D, 0xF8, 0x0E, 0xBD, 0xF4, 0x78, 0x20, 0x00, 0xF0, 0xB5, 0x19, 0x4D,
+ 0x19, 0x4A, 0x06, 0x46, 0xB5, 0xF8, 0x46, 0x30, 0x92, 0xF8, 0x98, 0x41,
+ 0x00, 0x20, 0xA3, 0x42, 0x00, 0xD3, 0xF0, 0xBD, 0x13, 0x4B, 0x00, 0x22,
+ 0x1B, 0x6B, 0x05, 0xE0, 0x03, 0xEB, 0x42, 0x17, 0x3F, 0x78, 0xE7, 0xB1,
+ 0x52, 0x1C, 0x92, 0xB2, 0x94, 0x42, 0xF7, 0xD8, 0x00, 0x28, 0xF0, 0xD0,
+ 0x01, 0x22, 0x02, 0x70, 0x41, 0x70, 0x4F, 0xF6, 0xFF, 0x71, 0x41, 0x80,
+ 0xFF, 0x21, 0x81, 0x72, 0x00, 0x21, 0x01, 0x75, 0x32, 0x68, 0x42, 0x60,
+ 0xB2, 0x88, 0x02, 0x81, 0xC0, 0xF8, 0x16, 0x10, 0xC0, 0xF8, 0x1A, 0x10,
+ 0x35, 0xF8, 0x46, 0x1F, 0x49, 0x1C, 0x29, 0x80, 0xF0, 0xBD, 0x03, 0xEB,
+ 0x42, 0x10, 0xE3, 0xE7, 0xF0, 0x75, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x03, 0x4A, 0x10, 0x44, 0x90, 0xF8, 0x48, 0x00, 0x08, 0x40, 0x00, 0xD0,
+ 0x01, 0x20, 0x70, 0x47, 0xF0, 0x75, 0x20, 0x00, 0x70, 0xB5, 0x14, 0x46,
+ 0x0D, 0x46, 0x00, 0xF0, 0x45, 0xFF, 0x00, 0x28, 0x04, 0xD0, 0x28, 0x44,
+ 0x80, 0x7D, 0x20, 0x40, 0x00, 0xD0, 0x01, 0x20, 0x70, 0xBD, 0x06, 0x22,
+ 0x02, 0xF0, 0x22, 0xB8, 0x7C, 0xB5, 0x6B, 0x46, 0x00, 0x24, 0x0D, 0x5D,
+ 0x64, 0x1C, 0x03, 0xF8, 0x01, 0x5B, 0x06, 0x2C, 0xF9, 0xD3, 0x03, 0xF8,
+ 0x01, 0x2B, 0x69, 0x46, 0x59, 0x1A, 0xCA, 0xB2, 0x69, 0x46, 0x02, 0xF0,
+ 0x11, 0xF8, 0x7C, 0xBD, 0x2D, 0xE9, 0xFF, 0x5F, 0xDF, 0xF8, 0x10, 0x82,
+ 0x10, 0xF8, 0x01, 0x2B, 0xDF, 0xF8, 0x0C, 0xA2, 0x88, 0xF8, 0x04, 0x20,
+ 0x10, 0xF8, 0x01, 0x2B, 0x0F, 0x46, 0x10, 0xF8, 0x01, 0x3B, 0x04, 0x46,
+ 0x02, 0xEB, 0x03, 0x22, 0x98, 0xF8, 0x01, 0x00, 0x95, 0xB2, 0x40, 0xB9,
+ 0xA5, 0xF5, 0x40, 0x60, 0x03, 0x38, 0x04, 0xD0, 0x2B, 0x46, 0x01, 0x22,
+ 0x79, 0x49, 0x50, 0x46, 0xE7, 0xE0, 0x04, 0x2F, 0x02, 0xD3, 0x14, 0xF8,
+ 0x01, 0x6B, 0x00, 0xE0, 0x00, 0x26, 0x30, 0x46, 0x00, 0xF0, 0xD8, 0xFE,
+ 0x83, 0x46, 0x41, 0xF2, 0x03, 0x01, 0xDF, 0xF8, 0xC4, 0x91, 0x68, 0x1A,
+ 0xA9, 0xF1, 0x01, 0x09, 0x8D, 0x42, 0x5E, 0xD0, 0x0D, 0xDC, 0x00, 0x2D,
+ 0x22, 0xD0, 0xA5, 0xF5, 0x40, 0x60, 0x01, 0x38, 0x06, 0xD0, 0xB0, 0xF5,
+ 0x80, 0x6F, 0x1D, 0xD0, 0xA0, 0xF5, 0x80, 0x60, 0x01, 0x38, 0x08, 0xD1,
+ 0x83, 0xE0, 0x02, 0x28, 0x60, 0xD0, 0x06, 0x28, 0x3A, 0xD0, 0xA0, 0xF5,
+ 0x80, 0x60, 0x02, 0x38, 0x79, 0xD0, 0x3F, 0x20, 0xB0, 0xEB, 0x95, 0x2F,
+ 0x76, 0xD1, 0x04, 0x2F, 0x01, 0xD3, 0x3F, 0x1F, 0xBF, 0xB2, 0xFB, 0xB2,
+ 0x5A, 0x46, 0x29, 0x46, 0x01, 0x20, 0x00, 0x94, 0xF7, 0xF7, 0x0E, 0xFE,
+ 0xBD, 0xE8, 0xFF, 0x9F, 0x98, 0xF8, 0x00, 0x00, 0x41, 0x46, 0x02, 0x28,
+ 0xF8, 0xD1, 0x00, 0x2E, 0xF6, 0xD1, 0x23, 0x78, 0x4B, 0x71, 0x60, 0x78,
+ 0xA2, 0x78, 0x66, 0x79, 0x00, 0xEB, 0x02, 0x20, 0x82, 0xB2, 0x20, 0x79,
+ 0xE5, 0x78, 0x00, 0xEB, 0x06, 0x20, 0x80, 0xB2, 0xA8, 0xF8, 0x06, 0x00,
+ 0xA1, 0x79, 0xE4, 0x79, 0xCD, 0xE9, 0x00, 0x25, 0x01, 0xEB, 0x04, 0x21,
+ 0x89, 0xB2, 0xCD, 0xE9, 0x02, 0x01, 0x4B, 0x49, 0x05, 0x22, 0x34, 0x31,
+ 0x48, 0x46, 0xEC, 0xF7, 0x2A, 0xDB, 0x58, 0xE0, 0x98, 0xF8, 0x00, 0x00,
+ 0x41, 0x46, 0x02, 0x28, 0xD2, 0xD1, 0x00, 0x2E, 0xD0, 0xD1, 0x00, 0x20,
+ 0x0B, 0x18, 0x14, 0xF8, 0x01, 0x2B, 0x40, 0x1C, 0x83, 0xF8, 0x20, 0x20,
+ 0x06, 0x28, 0xF7, 0xD3, 0x47, 0xE0, 0x98, 0xF8, 0x00, 0x00, 0x02, 0x28,
+ 0xC2, 0xD1, 0x00, 0x2E, 0xC0, 0xD1, 0x22, 0x46, 0x08, 0x21, 0x3C, 0x48,
+ 0xEC, 0xF7, 0x79, 0xDD, 0x39, 0x49, 0x03, 0x46, 0x01, 0x22, 0x90, 0x31,
+ 0x48, 0x46, 0xEC, 0xF7, 0x06, 0xDB, 0x34, 0xE0, 0x98, 0xF8, 0x00, 0x00,
+ 0x41, 0x46, 0x02, 0x28, 0xAE, 0xD1, 0x00, 0x2E, 0xAC, 0xD1, 0x20, 0x78,
+ 0x62, 0x78, 0x00, 0xEB, 0x02, 0x20, 0x83, 0xB2, 0xA1, 0xF8, 0x44, 0x30,
+ 0xE0, 0x78, 0x22, 0x79, 0x00, 0xEB, 0x02, 0x20, 0x80, 0xB2, 0xA1, 0xF8,
+ 0x42, 0x00, 0xA8, 0xF8, 0x40, 0x00, 0x2A, 0x49, 0x00, 0x90, 0x02, 0x22,
+ 0xB8, 0x31, 0x50, 0x46, 0xEC, 0xF7, 0xE7, 0xDA, 0x15, 0xE0, 0x18, 0xE0,
+ 0x31, 0xE0, 0x98, 0xF8, 0x00, 0x10, 0x40, 0x46, 0x02, 0x29, 0x8D, 0xD1,
+ 0x00, 0x2E, 0x8B, 0xD1, 0x41, 0x78, 0x00, 0x29, 0x88, 0xD0, 0xA5, 0xF5,
+ 0x40, 0x61, 0x01, 0x39, 0x05, 0xD1, 0xC1, 0x78, 0x01, 0x29, 0x02, 0xD1,
+ 0x10, 0x21, 0x88, 0xF8, 0x01, 0x10, 0xBD, 0xE8, 0xFF, 0x5F, 0x01, 0xF0,
+ 0xAF, 0xBF, 0x20, 0x78, 0x61, 0x78, 0xA4, 0x78, 0x00, 0xEB, 0x01, 0x20,
+ 0x85, 0xB2, 0x28, 0x46, 0x00, 0xF0, 0x42, 0xFE, 0x40, 0xB1, 0x42, 0x78,
+ 0x01, 0x1D, 0x04, 0xB0, 0x63, 0xB2, 0x58, 0x46, 0xBD, 0xE8, 0xF0, 0x5F,
+ 0xF9, 0xF7, 0x62, 0xBA, 0x0F, 0x49, 0x0E, 0x48, 0x01, 0x22, 0xEC, 0x31,
+ 0x2B, 0x46, 0xC0, 0x1E, 0x0F, 0xE0, 0x08, 0x20, 0xB0, 0xEB, 0x95, 0x2F,
+ 0x07, 0xD1, 0x04, 0xB0, 0x22, 0x46, 0x59, 0x46, 0x28, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x5F, 0x01, 0xF0, 0xC5, 0xB9, 0x08, 0x49, 0x2B, 0x46, 0x01, 0x22,
+ 0x48, 0x46, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x5F, 0xEC, 0xF7, 0x9D, 0x9A,
+ 0xF0, 0x75, 0x20, 0x00, 0x03, 0x3C, 0x10, 0x21, 0x98, 0x0A, 0xC0, 0x08,
+ 0x00, 0x00, 0x50, 0x21, 0xC0, 0x0B, 0xC0, 0x08, 0x38, 0xB5, 0x0C, 0x46,
+ 0x05, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22, 0x05, 0x49, 0x06, 0x48,
+ 0xEC, 0xF7, 0x89, 0xDA, 0x22, 0x46, 0x29, 0x46, 0xBD, 0xE8, 0x38, 0x40,
+ 0x40, 0xF2, 0x06, 0x40, 0x00, 0xF0, 0xA1, 0xBC, 0x88, 0x09, 0xC0, 0x08,
+ 0x02, 0x3C, 0x10, 0x21, 0x30, 0xB5, 0x8B, 0xB0, 0x0D, 0xF1, 0x01, 0x04,
+ 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x20, 0x0D, 0x5C, 0x40, 0x1C, 0x04, 0xF8,
+ 0x01, 0x5B, 0x06, 0x28, 0xF9, 0xD3, 0x00, 0x20, 0x11, 0x5C, 0x40, 0x1C,
+ 0x04, 0xF8, 0x01, 0x1B, 0x10, 0x28, 0xF9, 0xD3, 0x00, 0x20, 0x19, 0x5C,
+ 0x40, 0x1C, 0x04, 0xF8, 0x01, 0x1B, 0x10, 0x28, 0xF9, 0xD3, 0x68, 0x46,
+ 0x20, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2, 0x27, 0x00, 0x01, 0xF0,
+ 0xC1, 0xFE, 0x0B, 0xB0, 0x30, 0xBD, 0x42, 0xF2, 0x3D, 0x00, 0x00, 0xF0,
+ 0xD2, 0xBB, 0x42, 0xF2, 0x29, 0x00, 0x00, 0xF0, 0xCE, 0xBB, 0x42, 0xF2,
+ 0x10, 0x00, 0x00, 0xF0, 0xCA, 0xBB, 0x2D, 0xE9, 0xFF, 0x41, 0x0A, 0xAC,
+ 0x94, 0xE8, 0xE0, 0x00, 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x0A, 0x8D, 0xF8,
+ 0x01, 0x00, 0x8D, 0xF8, 0x02, 0x10, 0x08, 0x0A, 0x8D, 0xF8, 0x03, 0x00,
+ 0x8D, 0xF8, 0x04, 0x20, 0x10, 0x0A, 0x8D, 0xF8, 0x05, 0x00, 0x8D, 0xF8,
+ 0x06, 0x30, 0x18, 0x0A, 0x8D, 0xF8, 0x07, 0x00, 0x8D, 0xF8, 0x08, 0x50,
+ 0x28, 0x0A, 0x8D, 0xF8, 0x09, 0x00, 0x6C, 0x46, 0x8D, 0xF8, 0x0A, 0x60,
+ 0x30, 0x0A, 0xE0, 0x72, 0x27, 0x73, 0x38, 0x0A, 0x60, 0x73, 0x68, 0x46,
+ 0x0E, 0x34, 0x20, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2, 0x13, 0x00,
+ 0x01, 0xF0, 0x84, 0xFE, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x2D, 0xE9,
+ 0xF0, 0x4F, 0x87, 0xB0, 0x9A, 0x46, 0xDD, 0xE9, 0x14, 0x65, 0x8D, 0xF8,
+ 0x00, 0x00, 0x00, 0x0A, 0xDD, 0xE9, 0x10, 0x8B, 0x8D, 0xF8, 0x01, 0x00,
+ 0x91, 0x46, 0xDD, 0xE9, 0x16, 0x43, 0xDD, 0xE9, 0x12, 0xC7, 0x8D, 0xF8,
+ 0x02, 0x10, 0x08, 0x0A, 0x8D, 0xF8, 0x03, 0x00, 0x8D, 0xF8, 0x04, 0x90,
+ 0x8D, 0xF8, 0x05, 0xA0, 0x00, 0x20, 0x0D, 0xF1, 0x06, 0x02, 0x18, 0xF8,
+ 0x00, 0x10, 0x40, 0x1C, 0x02, 0xF8, 0x01, 0x1B, 0x06, 0x28, 0xF8, 0xD3,
+ 0x82, 0xF8, 0x00, 0xB0, 0x82, 0xF8, 0x01, 0xC0, 0x4F, 0xEA, 0x1C, 0x20,
+ 0x90, 0x70, 0xD7, 0x70, 0x38, 0x0A, 0x10, 0x71, 0x56, 0x71, 0x30, 0x0A,
+ 0x90, 0x71, 0xD5, 0x71, 0x28, 0x0A, 0x10, 0x72, 0x54, 0x72, 0x20, 0x0A,
+ 0x90, 0x72, 0xD3, 0x72, 0x18, 0x0A, 0x10, 0x73, 0x68, 0x46, 0x0D, 0x32,
+ 0x10, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2, 0x0D, 0x00, 0x01, 0xF0,
+ 0x3D, 0xFE, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x42, 0xF2, 0x0E, 0x00,
+ 0x00, 0xF0, 0x4D, 0xBB, 0x10, 0xB5, 0x88, 0xB0, 0x6A, 0x46, 0x00, 0x23,
+ 0xC4, 0x5C, 0x5B, 0x1C, 0x02, 0xF8, 0x01, 0x4B, 0x10, 0x2B, 0xF9, 0xD3,
+ 0x00, 0x20, 0x0B, 0x5C, 0x40, 0x1C, 0x02, 0xF8, 0x01, 0x3B, 0x10, 0x28,
+ 0xF9, 0xD3, 0x68, 0x46, 0x10, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2,
+ 0x17, 0x00, 0x01, 0xF0, 0x1D, 0xFE, 0x08, 0xB0, 0x10, 0xBD, 0x08, 0xB5,
+ 0x8D, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10, 0x8D, 0xF8, 0x02, 0x20,
+ 0x03, 0x22, 0x69, 0x46, 0x42, 0xF2, 0x33, 0x00, 0x01, 0xF0, 0x0E, 0xFE,
+ 0x08, 0xBD, 0x08, 0xB5, 0x8D, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10,
+ 0x8D, 0xF8, 0x02, 0x20, 0x8D, 0xF8, 0x03, 0x30, 0x04, 0x22, 0x69, 0x46,
+ 0x42, 0xF2, 0x34, 0x00, 0x01, 0xF0, 0xFE, 0xFD, 0x08, 0xBD, 0x70, 0xB5,
+ 0x90, 0xB0, 0x0D, 0xF1, 0x03, 0x04, 0xDD, 0xE9, 0x14, 0x65, 0x8D, 0xF8,
+ 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10, 0x8D, 0xF8, 0x02, 0x20, 0x00, 0x20,
+ 0x19, 0x5C, 0x40, 0x1C, 0x04, 0xF8, 0x01, 0x1B, 0x06, 0x28, 0xF9, 0xD3,
+ 0x04, 0xF8, 0x01, 0x6B, 0x06, 0xF0, 0x07, 0x00, 0x00, 0x22, 0x03, 0xE0,
+ 0x52, 0x1C, 0x41, 0x1E, 0xD2, 0xB2, 0x08, 0x40, 0x00, 0x28, 0xF9, 0xD1,
+ 0x00, 0x21, 0x2C, 0xE0, 0x05, 0xEB, 0x01, 0x10, 0x49, 0x1C, 0x03, 0x78,
+ 0x23, 0x70, 0x03, 0x88, 0xC9, 0xB2, 0x1B, 0x0A, 0x63, 0x70, 0x83, 0x78,
+ 0xA3, 0x70, 0x43, 0x88, 0x1B, 0x0A, 0xE3, 0x70, 0x03, 0x79, 0x23, 0x71,
+ 0x83, 0x88, 0x1B, 0x0A, 0x63, 0x71, 0x83, 0x79, 0xA3, 0x71, 0xC3, 0x88,
+ 0x1B, 0x0A, 0xE3, 0x71, 0x03, 0x7A, 0x23, 0x72, 0x03, 0x89, 0x1B, 0x0A,
+ 0x63, 0x72, 0x83, 0x7A, 0xA3, 0x72, 0x43, 0x89, 0x1B, 0x0A, 0xE3, 0x72,
+ 0x03, 0x7B, 0x23, 0x73, 0x83, 0x89, 0x1B, 0x0A, 0x63, 0x73, 0x83, 0x7B,
+ 0xA3, 0x73, 0xC0, 0x89, 0x00, 0x0A, 0xE0, 0x73, 0x10, 0x34, 0x91, 0x42,
+ 0xD0, 0xD3, 0x68, 0x46, 0x20, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2,
+ 0x43, 0x00, 0x01, 0xF0, 0xA5, 0xFD, 0x10, 0xB0, 0x70, 0xBD, 0x01, 0x46,
+ 0x42, 0xF2, 0x1B, 0x00, 0x00, 0xF0, 0x3C, 0xBB, 0x00, 0xB5, 0x85, 0xB0,
+ 0x0D, 0xF1, 0x02, 0x02, 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x0A, 0x8D, 0xF8,
+ 0x01, 0x00, 0x00, 0x20, 0x0B, 0x5C, 0x40, 0x1C, 0x02, 0xF8, 0x01, 0x3B,
+ 0x10, 0x28, 0xF9, 0xD3, 0x68, 0x46, 0x10, 0x1A, 0xC2, 0xB2, 0x69, 0x46,
+ 0x42, 0xF2, 0x1A, 0x00, 0x01, 0xF0, 0x86, 0xFD, 0x05, 0xB0, 0x00, 0xBD,
+ 0x1C, 0xB5, 0x0D, 0xF1, 0x01, 0x03, 0x8D, 0xF8, 0x00, 0x20, 0x00, 0x22,
+ 0x8C, 0x5C, 0x52, 0x1C, 0x03, 0xF8, 0x01, 0x4B, 0x06, 0x2A, 0xF9, 0xD3,
+ 0x69, 0x46, 0x59, 0x1A, 0xCA, 0xB2, 0x69, 0x46, 0x01, 0xF0, 0x72, 0xFD,
+ 0x1C, 0xBD, 0x42, 0xF2, 0x18, 0x00, 0x00, 0xF0, 0x84, 0xBA, 0x42, 0xF2,
+ 0x07, 0x00, 0x00, 0xF0, 0x80, 0xBA, 0x01, 0x46, 0x42, 0xF2, 0x15, 0x00,
+ 0x00, 0xF0, 0x02, 0xBB, 0x0A, 0x46, 0x01, 0x46, 0x42, 0xF2, 0x2C, 0x00,
+ 0x00, 0xF0, 0x24, 0xBB, 0x0A, 0x46, 0x01, 0x46, 0x42, 0xF2, 0x2B, 0x00,
+ 0x00, 0xF0, 0x1E, 0xBB, 0x01, 0x46, 0x42, 0xF2, 0x30, 0x00, 0x00, 0xF0,
+ 0xF1, 0xBA, 0x42, 0xF2, 0x4C, 0x00, 0x00, 0xF0, 0x66, 0xBA, 0x01, 0x46,
+ 0x42, 0xF2, 0x16, 0x00, 0x00, 0xF0, 0xE8, 0xBA, 0x42, 0xF2, 0x4B, 0x00,
+ 0x00, 0xF0, 0x5D, 0xBA, 0x01, 0x46, 0x42, 0xF2, 0x1D, 0x00, 0x00, 0xF0,
+ 0x1A, 0xBB, 0x01, 0x46, 0x42, 0xF2, 0x3C, 0x00, 0x00, 0xF0, 0x15, 0xBB,
+ 0x0A, 0x46, 0x01, 0x46, 0x42, 0xF2, 0x28, 0x00, 0x00, 0xF0, 0xFC, 0xBA,
+ 0x01, 0x46, 0x42, 0xF2, 0x2D, 0x00, 0x00, 0xF0, 0x0A, 0xBB, 0x00, 0x00,
+ 0x07, 0x4B, 0x93, 0xF8, 0x60, 0x20, 0x10, 0xB1, 0x42, 0xF0, 0x01, 0x01,
+ 0x01, 0xE0, 0x22, 0xF0, 0x01, 0x01, 0x83, 0xF8, 0x60, 0x10, 0x01, 0x46,
+ 0x42, 0xF2, 0x0A, 0x00, 0x00, 0xF0, 0xF9, 0xBA, 0xF0, 0x75, 0x20, 0x00,
+ 0x70, 0xB5, 0x88, 0xB0, 0x0D, 0x46, 0x06, 0x46, 0x14, 0x46, 0x20, 0x21,
+ 0x68, 0x46, 0x1E, 0xF4, 0x63, 0xF2, 0x68, 0x46, 0x1F, 0x2C, 0x00, 0xD9,
+ 0x1F, 0x24, 0x8D, 0xF8, 0x00, 0x40, 0x22, 0x46, 0x29, 0x46, 0x40, 0x1C,
+ 0x1E, 0xF4, 0xB7, 0xF1, 0x20, 0x22, 0x69, 0x46, 0x30, 0x46, 0x01, 0xF0,
+ 0x05, 0xFD, 0x08, 0xB0, 0x70, 0xBD, 0x2D, 0xE9, 0xFF, 0x41, 0x0D, 0xF1,
+ 0x07, 0x04, 0xDD, 0xE9, 0x0B, 0x57, 0xDD, 0xF8, 0x28, 0xC0, 0x8D, 0xF8,
+ 0x00, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x01, 0x00, 0x8D, 0xF8, 0x02, 0x10,
+ 0x08, 0x0A, 0x8D, 0xF8, 0x04, 0x20, 0x0D, 0x9E, 0x8D, 0xF8, 0x03, 0x00,
+ 0x8D, 0xF8, 0x05, 0x30, 0x8D, 0xF8, 0x06, 0xC0, 0x00, 0x20, 0x29, 0x5C,
+ 0x40, 0x1C, 0x04, 0xF8, 0x01, 0x1B, 0x06, 0x28, 0xF9, 0xD3, 0x04, 0xF8,
+ 0x01, 0x7B, 0x68, 0x46, 0x04, 0xF8, 0x01, 0x6B, 0x20, 0x1A, 0xC2, 0xB2,
+ 0x69, 0x46, 0x42, 0xF2, 0x06, 0x00, 0x01, 0xF0, 0xD7, 0xFC, 0x04, 0xB0,
+ 0xBD, 0xE8, 0xF0, 0x81, 0x0A, 0x46, 0x01, 0x46, 0x42, 0xF2, 0x35, 0x00,
+ 0x00, 0xF0, 0x94, 0xBA, 0x1C, 0xB5, 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x0A,
+ 0x8D, 0xF8, 0x01, 0x00, 0x8D, 0xF8, 0x02, 0x10, 0x08, 0x0A, 0x8D, 0xF8,
+ 0x03, 0x00, 0x8D, 0xF8, 0x04, 0x20, 0x10, 0x0A, 0x8D, 0xF8, 0x05, 0x00,
+ 0x06, 0x22, 0x69, 0x46, 0x42, 0xF2, 0x22, 0x00, 0x01, 0xF0, 0xB8, 0xFC,
+ 0x1C, 0xBD, 0x08, 0xB5, 0x8D, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10,
+ 0x8D, 0xF8, 0x02, 0x20, 0x03, 0x22, 0x69, 0x46, 0x42, 0xF2, 0x31, 0x00,
+ 0x01, 0xF0, 0xAA, 0xFC, 0x08, 0xBD, 0x1C, 0xB5, 0xFF, 0x20, 0x8D, 0xF8,
+ 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x00, 0x7F, 0x20, 0x8D, 0xF8, 0x02, 0x00,
+ 0x00, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x05, 0x00, 0x8D, 0xF8,
+ 0x06, 0x00, 0x8D, 0xF8, 0x03, 0x00, 0x8D, 0xF8, 0x07, 0x00, 0x08, 0x22,
+ 0x69, 0x46, 0x42, 0xF2, 0x01, 0x00, 0x01, 0xF0, 0x8F, 0xFC, 0x1C, 0xBD,
+ 0x30, 0xB5, 0xC1, 0xB0, 0x0D, 0xF1, 0x02, 0x03, 0x8D, 0xF8, 0x00, 0x00,
+ 0x8D, 0xF8, 0x01, 0x10, 0x00, 0x20, 0x13, 0xE0, 0x00, 0xEB, 0x40, 0x04,
+ 0x12, 0xF8, 0x14, 0x50, 0x02, 0xEB, 0x44, 0x04, 0x03, 0xF8, 0x01, 0x5B,
+ 0xA5, 0x78, 0x03, 0xF8, 0x01, 0x5B, 0x65, 0x88, 0x2D, 0x0A, 0x03, 0xF8,
+ 0x02, 0x5B, 0x24, 0x79, 0x40, 0x1C, 0x03, 0xF8, 0x01, 0x4C, 0xC0, 0xB2,
+ 0x88, 0x42, 0xE9, 0xD3, 0x68, 0x46, 0x18, 0x1A, 0xC2, 0xB2, 0x69, 0x46,
+ 0x42, 0xF2, 0x39, 0x00, 0x01, 0xF0, 0x66, 0xFC, 0x41, 0xB0, 0x30, 0xBD,
+ 0x70, 0xB5, 0xC0, 0xB0, 0x01, 0xAC, 0x8D, 0xF8, 0x00, 0x10, 0xDD, 0xE9,
+ 0x44, 0x56, 0x8D, 0xF8, 0x01, 0x20, 0x8D, 0xF8, 0x02, 0x30, 0x8D, 0xF8,
+ 0x03, 0x50, 0x00, 0x21, 0x03, 0xE0, 0x72, 0x5C, 0x04, 0xF8, 0x01, 0x2B,
+ 0x49, 0x1C, 0xA9, 0x42, 0xF9, 0xD3, 0x69, 0x46, 0x61, 0x1A, 0xCA, 0xB2,
+ 0x69, 0x46, 0x01, 0xF0, 0x49, 0xFC, 0x40, 0xB0, 0x70, 0xBD, 0x2D, 0xE9,
+ 0xF0, 0x4F, 0x87, 0xB0, 0x6C, 0x46, 0xDD, 0xE9, 0x14, 0xEC, 0x19, 0x9E,
+ 0x8D, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10, 0x08, 0x0A, 0xDD, 0xE9,
+ 0x10, 0x9A, 0x8D, 0xF8, 0x02, 0x00, 0x10, 0x0A, 0x8D, 0xF8, 0x04, 0x00,
+ 0x10, 0x0C, 0x8D, 0xF8, 0x05, 0x00, 0xDD, 0xE9, 0x16, 0x7B, 0x8D, 0xF8,
+ 0x06, 0x30, 0x18, 0x0A, 0x8D, 0xF8, 0x07, 0x00, 0xDD, 0xE9, 0x12, 0x85,
+ 0x18, 0x0C, 0x8D, 0xF8, 0x08, 0x00, 0x8D, 0xF8, 0x03, 0x20, 0x8D, 0xF8,
+ 0x09, 0x90, 0x04, 0xF8, 0x0A, 0xAF, 0x00, 0x20, 0x84, 0xF8, 0x01, 0x80,
+ 0xA4, 0x1C, 0x29, 0x5C, 0x40, 0x1C, 0x04, 0xF8, 0x01, 0x1B, 0x06, 0x28,
+ 0xF9, 0xD3, 0x04, 0xF8, 0x01, 0xEB, 0x69, 0x46, 0x04, 0xF8, 0x01, 0xCB,
+ 0x04, 0xF8, 0x01, 0x7B, 0x04, 0xF8, 0x03, 0xBB, 0x18, 0x98, 0x04, 0xF8,
+ 0x02, 0x0C, 0x04, 0xF8, 0x01, 0x6C, 0x1A, 0x98, 0x04, 0xF8, 0x01, 0x0B,
+ 0x68, 0x46, 0x20, 0x1A, 0xC2, 0xB2, 0x42, 0xF2, 0x36, 0x00, 0x01, 0xF0,
+ 0xFD, 0xFB, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x1C, 0xB5, 0x8D, 0xF8,
+ 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10, 0x8D, 0xF8, 0x02, 0x20, 0x10, 0x0A,
+ 0x8D, 0xF8, 0x03, 0x00, 0x8D, 0xF8, 0x04, 0x30, 0x18, 0x0A, 0x8D, 0xF8,
+ 0x05, 0x00, 0x06, 0x22, 0x69, 0x46, 0x42, 0xF2, 0x42, 0x00, 0x01, 0xF0,
+ 0xE5, 0xFB, 0x1C, 0xBD, 0x7F, 0xB5, 0x0D, 0xF1, 0x03, 0x04, 0x8D, 0xF8,
+ 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10, 0x8D, 0xF8, 0x02, 0x20, 0x02, 0xF0,
+ 0x05, 0x00, 0x00, 0x22, 0x03, 0xE0, 0x52, 0x1C, 0x41, 0x1E, 0xD2, 0xB2,
+ 0x08, 0x40, 0x00, 0x28, 0xF9, 0xD1, 0x17, 0xE0, 0x00, 0xEB, 0x40, 0x01,
+ 0x13, 0xF8, 0x11, 0x50, 0x03, 0xEB, 0x41, 0x01, 0x04, 0xF8, 0x01, 0x5B,
+ 0x8D, 0x78, 0x04, 0xF8, 0x01, 0x5B, 0x4D, 0x88, 0x2D, 0x0A, 0x04, 0xF8,
+ 0x02, 0x5B, 0x0D, 0x79, 0x04, 0xF8, 0x01, 0x5C, 0x89, 0x88, 0x09, 0x0A,
+ 0x40, 0x1C, 0x04, 0xF8, 0x01, 0x1B, 0xC0, 0xB2, 0x90, 0x42, 0xE5, 0xD3,
+ 0x68, 0x46, 0x20, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2, 0x41, 0x00,
+ 0x01, 0xF0, 0xAE, 0xFB, 0x04, 0xB0, 0x70, 0xBD, 0x1C, 0xB5, 0x6A, 0x46,
+ 0x00, 0x21, 0x43, 0x5C, 0x49, 0x1C, 0x02, 0xF8, 0x01, 0x3B, 0x05, 0x29,
+ 0xF9, 0xD3, 0x68, 0x46, 0x10, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2,
+ 0x14, 0x00, 0x01, 0xF0, 0x9B, 0xFB, 0x1C, 0xBD, 0x1C, 0xB5, 0x8D, 0xF8,
+ 0x00, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x01, 0x00, 0x04, 0x9C, 0x8D, 0xF8,
+ 0x02, 0x10, 0x8D, 0xF8, 0x04, 0x30, 0x8D, 0xF8, 0x05, 0x40, 0x20, 0x0A,
+ 0x8D, 0xF8, 0x03, 0x20, 0x8D, 0xF8, 0x06, 0x00, 0x07, 0x22, 0x69, 0x46,
+ 0x42, 0xF2, 0x32, 0x00, 0x01, 0xF0, 0x82, 0xFB, 0x1C, 0xBD, 0x1C, 0xB5,
+ 0x0D, 0xF1, 0x01, 0x03, 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x20, 0x0C, 0x5C,
+ 0x40, 0x1C, 0x03, 0xF8, 0x01, 0x4B, 0x06, 0x28, 0xF9, 0xD3, 0x03, 0xF8,
+ 0x01, 0x2B, 0x68, 0x46, 0x18, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2,
+ 0x4E, 0x00, 0x01, 0xF0, 0x6B, 0xFB, 0x1C, 0xBD, 0x01, 0x46, 0x42, 0xF2,
+ 0x05, 0x00, 0xFF, 0xF7, 0x40, 0xBB, 0x01, 0x46, 0x42, 0xF2, 0x2E, 0x00,
+ 0x00, 0xF0, 0xFE, 0xB8, 0x08, 0xB5, 0x02, 0x22, 0x8D, 0xF8, 0x00, 0x00,
+ 0x8D, 0xF8, 0x01, 0x10, 0x69, 0x46, 0x42, 0xF2, 0x0C, 0x00, 0x01, 0xF0,
+ 0x55, 0xFB, 0x08, 0xBD, 0x1C, 0xB5, 0x8D, 0xF8, 0x00, 0x00, 0x8D, 0xF8,
+ 0x01, 0x10, 0x08, 0x0A, 0x8D, 0xF8, 0x02, 0x00, 0x10, 0x0A, 0x8D, 0xF8,
+ 0x04, 0x00, 0x04, 0x9C, 0x8D, 0xF8, 0x03, 0x20, 0x8D, 0xF8, 0x05, 0x30,
+ 0x8D, 0xF8, 0x06, 0x40, 0x07, 0x22, 0x69, 0x46, 0x42, 0xF2, 0x0B, 0x00,
+ 0x01, 0xF0, 0x3C, 0xFB, 0x1C, 0xBD, 0x30, 0xB5, 0x87, 0xB0, 0x0D, 0xF1,
+ 0x02, 0x04, 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x01, 0x00,
+ 0x00, 0x20, 0x0D, 0x5C, 0x40, 0x1C, 0x04, 0xF8, 0x01, 0x5B, 0x08, 0x28,
+ 0xF9, 0xD3, 0x04, 0xF8, 0x01, 0x2B, 0x10, 0x0A, 0x04, 0xF8, 0x01, 0x0B,
+ 0x00, 0x20, 0x19, 0x5C, 0x40, 0x1C, 0x04, 0xF8, 0x01, 0x1B, 0x10, 0x28,
+ 0xF9, 0xD3, 0x68, 0x46, 0x20, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2,
+ 0x19, 0x00, 0x01, 0xF0, 0x17, 0xFB, 0x07, 0xB0, 0x30, 0xBD, 0x42, 0xF2,
+ 0x1F, 0x00, 0x00, 0xF0, 0x28, 0xB8, 0x08, 0xB5, 0x00, 0x23, 0x00, 0x93,
+ 0x8D, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10, 0x8D, 0xF8, 0x02, 0x20,
+ 0x03, 0x22, 0x69, 0x46, 0x42, 0xF2, 0x1E, 0x00, 0x01, 0xF0, 0x02, 0xFB,
+ 0x08, 0xBD, 0x08, 0xB5, 0x04, 0x22, 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x0A,
+ 0x8D, 0xF8, 0x01, 0x00, 0x8D, 0xF8, 0x02, 0x10, 0x08, 0x0A, 0x8D, 0xF8,
+ 0x03, 0x00, 0x69, 0x46, 0x42, 0xF2, 0x4D, 0x00, 0x01, 0xF0, 0xF0, 0xFA,
+ 0x08, 0xBD, 0x0A, 0x46, 0x01, 0x46, 0x42, 0xF2, 0x24, 0x00, 0x00, 0xF0,
+ 0x92, 0xB8, 0x00, 0x22, 0x11, 0x46, 0x01, 0xF0, 0xE5, 0xBA, 0x1C, 0xB5,
+ 0x01, 0x78, 0x8D, 0xF8, 0x00, 0x10, 0x41, 0x78, 0x8D, 0xF8, 0x01, 0x10,
+ 0x81, 0x78, 0x8D, 0xF8, 0x02, 0x10, 0xC1, 0x78, 0x8D, 0xF8, 0x03, 0x10,
+ 0x01, 0x79, 0x8D, 0xF8, 0x04, 0x10, 0x41, 0x79, 0x8D, 0xF8, 0x05, 0x10,
+ 0x81, 0x79, 0x8D, 0xF8, 0x06, 0x10, 0xC0, 0x79, 0x8D, 0xF8, 0x07, 0x00,
+ 0x08, 0x22, 0x69, 0x46, 0x40, 0xF6, 0x01, 0x40, 0x01, 0xF0, 0xC6, 0xFA,
+ 0x1C, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xFC, 0x41, 0x2C, 0x4F, 0x01, 0x78,
+ 0x42, 0x78, 0x3A, 0x71, 0x82, 0x78, 0xC0, 0x78, 0x02, 0xEB, 0x00, 0x20,
+ 0x84, 0xB2, 0x08, 0x46, 0x00, 0xF0, 0xA6, 0xF9, 0x06, 0x46, 0x78, 0x78,
+ 0x28, 0xB9, 0x24, 0xB1, 0x23, 0x46, 0x01, 0x22, 0x24, 0x49, 0x25, 0x48,
+ 0x3E, 0xE0, 0xF8, 0x8C, 0x00, 0x25, 0xA0, 0x42, 0x00, 0xD1, 0xFD, 0x84,
+ 0x00, 0x2C, 0x10, 0xD0, 0xA4, 0xF5, 0x80, 0x60, 0x06, 0x38, 0x0E, 0xD0,
+ 0x17, 0x28, 0x11, 0xD0, 0x3F, 0x20, 0xB0, 0xEB, 0x94, 0x2F, 0x1D, 0xD1,
+ 0x00, 0x23, 0x32, 0x46, 0x21, 0x46, 0x18, 0x46, 0x00, 0x95, 0xF7, 0xF7,
+ 0xEB, 0xF8, 0xBD, 0xE8, 0xFC, 0x81, 0xF8, 0x8D, 0x00, 0xF0, 0xA8, 0xF9,
+ 0xA0, 0xB9, 0xF8, 0xE7, 0xF8, 0x8D, 0x00, 0xF0, 0xA3, 0xF9, 0x00, 0x28,
+ 0xF3, 0xD0, 0x00, 0x2E, 0xF1, 0xD0, 0x00, 0x95, 0x01, 0x95, 0x42, 0x78,
+ 0x01, 0x1D, 0x00, 0x23, 0x30, 0x46, 0xF8, 0xF7, 0x93, 0xFD, 0xE8, 0xE7,
+ 0x08, 0x20, 0xB0, 0xEB, 0x94, 0x2F, 0x05, 0xD1, 0x31, 0x46, 0x20, 0x46,
+ 0xBD, 0xE8, 0xFC, 0x41, 0x00, 0xF0, 0xFE, 0xBE, 0x06, 0x49, 0x07, 0x48,
+ 0x01, 0x22, 0x3C, 0x31, 0x23, 0x46, 0x40, 0x1C, 0x02, 0xB0, 0xBD, 0xE8,
+ 0xF0, 0x41, 0xEB, 0xF7, 0x02, 0x9E, 0x00, 0x00, 0xF0, 0x75, 0x20, 0x00,
+ 0xF4, 0x09, 0xC0, 0x08, 0x01, 0x3C, 0x10, 0x21, 0x08, 0xB5, 0x02, 0x22,
+ 0x8D, 0xF8, 0x00, 0x10, 0x09, 0x0A, 0x8D, 0xF8, 0x01, 0x10, 0x69, 0x46,
+ 0x01, 0xF0, 0x58, 0xFA, 0x08, 0xBD, 0x08, 0xB5, 0x8D, 0xF8, 0x00, 0x10,
+ 0x09, 0x0A, 0x8D, 0xF8, 0x01, 0x10, 0x8D, 0xF8, 0x02, 0x20, 0x11, 0x0A,
+ 0x8D, 0xF8, 0x03, 0x10, 0x04, 0x22, 0x69, 0x46, 0x01, 0xF0, 0x48, 0xFA,
+ 0x08, 0xBD, 0x08, 0xB5, 0x8D, 0xF8, 0x00, 0x10, 0x09, 0x0A, 0x8D, 0xF8,
+ 0x01, 0x10, 0x8D, 0xF8, 0x02, 0x20, 0x03, 0x22, 0x69, 0x46, 0x01, 0xF0,
+ 0x3B, 0xFA, 0x08, 0xBD, 0x1C, 0xB5, 0x0D, 0xF1, 0x01, 0x03, 0x8D, 0xF8,
+ 0x00, 0x10, 0x00, 0x21, 0x54, 0x5C, 0x49, 0x1C, 0x03, 0xF8, 0x01, 0x4B,
+ 0x06, 0x29, 0xF9, 0xD3, 0x69, 0x46, 0x59, 0x1A, 0xCA, 0xB2, 0x69, 0x46,
+ 0x01, 0xF0, 0x28, 0xFA, 0x1C, 0xBD, 0x08, 0xB5, 0x01, 0x22, 0x8D, 0xF8,
+ 0x00, 0x10, 0x69, 0x46, 0x01, 0xF0, 0x20, 0xFA, 0x08, 0xBD, 0x01, 0xF0,
+ 0x1D, 0xBA, 0x00, 0x00, 0x7C, 0xB5, 0x41, 0x78, 0x82, 0x78, 0xC6, 0x78,
+ 0x01, 0xEB, 0x02, 0x21, 0x8D, 0xB2, 0x28, 0x46, 0x00, 0xF0, 0x2A, 0xF9,
+ 0x04, 0x00, 0x0E, 0xD0, 0x28, 0x46, 0x09, 0xF0, 0xDD, 0xFC, 0xA0, 0xB3,
+ 0x00, 0x22, 0x1F, 0x49, 0x1F, 0x48, 0xEB, 0xF7, 0xA0, 0xDD, 0x20, 0x7D,
+ 0x40, 0xF0, 0x10, 0x00, 0x20, 0x75, 0x66, 0x75, 0x7C, 0xBD, 0x1C, 0x4C,
+ 0x2B, 0x46, 0x03, 0x22, 0x14, 0xF8, 0x60, 0x0F, 0xC0, 0xF3, 0xC0, 0x00,
+ 0x61, 0x88, 0xCD, 0xE9, 0x00, 0x10, 0x15, 0x49, 0x15, 0x48, 0x6C, 0x39,
+ 0x40, 0x1E, 0xEB, 0xF7, 0x8A, 0xDD, 0x14, 0xF8, 0x60, 0x09, 0x01, 0x07,
+ 0xEA, 0xD5, 0xB4, 0xF8, 0x62, 0x10, 0xA9, 0x42, 0xE6, 0xD1, 0x20, 0xF0,
+ 0x08, 0x00, 0x84, 0xF8, 0x60, 0x00, 0x00, 0x21, 0xA4, 0xF8, 0x62, 0x10,
+ 0x80, 0x07, 0xDD, 0xD5, 0x01, 0x20, 0xFF, 0xF7, 0xAD, 0xFC, 0x14, 0xF8,
+ 0x60, 0x0F, 0x40, 0xF0, 0x04, 0x00, 0x20, 0x70, 0x7C, 0xBD, 0xFF, 0xE7,
+ 0x31, 0x46, 0x28, 0x46, 0x01, 0xF0, 0x29, 0xF8, 0x20, 0x1D, 0xBD, 0xE8,
+ 0x7C, 0x40, 0x00, 0xF0, 0xFF, 0xB8, 0x00, 0x00, 0x5C, 0x0C, 0xC0, 0x08,
+ 0x01, 0x3C, 0x10, 0x21, 0xF0, 0x75, 0x20, 0x00, 0x10, 0xB5, 0x0A, 0x48,
+ 0x86, 0xB0, 0x0D, 0xF1, 0x04, 0x0C, 0x01, 0x8F, 0xC4, 0x8F, 0x83, 0x8F,
+ 0x42, 0x8F, 0x8C, 0xE8, 0x1E, 0x00, 0xC1, 0x8E, 0x00, 0x91, 0x83, 0x8E,
+ 0x06, 0x22, 0x04, 0x49, 0x04, 0x48, 0xEB, 0xF7, 0x4C, 0xDD, 0x06, 0xB0,
+ 0x10, 0xBD, 0x00, 0x00, 0xF0, 0x75, 0x20, 0x00, 0xD0, 0x11, 0xC0, 0x08,
+ 0x03, 0x3C, 0x10, 0x21, 0x70, 0xB5, 0x20, 0xB1, 0x01, 0x28, 0x02, 0xD0,
+ 0x40, 0xF4, 0x80, 0x70, 0x1D, 0xE0, 0x15, 0x4C, 0x15, 0x4E, 0x4F, 0xF0,
+ 0x80, 0x45, 0xA0, 0x78, 0x01, 0x22, 0x00, 0xF0, 0x03, 0x03, 0x13, 0x49,
+ 0x30, 0x46, 0xEB, 0xF7, 0x30, 0xDD, 0xA0, 0x78, 0x10, 0xF0, 0x03, 0x01,
+ 0x05, 0xEB, 0xB0, 0x00, 0x4F, 0xEA, 0xB0, 0x70, 0xA0, 0x70, 0x0C, 0xD0,
+ 0x01, 0x29, 0x0D, 0xD0, 0x03, 0x29, 0xEA, 0xD1, 0xC0, 0xB2, 0x40, 0xF0,
+ 0x04, 0x00, 0xA0, 0x70, 0x00, 0x20, 0xBD, 0xE8, 0x70, 0x40, 0xF7, 0xF7,
+ 0xD3, 0xBD, 0x42, 0xF2, 0x3A, 0x00, 0x01, 0xE0, 0x42, 0xF2, 0x3B, 0x00,
+ 0xBD, 0xE8, 0x70, 0x40, 0xFF, 0xF7, 0x8F, 0xBE, 0xF0, 0x75, 0x20, 0x00,
+ 0x03, 0x3C, 0x10, 0x21, 0x44, 0x09, 0xC0, 0x08, 0x70, 0xB5, 0x41, 0x78,
+ 0x82, 0x78, 0x04, 0x78, 0x01, 0xEB, 0x02, 0x21, 0x8D, 0xB2, 0xC6, 0x78,
+ 0x28, 0x46, 0x00, 0xF0, 0x7F, 0xF8, 0x00, 0x28, 0x09, 0xD0, 0x20, 0x46,
+ 0x00, 0xF0, 0x52, 0xF8, 0x02, 0x46, 0x31, 0x46, 0x28, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0x0A, 0xF0, 0x13, 0xBC, 0x70, 0xBD, 0x70, 0xB5, 0x04, 0x78,
+ 0x41, 0x78, 0x80, 0x78, 0x01, 0xEB, 0x00, 0x20, 0x85, 0xB2, 0x28, 0x46,
+ 0x00, 0xF0, 0x68, 0xF8, 0x00, 0x28, 0x05, 0xD0, 0x21, 0x46, 0x28, 0x46,
+ 0xBD, 0xE8, 0x70, 0x40, 0x0A, 0xF0, 0x88, 0xB9, 0x70, 0xBD, 0x00, 0x00,
+ 0x00, 0xB5, 0x17, 0x48, 0x85, 0xB0, 0x40, 0xF2, 0x9E, 0x23, 0x14, 0x4A,
+ 0x69, 0x46, 0x00, 0x78, 0xF3, 0xF7, 0x1E, 0xFD, 0x88, 0xB1, 0xBD, 0xF8,
+ 0x00, 0x30, 0x18, 0x46, 0xB3, 0xF5, 0x00, 0x7F, 0x17, 0xD0, 0xA3, 0xF5,
+ 0x00, 0x73, 0x01, 0x3B, 0x0F, 0xD0, 0x01, 0x2B, 0x09, 0xD0, 0x03, 0x46,
+ 0x01, 0x22, 0x0C, 0x49, 0x0C, 0x48, 0xEB, 0xF7, 0xC2, 0xDC, 0x01, 0xF0,
+ 0x63, 0xFA, 0x05, 0xB0, 0x00, 0xBD, 0x68, 0x46, 0x00, 0xF0, 0x9D, 0xF9,
+ 0xF7, 0xE7, 0x68, 0x46, 0x00, 0xF0, 0xB6, 0xF9, 0xF3, 0xE7, 0x68, 0x46,
+ 0x00, 0xF0, 0xD8, 0xF9, 0xEF, 0xE7, 0x00, 0x00, 0x54, 0xA7, 0x82, 0x00,
+ 0xEC, 0x75, 0x20, 0x00, 0x60, 0x11, 0xC0, 0x08, 0x00, 0x3C, 0x10, 0x21,
+ 0x00, 0x28, 0x01, 0xD0, 0x40, 0xF4, 0x80, 0x70, 0x70, 0x47, 0x00, 0x00,
+ 0x2D, 0xE9, 0xF0, 0x41, 0x80, 0x46, 0x00, 0x24, 0x0C, 0x4E, 0x0D, 0x4F,
+ 0x0C, 0xE0, 0x30, 0x6B, 0x00, 0xEB, 0x44, 0x15, 0x28, 0x78, 0x28, 0xB1,
+ 0x06, 0x22, 0x41, 0x46, 0x28, 0x1D, 0x1D, 0xF4, 0x5B, 0xF5, 0x40, 0xB1,
+ 0x64, 0x1C, 0xA4, 0xB2, 0x97, 0xF8, 0x98, 0x01, 0xA0, 0x42, 0xEE, 0xD8,
+ 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x28, 0x46, 0xFB, 0xE7, 0x00, 0x00,
+ 0xF0, 0x75, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0x30, 0xB5, 0x04, 0x46,
+ 0x09, 0x48, 0x00, 0x21, 0x02, 0x6B, 0x09, 0x48, 0x90, 0xF8, 0x98, 0x31,
+ 0x08, 0xE0, 0x02, 0xEB, 0x41, 0x10, 0x05, 0x78, 0x15, 0xB1, 0x45, 0x88,
+ 0xA5, 0x42, 0x04, 0xD0, 0x49, 0x1C, 0x89, 0xB2, 0x8B, 0x42, 0xF4, 0xD8,
+ 0x00, 0x20, 0x30, 0xBD, 0xF0, 0x75, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x30, 0xB5, 0x87, 0xB0, 0x05, 0x46, 0xFF, 0xF7, 0xBF, 0xFF, 0x04, 0x46,
+ 0x29, 0x46, 0x14, 0x48, 0xEB, 0xF7, 0x2C, 0xDE, 0x03, 0x46, 0x02, 0x22,
+ 0x12, 0x49, 0x13, 0x48, 0x00, 0x94, 0xEB, 0xF7, 0x56, 0xDC, 0x00, 0x2C,
+ 0x19, 0xD0, 0x04, 0xF1, 0x0C, 0x05, 0x55, 0x23, 0x0F, 0x4A, 0x01, 0xA9,
+ 0x28, 0x46, 0xF3, 0xF7, 0xEF, 0xFF, 0x48, 0xB1, 0xBD, 0xF8, 0x08, 0x00,
+ 0xC0, 0x07, 0xF4, 0xD0, 0x59, 0x22, 0x0A, 0x49, 0x04, 0x98, 0xF3, 0xF7,
+ 0xC5, 0xFA, 0xEE, 0xE7, 0x08, 0x49, 0x00, 0x20, 0x20, 0x70, 0x31, 0xF8,
+ 0x46, 0x0F, 0x40, 0x1E, 0x08, 0x80, 0x07, 0xB0, 0x30, 0xBD, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x21, 0x48, 0x12, 0xC0, 0x08, 0x02, 0x3C, 0x10, 0x21,
+ 0x67, 0xA7, 0x82, 0x00, 0xF0, 0x75, 0x20, 0x00, 0x0E, 0x49, 0x0A, 0x6A,
+ 0x02, 0x60, 0x8A, 0x8C, 0x82, 0x80, 0x8A, 0x6C, 0xC0, 0xF8, 0x06, 0x20,
+ 0xCA, 0x6C, 0xC0, 0xF8, 0x0A, 0x20, 0x91, 0xF8, 0x50, 0x20, 0xC2, 0x73,
+ 0x91, 0xF8, 0x51, 0x20, 0x82, 0x73, 0xB1, 0xF8, 0x56, 0x20, 0x82, 0x82,
+ 0x91, 0xF8, 0x52, 0x20, 0x02, 0x74, 0x91, 0xF8, 0x53, 0x20, 0x42, 0x74,
+ 0x91, 0xF8, 0x54, 0x10, 0x81, 0x74, 0x70, 0x47, 0xF0, 0x75, 0x20, 0x00,
+ 0x10, 0xB5, 0xFF, 0xF7, 0x89, 0xFF, 0x00, 0x28, 0x00, 0xD0, 0x16, 0x30,
+ 0x10, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x43, 0x04, 0x46, 0x2E, 0x48,
+ 0xDF, 0xF8, 0xB8, 0x90, 0x85, 0xB0, 0x40, 0x78, 0xB8, 0xB3, 0xE1, 0x88,
+ 0xE0, 0x68, 0x45, 0x18, 0x15, 0xF8, 0x01, 0x0B, 0x15, 0xF8, 0x01, 0x1B,
+ 0x00, 0xEB, 0x01, 0x20, 0x15, 0xF8, 0x01, 0x1B, 0xC0, 0xF3, 0x01, 0x38,
+ 0x15, 0xF8, 0x01, 0x2B, 0xC0, 0xF3, 0x0B, 0x07, 0x01, 0xEB, 0x02, 0x21,
+ 0x8E, 0xB2, 0x38, 0x46, 0xFF, 0xF7, 0x64, 0xFF, 0x68, 0xB3, 0x4F, 0xF4,
+ 0x40, 0x70, 0xAD, 0xF8, 0x00, 0x00, 0xE0, 0x68, 0x03, 0x90, 0xA0, 0x89,
+ 0xAD, 0xF8, 0x08, 0x60, 0x28, 0x1A, 0xAD, 0xF8, 0x06, 0x00, 0xB8, 0xF1,
+ 0x01, 0x0F, 0x1C, 0xD0, 0x08, 0x20, 0x40, 0xF0, 0x01, 0x00, 0xAD, 0xF8,
+ 0x04, 0x00, 0x18, 0x48, 0xAD, 0xF8, 0x0A, 0x70, 0x68, 0x23, 0x15, 0x4A,
+ 0x69, 0x46, 0x00, 0x78, 0xF3, 0xF7, 0x62, 0xFC, 0x05, 0xB0, 0xBD, 0xE8,
+ 0xF0, 0x83, 0xFF, 0xE7, 0x00, 0x22, 0x12, 0x49, 0x48, 0x46, 0xEB, 0xF7,
+ 0xBE, 0xDB, 0x20, 0x79, 0xC0, 0x07, 0xF3, 0xD0, 0x4C, 0x22, 0xE0, 0x68,
+ 0x0D, 0xE0, 0x10, 0x20, 0xE1, 0xE7, 0x0C, 0x49, 0x3B, 0x46, 0x01, 0x22,
+ 0x34, 0x31, 0x48, 0x46, 0xEB, 0xF7, 0xAF, 0xDB, 0x20, 0x79, 0xC0, 0x07,
+ 0xE4, 0xD0, 0xE0, 0x68, 0x70, 0x22, 0x04, 0x49, 0xF3, 0xF7, 0x2A, 0xFA,
+ 0xDE, 0xE7, 0x00, 0x00, 0xF0, 0x75, 0x20, 0x00, 0x01, 0x3C, 0x10, 0x21,
+ 0xE6, 0xA6, 0x82, 0x00, 0x64, 0x76, 0x20, 0x00, 0x74, 0x0F, 0xC0, 0x08,
+ 0xC1, 0x68, 0xC0, 0x88, 0x22, 0x4A, 0x08, 0x44, 0x10, 0xF8, 0x01, 0x3B,
+ 0x52, 0x78, 0x10, 0xF8, 0x01, 0x1B, 0x3A, 0xB9, 0x0E, 0x2B, 0x05, 0xD0,
+ 0x0F, 0x2B, 0x03, 0xD0, 0x01, 0x22, 0x1D, 0x49, 0x1D, 0x48, 0x1C, 0xE0,
+ 0x10, 0x2B, 0x26, 0xD0, 0x0C, 0xDC, 0x0C, 0x2B, 0x1F, 0xD0, 0x04, 0xDC,
+ 0x05, 0x2B, 0x1A, 0xD0, 0x08, 0x2B, 0x0D, 0xD1, 0x20, 0xE0, 0x0E, 0x2B,
+ 0x11, 0xD0, 0x0F, 0x2B, 0x08, 0xD1, 0x10, 0xE0, 0x13, 0x2B, 0x14, 0xD0,
+ 0x30, 0x2B, 0x19, 0xD0, 0x3E, 0x2B, 0x19, 0xD0, 0xFF, 0x2B, 0x1A, 0xD0,
+ 0x0F, 0x49, 0x10, 0x48, 0x01, 0x22, 0x38, 0x31, 0x40, 0x1E, 0xEB, 0xF7,
+ 0x6A, 0x9B, 0xFE, 0xF7, 0xBF, 0xBF, 0xFF, 0xF7, 0x09, 0xBD, 0xFF, 0xF7,
+ 0xAF, 0xBD, 0x00, 0xF0, 0x41, 0xBF, 0x00, 0xF0, 0xF9, 0xBE, 0x00, 0x78,
+ 0xF6, 0xF7, 0x82, 0xBE, 0xFF, 0xF7, 0x50, 0xBE, 0xFF, 0xF7, 0x66, 0xBE,
+ 0x89, 0x1C, 0x00, 0xF0, 0x09, 0xB8, 0xF6, 0xF7, 0x4B, 0xBE, 0x00, 0x00,
+ 0xF0, 0x75, 0x20, 0x00, 0xD8, 0x0F, 0xC0, 0x08, 0x03, 0x3C, 0x10, 0x21,
+ 0x10, 0xF8, 0x01, 0x1B, 0x15, 0x29, 0x29, 0xD2, 0xDF, 0xE8, 0x01, 0xF0,
+ 0x28, 0x0B, 0x0D, 0x0F, 0x11, 0x13, 0x28, 0x15, 0x28, 0x28, 0x0B, 0x17,
+ 0x19, 0x1F, 0x28, 0x28, 0x28, 0x21, 0x1B, 0x1D, 0x26, 0x00, 0x00, 0xF0,
+ 0x89, 0xBC, 0x00, 0xF0, 0xE1, 0xB9, 0x00, 0xF0, 0x87, 0xBD, 0x00, 0xF0,
+ 0x97, 0xBE, 0x00, 0xF0, 0x69, 0xBE, 0x00, 0xF0, 0xA2, 0xBD, 0x00, 0xF0,
+ 0xBF, 0xBD, 0x00, 0xF0, 0x7C, 0xBE, 0x00, 0xF0, 0x27, 0xBA, 0x00, 0xF0,
+ 0xAE, 0xBE, 0x00, 0xF0, 0xFB, 0xBD, 0x00, 0x21, 0x4F, 0xF4, 0xD8, 0x70,
+ 0xF8, 0xF7, 0x35, 0xBB, 0x00, 0xF0, 0x35, 0xBA, 0x70, 0x47, 0x10, 0xB5,
+ 0x04, 0x46, 0xC1, 0x68, 0xC0, 0x88, 0x01, 0x44, 0x40, 0x1C, 0xE0, 0x80,
+ 0x20, 0x89, 0x40, 0x1E, 0x20, 0x81, 0x08, 0x78, 0x02, 0x28, 0x09, 0xD0,
+ 0x04, 0x28, 0x0C, 0xD1, 0x20, 0x46, 0xFF, 0xF7, 0x71, 0xFF, 0x20, 0x69,
+ 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0x10, 0xB9, 0x20, 0x46, 0xBD, 0xE8,
+ 0x10, 0x40, 0xFF, 0xF7, 0xFD, 0xBE, 0x10, 0xBD, 0x38, 0xB5, 0xC1, 0x68,
+ 0x09, 0x78, 0x02, 0x29, 0x07, 0xD1, 0x0C, 0x49, 0x31, 0xF8, 0x3E, 0x2F,
+ 0x52, 0x1C, 0x0A, 0x80, 0x4A, 0x88, 0x52, 0x1C, 0x4A, 0x80, 0xC3, 0x68,
+ 0x02, 0x22, 0x08, 0x49, 0x53, 0xF8, 0x04, 0x4C, 0x07, 0x48, 0x00, 0x94,
+ 0xEB, 0xF7, 0xEB, 0xDA, 0x20, 0x46, 0xBD, 0xE8, 0x38, 0x40, 0x40, 0xF2,
+ 0x2B, 0x12, 0x04, 0x49, 0xF3, 0xF7, 0x66, 0xB9, 0xF0, 0x75, 0x20, 0x00,
+ 0x40, 0x10, 0xC0, 0x08, 0x03, 0x3C, 0x10, 0x21, 0xF9, 0xA6, 0x82, 0x00,
+ 0x2D, 0xE9, 0xF0, 0x41, 0xC3, 0x88, 0x28, 0x4F, 0x04, 0x46, 0x10, 0x2B,
+ 0x0B, 0xD2, 0x01, 0x22, 0x26, 0x49, 0x38, 0x46, 0xEB, 0xF7, 0xCF, 0xDA,
+ 0x20, 0x79, 0xC0, 0x07, 0x42, 0xD0, 0x40, 0xF2, 0x3B, 0x12, 0xE0, 0x68,
+ 0x23, 0xE0, 0x60, 0x89, 0xC0, 0xF3, 0x0B, 0x05, 0x28, 0x46, 0xFF, 0xF7,
+ 0x41, 0xFE, 0x06, 0x00, 0x0E, 0xD0, 0x21, 0x89, 0x48, 0x1D, 0x20, 0x81,
+ 0xE0, 0x88, 0x40, 0x1F, 0x80, 0xB2, 0xE0, 0x80, 0xE2, 0x68, 0x10, 0x44,
+ 0xA2, 0x88, 0xD3, 0x06, 0x14, 0xD5, 0x45, 0xF4, 0x80, 0x55, 0x15, 0xE0,
+ 0x15, 0x49, 0x2B, 0x46, 0x01, 0x22, 0x30, 0x31, 0x38, 0x46, 0xEB, 0xF7,
+ 0xAA, 0xDA, 0x20, 0x79, 0xC0, 0x07, 0x1D, 0xD0, 0xE0, 0x68, 0x40, 0xF2,
+ 0x49, 0x12, 0xBD, 0xE8, 0xF0, 0x41, 0x0F, 0x49, 0xF3, 0xF7, 0x22, 0xB9,
+ 0x52, 0x06, 0x01, 0xD5, 0x45, 0xF4, 0x00, 0x55, 0x02, 0x22, 0x02, 0x70,
+ 0x45, 0x70, 0x2A, 0x0A, 0x82, 0x70, 0xC1, 0x70, 0x09, 0x0A, 0x01, 0x71,
+ 0x21, 0x46, 0x06, 0xF1, 0x0C, 0x00, 0xBD, 0xE8, 0xF0, 0x41, 0x4F, 0xF4,
+ 0xB4, 0x73, 0x04, 0x4A, 0xF3, 0xF7, 0x56, 0xBE, 0xBD, 0xE8, 0xF0, 0x81,
+ 0x00, 0x3C, 0x10, 0x21, 0x6C, 0x10, 0xC0, 0x08, 0x13, 0xA7, 0x82, 0x00,
+ 0x2D, 0xE9, 0xF0, 0x41, 0x86, 0xB0, 0x1E, 0x46, 0x14, 0x46, 0x00, 0x91,
+ 0xCD, 0xE9, 0x01, 0x46, 0x0F, 0x46, 0x80, 0x46, 0x03, 0x46, 0x01, 0x25,
+ 0x04, 0x22, 0x38, 0x49, 0x38, 0x48, 0xEB, 0xF7, 0x70, 0xDA, 0x43, 0x46,
+ 0xDF, 0xF8, 0xDC, 0x80, 0x02, 0x22, 0x08, 0xF1, 0x04, 0x01, 0x01, 0xF1,
+ 0x20, 0x00, 0x05, 0x2B, 0x5E, 0xD2, 0xDF, 0xE8, 0x03, 0xF0, 0x4D, 0x5D,
+ 0x03, 0x37, 0x49, 0x00, 0x08, 0x8F, 0x00, 0x25, 0x40, 0x1C, 0x08, 0x87,
+ 0x23, 0x78, 0x02, 0x2B, 0x09, 0xD0, 0x04, 0x2B, 0x09, 0xD0, 0x2A, 0x49,
+ 0x2A, 0x48, 0x01, 0x22, 0x34, 0x31, 0xC0, 0x1E, 0xEB, 0xF7, 0x51, 0xDA,
+ 0x1E, 0xE0, 0x4D, 0x89, 0x62, 0x55, 0x76, 0x1B, 0x62, 0x19, 0xB1, 0xB2,
+ 0x26, 0x48, 0xEB, 0xF7, 0x6F, 0xDB, 0x40, 0xF2, 0x02, 0x20, 0xAD, 0xF8,
+ 0x00, 0x00, 0xAD, 0xF8, 0x06, 0x50, 0x01, 0x20, 0x03, 0x94, 0xAD, 0xF8,
+ 0x08, 0x60, 0xAD, 0xF8, 0x04, 0x00, 0x04, 0x94, 0x40, 0xF2, 0xAB, 0x13,
+ 0x1E, 0x4A, 0x69, 0x46, 0x98, 0xF8, 0x00, 0x00, 0xF3, 0xF7, 0xCE, 0xFA,
+ 0x05, 0x00, 0x29, 0xD1, 0x20, 0x46, 0x00, 0xF0, 0x37, 0xF8, 0x25, 0xE0,
+ 0x40, 0xF2, 0x01, 0x20, 0xAD, 0xF8, 0x00, 0x00, 0x03, 0x94, 0xC8, 0x8E,
+ 0x4F, 0xF4, 0xDF, 0x73, 0x40, 0x1C, 0xC8, 0x86, 0x13, 0x4A, 0x69, 0x46,
+ 0x98, 0xF8, 0x00, 0x00, 0xF3, 0xF7, 0xB8, 0xFA, 0x05, 0x46, 0x13, 0xE0,
+ 0x97, 0xB9, 0x4F, 0xF4, 0xB3, 0x71, 0x0D, 0xE0, 0x57, 0xB1, 0x0A, 0x70,
+ 0x00, 0x20, 0x48, 0x70, 0xC8, 0x78, 0x01, 0x28, 0x01, 0xD1, 0x07, 0x20,
+ 0x48, 0x70, 0x00, 0xF0, 0xEF, 0xFE, 0x03, 0xE0, 0x40, 0xF2, 0x65, 0x11,
+ 0xF5, 0xF7, 0xB0, 0xF9, 0x06, 0xB0, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x81,
+ 0xD0, 0x10, 0xC0, 0x08, 0x03, 0x3C, 0x10, 0x21, 0xEC, 0x75, 0x20, 0x00,
+ 0x00, 0x3D, 0x28, 0x21, 0x2D, 0xA7, 0x82, 0x00, 0xF9, 0xF7, 0xA9, 0x9E,
+ 0x10, 0xB5, 0x04, 0x46, 0x03, 0x46, 0x01, 0x22, 0x09, 0x49, 0x0A, 0x48,
+ 0xEB, 0xF7, 0xEF, 0xD9, 0x09, 0x4A, 0x0A, 0x48, 0x51, 0x8F, 0x49, 0x1C,
+ 0x51, 0x87, 0x00, 0x78, 0x00, 0x28, 0x20, 0x46, 0x01, 0xD0, 0x07, 0x49,
+ 0x00, 0xE0, 0x07, 0x49, 0x09, 0x68, 0xBD, 0xE8, 0x10, 0x40, 0x08, 0x47,
+ 0xDC, 0x09, 0xC0, 0x08, 0x03, 0x3C, 0x10, 0x21, 0xF0, 0x75, 0x20, 0x00,
+ 0xE8, 0x75, 0x20, 0x00, 0x74, 0x05, 0x20, 0x00, 0x78, 0x05, 0x20, 0x00,
+ 0xF9, 0xF7, 0x71, 0x9E, 0x38, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0x03, 0x46,
+ 0x00, 0x91, 0x02, 0x22, 0x07, 0x49, 0x08, 0x48, 0xEB, 0xF7, 0xC7, 0xD9,
+ 0x07, 0x49, 0x08, 0x4A, 0x88, 0x8E, 0x40, 0x1C, 0x88, 0x86, 0x12, 0x68,
+ 0x01, 0xB0, 0x21, 0x46, 0x28, 0x46, 0xBD, 0xE8, 0x30, 0x40, 0x10, 0x47,
+ 0xBC, 0x09, 0xC0, 0x08, 0x03, 0x3C, 0x10, 0x21, 0xF0, 0x75, 0x20, 0x00,
+ 0x70, 0x05, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x28, 0x4A, 0x29, 0x49,
+ 0x10, 0x1F, 0xF3, 0xF7, 0xFB, 0xF8, 0x00, 0x28, 0x48, 0xD0, 0x25, 0x48,
+ 0x10, 0x30, 0xF3, 0xF7, 0xFC, 0xFC, 0x23, 0x48, 0x18, 0x30, 0xF3, 0xF7,
+ 0xF8, 0xFC, 0x21, 0x4D, 0x00, 0x26, 0x07, 0x20, 0x2E, 0x70, 0x28, 0x72,
+ 0x13, 0x20, 0x68, 0x81, 0x0B, 0x20, 0xA8, 0x81, 0xEE, 0x84, 0x7F, 0x20,
+ 0x85, 0xF8, 0x53, 0x00, 0x85, 0xF8, 0x54, 0x00, 0x05, 0xF1, 0x64, 0x00,
+ 0xF3, 0xF7, 0xE5, 0xFC, 0x19, 0x4F, 0x85, 0xF8, 0x72, 0x60, 0x97, 0xF8,
+ 0x98, 0x01, 0x30, 0xB3, 0x41, 0x01, 0x40, 0xF2, 0xE1, 0x23, 0x16, 0x4A,
+ 0x00, 0x20, 0xF5, 0xF7, 0x17, 0xDF, 0x28, 0x63, 0x00, 0x28, 0x1D, 0xD0,
+ 0x00, 0x24, 0x4F, 0xF0, 0xFF, 0x08, 0x4F, 0xF0, 0x0A, 0x09, 0x4F, 0xF0,
+ 0x0C, 0x0A, 0x10, 0xE0, 0x28, 0x6B, 0x09, 0xEB, 0x44, 0x11, 0x00, 0xEB,
+ 0x44, 0x10, 0x06, 0x70, 0x2A, 0x6B, 0x0A, 0xEB, 0x44, 0x10, 0x02, 0xF8,
+ 0x01, 0x80, 0x29, 0x6B, 0x08, 0x44, 0xF3, 0xF7, 0xBE, 0xFC, 0x64, 0x1C,
+ 0xA4, 0xB2, 0x97, 0xF8, 0x98, 0x01, 0xA0, 0x42, 0xEA, 0xD8, 0x01, 0x20,
+ 0xBD, 0xE8, 0xF0, 0x87, 0xF0, 0x75, 0x20, 0x00, 0x99, 0xC6, 0x81, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x5E, 0xA7, 0x82, 0x00, 0x2D, 0xE9, 0xFC, 0x41,
+ 0x10, 0xF8, 0x01, 0x8B, 0x06, 0x46, 0x00, 0x25, 0x40, 0xE0, 0x23, 0x48,
+ 0x40, 0xF2, 0x54, 0x53, 0x20, 0x4A, 0x2D, 0x21, 0x00, 0x78, 0xF2, 0xF7,
+ 0xDD, 0xFE, 0x04, 0x00, 0x1E, 0xD0, 0x40, 0xF2, 0x3B, 0x10, 0x60, 0x80,
+ 0x70, 0x1C, 0x37, 0x78, 0x10, 0xF8, 0x01, 0x3B, 0x00, 0x21, 0x6A, 0x46,
+ 0x10, 0xF8, 0x01, 0x6B, 0x56, 0x54, 0x49, 0x1C, 0x06, 0x29, 0xF9, 0xD3,
+ 0x10, 0xF8, 0x01, 0x2B, 0x86, 0x18, 0x1F, 0x2A, 0x0C, 0xD9, 0x00, 0x22,
+ 0x14, 0x49, 0x15, 0x48, 0xEB, 0xF7, 0x2D, 0xD9, 0x40, 0xF2, 0x65, 0x52,
+ 0x0F, 0x49, 0x20, 0x46, 0xF2, 0xF7, 0xAA, 0xFF, 0xBD, 0xE8, 0xFC, 0x81,
+ 0x16, 0xF8, 0x01, 0x1B, 0xA3, 0x72, 0xE7, 0x72, 0x21, 0x73, 0x62, 0x73,
+ 0x00, 0x99, 0x61, 0x60, 0xBD, 0xF8, 0x04, 0x10, 0x21, 0x81, 0x01, 0x46,
+ 0x04, 0xF1, 0x0E, 0x00, 0x1D, 0xF4, 0x29, 0xF2, 0x00, 0x21, 0x20, 0x46,
+ 0xF8, 0xF7, 0x8A, 0xF9, 0x6D, 0x1C, 0xED, 0xB2, 0x45, 0x45, 0xBC, 0xD3,
+ 0xE4, 0xE7, 0x00, 0x00, 0xD0, 0xA6, 0x82, 0x00, 0x03, 0x74, 0x20, 0x00,
+ 0x10, 0x0F, 0xC0, 0x08, 0x00, 0x3C, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41,
+ 0x81, 0x78, 0xC2, 0x78, 0x04, 0x78, 0x46, 0x78, 0x01, 0xEB, 0x02, 0x21,
+ 0x07, 0x79, 0x8D, 0xB2, 0x1C, 0xB9, 0x29, 0x46, 0x30, 0x46, 0xF7, 0xF7,
+ 0xB9, 0xFF, 0x20, 0x46, 0xFF, 0xF7, 0x48, 0xFC, 0x3B, 0x46, 0x2A, 0x46,
+ 0x31, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0xF6, 0xF7, 0xEF, 0xBD, 0x01, 0x78,
+ 0x42, 0x78, 0x01, 0xEB, 0x02, 0x21, 0x8A, 0xB2, 0x81, 0x78, 0x10, 0x46,
+ 0xF7, 0xF7, 0xBE, 0xB8, 0x2D, 0xE9, 0xFC, 0x41, 0x0C, 0x46, 0x6F, 0xF4,
+ 0x00, 0x51, 0x00, 0xEB, 0x01, 0x0C, 0xE3, 0x49, 0x00, 0x27, 0xE0, 0x4B,
+ 0xE0, 0x4E, 0x08, 0x78, 0x01, 0xF1, 0x5A, 0x05, 0xBC, 0xF1, 0x4E, 0x0F,
+ 0x7E, 0xD2, 0xDF, 0xE8, 0x0C, 0xF0, 0x92, 0x57, 0x27, 0x94, 0xFC, 0xA9,
+ 0x8A, 0xA9, 0xA9, 0x96, 0xFB, 0xFA, 0x94, 0x94, 0x82, 0xF9, 0xF9, 0xF9,
+ 0xF8, 0xF7, 0xF6, 0x94, 0xF5, 0xF4, 0x94, 0x94, 0x94, 0x3E, 0xF3, 0xF2,
+ 0xF1, 0x94, 0x94, 0xF0, 0x94, 0xEF, 0x94, 0x94, 0xEE, 0xED, 0xEC, 0xEB,
+ 0xEA, 0xE9, 0xE8, 0xE7, 0x94, 0xE6, 0xE5, 0x94, 0xE4, 0xE3, 0xD1, 0xC8,
+ 0xCB, 0xCB, 0xCB, 0xB7, 0xBF, 0xE2, 0xE2, 0x94, 0x94, 0x94, 0xE1, 0xE0,
+ 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0xAE, 0x94, 0x94, 0xDF,
+ 0x02, 0x28, 0x6A, 0xD1, 0x00, 0x2C, 0x2A, 0xD1, 0x00, 0x20, 0x0D, 0x18,
+ 0x12, 0xF8, 0x01, 0x4B, 0x40, 0x1C, 0x85, 0xF8, 0x48, 0x40, 0x08, 0x28,
+ 0xF7, 0xD3, 0xC3, 0x4A, 0x08, 0x21, 0x48, 0x32, 0x18, 0x46, 0xEB, 0xF7,
+ 0x00, 0xDB, 0x03, 0x46, 0x01, 0x22, 0xC0, 0x49, 0x14, 0xE0, 0x02, 0x28,
+ 0x53, 0xD1, 0x00, 0x2C, 0xE7, 0xD1, 0x00, 0x20, 0x69, 0x46, 0x12, 0xF8,
+ 0x01, 0x4B, 0x0C, 0x54, 0x40, 0x1C, 0x08, 0x28, 0xF9, 0xD3, 0x0A, 0x46,
+ 0x08, 0x21, 0x18, 0x46, 0xEB, 0xF7, 0xEB, 0xDA, 0xB6, 0x49, 0x01, 0x22,
+ 0x03, 0x46, 0x30, 0x31, 0x30, 0x46, 0xEB, 0xF7, 0x78, 0xD8, 0x16, 0xE1,
+ 0x02, 0x28, 0x3A, 0xD1, 0x00, 0x2C, 0x25, 0xD1, 0x10, 0x78, 0x53, 0x78,
+ 0x94, 0x78, 0x00, 0xEB, 0x03, 0x20, 0x05, 0x04, 0x2D, 0x0C, 0x06, 0xD0,
+ 0x2C, 0xB1, 0xA1, 0xF8, 0x44, 0x50, 0xA1, 0xF8, 0x42, 0x40, 0xA1, 0xF8,
+ 0x40, 0x40, 0xA9, 0x49, 0xA6, 0x48, 0x2B, 0x46, 0x02, 0x22, 0x5C, 0x31,
+ 0x40, 0x1C, 0x00, 0x94, 0xEB, 0xF7, 0x5B, 0xD8, 0x0D, 0xB1, 0x00, 0x2C,
+ 0x0A, 0xD1, 0xA3, 0x49, 0xA0, 0x48, 0x02, 0x22, 0x90, 0x31, 0x2B, 0x46,
+ 0x80, 0x1E, 0x00, 0xE0, 0x15, 0xE0, 0x00, 0x94, 0xEB, 0xF7, 0x4D, 0xD8,
+ 0xEB, 0xE0, 0x02, 0x28, 0x0F, 0xD1, 0x00, 0x2C, 0x02, 0xD1, 0x10, 0x78,
+ 0x81, 0xF8, 0x50, 0x00, 0xE3, 0xE0, 0x02, 0x28, 0x51, 0xD0, 0x11, 0x78,
+ 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41, 0xF7, 0xF7, 0x33, 0xBC, 0x02, 0x28,
+ 0x49, 0xD0, 0xBD, 0xE8, 0xFC, 0x81, 0x91, 0xF8, 0x60, 0x00, 0x42, 0x07,
+ 0x04, 0xD5, 0x20, 0xF0, 0x04, 0x00, 0x81, 0xF8, 0x60, 0x00, 0xF4, 0xE7,
+ 0x44, 0xB9, 0xC2, 0x07, 0x02, 0xD0, 0x40, 0xF0, 0x02, 0x00, 0x01, 0xE0,
+ 0x20, 0xF0, 0x02, 0x00, 0x81, 0xF8, 0x60, 0x00, 0x20, 0x46, 0xBD, 0xE8,
+ 0xFC, 0x41, 0xFC, 0xF7, 0xD3, 0xBC, 0x02, 0x28, 0xE3, 0xD1, 0x64, 0xBB,
+ 0x10, 0x78, 0x01, 0xF8, 0x53, 0x0F, 0x50, 0x78, 0x48, 0x70, 0xB6, 0xE0,
+ 0x54, 0xB9, 0x10, 0x78, 0x52, 0x78, 0x00, 0xEB, 0x02, 0x20, 0xA1, 0xF8,
+ 0x56, 0x00, 0x03, 0xE0, 0x14, 0xB9, 0x10, 0x78, 0x81, 0xF8, 0x52, 0x00,
+ 0xE0, 0xB2, 0xBD, 0xE8, 0xFC, 0x41, 0xFF, 0xF7, 0xC3, 0xBA, 0x10, 0x78,
+ 0x41, 0xB2, 0x00, 0xE0, 0x00, 0x21, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41,
+ 0xFC, 0xF7, 0xBC, 0xBC, 0x0E, 0x46, 0x2A, 0x46, 0x06, 0xF8, 0x58, 0x7F,
+ 0x20, 0x46, 0x71, 0x78, 0x0D, 0xF0, 0x46, 0xF8, 0x71, 0x78, 0x2A, 0x46,
+ 0x20, 0x46, 0x02, 0xB0, 0x1E, 0xE0, 0x8E, 0xE0, 0xB1, 0xE0, 0x28, 0xE0,
+ 0x23, 0xE0, 0x1D, 0xE0, 0xB5, 0xE0, 0xB0, 0xE0, 0xC9, 0xE0, 0xB6, 0xE0,
+ 0xA5, 0xE0, 0xA0, 0xE0, 0x99, 0xE0, 0x92, 0xE0, 0x7A, 0xE0, 0x8A, 0xE0,
+ 0x86, 0xE0, 0x82, 0xE0, 0x71, 0xE0, 0x66, 0xE0, 0x5B, 0xE0, 0x56, 0xE0,
+ 0x51, 0xE0, 0x41, 0xE0, 0x3B, 0xE0, 0x2D, 0xE0, 0x23, 0xE0, 0x1C, 0xE0,
+ 0x25, 0xE0, 0x16, 0xE0, 0x11, 0xE0, 0x3E, 0xE0, 0xBD, 0xE8, 0xF0, 0x41,
+ 0xF7, 0xF7, 0x58, 0xBD, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41, 0xFC, 0xF7,
+ 0x07, 0xBC, 0x21, 0x46, 0x4F, 0xF4, 0xC6, 0x70, 0xA8, 0xE0, 0x21, 0x46,
+ 0x4F, 0xF4, 0xC7, 0x70, 0xA4, 0xE0, 0x21, 0x46, 0x4F, 0xF4, 0x9D, 0x70,
+ 0xA0, 0xE0, 0x21, 0x46, 0x4F, 0xF4, 0x9C, 0x70, 0x9C, 0xE0, 0x21, 0x46,
+ 0xBD, 0xE8, 0xFC, 0x41, 0x00, 0x20, 0xFC, 0xF7, 0x09, 0xBB, 0x21, 0x46,
+ 0x40, 0xF2, 0x5D, 0x10, 0x92, 0xE0, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41,
+ 0xFC, 0xF7, 0x26, 0xBC, 0x12, 0xF8, 0x01, 0x0B, 0x12, 0xF8, 0x01, 0x1B,
+ 0x02, 0xB0, 0x00, 0xEB, 0x01, 0x20, 0x21, 0x46, 0xBD, 0xE8, 0xF0, 0x41,
+ 0x80, 0xB2, 0xF6, 0xF7, 0x3B, 0xB8, 0x10, 0x46, 0xBD, 0xE8, 0xFC, 0x41,
+ 0x09, 0xF0, 0x12, 0xBF, 0x10, 0x46, 0xBD, 0xE8, 0xFC, 0x41, 0x0A, 0xF0,
+ 0x77, 0xB8, 0x81, 0xF8, 0x58, 0x70, 0x29, 0x46, 0x20, 0x46, 0x0D, 0xF0,
+ 0x2F, 0xF8, 0x21, 0x46, 0x40, 0xF2, 0x69, 0x10, 0x6C, 0xE0, 0x21, 0x46,
+ 0x40, 0xF2, 0x61, 0x10, 0x68, 0xE0, 0x21, 0x46, 0x40, 0xF2, 0x63, 0x10,
+ 0x64, 0xE0, 0x10, 0x78, 0x51, 0x78, 0x00, 0xEB, 0x01, 0x20, 0x81, 0xB2,
+ 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41, 0xF7, 0xF7, 0x18, 0xBE, 0x10, 0x78,
+ 0x51, 0x78, 0x00, 0xEB, 0x01, 0x20, 0x81, 0xB2, 0x20, 0x46, 0xBD, 0xE8,
+ 0xFC, 0x41, 0xF7, 0xF7, 0x30, 0xBD, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41,
+ 0xF7, 0xF7, 0x4A, 0xBE, 0x02, 0x28, 0x7F, 0xF4, 0x34, 0xAF, 0x14, 0xB9,
+ 0x10, 0x78, 0x81, 0xF8, 0x51, 0x00, 0xBD, 0xE8, 0xFC, 0x41, 0x00, 0xF0,
+ 0x3F, 0xBC, 0x21, 0x46, 0x01, 0x20, 0x04, 0xE0, 0x21, 0x46, 0x02, 0x20,
+ 0x01, 0xE0, 0x21, 0x46, 0x00, 0x20, 0xBD, 0xE8, 0xFC, 0x41, 0xF7, 0xF7,
+ 0xD1, 0xBA, 0x11, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41, 0xF7, 0xF7,
+ 0xBB, 0xBB, 0x11, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41, 0xF7, 0xF7,
+ 0x89, 0xBB, 0x21, 0x46, 0x4F, 0xF4, 0xBD, 0x70, 0x24, 0xE0, 0x21, 0x46,
+ 0x4F, 0xF4, 0xBE, 0x70, 0x20, 0xE0, 0x21, 0x46, 0x4F, 0xF4, 0xC0, 0x70,
+ 0x1C, 0xE0, 0x21, 0x46, 0x4F, 0xF4, 0xCA, 0x70, 0x18, 0xE0, 0x21, 0x46,
+ 0x4F, 0xF4, 0xCB, 0x70, 0x14, 0xE0, 0x12, 0xF8, 0x01, 0x0B, 0x12, 0xF8,
+ 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x20, 0x80, 0xB2, 0x34, 0xB1, 0x01, 0x21,
+ 0x0A, 0x46, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x41, 0xF6, 0xF7, 0x06, 0xB8,
+ 0x11, 0x78, 0x52, 0x78, 0xF7, 0xE7, 0x21, 0x46, 0x4F, 0xF4, 0xC8, 0x70,
+ 0xBD, 0xE8, 0xFC, 0x41, 0xF7, 0xF7, 0x2B, 0xBF, 0x00, 0x00, 0x50, 0x21,
+ 0x02, 0x3C, 0x10, 0x21, 0xF0, 0x75, 0x20, 0x00, 0x4C, 0x0D, 0xC0, 0x08,
+ 0xF8, 0xB5, 0x0C, 0x46, 0x06, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22,
+ 0x28, 0x49, 0x29, 0x48, 0xEA, 0xF7, 0x05, 0xDF, 0x42, 0xF2, 0x19, 0x02,
+ 0xB1, 0x1A, 0x27, 0x4D, 0x96, 0x42, 0x29, 0xD0, 0x08, 0xDC, 0xA6, 0xF5,
+ 0x00, 0x50, 0x0D, 0x38, 0x13, 0xD0, 0x06, 0x28, 0x1C, 0xD0, 0x09, 0x28,
+ 0x04, 0xD1, 0x2B, 0xE0, 0x19, 0x29, 0x34, 0xD0, 0x2A, 0x29, 0x0A, 0xD0,
+ 0x01, 0xB0, 0x33, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x1A, 0x49, 0x1B, 0x48,
+ 0x01, 0x22, 0x78, 0x31, 0x40, 0x1E, 0xEA, 0xF7, 0xE6, 0x9E, 0x14, 0xB1,
+ 0x00, 0x20, 0x85, 0xF8, 0x72, 0x00, 0x21, 0x46, 0xBD, 0xE8, 0xF8, 0x40,
+ 0x15, 0x48, 0x28, 0x30, 0xFC, 0xF7, 0x44, 0xBA, 0xE8, 0x8D, 0x21, 0x46,
+ 0xBD, 0xE8, 0xF8, 0x40, 0xFC, 0xF7, 0x2C, 0xBA, 0x00, 0x2C, 0x1A, 0xD0,
+ 0xE0, 0xB2, 0xFF, 0xF7, 0x27, 0xFA, 0x02, 0x46, 0xE8, 0x8D, 0xBD, 0xE8,
+ 0xF8, 0x40, 0x00, 0x21, 0x09, 0xF0, 0xE8, 0xBD, 0x00, 0x2C, 0x0E, 0xD0,
+ 0xBD, 0xE8, 0xF8, 0x40, 0x06, 0x49, 0x07, 0x48, 0x00, 0x22, 0x38, 0x31,
+ 0x80, 0x1E, 0xEA, 0xF7, 0xBE, 0x9E, 0xE8, 0x8D, 0x21, 0x46, 0xBD, 0xE8,
+ 0xF8, 0x40, 0xF6, 0xF7, 0x48, 0xB8, 0xF8, 0xBD, 0x14, 0x0E, 0xC0, 0x08,
+ 0x02, 0x3C, 0x10, 0x21, 0xF0, 0x75, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x4F,
+ 0x93, 0xB0, 0x4F, 0xF0, 0x00, 0x0A, 0x89, 0x46, 0x04, 0x46, 0x55, 0x46,
+ 0xCD, 0xF8, 0x44, 0xA0, 0xCD, 0xF8, 0x48, 0xA0, 0x24, 0x21, 0x06, 0xA8,
+ 0xCD, 0xF8, 0x00, 0xA0, 0x1D, 0xF4, 0x54, 0xF0, 0x8D, 0xF8, 0x14, 0x50,
+ 0x14, 0xF8, 0x01, 0x1B, 0x0D, 0xF1, 0x3C, 0x0B, 0x14, 0xF8, 0x01, 0x0B,
+ 0x14, 0xF8, 0x02, 0x2B, 0x00, 0xEB, 0x02, 0x20, 0x14, 0xF8, 0x01, 0x5C,
+ 0x87, 0xB2, 0x14, 0xF8, 0x01, 0x8B, 0x00, 0x20, 0x14, 0xF8, 0x01, 0x3B,
+ 0x0B, 0xF8, 0x00, 0x30, 0x40, 0x1C, 0x06, 0x28, 0xF8, 0xD3, 0x08, 0x46,
+ 0xFF, 0xF7, 0xDA, 0xF9, 0x06, 0x46, 0xB9, 0xF1, 0x0A, 0x0F, 0x0E, 0xD0,
+ 0xCD, 0xF8, 0x27, 0xA0, 0xAD, 0xF8, 0x2B, 0xA0, 0xCD, 0xF8, 0x2D, 0xA0,
+ 0xAD, 0xF8, 0x31, 0xA0, 0xDF, 0xF8, 0x7C, 0x91, 0x99, 0xF8, 0x72, 0x00,
+ 0x18, 0xB3, 0x95, 0xB1, 0x21, 0xE0, 0x00, 0x20, 0x06, 0xA9, 0x0B, 0x18,
+ 0x14, 0xF8, 0x01, 0x2B, 0x40, 0x1C, 0xDA, 0x73, 0x06, 0x28, 0xF8, 0xD3,
+ 0x00, 0x20, 0x0B, 0x18, 0x14, 0xF8, 0x01, 0x2B, 0x40, 0x1C, 0x5A, 0x75,
+ 0x06, 0x28, 0xF8, 0xD3, 0xE6, 0xE7, 0x53, 0x48, 0x06, 0x22, 0x6C, 0x30,
+ 0x0F, 0xA9, 0x01, 0x90, 0x1C, 0xF4, 0x20, 0xF7, 0x28, 0xB1, 0x06, 0x22,
+ 0x11, 0xA9, 0x01, 0x98, 0x1C, 0xF4, 0x1A, 0xF7, 0x08, 0xB9, 0x89, 0xF8,
+ 0x72, 0xA0, 0x16, 0xB1, 0x3C, 0x2E, 0x65, 0xD0, 0x6A, 0xE0, 0x0F, 0xA8,
+ 0xFF, 0xF7, 0xA4, 0xF9, 0xA8, 0xB1, 0x0F, 0xAA, 0x06, 0x21, 0x47, 0x48,
+ 0xEB, 0xF7, 0xAD, 0xD8, 0x00, 0x90, 0x3B, 0x46, 0x02, 0x22, 0x45, 0x49,
+ 0x45, 0x48, 0xEA, 0xF7, 0x3A, 0xDE, 0x48, 0x46, 0x10, 0xF8, 0x60, 0x1F,
+ 0x41, 0xF0, 0x08, 0x01, 0x01, 0x70, 0xA9, 0xF8, 0x62, 0x70, 0x13, 0x21,
+ 0x0B, 0xE0, 0x41, 0x46, 0x0F, 0xA8, 0xFE, 0xF7, 0x1F, 0xFA, 0x28, 0xB1,
+ 0x85, 0x72, 0x47, 0x80, 0x4D, 0xB1, 0x01, 0x2D, 0x0A, 0xD0, 0x15, 0xE0,
+ 0x14, 0x21, 0x38, 0x46, 0xFE, 0xF7, 0x8E, 0xFB, 0x13, 0xB0, 0xBD, 0xE8,
+ 0xF0, 0x8F, 0xF7, 0xF7, 0xE7, 0xF8, 0x09, 0xE0, 0x05, 0xA9, 0x38, 0x46,
+ 0xF7, 0xF7, 0xE8, 0xF8, 0x10, 0xB1, 0x01, 0x20, 0x00, 0x90, 0x03, 0xE0,
+ 0xF7, 0xF7, 0xD6, 0xF8, 0x8D, 0xF8, 0x14, 0x00, 0x8D, 0xF8, 0x18, 0x50,
+ 0x9D, 0xF8, 0x14, 0x00, 0x8D, 0xF8, 0x19, 0x00, 0x8D, 0xF8, 0x20, 0x80,
+ 0x0F, 0x98, 0xCD, 0xF8, 0x1A, 0x00, 0xBD, 0xF8, 0x40, 0x00, 0xAD, 0xF8,
+ 0x1E, 0x00, 0x0F, 0x99, 0xCD, 0xF8, 0x21, 0x10, 0xAD, 0xF8, 0x25, 0x00,
+ 0x20, 0x78, 0x61, 0x78, 0x00, 0xEB, 0x01, 0x20, 0xAD, 0xF8, 0x34, 0x00,
+ 0xA0, 0x78, 0xE1, 0x78, 0x00, 0xEB, 0x01, 0x20, 0xAD, 0xF8, 0x36, 0x00,
+ 0x20, 0x79, 0x61, 0x79, 0x00, 0xEB, 0x01, 0x20, 0xAD, 0xF8, 0x38, 0x00,
+ 0xA0, 0x79, 0x8D, 0xF8, 0x3A, 0x00, 0x05, 0xE0, 0x99, 0xF8, 0x60, 0x10,
+ 0x21, 0xF0, 0x02, 0x01, 0x89, 0xF8, 0x60, 0x10, 0xF3, 0xB2, 0x2A, 0x46,
+ 0x39, 0x46, 0x0F, 0xA8, 0x01, 0xF0, 0x42, 0xFC, 0x06, 0xAB, 0x39, 0x46,
+ 0x30, 0x46, 0x00, 0x9A, 0x09, 0xF0, 0x1E, 0xFC, 0xBD, 0xF8, 0x38, 0x00,
+ 0xBD, 0xF8, 0x36, 0x10, 0xBD, 0xF8, 0x34, 0x20, 0xCD, 0xF8, 0x00, 0x80,
+ 0xCD, 0xE9, 0x03, 0x10, 0xCD, 0xE9, 0x01, 0xB2, 0x9D, 0xF8, 0x19, 0x30,
+ 0x2A, 0x46, 0x31, 0x46, 0x38, 0x46, 0xFC, 0xF7, 0x53, 0xF8, 0x00, 0x2E,
+ 0x9C, 0xD1, 0x38, 0x46, 0xFE, 0xF7, 0xCA, 0xFC, 0x38, 0x46, 0xFE, 0xF7,
+ 0xD0, 0xFC, 0x95, 0xE7, 0xF0, 0x75, 0x20, 0x00, 0x00, 0x00, 0x50, 0x21,
+ 0xC0, 0x0E, 0xC0, 0x08, 0x00, 0x3C, 0x10, 0x21, 0xF8, 0xB5, 0x42, 0x78,
+ 0x83, 0x78, 0x01, 0x78, 0x02, 0xEB, 0x03, 0x22, 0x96, 0xB2, 0xC2, 0x78,
+ 0x03, 0x79, 0x02, 0xEB, 0x03, 0x22, 0x95, 0xB2, 0x42, 0x79, 0x83, 0x79,
+ 0x02, 0xEB, 0x03, 0x22, 0x94, 0xB2, 0xC2, 0x79, 0x00, 0x7A, 0x02, 0xEB,
+ 0x00, 0x20, 0x87, 0xB2, 0x08, 0x46, 0xFF, 0xF7, 0xED, 0xF8, 0x01, 0x46,
+ 0x23, 0x46, 0x2A, 0x46, 0x30, 0x46, 0x00, 0x97, 0xFC, 0xF7, 0xB3, 0xF8,
+ 0xF8, 0xBD, 0x38, 0xB5, 0x01, 0x78, 0x42, 0x78, 0x43, 0x79, 0x01, 0xEB,
+ 0x02, 0x21, 0x8C, 0xB2, 0x81, 0x78, 0xC2, 0x78, 0xC5, 0x79, 0x01, 0xEB,
+ 0x02, 0x21, 0x02, 0x79, 0x89, 0xB2, 0x02, 0xEB, 0x03, 0x22, 0x83, 0x79,
+ 0x92, 0xB2, 0x03, 0xEB, 0x05, 0x23, 0x05, 0x7A, 0x40, 0x7A, 0x9B, 0xB2,
+ 0x05, 0xEB, 0x00, 0x20, 0x80, 0xB2, 0x00, 0x90, 0x20, 0x46, 0xF6, 0xF7,
+ 0x72, 0xFD, 0x38, 0xBD, 0xF0, 0xB5, 0x87, 0xB0, 0x10, 0xF8, 0x01, 0x6B,
+ 0x04, 0x46, 0x00, 0x25, 0x04, 0xAF, 0x20, 0xE0, 0x14, 0xF8, 0x01, 0x0B,
+ 0x00, 0x22, 0x14, 0xF8, 0x01, 0x1B, 0x02, 0xAB, 0x14, 0xF8, 0x01, 0xCB,
+ 0x03, 0xF8, 0x02, 0xC0, 0x52, 0x1C, 0x06, 0x2A, 0xF8, 0xD3, 0x14, 0xF8,
+ 0x01, 0x3B, 0x00, 0x22, 0x14, 0xF8, 0x01, 0xCB, 0x07, 0xF8, 0x02, 0xC0,
+ 0x52, 0x1C, 0x06, 0x2A, 0xF8, 0xD3, 0x14, 0xF8, 0x01, 0x2B, 0x52, 0xB2,
+ 0xCD, 0xE9, 0x00, 0x72, 0x02, 0xAA, 0xF6, 0xF7, 0x83, 0xFD, 0x6D, 0x1C,
+ 0xED, 0xB2, 0xB5, 0x42, 0xDC, 0xD3, 0x07, 0xB0, 0xF0, 0xBD, 0x70, 0xB5,
+ 0x04, 0x46, 0x0D, 0x46, 0x08, 0x46, 0xFF, 0xF7, 0x93, 0xF8, 0x01, 0x46,
+ 0x20, 0x46, 0x01, 0xF0, 0x09, 0xFB, 0x20, 0x46, 0x09, 0xF0, 0x30, 0xFC,
+ 0x28, 0x46, 0xFF, 0xF7, 0x89, 0xF8, 0x01, 0x46, 0x20, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0xFC, 0xF7, 0xB9, 0xB8, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x4F,
+ 0x91, 0xB0, 0x10, 0xF8, 0x01, 0x1B, 0x04, 0x46, 0x00, 0x25, 0x0E, 0xAE,
+ 0x0D, 0x91, 0x4F, 0xE0, 0x14, 0xF8, 0x01, 0x0B, 0x14, 0xF8, 0x01, 0x1B,
+ 0x00, 0xEB, 0x01, 0x20, 0xC0, 0xF3, 0x41, 0x1E, 0x00, 0xF0, 0x1F, 0x00,
+ 0x0C, 0x90, 0x14, 0xF8, 0x01, 0xBB, 0x00, 0x20, 0x0A, 0xA9, 0x14, 0xF8,
+ 0x01, 0x2B, 0x0A, 0x54, 0x40, 0x1C, 0x06, 0x28, 0xF9, 0xD3, 0x14, 0xF8,
+ 0x01, 0xAB, 0x14, 0xF8, 0x01, 0x9B, 0x14, 0xF8, 0x02, 0x8B, 0x14, 0xF9,
+ 0x01, 0x7C, 0x14, 0xF9, 0x04, 0x3B, 0x14, 0xF8, 0x03, 0x0C, 0x14, 0xF8,
+ 0x02, 0x1C, 0x00, 0xEB, 0x01, 0x20, 0x82, 0xB2, 0x14, 0xF8, 0x01, 0x1C,
+ 0x00, 0x20, 0x14, 0xF8, 0x01, 0xCB, 0x06, 0xF8, 0x00, 0xC0, 0x40, 0x1C,
+ 0x06, 0x28, 0xF8, 0xD3, 0x14, 0xF8, 0x01, 0x0B, 0xA4, 0x46, 0x04, 0x44,
+ 0xE5, 0x28, 0x07, 0xD9, 0x00, 0x22, 0x0E, 0x49, 0x0E, 0x48, 0xEA, 0xF7,
+ 0xE6, 0xDC, 0x11, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xCD, 0xE9, 0x04, 0x32,
+ 0xCD, 0xE9, 0x06, 0x16, 0xCD, 0xE9, 0x08, 0x0C, 0xCD, 0xE9, 0x02, 0x87,
+ 0xCD, 0xE9, 0x00, 0xA9, 0x0A, 0xAB, 0x5A, 0x46, 0x71, 0x46, 0x0C, 0x98,
+ 0xF6, 0xF7, 0x9A, 0xFE, 0x6D, 0x1C, 0xED, 0xB2, 0x0D, 0x98, 0x85, 0x42,
+ 0xAC, 0xD3, 0xE6, 0xE7, 0x40, 0x0F, 0xC0, 0x08, 0x00, 0x3C, 0x10, 0x21,
+ 0x1C, 0xB5, 0x10, 0xF8, 0x01, 0x1B, 0x6B, 0x46, 0x10, 0xF8, 0x01, 0x2B,
+ 0x01, 0xEB, 0x02, 0x21, 0x8A, 0xB2, 0x00, 0x21, 0x10, 0xF8, 0x01, 0x4B,
+ 0x5C, 0x54, 0x49, 0x1C, 0x08, 0x29, 0xF9, 0xD3, 0x01, 0x78, 0x40, 0x78,
+ 0x01, 0xEB, 0x00, 0x20, 0x80, 0xB2, 0x19, 0x46, 0x09, 0xF0, 0x32, 0xFD,
+ 0x1C, 0xBD, 0x70, 0xB5, 0x42, 0x78, 0x83, 0x78, 0x01, 0x78, 0x02, 0xEB,
+ 0x03, 0x22, 0xC5, 0x78, 0x06, 0x79, 0x94, 0xB2, 0x08, 0x46, 0xFE, 0xF7,
+ 0xFB, 0xFF, 0x33, 0x46, 0x2A, 0x46, 0x21, 0x46, 0xBD, 0xE8, 0x70, 0x40,
+ 0xF7, 0xF7, 0x58, 0xB8, 0x70, 0xB5, 0x10, 0xF8, 0x01, 0x5B, 0x10, 0xF8,
+ 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B, 0x04, 0x46, 0x01, 0xEB, 0x02, 0x21,
+ 0x8E, 0xB2, 0x30, 0x46, 0xFF, 0xF7, 0x0E, 0xF8, 0x01, 0x00, 0x11, 0xD0,
+ 0x3D, 0xB9, 0x00, 0x20, 0x0B, 0x18, 0x14, 0xF8, 0x01, 0x2B, 0x40, 0x1C,
+ 0x9A, 0x75, 0x08, 0x28, 0xF8, 0xD3, 0x28, 0x46, 0xFE, 0xF7, 0xD8, 0xFF,
+ 0x01, 0x46, 0x30, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xF7, 0xF7, 0x2C, 0xB9,
+ 0x70, 0xBD, 0x7C, 0xB5, 0x10, 0xF8, 0x01, 0x4B, 0x00, 0x22, 0x10, 0xF8,
+ 0x01, 0x1B, 0x6B, 0x46, 0x10, 0xF8, 0x01, 0x5B, 0x9D, 0x54, 0x52, 0x1C,
+ 0x06, 0x2A, 0xF9, 0xD3, 0x1A, 0x46, 0x20, 0x46, 0xF7, 0xF7, 0x84, 0xF9,
+ 0x7C, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xFC, 0x41, 0x10, 0xF8, 0x01, 0x5B,
+ 0x04, 0x46, 0xDF, 0xF8, 0x40, 0x80, 0x18, 0xE0, 0x14, 0xF8, 0x01, 0x0B,
+ 0x14, 0xF8, 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x20, 0x86, 0xB2, 0x14, 0xF8,
+ 0x01, 0x0B, 0x14, 0xF8, 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x20, 0x87, 0xB2,
+ 0x30, 0x46, 0xFE, 0xF7, 0xCD, 0xFF, 0xCD, 0xE9, 0x00, 0x70, 0x33, 0x46,
+ 0x03, 0x22, 0x05, 0x49, 0x40, 0x46, 0xEA, 0xF7, 0x46, 0xDC, 0x6D, 0x1E,
+ 0xED, 0xB2, 0xE3, 0xD2, 0xBD, 0xE8, 0xFC, 0x81, 0x02, 0x3C, 0x10, 0x21,
+ 0xFC, 0x0C, 0xC0, 0x08, 0x7C, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0xFE, 0xF7,
+ 0x95, 0xFF, 0x48, 0xB1, 0x41, 0x88, 0x40, 0xF2, 0x1D, 0x40, 0xFE, 0xF7,
+ 0x37, 0xFE, 0x00, 0x28, 0x0C, 0xD1, 0x4F, 0xF4, 0xB4, 0x70, 0x01, 0xE0,
+ 0x4F, 0xF4, 0x89, 0x70, 0x00, 0x21, 0x00, 0x91, 0x0B, 0x46, 0x01, 0x91,
+ 0x22, 0x46, 0x29, 0x46, 0xF7, 0xF7, 0x9E, 0xFB, 0x7C, 0xBD, 0x00, 0x00,
+ 0x2D, 0xE9, 0xFC, 0x47, 0x41, 0x78, 0x82, 0x78, 0x90, 0xF8, 0x00, 0x90,
+ 0x01, 0xEB, 0x02, 0x21, 0x8D, 0xB2, 0x01, 0x79, 0x42, 0x79, 0x90, 0xF8,
+ 0x03, 0x80, 0x01, 0xEB, 0x02, 0x21, 0x8C, 0xB2, 0x81, 0x79, 0xC0, 0x79,
+ 0x01, 0xEB, 0x00, 0x20, 0x87, 0xB2, 0x28, 0x46, 0xFE, 0xF7, 0x88, 0xFF,
+ 0x06, 0x00, 0x0B, 0xD0, 0x48, 0x46, 0xFE, 0xF7, 0x5B, 0xFF, 0xCD, 0xE9,
+ 0x00, 0x47, 0x72, 0x78, 0x43, 0x46, 0x31, 0x1D, 0xF7, 0xF7, 0x78, 0xFB,
+ 0xBD, 0xE8, 0xFC, 0x87, 0x02, 0xB0, 0x2B, 0x46, 0xBD, 0xE8, 0xF0, 0x47,
+ 0x01, 0x22, 0x02, 0x49, 0x02, 0x48, 0xEA, 0xF7, 0xF2, 0x9B, 0x00, 0x00,
+ 0x8C, 0x0C, 0xC0, 0x08, 0x00, 0x3C, 0x10, 0x21, 0x70, 0xB5, 0x0C, 0x46,
+ 0x05, 0x46, 0xFE, 0xF7, 0x45, 0xFF, 0x48, 0xB1, 0x41, 0x88, 0x41, 0xF2,
+ 0x05, 0x40, 0xFE, 0xF7, 0xE7, 0xFD, 0x00, 0x28, 0x0B, 0xD1, 0x4F, 0xF4,
+ 0xB4, 0x70, 0x01, 0xE0, 0x4F, 0xF4, 0x89, 0x70, 0x22, 0x46, 0x29, 0x46,
+ 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x23, 0xF7, 0xF7, 0x7D, 0xBB, 0x70, 0xBD,
+ 0x08, 0x49, 0x10, 0xB5, 0x01, 0x20, 0xC8, 0x70, 0x07, 0x48, 0xFF, 0xF7,
+ 0xF9, 0xF9, 0x00, 0x28, 0x06, 0xD1, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0x22,
+ 0x04, 0x49, 0x05, 0x48, 0xEA, 0xF7, 0xC3, 0x9B, 0x10, 0xBD, 0x00, 0x00,
+ 0xF0, 0x75, 0x20, 0x00, 0x55, 0xCB, 0x81, 0x00, 0xAC, 0x11, 0xC0, 0x08,
+ 0x00, 0x3C, 0x10, 0x21, 0x70, 0xB5, 0x05, 0x46, 0xFE, 0xF7, 0x34, 0xFF,
+ 0x04, 0x00, 0x14, 0xD0, 0x20, 0x7D, 0xC0, 0x06, 0x11, 0xD5, 0x00, 0x22,
+ 0x08, 0x49, 0x09, 0x48, 0xEA, 0xF7, 0xAB, 0xDB, 0x20, 0x7D, 0x20, 0xF0,
+ 0x10, 0x00, 0x20, 0x75, 0x61, 0x7D, 0x28, 0x46, 0xFF, 0xF7, 0x61, 0xFE,
+ 0x20, 0x1D, 0xBD, 0xE8, 0x70, 0x40, 0xFE, 0xF7, 0x37, 0xBF, 0x70, 0xBD,
+ 0x68, 0x09, 0xC0, 0x08, 0x01, 0x3C, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x47,
+ 0xDF, 0xF8, 0xE4, 0x80, 0x05, 0x46, 0x8A, 0x46, 0x98, 0xF8, 0x08, 0x00,
+ 0x17, 0x1D, 0xC1, 0x19, 0x37, 0x48, 0x16, 0x46, 0x86, 0xB0, 0x4F, 0xF4,
+ 0x8E, 0x73, 0x34, 0x4A, 0x00, 0x78, 0xF2, 0xF7, 0x1B, 0xF9, 0x04, 0x00,
+ 0x33, 0xD0, 0x98, 0xF8, 0x08, 0x00, 0x4F, 0xF0, 0x01, 0x09, 0x20, 0x44,
+ 0x29, 0x0A, 0x00, 0xF8, 0x01, 0x9B, 0x00, 0xF8, 0x01, 0x5B, 0x00, 0xF8,
+ 0x02, 0x1B, 0xBA, 0xF1, 0x00, 0x01, 0x00, 0xF8, 0x01, 0x6C, 0x03, 0xD0,
+ 0x16, 0xB1, 0x32, 0x46, 0x1C, 0xF4, 0x83, 0xF4, 0x4F, 0xF4, 0x00, 0x70,
+ 0xAD, 0xF8, 0x00, 0x00, 0x03, 0x94, 0x98, 0xF8, 0x08, 0x00, 0xAD, 0xF8,
+ 0x06, 0x00, 0x42, 0xF2, 0x16, 0x01, 0x68, 0x1A, 0xAD, 0xF8, 0x04, 0x90,
+ 0xAD, 0xF8, 0x08, 0x70, 0x8D, 0x42, 0x24, 0xD0, 0x0F, 0xDC, 0xA5, 0xF5,
+ 0x80, 0x65, 0x1D, 0x3D, 0x1F, 0xD0, 0x05, 0xF5, 0x82, 0x65, 0xB5, 0xF5,
+ 0x00, 0x55, 0x13, 0xD0, 0x06, 0x2D, 0x0A, 0xD1, 0x17, 0xE0, 0x00, 0x20,
+ 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x03, 0x28, 0x11, 0xD0, 0x1C, 0x28,
+ 0x0F, 0xD0, 0x2D, 0x28, 0x06, 0xD0, 0x11, 0x48, 0x40, 0xF2, 0x4F, 0x13,
+ 0x10, 0x4A, 0x69, 0x46, 0x10, 0x30, 0x0C, 0xE0, 0x0D, 0x48, 0x4F, 0xF4,
+ 0x9D, 0x73, 0x0D, 0x4A, 0x69, 0x46, 0x64, 0x30, 0x05, 0xE0, 0x0A, 0x48,
+ 0x40, 0xF2, 0x4B, 0x13, 0x09, 0x4A, 0x69, 0x46, 0x18, 0x30, 0xF2, 0xF7,
+ 0xFD, 0xFE, 0x05, 0x00, 0x05, 0xD1, 0x40, 0xF2, 0x55, 0x12, 0x05, 0x49,
+ 0x20, 0x46, 0xF2, 0xF7, 0xAB, 0xF9, 0x00, 0xF0, 0xC9, 0xF8, 0x28, 0x46,
+ 0xD4, 0xE7, 0x00, 0x00, 0xF0, 0x75, 0x20, 0x00, 0x75, 0xA7, 0x82, 0x00,
+ 0x00, 0x74, 0x20, 0x00, 0x7C, 0xB5, 0x35, 0x4D, 0x35, 0x4C, 0x01, 0x22,
+ 0x35, 0x49, 0x63, 0x78, 0x28, 0x46, 0xEA, 0xF7, 0x14, 0xDB, 0x61, 0x78,
+ 0x48, 0x1C, 0x60, 0x70, 0x12, 0x29, 0xF4, 0xD2, 0xDF, 0xE8, 0x01, 0xF0,
+ 0x09, 0x09, 0x0A, 0x0D, 0x10, 0x13, 0x16, 0x19, 0x25, 0x28, 0x2B, 0x2E,
+ 0x31, 0x09, 0x09, 0x37, 0x3B, 0x3F, 0xE8, 0xE7, 0x41, 0xF2, 0x09, 0x00,
+ 0x25, 0xE0, 0x41, 0xF2, 0x02, 0x00, 0x22, 0xE0, 0x41, 0xF2, 0x05, 0x00,
+ 0x1F, 0xE0, 0x41, 0xF2, 0x01, 0x00, 0x1C, 0xE0, 0x41, 0xF2, 0x03, 0x00,
+ 0x19, 0xE0, 0x60, 0x79, 0x06, 0x28, 0xD6, 0xD3, 0x22, 0xA0, 0xD0, 0xE9,
+ 0x00, 0x10, 0xCD, 0xE9, 0x00, 0x10, 0x68, 0x46, 0xFE, 0xF7, 0x6B, 0xFC,
+ 0x7C, 0xBD, 0x42, 0xF2, 0x03, 0x00, 0x0A, 0xE0, 0x42, 0xF2, 0x1C, 0x00,
+ 0x07, 0xE0, 0x42, 0xF2, 0x02, 0x00, 0x04, 0xE0, 0x42, 0xF2, 0x0F, 0x00,
+ 0x01, 0xE0, 0x42, 0xF2, 0x2A, 0x00, 0xBD, 0xE8, 0x7C, 0x40, 0xFE, 0xF7,
+ 0x54, 0xBC, 0xBD, 0xE8, 0x7C, 0x40, 0xFE, 0xF7, 0xEF, 0xB9, 0xBD, 0xE8,
+ 0x7C, 0x40, 0xFE, 0xF7, 0x8C, 0xBA, 0xE0, 0x78, 0x03, 0x25, 0x01, 0x28,
+ 0x10, 0xD0, 0x0D, 0x48, 0x00, 0x21, 0x20, 0x30, 0x06, 0x46, 0xF4, 0xF7,
+ 0x6D, 0xFA, 0xB4, 0xF8, 0x44, 0x10, 0x00, 0x20, 0x02, 0xF0, 0xEC, 0xF9,
+ 0x25, 0x70, 0x30, 0x46, 0xBD, 0xE8, 0x7C, 0x40, 0x08, 0xF0, 0x36, 0xB9,
+ 0x25, 0x70, 0x00, 0x20, 0xE0, 0x70, 0xBD, 0xE8, 0x7C, 0x40, 0xF7, 0xF7,
+ 0x7C, 0xBB, 0x00, 0x00, 0x03, 0x3C, 0x10, 0x21, 0xF0, 0x75, 0x20, 0x00,
+ 0x6C, 0x12, 0xC0, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D,
+ 0x70, 0xB5, 0x11, 0x4D, 0x06, 0x46, 0x0C, 0x46, 0x95, 0xF8, 0x58, 0x00,
+ 0x28, 0xB1, 0x0A, 0x46, 0x31, 0x46, 0x4F, 0xF4, 0x86, 0x70, 0xF7, 0xF7,
+ 0x25, 0xF8, 0x21, 0x46, 0x30, 0x46, 0xFE, 0xF7, 0x29, 0xFA, 0x48, 0xB1,
+ 0x02, 0x20, 0x05, 0xF8, 0x58, 0x0F, 0x6E, 0x70, 0x20, 0x68, 0xC5, 0xF8,
+ 0x02, 0x00, 0xA0, 0x88, 0xE8, 0x80, 0x70, 0xBD, 0x22, 0x46, 0x31, 0x46,
+ 0xBD, 0xE8, 0x70, 0x40, 0x4F, 0xF4, 0xB4, 0x70, 0xF7, 0xF7, 0x0E, 0xB8,
+ 0xF0, 0x75, 0x20, 0x00, 0x70, 0xB5, 0x10, 0x4C, 0x05, 0x46, 0x40, 0xF2,
+ 0x69, 0x16, 0x94, 0xF8, 0x58, 0x00, 0x20, 0xB1, 0x4F, 0xF4, 0x86, 0x71,
+ 0x30, 0x46, 0xF7, 0xF7, 0x88, 0xFA, 0x28, 0x46, 0xFE, 0xF7, 0x6E, 0xFB,
+ 0x40, 0xB1, 0x01, 0x20, 0x04, 0xF8, 0x58, 0x0F, 0x28, 0x68, 0xC4, 0xF8,
+ 0x02, 0x00, 0xA8, 0x88, 0xE0, 0x80, 0x70, 0xBD, 0x30, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0x4F, 0xF4, 0xB4, 0x71, 0xF7, 0xF7, 0x74, 0xBA, 0x00, 0x00,
+ 0xF0, 0x75, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x5B, 0x4C, 0x86, 0xB0,
+ 0x04, 0xF1, 0x10, 0x08, 0x42, 0xF2, 0x0D, 0x06, 0x42, 0xF2, 0x43, 0x05,
+ 0x80, 0xE0, 0xE0, 0x8C, 0x10, 0xB1, 0x40, 0xF2, 0x19, 0x23, 0x16, 0xE0,
+ 0x94, 0xF8, 0x72, 0x00, 0x40, 0xB9, 0x53, 0x48, 0x40, 0xF2, 0x21, 0x23,
+ 0x52, 0x4A, 0x69, 0x46, 0x64, 0x30, 0xF2, 0xF7, 0xE5, 0xFD, 0x80, 0xB9,
+ 0x4E, 0x48, 0x4F, 0xF4, 0x09, 0x73, 0x4E, 0x4A, 0x69, 0x46, 0x18, 0x30,
+ 0xF2, 0xF7, 0xDC, 0xFD, 0x38, 0xB9, 0x40, 0xF2, 0x26, 0x23, 0x4A, 0x4A,
+ 0x69, 0x46, 0x40, 0x46, 0xF2, 0xF7, 0xD4, 0xFD, 0x90, 0xB3, 0xBD, 0xF8,
+ 0x00, 0x00, 0xB0, 0xF5, 0x00, 0x7F, 0x59, 0xD1, 0xBD, 0xF8, 0x06, 0x10,
+ 0x03, 0x98, 0x42, 0x18, 0x12, 0xF8, 0x01, 0x0F, 0x51, 0x78, 0x92, 0x1C,
+ 0x00, 0xEB, 0x01, 0x20, 0x80, 0xB2, 0xA0, 0xF5, 0x40, 0x61, 0x35, 0x39,
+ 0x02, 0xD0, 0x21, 0x79, 0x49, 0x1E, 0x21, 0x71, 0xB0, 0x42, 0x0B, 0xD1,
+ 0x00, 0x21, 0xE0, 0x84, 0xD2, 0x1D, 0x67, 0x18, 0x12, 0xF8, 0x01, 0x3B,
+ 0x49, 0x1C, 0x87, 0xF8, 0x28, 0x30, 0x06, 0x29, 0xF7, 0xD3, 0x28, 0xE0,
+ 0xA8, 0x42, 0x0C, 0xD1, 0x00, 0x21, 0xE0, 0x84, 0x12, 0x1D, 0x67, 0x18,
+ 0x12, 0xF8, 0x01, 0x3B, 0x49, 0x1C, 0x87, 0xF8, 0x28, 0x30, 0x06, 0x29,
+ 0xF7, 0xD3, 0x1A, 0xE0, 0x2E, 0xE0, 0xA0, 0xF5, 0x80, 0x61, 0x1D, 0x39,
+ 0x0F, 0xD0, 0xA0, 0xF5, 0x00, 0x51, 0x13, 0x39, 0x0B, 0xD0, 0xA0, 0xF5,
+ 0x00, 0x51, 0x16, 0x39, 0x07, 0xD0, 0xA0, 0xF5, 0x00, 0x51, 0x32, 0x39,
+ 0x03, 0xD0, 0xA0, 0xF5, 0x00, 0x51, 0x19, 0x39, 0x05, 0xD1, 0xE0, 0x84,
+ 0x51, 0x78, 0x92, 0x78, 0x01, 0xEB, 0x02, 0x21, 0xE1, 0x85, 0xB0, 0x42,
+ 0x01, 0xD0, 0xA8, 0x42, 0x09, 0xD1, 0x01, 0x20, 0x84, 0xF8, 0x72, 0x00,
+ 0x1B, 0x48, 0x00, 0x1F, 0xC1, 0x6A, 0x01, 0x67, 0x01, 0x8E, 0xA0, 0xF8,
+ 0x74, 0x10, 0x68, 0x46, 0x00, 0xF0, 0x4E, 0xF8, 0x20, 0x79, 0x00, 0x28,
+ 0x7F, 0xF4, 0x7B, 0xAF, 0xB4, 0xF8, 0x46, 0x00, 0x00, 0x28, 0x21, 0xD0,
+ 0x00, 0x25, 0x40, 0xF2, 0x86, 0x28, 0x13, 0x4F, 0x26, 0x6B, 0x17, 0xE0,
+ 0x06, 0xEB, 0x45, 0x10, 0x01, 0x78, 0x89, 0xB1, 0xB4, 0xF8, 0x40, 0x10,
+ 0x71, 0xB1, 0x43, 0x46, 0x0C, 0x4A, 0x69, 0x46, 0x0C, 0x30, 0xF2, 0xF7,
+ 0x59, 0xFD, 0x38, 0xB1, 0x68, 0x46, 0x00, 0xF0, 0x2F, 0xF8, 0xB4, 0xF8,
+ 0x40, 0x00, 0x40, 0x1E, 0xA4, 0xF8, 0x40, 0x00, 0x6D, 0x1C, 0xED, 0xB2,
+ 0x97, 0xF8, 0x98, 0x01, 0xA8, 0x42, 0xE3, 0xD8, 0x06, 0xB0, 0xBD, 0xE8,
+ 0xF0, 0x81, 0x00, 0x00, 0xF0, 0x75, 0x20, 0x00, 0x47, 0xA7, 0x82, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x08, 0x48, 0x10, 0xB5, 0x01, 0x21, 0x01, 0x70,
+ 0x01, 0x71, 0x07, 0x48, 0xFE, 0xF7, 0xC2, 0xFF, 0x08, 0xB1, 0x01, 0x20,
+ 0x10, 0xBD, 0x00, 0x22, 0x04, 0x49, 0x05, 0x48, 0xEA, 0xF7, 0x8D, 0xD9,
+ 0x00, 0x20, 0x10, 0xBD, 0xF0, 0x75, 0x20, 0x00, 0x55, 0xCB, 0x81, 0x00,
+ 0x88, 0x11, 0xC0, 0x08, 0x00, 0x3C, 0x10, 0x21, 0x38, 0xB5, 0x04, 0x46,
+ 0xC0, 0x68, 0xE1, 0x88, 0x45, 0x18, 0x21, 0x89, 0x2A, 0x46, 0x16, 0x48,
+ 0xEA, 0xF7, 0xA0, 0xDA, 0x28, 0x78, 0x02, 0x28, 0x04, 0xD1, 0x05, 0xF8,
+ 0x08, 0x0D, 0x20, 0x89, 0x08, 0x30, 0x20, 0x81, 0xE0, 0x68, 0x45, 0xF8,
+ 0x04, 0x0C, 0x28, 0x78, 0x02, 0x28, 0x03, 0xD1, 0x0E, 0x48, 0x81, 0x8F,
+ 0x49, 0x1C, 0x81, 0x87, 0x21, 0x89, 0x28, 0x46, 0xFE, 0xF7, 0x92, 0xFF,
+ 0x00, 0x28, 0x0F, 0xD1, 0x20, 0x89, 0x00, 0x90, 0x2B, 0x78, 0x02, 0x22,
+ 0x08, 0x49, 0x09, 0x48, 0xEA, 0xF7, 0x59, 0xD9, 0xE0, 0x68, 0xBD, 0xE8,
+ 0x38, 0x40, 0x40, 0xF2, 0x01, 0x22, 0x06, 0x49, 0xF1, 0xF7, 0xD4, 0xBF,
+ 0x38, 0xBD, 0x00, 0x00, 0x00, 0x3D, 0x20, 0x21, 0xF0, 0x75, 0x20, 0x00,
+ 0x2C, 0x11, 0xC0, 0x08, 0x00, 0x3C, 0x10, 0x21, 0x3D, 0xA7, 0x82, 0x00,
+ 0x70, 0xB5, 0x06, 0x46, 0x04, 0x98, 0x1D, 0x46, 0x00, 0xFB, 0x02, 0x10,
+ 0x81, 0xB2, 0x1A, 0x46, 0x30, 0x46, 0xEE, 0xF7, 0x0D, 0xDD, 0x04, 0x00,
+ 0x03, 0xD0, 0x29, 0x46, 0x30, 0x46, 0x1C, 0xF4, 0xC7, 0xF2, 0x20, 0x46,
+ 0x70, 0xBD, 0x30, 0xB4, 0x02, 0x9C, 0x04, 0xFB, 0x02, 0x11, 0x30, 0xBC,
+ 0x89, 0xB2, 0x1A, 0x46, 0xEE, 0xF7, 0x9D, 0x9C, 0x70, 0xB5, 0x05, 0x46,
+ 0x17, 0x4A, 0x18, 0x4C, 0x00, 0x20, 0x01, 0x46, 0x12, 0x68, 0x04, 0x23,
+ 0x94, 0xF8, 0x98, 0x41, 0x07, 0xE0, 0x01, 0xEB, 0x01, 0x16, 0x03, 0xEB,
+ 0x86, 0x06, 0x96, 0x5D, 0xDE, 0xB1, 0x49, 0x1C, 0xC9, 0xB2, 0x8C, 0x42,
+ 0xF5, 0xD8, 0x00, 0x28, 0x14, 0xD0, 0x01, 0x21, 0x01, 0x71, 0x4F, 0xF6,
+ 0xFF, 0x71, 0x41, 0x80, 0x00, 0x21, 0x01, 0x80, 0x81, 0x62, 0xC1, 0x85,
+ 0x01, 0x86, 0x41, 0x71, 0x81, 0x71, 0x41, 0x63, 0x01, 0x64, 0x2A, 0x68,
+ 0xC2, 0x60, 0xAA, 0x88, 0x02, 0x82, 0x17, 0x22, 0x42, 0x81, 0x01, 0x72,
+ 0x70, 0xBD, 0x01, 0xEB, 0x01, 0x10, 0x02, 0xEB, 0x80, 0x00, 0xE2, 0xE7,
+ 0x68, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0xFE, 0xB5, 0x04, 0x46,
+ 0x0D, 0x46, 0x00, 0x7F, 0xA1, 0x89, 0xCD, 0xE9, 0x00, 0x10, 0x02, 0x95,
+ 0x60, 0x68, 0x16, 0x46, 0x04, 0x22, 0x43, 0x88, 0x26, 0x49, 0x27, 0x48,
+ 0xEA, 0xF7, 0xE3, 0xD8, 0x23, 0x7F, 0x08, 0x2B, 0x3D, 0xD2, 0xDF, 0xE8,
+ 0x03, 0xF0, 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x3C, 0x2C, 0x34, 0x03, 0xB0,
+ 0x32, 0x46, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x00, 0xF0,
+ 0x3D, 0xB8, 0x03, 0xB0, 0x32, 0x46, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x40, 0x00, 0xF0, 0x0D, 0xB9, 0x03, 0xB0, 0x32, 0x46, 0x29, 0x46,
+ 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x00, 0xF0, 0xD1, 0xB9, 0x03, 0xB0,
+ 0x32, 0x46, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x00, 0xF0,
+ 0xBB, 0xB8, 0x03, 0xB0, 0x32, 0x46, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x40, 0x00, 0xF0, 0x3F, 0xB9, 0x03, 0xB0, 0x32, 0x46, 0x29, 0x46,
+ 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x00, 0xF0, 0x57, 0xB8, 0x03, 0xB0,
+ 0x32, 0x46, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x00, 0xF0,
+ 0x7D, 0xB9, 0x04, 0x49, 0x04, 0x48, 0x02, 0x22, 0x44, 0x31, 0xC0, 0x1E,
+ 0x00, 0x95, 0xEA, 0xF7, 0x9A, 0xD8, 0xFE, 0xBD, 0x58, 0x1D, 0xC0, 0x08,
+ 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x16, 0x46, 0x05, 0x46, 0x0C, 0x46,
+ 0x0B, 0x46, 0x01, 0x22, 0x1B, 0x49, 0x1C, 0x48, 0xEA, 0xF7, 0x8B, 0xD8,
+ 0x05, 0x2C, 0x15, 0xD0, 0x09, 0xDC, 0x01, 0x2C, 0x17, 0xD0, 0x03, 0x2C,
+ 0x1A, 0xD0, 0x04, 0x2C, 0x28, 0xD1, 0x01, 0x20, 0x28, 0x77, 0x01, 0x46,
+ 0x1F, 0xE0, 0xA4, 0xF5, 0x80, 0x74, 0x07, 0x3C, 0x13, 0xD0, 0xF9, 0x2C,
+ 0x16, 0xD0, 0xA4, 0xF5, 0x80, 0x74, 0xF9, 0x3C, 0x1A, 0xD1, 0x0C, 0xE0,
+ 0x00, 0x21, 0x28, 0x46, 0x02, 0xF0, 0x03, 0xF8, 0x07, 0xE0, 0x31, 0x88,
+ 0x28, 0x46, 0x01, 0xF0, 0xD3, 0xFF, 0x02, 0xE0, 0x28, 0x46, 0x01, 0xF0,
+ 0x53, 0xFB, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, 0x76, 0xBA,
+ 0x02, 0x20, 0x28, 0x77, 0x00, 0x21, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40,
+ 0x01, 0xF0, 0xB4, 0xBF, 0x70, 0xBD, 0x00, 0x00, 0x34, 0x1C, 0xC0, 0x08,
+ 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x16, 0x46, 0x05, 0x46, 0x0C, 0x46,
+ 0x0B, 0x46, 0x01, 0x22, 0x24, 0x49, 0x25, 0x48, 0xEA, 0xF7, 0x49, 0xD8,
+ 0x40, 0xF2, 0x07, 0x12, 0x07, 0x21, 0xA4, 0xF2, 0x07, 0x10, 0x94, 0x42,
+ 0x20, 0xD0, 0x0B, 0xDC, 0x01, 0x2C, 0x30, 0xD0, 0x03, 0x2C, 0x33, 0xD0,
+ 0x05, 0x2C, 0x35, 0xD1, 0x29, 0x77, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40,
+ 0x01, 0xF0, 0xFC, 0xBA, 0xB0, 0xF5, 0x80, 0x7F, 0x17, 0xD0, 0xA0, 0xF5,
+ 0x80, 0x70, 0xF9, 0x38, 0x28, 0xD1, 0x40, 0xF2, 0xF6, 0x21, 0x28, 0x46,
+ 0x01, 0xF0, 0xB7, 0xFF, 0x28, 0x46, 0x01, 0xF0, 0xED, 0xFA, 0x28, 0x46,
+ 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, 0x36, 0xBA, 0x34, 0x88, 0x29, 0x77,
+ 0x28, 0x46, 0x01, 0xF0, 0xE3, 0xFA, 0x21, 0x46, 0x0C, 0xE0, 0x05, 0xF1,
+ 0x08, 0x00, 0x01, 0xF0, 0x6F, 0xFF, 0x00, 0x20, 0x28, 0x77, 0x01, 0x46,
+ 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0, 0x9C, 0xBF, 0x31, 0x88,
+ 0x28, 0x46, 0x01, 0xF0, 0x98, 0xFF, 0xE2, 0xE7, 0x28, 0x46, 0x01, 0xF0,
+ 0xF3, 0xFA, 0xDE, 0xE7, 0x70, 0xBD, 0x00, 0x00, 0x08, 0x1D, 0xC0, 0x08,
+ 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x16, 0x46, 0x05, 0x46, 0x0C, 0x46,
+ 0x0B, 0x46, 0x01, 0x22, 0x1B, 0x49, 0x1C, 0x48, 0xE9, 0xF7, 0xF5, 0xDF,
+ 0x05, 0x2C, 0x23, 0xD0, 0x0B, 0xDC, 0x01, 0x2C, 0x27, 0xD0, 0x03, 0x2C,
+ 0x2A, 0xD1, 0x28, 0x46, 0x01, 0xF0, 0xD8, 0xFA, 0x28, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0x00, 0xF0, 0xFB, 0xB9, 0xA4, 0xF5, 0x80, 0x74, 0x01, 0x3C,
+ 0x06, 0xD0, 0x02, 0x2C, 0x1C, 0xD1, 0x31, 0x88, 0x68, 0x68, 0x01, 0xF0,
+ 0xEF, 0xFB, 0xEF, 0xE7, 0x06, 0x20, 0x28, 0x77, 0x00, 0x21, 0x28, 0x46,
+ 0x01, 0xF0, 0x62, 0xFC, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x21,
+ 0x01, 0xF0, 0x38, 0xBF, 0x07, 0x20, 0x28, 0x77, 0x28, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0x01, 0xF0, 0x8F, 0xBA, 0x31, 0x88, 0x28, 0x46, 0x01, 0xF0,
+ 0x52, 0xFF, 0xD7, 0xE7, 0x70, 0xBD, 0x00, 0x00, 0xAC, 0x1C, 0xC0, 0x08,
+ 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x15, 0x46, 0x06, 0x46, 0x0C, 0x46,
+ 0x0B, 0x46, 0x01, 0x22, 0x1F, 0x49, 0x20, 0x48, 0xE9, 0xF7, 0xB3, 0xDF,
+ 0x06, 0x2C, 0x22, 0xD0, 0x0A, 0xDC, 0x01, 0x2C, 0x2C, 0xD0, 0x03, 0x2C,
+ 0x2F, 0xD0, 0x05, 0x2C, 0x31, 0xD1, 0x00, 0x21, 0x30, 0x46, 0x01, 0xF0,
+ 0x3A, 0xFF, 0x11, 0xE0, 0x07, 0x2C, 0x1E, 0xD0, 0xA4, 0xF5, 0x80, 0x74,
+ 0x07, 0x3C, 0x1D, 0xD0, 0xA4, 0xF5, 0x80, 0x74, 0xF9, 0x3C, 0x22, 0xD1,
+ 0x40, 0xF2, 0xF6, 0x21, 0x30, 0x46, 0x01, 0xF0, 0xFF, 0xFE, 0x30, 0x46,
+ 0x01, 0xF0, 0x5A, 0xFA, 0x30, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0,
+ 0xA3, 0xB9, 0x70, 0x7F, 0x01, 0x28, 0x12, 0xD1, 0x04, 0x20, 0x30, 0x77,
+ 0x30, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0, 0xC9, 0xBB, 0x70, 0x7F,
+ 0x01, 0x28, 0x08, 0xD1, 0x29, 0x88, 0x30, 0x46, 0x01, 0xF0, 0xE6, 0xFE,
+ 0xE8, 0xE7, 0x30, 0x46, 0x01, 0xF0, 0x66, 0xFA, 0xE4, 0xE7, 0x70, 0xBD,
+ 0x54, 0x1C, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x15, 0x46,
+ 0x06, 0x46, 0x0C, 0x46, 0x0B, 0x46, 0x01, 0x22, 0x21, 0x49, 0x22, 0x48,
+ 0xE9, 0xF7, 0x69, 0xDF, 0x40, 0xF2, 0x01, 0x20, 0xA4, 0xF2, 0x01, 0x21,
+ 0x84, 0x42, 0x29, 0xD0, 0x0A, 0xDC, 0x01, 0x2C, 0x2E, 0xD0, 0x03, 0x2C,
+ 0x2E, 0xD0, 0x05, 0x2C, 0x14, 0xD0, 0xA4, 0xF5, 0x80, 0x74, 0x07, 0x3C,
+ 0x2C, 0xD1, 0x25, 0xE0, 0x01, 0x29, 0x29, 0xD0, 0x02, 0x29, 0x21, 0xD0,
+ 0xFF, 0x29, 0x25, 0xD1, 0x40, 0xF2, 0xF6, 0x21, 0x30, 0x46, 0x01, 0xF0,
+ 0xB5, 0xFE, 0x30, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, 0x5C, 0xB9,
+ 0xF0, 0x89, 0x30, 0xB1, 0x07, 0x20, 0x30, 0x77, 0x30, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0x01, 0xF0, 0x05, 0xBA, 0x00, 0x21, 0x30, 0x46, 0x01, 0xF0,
+ 0xCE, 0xFE, 0xEC, 0xE7, 0x06, 0x20, 0x30, 0x77, 0x30, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0x00, 0x21, 0x01, 0xF0, 0x9A, 0xBE, 0x29, 0x88, 0xDF, 0xE7,
+ 0x30, 0x46, 0x01, 0xF0, 0x19, 0xFA, 0xDE, 0xE7, 0x70, 0xBD, 0x00, 0x00,
+ 0xD8, 0x1C, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x16, 0x46,
+ 0x05, 0x46, 0x0C, 0x46, 0x0B, 0x46, 0x01, 0x22, 0x14, 0x49, 0x15, 0x48,
+ 0xE9, 0xF7, 0x1B, 0xDF, 0x40, 0xF2, 0x07, 0x20, 0xA4, 0xF2, 0x07, 0x21,
+ 0x84, 0x42, 0x13, 0xD0, 0x0B, 0xDC, 0x01, 0x2C, 0x15, 0xD0, 0x03, 0x2C,
+ 0x18, 0xD1, 0x28, 0x46, 0x01, 0xF0, 0xFA, 0xF9, 0x28, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0x00, 0xF0, 0x1D, 0xB9, 0x01, 0x29, 0x07, 0xD0, 0xF9, 0x29,
+ 0x0C, 0xD1, 0x40, 0xF2, 0xF6, 0x21, 0x05, 0xE0, 0x28, 0x46, 0x01, 0xF0,
+ 0xEB, 0xF9, 0x00, 0x21, 0x00, 0xE0, 0x31, 0x88, 0x28, 0x46, 0x01, 0xF0,
+ 0x8C, 0xFE, 0xE9, 0xE7, 0x70, 0xBD, 0x00, 0x00, 0x28, 0x1D, 0xC0, 0x08,
+ 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x16, 0x46, 0x05, 0x46, 0x0C, 0x46,
+ 0x0B, 0x46, 0x01, 0x22, 0x20, 0x49, 0x21, 0x48, 0xE9, 0xF7, 0xE7, 0xDE,
+ 0x07, 0x2C, 0x2A, 0xD0, 0x11, 0xDC, 0x01, 0x2C, 0x32, 0xD0, 0x03, 0x2C,
+ 0x1C, 0xD0, 0x05, 0x2C, 0x1E, 0xD0, 0x06, 0x2C, 0x31, 0xD1, 0x68, 0x7F,
+ 0x02, 0x28, 0x2E, 0xD1, 0x03, 0x20, 0x28, 0x77, 0x28, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0x01, 0xF0, 0x55, 0xBE, 0xA4, 0xF5, 0x80, 0x74, 0x07, 0x3C,
+ 0x1E, 0xD0, 0xB4, 0xF5, 0x80, 0x7F, 0x07, 0xD0, 0xA4, 0xF5, 0x80, 0x74,
+ 0xF9, 0x3C, 0x1C, 0xD1, 0x28, 0x46, 0x01, 0xF0, 0x8B, 0xF9, 0x13, 0xE0,
+ 0x28, 0x46, 0x01, 0xF0, 0xAD, 0xF9, 0x0F, 0xE0, 0x00, 0x21, 0x28, 0x46,
+ 0x01, 0xF0, 0x4F, 0xFE, 0x0A, 0xE0, 0x68, 0x7F, 0x02, 0x28, 0x0C, 0xD1,
+ 0x31, 0x88, 0x11, 0xB1, 0xC8, 0xB2, 0x30, 0x38, 0x81, 0xB2, 0x68, 0x68,
+ 0x01, 0xF0, 0xC2, 0xFA, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0,
+ 0xBF, 0xB8, 0x70, 0xBD, 0x80, 0x1C, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21,
+ 0x00, 0x22, 0x21, 0xB1, 0x01, 0x29, 0x08, 0xD0, 0x03, 0x29, 0x1A, 0xD1,
+ 0x0B, 0xE0, 0xC0, 0xB1, 0x16, 0x28, 0x16, 0xD0, 0xC0, 0x07, 0x13, 0xD0,
+ 0x13, 0xE0, 0x90, 0xB1, 0x16, 0x28, 0x10, 0xD0, 0xC0, 0x07, 0x0D, 0xD1,
+ 0x0D, 0xE0, 0x01, 0x28, 0x0A, 0xD0, 0x12, 0x28, 0x08, 0xD0, 0x13, 0x28,
+ 0x06, 0xD0, 0x06, 0x28, 0x04, 0xD0, 0x07, 0x28, 0x02, 0xD0, 0x14, 0x38,
+ 0x02, 0x28, 0x00, 0xD8, 0x01, 0x22, 0x10, 0x46, 0x70, 0x47, 0x00, 0x21,
+ 0x04, 0x28, 0x03, 0xD0, 0x05, 0x28, 0x01, 0xD0, 0x06, 0x28, 0x00, 0xD1,
+ 0x01, 0x21, 0x08, 0x46, 0x70, 0x47, 0x30, 0xB5, 0x84, 0x1F, 0x40, 0xF6,
+ 0x7A, 0x45, 0xAC, 0x42, 0x0F, 0xD8, 0x06, 0x29, 0x0D, 0xD3, 0xAC, 0x1D,
+ 0xA1, 0x42, 0x0A, 0xD8, 0x81, 0x42, 0x08, 0xD3, 0xB2, 0xF5, 0xFA, 0x7F,
+ 0x05, 0xD2, 0x0A, 0x2B, 0x03, 0xD3, 0xA3, 0x42, 0x01, 0xD8, 0x00, 0x20,
+ 0x30, 0xBD, 0x40, 0xF2, 0x05, 0x20, 0x30, 0xBD, 0x13, 0xB5, 0x04, 0x46,
+ 0x83, 0x89, 0x01, 0x22, 0x05, 0x49, 0x06, 0x48, 0xE9, 0xF7, 0x57, 0xDE,
+ 0x01, 0xAA, 0x40, 0xF2, 0x07, 0x11, 0x20, 0x46, 0xFF, 0xF7, 0x5E, 0xFD,
+ 0x1C, 0xBD, 0x00, 0x00, 0x18, 0x1C, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21,
+ 0x2D, 0xE9, 0xF0, 0x41, 0x07, 0x46, 0x2A, 0x4D, 0x2A, 0x48, 0x0E, 0x46,
+ 0x69, 0x7E, 0x90, 0xF8, 0x99, 0x21, 0x00, 0x24, 0x91, 0x42, 0x02, 0xD3,
+ 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x24, 0x49, 0x00, 0x20, 0x34, 0x23,
+ 0x89, 0x68, 0x0C, 0xE0, 0x00, 0xEB, 0x40, 0x0C, 0x0C, 0xEB, 0x00, 0x1C,
+ 0x03, 0xEB, 0x8C, 0x0C, 0x11, 0xF8, 0x0C, 0xC0, 0xBC, 0xF1, 0x00, 0x0F,
+ 0x2A, 0xD0, 0x40, 0x1C, 0xC0, 0xB2, 0x82, 0x42, 0xF0, 0xD8, 0x1C, 0xB3,
+ 0x4C, 0x21, 0x20, 0x46, 0x1B, 0xF4, 0xD8, 0xF7, 0x00, 0xF0, 0x9A, 0xF9,
+ 0xA0, 0x81, 0x20, 0xB3, 0x04, 0xF1, 0x20, 0x00, 0xF2, 0xF7, 0x71, 0xF9,
+ 0x00, 0x20, 0x67, 0x60, 0xA0, 0x62, 0x20, 0x77, 0x60, 0x77, 0xE6, 0x81,
+ 0x4F, 0xF4, 0x28, 0x71, 0x21, 0x82, 0x61, 0x82, 0xA0, 0x60, 0x68, 0x7E,
+ 0x40, 0x1C, 0x68, 0x76, 0x01, 0x20, 0x84, 0xF8, 0x34, 0x00, 0x60, 0x68,
+ 0x01, 0x88, 0x49, 0x1C, 0x01, 0x80, 0x20, 0x46, 0x01, 0xF0, 0x04, 0xF8,
+ 0x20, 0x46, 0xC2, 0xE7, 0x00, 0xEB, 0x40, 0x02, 0x02, 0xEB, 0x00, 0x10,
+ 0x01, 0xEB, 0x80, 0x04, 0xD1, 0xE7, 0x00, 0x22, 0x04, 0x49, 0x05, 0x48,
+ 0xE9, 0xF7, 0xF5, 0xDD, 0xB4, 0xE7, 0x00, 0x00, 0x68, 0x76, 0x20, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0xE8, 0x1B, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21,
+ 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, 0x01, 0x46, 0x86, 0xB0, 0x20, 0x48,
+ 0xF4, 0xF7, 0x8D, 0xDD, 0x00, 0x28, 0x37, 0xD0, 0x60, 0x68, 0x01, 0x88,
+ 0x49, 0x1E, 0x01, 0x80, 0x04, 0xF1, 0x08, 0x00, 0x01, 0xF0, 0x32, 0xFD,
+ 0xA0, 0x6B, 0x00, 0x25, 0x28, 0xB1, 0x4F, 0xF4, 0x98, 0x72, 0x18, 0x49,
+ 0xF1, 0xF7, 0x54, 0xFC, 0xA5, 0x63, 0xE5, 0x87, 0xA4, 0xF8, 0x40, 0x50,
+ 0xA0, 0x6A, 0x28, 0xB1, 0x40, 0xF2, 0x39, 0x12, 0x12, 0x49, 0xF1, 0xF7,
+ 0x49, 0xFC, 0xA5, 0x62, 0x40, 0xF2, 0x3F, 0x17, 0x40, 0xF2, 0x3D, 0x18,
+ 0x04, 0xF1, 0x20, 0x06, 0x43, 0x46, 0x0D, 0x4A, 0x69, 0x46, 0x30, 0x46,
+ 0xF2, 0xF7, 0x5C, 0xF9, 0x28, 0xB1, 0x3A, 0x46, 0x09, 0x49, 0x03, 0x98,
+ 0xF1, 0xF7, 0x36, 0xFC, 0xF2, 0xE7, 0x06, 0x49, 0x25, 0x77, 0x0C, 0x39,
+ 0x84, 0xF8, 0x34, 0x50, 0x48, 0x7E, 0x40, 0x1E, 0x48, 0x76, 0x01, 0x20,
+ 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, 0x74, 0x76, 0x20, 0x00,
+ 0x59, 0xA8, 0x82, 0x00, 0x00, 0xB5, 0x13, 0x48, 0x85, 0xB0, 0x4F, 0xF4,
+ 0xAC, 0x63, 0x10, 0x4A, 0x69, 0x46, 0x00, 0x78, 0xF1, 0xF7, 0xE0, 0xFD,
+ 0x00, 0x28, 0x0C, 0xD0, 0xBD, 0xF8, 0x00, 0x30, 0xB3, 0xF5, 0x40, 0x7F,
+ 0x09, 0xD0, 0xB3, 0xF5, 0xC0, 0x6F, 0x0A, 0xD0, 0x01, 0x22, 0x0A, 0x49,
+ 0x0A, 0x48, 0xE9, 0xF7, 0x88, 0xDD, 0x05, 0xB0, 0x00, 0xBD, 0x68, 0x46,
+ 0x00, 0xF0, 0x28, 0xF9, 0xF9, 0xE7, 0xBD, 0xF8, 0x06, 0x10, 0x9D, 0xF8,
+ 0x05, 0x00, 0x00, 0xF0, 0x2B, 0xFE, 0xF2, 0xE7, 0x34, 0xA8, 0x82, 0x00,
+ 0x64, 0x76, 0x20, 0x00, 0xA0, 0x1B, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21,
+ 0x2D, 0xE9, 0xF0, 0x41, 0x80, 0x46, 0x00, 0x24, 0x0D, 0x4E, 0x0E, 0x4F,
+ 0x0F, 0xE0, 0x30, 0x68, 0x04, 0xEB, 0x04, 0x11, 0x00, 0xEB, 0x81, 0x05,
+ 0x28, 0x79, 0x30, 0xB1, 0x06, 0x22, 0x05, 0xF1, 0x0C, 0x01, 0x40, 0x46,
+ 0x1B, 0xF4, 0x28, 0xF6, 0x40, 0xB1, 0x64, 0x1C, 0xE4, 0xB2, 0x97, 0xF8,
+ 0x98, 0x01, 0xA0, 0x42, 0xEB, 0xD8, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81,
+ 0x28, 0x46, 0xFB, 0xE7, 0x68, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x02, 0x46, 0x30, 0xB5, 0x09, 0x48, 0x00, 0x21, 0x03, 0x68, 0x09, 0x48,
+ 0x90, 0xF8, 0x98, 0x41, 0x08, 0xE0, 0x01, 0xEB, 0x01, 0x10, 0x03, 0xEB,
+ 0x80, 0x00, 0x45, 0x88, 0x95, 0x42, 0x04, 0xD0, 0x49, 0x1C, 0xC9, 0xB2,
+ 0x8C, 0x42, 0xF4, 0xD8, 0x00, 0x20, 0x30, 0xBD, 0x68, 0x76, 0x20, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x02, 0x46, 0x06, 0x48, 0xC0, 0x68, 0x06, 0xE0,
+ 0x43, 0x68, 0x93, 0x42, 0x02, 0xD1, 0x83, 0x7F, 0x8B, 0x42, 0x02, 0xD0,
+ 0x00, 0x68, 0x00, 0x28, 0xF6, 0xD1, 0x70, 0x47, 0x68, 0x76, 0x20, 0x00,
+ 0x01, 0x46, 0x05, 0x48, 0xC0, 0x68, 0x03, 0xE0, 0x82, 0x89, 0x8A, 0x42,
+ 0x02, 0xD0, 0x00, 0x68, 0x00, 0x28, 0xF9, 0xD1, 0x70, 0x47, 0x00, 0x00,
+ 0x68, 0x76, 0x20, 0x00, 0x02, 0x46, 0x06, 0x48, 0xC0, 0x68, 0x06, 0xE0,
+ 0x43, 0x68, 0x93, 0x42, 0x02, 0xD1, 0xC3, 0x89, 0x8B, 0x42, 0x02, 0xD0,
+ 0x00, 0x68, 0x00, 0x28, 0xF6, 0xD1, 0x70, 0x47, 0x68, 0x76, 0x20, 0x00,
+ 0x02, 0x46, 0x30, 0xB5, 0x08, 0x48, 0x00, 0x21, 0x43, 0x68, 0x08, 0x48,
+ 0x90, 0xF8, 0xCA, 0x41, 0x06, 0xE0, 0x03, 0xEB, 0x81, 0x00, 0x05, 0x88,
+ 0x95, 0x42, 0x04, 0xD0, 0x49, 0x1C, 0xC9, 0xB2, 0x8C, 0x42, 0xF6, 0xD8,
+ 0x00, 0x20, 0x30, 0xBD, 0x68, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x10, 0xB5, 0x04, 0x46, 0x03, 0x46, 0x01, 0x22, 0x04, 0x49, 0x05, 0x48,
+ 0xE9, 0xF7, 0xE7, 0xDC, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0,
+ 0xF5, 0xBF, 0x00, 0x00, 0xDC, 0x13, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21,
+ 0x70, 0xB5, 0x04, 0x46, 0x00, 0xF1, 0x0C, 0x01, 0x86, 0xB0, 0x24, 0x48,
+ 0xE9, 0xF7, 0xA4, 0xDE, 0x03, 0x46, 0x01, 0x22, 0x22, 0x49, 0x23, 0x48,
+ 0xE9, 0xF7, 0xCF, 0xDC, 0x4F, 0xF6, 0xFF, 0x70, 0x60, 0x80, 0x00, 0x25,
+ 0x25, 0x71, 0x25, 0x80, 0x60, 0x6B, 0x20, 0xB1, 0x72, 0x22, 0x1E, 0x49,
+ 0xF1, 0xF7, 0x46, 0xFB, 0x65, 0x63, 0x04, 0xF1, 0x1C, 0x06, 0x76, 0x23,
+ 0x1A, 0x4A, 0x69, 0x46, 0x30, 0x46, 0xF2, 0xF7, 0x5D, 0xF8, 0x58, 0xB1,
+ 0x78, 0x22, 0x17, 0x49, 0x03, 0x98, 0xF1, 0xF7, 0x37, 0xFB, 0xF2, 0xE7,
+ 0x7D, 0x22, 0x14, 0x49, 0x03, 0x98, 0xF1, 0xF7, 0x31, 0xFB, 0x01, 0xE0,
+ 0x04, 0xF1, 0x14, 0x06, 0x7B, 0x23, 0x10, 0x4A, 0x69, 0x46, 0x30, 0x46,
+ 0xF2, 0xF7, 0x48, 0xF8, 0x00, 0x28, 0xEF, 0xD1, 0xE0, 0x8D, 0x30, 0xB1,
+ 0x82, 0x22, 0x0B, 0x49, 0xA0, 0x6A, 0xF1, 0xF7, 0x1F, 0xFB, 0xA5, 0x62,
+ 0xE5, 0x85, 0xA0, 0x79, 0x00, 0x28, 0x04, 0xD0, 0x04, 0xF1, 0x40, 0x00,
+ 0x01, 0xF0, 0xEC, 0xFB, 0xA5, 0x71, 0x06, 0xB0, 0x70, 0xBD, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x21, 0xC8, 0x1B, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21,
+ 0x47, 0xA8, 0x82, 0x00, 0x10, 0xB5, 0x7F, 0x24, 0x40, 0x23, 0x18, 0x46,
+ 0xFF, 0xF7, 0x5C, 0xFF, 0x28, 0xB1, 0x5B, 0x1C, 0x9B, 0xB2, 0xA3, 0x42,
+ 0xF7, 0xD3, 0x00, 0x20, 0x10, 0xBD, 0x18, 0x46, 0x10, 0xBD, 0x41, 0x79,
+ 0x49, 0x1C, 0x11, 0xF0, 0xFF, 0x01, 0x41, 0x71, 0x01, 0xD1, 0x01, 0x21,
+ 0x41, 0x71, 0xC8, 0xB2, 0x70, 0x47, 0x00, 0x00, 0x48, 0x68, 0x10, 0xF8,
+ 0x01, 0x2B, 0x10, 0xF8, 0x01, 0x3B, 0x48, 0x60, 0x02, 0xEB, 0x03, 0x22,
+ 0x93, 0xB2, 0x01, 0x22, 0x01, 0x49, 0x02, 0x48, 0xE9, 0xF7, 0x5F, 0x9C,
+ 0xBC, 0x17, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x4F,
+ 0x05, 0x46, 0x85, 0xB0, 0x40, 0x89, 0xFF, 0xF7, 0x05, 0xFF, 0xDF, 0xF8,
+ 0x30, 0xB3, 0x04, 0x00, 0x21, 0xD0, 0x28, 0x79, 0x2E, 0x89, 0x00, 0x07,
+ 0xE0, 0x8D, 0x4F, 0xF0, 0x00, 0x09, 0x31, 0xD5, 0x50, 0xB1, 0x00, 0x22,
+ 0xC6, 0x49, 0x58, 0x46, 0xE9, 0xF7, 0x43, 0xDC, 0x40, 0xF2, 0x4D, 0x42,
+ 0xC4, 0x49, 0xA0, 0x6A, 0xF1, 0xF7, 0xC0, 0xFA, 0x04, 0x2E, 0x17, 0xD2,
+ 0xC0, 0x49, 0x00, 0x22, 0x38, 0x31, 0x58, 0x46, 0xE9, 0xF7, 0x35, 0xDC,
+ 0xE8, 0x68, 0x40, 0xF2, 0x54, 0x42, 0xBD, 0x49, 0xF1, 0xF7, 0xB2, 0xFA,
+ 0x4D, 0xE1, 0xBA, 0x49, 0x6B, 0x89, 0x01, 0x22, 0x34, 0x39, 0x58, 0x46,
+ 0xE9, 0xF7, 0x27, 0xDC, 0x4F, 0xF4, 0x88, 0x62, 0xE8, 0x68, 0xF0, 0xE7,
+ 0xE8, 0x68, 0xA0, 0x62, 0xE8, 0x88, 0xA0, 0x85, 0xE6, 0x85, 0xA4, 0xF8,
+ 0x30, 0x90, 0xA8, 0x88, 0x20, 0xF0, 0x01, 0x00, 0xA8, 0x80, 0x47, 0xE0,
+ 0xF0, 0xB1, 0x23, 0x8E, 0x19, 0x1A, 0xB1, 0x42, 0x24, 0xDA, 0x30, 0x44,
+ 0xAB, 0x49, 0x00, 0x90, 0x02, 0x22, 0x94, 0x31, 0x58, 0x46, 0xE9, 0xF7,
+ 0x0A, 0xDC, 0x40, 0xF2, 0x6F, 0x42, 0xA8, 0x49, 0xE8, 0x68, 0xF1, 0xF7,
+ 0x87, 0xFA, 0x4F, 0xF4, 0x8E, 0x62, 0xA5, 0x49, 0xA0, 0x6A, 0xF1, 0xF7,
+ 0x81, 0xFA, 0xA4, 0xF8, 0x2E, 0x90, 0xA4, 0xF8, 0x30, 0x90, 0xC4, 0xF8,
+ 0x28, 0x90, 0x16, 0xE1, 0x9E, 0x49, 0x00, 0x22, 0x68, 0x31, 0x58, 0x46,
+ 0xE9, 0xF7, 0xF1, 0xDB, 0x40, 0xF2, 0x66, 0x42, 0xE8, 0x68, 0xBA, 0xE7,
+ 0xEA, 0x88, 0xE9, 0x68, 0xA3, 0x8D, 0x11, 0x44, 0xA2, 0x6A, 0x1A, 0x44,
+ 0x10, 0x44, 0x32, 0x46, 0x1B, 0xF4, 0xF7, 0xF4, 0xE0, 0x8D, 0x40, 0xF2,
+ 0x7D, 0x42, 0x30, 0x44, 0xE0, 0x85, 0x93, 0x49, 0xE8, 0x68, 0xF1, 0xF7,
+ 0x5D, 0xFA, 0xE0, 0x8D, 0x8F, 0x49, 0xCD, 0xE9, 0x00, 0x60, 0x8D, 0x48,
+ 0x23, 0x8E, 0x03, 0x22, 0xD0, 0x31, 0xC0, 0x1C, 0xE9, 0xF7, 0xCF, 0xDB,
+ 0xA1, 0x8D, 0xA0, 0x6A, 0x08, 0x44, 0x10, 0xF8, 0x01, 0x1B, 0x10, 0xF8,
+ 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21, 0x8F, 0xB2, 0x10, 0xF8, 0x01, 0x1B,
+ 0x10, 0xF8, 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21, 0x1F, 0xFA, 0x81, 0xF8,
+ 0x21, 0x8E, 0x00, 0x29, 0x7D, 0xD1, 0x41, 0x46, 0xB8, 0xF1, 0x05, 0x0F,
+ 0x1F, 0xD1, 0x17, 0x2F, 0x1D, 0xD9, 0x90, 0xF8, 0x01, 0x80, 0x17, 0x26,
+ 0x3B, 0x46, 0x01, 0x22, 0x7C, 0x49, 0x58, 0x46, 0xE9, 0xF7, 0xAB, 0xDB,
+ 0x40, 0xF2, 0x94, 0x42, 0x78, 0x49, 0xE8, 0x68, 0xF1, 0xF7, 0x28, 0xFA,
+ 0xA4, 0xF8, 0x2E, 0x90, 0xA4, 0xF8, 0x30, 0x90, 0xC4, 0xF8, 0x28, 0x90,
+ 0x84, 0xF8, 0x07, 0x80, 0x00, 0x23, 0x32, 0x46, 0x01, 0x21, 0x20, 0x46,
+ 0x00, 0xF0, 0x20, 0xFE, 0xB5, 0xE0, 0x08, 0x46, 0xFF, 0xF7, 0x11, 0xFD,
+ 0xC0, 0xBB, 0x40, 0x46, 0xFF, 0xF7, 0x6A, 0xFE, 0x60, 0x62, 0x18, 0xB1,
+ 0x81, 0x6B, 0x80, 0x8A, 0xA1, 0xB1, 0x14, 0xE0, 0x69, 0x49, 0x43, 0x46,
+ 0x01, 0x22, 0x38, 0x31, 0x58, 0x46, 0xE9, 0xF7, 0x82, 0xDB, 0x40, 0xF2,
+ 0xAB, 0x42, 0x64, 0x49, 0xE8, 0x68, 0xF1, 0xF7, 0xFF, 0xF9, 0xC4, 0xF8,
+ 0x28, 0x90, 0xA4, 0xF8, 0x2E, 0x90, 0xA4, 0xF8, 0x30, 0x90, 0x94, 0xE0,
+ 0x80, 0x1C, 0xB8, 0x42, 0x19, 0xD2, 0x5E, 0x49, 0x3B, 0x46, 0x01, 0x22,
+ 0x64, 0x31, 0x58, 0x46, 0xE9, 0xF7, 0x6B, 0xDB, 0x40, 0xF2, 0xBC, 0x42,
+ 0x58, 0x49, 0xE8, 0x68, 0xF1, 0xF7, 0xE8, 0xF9, 0xC4, 0xF8, 0x28, 0x90,
+ 0xA4, 0xF8, 0x2E, 0x90, 0xA4, 0xF8, 0x30, 0x90, 0x40, 0xF2, 0xF1, 0x21,
+ 0x60, 0x6A, 0xFF, 0xF7, 0xFB, 0xFC, 0x78, 0xE0, 0xFF, 0xE7, 0x39, 0x1D,
+ 0x88, 0xB2, 0x20, 0x86, 0xB0, 0x42, 0x3B, 0xD9, 0x4F, 0x4A, 0xDF, 0xF8,
+ 0x40, 0xA1, 0x92, 0xF8, 0x00, 0xC0, 0x9A, 0xF8, 0x78, 0x21, 0x52, 0x06,
+ 0x03, 0xD5, 0xBA, 0xF8, 0xA8, 0x21, 0x90, 0x42, 0x2E, 0xD9, 0xA0, 0x8D,
+ 0x40, 0xF2, 0xDF, 0x43, 0x00, 0x1F, 0xA0, 0x85, 0x08, 0x44, 0x81, 0xB2,
+ 0x43, 0x4A, 0x60, 0x46, 0x00, 0xE0, 0x25, 0xE0, 0xF1, 0xF7, 0xCE, 0xF8,
+ 0xA0, 0x62, 0xE8, 0xB3, 0xEA, 0x88, 0xE9, 0x68, 0x11, 0x44, 0xA2, 0x8D,
+ 0x10, 0x44, 0x32, 0x46, 0x1B, 0xF4, 0x43, 0xF4, 0xBA, 0xF8, 0x78, 0x01,
+ 0xC0, 0x04, 0x4F, 0xD5, 0xA8, 0x88, 0x39, 0x4B, 0x20, 0xF0, 0x01, 0x00,
+ 0xA8, 0x80, 0x40, 0xF2, 0xEA, 0x40, 0x00, 0x90, 0xEA, 0x68, 0x39, 0x49,
+ 0xA0, 0x6A, 0xF1, 0xF7, 0x79, 0xF8, 0x28, 0xB9, 0xE8, 0x68, 0x40, 0xF2,
+ 0xED, 0x42, 0x31, 0x49, 0xF1, 0xF7, 0x9A, 0xF9, 0x20, 0x8E, 0xC0, 0xB3,
+ 0xE0, 0x8D, 0x21, 0x8E, 0x88, 0x42, 0x53, 0xD1, 0xA4, 0xF8, 0x2E, 0x90,
+ 0xA4, 0xF8, 0x30, 0x90, 0x01, 0x20, 0xAD, 0xF8, 0x04, 0x00, 0xA0, 0x6A,
+ 0x03, 0x90, 0xA0, 0x8D, 0x4D, 0x46, 0x00, 0x1D, 0xAD, 0xF8, 0x06, 0x00,
+ 0xAD, 0xF8, 0x08, 0x70, 0x40, 0x46, 0xB8, 0xF1, 0x05, 0x0F, 0x2D, 0xD0,
+ 0xB8, 0xF1, 0x04, 0x0F, 0x2F, 0xD0, 0x00, 0xE0, 0x20, 0xE0, 0xB8, 0xF1,
+ 0x06, 0x0F, 0x2A, 0xD0, 0x60, 0x6A, 0x03, 0x7F, 0x06, 0x2B, 0x2C, 0xD0,
+ 0x05, 0x2B, 0x2A, 0xD0, 0x1C, 0x49, 0x01, 0x22, 0x98, 0x31, 0x58, 0x46,
+ 0xE9, 0xF7, 0xE9, 0xDA, 0x40, 0xF2, 0x34, 0x52, 0x17, 0x49, 0xA0, 0x6A,
+ 0xF1, 0xF7, 0x66, 0xF9, 0xE5, 0x85, 0x25, 0x86, 0xA5, 0x62, 0x00, 0x20,
+ 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x1D, 0xE0, 0x40, 0xF2, 0xF2, 0x42,
+ 0xE8, 0x68, 0xBC, 0xE7, 0xA4, 0xF8, 0x2E, 0x90, 0xA4, 0xF8, 0x30, 0x90,
+ 0x40, 0xF2, 0xFB, 0x42, 0xE8, 0x68, 0x9C, 0xE6, 0x69, 0x46, 0x20, 0x46,
+ 0x00, 0xF0, 0x32, 0xFB, 0x0B, 0xE0, 0x01, 0x46, 0x6A, 0x46, 0x20, 0x46,
+ 0x00, 0xF0, 0x46, 0xF9, 0x05, 0xE0, 0x81, 0x89, 0xAD, 0xF8, 0x0A, 0x10,
+ 0x69, 0x46, 0x00, 0xF0, 0x5F, 0xF9, 0xA5, 0x62, 0x01, 0x20, 0xDB, 0xE7,
+ 0x00, 0x3B, 0x10, 0x21, 0xC8, 0x19, 0xC0, 0x08, 0x20, 0xA8, 0x82, 0x00,
+ 0xD8, 0x1A, 0xC0, 0x08, 0x04, 0x74, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x59, 0xF5, 0x81, 0x00, 0xF8, 0xB5, 0x07, 0x46, 0x48, 0x68, 0x0C, 0x46,
+ 0x10, 0xF8, 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB,
+ 0x02, 0x21, 0x8E, 0xB2, 0x10, 0xF8, 0x01, 0x1B, 0x33, 0x46, 0x10, 0xF8,
+ 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB, 0x02, 0x21, 0x8D, 0xB2, 0x02, 0x22,
+ 0x10, 0x49, 0x11, 0x48, 0x00, 0x95, 0xE9, 0xF7, 0x92, 0xDA, 0x60, 0x78,
+ 0xF8, 0x71, 0x30, 0x46, 0xFF, 0xF7, 0x68, 0xFD, 0x58, 0xB1, 0xC1, 0x89,
+ 0xA9, 0x42, 0x11, 0xD1, 0x61, 0x78, 0xC1, 0x77, 0xBD, 0xE8, 0xF8, 0x40,
+ 0x00, 0x22, 0x40, 0xF2, 0x07, 0x21, 0xFF, 0xF7, 0x8D, 0xB9, 0x01, 0xB0,
+ 0x2B, 0x46, 0x32, 0x46, 0x38, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x02, 0x21,
+ 0x00, 0xF0, 0x00, 0xBD, 0xF8, 0xBD, 0x00, 0x00, 0xDC, 0x16, 0xC0, 0x08,
+ 0x03, 0x3B, 0x10, 0x21, 0xF8, 0xB5, 0x4A, 0x68, 0x0C, 0x46, 0x12, 0xF8,
+ 0x01, 0x0B, 0x12, 0xF8, 0x01, 0x1B, 0x62, 0x60, 0x00, 0xEB, 0x01, 0x20,
+ 0x85, 0xB2, 0x12, 0xF8, 0x01, 0x0B, 0x2B, 0x46, 0x12, 0xF8, 0x01, 0x1B,
+ 0x62, 0x60, 0x00, 0xEB, 0x01, 0x20, 0x86, 0xB2, 0x02, 0x22, 0x14, 0x49,
+ 0x14, 0x48, 0x00, 0x96, 0xE9, 0xF7, 0x57, 0xDA, 0x30, 0x46, 0xFF, 0xF7,
+ 0x2F, 0xFD, 0x11, 0x4B, 0xDB, 0x1E, 0x30, 0xB1, 0xC1, 0x89, 0xA9, 0x42,
+ 0x07, 0xD0, 0x0D, 0x49, 0x00, 0x22, 0x58, 0x31, 0x0B, 0xE0, 0x0B, 0x49,
+ 0x00, 0x22, 0x34, 0x31, 0x07, 0xE0, 0x81, 0x7F, 0x62, 0x78, 0x91, 0x42,
+ 0x4F, 0xF0, 0x00, 0x02, 0x06, 0xD0, 0x06, 0x49, 0x84, 0x31, 0x18, 0x46,
+ 0xBD, 0xE8, 0xF8, 0x40, 0xE9, 0xF7, 0x39, 0x9A, 0xBD, 0xE8, 0xF8, 0x40,
+ 0x4F, 0xF4, 0x02, 0x71, 0xFF, 0xF7, 0x40, 0xB9, 0x10, 0x17, 0xC0, 0x08,
+ 0x03, 0x3B, 0x10, 0x21, 0x38, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0x03, 0x46,
+ 0x00, 0x91, 0x02, 0x22, 0x0B, 0x49, 0x0C, 0x48, 0xE9, 0xF7, 0x25, 0xDA,
+ 0x28, 0x46, 0xFF, 0xF7, 0xD3, 0xFC, 0x00, 0x28, 0x0D, 0xD0, 0x01, 0x88,
+ 0x39, 0xB1, 0x04, 0x21, 0x01, 0x71, 0x22, 0x46, 0xBD, 0xE8, 0x38, 0x40,
+ 0x05, 0x49, 0x00, 0xF0, 0x1D, 0xBC, 0xBD, 0xE8, 0x38, 0x40, 0xFF, 0xF7,
+ 0x35, 0xBD, 0x38, 0xBD, 0xF4, 0x18, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21,
+ 0x89, 0xF3, 0x81, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, 0x82, 0x46, 0x48, 0x68,
+ 0x0C, 0x46, 0x10, 0xF8, 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B, 0x60, 0x60,
+ 0x01, 0xEB, 0x02, 0x21, 0x8D, 0xB2, 0x10, 0xF8, 0x01, 0x1B, 0x2B, 0x46,
+ 0x10, 0xF8, 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB, 0x02, 0x21, 0x8F, 0xB2,
+ 0x10, 0xF8, 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB,
+ 0x02, 0x21, 0x1F, 0xFA, 0x81, 0xF9, 0x10, 0xF8, 0x01, 0x1B, 0x10, 0xF8,
+ 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB, 0x02, 0x21, 0x8E, 0xB2, 0x10, 0xF8,
+ 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB, 0x02, 0x21,
+ 0x1F, 0xFA, 0x81, 0xF8, 0x02, 0x22, 0x1E, 0x49, 0x1E, 0x48, 0x00, 0x97,
+ 0xE9, 0xF7, 0xD5, 0xD9, 0x61, 0x78, 0x8A, 0xF8, 0x07, 0x10, 0x28, 0x46,
+ 0xFF, 0xF7, 0xC8, 0xFC, 0x10, 0xB1, 0x0D, 0xB1, 0xFF, 0x2D, 0x01, 0xD9,
+ 0x02, 0x21, 0x1D, 0xE0, 0x39, 0x46, 0x50, 0x46, 0xFF, 0xF7, 0xAE, 0xFC,
+ 0x08, 0xB1, 0x0A, 0x21, 0x16, 0xE0, 0x39, 0x46, 0x50, 0x46, 0xFF, 0xF7,
+ 0x73, 0xFB, 0x80, 0xB1, 0x05, 0x83, 0x02, 0x21, 0x41, 0x77, 0x61, 0x78,
+ 0xC1, 0x77, 0x0F, 0x49, 0xA0, 0xF8, 0x12, 0x90, 0xA0, 0xF8, 0x46, 0x80,
+ 0xB1, 0xF8, 0xA4, 0x11, 0x89, 0x1E, 0xB1, 0x42, 0x07, 0xDA, 0xC1, 0x82,
+ 0x06, 0xE0, 0x04, 0x21, 0x50, 0x46, 0xBD, 0xE8, 0xF8, 0x4F, 0x00, 0xF0,
+ 0xB9, 0xBD, 0xC6, 0x82, 0xBD, 0xE8, 0xF8, 0x4F, 0x00, 0x22, 0x4F, 0xF4,
+ 0x00, 0x71, 0xFF, 0xF7, 0xAB, 0xB8, 0x00, 0x00, 0x58, 0x1F, 0xC0, 0x08,
+ 0x03, 0x3B, 0x10, 0x21, 0x64, 0x01, 0x20, 0x00, 0x70, 0xB5, 0x15, 0x46,
+ 0x0C, 0x46, 0x06, 0x46, 0x00, 0x2B, 0x0A, 0xD1, 0xFF, 0xF7, 0x1C, 0xFC,
+ 0x18, 0xB9, 0x30, 0x46, 0xFF, 0xF7, 0x62, 0xF8, 0x20, 0xB1, 0x44, 0x80,
+ 0x05, 0x72, 0x03, 0x21, 0x01, 0x71, 0x70, 0xBD, 0x20, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0x14, 0x21, 0xFC, 0xF7, 0xEC, 0xBE, 0x10, 0xB5, 0x14, 0x46,
+ 0x04, 0x29, 0x12, 0xD0, 0x06, 0x29, 0x05, 0xD0, 0x20, 0x79, 0xC0, 0x07,
+ 0x13, 0xD0, 0xD0, 0x68, 0x5B, 0x22, 0x05, 0xE0, 0x40, 0x88, 0x11, 0x46,
+ 0x09, 0xF0, 0xC4, 0xFA, 0xE0, 0x68, 0x6C, 0x22, 0xBD, 0xE8, 0x10, 0x40,
+ 0x04, 0x49, 0xF0, 0xF7, 0xEB, 0xBF, 0x40, 0x88, 0xBD, 0xE8, 0x10, 0x40,
+ 0x11, 0x46, 0xFA, 0xF7, 0x6F, 0xB9, 0x10, 0xBD, 0x6A, 0xA8, 0x82, 0x00,
+ 0x2D, 0xE9, 0xF8, 0x43, 0x04, 0x46, 0xB0, 0xF8, 0x44, 0x00, 0x00, 0x90,
+ 0x0D, 0x46, 0xA3, 0x89, 0x02, 0x22, 0x57, 0x49, 0x57, 0x48, 0xE9, 0xF7,
+ 0x52, 0xD9, 0xB4, 0xF8, 0x44, 0x00, 0xD0, 0xB1, 0x40, 0x1E, 0xA4, 0xF8,
+ 0x44, 0x00, 0xDF, 0xF8, 0x4C, 0xC1, 0x2F, 0x89, 0xA1, 0x6B, 0xAC, 0xF1,
+ 0x03, 0x0C, 0x40, 0xF2, 0xF1, 0x28, 0x89, 0xB1, 0xE2, 0x8F, 0xB4, 0xF8,
+ 0x40, 0x30, 0xD0, 0x19, 0x98, 0x42, 0x52, 0xD9, 0x4A, 0x49, 0x02, 0x22,
+ 0x60, 0x31, 0x00, 0x90, 0x60, 0x46, 0xE9, 0xF7, 0x36, 0xD9, 0x46, 0x46,
+ 0x3D, 0xE0, 0x40, 0xF2, 0xF2, 0x26, 0x3A, 0xE0, 0xE9, 0x88, 0xE8, 0x68,
+ 0x42, 0x5C, 0x01, 0x44, 0x49, 0x78, 0x02, 0xEB, 0x01, 0x21, 0x8E, 0xB2,
+ 0x21, 0x8A, 0xB1, 0x42, 0x05, 0xD2, 0x00, 0x91, 0x3E, 0x49, 0x02, 0x22,
+ 0x33, 0x46, 0x2C, 0x31, 0xE6, 0xE7, 0xBF, 0x1E, 0xBE, 0x42, 0x07, 0xD1,
+ 0xA0, 0x63, 0xE8, 0x88, 0x80, 0x1C, 0xA0, 0x87, 0xA4, 0xF8, 0x40, 0x60,
+ 0xE7, 0x87, 0x3E, 0xE0, 0x06, 0xF1, 0x1C, 0x00, 0x81, 0xB2, 0x38, 0x48,
+ 0x40, 0xF2, 0x16, 0x43, 0x35, 0x4A, 0x00, 0x78, 0xF0, 0xF7, 0xA0, 0xFE,
+ 0xA0, 0x63, 0x80, 0xB1, 0x1C, 0x21, 0xA1, 0x87, 0xA4, 0xF8, 0x40, 0x60,
+ 0xBA, 0xB2, 0xE2, 0x87, 0xEB, 0x88, 0xE9, 0x68, 0x1C, 0x30, 0x19, 0x44,
+ 0x89, 0x1C, 0x1B, 0xF4, 0x10, 0xF2, 0x40, 0xF2, 0x25, 0x42, 0xE8, 0x68,
+ 0x1E, 0xE0, 0x4F, 0xF4, 0x01, 0x76, 0x4F, 0xF4, 0x8B, 0x62, 0x28, 0x49,
+ 0xE8, 0x68, 0xF0, 0xF7, 0x73, 0xFF, 0x31, 0x46, 0x20, 0x46, 0xBD, 0xE8,
+ 0xF8, 0x43, 0xFF, 0xF7, 0x8B, 0xBA, 0xEB, 0x88, 0xE8, 0x68, 0x18, 0x44,
+ 0xA3, 0x8F, 0x19, 0x44, 0x8B, 0x18, 0x01, 0x46, 0x3A, 0x46, 0x18, 0x46,
+ 0x1B, 0xF4, 0xF3, 0xF1, 0xE0, 0x8F, 0x40, 0xF2, 0x37, 0x42, 0x38, 0x44,
+ 0xE0, 0x87, 0xE8, 0x68, 0x1A, 0x49, 0xF0, 0xF7, 0x59, 0xFF, 0xE0, 0x8F,
+ 0xB4, 0xF8, 0x40, 0x10, 0x88, 0x42, 0x0C, 0xD1, 0x00, 0x90, 0x60, 0x68,
+ 0xA3, 0x8F, 0xA1, 0x89, 0x40, 0x88, 0xA2, 0x6B, 0xF5, 0xF7, 0xAE, 0xF8,
+ 0x00, 0x20, 0xA0, 0x63, 0xA4, 0xF8, 0x40, 0x00, 0xE0, 0x87, 0xB4, 0xF8,
+ 0x4A, 0x10, 0xB4, 0xF8, 0x44, 0x00, 0x71, 0xB1, 0x88, 0x42, 0x0A, 0xD1,
+ 0xB4, 0xF8, 0x48, 0x10, 0x08, 0x1A, 0x81, 0xB2, 0x20, 0x46, 0x00, 0xF0,
+ 0x89, 0xFD, 0xB4, 0xF8, 0x48, 0x00, 0xA4, 0xF8, 0x44, 0x00, 0xBD, 0xE8,
+ 0xF8, 0x83, 0x00, 0x28, 0xFB, 0xD1, 0x60, 0x68, 0xA1, 0x89, 0x40, 0x88,
+ 0xBD, 0xE8, 0xF8, 0x43, 0xF4, 0xF7, 0x84, 0xBF, 0xDC, 0x21, 0xC0, 0x08,
+ 0x03, 0x3B, 0x10, 0x21, 0xC0, 0xA8, 0x82, 0x00, 0x04, 0x74, 0x20, 0x00,
+ 0x2D, 0xE9, 0xFE, 0x43, 0x05, 0x46, 0x48, 0x68, 0x0C, 0x46, 0x10, 0xF8,
+ 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB, 0x02, 0x21,
+ 0x1F, 0xFA, 0x81, 0xF9, 0x10, 0xF8, 0x01, 0x1B, 0x4B, 0x46, 0x10, 0xF8,
+ 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB, 0x02, 0x21, 0x1F, 0xFA, 0x81, 0xF8,
+ 0x10, 0xF8, 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB,
+ 0x02, 0x21, 0x8F, 0xB2, 0x10, 0xF8, 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B,
+ 0x60, 0x60, 0x01, 0xEB, 0x02, 0x21, 0x8E, 0xB2, 0xCD, 0xF8, 0x00, 0x80,
+ 0xCD, 0xE9, 0x01, 0x76, 0x04, 0x22, 0x18, 0x49, 0x18, 0x48, 0xE9, 0xF7,
+ 0x6E, 0xD8, 0x60, 0x78, 0xE8, 0x71, 0x28, 0x7A, 0x40, 0xB1, 0x03, 0xB0,
+ 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x43, 0x00, 0x23, 0x1A, 0x46, 0x19, 0x46,
+ 0x00, 0xF0, 0xEA, 0xBA, 0x33, 0x46, 0x3A, 0x46, 0x41, 0x46, 0x48, 0x46,
+ 0xFF, 0xF7, 0xE3, 0xF9, 0x80, 0xB1, 0x01, 0x20, 0x8D, 0xF8, 0x08, 0x00,
+ 0x00, 0x21, 0x02, 0x20, 0xCD, 0xE9, 0x00, 0x01, 0x8D, 0xF8, 0x09, 0x10,
+ 0x02, 0xAB, 0x13, 0x22, 0x29, 0x46, 0x00, 0x20, 0x00, 0xF0, 0xE6, 0xFE,
+ 0xBD, 0xE8, 0xFE, 0x83, 0x00, 0x96, 0x68, 0x88, 0x3B, 0x46, 0x42, 0x46,
+ 0x49, 0x46, 0xFA, 0xF7, 0x53, 0xFA, 0xF5, 0xE7, 0xF4, 0x1D, 0xC0, 0x08,
+ 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x04, 0x46, 0x48, 0x68, 0x00, 0x25,
+ 0x10, 0xF8, 0x01, 0x2B, 0x10, 0xF8, 0x01, 0x3B, 0x48, 0x60, 0x02, 0xEB,
+ 0x03, 0x22, 0x96, 0xB2, 0x33, 0x46, 0x01, 0x22, 0x0D, 0x49, 0x0E, 0x48,
+ 0xE9, 0xF7, 0x2B, 0xD8, 0x20, 0x7A, 0x01, 0x28, 0x11, 0xD1, 0x01, 0x2E,
+ 0x02, 0xD0, 0x02, 0x2E, 0x03, 0xD0, 0x04, 0xE0, 0x40, 0xF2, 0x41, 0x25,
+ 0x01, 0xE0, 0x40, 0xF2, 0x42, 0x25, 0x04, 0xF1, 0x40, 0x00, 0x00, 0xF0,
+ 0x73, 0xFF, 0x60, 0x88, 0x29, 0x46, 0xFA, 0xF7, 0x6D, 0xFB, 0x00, 0x20,
+ 0xA0, 0x71, 0x70, 0xBD, 0xCC, 0x1D, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21,
+ 0x37, 0xB5, 0x84, 0xB0, 0x04, 0x46, 0x9D, 0xF8, 0x14, 0x00, 0xBD, 0xF8,
+ 0x16, 0x20, 0x9D, 0xF8, 0x15, 0x10, 0x8D, 0xE8, 0x07, 0x00, 0x63, 0x88,
+ 0x04, 0x22, 0x32, 0x49, 0x32, 0x48, 0xE8, 0xF7, 0xFE, 0xDF, 0x31, 0x4D,
+ 0x9D, 0xF8, 0x15, 0x00, 0xED, 0x1E, 0x98, 0xB1, 0x9D, 0xF8, 0x14, 0x00,
+ 0x03, 0x21, 0xFF, 0xF7, 0x4F, 0xF9, 0xD8, 0xB1, 0x9D, 0xF8, 0x14, 0x10,
+ 0x13, 0x29, 0x3D, 0xD0, 0x10, 0xDC, 0x01, 0x29, 0x26, 0xD0, 0x06, 0x29,
+ 0x29, 0xD0, 0x07, 0x29, 0x2C, 0xD0, 0x12, 0x29, 0x0E, 0xD1, 0x2E, 0xE0,
+ 0x23, 0x49, 0x00, 0x22, 0x44, 0x31, 0x28, 0x46, 0xE8, 0xF7, 0xDF, 0xDF,
+ 0x07, 0xB0, 0x30, 0xBD, 0x14, 0x29, 0x2E, 0xD0, 0x15, 0x29, 0x31, 0xD0,
+ 0x16, 0x29, 0x34, 0xD0, 0x1C, 0x49, 0x9D, 0xF8, 0x14, 0x30, 0x01, 0x22,
+ 0x70, 0x31, 0x28, 0x46, 0xE8, 0xF7, 0xCF, 0xDF, 0x9D, 0xF8, 0x15, 0x00,
+ 0x00, 0x23, 0xE0, 0x71, 0x1A, 0x46, 0x19, 0x46, 0x20, 0x46, 0x00, 0xF0,
+ 0x4F, 0xFA, 0xE5, 0xE7, 0x05, 0xA9, 0x20, 0x46, 0xFF, 0xF7, 0x54, 0xFB,
+ 0xE0, 0xE7, 0x05, 0xA9, 0x20, 0x46, 0xFF, 0xF7, 0x0F, 0xFD, 0xDB, 0xE7,
+ 0x05, 0xA9, 0x20, 0x46, 0xFF, 0xF7, 0x46, 0xFD, 0xD6, 0xE7, 0x05, 0xA9,
+ 0x20, 0x46, 0xFF, 0xF7, 0x13, 0xFF, 0xD1, 0xE7, 0x05, 0xA9, 0x20, 0x46,
+ 0xFF, 0xF7, 0x70, 0xFF, 0xCC, 0xE7, 0x05, 0xA9, 0x20, 0x46, 0xFF, 0xF7,
+ 0x9D, 0xFD, 0xC7, 0xE7, 0x05, 0xA9, 0x20, 0x46, 0x00, 0xF0, 0x9C, 0xF8,
+ 0xC2, 0xE7, 0x05, 0xA9, 0x20, 0x46, 0x00, 0xF0, 0xFF, 0xF8, 0xBD, 0xE7,
+ 0xE0, 0x17, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x2D, 0xE9, 0xF8, 0x43,
+ 0x81, 0x46, 0x0F, 0x46, 0xC8, 0x68, 0xC9, 0x88, 0xDF, 0xF8, 0x74, 0x80,
+ 0x44, 0x18, 0x38, 0x89, 0x05, 0x19, 0x2A, 0xE0, 0x20, 0x1D, 0xA8, 0x42,
+ 0x05, 0xD9, 0x00, 0x22, 0x19, 0x49, 0x40, 0x46, 0xE8, 0xF7, 0x85, 0xDF,
+ 0x23, 0xE0, 0x20, 0x78, 0x62, 0x1C, 0x60, 0xF3, 0x07, 0x06, 0x12, 0xF8,
+ 0x01, 0x0B, 0x60, 0xF3, 0x0F, 0x26, 0x12, 0xF8, 0x01, 0x0B, 0x12, 0xF8,
+ 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x20, 0x83, 0xB2, 0xA8, 0x1A, 0x63, 0xF3,
+ 0x1F, 0x46, 0x83, 0x42, 0x08, 0xDD, 0xA8, 0x1A, 0x0C, 0x49, 0x00, 0x90,
+ 0x02, 0x22, 0x34, 0x31, 0x40, 0x46, 0xE8, 0xF7, 0x68, 0xDF, 0x06, 0xE0,
+ 0x9C, 0x18, 0x31, 0x46, 0x48, 0x46, 0xFF, 0xF7, 0x53, 0xFF, 0xAC, 0x42,
+ 0xD2, 0xD3, 0xF8, 0x68, 0xBD, 0xE8, 0xF8, 0x43, 0x40, 0xF2, 0xCD, 0x32,
+ 0x03, 0x49, 0xF0, 0xF7, 0xDB, 0xBD, 0x00, 0x00, 0x01, 0x3B, 0x10, 0x21,
+ 0x80, 0x18, 0xC0, 0x08, 0xF6, 0xA7, 0x82, 0x00, 0x3E, 0xB5, 0x0D, 0x46,
+ 0x04, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22, 0x1F, 0x49, 0x20, 0x48,
+ 0xE8, 0xF7, 0x47, 0xDF, 0x81, 0x2C, 0x26, 0xD0, 0x82, 0x2C, 0x0A, 0xD0,
+ 0x03, 0xB0, 0x23, 0x46, 0x1A, 0x49, 0x1B, 0x48, 0xBD, 0xE8, 0x30, 0x40,
+ 0x01, 0x22, 0x38, 0x31, 0x80, 0x1E, 0xE8, 0xF7, 0x38, 0x9F, 0x28, 0x46,
+ 0xFF, 0xF7, 0xE6, 0xF9, 0x04, 0x00, 0x13, 0xD0, 0x04, 0xF1, 0x40, 0x00,
+ 0xF1, 0xF7, 0xD8, 0xFC, 0x02, 0x20, 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x20,
+ 0x8D, 0xF8, 0x01, 0x00, 0xCD, 0xF8, 0x08, 0xD0, 0x01, 0xA9, 0x20, 0x46,
+ 0xFF, 0xF7, 0xE6, 0xFE, 0x60, 0x88, 0x3B, 0x21, 0xFC, 0xF7, 0x8C, 0xFC,
+ 0x3E, 0xBD, 0x28, 0x46, 0xFF, 0xF7, 0xF6, 0xF9, 0x04, 0x00, 0xF9, 0xD0,
+ 0x04, 0xF1, 0x08, 0x00, 0xF1, 0xF7, 0xBE, 0xFC, 0x03, 0xB0, 0x20, 0x46,
+ 0xBD, 0xE8, 0x30, 0x40, 0x00, 0x22, 0x4F, 0xF4, 0x40, 0x71, 0xFE, 0xF7,
+ 0x19, 0xBE, 0x00, 0x00, 0x2C, 0x19, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21,
+ 0x2D, 0xE9, 0xF8, 0x43, 0x0D, 0x46, 0x49, 0x68, 0x11, 0xF8, 0x01, 0x2B,
+ 0x11, 0xF8, 0x01, 0x3B, 0x69, 0x60, 0x02, 0xEB, 0x03, 0x22, 0x1F, 0xFA,
+ 0x82, 0xF9, 0x11, 0xF8, 0x01, 0x2B, 0x11, 0xF8, 0x01, 0x3B, 0x69, 0x60,
+ 0x02, 0xEB, 0x03, 0x22, 0x1F, 0xFA, 0x82, 0xF8, 0x11, 0xF8, 0x01, 0x2B,
+ 0x11, 0xF8, 0x01, 0x3B, 0x69, 0x60, 0x02, 0xEB, 0x03, 0x22, 0x96, 0xB2,
+ 0x11, 0xF8, 0x01, 0x2B, 0x11, 0xF8, 0x01, 0x3B, 0x69, 0x60, 0x02, 0xEB,
+ 0x03, 0x22, 0x97, 0xB2, 0x11, 0xF8, 0x01, 0x2B, 0x11, 0xF8, 0x01, 0x3B,
+ 0x02, 0xEB, 0x03, 0x22, 0xAD, 0xF8, 0x00, 0x20, 0x69, 0x60, 0x69, 0x78,
+ 0xFF, 0xF7, 0xA0, 0xF9, 0x04, 0x00, 0x0F, 0xD0, 0x04, 0xF1, 0x08, 0x00,
+ 0x00, 0xF0, 0x28, 0xFE, 0xBD, 0xF8, 0x00, 0x00, 0x80, 0xB1, 0x30, 0x30,
+ 0x40, 0xF4, 0x00, 0x70, 0xAD, 0xF8, 0x00, 0x00, 0x6A, 0x46, 0x40, 0xF2,
+ 0x03, 0x21, 0x19, 0xE0, 0x6B, 0x78, 0x01, 0x22, 0x0D, 0x49, 0x0E, 0x48,
+ 0xE8, 0xF7, 0xBD, 0xDE, 0xBD, 0xE8, 0xF8, 0x83, 0xA4, 0xF8, 0x0E, 0x90,
+ 0x0B, 0x48, 0xA4, 0xF8, 0x12, 0x80, 0xA4, 0xF8, 0x46, 0x70, 0xB0, 0xF8,
+ 0xA4, 0x01, 0x80, 0x1E, 0xB0, 0x42, 0x01, 0xDA, 0xE0, 0x82, 0x00, 0xE0,
+ 0xE6, 0x82, 0x00, 0x22, 0x40, 0xF2, 0x01, 0x21, 0x20, 0x46, 0xFE, 0xF7,
+ 0xB3, 0xFD, 0xE7, 0xE7, 0x88, 0x1F, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21,
+ 0x64, 0x01, 0x20, 0x00, 0x38, 0xB5, 0x4A, 0x68, 0x12, 0xF8, 0x01, 0x3B,
+ 0x12, 0xF8, 0x01, 0x4B, 0x4A, 0x60, 0x03, 0xEB, 0x04, 0x23, 0x12, 0xF8,
+ 0x01, 0x4B, 0x9B, 0xB2, 0x12, 0xF8, 0x01, 0x5B, 0x4A, 0x60, 0x04, 0xEB,
+ 0x05, 0x25, 0x19, 0x46, 0xFF, 0xF7, 0x74, 0xF9, 0x04, 0x00, 0x1C, 0xD0,
+ 0x2B, 0x46, 0x01, 0x22, 0x0D, 0x49, 0x0E, 0x48, 0xE8, 0xF7, 0x83, 0xDE,
+ 0xB4, 0xF8, 0x46, 0x00, 0x28, 0x44, 0xB0, 0xF5, 0x80, 0x3F, 0x06, 0xD2,
+ 0xA4, 0xF8, 0x46, 0x00, 0x20, 0x46, 0xBD, 0xE8, 0x38, 0x40, 0x00, 0xF0,
+ 0xB5, 0xBB, 0x4F, 0xF4, 0x3C, 0x70, 0xAD, 0xF8, 0x00, 0x00, 0x6A, 0x46,
+ 0x40, 0xF2, 0x07, 0x11, 0x20, 0x46, 0xFE, 0xF7, 0x79, 0xFD, 0x38, 0xBD,
+ 0xB8, 0x1F, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x13, 0xB5, 0x01, 0xAA,
+ 0x01, 0x21, 0xFE, 0xF7, 0x6F, 0xFD, 0x1C, 0xBD, 0x2D, 0xE9, 0xF0, 0x47,
+ 0x2B, 0x4A, 0x2C, 0x49, 0x10, 0x1F, 0xF0, 0xF7, 0xA9, 0xFD, 0x00, 0x28,
+ 0x4D, 0xD0, 0x28, 0x48, 0x0C, 0x30, 0xF3, 0xF7, 0xAD, 0xDD, 0x26, 0x4E,
+ 0x27, 0x4F, 0x1E, 0x20, 0x30, 0x76, 0x97, 0xF8, 0xCA, 0x01, 0x48, 0xB1,
+ 0x81, 0x00, 0x4F, 0xF4, 0xB1, 0x63, 0x24, 0x4A, 0x00, 0x20, 0xF3, 0xF7,
+ 0xDB, 0xDB, 0x70, 0x60, 0x00, 0x28, 0x38, 0xD0, 0x97, 0xF8, 0x98, 0x01,
+ 0x28, 0xB3, 0x00, 0xEB, 0x00, 0x10, 0x81, 0x00, 0x40, 0xF2, 0xA4, 0x53,
+ 0x1C, 0x4A, 0x00, 0x20, 0xF3, 0xF7, 0xCC, 0xDB, 0x30, 0x60, 0x00, 0x28,
+ 0x29, 0xD0, 0x00, 0x24, 0x4F, 0xF0, 0x14, 0x08, 0x4F, 0xF0, 0x1C, 0x09,
+ 0x0F, 0xE0, 0x04, 0xEB, 0x04, 0x15, 0x30, 0x68, 0x08, 0xEB, 0x85, 0x01,
+ 0x08, 0x44, 0xF1, 0xF7, 0x7C, 0xF9, 0x31, 0x68, 0x09, 0xEB, 0x85, 0x00,
+ 0x08, 0x44, 0xF1, 0xF7, 0x76, 0xF9, 0x64, 0x1C, 0xA4, 0xB2, 0x97, 0xF8,
+ 0x98, 0x01, 0xA0, 0x42, 0xEB, 0xD8, 0x97, 0xF8, 0x99, 0x01, 0x58, 0xB1,
+ 0x4C, 0x21, 0x10, 0xFB, 0x01, 0xF1, 0x40, 0xF2, 0xB4, 0x53, 0x08, 0x4A,
+ 0x00, 0x20, 0xF3, 0xF7, 0xA3, 0xDB, 0xB0, 0x60, 0x00, 0x28, 0x00, 0xD0,
+ 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0x00, 0x00, 0x68, 0x76, 0x20, 0x00,
+ 0x15, 0xE5, 0x81, 0x00, 0x64, 0x01, 0x20, 0x00, 0x3E, 0xA8, 0x82, 0x00,
+ 0x01, 0x46, 0x01, 0x48, 0xF3, 0xF7, 0x59, 0x9D, 0x74, 0x76, 0x20, 0x00,
+ 0x2D, 0xE9, 0xF0, 0x41, 0x06, 0x46, 0x08, 0x48, 0x17, 0x46, 0x0D, 0x46,
+ 0xC0, 0x68, 0x07, 0xE0, 0xD0, 0xE9, 0x00, 0x41, 0xB1, 0x42, 0x02, 0xD1,
+ 0x0D, 0xB1, 0x39, 0x46, 0xA8, 0x47, 0x20, 0x46, 0x00, 0x28, 0xF5, 0xD1,
+ 0xBD, 0xE8, 0xF0, 0x81, 0x68, 0x76, 0x20, 0x00, 0x38, 0xB5, 0x04, 0x68,
+ 0x05, 0x46, 0x03, 0x46, 0x02, 0x22, 0x0F, 0x49, 0x0F, 0x48, 0x00, 0x94,
+ 0xE8, 0xF7, 0xD9, 0xDD, 0x4F, 0xF4, 0x3C, 0x72, 0x0D, 0x49, 0x28, 0x46,
+ 0xF0, 0xF7, 0x56, 0xFC, 0x94, 0xF8, 0x34, 0x00, 0x01, 0x28, 0x0D, 0xD1,
+ 0x20, 0x7F, 0x06, 0x28, 0x0A, 0xD1, 0x60, 0x68, 0xA1, 0x89, 0x00, 0x22,
+ 0x40, 0x88, 0xF3, 0xF7, 0x10, 0xFD, 0x20, 0x46, 0xBD, 0xE8, 0x38, 0x40,
+ 0x00, 0xF0, 0x00, 0xBB, 0x38, 0xBD, 0x00, 0x00, 0x60, 0x20, 0xC0, 0x08,
+ 0x03, 0x3B, 0x10, 0x21, 0x80, 0xA8, 0x82, 0x00, 0x00, 0xF0, 0xF6, 0xBA,
+ 0x10, 0xB5, 0x04, 0x46, 0x03, 0x46, 0x01, 0x22, 0x09, 0x49, 0x0A, 0x48,
+ 0xE8, 0xF7, 0xAF, 0xDD, 0x20, 0x7F, 0x06, 0x28, 0x0A, 0xD1, 0x60, 0x68,
+ 0xA1, 0x89, 0x00, 0x22, 0x40, 0x88, 0xF3, 0xF7, 0xF0, 0xFC, 0x20, 0x46,
+ 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0xE0, 0xBA, 0x10, 0xBD, 0x00, 0x00,
+ 0x8C, 0x20, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x38, 0xB5, 0x05, 0x68,
+ 0x04, 0x46, 0x03, 0x46, 0x02, 0x22, 0x08, 0x49, 0x08, 0x48, 0x00, 0x95,
+ 0xE8, 0xF7, 0x91, 0xDD, 0x4F, 0xF4, 0x91, 0x72, 0x06, 0x49, 0x20, 0x46,
+ 0xF0, 0xF7, 0x0E, 0xFC, 0x28, 0x46, 0xBD, 0xE8, 0x38, 0x40, 0x00, 0xF0,
+ 0x99, 0xB8, 0x00, 0x00, 0xFC, 0x13, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21,
+ 0x86, 0xA7, 0x82, 0x00, 0x40, 0xF2, 0x23, 0x42, 0x01, 0x49, 0xF0, 0xF7,
+ 0xFD, 0xBB, 0x00, 0x00, 0x0C, 0xA8, 0x82, 0x00, 0x2D, 0xE9, 0xFF, 0x41,
+ 0x1E, 0x46, 0x17, 0x46, 0x80, 0x46, 0x0D, 0x46, 0x0B, 0x46, 0x02, 0xAC,
+ 0x01, 0x22, 0x18, 0x49, 0x18, 0x48, 0xE8, 0xF7, 0x6A, 0xDD, 0x28, 0x0A,
+ 0x8D, 0xF8, 0x08, 0x50, 0x8D, 0xF8, 0x09, 0x00, 0xA4, 0x1C, 0xB5, 0xB1,
+ 0x38, 0x0A, 0xF9, 0xB2, 0x01, 0x2D, 0x02, 0xD0, 0x02, 0x2D, 0x10, 0xD1,
+ 0x05, 0xE0, 0x8D, 0xF8, 0x0A, 0x10, 0x8D, 0xF8, 0x0B, 0x00, 0xA4, 0x1C,
+ 0x09, 0xE0, 0x8D, 0xF8, 0x0A, 0x10, 0x8D, 0xF8, 0x0B, 0x00, 0x30, 0x0A,
+ 0x8D, 0xF8, 0x0C, 0x60, 0x8D, 0xF8, 0x0D, 0x00, 0x24, 0x1D, 0x02, 0xA8,
+ 0x20, 0x1A, 0x00, 0x21, 0x80, 0xB2, 0xCD, 0xE9, 0x00, 0x01, 0x02, 0xAB,
+ 0x01, 0x22, 0x41, 0x46, 0x00, 0x20, 0x00, 0xF0, 0xDB, 0xFB, 0xBD, 0xE8,
+ 0xFF, 0x81, 0x00, 0x00, 0x58, 0x16, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21,
+ 0x3E, 0xB5, 0x04, 0x46, 0x80, 0x89, 0x00, 0x90, 0xE3, 0x89, 0x02, 0x22,
+ 0x0D, 0x49, 0x0E, 0x48, 0xE8, 0xF7, 0x2F, 0xDD, 0xE0, 0x89, 0x8D, 0xF8,
+ 0x08, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x09, 0x00, 0x20, 0x7B, 0x8D, 0xF8,
+ 0x0A, 0x00, 0xA0, 0x89, 0x00, 0x21, 0x00, 0x0A, 0x8D, 0xF8, 0x0B, 0x00,
+ 0x04, 0x20, 0xCD, 0xE9, 0x00, 0x01, 0x02, 0xAB, 0x06, 0x22, 0x20, 0x46,
+ 0x00, 0xF0, 0xB4, 0xFB, 0x3E, 0xBD, 0x00, 0x00, 0x7C, 0x16, 0xC0, 0x08,
+ 0x03, 0x3B, 0x10, 0x21, 0x3E, 0xB5, 0x04, 0x46, 0xC0, 0x89, 0x00, 0x90,
+ 0xA3, 0x89, 0x02, 0x22, 0x0D, 0x49, 0x0E, 0x48, 0xE8, 0xF7, 0x09, 0xDD,
+ 0xA0, 0x89, 0x8D, 0xF8, 0x08, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x09, 0x00,
+ 0xA0, 0x7B, 0x8D, 0xF8, 0x0A, 0x00, 0xE0, 0x89, 0x00, 0x21, 0x00, 0x0A,
+ 0x8D, 0xF8, 0x0B, 0x00, 0x04, 0x20, 0xCD, 0xE9, 0x00, 0x01, 0x02, 0xAB,
+ 0x07, 0x22, 0x20, 0x46, 0x00, 0xF0, 0x8E, 0xFB, 0x3E, 0xBD, 0x00, 0x00,
+ 0xAC, 0x16, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x4F,
+ 0x04, 0x46, 0x00, 0x79, 0x8B, 0xB0, 0x80, 0xB1, 0x01, 0x28, 0x0E, 0xD0,
+ 0x67, 0x48, 0x00, 0x27, 0x4F, 0xF0, 0x18, 0x08, 0x45, 0x8B, 0x66, 0x48,
+ 0x90, 0xF8, 0x00, 0xA0, 0x05, 0xF1, 0x18, 0x00, 0x1F, 0xFA, 0x80, 0xFB,
+ 0x60, 0x6B, 0x40, 0xB1, 0x34, 0xE0, 0x00, 0x90, 0x23, 0x46, 0x02, 0x22,
+ 0x60, 0x49, 0x61, 0x48, 0xE8, 0xF7, 0xCF, 0xDC, 0xB5, 0xE0, 0x40, 0xF2,
+ 0x5D, 0x13, 0x5F, 0x4A, 0x01, 0xA9, 0x04, 0xF1, 0x1C, 0x00, 0xF1, 0xF7,
+ 0x69, 0xF8, 0x48, 0xB9, 0x40, 0xF2, 0x5F, 0x13, 0x5A, 0x4A, 0x01, 0xA9,
+ 0x04, 0xF1, 0x14, 0x00, 0xF1, 0xF7, 0x60, 0xF8, 0x00, 0x28, 0x7D, 0xD0,
+ 0xBD, 0xF8, 0x0C, 0x00, 0xA8, 0x42, 0x05, 0xD8, 0x60, 0x88, 0x01, 0x22,
+ 0x01, 0xA9, 0x00, 0xF0, 0xAB, 0xF8, 0xD7, 0xE7, 0x04, 0x98, 0x60, 0x63,
+ 0xBD, 0xF8, 0x0A, 0x00, 0x20, 0x87, 0xBD, 0xF8, 0x0C, 0x00, 0x60, 0x87,
+ 0xBD, 0xF8, 0x0E, 0x00, 0xA0, 0x87, 0xBD, 0xF8, 0x08, 0x00, 0x20, 0xF0,
+ 0x02, 0x00, 0xE0, 0x87, 0x94, 0xF8, 0x3E, 0x00, 0x40, 0xF3, 0x40, 0x00,
+ 0x00, 0xF1, 0x01, 0x09, 0x60, 0x8F, 0xA8, 0x42, 0x3E, 0xD9, 0x4F, 0xF4,
+ 0xBC, 0x73, 0x44, 0x4A, 0x59, 0x46, 0x50, 0x46, 0xF0, 0xF7, 0x26, 0xFA,
+ 0x06, 0x00, 0x71, 0xD0, 0x40, 0xF2, 0x7F, 0x10, 0x00, 0x90, 0x3F, 0x4B,
+ 0x22, 0x46, 0x3F, 0x49, 0x30, 0x46, 0xF0, 0xF7, 0xE1, 0xF9, 0x00, 0x28,
+ 0x6A, 0xD0, 0x39, 0x49, 0x39, 0x48, 0x00, 0x95, 0xA3, 0x8F, 0x02, 0x22,
+ 0x38, 0x31, 0x80, 0x1C, 0xE8, 0xF7, 0x7B, 0xDC, 0x21, 0x8F, 0x60, 0x6B,
+ 0x2A, 0x46, 0x01, 0x44, 0x06, 0xF1, 0x18, 0x00, 0x1A, 0xF4, 0x87, 0xF5,
+ 0x09, 0x96, 0xAD, 0xF8, 0x1E, 0x80, 0xE0, 0x8F, 0xAD, 0xF8, 0x20, 0x50,
+ 0x40, 0xF0, 0x01, 0x00, 0xAD, 0xF8, 0x1C, 0x00, 0x60, 0x88, 0x4A, 0x46,
+ 0x06, 0xA9, 0x00, 0xF0, 0x5D, 0xF8, 0x20, 0x8F, 0x28, 0x44, 0x20, 0x87,
+ 0x60, 0x8F, 0x40, 0x1B, 0x60, 0x87, 0xE0, 0x8F, 0x40, 0xF0, 0x02, 0x00,
+ 0xE0, 0x87, 0x7F, 0xE7, 0x40, 0xF2, 0x97, 0x13, 0x24, 0x4A, 0x59, 0x46,
+ 0x50, 0x46, 0xF0, 0xF7, 0xE7, 0xF9, 0x06, 0x00, 0x32, 0xD0, 0x60, 0x8F,
+ 0x00, 0x90, 0x1E, 0x49, 0x1E, 0x48, 0xA3, 0x8F, 0x02, 0x22, 0x70, 0x31,
+ 0x80, 0x1C, 0xE8, 0xF7, 0x46, 0xDC, 0x21, 0x8F, 0x60, 0x6B, 0x62, 0x8F,
+ 0x01, 0x44, 0x06, 0xF1, 0x18, 0x00, 0x1A, 0xF4, 0x52, 0xF5, 0x00, 0xE0,
+ 0x1E, 0xE0, 0x60, 0x6B, 0x16, 0x4B, 0x18, 0x49, 0x04, 0x60, 0x40, 0xF2,
+ 0xA5, 0x10, 0x00, 0x90, 0x30, 0x46, 0x62, 0x6B, 0xF0, 0xF7, 0x8C, 0xF9,
+ 0xB0, 0xB1, 0x09, 0x96, 0xAD, 0xF8, 0x1E, 0x80, 0xE0, 0x8F, 0x4A, 0x46,
+ 0x40, 0xF0, 0x01, 0x00, 0xAD, 0xF8, 0x1C, 0x00, 0x60, 0x8F, 0xAD, 0xF8,
+ 0x20, 0x00, 0x60, 0x88, 0x06, 0xA9, 0x00, 0xF0, 0x19, 0xF8, 0x67, 0x63,
+ 0x67, 0x87, 0x43, 0xE7, 0x01, 0x20, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F,
+ 0x67, 0x63, 0x00, 0x20, 0xF9, 0xE7, 0x00, 0x00, 0x68, 0x76, 0x20, 0x00,
+ 0x05, 0x74, 0x20, 0x00, 0x24, 0x14, 0xC0, 0x08, 0x01, 0x3B, 0x10, 0x21,
+ 0xAC, 0xA7, 0x82, 0x00, 0x79, 0xE6, 0x81, 0x00, 0x21, 0xF5, 0x81, 0x00,
+ 0x8B, 0x88, 0x23, 0xF0, 0x18, 0x03, 0x8B, 0x80, 0x0A, 0xB1, 0x08, 0x22,
+ 0x00, 0xE0, 0x10, 0x22, 0x13, 0x43, 0x8B, 0x80, 0x48, 0x81, 0x4F, 0xF4,
+ 0x00, 0x70, 0x08, 0x80, 0x04, 0x48, 0x4F, 0xF4, 0x97, 0x73, 0x02, 0x4A,
+ 0x00, 0x78, 0xF0, 0xF7, 0x8D, 0xBC, 0x00, 0x00, 0x97, 0xA7, 0x82, 0x00,
+ 0xEC, 0x75, 0x20, 0x00, 0x70, 0xB5, 0x86, 0xB0, 0x00, 0x24, 0x06, 0x46,
+ 0x8D, 0xF8, 0x08, 0x40, 0x8D, 0xF8, 0x0C, 0x40, 0x8D, 0xF8, 0x10, 0x10,
+ 0x08, 0x0A, 0x8D, 0xF8, 0x09, 0x40, 0x8D, 0xF8, 0x0D, 0x40, 0x8D, 0xF8,
+ 0x0A, 0x40, 0x8D, 0xF8, 0x0E, 0x40, 0x8D, 0xF8, 0x11, 0x00, 0x0B, 0x46,
+ 0x0D, 0xF1, 0x12, 0x05, 0x8D, 0xF8, 0x0B, 0x40, 0x8D, 0xF8, 0x0F, 0x40,
+ 0x01, 0x22, 0x08, 0x49, 0x08, 0x48, 0xE8, 0xF7, 0xCC, 0xDB, 0x02, 0xA8,
+ 0x28, 0x1A, 0x80, 0xB2, 0xCD, 0xE9, 0x00, 0x04, 0x02, 0xAB, 0x15, 0x22,
+ 0x31, 0x46, 0x00, 0x20, 0x00, 0xF0, 0x5C, 0xFA, 0x06, 0xB0, 0x70, 0xBD,
+ 0xA0, 0x1E, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21, 0x30, 0xB5, 0x87, 0xB0,
+ 0x04, 0x46, 0x00, 0x8B, 0x8D, 0xF8, 0x10, 0x00, 0x00, 0x0A, 0x8D, 0xF8,
+ 0x11, 0x00, 0x20, 0x7B, 0x8D, 0xF8, 0x12, 0x00, 0xA0, 0x89, 0x0D, 0xF1,
+ 0x1A, 0x05, 0x00, 0x0A, 0x8D, 0xF8, 0x13, 0x00, 0x20, 0x7C, 0x8D, 0xF8,
+ 0x14, 0x00, 0x20, 0x8A, 0x00, 0x0A, 0x8D, 0xF8, 0x15, 0x00, 0x20, 0x7D,
+ 0x8D, 0xF8, 0x16, 0x00, 0xA0, 0x8A, 0x00, 0x0A, 0x8D, 0xF8, 0x17, 0x00,
+ 0x94, 0xF8, 0x44, 0x00, 0x8D, 0xF8, 0x18, 0x00, 0xB4, 0xF8, 0x44, 0x00,
+ 0x00, 0x0A, 0x8D, 0xF8, 0x19, 0x00, 0xA0, 0x89, 0xB4, 0xF8, 0x44, 0x30,
+ 0xA2, 0x8A, 0x21, 0x8A, 0x8D, 0xE8, 0x0F, 0x00, 0x23, 0x8B, 0x05, 0x22,
+ 0x08, 0x49, 0x09, 0x48, 0xE8, 0xF7, 0x85, 0xDB, 0x04, 0xA8, 0x28, 0x1A,
+ 0x00, 0x21, 0x80, 0xB2, 0xCD, 0xE9, 0x00, 0x01, 0x04, 0xAB, 0x14, 0x22,
+ 0x20, 0x46, 0x00, 0xF0, 0x15, 0xFA, 0x07, 0xB0, 0x30, 0xBD, 0x00, 0x00,
+ 0x44, 0x1E, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x30, 0xB5, 0x87, 0xB0,
+ 0x04, 0x46, 0x80, 0x89, 0x8D, 0xF8, 0x10, 0x00, 0x00, 0x0A, 0x8D, 0xF8,
+ 0x11, 0x00, 0x20, 0x7C, 0x8D, 0xF8, 0x12, 0x00, 0x20, 0x8A, 0x0D, 0xF1,
+ 0x1A, 0x05, 0x00, 0x0A, 0x8D, 0xF8, 0x13, 0x00, 0x20, 0x7D, 0x8D, 0xF8,
+ 0x14, 0x00, 0xA0, 0x8A, 0x00, 0x0A, 0x8D, 0xF8, 0x15, 0x00, 0x94, 0xF8,
+ 0x44, 0x00, 0x8D, 0xF8, 0x16, 0x00, 0xB4, 0xF8, 0x44, 0x00, 0x8D, 0xF8,
+ 0x18, 0x10, 0x00, 0x0A, 0x8D, 0xF8, 0x17, 0x00, 0x08, 0x0A, 0x8D, 0xF8,
+ 0x19, 0x00, 0xA2, 0x8A, 0xB4, 0xF8, 0x44, 0x00, 0x23, 0x8A, 0xCD, 0xE9,
+ 0x00, 0x32, 0xCD, 0xE9, 0x02, 0x01, 0xA3, 0x89, 0x05, 0x22, 0x08, 0x49,
+ 0x08, 0x48, 0xE8, 0xF7, 0x3E, 0xDB, 0x04, 0xA8, 0x28, 0x1A, 0x00, 0x21,
+ 0x80, 0xB2, 0xCD, 0xE9, 0x00, 0x01, 0x04, 0xAB, 0x15, 0x22, 0x20, 0x46,
+ 0x00, 0xF0, 0xCE, 0xF9, 0x07, 0xB0, 0x30, 0xBD, 0xC4, 0x1E, 0xC0, 0x08,
+ 0x03, 0x3B, 0x10, 0x21, 0x3E, 0xB5, 0x04, 0x46, 0x80, 0x89, 0xCD, 0xE9,
+ 0x00, 0x01, 0x0D, 0x46, 0xE3, 0x89, 0x03, 0x22, 0x0C, 0x49, 0x0D, 0x48,
+ 0xE8, 0xF7, 0x21, 0xDB, 0xA0, 0x89, 0x8D, 0xF8, 0x08, 0x00, 0x00, 0x0A,
+ 0x8D, 0xF8, 0x09, 0x00, 0x8D, 0xF8, 0x0A, 0x50, 0x28, 0x0A, 0x8D, 0xF8,
+ 0x0B, 0x00, 0x00, 0x21, 0x04, 0x20, 0xCD, 0xE9, 0x00, 0x01, 0x02, 0xAB,
+ 0x16, 0x22, 0x20, 0x46, 0x00, 0xF0, 0xA8, 0xF9, 0x3E, 0xBD, 0x00, 0x00,
+ 0x1C, 0x1F, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x06, 0x46,
+ 0xCB, 0x88, 0xC8, 0x68, 0x0C, 0x46, 0xC5, 0x18, 0x96, 0xF8, 0x34, 0x00,
+ 0x40, 0xB1, 0x1C, 0x2B, 0x0D, 0xD2, 0x01, 0x22, 0x19, 0x49, 0x1A, 0x48,
+ 0xE8, 0xF7, 0xF7, 0xDA, 0x00, 0x20, 0x70, 0xBD, 0x03, 0x46, 0x16, 0x49,
+ 0x16, 0x48, 0x01, 0x22, 0x20, 0x39, 0x40, 0x1C, 0xF4, 0xE7, 0x22, 0x89,
+ 0xF0, 0x8A, 0x82, 0x42, 0x13, 0xD8, 0xA8, 0x1E, 0x29, 0x46, 0xEE, 0xF7,
+ 0x1A, 0xFD, 0x20, 0x7A, 0x05, 0xF8, 0x04, 0x0D, 0x20, 0x89, 0x00, 0x0A,
+ 0x68, 0x70, 0xA0, 0x88, 0x40, 0xF0, 0x04, 0x00, 0xA0, 0x80, 0x20, 0x89,
+ 0x80, 0x1C, 0x20, 0x81, 0xE0, 0x88, 0x00, 0x1F, 0xE0, 0x80, 0x40, 0xF2,
+ 0xD6, 0x33, 0x08, 0x4A, 0x21, 0x46, 0x06, 0xF1, 0x20, 0x00, 0xF0, 0xF7,
+ 0x9B, 0xFE, 0x00, 0x28, 0xD5, 0xD0, 0x30, 0x46, 0xBD, 0xE8, 0x70, 0x40,
+ 0x00, 0xF0, 0x06, 0xB8, 0xA8, 0x21, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21,
+ 0xAC, 0xA8, 0x82, 0x00, 0x2D, 0xE9, 0xF0, 0x43, 0x90, 0xF8, 0x34, 0x30,
+ 0xDF, 0xF8, 0x04, 0x82, 0x8B, 0xB0, 0x04, 0x46, 0x4B, 0xB1, 0x80, 0x4E,
+ 0x08, 0xF1, 0x02, 0x09, 0x00, 0x25, 0xB4, 0xF8, 0x46, 0x00, 0x40, 0xB1,
+ 0xA0, 0x6A, 0x70, 0xB1, 0x2D, 0xE0, 0x01, 0x22, 0x7B, 0x49, 0x40, 0x46,
+ 0xE8, 0xF7, 0xA9, 0xDA, 0xEB, 0xE0, 0x79, 0x49, 0x23, 0x8E, 0x01, 0x22,
+ 0x24, 0x31, 0x40, 0x46, 0xE8, 0xF7, 0xA1, 0xDA, 0xDE, 0xE0, 0x4F, 0xF4,
+ 0x4B, 0x73, 0x75, 0x4A, 0x06, 0xA9, 0x04, 0xF1, 0x20, 0x00, 0xF0, 0xF7,
+ 0x3B, 0xFE, 0x00, 0x28, 0xF4, 0xD0, 0xBD, 0xF8, 0x1C, 0x00, 0x20, 0xF0,
+ 0x38, 0x00, 0x40, 0xF0, 0x08, 0x00, 0xAD, 0xF8, 0x1C, 0x00, 0x09, 0x98,
+ 0xA0, 0x62, 0xBD, 0xF8, 0x1E, 0x00, 0xA0, 0x85, 0xBD, 0xF8, 0x20, 0x00,
+ 0xE0, 0x85, 0xBD, 0xF8, 0x22, 0x00, 0x20, 0x86, 0xBD, 0xF8, 0x1C, 0x00,
+ 0x60, 0x86, 0x62, 0x8E, 0x50, 0x07, 0x10, 0xD5, 0x09, 0x98, 0x64, 0x4B,
+ 0x22, 0x46, 0x04, 0x60, 0x40, 0xF2, 0x3F, 0x30, 0x00, 0x90, 0x62, 0x49,
+ 0x09, 0x98, 0xEF, 0xF7, 0xCD, 0xFF, 0x00, 0x28, 0x7D, 0xD0, 0xE0, 0x89,
+ 0x06, 0xAA, 0x61, 0x68, 0xA0, 0xE0, 0xE0, 0x8A, 0x12, 0x07, 0x00, 0xF1,
+ 0x1C, 0x01, 0x89, 0xB2, 0x01, 0xD5, 0x89, 0x1C, 0x89, 0xB2, 0xE2, 0x8D,
+ 0x82, 0x42, 0x58, 0xD9, 0x4F, 0xF4, 0x56, 0x73, 0x55, 0x4A, 0x30, 0x78,
+ 0xEF, 0xF7, 0xF0, 0xFF, 0x07, 0x00, 0x67, 0xD0, 0x40, 0xF2, 0x5F, 0x30,
+ 0x00, 0x90, 0x51, 0x4B, 0x22, 0x46, 0x52, 0x49, 0x38, 0x46, 0xEF, 0xF7,
+ 0xAB, 0xFF, 0x00, 0x28, 0x5B, 0xD0, 0xE0, 0x8A, 0x00, 0x90, 0x4B, 0x49,
+ 0x23, 0x8E, 0x02, 0x22, 0x64, 0x31, 0x48, 0x46, 0xE8, 0xF7, 0x45, 0xDA,
+ 0x1C, 0x20, 0x04, 0x97, 0xAD, 0xF8, 0x0A, 0x00, 0x60, 0x8E, 0x40, 0xF0,
+ 0x01, 0x00, 0xAD, 0xF8, 0x08, 0x00, 0xE0, 0x8A, 0xAD, 0xF8, 0x0C, 0x00,
+ 0x94, 0xF8, 0x32, 0x10, 0x07, 0xF1, 0x1C, 0x00, 0x09, 0x07, 0x0C, 0xD5,
+ 0x94, 0xF8, 0x2E, 0x10, 0x00, 0xF8, 0x01, 0x1B, 0xE1, 0x8D, 0x09, 0x0A,
+ 0x00, 0xF8, 0x01, 0x1B, 0xBD, 0xF8, 0x0C, 0x10, 0x89, 0x1C, 0xAD, 0xF8,
+ 0x0C, 0x10, 0xA2, 0x8D, 0xA1, 0x6A, 0x11, 0x44, 0xE2, 0x8A, 0x1A, 0xF4,
+ 0x34, 0xF3, 0xE0, 0x89, 0x01, 0xAA, 0x61, 0x68, 0x00, 0xF0, 0x70, 0xF8,
+ 0xB4, 0xF8, 0x46, 0x00, 0x40, 0x1E, 0xA4, 0xF8, 0x46, 0x00, 0xA1, 0x8D,
+ 0xE0, 0x8A, 0x01, 0x44, 0xA1, 0x85, 0xE1, 0x8D, 0x08, 0x1A, 0xE0, 0x85,
+ 0x60, 0x8E, 0x20, 0xF0, 0x08, 0x00, 0x40, 0xF0, 0x10, 0x00, 0x60, 0x86,
+ 0x53, 0xE7, 0x40, 0xF2, 0x83, 0x33, 0x29, 0x4A, 0x30, 0x78, 0xEF, 0xF7,
+ 0x97, 0xFF, 0x07, 0x00, 0x3E, 0xD0, 0xE0, 0x8D, 0x00, 0x90, 0x24, 0x49,
+ 0x23, 0x8E, 0x02, 0x22, 0x9C, 0x31, 0x48, 0x46, 0xE8, 0xF7, 0xF7, 0xD9,
+ 0xA1, 0x8D, 0xA0, 0x6A, 0xE2, 0x8D, 0x01, 0x44, 0x01, 0xE0, 0x33, 0xE0,
+ 0x2E, 0xE0, 0x07, 0xF1, 0x1C, 0x00, 0x1A, 0xF4, 0x00, 0xF3, 0xA0, 0x6A,
+ 0x1B, 0x4B, 0x1E, 0x49, 0x04, 0x60, 0x40, 0xF2, 0x91, 0x30, 0x00, 0x90,
+ 0x38, 0x46, 0xA2, 0x6A, 0xEF, 0xF7, 0x3C, 0xFF, 0x10, 0xB3, 0x60, 0x8E,
+ 0x01, 0xAA, 0x20, 0xF0, 0x18, 0x00, 0x40, 0xF0, 0x20, 0x00, 0x60, 0x86,
+ 0x1E, 0x20, 0x04, 0x97, 0xAD, 0xF8, 0x0A, 0x00, 0x60, 0x8E, 0x40, 0xF0,
+ 0x01, 0x00, 0xAD, 0xF8, 0x08, 0x00, 0xE0, 0x8D, 0xAD, 0xF8, 0x0C, 0x00,
+ 0xE0, 0x89, 0x61, 0x68, 0x00, 0xF0, 0x1E, 0xF8, 0xB4, 0xF8, 0x46, 0x00,
+ 0x40, 0x1E, 0xA4, 0xF8, 0x46, 0x00, 0xA5, 0x62, 0xE5, 0x85, 0x0C, 0xE7,
+ 0x01, 0x20, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0xA5, 0x62, 0x00, 0x20,
+ 0xF9, 0xE7, 0x00, 0x00, 0x01, 0x3B, 0x10, 0x21, 0x05, 0x74, 0x20, 0x00,
+ 0xB4, 0x20, 0xC0, 0x08, 0x94, 0xA8, 0x82, 0x00, 0xE9, 0xF4, 0x81, 0x00,
+ 0xE5, 0xF4, 0x81, 0x00, 0x91, 0xF4, 0x81, 0x00, 0x38, 0xB5, 0x0D, 0x46,
+ 0x09, 0x79, 0x14, 0x46, 0x51, 0xB3, 0xE2, 0x88, 0xE1, 0x68, 0x11, 0x44,
+ 0x22, 0x7A, 0x01, 0xF8, 0x04, 0x2D, 0x22, 0x89, 0x12, 0x0A, 0x4A, 0x70,
+ 0x88, 0x70, 0x02, 0x0A, 0xCA, 0x70, 0x21, 0x89, 0x09, 0x1D, 0x21, 0x81,
+ 0xE1, 0x88, 0x09, 0x1F, 0xE1, 0x80, 0xA1, 0x88, 0x05, 0x28, 0x21, 0xF0,
+ 0x18, 0x01, 0xA1, 0x80, 0x4F, 0xF4, 0x00, 0x71, 0x21, 0x80, 0x60, 0x81,
+ 0x17, 0xD0, 0x4F, 0xF4, 0xF0, 0x73, 0x0E, 0x4A, 0x21, 0x46, 0x05, 0xF1,
+ 0x14, 0x00, 0xF0, 0xF7, 0x4F, 0xFD, 0x00, 0x28, 0x0C, 0xD0, 0x28, 0x46,
+ 0xBD, 0xE8, 0x38, 0x40, 0xFF, 0xF7, 0x8E, 0xBC, 0x00, 0x91, 0x2B, 0x46,
+ 0x02, 0x22, 0x07, 0x49, 0x07, 0x48, 0xE8, 0xF7, 0x74, 0xD9, 0x00, 0x20,
+ 0x38, 0xBD, 0x4F, 0xF4, 0xEE, 0x73, 0x02, 0x4A, 0x21, 0x46, 0x05, 0xF1,
+ 0x1C, 0x00, 0xE6, 0xE7, 0xC2, 0xA7, 0x82, 0x00, 0xCC, 0x14, 0xC0, 0x08,
+ 0x01, 0x3B, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x4F, 0x87, 0xB0, 0x93, 0x46,
+ 0xDD, 0xE9, 0x14, 0x79, 0x0E, 0x46, 0x05, 0x00, 0x00, 0xD0, 0x6E, 0x68,
+ 0x3E, 0x4C, 0x76, 0xB1, 0x70, 0x89, 0x07, 0xF1, 0x04, 0x0A, 0x50, 0x45,
+ 0x10, 0xD2, 0x00, 0x90, 0x02, 0x22, 0x3B, 0x49, 0x20, 0x46, 0x3B, 0x1D,
+ 0xE8, 0xF7, 0x4D, 0xD9, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x37, 0x49,
+ 0x00, 0x22, 0x28, 0x39, 0x20, 0x46, 0xE8, 0xF7, 0x44, 0xD9, 0xF5, 0xE7,
+ 0x1C, 0x30, 0x81, 0xB2, 0x34, 0x48, 0x40, 0xF2, 0x12, 0x23, 0x32, 0x4A,
+ 0x00, 0x78, 0xEF, 0xF7, 0xCF, 0xFE, 0x5F, 0xEA, 0x00, 0x08, 0xE9, 0xD0,
+ 0x08, 0xF1, 0x1C, 0x04, 0x00, 0x21, 0x04, 0xF8, 0x01, 0xBB, 0x58, 0x46,
+ 0xFE, 0xF7, 0x8A, 0xFA, 0x20, 0xB3, 0x2C, 0x4A, 0x30, 0x46, 0x7D, 0xB1,
+ 0xFE, 0xF7, 0xB1, 0xFC, 0xA8, 0x77, 0x04, 0xF8, 0x01, 0x0B, 0xB9, 0xF1,
+ 0x00, 0x00, 0x01, 0xD0, 0x03, 0x46, 0x00, 0xE0, 0x13, 0x7E, 0xAA, 0x89,
+ 0x81, 0x21, 0x05, 0xF1, 0x08, 0x00, 0x0E, 0xE0, 0xFE, 0xF7, 0xA1, 0xFC,
+ 0xB0, 0x71, 0x04, 0xF8, 0x01, 0x0B, 0xB9, 0xF1, 0x00, 0x00, 0x01, 0xD0,
+ 0x03, 0x46, 0x00, 0xE0, 0x13, 0x7E, 0x72, 0x88, 0x82, 0x21, 0x06, 0xF1,
+ 0x40, 0x00, 0x00, 0xF0, 0x3D, 0xF8, 0x0C, 0xE0, 0xBB, 0xF1, 0x16, 0x0F,
+ 0x02, 0xD0, 0x2D, 0xB1, 0xE8, 0x7F, 0x04, 0xE0, 0x30, 0x46, 0xFE, 0xF7,
+ 0x88, 0xFC, 0x00, 0xE0, 0xF0, 0x79, 0x04, 0xF8, 0x01, 0x0B, 0x38, 0x0A,
+ 0x04, 0xF8, 0x01, 0x7B, 0x04, 0xF8, 0x01, 0x0B, 0x00, 0x20, 0x04, 0xE0,
+ 0x0A, 0x99, 0x09, 0x5C, 0x04, 0xF8, 0x01, 0x1B, 0x40, 0x1C, 0xB8, 0x42,
+ 0xF8, 0xD3, 0x1C, 0x20, 0xAD, 0xF8, 0x0A, 0x00, 0x01, 0x20, 0xAD, 0xF8,
+ 0x08, 0x00, 0xCD, 0xF8, 0x10, 0x80, 0xAD, 0xF8, 0x0C, 0xA0, 0x05, 0x20,
+ 0x01, 0xAA, 0x31, 0x46, 0xFF, 0xF7, 0x34, 0xFF, 0x90, 0xE7, 0x00, 0x00,
+ 0x00, 0x3B, 0x10, 0x21, 0x24, 0x15, 0xC0, 0x08, 0xD3, 0xA7, 0x82, 0x00,
+ 0x01, 0x74, 0x20, 0x00, 0x68, 0x76, 0x20, 0x00, 0x01, 0x48, 0x41, 0x83,
+ 0x70, 0x47, 0x00, 0x00, 0x68, 0x76, 0x20, 0x00, 0x30, 0xB4, 0x15, 0x46,
+ 0x0C, 0x46, 0x81, 0x29, 0x0C, 0xD0, 0x07, 0xA1, 0x09, 0x4A, 0x12, 0x78,
+ 0x12, 0x06, 0x42, 0xEA, 0x04, 0x42, 0x2A, 0x43, 0x4F, 0xF4, 0x7A, 0x74,
+ 0x63, 0x43, 0x30, 0xBC, 0xF0, 0xF7, 0x4C, 0xBE, 0x04, 0xA1, 0xF1, 0xE7,
+ 0x6C, 0x32, 0x63, 0x5F, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x00,
+ 0x64, 0x76, 0x20, 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x63, 0x68, 0x61, 0x6E,
+ 0x6E, 0x5F, 0x72, 0x74, 0x78, 0x5F, 0x6C, 0x65, 0x00, 0x00, 0x00, 0x00,
+ 0xF0, 0xF7, 0x4E, 0xBE, 0x1C, 0xB5, 0x44, 0x68, 0x01, 0x22, 0x63, 0x88,
+ 0xCD, 0xE9, 0x00, 0x12, 0x02, 0x8B, 0x81, 0x89, 0x04, 0xF1, 0x0C, 0x00,
+ 0x05, 0xF0, 0xA4, 0xFE, 0x1C, 0xBD, 0x00, 0x00, 0x7C, 0xB5, 0x04, 0x46,
+ 0x40, 0x8A, 0xCD, 0xE9, 0x00, 0x01, 0x0D, 0x46, 0xA3, 0x89, 0x03, 0x22,
+ 0x06, 0x49, 0x07, 0x48, 0xE8, 0xF7, 0x8B, 0xD8, 0x00, 0x95, 0x60, 0x68,
+ 0xB4, 0xF8, 0x46, 0x30, 0x62, 0x8A, 0xA1, 0x89, 0x40, 0x88, 0xF3, 0xF7,
+ 0x67, 0xFC, 0x7C, 0xBD, 0x34, 0x13, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21,
+ 0x81, 0x89, 0x40, 0x68, 0x40, 0x88, 0xF3, 0xF7, 0x83, 0xBC, 0x0A, 0x46,
+ 0x81, 0x89, 0x40, 0x68, 0x40, 0x88, 0xF3, 0xF7, 0x98, 0xBC, 0x0A, 0x46,
+ 0x81, 0x89, 0x40, 0x68, 0x40, 0x88, 0xF3, 0xF7, 0xAA, 0xBC, 0x0A, 0x46,
+ 0x81, 0x89, 0x40, 0x68, 0x40, 0x88, 0xF3, 0xF7, 0xC6, 0xBC, 0x00, 0x00,
+ 0x2D, 0xE9, 0xFC, 0x47, 0xDF, 0xF8, 0x98, 0x80, 0x17, 0x46, 0x0E, 0x46,
+ 0x81, 0x46, 0x98, 0xF8, 0xCA, 0x41, 0x4B, 0x46, 0x25, 0x46, 0x03, 0x22,
+ 0x22, 0x49, 0x23, 0x48, 0xCD, 0xE9, 0x00, 0x67, 0xE8, 0xF7, 0x53, 0xD8,
+ 0xDF, 0xF8, 0x84, 0xC0, 0x00, 0x20, 0x98, 0xF8, 0xCA, 0x11, 0xDC, 0xF8,
+ 0x04, 0x30, 0x08, 0xE0, 0x33, 0xF8, 0x20, 0x20, 0xB2, 0x42, 0x00, 0xD1,
+ 0x04, 0x46, 0x02, 0xB9, 0x05, 0x46, 0x40, 0x1C, 0xC0, 0xB2, 0x81, 0x42,
+ 0xF4, 0xD8, 0x17, 0x48, 0x02, 0x22, 0xC0, 0x1E, 0x8F, 0xB1, 0xA1, 0x42,
+ 0x0A, 0xD1, 0xA9, 0x42, 0x08, 0xD0, 0x23, 0xF8, 0x25, 0x60, 0xDC, 0xF8,
+ 0x04, 0x10, 0x02, 0xEB, 0x85, 0x02, 0x01, 0xF8, 0x02, 0x90, 0x0E, 0xE0,
+ 0x0D, 0x49, 0x01, 0x22, 0x33, 0x46, 0x3C, 0x31, 0x10, 0xE0, 0xA1, 0x42,
+ 0x0A, 0xD0, 0x00, 0x20, 0x23, 0xF8, 0x24, 0x00, 0xDC, 0xF8, 0x04, 0x10,
+ 0x02, 0xEB, 0x84, 0x02, 0x88, 0x54, 0x01, 0x20, 0xBD, 0xE8, 0xFC, 0x87,
+ 0x04, 0x49, 0x33, 0x46, 0x01, 0x22, 0x74, 0x31, 0xE8, 0xF7, 0x17, 0xD8,
+ 0x00, 0x20, 0xF5, 0xE7, 0x64, 0x01, 0x20, 0x00, 0x88, 0x12, 0xC0, 0x08,
+ 0x03, 0x3B, 0x10, 0x21, 0x68, 0x76, 0x20, 0x00, 0x13, 0xB5, 0x82, 0xB0,
+ 0x04, 0x46, 0xBD, 0xF8, 0x0C, 0x00, 0x00, 0x90, 0x23, 0x46, 0x02, 0x22,
+ 0x0D, 0x49, 0x0E, 0x48, 0xE8, 0xF7, 0x01, 0xD8, 0x20, 0x46, 0xFE, 0xF7,
+ 0xD9, 0xFA, 0x28, 0xB1, 0xBD, 0xF8, 0x0C, 0x10, 0x59, 0xB1, 0x03, 0xAA,
+ 0x07, 0x21, 0x0A, 0xE0, 0x06, 0x49, 0x07, 0x48, 0x23, 0x46, 0x01, 0x22,
+ 0x30, 0x31, 0xC0, 0x1E, 0xE7, 0xF7, 0xEF, 0xDF, 0x1F, 0xBD, 0x00, 0x22,
+ 0x06, 0x21, 0xFD, 0xF7, 0xF7, 0xFE, 0x1F, 0xBD, 0x7C, 0x13, 0xC0, 0x08,
+ 0x03, 0x3B, 0x10, 0x21, 0x7C, 0xB5, 0x04, 0x46, 0x01, 0x89, 0xC0, 0x68,
+ 0xCD, 0xE9, 0x00, 0x01, 0x63, 0x89, 0x03, 0x22, 0x2B, 0x49, 0x2C, 0x48,
+ 0xE7, 0xF7, 0xD9, 0xDF, 0x2A, 0x4E, 0x60, 0x89, 0xF6, 0x1E, 0x06, 0x28,
+ 0x19, 0xD0, 0x04, 0x28, 0x17, 0xD0, 0xFE, 0xF7, 0xAB, 0xFA, 0x05, 0x00,
+ 0x26, 0xD0, 0x23, 0x89, 0x68, 0x8A, 0x83, 0x42, 0x2A, 0xD9, 0x22, 0x49,
+ 0x00, 0x90, 0x02, 0x22, 0x94, 0x31, 0x30, 0x46, 0xE7, 0xF7, 0xC3, 0xDF,
+ 0x20, 0x48, 0xB0, 0xF8, 0x78, 0x01, 0x81, 0x07, 0x01, 0xD4, 0xC0, 0x06,
+ 0x1C, 0xD5, 0x00, 0x25, 0x29, 0xE0, 0x20, 0x8A, 0x80, 0xB2, 0xFE, 0xF7,
+ 0x67, 0xFA, 0x01, 0x00, 0x07, 0xD0, 0x60, 0x89, 0x22, 0x46, 0xFF, 0xF7,
+ 0x05, 0xFE, 0x05, 0x00, 0x1D, 0xD0, 0x01, 0x20, 0x7C, 0xBD, 0x13, 0x49,
+ 0x01, 0x22, 0x38, 0x31, 0x23, 0x69, 0x03, 0xE0, 0x10, 0x49, 0x63, 0x89,
+ 0x01, 0x22, 0x68, 0x31, 0x30, 0x46, 0xE7, 0xF7, 0xA0, 0xDF, 0xE2, 0xE7,
+ 0x2B, 0x7F, 0x06, 0x2B, 0x05, 0xD0, 0x05, 0x2B, 0x03, 0xD0, 0x0A, 0x49,
+ 0x01, 0x22, 0xCC, 0x31, 0xF2, 0xE7, 0x21, 0x46, 0x28, 0x46, 0xFF, 0xF7,
+ 0x8B, 0xFC, 0x05, 0x00, 0x08, 0xD1, 0x20, 0x79, 0xC0, 0x07, 0x05, 0xD0,
+ 0x40, 0xF2, 0xCD, 0x22, 0x05, 0x49, 0xE0, 0x68, 0xEF, 0xF7, 0x0A, 0xFE,
+ 0x28, 0x46, 0x7C, 0xBD, 0x60, 0x15, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21,
+ 0x64, 0x01, 0x20, 0x00, 0xE7, 0xA7, 0x82, 0x00, 0x10, 0xB5, 0xFE, 0xF7,
+ 0x55, 0xFA, 0x00, 0x28, 0x05, 0xD0, 0x00, 0x22, 0xBD, 0xE8, 0x10, 0x40,
+ 0x03, 0x21, 0xFD, 0xF7, 0x7F, 0xBE, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x41,
+ 0x1E, 0x46, 0x15, 0x46, 0x0C, 0x46, 0x07, 0x46, 0xFE, 0xF7, 0x44, 0xFA,
+ 0x30, 0xB1, 0xBD, 0xF8, 0x18, 0x10, 0x61, 0xB1, 0x06, 0xAA, 0x40, 0xF2,
+ 0x03, 0x11, 0x1C, 0xE0, 0x3B, 0x46, 0x01, 0x22, 0x0F, 0x49, 0x10, 0x48,
+ 0xE7, 0xF7, 0x5B, 0xDF, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x0E, 0x49,
+ 0xB1, 0xF8, 0xA8, 0x11, 0x04, 0x82, 0x89, 0x1F, 0x89, 0xB2, 0x8C, 0x42,
+ 0x01, 0xD2, 0x84, 0x82, 0x00, 0xE0, 0x81, 0x82, 0xA0, 0xF8, 0x44, 0x50,
+ 0xA0, 0xF8, 0x48, 0x50, 0xA0, 0xF8, 0x4A, 0x60, 0x00, 0x22, 0x40, 0xF2,
+ 0x01, 0x11, 0xFD, 0xF7, 0x4F, 0xFE, 0x01, 0x20, 0xE5, 0xE7, 0x00, 0x00,
+ 0xDC, 0x1F, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21, 0x64, 0x01, 0x20, 0x00,
+ 0x2D, 0xE9, 0xF0, 0x47, 0x82, 0x46, 0x22, 0x48, 0x98, 0x46, 0x15, 0x46,
+ 0xB0, 0xF8, 0xA8, 0x01, 0x0F, 0x46, 0x80, 0x1F, 0x86, 0xB2, 0x50, 0x46,
+ 0xDD, 0xF8, 0x20, 0x90, 0xFE, 0xF7, 0xDA, 0xF9, 0x04, 0x46, 0x17, 0x2D,
+ 0x11, 0xD3, 0x87, 0xB1, 0x7C, 0xB1, 0x38, 0x46, 0xFE, 0xF7, 0x1A, 0xFA,
+ 0x70, 0xB1, 0x00, 0x21, 0x20, 0x46, 0xFE, 0xF7, 0xD1, 0xF8, 0x04, 0x00,
+ 0x0B, 0xD0, 0x27, 0x83, 0x25, 0x82, 0xB5, 0x42, 0x10, 0xD2, 0xA5, 0x82,
+ 0x0F, 0xE0, 0x40, 0xF2, 0x05, 0x22, 0x04, 0xE0, 0x40, 0xF2, 0x02, 0x22,
+ 0x01, 0xE0, 0x40, 0xF2, 0xF3, 0x22, 0x00, 0x21, 0x50, 0x46, 0xF3, 0xF7,
+ 0x2E, 0xFB, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0xA6, 0x82, 0xA4, 0xF8,
+ 0x44, 0x80, 0xA4, 0xF8, 0x48, 0x80, 0xA4, 0xF8, 0x4A, 0x90, 0x01, 0x20,
+ 0x60, 0x77, 0x00, 0x21, 0x20, 0x46, 0xFF, 0xF7, 0x80, 0xFE, 0x00, 0x22,
+ 0x04, 0x21, 0x20, 0x46, 0xFD, 0xF7, 0x00, 0xFE, 0x01, 0x20, 0xE9, 0xE7,
+ 0x64, 0x01, 0x20, 0x00, 0x70, 0xB5, 0x0E, 0x46, 0x00, 0x25, 0xFE, 0xF7,
+ 0xC5, 0xF9, 0x10, 0x4B, 0x04, 0x00, 0x0B, 0xD0, 0x20, 0x7F, 0x06, 0x28,
+ 0x11, 0xD0, 0x00, 0x22, 0x0D, 0x49, 0x18, 0x46, 0xE7, 0xF7, 0xDF, 0xDE,
+ 0x4F, 0xF4, 0x3D, 0x75, 0x28, 0x46, 0x70, 0xBD, 0x09, 0x49, 0x00, 0x22,
+ 0x2C, 0x39, 0x18, 0x46, 0xE7, 0xF7, 0xD5, 0xDE, 0x40, 0xF2, 0x05, 0x20,
+ 0x70, 0xBD, 0x31, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0xA1, 0xFB, 0x34, 0xF8,
+ 0x44, 0x0F, 0x30, 0x44, 0x20, 0x80, 0xEB, 0xE7, 0x00, 0x3B, 0x10, 0x21,
+ 0x38, 0x20, 0xC0, 0x08, 0x10, 0xB5, 0xFE, 0xF7, 0x9D, 0xF9, 0x28, 0xB1,
+ 0x00, 0x22, 0x05, 0x21, 0xFD, 0xF7, 0xCA, 0xFD, 0x00, 0x20, 0x10, 0xBD,
+ 0x40, 0xF2, 0x05, 0x20, 0x10, 0xBD, 0x7F, 0xB5, 0x0C, 0x46, 0x06, 0x46,
+ 0xFE, 0xF7, 0x64, 0xF9, 0x05, 0x00, 0x0F, 0xD0, 0x23, 0x89, 0xE2, 0x88,
+ 0xA1, 0x88, 0x60, 0x88, 0xFE, 0xF7, 0x33, 0xF8, 0x00, 0x28, 0x05, 0xD1,
+ 0x28, 0x7A, 0x40, 0xB1, 0xA8, 0x79, 0xA8, 0xB1, 0x40, 0xF2, 0x01, 0x20,
+ 0x04, 0xB0, 0x70, 0xBD, 0x40, 0xF2, 0x05, 0x20, 0xFA, 0xE7, 0x20, 0x89,
+ 0xA2, 0x89, 0x61, 0x89, 0x8D, 0xE8, 0x07, 0x00, 0xE3, 0x88, 0xA2, 0x88,
+ 0x61, 0x88, 0x30, 0x46, 0xFB, 0xF7, 0x47, 0xFC, 0x40, 0xBB, 0x4F, 0xF4,
+ 0xB4, 0x70, 0xEB, 0xE7, 0xA0, 0x78, 0x8D, 0xF8, 0x08, 0x00, 0x60, 0x88,
+ 0x00, 0x21, 0x00, 0x0A, 0x8D, 0xF8, 0x09, 0x00, 0x20, 0x79, 0x8D, 0xF8,
+ 0x0A, 0x00, 0xA0, 0x88, 0x02, 0xAB, 0x00, 0x0A, 0x8D, 0xF8, 0x0B, 0x00,
+ 0xA0, 0x79, 0x8D, 0xF8, 0x0C, 0x00, 0xE0, 0x88, 0x12, 0x22, 0x00, 0x0A,
+ 0x8D, 0xF8, 0x0D, 0x00, 0x20, 0x7A, 0x8D, 0xF8, 0x0E, 0x00, 0x20, 0x89,
+ 0x00, 0x0A, 0x8D, 0xF8, 0x0F, 0x00, 0x08, 0x20, 0xCD, 0xE9, 0x00, 0x01,
+ 0x29, 0x46, 0x00, 0x20, 0xFF, 0xF7, 0x04, 0xFD, 0x00, 0x20, 0xC3, 0xE7,
+ 0x2D, 0xE9, 0xFF, 0x5F, 0x98, 0x46, 0xDD, 0xE9, 0x10, 0x64, 0xDD, 0xE9,
+ 0x0E, 0x57, 0x91, 0x46, 0x8A, 0x46, 0x83, 0x46, 0xFE, 0xF7, 0x0C, 0xF9,
+ 0x01, 0x00, 0x23, 0xD0, 0x08, 0x7A, 0x00, 0x28, 0x20, 0xD1, 0x8D, 0xF8,
+ 0x0C, 0x40, 0x20, 0x0A, 0x8D, 0xF8, 0x0D, 0x00, 0x00, 0x22, 0x02, 0x20,
+ 0xCD, 0xE9, 0x00, 0x02, 0x03, 0xAB, 0x13, 0x22, 0x00, 0x20, 0xFF, 0xF7,
+ 0xE3, 0xFC, 0x00, 0x2C, 0x10, 0xD1, 0x2B, 0x46, 0x42, 0x46, 0x49, 0x46,
+ 0x50, 0x46, 0xFD, 0xF7, 0xC8, 0xFF, 0x00, 0x28, 0x08, 0xD1, 0xCD, 0xE9,
+ 0x00, 0x57, 0x43, 0x46, 0x4A, 0x46, 0x51, 0x46, 0x58, 0x46, 0x02, 0x96,
+ 0xFB, 0xF7, 0xE9, 0xFB, 0xBD, 0xE8, 0xFF, 0x9F, 0x2D, 0xE9, 0xFF, 0x41,
+ 0x1F, 0x46, 0xCD, 0xE9, 0x00, 0x12, 0x14, 0x46, 0x0D, 0x46, 0x06, 0x46,
+ 0x43, 0x78, 0x03, 0x22, 0x0D, 0x49, 0x0E, 0x48, 0xE7, 0xF7, 0x25, 0xDE,
+ 0x60, 0x19, 0x8D, 0xF8, 0x08, 0x00, 0x20, 0x1D, 0xC3, 0xB2, 0x71, 0x78,
+ 0x38, 0x19, 0x2A, 0x46, 0xF6, 0xF7, 0x02, 0xF9, 0x28, 0xB9, 0x71, 0x78,
+ 0x04, 0x22, 0x02, 0xA8, 0xF6, 0xF7, 0xEE, 0xFB, 0x18, 0xB1, 0x00, 0x20,
+ 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x01, 0x20, 0xFA, 0xE7, 0x00, 0x00,
+ 0x04, 0x71, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x0C, 0x46,
+ 0x03, 0x46, 0xA0, 0xF5, 0x18, 0x72, 0x00, 0x25, 0x19, 0x48, 0x1A, 0x49,
+ 0x0A, 0x2A, 0x27, 0xD2, 0xDF, 0xE8, 0x02, 0xF0, 0x05, 0x07, 0x0B, 0x12,
+ 0x15, 0x17, 0x1D, 0x1F, 0x21, 0x23, 0x00, 0x79, 0x0B, 0xE0, 0x0A, 0x78,
+ 0x13, 0x49, 0x08, 0x31, 0x02, 0xE0, 0x11, 0x49, 0x02, 0x78, 0x0C, 0x31,
+ 0x20, 0x46, 0x19, 0xF4, 0x00, 0xF7, 0x19, 0xE0, 0x40, 0x78, 0x20, 0x70,
+ 0x16, 0xE0, 0x80, 0x78, 0xFB, 0xE7, 0xD0, 0xF8, 0x06, 0x10, 0x21, 0x60,
+ 0x40, 0x89, 0xA0, 0x80, 0x0E, 0xE0, 0x48, 0x78, 0xF3, 0xE7, 0xC0, 0x78,
+ 0xF1, 0xE7, 0x88, 0x88, 0x00, 0xE0, 0xC8, 0x88, 0x20, 0x80, 0x05, 0xE0,
+ 0x03, 0x25, 0x01, 0x22, 0x04, 0x49, 0x05, 0x48, 0xE7, 0xF7, 0xD1, 0xDD,
+ 0x28, 0x46, 0x70, 0xBD, 0x38, 0x79, 0x20, 0x00, 0x88, 0x74, 0x20, 0x00,
+ 0xD4, 0x81, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x1C, 0xB5, 0x41, 0x88,
+ 0x4F, 0xF4, 0x9A, 0x73, 0xB1, 0xF5, 0x9B, 0x7F, 0x05, 0xD0, 0x08, 0xDC,
+ 0xB1, 0xF5, 0x99, 0x7F, 0x10, 0xD0, 0x99, 0x42, 0x28, 0xD1, 0x19, 0x4A,
+ 0x92, 0x78, 0x82, 0xB1, 0x25, 0xE0, 0xA1, 0xF5, 0x80, 0x71, 0x67, 0x39,
+ 0x25, 0xD0, 0x1B, 0x29, 0x1E, 0xD1, 0xBD, 0xE8, 0x1C, 0x40, 0x00, 0x1D,
+ 0x00, 0xF0, 0x60, 0xB8, 0xBD, 0xE8, 0x1C, 0x40, 0x00, 0x1D, 0x00, 0xF0,
+ 0x25, 0xB8, 0x10, 0x4A, 0x54, 0x79, 0x94, 0xB1, 0x00, 0x24, 0x54, 0x71,
+ 0x0E, 0x4A, 0x12, 0x68, 0x00, 0x2A, 0x0B, 0xD0, 0x99, 0x42, 0x01, 0xD1,
+ 0x80, 0x88, 0x00, 0xE0, 0xC0, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0xCD, 0xF8,
+ 0x04, 0xD0, 0x01, 0xA9, 0x40, 0x20, 0x90, 0x47, 0x1C, 0xBD, 0xBD, 0xE8,
+ 0x1C, 0x40, 0x0A, 0xF0, 0x57, 0xB8, 0xBD, 0xE8, 0x1C, 0x40, 0x00, 0x1D,
+ 0x00, 0xF0, 0x4C, 0xB8, 0x88, 0x74, 0x20, 0x00, 0x38, 0x79, 0x20, 0x00,
+ 0x48, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x43, 0x88, 0x16, 0x4D, 0x04, 0x46,
+ 0x4B, 0xB1, 0x01, 0x22, 0x15, 0x49, 0x16, 0x48, 0xE7, 0xF7, 0x77, 0xDD,
+ 0x20, 0x78, 0xA8, 0xB1, 0x01, 0x28, 0x0E, 0xD1, 0x1D, 0xE0, 0x10, 0x48,
+ 0x21, 0x78, 0x00, 0x78, 0x20, 0xF0, 0x0C, 0x00, 0x11, 0xB1, 0x01, 0x29,
+ 0x05, 0xD1, 0x02, 0xE0, 0x20, 0xF0, 0x02, 0x00, 0x00, 0xE0, 0x08, 0x30,
+ 0x28, 0x70, 0x60, 0x88, 0xBD, 0xE8, 0x70, 0x40, 0xF7, 0xF7, 0xE8, 0xB8,
+ 0x28, 0x78, 0xC0, 0xF3, 0x81, 0x01, 0x03, 0x29, 0x02, 0xD1, 0x20, 0xF0,
+ 0x0C, 0x00, 0xF0, 0xE7, 0x20, 0xF0, 0x0C, 0x00, 0xEA, 0xE7, 0x28, 0x78,
+ 0xFA, 0xE7, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, 0xF4, 0x82, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x06, 0x49, 0x08, 0x78, 0xC0, 0xF3, 0x81, 0x02,
+ 0x02, 0x2A, 0x05, 0xD1, 0x20, 0xF0, 0x0E, 0x00, 0x08, 0x70, 0x00, 0x20,
+ 0xF7, 0xF7, 0xC8, 0xB8, 0x70, 0x47, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00,
+ 0x04, 0x49, 0x08, 0xB5, 0x0A, 0x68, 0x00, 0x2A, 0x03, 0xD0, 0x00, 0x90,
+ 0x69, 0x46, 0x41, 0x20, 0x90, 0x47, 0x08, 0xBD, 0x48, 0x78, 0x20, 0x00,
+ 0x10, 0xB5, 0xF4, 0xF7, 0x17, 0xF9, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD,
+ 0x07, 0x20, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x3C, 0x4E, 0x0C, 0x46,
+ 0x03, 0x46, 0xA0, 0xF5, 0x18, 0x71, 0xB0, 0x78, 0x00, 0x25, 0x38, 0x4F,
+ 0x94, 0x46, 0x40, 0xF0, 0x02, 0x00, 0x0A, 0x29, 0x0E, 0xD2, 0xDF, 0xE8,
+ 0x01, 0xF0, 0x05, 0x14, 0x24, 0x31, 0x39, 0x43, 0x4D, 0x55, 0x5D, 0x63,
+ 0x01, 0x2C, 0x05, 0xD1, 0x9C, 0xF8, 0x00, 0x10, 0x03, 0x29, 0x01, 0xD8,
+ 0x39, 0x71, 0x12, 0xE0, 0x03, 0x25, 0x01, 0x22, 0x2E, 0x49, 0x2F, 0x48,
+ 0xE7, 0xF7, 0x03, 0xDD, 0x0C, 0xE0, 0x1F, 0x2C, 0xF6, 0xD8, 0x2A, 0x48,
+ 0x22, 0x46, 0x61, 0x46, 0x08, 0x30, 0x19, 0xF4, 0x0E, 0xF6, 0x34, 0x70,
+ 0xB0, 0x78, 0x40, 0xF0, 0x01, 0x00, 0xB0, 0x70, 0x28, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x81, 0x1F, 0x2C, 0xE6, 0xD8, 0x21, 0x48, 0x22, 0x46, 0x61, 0x46,
+ 0x0C, 0x30, 0x19, 0xF4, 0xFE, 0xF5, 0x3C, 0x70, 0xB0, 0x78, 0x40, 0xF0,
+ 0x04, 0x00, 0xEE, 0xE7, 0x01, 0x2C, 0xD9, 0xD1, 0x9C, 0xF8, 0x00, 0x10,
+ 0x04, 0x29, 0xD5, 0xD8, 0x79, 0x70, 0xE6, 0xE7, 0x01, 0x2C, 0xD1, 0xD1,
+ 0x9C, 0xF8, 0x00, 0x10, 0x03, 0x29, 0xCD, 0xD8, 0x01, 0xF0, 0x01, 0x01,
+ 0xB9, 0x70, 0xDC, 0xE7, 0x06, 0x2C, 0xC7, 0xD1, 0xDC, 0xF8, 0x00, 0x10,
+ 0xC7, 0xF8, 0x06, 0x10, 0xBC, 0xF8, 0x04, 0x10, 0x79, 0x81, 0xD2, 0xE7,
+ 0x01, 0x2C, 0xBD, 0xD1, 0x9C, 0xF8, 0x00, 0x10, 0x07, 0x29, 0xB9, 0xD8,
+ 0x71, 0x70, 0xCA, 0xE7, 0x01, 0x2C, 0xB5, 0xD1, 0x9C, 0xF8, 0x00, 0x10,
+ 0x03, 0x29, 0xB1, 0xD8, 0xF9, 0x70, 0xC2, 0xE7, 0x02, 0x2C, 0xAD, 0xD1,
+ 0xBC, 0xF8, 0x00, 0x10, 0xB1, 0x80, 0xBC, 0xE7, 0x02, 0x2C, 0xA7, 0xD1,
+ 0xBC, 0xF8, 0x00, 0x10, 0xF1, 0x80, 0xB6, 0xE7, 0x38, 0x79, 0x20, 0x00,
+ 0x88, 0x74, 0x20, 0x00, 0xAC, 0x81, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0x08, 0xB5, 0x00, 0x22, 0x8D, 0xF8, 0x00, 0x20, 0x8D, 0xF8, 0x01, 0x00,
+ 0x8D, 0xF8, 0x02, 0x10, 0x6A, 0x46, 0x03, 0x21, 0x4F, 0xF6, 0x80, 0x50,
+ 0xF4, 0xF7, 0x0C, 0xFE, 0x08, 0xB1, 0x00, 0x20, 0x08, 0xBD, 0x07, 0x20,
+ 0x08, 0xBD, 0x00, 0x00, 0x70, 0xB5, 0x00, 0x22, 0x1B, 0x49, 0x1C, 0x48,
+ 0xE7, 0xF7, 0x8B, 0xDC, 0x1B, 0x4C, 0x1C, 0x4E, 0x1C, 0x4D, 0x20, 0x78,
+ 0xC0, 0xF3, 0x81, 0x03, 0x70, 0x79, 0x18, 0x43, 0x07, 0xD0, 0x15, 0x49,
+ 0x01, 0x22, 0x58, 0x31, 0x28, 0x46, 0xE7, 0xF7, 0x7C, 0xDC, 0x02, 0x20,
+ 0x70, 0xBD, 0x02, 0xF0, 0xAD, 0xFC, 0x28, 0xB9, 0x71, 0x78, 0xA1, 0xB1,
+ 0x01, 0x29, 0x12, 0xD0, 0x04, 0x29, 0x10, 0xD0, 0x11, 0x48, 0x81, 0x78,
+ 0x41, 0xF0, 0x08, 0x01, 0x81, 0x70, 0x20, 0x78, 0x20, 0xF0, 0x0C, 0x00,
+ 0x00, 0x1D, 0x20, 0x70, 0x09, 0xF0, 0x30, 0xFF, 0x00, 0x20, 0xF6, 0xF7,
+ 0xEB, 0xFF, 0x00, 0x20, 0x70, 0xBD, 0x04, 0x49, 0x00, 0x22, 0x10, 0x31,
+ 0x28, 0x46, 0xE7, 0xF7, 0x5A, 0xDC, 0x0B, 0x20, 0x70, 0xBD, 0x00, 0x00,
+ 0x20, 0x82, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x38, 0x78, 0x20, 0x00,
+ 0x38, 0x79, 0x20, 0x00, 0x00, 0x35, 0x10, 0x21, 0x88, 0x74, 0x20, 0x00,
+ 0x10, 0xB5, 0x00, 0x22, 0x12, 0x49, 0x13, 0x48, 0xE7, 0xF7, 0x45, 0xDC,
+ 0x12, 0x4C, 0x20, 0x78, 0xC0, 0xF3, 0x81, 0x03, 0x02, 0x2B, 0x02, 0xD1,
+ 0x10, 0x48, 0x40, 0x79, 0x40, 0xB1, 0x0C, 0x49, 0x0C, 0x48, 0x01, 0x22,
+ 0x0C, 0x31, 0xC0, 0x1E, 0xE7, 0xF7, 0x35, 0xDC, 0x02, 0x20, 0x10, 0xBD,
+ 0x00, 0x20, 0xF3, 0xF7, 0x17, 0xF9, 0x40, 0xB1, 0x20, 0x78, 0x40, 0xF0,
+ 0x0C, 0x00, 0x20, 0x70, 0x00, 0x20, 0xF6, 0xF7, 0xB1, 0xFF, 0x00, 0x20,
+ 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, 0x00, 0x00, 0xC4, 0x82, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0x38, 0x78, 0x20, 0x00, 0x38, 0x79, 0x20, 0x00,
+ 0x12, 0x48, 0x10, 0xB5, 0x80, 0x78, 0x00, 0x24, 0x00, 0xB9, 0x03, 0x24,
+ 0x10, 0x49, 0x4A, 0x79, 0x02, 0xB1, 0x01, 0x24, 0x82, 0x07, 0x0F, 0x48,
+ 0x00, 0x78, 0x02, 0xD5, 0x10, 0xF0, 0x0C, 0x0F, 0x05, 0xD1, 0xC0, 0xF3,
+ 0x81, 0x00, 0x01, 0x28, 0x01, 0xD0, 0x4C, 0xB1, 0x00, 0xE0, 0x02, 0x24,
+ 0x23, 0x46, 0x01, 0x22, 0x08, 0x49, 0x09, 0x48, 0xE7, 0xF7, 0xFD, 0xDB,
+ 0x20, 0x46, 0x10, 0xBD, 0x01, 0x20, 0x48, 0x71, 0x09, 0xF0, 0xC2, 0xFE,
+ 0x00, 0x20, 0x10, 0xBD, 0x88, 0x74, 0x20, 0x00, 0x38, 0x79, 0x20, 0x00,
+ 0x38, 0x78, 0x20, 0x00, 0x9C, 0x82, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0x2D, 0xE9, 0xF0, 0x41, 0x06, 0x46, 0x17, 0x48, 0x00, 0x23, 0x05, 0x78,
+ 0x08, 0xE0, 0x47, 0x68, 0x03, 0xEB, 0x43, 0x04, 0x07, 0xEB, 0xC4, 0x04,
+ 0x27, 0x78, 0x5F, 0xB1, 0x5B, 0x1C, 0xDB, 0xB2, 0xAB, 0x42, 0xF4, 0xD3,
+ 0x00, 0x22, 0x10, 0x49, 0x10, 0x48, 0xE7, 0xF7, 0xD4, 0xDB, 0x00, 0x20,
+ 0xBD, 0xE8, 0xF0, 0x81, 0x01, 0x25, 0x63, 0x70, 0x25, 0x70, 0x00, 0x20,
+ 0x60, 0x80, 0xA1, 0x73, 0x31, 0x68, 0xA1, 0x60, 0xB1, 0x88, 0xA1, 0x81,
+ 0x4A, 0xB1, 0x25, 0x71, 0x06, 0x49, 0x07, 0x48, 0x01, 0x22, 0x20, 0x39,
+ 0xC0, 0x1C, 0xE7, 0xF7, 0xBE, 0xDB, 0x20, 0x46, 0xE8, 0xE7, 0x20, 0x71,
+ 0xF4, 0xE7, 0x00, 0x00, 0xBC, 0x78, 0x20, 0x00, 0x10, 0x70, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0xF3, 0xF7, 0xE3, 0xF8, 0x00, 0x20,
+ 0x10, 0xBD, 0x00, 0x00, 0x07, 0x48, 0x10, 0xB5, 0x90, 0xF8, 0x78, 0x01,
+ 0x00, 0x06, 0x07, 0xD5, 0x00, 0xF0, 0xE8, 0xFD, 0x00, 0x21, 0xBD, 0xE8,
+ 0x10, 0x40, 0x02, 0x20, 0x00, 0xF0, 0x9E, 0xBC, 0x10, 0xBD, 0x00, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0xF8, 0xB5, 0x06, 0x46, 0x10, 0x48, 0x0D, 0x46,
+ 0x90, 0xF8, 0x78, 0x01, 0x00, 0x06, 0x18, 0xD5, 0x30, 0x46, 0x02, 0xF0,
+ 0x81, 0xF8, 0x04, 0x00, 0x08, 0xD0, 0x01, 0x46, 0x00, 0x20, 0x00, 0xF0,
+ 0x89, 0xFC, 0x20, 0x46, 0x01, 0xF0, 0xE0, 0xF8, 0x00, 0x20, 0xF8, 0xBD,
+ 0x31, 0x46, 0x07, 0x48, 0xE7, 0xF7, 0x50, 0xDD, 0x03, 0x46, 0x02, 0x22,
+ 0x05, 0x49, 0x06, 0x48, 0x00, 0x95, 0xE7, 0xF7, 0x7A, 0xDB, 0x0A, 0x20,
+ 0xF8, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0x00, 0x00, 0x30, 0x21,
+ 0xB4, 0x5B, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x05, 0x46,
+ 0x0D, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x00, 0x06, 0x13, 0xD5, 0x28, 0x46,
+ 0x02, 0xF0, 0xDC, 0xF8, 0x04, 0x00, 0x08, 0xD0, 0x01, 0x46, 0x00, 0x20,
+ 0x00, 0xF0, 0x5E, 0xFC, 0x20, 0x46, 0x01, 0xF0, 0xB5, 0xF8, 0x00, 0x20,
+ 0x70, 0xBD, 0x2B, 0x46, 0x01, 0x22, 0x04, 0x49, 0x04, 0x48, 0xE7, 0xF7,
+ 0x54, 0xDB, 0x0A, 0x20, 0x70, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x88, 0x5B, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x0D, 0x46,
+ 0x04, 0x46, 0x01, 0x46, 0x07, 0x48, 0x02, 0xF0, 0x9B, 0xFF, 0x48, 0xB1,
+ 0x06, 0x49, 0x04, 0xEB, 0x44, 0x00, 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10,
+ 0x80, 0x6A, 0x28, 0x60, 0x00, 0x20, 0x70, 0xBD, 0x04, 0x20, 0x70, 0xBD,
+ 0x1F, 0xB1, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x0C, 0x46,
+ 0x03, 0x46, 0xA0, 0xF5, 0x04, 0x71, 0x00, 0x25, 0x10, 0x48, 0x05, 0x29,
+ 0x16, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, 0x03, 0x0A, 0x0D, 0x0F, 0x12, 0x00,
+ 0x0C, 0x49, 0x10, 0x22, 0x0C, 0x31, 0x20, 0x46, 0x19, 0xF4, 0x33, 0xF4,
+ 0x10, 0xE0, 0x80, 0x68, 0x20, 0x60, 0x0D, 0xE0, 0x40, 0x78, 0x00, 0xE0,
+ 0x00, 0x78, 0x20, 0x70, 0x08, 0xE0, 0x80, 0x88, 0x20, 0x80, 0x05, 0xE0,
+ 0x03, 0x25, 0x01, 0x22, 0x03, 0x49, 0x04, 0x48, 0xE7, 0xF7, 0x0D, 0xDB,
+ 0x28, 0x46, 0x70, 0xBD, 0x0C, 0x78, 0x20, 0x00, 0x38, 0x5C, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x8A, 0xB0, 0x0C, 0x46, 0x00, 0x21,
+ 0x21, 0x70, 0x09, 0xAA, 0x07, 0xA9, 0x02, 0xF0, 0xAB, 0xF9, 0xB8, 0xB1,
+ 0x9D, 0xF8, 0x24, 0x10, 0x07, 0xA8, 0x01, 0xF0, 0xE7, 0xFF, 0x88, 0xB1,
+ 0x6A, 0x46, 0x11, 0x21, 0x02, 0xF0, 0x2A, 0xFB, 0x60, 0xB1, 0x9D, 0xF8,
+ 0x1B, 0x30, 0x01, 0x22, 0x05, 0x49, 0x06, 0x48, 0xE7, 0xF7, 0xE9, 0xDA,
+ 0x9D, 0xF8, 0x1B, 0x00, 0x20, 0x70, 0x00, 0x20, 0x0A, 0xB0, 0x10, 0xBD,
+ 0x03, 0x20, 0xFB, 0xE7, 0xEC, 0x5B, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21,
+ 0x2D, 0xE9, 0xFF, 0x41, 0x04, 0x46, 0x81, 0x79, 0x02, 0xF0, 0x94, 0xFF,
+ 0x05, 0x00, 0x7D, 0xD0, 0xE0, 0x79, 0x00, 0x26, 0x4B, 0x4F, 0xC0, 0x1E,
+ 0x07, 0x28, 0x77, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x04, 0x27, 0x09, 0x3E,
+ 0x90, 0x90, 0x49, 0x00, 0x2E, 0x71, 0x00, 0x22, 0xE8, 0x78, 0x11, 0x46,
+ 0x2F, 0xE0, 0xA0, 0x89, 0x38, 0xB9, 0x40, 0xF2, 0xED, 0x50, 0xA0, 0x81,
+ 0x00, 0x22, 0x42, 0x49, 0x42, 0x48, 0xE7, 0xF7, 0xBA, 0xDA, 0x97, 0xF8,
+ 0x78, 0x01, 0x00, 0x06, 0x0C, 0xD5, 0xA0, 0x89, 0xB0, 0xF5, 0x83, 0x7F,
+ 0x08, 0xD1, 0xA1, 0x79, 0x20, 0x46, 0x01, 0xF0, 0x9F, 0xFF, 0x01, 0x00,
+ 0x02, 0xD0, 0x04, 0x20, 0x00, 0xF0, 0xA8, 0xFB, 0xA2, 0x89, 0xE8, 0x78,
+ 0x10, 0xE0, 0x97, 0xF8, 0x78, 0x01, 0x00, 0x06, 0x0A, 0xD5, 0x28, 0x79,
+ 0x40, 0xB1, 0xA1, 0x79, 0x20, 0x46, 0x01, 0xF0, 0x8D, 0xFF, 0x01, 0x00,
+ 0x02, 0xD0, 0x01, 0x20, 0x00, 0xF0, 0x96, 0xFB, 0xE8, 0x78, 0x00, 0x22,
+ 0x01, 0x21, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x41, 0xF6, 0xF7, 0xAC, 0xBD,
+ 0x97, 0xF8, 0x78, 0x01, 0x00, 0x06, 0x4D, 0xD5, 0xA9, 0x79, 0x04, 0xB0,
+ 0xE8, 0x1D, 0xBD, 0xE8, 0xF0, 0x41, 0x04, 0xF0, 0xD5, 0xB8, 0x97, 0xF8,
+ 0x78, 0x01, 0x00, 0x06, 0x42, 0xD5, 0x04, 0xF1, 0x08, 0x01, 0x0D, 0x46,
+ 0x23, 0x48, 0xE7, 0xF7, 0x49, 0xDC, 0x03, 0x46, 0xA0, 0x7B, 0x00, 0x90,
+ 0x1E, 0x49, 0x1F, 0x48, 0x02, 0x22, 0x28, 0x31, 0xC0, 0x1C, 0xE7, 0xF7,
+ 0x70, 0xDA, 0x01, 0x96, 0x02, 0x96, 0x06, 0x22, 0x01, 0xA9, 0x28, 0x46,
+ 0x03, 0x96, 0x19, 0xF4, 0x31, 0xF3, 0x00, 0x28, 0x28, 0xD0, 0x06, 0x22,
+ 0x29, 0x46, 0x20, 0x46, 0x19, 0xF4, 0x2A, 0xF3, 0x00, 0x28, 0x21, 0xD0,
+ 0xA0, 0x7B, 0x00, 0x26, 0x80, 0x1C, 0xC1, 0xB2, 0x28, 0x46, 0x01, 0xF0,
+ 0x49, 0xFF, 0x00, 0xE0, 0x18, 0xE0, 0x05, 0x46, 0xA1, 0x79, 0x20, 0x46,
+ 0x02, 0xF0, 0x0E, 0xFF, 0x00, 0xB1, 0x46, 0x79, 0x00, 0x2D, 0x0F, 0xD0,
+ 0x06, 0x22, 0x21, 0x46, 0x05, 0xF1, 0x08, 0x00, 0x19, 0xF4, 0x10, 0xF3,
+ 0x10, 0xB9, 0x28, 0x79, 0xB0, 0x42, 0x05, 0xD0, 0xA2, 0x79, 0x33, 0x46,
+ 0x21, 0x46, 0x28, 0x46, 0x04, 0xF0, 0x66, 0xF9, 0xBD, 0xE8, 0xFF, 0x81,
+ 0x64, 0x01, 0x20, 0x00, 0x64, 0x5C, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0x00, 0x00, 0x30, 0x21, 0x70, 0xB5, 0x8A, 0xB0, 0x04, 0x46, 0x00, 0x26,
+ 0x02, 0x25, 0x81, 0x79, 0x01, 0xF0, 0x1C, 0xFF, 0x20, 0xB9, 0xA1, 0x79,
+ 0x20, 0x46, 0x01, 0xF0, 0xA5, 0xFE, 0x30, 0xB1, 0xE1, 0x79, 0x02, 0xAA,
+ 0x02, 0xF0, 0x5A, 0xFA, 0x06, 0x00, 0x00, 0xD0, 0x01, 0x25, 0xE0, 0x79,
+ 0xCD, 0xE9, 0x00, 0x05, 0xA1, 0x79, 0x02, 0xAB, 0x32, 0x46, 0x20, 0x46,
+ 0xF0, 0xF7, 0x26, 0xF8, 0x0A, 0xB0, 0x70, 0xBD, 0x2D, 0xE9, 0xF0, 0x47,
+ 0x04, 0x46, 0x00, 0x7A, 0x11, 0x28, 0x09, 0xD0, 0x12, 0x28, 0x07, 0xD0,
+ 0x13, 0x28, 0x05, 0xD0, 0x14, 0x28, 0x03, 0xD0, 0x15, 0x28, 0x01, 0xD0,
+ 0x16, 0x28, 0x5A, 0xD1, 0x94, 0xF8, 0x06, 0x90, 0x02, 0x26, 0x4F, 0xF0,
+ 0x00, 0x08, 0x49, 0x46, 0x20, 0x46, 0x02, 0xF0, 0xB7, 0xFE, 0x05, 0x00,
+ 0x01, 0xD0, 0x95, 0xF8, 0x05, 0x80, 0x49, 0x46, 0x20, 0x46, 0x01, 0xF0,
+ 0xE3, 0xFE, 0x28, 0xBB, 0x42, 0x46, 0x49, 0x46, 0x20, 0x46, 0xFF, 0xF7,
+ 0x01, 0xFE, 0xF8, 0xB9, 0xDF, 0xF8, 0x8C, 0xA0, 0x00, 0x22, 0x21, 0x49,
+ 0x50, 0x46, 0xE7, 0xF7, 0xE4, 0xD9, 0x21, 0x48, 0x80, 0x78, 0x20, 0xB1,
+ 0x00, 0x21, 0x03, 0x20, 0x00, 0xF0, 0xDC, 0xFA, 0x0A, 0xE0, 0x02, 0xF0,
+ 0x61, 0xFA, 0x07, 0x00, 0x06, 0xD0, 0x01, 0x46, 0x00, 0x20, 0x00, 0xF0,
+ 0xD3, 0xFA, 0x38, 0x46, 0x00, 0xF0, 0x2A, 0xFF, 0x42, 0x46, 0x49, 0x46,
+ 0x20, 0x46, 0xFF, 0xF7, 0xE1, 0xFD, 0x40, 0xB1, 0xE2, 0x79, 0x21, 0x7A,
+ 0x04, 0xF1, 0x09, 0x03, 0x03, 0xF0, 0x3C, 0xFC, 0x38, 0xB1, 0x00, 0x26,
+ 0x05, 0xE0, 0x0E, 0x49, 0x00, 0x22, 0x30, 0x31, 0x50, 0x46, 0xE7, 0xF7,
+ 0xBC, 0xD9, 0x22, 0x7A, 0xA1, 0x79, 0x33, 0x46, 0x20, 0x46, 0xEF, 0xF7,
+ 0xEF, 0xFF, 0x00, 0x2E, 0x0B, 0xD1, 0x20, 0x7A, 0x11, 0x28, 0x01, 0xD0,
+ 0x12, 0x28, 0x06, 0xD1, 0x00, 0x2D, 0x04, 0xD0, 0x28, 0x79, 0x00, 0x28,
+ 0x01, 0xD1, 0x01, 0x20, 0x28, 0x71, 0xBD, 0xE8, 0xF0, 0x87, 0x00, 0x00,
+ 0xD8, 0x5C, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x0C, 0x78, 0x20, 0x00,
+ 0x2D, 0x4A, 0x41, 0x88, 0xB2, 0xF8, 0x78, 0x21, 0x1F, 0x29, 0x4E, 0xD0,
+ 0x12, 0xDC, 0x17, 0x29, 0x3B, 0xD0, 0x06, 0xDC, 0x08, 0x29, 0x2F, 0xD0,
+ 0x12, 0x29, 0x4C, 0xD1, 0x00, 0x1D, 0x00, 0xF0, 0xC6, 0xB9, 0x19, 0x29,
+ 0x36, 0xD0, 0x1B, 0x29, 0x3C, 0xD0, 0x1E, 0x29, 0x43, 0xD1, 0x00, 0x1D,
+ 0x00, 0xF0, 0x22, 0xB9, 0xB1, 0xF5, 0x96, 0x7F, 0x1B, 0xD0, 0x0E, 0xDC,
+ 0xB1, 0xF5, 0x80, 0x7F, 0x1D, 0xD0, 0xB1, 0xF5, 0x92, 0x7F, 0x1D, 0xD0,
+ 0xA1, 0xF5, 0x80, 0x71, 0x25, 0x39, 0x32, 0xD1, 0x11, 0x06, 0x30, 0xD5,
+ 0x00, 0x1D, 0x00, 0xF0, 0x61, 0xB8, 0xB1, 0xF5, 0xDC, 0x7F, 0x27, 0xD0,
+ 0xA1, 0xF5, 0x80, 0x71, 0xB9, 0x39, 0x1A, 0xD0, 0x02, 0x29, 0x24, 0xD1,
+ 0x00, 0x1D, 0x00, 0xF0, 0x8A, 0xB9, 0x00, 0x1D, 0x00, 0xF0, 0x22, 0xB8,
+ 0x00, 0x1D, 0xFF, 0xF7, 0x83, 0xBE, 0x00, 0x1D, 0x00, 0xF0, 0x5A, 0xB9,
+ 0x00, 0x1D, 0x00, 0xF0, 0x29, 0xB8, 0x11, 0x06, 0x13, 0xD5, 0x00, 0x1D,
+ 0xFF, 0xF7, 0x42, 0xBF, 0x11, 0x06, 0x0E, 0xD5, 0x00, 0x1D, 0xFF, 0xF7,
+ 0x1D, 0xBF, 0x00, 0x1D, 0x00, 0xF0, 0xBE, 0xB8, 0x00, 0x1D, 0x00, 0xF0,
+ 0x5A, 0xB9, 0x00, 0x1D, 0x00, 0xF0, 0xCA, 0xB8, 0x00, 0x1D, 0x00, 0xF0,
+ 0xFB, 0xB8, 0x70, 0x47, 0x64, 0x01, 0x20, 0x00, 0x05, 0x49, 0x0A, 0x78,
+ 0x01, 0x2A, 0x05, 0xD1, 0x04, 0x4A, 0x40, 0x88, 0x89, 0x88, 0x12, 0x78,
+ 0xF0, 0xF7, 0x1E, 0xBE, 0x70, 0x47, 0x00, 0x00, 0x0C, 0x78, 0x20, 0x00,
+ 0x4E, 0x74, 0x20, 0x00, 0x10, 0xB5, 0x81, 0x88, 0x04, 0x46, 0xA1, 0xF5,
+ 0xA0, 0x60, 0xE6, 0x38, 0x0B, 0xD0, 0xA1, 0xF5, 0xA0, 0x60, 0xE3, 0x38,
+ 0x07, 0xD0, 0xA1, 0xF5, 0xA0, 0x60, 0xEF, 0x38, 0x03, 0xD0, 0xA1, 0xF5,
+ 0xA0, 0x60, 0xE7, 0x38, 0x0B, 0xD1, 0x20, 0x88, 0x02, 0xF0, 0x10, 0xFE,
+ 0x00, 0x28, 0x06, 0xD0, 0xA2, 0x88, 0xC0, 0x78, 0xBD, 0xE8, 0x10, 0x40,
+ 0x01, 0x21, 0xF6, 0xF7, 0x2F, 0xBC, 0x10, 0xBD, 0x2D, 0xE9, 0xFC, 0x47,
+ 0x04, 0x46, 0x3D, 0x48, 0x4F, 0xF0, 0x00, 0x09, 0x04, 0x21, 0x90, 0xF8,
+ 0xC1, 0x01, 0xC8, 0x46, 0x01, 0xEB, 0x80, 0x01, 0x4F, 0xF4, 0x89, 0x63,
+ 0x38, 0x4A, 0x48, 0x46, 0xF1, 0xF7, 0x68, 0xDE, 0x05, 0x00, 0x4F, 0xF0,
+ 0x02, 0x07, 0x4F, 0xF0, 0x00, 0x06, 0x04, 0xD0, 0x20, 0x78, 0x70, 0xB1,
+ 0x01, 0x28, 0x0C, 0xD0, 0x16, 0xE0, 0x03, 0x21, 0x00, 0x20, 0xCD, 0xE9,
+ 0x00, 0x01, 0x62, 0x78, 0x20, 0x78, 0x00, 0x23, 0xA1, 0x1C, 0xF0, 0xF7,
+ 0xF7, 0xFD, 0xBD, 0xE8, 0xFC, 0x87, 0x61, 0x78, 0xA0, 0x1C, 0x01, 0xF0,
+ 0xD5, 0xFD, 0x06, 0x00, 0x04, 0xD1, 0x61, 0x78, 0xA0, 0x1C, 0x01, 0xF0,
+ 0x5D, 0xFD, 0x06, 0x46, 0x20, 0x78, 0x10, 0xB1, 0x01, 0x28, 0x31, 0xD1,
+ 0x0A, 0xE0, 0x7E, 0xB3, 0x29, 0x46, 0x30, 0x46, 0x01, 0xF0, 0x72, 0xFF,
+ 0x50, 0xB3, 0x95, 0xF8, 0x00, 0x90, 0x05, 0xF1, 0x04, 0x08, 0x24, 0xE0,
+ 0x26, 0xB3, 0x29, 0x46, 0x30, 0x46, 0x01, 0xF0, 0x67, 0xFF, 0x90, 0xB1,
+ 0x2A, 0x78, 0x82, 0xB1, 0x20, 0x7A, 0x82, 0x42, 0x0D, 0xD2, 0x28, 0x1D,
+ 0xE1, 0x68, 0x19, 0xF4, 0x87, 0xF1, 0x40, 0xB9, 0x20, 0x7A, 0x2A, 0x78,
+ 0xE3, 0x68, 0x80, 0x1A, 0xC1, 0xB2, 0x30, 0x46, 0xFF, 0xF7, 0x82, 0xFA,
+ 0x58, 0xB9, 0x20, 0x7A, 0x28, 0x70, 0x22, 0x7A, 0x28, 0x1D, 0xE1, 0x68,
+ 0x19, 0xF4, 0xC1, 0xF1, 0x29, 0x46, 0x30, 0x46, 0x03, 0xF0, 0x0C, 0xFB,
+ 0x00, 0xB1, 0x00, 0x27, 0xE0, 0x68, 0x18, 0xB1, 0x21, 0x7A, 0x09, 0xB1,
+ 0xEF, 0xF7, 0x26, 0xFF, 0xCD, 0xE9, 0x00, 0x87, 0x62, 0x78, 0x20, 0x78,
+ 0x4B, 0x46, 0xA1, 0x1C, 0xF0, 0xF7, 0xA6, 0xFD, 0x28, 0x46, 0xBD, 0xE8,
+ 0xFC, 0x47, 0xF1, 0xF7, 0x88, 0x9E, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x84, 0xB1, 0x82, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x81, 0x79, 0x02, 0xF0,
+ 0x47, 0xFD, 0x20, 0xB1, 0xC0, 0x78, 0xBD, 0xE8, 0x10, 0x40, 0xF6, 0xF7,
+ 0x77, 0xBC, 0xA1, 0x79, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x02, 0x22,
+ 0xF2, 0xF7, 0xDE, 0xBB, 0x1C, 0xB5, 0x04, 0x46, 0x81, 0x79, 0x02, 0xF0,
+ 0x35, 0xFD, 0x00, 0x28, 0x0E, 0xD0, 0x08, 0x49, 0x0A, 0x68, 0x00, 0x2A,
+ 0x0A, 0xD0, 0xC0, 0x78, 0x8D, 0xF8, 0x00, 0x00, 0xE0, 0x79, 0x8D, 0xF8,
+ 0x01, 0x00, 0xCD, 0xF8, 0x04, 0xD0, 0x01, 0xA9, 0x22, 0x20, 0x90, 0x47,
+ 0x1C, 0xBD, 0x00, 0x00, 0x48, 0x78, 0x20, 0x00, 0x1C, 0xB5, 0x04, 0x46,
+ 0x01, 0x7A, 0x80, 0x1C, 0x02, 0xF0, 0x1A, 0xFD, 0x00, 0x28, 0x0E, 0xD0,
+ 0x07, 0x49, 0x0A, 0x68, 0x00, 0x2A, 0x0A, 0xD0, 0xC0, 0x78, 0x8D, 0xF8,
+ 0x00, 0x00, 0x20, 0x88, 0xAD, 0xF8, 0x02, 0x00, 0xCD, 0xF8, 0x04, 0xD0,
+ 0x01, 0xA9, 0x21, 0x20, 0x90, 0x47, 0x1C, 0xBD, 0x48, 0x78, 0x20, 0x00,
+ 0x30, 0xB5, 0x04, 0x46, 0x85, 0xB0, 0x00, 0x88, 0x02, 0xF0, 0x38, 0xFD,
+ 0x05, 0x00, 0x1E, 0xD0, 0x60, 0x88, 0xF0, 0xB1, 0x00, 0x90, 0x23, 0x88,
+ 0x02, 0x22, 0x18, 0x49, 0x18, 0x48, 0xE7, 0xF7, 0x38, 0xD8, 0x18, 0x48,
+ 0x02, 0x68, 0x00, 0x2A, 0x11, 0xD0, 0xE8, 0x78, 0x8D, 0xF8, 0x00, 0x00,
+ 0x60, 0x88, 0xAD, 0xF8, 0x02, 0x00, 0x20, 0x79, 0x8D, 0xF8, 0x04, 0x00,
+ 0xA0, 0x68, 0x02, 0x90, 0xE0, 0x68, 0x03, 0x90, 0xCD, 0xF8, 0x10, 0xD0,
+ 0x04, 0xA9, 0x23, 0x20, 0x90, 0x47, 0x05, 0xB0, 0x30, 0xBD, 0x0D, 0x48,
+ 0x90, 0xF8, 0x78, 0x01, 0x00, 0x06, 0xE2, 0xD5, 0xA9, 0x79, 0xE8, 0x1D,
+ 0x01, 0xF0, 0x08, 0xFD, 0x00, 0x28, 0xDC, 0xD0, 0x21, 0x79, 0x19, 0xB1,
+ 0xA1, 0x68, 0x03, 0xF0, 0x0D, 0xFF, 0xD6, 0xE7, 0xE1, 0x68, 0x03, 0xF0,
+ 0x69, 0xFF, 0xD2, 0xE7, 0x3C, 0x5D, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0x48, 0x78, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46,
+ 0x20, 0x21, 0x02, 0xF0, 0xBB, 0xFC, 0x20, 0xB1, 0xC0, 0x78, 0xBD, 0xE8,
+ 0x10, 0x40, 0xF6, 0xF7, 0x5F, 0xBC, 0xA1, 0x79, 0x20, 0x46, 0x02, 0x23,
+ 0xBD, 0xE8, 0x10, 0x40, 0x00, 0x22, 0xF3, 0xF7, 0xCF, 0xBF, 0x10, 0xB5,
+ 0x04, 0x46, 0x81, 0x79, 0x02, 0xF0, 0xA8, 0xFC, 0x30, 0xB1, 0xA1, 0x68,
+ 0x81, 0x62, 0xC0, 0x78, 0xBD, 0xE8, 0x10, 0x40, 0xF6, 0xF7, 0x98, 0xBC,
+ 0xA1, 0x79, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x02, 0x22, 0xF4, 0xF7,
+ 0xB1, 0xB8, 0x10, 0xB5, 0x04, 0x46, 0x81, 0x79, 0x02, 0xF0, 0x94, 0xFC,
+ 0x30, 0xB1, 0xA1, 0x68, 0x81, 0x62, 0xC0, 0x78, 0xBD, 0xE8, 0x10, 0x40,
+ 0xF6, 0xF7, 0x4E, 0xBC, 0xA1, 0x79, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40,
+ 0x02, 0x22, 0xF4, 0xF7, 0xC9, 0xB8, 0x70, 0xB5, 0x04, 0x46, 0x81, 0x79,
+ 0x02, 0xF0, 0x80, 0xFC, 0x05, 0x46, 0xA1, 0x79, 0x01, 0x22, 0x20, 0x46,
+ 0xF4, 0xF7, 0x00, 0xF9, 0x00, 0x2D, 0x05, 0xD0, 0xE1, 0x79, 0xE8, 0x78,
+ 0xBD, 0xE8, 0x70, 0x40, 0xF6, 0xF7, 0x4E, 0xBC, 0x70, 0xBD, 0x00, 0x00,
+ 0x03, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x00, 0x06, 0x01, 0xD5, 0x02, 0xF0,
+ 0x7B, 0xBB, 0x70, 0x47, 0x64, 0x01, 0x20, 0x00, 0x0A, 0x46, 0x00, 0xEB,
+ 0x40, 0x01, 0x07, 0x48, 0x10, 0xB5, 0x00, 0x68, 0x00, 0xEB, 0x01, 0x10,
+ 0x01, 0x78, 0x29, 0xB1, 0x81, 0x79, 0xC0, 0x1D, 0xF2, 0xF7, 0xFC, 0xFA,
+ 0x00, 0x20, 0x10, 0xBD, 0x04, 0x20, 0x10, 0xBD, 0x64, 0x78, 0x20, 0x00,
+ 0x70, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x01, 0x46, 0x09, 0x48, 0x02, 0xF0,
+ 0xE5, 0xFB, 0x60, 0xB1, 0x08, 0x48, 0x04, 0xEB, 0x44, 0x01, 0x2A, 0x46,
+ 0x00, 0x68, 0x00, 0xEB, 0x01, 0x10, 0x81, 0x79, 0xC0, 0x1D, 0xF2, 0xF7,
+ 0x39, 0xFB, 0x00, 0x20, 0x70, 0xBD, 0x04, 0x20, 0x70, 0xBD, 0x00, 0x00,
+ 0x6C, 0xB1, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x0D, 0x46,
+ 0x04, 0x46, 0x01, 0x46, 0x09, 0x48, 0x02, 0xF0, 0xC9, 0xFB, 0x68, 0xB1,
+ 0x08, 0x48, 0x04, 0xEB, 0x44, 0x01, 0x2B, 0x46, 0x00, 0x68, 0x07, 0x4A,
+ 0x00, 0xEB, 0x01, 0x10, 0x81, 0x79, 0xC0, 0x1D, 0xF3, 0xF7, 0x44, 0xFF,
+ 0x00, 0x20, 0x70, 0xBD, 0x04, 0x20, 0x70, 0xBD, 0x05, 0xB1, 0x82, 0x00,
+ 0x64, 0x78, 0x20, 0x00, 0x18, 0x78, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46,
+ 0x01, 0x46, 0x0A, 0x48, 0x02, 0xF0, 0xAC, 0xFB, 0x70, 0xB1, 0x09, 0x49,
+ 0x04, 0xEB, 0x44, 0x00, 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x07, 0x49,
+ 0x00, 0x8A, 0x0A, 0x78, 0x06, 0x49, 0x89, 0x88, 0xF0, 0xF7, 0x2E, 0xFC,
+ 0x00, 0x20, 0x10, 0xBD, 0x04, 0x20, 0x10, 0xBD, 0xDA, 0xB0, 0x82, 0x00,
+ 0x64, 0x78, 0x20, 0x00, 0x4E, 0x74, 0x20, 0x00, 0x0C, 0x78, 0x20, 0x00,
+ 0x70, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x01, 0x46, 0x09, 0x48, 0x02, 0xF0,
+ 0x8B, 0xFB, 0x60, 0xB1, 0x08, 0x48, 0x04, 0xEB, 0x44, 0x01, 0x2A, 0x46,
+ 0x00, 0x68, 0x00, 0xEB, 0x01, 0x10, 0x81, 0x79, 0xC0, 0x1D, 0xF4, 0xF7,
+ 0x29, 0xF8, 0x00, 0x20, 0x70, 0xBD, 0x04, 0x20, 0x70, 0xBD, 0x00, 0x00,
+ 0x4C, 0xB1, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x0E, 0x46,
+ 0x04, 0x46, 0x01, 0x46, 0x15, 0x46, 0x0A, 0x48, 0x02, 0xF0, 0x6E, 0xFB,
+ 0x68, 0xB1, 0x09, 0x48, 0x04, 0xEB, 0x44, 0x01, 0x2B, 0x46, 0x00, 0x68,
+ 0x32, 0x46, 0x00, 0xEB, 0x01, 0x10, 0x81, 0x79, 0xC0, 0x1D, 0xF4, 0xF7,
+ 0x65, 0xF8, 0x00, 0x20, 0x70, 0xBD, 0x04, 0x20, 0x70, 0xBD, 0x00, 0x00,
+ 0xE7, 0xB0, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, 0x0E, 0xB5, 0x08, 0x4A,
+ 0x12, 0x78, 0xD2, 0x07, 0x0B, 0xD0, 0x07, 0x4A, 0x12, 0x68, 0x00, 0x2A,
+ 0x07, 0xD0, 0x8D, 0xF8, 0x00, 0x00, 0x68, 0x46, 0xCD, 0xE9, 0x01, 0x10,
+ 0x02, 0xA9, 0x20, 0x20, 0x90, 0x47, 0x0E, 0xBD, 0x38, 0x78, 0x20, 0x00,
+ 0x48, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x15, 0x46, 0x03, 0x46, 0xA0, 0xF5,
+ 0x04, 0x72, 0x00, 0x24, 0x34, 0x48, 0x0A, 0x2A, 0x0D, 0xD2, 0xDF, 0xE8,
+ 0x02, 0xF0, 0x05, 0x26, 0x13, 0x1A, 0x21, 0x40, 0x4A, 0x51, 0x39, 0x5A,
+ 0x10, 0x29, 0x04, 0xD1, 0x2E, 0x48, 0x10, 0x22, 0x29, 0x46, 0x0C, 0x30,
+ 0x4A, 0xE0, 0x03, 0x24, 0x01, 0x22, 0x2C, 0x49, 0x2C, 0x48, 0xE6, 0xF7,
+ 0xCE, 0xDE, 0x4F, 0xE0, 0x01, 0x29, 0xF6, 0xD1, 0x29, 0x78, 0x01, 0x29,
+ 0xF3, 0xD8, 0x41, 0x70, 0x48, 0xE0, 0x01, 0x29, 0xEF, 0xD1, 0x29, 0x78,
+ 0x01, 0x29, 0xEC, 0xD8, 0x01, 0x70, 0x41, 0xE0, 0x02, 0x29, 0xE8, 0xD1,
+ 0x29, 0x88, 0x81, 0x80, 0x3C, 0xE0, 0x04, 0x29, 0xE3, 0xD1, 0x21, 0x4A,
+ 0x29, 0x68, 0x91, 0x42, 0xDF, 0xD8, 0x20, 0x4A, 0x81, 0x60, 0x12, 0x78,
+ 0xD2, 0x07, 0x31, 0xD0, 0x40, 0x78, 0x08, 0xB1, 0x41, 0xF0, 0x00, 0x41,
+ 0x08, 0x46, 0xF2, 0xF7, 0xDD, 0xFB, 0x29, 0xE0, 0x01, 0x29, 0xD0, 0xD1,
+ 0x29, 0x78, 0x01, 0x29, 0xCD, 0xD8, 0x81, 0x70, 0x22, 0xE0, 0x01, 0x29,
+ 0xC9, 0xD1, 0x28, 0x78, 0x10, 0x28, 0xC6, 0xD8, 0x07, 0x28, 0xC4, 0xD3,
+ 0x13, 0x49, 0x08, 0x70, 0x18, 0xE0, 0x01, 0x29, 0xBF, 0xD1, 0x29, 0x78,
+ 0x01, 0x29, 0xBC, 0xD8, 0xC1, 0x70, 0x11, 0xE0, 0x10, 0x29, 0xB8, 0xD1,
+ 0x08, 0x48, 0x10, 0x22, 0x29, 0x46, 0x1C, 0x30, 0x18, 0xF4, 0x9B, 0xF7,
+ 0x08, 0xE0, 0x01, 0x29, 0xAF, 0xD1, 0x28, 0x78, 0x01, 0x28, 0xAC, 0xD8,
+ 0x00, 0xB1, 0x01, 0x20, 0xF2, 0xF7, 0xC3, 0xFB, 0x20, 0x46, 0x70, 0xBD,
+ 0x0C, 0x78, 0x20, 0x00, 0x0C, 0x5C, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0x3F, 0x42, 0x0F, 0x00, 0x38, 0x78, 0x20, 0x00, 0x4E, 0x74, 0x20, 0x00,
+ 0x70, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x01, 0x46, 0x09, 0x48, 0x02, 0xF0,
+ 0xBF, 0xFA, 0x60, 0xB1, 0x08, 0x48, 0x04, 0xEB, 0x44, 0x01, 0x2A, 0x46,
+ 0x00, 0x68, 0x00, 0xEB, 0x01, 0x10, 0x81, 0x79, 0xC0, 0x1D, 0xF3, 0xF7,
+ 0x31, 0xFF, 0x00, 0x20, 0x70, 0xBD, 0x04, 0x20, 0x70, 0xBD, 0x00, 0x00,
+ 0x37, 0xB1, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, 0x10, 0xB5, 0xF2, 0xF7,
+ 0x69, 0xFB, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD,
+ 0x10, 0xB5, 0x04, 0x46, 0x40, 0x79, 0x01, 0x22, 0x8C, 0xB0, 0xB2, 0xEB,
+ 0x90, 0x1F, 0x33, 0xD1, 0x00, 0x20, 0x00, 0x90, 0x01, 0x90, 0x02, 0x90,
+ 0x03, 0x90, 0x60, 0x79, 0x8D, 0xF8, 0x0D, 0x00, 0x20, 0x79, 0x8D, 0xF8,
+ 0x0E, 0x00, 0xE0, 0x78, 0x8D, 0xF8, 0x0F, 0x00, 0x00, 0x20, 0x08, 0xAA,
+ 0xC0, 0xF1, 0x0F, 0x03, 0xCB, 0x5C, 0x13, 0x54, 0x40, 0x1C, 0xC0, 0xB2,
+ 0x10, 0x28, 0xF7, 0xD3, 0x04, 0xAA, 0x08, 0xA9, 0x68, 0x46, 0xE7, 0xF7,
+ 0x97, 0xDF, 0x9D, 0xF8, 0x1D, 0x00, 0xA1, 0x78, 0x88, 0x42, 0x11, 0xD1,
+ 0x9D, 0xF8, 0x1E, 0x00, 0x61, 0x78, 0x88, 0x42, 0x0C, 0xD1, 0x9D, 0xF8,
+ 0x1F, 0x00, 0x21, 0x78, 0x88, 0x42, 0x07, 0xD1, 0x00, 0x22, 0x0A, 0x49,
+ 0x0A, 0x48, 0xE6, 0xF7, 0x12, 0xDE, 0x01, 0x20, 0x0C, 0xB0, 0x10, 0xBD,
+ 0x21, 0x46, 0x08, 0x48, 0xE6, 0xF7, 0xDA, 0xDF, 0x03, 0x46, 0x04, 0x49,
+ 0x04, 0x48, 0x01, 0x22, 0x2C, 0x31, 0x80, 0x1E, 0xE6, 0xF7, 0x03, 0xDE,
+ 0x00, 0x20, 0xEF, 0xE7, 0x90, 0x71, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21,
+ 0x00, 0x00, 0x30, 0x21, 0x30, 0xB5, 0x17, 0x4D, 0x87, 0xB0, 0x04, 0x00,
+ 0x02, 0xD0, 0x20, 0x78, 0x01, 0x28, 0x08, 0xD0, 0x01, 0x23, 0x01, 0x22,
+ 0x13, 0x49, 0x28, 0x46, 0xE6, 0xF7, 0xED, 0xDD, 0x00, 0x20, 0x07, 0xB0,
+ 0x30, 0xBD, 0xA0, 0x78, 0x00, 0x07, 0x18, 0xD5, 0x6A, 0x46, 0x14, 0x21,
+ 0x20, 0x46, 0x01, 0xF0, 0x1B, 0xFE, 0x80, 0xB1, 0x10, 0x22, 0x0C, 0x49,
+ 0x68, 0x46, 0x18, 0xF4, 0xA5, 0xF6, 0x40, 0xB1, 0x08, 0x49, 0x63, 0x78,
+ 0x01, 0x22, 0x30, 0x39, 0x28, 0x46, 0xE6, 0xF7, 0xD4, 0xDD, 0x01, 0x20,
+ 0xE5, 0xE7, 0x05, 0x23, 0xDD, 0xE7, 0x04, 0x23, 0xDB, 0xE7, 0x02, 0x23,
+ 0xD9, 0xE7, 0x00, 0x00, 0x02, 0x35, 0x10, 0x21, 0xFC, 0x73, 0xC0, 0x08,
+ 0xC2, 0xB3, 0x82, 0x00, 0x02, 0x4A, 0x10, 0x5C, 0x08, 0x40, 0x00, 0xD0,
+ 0x01, 0x20, 0x70, 0x47, 0x58, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x00, 0x22,
+ 0x0D, 0x49, 0x0E, 0x48, 0xE6, 0xF7, 0xB7, 0xDD, 0x00, 0x24, 0x0D, 0x4D,
+ 0x0B, 0xE0, 0x69, 0x68, 0x04, 0xEB, 0x44, 0x00, 0x01, 0xEB, 0xC0, 0x00,
+ 0x01, 0x78, 0x01, 0x29, 0x01, 0xD1, 0x00, 0xF0, 0x11, 0xFB, 0x64, 0x1C,
+ 0xE4, 0xB2, 0x28, 0x78, 0x84, 0x42, 0xF0, 0xD3, 0xBD, 0xE8, 0x70, 0x40,
+ 0x01, 0x20, 0xEE, 0xF7, 0xC5, 0xB9, 0x00, 0x00, 0xEC, 0x70, 0xC0, 0x08,
+ 0x02, 0x35, 0x10, 0x21, 0xBC, 0x78, 0x20, 0x00, 0xF8, 0xB5, 0x0C, 0x46,
+ 0x05, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22, 0x20, 0x49, 0x21, 0x48,
+ 0xE6, 0xF7, 0x8F, 0xDD, 0x20, 0x49, 0x1F, 0x4B, 0x00, 0x20, 0xDB, 0x1E,
+ 0x0A, 0x78, 0x8F, 0x68, 0x17, 0xE0, 0x00, 0xEB, 0x40, 0x01, 0x01, 0xEB,
+ 0xC0, 0x01, 0x07, 0xEB, 0x41, 0x06, 0x31, 0x78, 0x69, 0xB1, 0x71, 0x78,
+ 0xA9, 0x42, 0x0A, 0xD1, 0xF1, 0x88, 0xA1, 0x42, 0x07, 0xD1, 0x14, 0x49,
+ 0x00, 0x22, 0x2C, 0x31, 0x18, 0x46, 0xE6, 0xF7, 0x74, 0xDD, 0x30, 0x46,
+ 0xF8, 0xBD, 0x40, 0x1C, 0xC0, 0xB2, 0x90, 0x42, 0xE5, 0xD3, 0x00, 0x21,
+ 0x09, 0xE0, 0x01, 0xEB, 0x41, 0x00, 0x00, 0xEB, 0xC1, 0x00, 0x07, 0xEB,
+ 0x40, 0x00, 0x06, 0x78, 0x5E, 0xB1, 0x49, 0x1C, 0xC9, 0xB2, 0x91, 0x42,
+ 0xF3, 0xD3, 0x07, 0x49, 0x00, 0x22, 0x54, 0x31, 0x18, 0x46, 0xE6, 0xF7,
+ 0x5A, 0xDD, 0x00, 0x20, 0xF8, 0xBD, 0x01, 0x21, 0x01, 0x70, 0x45, 0x70,
+ 0xC4, 0x80, 0x00, 0x21, 0x81, 0x70, 0xF8, 0xBD, 0x24, 0x86, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0x70, 0x79, 0x20, 0x00, 0x70, 0xB5, 0x0F, 0x49,
+ 0x03, 0x46, 0x00, 0x20, 0x0C, 0x78, 0x8A, 0x68, 0x0E, 0xE0, 0x00, 0xEB,
+ 0x40, 0x01, 0x01, 0xEB, 0xC0, 0x01, 0x02, 0xEB, 0x41, 0x01, 0x0D, 0x78,
+ 0x25, 0xB1, 0xCD, 0x88, 0x9D, 0x42, 0x01, 0xD1, 0x08, 0x46, 0x70, 0xBD,
+ 0x40, 0x1C, 0xC0, 0xB2, 0xA0, 0x42, 0xEE, 0xD3, 0x01, 0x22, 0x04, 0x49,
+ 0x04, 0x48, 0xE6, 0xF7, 0x2E, 0xDD, 0x00, 0x20, 0x70, 0xBD, 0x00, 0x00,
+ 0x70, 0x79, 0x20, 0x00, 0xC0, 0x86, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0x70, 0xB5, 0x05, 0x46, 0x0F, 0x48, 0x00, 0x22, 0x03, 0x78, 0x84, 0x68,
+ 0x0F, 0xE0, 0x02, 0xEB, 0x42, 0x00, 0x00, 0xEB, 0xC2, 0x00, 0x04, 0xEB,
+ 0x40, 0x00, 0x06, 0x78, 0x2E, 0xB1, 0xC6, 0x88, 0x8E, 0x42, 0x02, 0xD1,
+ 0x86, 0x88, 0xAE, 0x42, 0x0A, 0xD0, 0x52, 0x1C, 0xD2, 0xB2, 0x9A, 0x42,
+ 0xED, 0xD3, 0x0B, 0x46, 0x01, 0x22, 0x04, 0x49, 0x04, 0x48, 0xE6, 0xF7,
+ 0x06, 0xDD, 0x00, 0x20, 0x70, 0xBD, 0x00, 0x00, 0x70, 0x79, 0x20, 0x00,
+ 0xF4, 0x86, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x04, 0x00,
+ 0x0B, 0xD0, 0xE3, 0x88, 0x01, 0x22, 0x05, 0x49, 0x05, 0x48, 0xE6, 0xF7,
+ 0xF4, 0xDC, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x16, 0x21, 0x18, 0xF4,
+ 0x81, 0xB6, 0x10, 0xBD, 0x9C, 0x86, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21,
+ 0xF8, 0xB5, 0x0E, 0x46, 0x05, 0x46, 0x01, 0x46, 0x19, 0x48, 0x02, 0xF0,
+ 0x39, 0xF9, 0x20, 0xB3, 0x00, 0xF0, 0x78, 0xF8, 0x18, 0xB3, 0x00, 0x21,
+ 0x28, 0x46, 0xFF, 0xF7, 0x41, 0xFF, 0x04, 0x00, 0x1F, 0xD0, 0x14, 0x49,
+ 0x01, 0x20, 0xA0, 0x70, 0x09, 0x68, 0x05, 0xEB, 0x45, 0x00, 0x01, 0xEB,
+ 0x00, 0x10, 0x11, 0x49, 0x00, 0x8A, 0xA0, 0x80, 0xE6, 0x81, 0x0A, 0x78,
+ 0x00, 0x92, 0x8B, 0x78, 0x8A, 0x88, 0x31, 0x46, 0xF2, 0xF7, 0xE8, 0xFB,
+ 0x68, 0xB1, 0x00, 0x23, 0xA2, 0x78, 0x19, 0x46, 0x28, 0x46, 0x00, 0xF0,
+ 0x79, 0xF8, 0x00, 0x20, 0xF8, 0xBD, 0x04, 0x20, 0xF8, 0xBD, 0x0B, 0x20,
+ 0xF8, 0xBD, 0x08, 0x20, 0xF8, 0xBD, 0x20, 0x46, 0xFF, 0xF7, 0xB6, 0xFF,
+ 0x07, 0x20, 0xF8, 0xBD, 0xB2, 0xB5, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00,
+ 0xB6, 0x74, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, 0xFF, 0xF7, 0x5C, 0xFF,
+ 0x20, 0xB1, 0x81, 0x78, 0x02, 0x29, 0x03, 0xD0, 0x02, 0x20, 0x10, 0xBD,
+ 0x03, 0x20, 0x10, 0xBD, 0x03, 0x21, 0x81, 0x70, 0x80, 0x88, 0x21, 0x46,
+ 0xF2, 0xF7, 0x2A, 0xFC, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20,
+ 0x10, 0xBD, 0x00, 0x00, 0x70, 0xB5, 0x05, 0x46, 0x0C, 0x46, 0x00, 0x26,
+ 0x10, 0x46, 0xFF, 0xF7, 0x41, 0xFF, 0x20, 0xB1, 0x81, 0x78, 0x02, 0x29,
+ 0x03, 0xD0, 0x02, 0x20, 0x70, 0xBD, 0x03, 0x20, 0x70, 0xBD, 0xB5, 0xF5,
+ 0x82, 0x6F, 0x0E, 0xD0, 0xA5, 0xF5, 0x80, 0x61, 0x11, 0x39, 0x0C, 0xD0,
+ 0x01, 0x29, 0x0D, 0xD0, 0x03, 0x26, 0x2B, 0x46, 0x01, 0x22, 0x06, 0x49,
+ 0x06, 0x48, 0xE6, 0xF7, 0x74, 0xDC, 0x30, 0x46, 0x70, 0xBD, 0x80, 0x89,
+ 0x00, 0xE0, 0x80, 0x8A, 0x20, 0x80, 0xF8, 0xE7, 0x00, 0x89, 0xFB, 0xE7,
+ 0x58, 0x88, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x0D, 0x48,
+ 0x00, 0x24, 0x21, 0x46, 0x02, 0x78, 0x83, 0x68, 0x0A, 0xE0, 0x01, 0xEB,
+ 0x41, 0x00, 0x00, 0xEB, 0xC1, 0x00, 0x13, 0xF8, 0x10, 0x00, 0x08, 0xB9,
+ 0x64, 0x1C, 0xE4, 0xB2, 0x49, 0x1C, 0xC9, 0xB2, 0x91, 0x42, 0xF2, 0xD3,
+ 0x23, 0x46, 0x01, 0x22, 0x03, 0x49, 0x04, 0x48, 0xE6, 0xF7, 0x4D, 0xDC,
+ 0x20, 0x46, 0x10, 0xBD, 0x70, 0x79, 0x20, 0x00, 0x2C, 0x87, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0x3E, 0xB5, 0x09, 0x4C, 0x64, 0x68, 0x00, 0x2C,
+ 0x0C, 0xD0, 0xAD, 0xF8, 0x02, 0x10, 0x8D, 0xF8, 0x00, 0x00, 0xAD, 0xF8,
+ 0x06, 0x30, 0x8D, 0xF8, 0x04, 0x20, 0xCD, 0xF8, 0x08, 0xD0, 0x02, 0xA9,
+ 0x01, 0x20, 0xA0, 0x47, 0x3E, 0xBD, 0x00, 0x00, 0x70, 0x79, 0x20, 0x00,
+ 0xF8, 0xB5, 0x04, 0x46, 0x16, 0x20, 0x14, 0xFB, 0x00, 0xF6, 0x17, 0x48,
+ 0x02, 0xF0, 0x2A, 0xFC, 0x15, 0x4A, 0x16, 0x4D, 0x92, 0xF8, 0x41, 0x00,
+ 0xA0, 0x42, 0x07, 0xD2, 0x00, 0x90, 0x23, 0x46, 0x02, 0x22, 0x13, 0x49,
+ 0x28, 0x46, 0xE6, 0xF7, 0x1A, 0xDC, 0x1A, 0xE0, 0x11, 0x49, 0xB2, 0xF8,
+ 0x4E, 0x00, 0x0D, 0x4F, 0x88, 0x80, 0x92, 0xF8, 0x47, 0x00, 0x48, 0x70,
+ 0x88, 0x70, 0x10, 0x3F, 0xB6, 0x23, 0x3C, 0x70, 0x0C, 0x4A, 0x31, 0x46,
+ 0x00, 0x20, 0xF1, 0xF7, 0x9D, 0xD9, 0xB8, 0x60, 0x08, 0xB1, 0x01, 0x20,
+ 0xF8, 0xBD, 0x06, 0x49, 0x00, 0x22, 0x38, 0x31, 0x28, 0x46, 0xE6, 0xF7,
+ 0xFE, 0xDB, 0x00, 0x20, 0xF8, 0xBD, 0x00, 0x00, 0x80, 0x79, 0x20, 0x00,
+ 0x00, 0x35, 0x10, 0x21, 0x44, 0x87, 0xC0, 0x08, 0xB6, 0x74, 0x20, 0x00,
+ 0xA6, 0xB5, 0x82, 0x00, 0x10, 0xB5, 0xF2, 0xF7, 0x8F, 0xFB, 0x08, 0xB1,
+ 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, 0x01, 0x49, 0x48, 0x60,
+ 0x70, 0x47, 0x00, 0x00, 0x70, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xF8, 0x43,
+ 0x17, 0x46, 0x88, 0x46, 0x81, 0x46, 0xFF, 0xF7, 0x91, 0xFE, 0x04, 0x00,
+ 0x24, 0x48, 0x06, 0x88, 0x24, 0x48, 0x03, 0x88, 0x24, 0x48, 0x09, 0xD0,
+ 0xA1, 0x78, 0x02, 0x29, 0x0C, 0xD0, 0x00, 0x22, 0x22, 0x49, 0xE6, 0xF7,
+ 0xCE, 0xDB, 0x02, 0x20, 0xBD, 0xE8, 0xF8, 0x83, 0x1F, 0x49, 0x00, 0x22,
+ 0x24, 0x39, 0xE6, 0xF7, 0xC6, 0xDB, 0x28, 0xE0, 0x21, 0x89, 0xB9, 0x42,
+ 0x06, 0xD2, 0x1B, 0x49, 0x00, 0x22, 0x24, 0x31, 0xE6, 0xF7, 0xBD, 0xDB,
+ 0x09, 0x20, 0xED, 0xE7, 0xB8, 0xF1, 0x00, 0x0F, 0x1B, 0xD0, 0xD7, 0xB1,
+ 0xA1, 0x89, 0xD1, 0xB1, 0x32, 0x46, 0x39, 0x46, 0x18, 0x46, 0xEF, 0xF7,
+ 0x27, 0xFA, 0x05, 0x00, 0x18, 0xD0, 0xA8, 0x19, 0x3A, 0x46, 0x41, 0x46,
+ 0x18, 0xF4, 0xBD, 0xF4, 0x00, 0x96, 0xA1, 0x88, 0x3B, 0x46, 0x4A, 0x46,
+ 0x28, 0x46, 0xF2, 0xF7, 0x03, 0xFB, 0x68, 0xB1, 0xA0, 0x89, 0x40, 0x1E,
+ 0xA0, 0x81, 0x00, 0x20, 0xCE, 0xE7, 0x03, 0x20, 0xCC, 0xE7, 0x07, 0x49,
+ 0x00, 0x22, 0x4C, 0x31, 0xE6, 0xF7, 0x95, 0xDB, 0x08, 0x20, 0xC5, 0xE7,
+ 0x07, 0x20, 0xC3, 0xE7, 0x46, 0x78, 0x20, 0x00, 0x44, 0x78, 0x20, 0x00,
+ 0x00, 0x35, 0x10, 0x21, 0xE8, 0x87, 0xC0, 0x08, 0x70, 0xB5, 0x00, 0x24,
+ 0x11, 0x4B, 0xB0, 0xF5, 0x80, 0x6F, 0x04, 0xD0, 0xA0, 0xF5, 0x80, 0x65,
+ 0x01, 0x3D, 0x08, 0xD1, 0x0F, 0xE0, 0x01, 0x29, 0x05, 0xD1, 0x11, 0x78,
+ 0x5A, 0x78, 0x91, 0x42, 0x01, 0xD8, 0x19, 0x70, 0x0F, 0xE0, 0x03, 0x46,
+ 0x03, 0x24, 0x01, 0x22, 0x08, 0x49, 0x09, 0x48, 0xE6, 0xF7, 0x6F, 0xDB,
+ 0x07, 0xE0, 0x02, 0x29, 0xF5, 0xD1, 0x11, 0x88, 0x06, 0x4A, 0x52, 0x88,
+ 0x91, 0x42, 0xF0, 0xD8, 0x99, 0x80, 0x20, 0x46, 0x70, 0xBD, 0x00, 0x00,
+ 0xB6, 0x74, 0x20, 0x00, 0x9C, 0x87, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0x70, 0x79, 0x20, 0x00, 0x10, 0xB5, 0xF2, 0xF7, 0x1D, 0xFB, 0x08, 0xB1,
+ 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x4F,
+ 0x8F, 0xB0, 0x99, 0x46, 0x93, 0x46, 0x0F, 0x46, 0x05, 0x46, 0x00, 0x24,
+ 0xDD, 0xF8, 0x60, 0xA0, 0x01, 0xF0, 0x7C, 0xFB, 0x08, 0xB1, 0x4F, 0xB1,
+ 0x09, 0xE0, 0x00, 0x22, 0x21, 0x49, 0x22, 0x48, 0xE6, 0xF7, 0x3F, 0xDB,
+ 0x0B, 0x20, 0x0F, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x1F, 0x4F, 0xDF, 0xF8,
+ 0x80, 0x80, 0x03, 0xAE, 0x98, 0xF8, 0x00, 0x00, 0x70, 0xB3, 0x0D, 0xB1,
+ 0x07, 0x2D, 0x01, 0xD9, 0x03, 0x20, 0xF0, 0xE7, 0xE8, 0x07, 0x06, 0xD0,
+ 0x18, 0x49, 0x30, 0x46, 0x10, 0x22, 0x89, 0x1D, 0x18, 0xF4, 0x3B, 0xF4,
+ 0x01, 0x24, 0xA8, 0x07, 0x07, 0xD5, 0x14, 0x49, 0x06, 0xEB, 0x04, 0x10,
+ 0x10, 0x22, 0x16, 0x31, 0x18, 0xF4, 0x31, 0xF4, 0x64, 0x1C, 0x68, 0x07,
+ 0x06, 0xD5, 0x0F, 0x49, 0x06, 0xEB, 0x04, 0x10, 0x10, 0x22, 0x26, 0x31,
+ 0x18, 0xF4, 0x27, 0xF4, 0xCD, 0xF8, 0x00, 0xA0, 0xCD, 0xE9, 0x01, 0x96,
+ 0x98, 0xF8, 0x00, 0x00, 0x00, 0xB1, 0x01, 0x20, 0x5B, 0x46, 0x3A, 0x46,
+ 0x29, 0x46, 0x00, 0xF0, 0x0F, 0xF8, 0xC6, 0xE7, 0x04, 0x49, 0x10, 0x22,
+ 0x30, 0x46, 0x89, 0x1D, 0xEA, 0xE7, 0x00, 0x00, 0xAC, 0x60, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x68, 0x78, 0x20, 0x00, 0x41, 0x78, 0x20, 0x00,
+ 0x2D, 0xE9, 0xFF, 0x4F, 0x23, 0x4E, 0x83, 0xB0, 0x00, 0x25, 0x30, 0x78,
+ 0xDD, 0xF8, 0x40, 0xB0, 0xDD, 0xF8, 0x48, 0xA0, 0x98, 0x46, 0x89, 0x46,
+ 0x80, 0x09, 0x0A, 0xD0, 0x02, 0x25, 0x2B, 0x46, 0x01, 0x22, 0x1D, 0x49,
+ 0x1D, 0x48, 0xE6, 0xF7, 0xE2, 0xDA, 0x07, 0xB0, 0x28, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x8F, 0x19, 0x46, 0x05, 0x98, 0x01, 0xF0, 0x97, 0xFF, 0x08, 0xB1,
+ 0x01, 0x25, 0xEE, 0xE7, 0x05, 0x98, 0x01, 0xF0, 0xD1, 0xFE, 0x04, 0x00,
+ 0x1D, 0xD0, 0x84, 0xF8, 0x06, 0x80, 0x01, 0x27, 0xA7, 0x70, 0xCD, 0xE9,
+ 0x00, 0x9B, 0xCD, 0xF8, 0x08, 0xA0, 0x42, 0x46, 0x11, 0x9B, 0x05, 0x99,
+ 0x03, 0x98, 0xF2, 0xF7, 0xE1, 0xF8, 0x80, 0xB1, 0x30, 0x78, 0x00, 0x22,
+ 0x20, 0xF0, 0xC0, 0x00, 0x40, 0x30, 0x30, 0x70, 0x67, 0x70, 0xE0, 0x78,
+ 0x01, 0x21, 0xF5, 0xF7, 0x1D, 0xFE, 0x00, 0x20, 0xF5, 0xF7, 0x3E, 0xFE,
+ 0xD1, 0xE7, 0x08, 0x25, 0xC9, 0xE7, 0x20, 0x46, 0x02, 0xF0, 0x9E, 0xFA,
+ 0x07, 0x25, 0xC4, 0xE7, 0x38, 0x78, 0x20, 0x00, 0x88, 0x60, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x04, 0x00, 0x08, 0xD0, 0x61, 0x78,
+ 0x01, 0x20, 0xED, 0xF7, 0xDB, 0xFE, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40,
+ 0x00, 0xF0, 0x02, 0xB8, 0x10, 0xBD, 0x00, 0x00, 0x30, 0xB5, 0x04, 0x46,
+ 0x43, 0x78, 0x8B, 0xB0, 0x01, 0x22, 0x20, 0x49, 0x20, 0x48, 0xE6, 0xF7,
+ 0x90, 0xDA, 0x00, 0x25, 0x08, 0x95, 0x09, 0x95, 0x61, 0x78, 0x08, 0xA8,
+ 0xF5, 0xF7, 0xE8, 0xF8, 0xA0, 0x78, 0x80, 0x07, 0x06, 0xD5, 0x8D, 0xF8,
+ 0x00, 0x50, 0x61, 0x78, 0x04, 0x22, 0x68, 0x46, 0xF5, 0xF7, 0xB2, 0xF8,
+ 0xA0, 0x78, 0x40, 0x07, 0x06, 0xD5, 0x8D, 0xF8, 0x00, 0x50, 0x61, 0x78,
+ 0x04, 0x22, 0x68, 0x46, 0xF5, 0xF7, 0x5C, 0xF9, 0xA0, 0x78, 0x00, 0x07,
+ 0x02, 0xD5, 0x60, 0x78, 0xF4, 0xF7, 0xE4, 0xFD, 0xA0, 0x78, 0xC0, 0x06,
+ 0x02, 0xD5, 0x60, 0x78, 0xF4, 0xF7, 0x82, 0xFD, 0xA0, 0x78, 0x80, 0x06,
+ 0x02, 0xD5, 0x60, 0x78, 0xF4, 0xF7, 0xAA, 0xFD, 0xA0, 0x78, 0x40, 0x06,
+ 0x06, 0xD5, 0x8D, 0xF8, 0x00, 0x50, 0x61, 0x78, 0x04, 0x22, 0x68, 0x46,
+ 0xF5, 0xF7, 0x32, 0xF8, 0x18, 0x21, 0x20, 0x46, 0x18, 0xF4, 0xE8, 0xF3,
+ 0x0B, 0xB0, 0x30, 0xBD, 0xD0, 0x70, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21,
+ 0x38, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x01, 0x46, 0x13, 0x48, 0x01, 0xF0,
+ 0x9F, 0xFE, 0x00, 0xB3, 0x12, 0x49, 0x04, 0xEB, 0x44, 0x00, 0x09, 0x68,
+ 0x01, 0xEB, 0x00, 0x10, 0x01, 0x21, 0x00, 0x8A, 0x8D, 0xF8, 0x00, 0x10,
+ 0x8D, 0xF8, 0x01, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x02, 0x00, 0x1D, 0xB1,
+ 0x00, 0x20, 0x8D, 0xF8, 0x03, 0x00, 0x01, 0xE0, 0x8D, 0xF8, 0x03, 0x10,
+ 0x6A, 0x46, 0x04, 0x21, 0x4F, 0xF6, 0x80, 0x50, 0xF3, 0xF7, 0xA0, 0xFB,
+ 0x08, 0xB1, 0x00, 0x20, 0x38, 0xBD, 0x07, 0x20, 0x38, 0xBD, 0x04, 0x20,
+ 0x38, 0xBD, 0x00, 0x00, 0xD8, 0xB1, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00,
+ 0x2D, 0xE9, 0xF0, 0x41, 0x18, 0x4E, 0x04, 0x46, 0x18, 0x4F, 0x70, 0x78,
+ 0x40, 0x1E, 0x84, 0x42, 0x08, 0xDD, 0x23, 0x46, 0x01, 0x22, 0x16, 0x49,
+ 0x38, 0x46, 0xE6, 0xF7, 0x10, 0xDA, 0x03, 0x20, 0xBD, 0xE8, 0xF0, 0x81,
+ 0x70, 0x68, 0x04, 0xEB, 0x44, 0x05, 0x00, 0xEB, 0x05, 0x10, 0x43, 0x78,
+ 0x02, 0x2B, 0x09, 0xD0, 0x01, 0x2B, 0x07, 0xD0, 0x0D, 0x49, 0x01, 0x22,
+ 0x2C, 0x31, 0x38, 0x46, 0xE6, 0xF7, 0xFD, 0xD9, 0x04, 0x20, 0xEB, 0xE7,
+ 0x00, 0x8A, 0x06, 0x21, 0xF2, 0xF7, 0x82, 0xFA, 0x71, 0x68, 0x03, 0x20,
+ 0x01, 0xEB, 0x05, 0x11, 0x00, 0x22, 0x48, 0x70, 0x01, 0x46, 0x20, 0x46,
+ 0xF5, 0xF7, 0x52, 0xFD, 0x00, 0x20, 0xDB, 0xE7, 0x60, 0x78, 0x20, 0x00,
+ 0x00, 0x35, 0x10, 0x21, 0x38, 0x60, 0xC0, 0x08, 0x10, 0xB5, 0xF2, 0xF7,
+ 0xB5, 0xFA, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD,
+ 0x10, 0xB5, 0xF2, 0xF7, 0xBF, 0xFA, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD,
+ 0x07, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0x41, 0x88, 0x01, 0x24, 0x40, 0xF2,
+ 0x65, 0x13, 0xA1, 0xF2, 0x65, 0x12, 0x99, 0x42, 0x16, 0xD0, 0x06, 0xDC,
+ 0xA1, 0xF5, 0x80, 0x71, 0x61, 0x39, 0x09, 0xD0, 0x02, 0x29, 0x04, 0xD1,
+ 0x0A, 0xE0, 0x2F, 0x2A, 0x10, 0xD0, 0x31, 0x2A, 0x12, 0xD0, 0x00, 0x24,
+ 0x20, 0x46, 0x10, 0xBD, 0x00, 0x1D, 0xF5, 0xF7, 0xC1, 0xFA, 0xF9, 0xE7,
+ 0x00, 0x1D, 0xF5, 0xF7, 0xFD, 0xFA, 0xF5, 0xE7, 0x00, 0x1D, 0xF5, 0xF7,
+ 0xED, 0xFA, 0xF1, 0xE7, 0x00, 0x1D, 0xF5, 0xF7, 0x53, 0xFA, 0xED, 0xE7,
+ 0x00, 0x1D, 0xF5, 0xF7, 0x5D, 0xFA, 0xE9, 0xE7, 0x10, 0xB5, 0xF2, 0xF7,
+ 0x49, 0xFE, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD,
+ 0x10, 0xB5, 0xF3, 0xF7, 0x34, 0xF8, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD,
+ 0x07, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0xF3, 0xF7, 0x48, 0xF8, 0x08, 0xB1,
+ 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0x14, 0x4C,
+ 0xA0, 0x68, 0x28, 0xB9, 0x06, 0x20, 0x00, 0xF0, 0x45, 0xFB, 0x08, 0xB1,
+ 0x00, 0x20, 0x10, 0xBD, 0x00, 0x23, 0x61, 0x78, 0xA0, 0x68, 0x07, 0xE0,
+ 0xC3, 0xEB, 0x03, 0x12, 0x00, 0xEB, 0x82, 0x04, 0x22, 0x78, 0x4A, 0xB1,
+ 0x5B, 0x1C, 0xDB, 0xB2, 0x8B, 0x42, 0xF5, 0xD3, 0x00, 0x22, 0x09, 0x49,
+ 0x09, 0x48, 0xE6, 0xF7, 0x74, 0xD9, 0xE9, 0xE7, 0x01, 0x20, 0x20, 0x70,
+ 0x02, 0x46, 0x05, 0x49, 0x05, 0x48, 0x63, 0x70, 0x20, 0x39, 0xC0, 0x1C,
+ 0xE6, 0xF7, 0x69, 0xD9, 0x20, 0x46, 0x10, 0xBD, 0xF8, 0x79, 0x20, 0x00,
+ 0x54, 0x8A, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x38, 0xB5, 0x13, 0x49,
+ 0x8C, 0x68, 0x14, 0xB1, 0x00, 0x20, 0x4B, 0x78, 0x0E, 0xE0, 0x03, 0x20,
+ 0x38, 0xBD, 0xC0, 0xEB, 0x00, 0x11, 0x04, 0xEB, 0x81, 0x01, 0x0A, 0x78,
+ 0x22, 0xB1, 0xCA, 0x78, 0x01, 0x2A, 0x0B, 0xD0, 0x02, 0x2A, 0x09, 0xD0,
+ 0x40, 0x1C, 0xC0, 0xB2, 0x98, 0x42, 0xF0, 0xD3, 0x00, 0x21, 0x08, 0x46,
+ 0xF2, 0xF7, 0x72, 0xFC, 0x00, 0x20, 0x38, 0xBD, 0xD0, 0xB2, 0x00, 0x90,
+ 0x4B, 0x78, 0x02, 0x22, 0x03, 0x49, 0x04, 0x48, 0xE6, 0xF7, 0x3B, 0xD9,
+ 0x02, 0x20, 0x38, 0xBD, 0xF8, 0x79, 0x20, 0x00, 0x94, 0x8B, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0xFF, 0xF7, 0x9F, 0xFF, 0x08, 0xB1,
+ 0x40, 0x78, 0x10, 0xBD, 0xFF, 0x20, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x47,
+ 0x86, 0xB0, 0x88, 0x46, 0x05, 0x00, 0x4F, 0xF0, 0x00, 0x06, 0x01, 0xD0,
+ 0x04, 0x2D, 0x03, 0xD9, 0x03, 0x20, 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x87,
+ 0xDF, 0xF8, 0x84, 0xA0, 0x9A, 0xF8, 0x03, 0x00, 0x08, 0xB1, 0x01, 0x20,
+ 0xF5, 0xE7, 0x00, 0x24, 0xE9, 0x46, 0x0E, 0xE0, 0x18, 0xF8, 0x04, 0x70,
+ 0x38, 0x46, 0x00, 0xF0, 0xB3, 0xF8, 0x60, 0xB1, 0x80, 0x78, 0xC0, 0x07,
+ 0x0B, 0xD0, 0x04, 0xEB, 0x44, 0x01, 0x64, 0x1C, 0x09, 0xF8, 0x11, 0x70,
+ 0xE4, 0xB2, 0xAC, 0x42, 0xEE, 0xD3, 0x26, 0xB1, 0x23, 0xE0, 0x0A, 0x26,
+ 0x21, 0xE0, 0x03, 0x26, 0x1F, 0xE0, 0x00, 0x24, 0x4F, 0xF0, 0x03, 0x09,
+ 0x11, 0xE0, 0x18, 0xF8, 0x04, 0x70, 0x38, 0x46, 0x00, 0xF0, 0x98, 0xF8,
+ 0x48, 0xB1, 0xC1, 0x78, 0x02, 0x29, 0x06, 0xD1, 0x80, 0xF8, 0x03, 0x90,
+ 0x49, 0x46, 0x00, 0x22, 0x38, 0x46, 0x00, 0xF0, 0x59, 0xFC, 0x64, 0x1C,
+ 0xE4, 0xB2, 0xAC, 0x42, 0xEB, 0xD3, 0x01, 0x21, 0x8A, 0xF8, 0x03, 0x10,
+ 0x6A, 0x46, 0x29, 0x46, 0x00, 0x20, 0xF2, 0xF7, 0x27, 0xFA, 0x30, 0x46,
+ 0xB9, 0xE7, 0x00, 0x00, 0xF8, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x47,
+ 0x86, 0xB0, 0x88, 0x46, 0x05, 0x00, 0x4F, 0xF0, 0x00, 0x06, 0x01, 0xD0,
+ 0x04, 0x2D, 0x03, 0xD9, 0x03, 0x20, 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x87,
+ 0xDF, 0xF8, 0x88, 0xA0, 0x9A, 0xF8, 0x03, 0x00, 0x08, 0xB1, 0x01, 0x20,
+ 0xF5, 0xE7, 0x00, 0x24, 0xE9, 0x46, 0x15, 0xE0, 0x18, 0xF8, 0x04, 0x70,
+ 0x38, 0x46, 0x00, 0xF0, 0x5F, 0xF8, 0x98, 0xB1, 0x81, 0x78, 0xC9, 0x07,
+ 0x12, 0xD0, 0x04, 0xEB, 0x44, 0x01, 0x64, 0x1C, 0x09, 0xF8, 0x11, 0x70,
+ 0x09, 0xEB, 0x41, 0x01, 0x03, 0x8F, 0x4B, 0x80, 0x90, 0xF8, 0x36, 0x00,
+ 0x08, 0x71, 0xE4, 0xB2, 0xAC, 0x42, 0xE7, 0xD3, 0x26, 0xB1, 0x1F, 0xE0,
+ 0x0A, 0x26, 0x1D, 0xE0, 0x03, 0x26, 0x1B, 0xE0, 0x00, 0x24, 0x01, 0x27,
+ 0x0F, 0xE0, 0x18, 0xF8, 0x04, 0x00, 0x81, 0x46, 0x00, 0xF0, 0x3E, 0xF8,
+ 0x38, 0xB1, 0xC1, 0x78, 0x29, 0xB9, 0xC7, 0x70, 0x39, 0x46, 0x00, 0x22,
+ 0x48, 0x46, 0x00, 0xF0, 0x01, 0xFC, 0x64, 0x1C, 0xE4, 0xB2, 0xAC, 0x42,
+ 0xED, 0xD3, 0x8A, 0xF8, 0x03, 0x70, 0x6A, 0x46, 0x29, 0x46, 0x01, 0x20,
+ 0xF2, 0xF7, 0xD0, 0xF9, 0x30, 0x46, 0xB6, 0xE7, 0xF8, 0x79, 0x20, 0x00,
+ 0x70, 0xB5, 0x0F, 0x49, 0x03, 0x46, 0x8C, 0x68, 0x14, 0xB1, 0x00, 0x20,
+ 0x4A, 0x78, 0x0E, 0xE0, 0x00, 0x20, 0x70, 0xBD, 0xC0, 0xEB, 0x00, 0x11,
+ 0x04, 0xEB, 0x81, 0x01, 0x0D, 0x78, 0x25, 0xB1, 0x4D, 0x8F, 0x9D, 0x42,
+ 0x01, 0xD1, 0x08, 0x46, 0x70, 0xBD, 0x40, 0x1C, 0xC0, 0xB2, 0x90, 0x42,
+ 0xF0, 0xD3, 0x01, 0x22, 0x03, 0x49, 0x04, 0x48, 0xE6, 0xF7, 0x63, 0xD8,
+ 0xE8, 0xE7, 0x00, 0x00, 0xF8, 0x79, 0x20, 0x00, 0xD8, 0x8A, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x0F, 0x49, 0x03, 0x46, 0x8C, 0x68,
+ 0x14, 0xB1, 0x00, 0x20, 0x4A, 0x78, 0x0E, 0xE0, 0x00, 0x20, 0x70, 0xBD,
+ 0xC0, 0xEB, 0x00, 0x11, 0x04, 0xEB, 0x81, 0x01, 0x0D, 0x78, 0x25, 0xB1,
+ 0x4D, 0x78, 0x9D, 0x42, 0x01, 0xD1, 0x08, 0x46, 0x70, 0xBD, 0x40, 0x1C,
+ 0xC0, 0xB2, 0x90, 0x42, 0xF0, 0xD3, 0x01, 0x22, 0x03, 0x49, 0x04, 0x48,
+ 0xE6, 0xF7, 0x3D, 0xD8, 0xE8, 0xE7, 0x00, 0x00, 0xF8, 0x79, 0x20, 0x00,
+ 0x9C, 0x8A, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x38, 0xB5, 0x04, 0x46,
+ 0x02, 0x46, 0x69, 0x46, 0x40, 0xF2, 0x7B, 0x20, 0x00, 0xF0, 0x3C, 0xFF,
+ 0x30, 0xB9, 0xBD, 0xF8, 0x00, 0x00, 0xFF, 0xF7, 0xA7, 0xFF, 0x08, 0xB1,
+ 0xC1, 0x78, 0x39, 0xB1, 0x23, 0x46, 0x01, 0x22, 0x03, 0x49, 0x04, 0x48,
+ 0xE6, 0xF7, 0x1F, 0xD8, 0xFF, 0x20, 0x38, 0xBD, 0x40, 0x78, 0x38, 0xBD,
+ 0x58, 0x8B, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x04, 0x46,
+ 0xFF, 0xF7, 0xB8, 0xFF, 0x40, 0xB1, 0xC1, 0x78, 0x31, 0xB9, 0x40, 0x8F,
+ 0x20, 0xB1, 0x01, 0xF0, 0x01, 0xFD, 0x08, 0xB1, 0xC0, 0x78, 0x10, 0xBD,
+ 0x23, 0x46, 0x01, 0x22, 0x02, 0x49, 0x03, 0x48, 0xE6, 0xF7, 0x03, 0xD8,
+ 0xFF, 0x20, 0x10, 0xBD, 0x18, 0x8B, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0x10, 0xB5, 0x00, 0x24, 0x0B, 0x4A, 0xB0, 0xF5, 0x4C, 0x7F, 0x0C, 0xD0,
+ 0xA0, 0xF5, 0x40, 0x73, 0x31, 0x3B, 0x0B, 0xD0, 0x03, 0x46, 0x03, 0x24,
+ 0x01, 0x22, 0x07, 0x49, 0x07, 0x48, 0xE5, 0xF7, 0xEC, 0xDF, 0x20, 0x46,
+ 0x10, 0xBD, 0x90, 0x88, 0x08, 0x80, 0xFA, 0xE7, 0x10, 0x78, 0x08, 0x70,
+ 0xF7, 0xE7, 0x00, 0x00, 0xF8, 0x79, 0x20, 0x00, 0x08, 0x8A, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x25, 0x49, 0x10, 0xB5, 0x89, 0x68, 0x01, 0x24,
+ 0x89, 0xB1, 0x41, 0x88, 0xB1, 0xF5, 0xC5, 0x7F, 0x2B, 0xD0, 0x0E, 0xDC,
+ 0xB1, 0xF5, 0xC1, 0x7F, 0x33, 0xD0, 0xB1, 0xF5, 0xC2, 0x7F, 0x1C, 0xD0,
+ 0xB1, 0xF5, 0xC3, 0x7F, 0x11, 0xD0, 0xB1, 0xF5, 0xC4, 0x7F, 0x31, 0xD1,
+ 0x11, 0xE0, 0x00, 0x20, 0x10, 0xBD, 0xB1, 0xF5, 0xCF, 0x7F, 0x14, 0xD0,
+ 0xA1, 0xF5, 0x80, 0x71, 0xB1, 0x39, 0x18, 0xD0, 0x01, 0x29, 0x1A, 0xD0,
+ 0x04, 0x29, 0x23, 0xD1, 0x1F, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0xEA, 0xF8,
+ 0x1F, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x70, 0xF8, 0x1B, 0xE0, 0x00, 0x1D,
+ 0x00, 0xF0, 0x52, 0xF9, 0x17, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0xF8, 0xF8,
+ 0x13, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x7E, 0xF8, 0x0F, 0xE0, 0x00, 0x1D,
+ 0x00, 0xF0, 0x34, 0xF8, 0x0B, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x36, 0xF9,
+ 0x07, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x0A, 0xF8, 0x02, 0xE0, 0x00, 0x1D,
+ 0x00, 0xF0, 0x48, 0xF8, 0x00, 0x24, 0x20, 0x46, 0x10, 0xBD, 0x00, 0x00,
+ 0xF8, 0x79, 0x20, 0x00, 0x0F, 0x4A, 0x30, 0xB4, 0x94, 0x68, 0x00, 0x21,
+ 0x52, 0x78, 0x15, 0xE0, 0xC1, 0xEB, 0x01, 0x13, 0x04, 0xEB, 0x83, 0x03,
+ 0x1D, 0x78, 0x6D, 0xB1, 0xDD, 0x78, 0x02, 0x2D, 0x0A, 0xD1, 0x9D, 0x79,
+ 0x2D, 0x07, 0x07, 0xD5, 0x00, 0x21, 0xD9, 0x70, 0x59, 0x87, 0x02, 0x88,
+ 0x58, 0x78, 0x30, 0xBC, 0x00, 0xF0, 0xE6, 0xBA, 0x49, 0x1C, 0xC9, 0xB2,
+ 0x91, 0x42, 0xE7, 0xD3, 0x30, 0xBC, 0x70, 0x47, 0xF8, 0x79, 0x20, 0x00,
+ 0x10, 0xB5, 0x04, 0x46, 0x80, 0x78, 0xFF, 0xF7, 0x0D, 0xFF, 0x58, 0xB1,
+ 0x00, 0x21, 0xC1, 0x70, 0x23, 0x88, 0x7B, 0xB1, 0x0A, 0x46, 0x42, 0x87,
+ 0x22, 0x88, 0x40, 0x78, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0xCC, 0xBA,
+ 0xA3, 0x78, 0xBD, 0xE8, 0x10, 0x40, 0x01, 0x22, 0x02, 0x49, 0x03, 0x48,
+ 0xE5, 0xF7, 0x53, 0x9F, 0xA2, 0x88, 0xEE, 0xE7, 0x50, 0x8C, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x01, 0x88, 0x00, 0x29, 0x04, 0xD1, 0x03, 0x49,
+ 0x42, 0x88, 0x8A, 0x80, 0x00, 0x79, 0x08, 0x70, 0x70, 0x47, 0x00, 0x00,
+ 0xF8, 0x79, 0x20, 0x00, 0x01, 0x78, 0x31, 0xB1, 0x04, 0x22, 0x0A, 0x4B,
+ 0x40, 0x88, 0xD9, 0x68, 0x18, 0xB1, 0x49, 0x78, 0x0B, 0xE0, 0x02, 0x22,
+ 0xF7, 0xE7, 0x88, 0x78, 0x10, 0x43, 0x88, 0x70, 0x98, 0x78, 0x08, 0xB1,
+ 0x00, 0xF0, 0xB0, 0xB9, 0x00, 0x22, 0x49, 0x78, 0x10, 0x46, 0x00, 0xF0,
+ 0x43, 0xB9, 0x00, 0x00, 0xF8, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xF8, 0x43,
+ 0x04, 0x46, 0x00, 0x78, 0x4F, 0xF0, 0x00, 0x09, 0x28, 0x4E, 0x02, 0x27,
+ 0x4D, 0x46, 0xB0, 0xB1, 0xB8, 0x46, 0x4F, 0x46, 0x2C, 0xE0, 0xB1, 0x68,
+ 0xC5, 0xEB, 0x05, 0x10, 0x01, 0xEB, 0x80, 0x00, 0x01, 0x78, 0x51, 0xB1,
+ 0xC1, 0x78, 0x03, 0x29, 0x07, 0xD1, 0x61, 0x88, 0x29, 0xB1, 0xC7, 0x70,
+ 0x39, 0x46, 0x62, 0x88, 0x40, 0x78, 0x00, 0xF0, 0x79, 0xFA, 0x6D, 0x1C,
+ 0xED, 0xB2, 0x70, 0x78, 0x85, 0x42, 0xE8, 0xD3, 0x17, 0xE0, 0xB1, 0x68,
+ 0xC5, 0xEB, 0x05, 0x10, 0x01, 0xEB, 0x80, 0x00, 0x01, 0x78, 0x59, 0xB1,
+ 0xC1, 0x78, 0x01, 0x29, 0x08, 0xD1, 0x61, 0x88, 0xD9, 0xB1, 0xC7, 0x70,
+ 0x47, 0x87, 0xC1, 0x78, 0x62, 0x88, 0x40, 0x78, 0x00, 0xF0, 0x60, 0xFA,
+ 0x6D, 0x1C, 0xED, 0xB2, 0x70, 0x78, 0x85, 0x42, 0xE7, 0xD3, 0x0E, 0x48,
+ 0x86, 0xF8, 0x03, 0x90, 0x21, 0x78, 0x02, 0x68, 0x61, 0xB1, 0x00, 0x2A,
+ 0x05, 0xD0, 0x60, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0x69, 0x46, 0x63, 0x20,
+ 0x90, 0x47, 0xBD, 0xE8, 0xF8, 0x83, 0x80, 0xF8, 0x03, 0x80, 0xE2, 0xE7,
+ 0x00, 0x2A, 0xF8, 0xD0, 0x60, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0x69, 0x46,
+ 0x64, 0x20, 0xF1, 0xE7, 0xF8, 0x79, 0x20, 0x00, 0x48, 0x78, 0x20, 0x00,
+ 0x0B, 0x4B, 0x02, 0x46, 0x40, 0x88, 0xD9, 0x68, 0x10, 0xB1, 0x49, 0x78,
+ 0x01, 0x22, 0x0C, 0xE0, 0x88, 0x78, 0x40, 0xF0, 0x01, 0x00, 0x88, 0x70,
+ 0x10, 0x78, 0x08, 0x71, 0x98, 0x78, 0x08, 0xB1, 0x00, 0xF0, 0x3A, 0xB9,
+ 0x00, 0x22, 0x49, 0x78, 0x10, 0x46, 0x00, 0xF0, 0xCD, 0xB8, 0x00, 0x00,
+ 0xF8, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x41, 0x1E, 0x4F, 0x04, 0x46,
+ 0x01, 0x78, 0x3D, 0x78, 0x40, 0x88, 0x1D, 0x4E, 0x02, 0x29, 0x01, 0xD0,
+ 0xF8, 0xB1, 0x26, 0xE0, 0xFF, 0x21, 0x39, 0x70, 0x28, 0xB9, 0x28, 0x46,
+ 0xFF, 0xF7, 0x44, 0xFE, 0x70, 0xB1, 0x00, 0xF0, 0x7F, 0xF8, 0x32, 0x68,
+ 0x00, 0x2A, 0x25, 0xD0, 0x60, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0x8D, 0xF8,
+ 0x02, 0x50, 0xCD, 0xF8, 0x04, 0xD0, 0x01, 0xA9, 0x61, 0x20, 0x1A, 0xE0,
+ 0x3B, 0x78, 0x02, 0xB0, 0x01, 0x22, 0xBD, 0xE8, 0xF0, 0x41, 0x0E, 0x49,
+ 0x0E, 0x48, 0xE5, 0xF7, 0x86, 0x9E, 0x0E, 0x4A, 0x50, 0x78, 0xC0, 0xEB,
+ 0x00, 0x10, 0x81, 0x00, 0x90, 0x68, 0x18, 0xF4, 0x33, 0xF0, 0x32, 0x68,
+ 0x00, 0x2A, 0x07, 0xD0, 0x60, 0x88, 0xAD, 0xF8, 0x04, 0x00, 0x01, 0xA8,
+ 0x00, 0x90, 0x69, 0x46, 0x62, 0x20, 0x90, 0x47, 0xBD, 0xE8, 0xFC, 0x81,
+ 0xBC, 0x74, 0x20, 0x00, 0x48, 0x78, 0x20, 0x00, 0x0C, 0x8C, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0xF8, 0x79, 0x20, 0x00, 0x04, 0x49, 0x08, 0xB5,
+ 0x0A, 0x68, 0x00, 0x2A, 0x03, 0xD0, 0x00, 0x90, 0x69, 0x46, 0x65, 0x20,
+ 0x90, 0x47, 0x08, 0xBD, 0x48, 0x78, 0x20, 0x00, 0x09, 0x4A, 0x00, 0x88,
+ 0xD1, 0x68, 0x10, 0xB1, 0x49, 0x78, 0x08, 0x22, 0x0A, 0xE0, 0x88, 0x78,
+ 0x40, 0xF0, 0x08, 0x00, 0x88, 0x70, 0x90, 0x78, 0x08, 0xB1, 0x00, 0xF0,
+ 0xCD, 0xB8, 0x00, 0x22, 0x49, 0x78, 0x10, 0x46, 0x00, 0xF0, 0x60, 0xB8,
+ 0xF8, 0x79, 0x20, 0x00, 0x70, 0xB5, 0x0F, 0x4D, 0x04, 0x46, 0xA8, 0x68,
+ 0x08, 0xB1, 0x00, 0x20, 0x70, 0xBD, 0x0C, 0xB1, 0x0A, 0x2C, 0x07, 0xD9,
+ 0x23, 0x46, 0x01, 0x22, 0x0A, 0x49, 0x0B, 0x48, 0xE5, 0xF7, 0x35, 0xDE,
+ 0x03, 0x20, 0x70, 0xBD, 0xC4, 0xEB, 0x04, 0x10, 0x81, 0x00, 0x88, 0x23,
+ 0x07, 0x4A, 0x00, 0x20, 0xF0, 0xF7, 0xC0, 0xDB, 0xA8, 0x60, 0x08, 0xB1,
+ 0x6C, 0x70, 0xE6, 0xE7, 0x08, 0x20, 0x70, 0xBD, 0xF8, 0x79, 0x20, 0x00,
+ 0xDC, 0x89, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0xC0, 0xB5, 0x82, 0x00,
+ 0x10, 0xB5, 0x04, 0x00, 0x0B, 0xD0, 0x63, 0x78, 0x01, 0x22, 0x05, 0x49,
+ 0x05, 0x48, 0xE5, 0xF7, 0x14, 0xDE, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40,
+ 0x3C, 0x21, 0x17, 0xF4, 0xC3, 0xB7, 0x10, 0xBD, 0x74, 0x8A, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x04, 0x46, 0xFF, 0xF7, 0xAA, 0xFD,
+ 0x10, 0xB1, 0xC1, 0x78, 0x61, 0xB9, 0x01, 0xE0, 0x0A, 0x20, 0x70, 0xBD,
+ 0x09, 0x4D, 0x29, 0x78, 0xFF, 0x29, 0x01, 0xD0, 0x01, 0x20, 0x70, 0xBD,
+ 0x07, 0x49, 0xC9, 0x68, 0x81, 0x42, 0x01, 0xD1, 0x02, 0x20, 0x70, 0xBD,
+ 0x21, 0x46, 0x02, 0x20, 0xF2, 0xF7, 0x1C, 0xF9, 0x2C, 0x70, 0x00, 0x20,
+ 0x70, 0xBD, 0x00, 0x00, 0xBC, 0x74, 0x20, 0x00, 0xF8, 0x79, 0x20, 0x00,
+ 0x1C, 0xB5, 0x0A, 0x4B, 0x00, 0x24, 0xDC, 0x60, 0x9C, 0x70, 0x09, 0x4B,
+ 0x1B, 0x68, 0x00, 0x2B, 0x0A, 0xD0, 0xAD, 0xF8, 0x00, 0x00, 0x8D, 0xF8,
+ 0x02, 0x10, 0x8D, 0xF8, 0x03, 0x20, 0xCD, 0xF8, 0x04, 0xD0, 0x01, 0xA9,
+ 0x60, 0x20, 0x98, 0x47, 0x1C, 0xBD, 0x00, 0x00, 0xF8, 0x79, 0x20, 0x00,
+ 0x48, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x15, 0x46, 0x0C, 0x46, 0xFF, 0xF7,
+ 0x6D, 0xFD, 0x20, 0xB1, 0xB4, 0xF5, 0x80, 0x6F, 0x03, 0xD9, 0x03, 0x20,
+ 0x70, 0xBD, 0x0A, 0x20, 0x70, 0xBD, 0x45, 0x62, 0x04, 0x84, 0x00, 0x20,
+ 0x70, 0xBD, 0x70, 0xB5, 0x14, 0x46, 0x0D, 0x46, 0xFF, 0xF7, 0x5C, 0xFD,
+ 0x20, 0xB1, 0x05, 0x87, 0x80, 0xF8, 0x36, 0x40, 0x00, 0x20, 0x70, 0xBD,
+ 0x0A, 0x20, 0x70, 0xBD, 0x2D, 0xE9, 0xF0, 0x5F, 0x1D, 0x46, 0xDD, 0xE9,
+ 0x0C, 0xB4, 0xDD, 0xE9, 0x0F, 0x98, 0x16, 0x46, 0x0F, 0x46, 0xDD, 0xF8,
+ 0x4C, 0xA0, 0xFF, 0xF7, 0x47, 0xFD, 0xF8, 0xB1, 0xC7, 0x80, 0xC0, 0xE9,
+ 0x02, 0x65, 0x0A, 0x99, 0x01, 0x74, 0x0B, 0x99, 0x41, 0x74, 0x80, 0xF8,
+ 0x12, 0xB0, 0x0E, 0x99, 0x41, 0x76, 0x80, 0xF8, 0x1A, 0x90, 0x80, 0xF8,
+ 0x1B, 0x80, 0x12, 0x99, 0x41, 0x77, 0x11, 0x99, 0x01, 0x77, 0x80, 0xF8,
+ 0x1E, 0xA0, 0x14, 0x99, 0xC1, 0x77, 0x24, 0xB1, 0x21, 0x68, 0x40, 0xF8,
+ 0x13, 0x1F, 0xA1, 0x88, 0x81, 0x80, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x9F,
+ 0x0A, 0x20, 0xFB, 0xE7, 0x70, 0xB5, 0x4D, 0x4C, 0x8C, 0xB0, 0x02, 0x22,
+ 0xA0, 0x78, 0x00, 0x90, 0xE0, 0x68, 0x4B, 0x49, 0x43, 0x78, 0x4B, 0x48,
+ 0xE5, 0xF7, 0x73, 0xDD, 0xA0, 0x78, 0xC1, 0x07, 0x1E, 0xD0, 0xE0, 0x68,
+ 0x07, 0xAE, 0x01, 0x7F, 0xC5, 0x7F, 0x83, 0x7F, 0x42, 0x7F, 0x86, 0xE8,
+ 0x2E, 0x00, 0x03, 0xAE, 0xC5, 0x7E, 0x83, 0x7E, 0x42, 0x7E, 0x00, 0xF1,
+ 0x13, 0x01, 0x86, 0xE8, 0x2E, 0x00, 0x01, 0x7C, 0x83, 0x7C, 0x42, 0x7C,
+ 0x8D, 0xE8, 0x0E, 0x00, 0xD0, 0xE9, 0x02, 0x23, 0xC1, 0x88, 0x40, 0x78,
+ 0xF1, 0xF7, 0xCE, 0xFE, 0xA0, 0x78, 0x20, 0xF0, 0x01, 0x00, 0x6A, 0xE0,
+ 0x41, 0x07, 0x4F, 0xF0, 0x00, 0x05, 0x2D, 0xD5, 0xE1, 0x68, 0x4B, 0x8D,
+ 0x4B, 0xB1, 0xC8, 0x6A, 0xC6, 0x18, 0x08, 0x8D, 0xC0, 0x1A, 0x80, 0xB2,
+ 0xC8, 0x28, 0x0C, 0xD9, 0xC8, 0x20, 0x00, 0x22, 0x0A, 0xE0, 0x08, 0x8D,
+ 0xCE, 0x6A, 0xC8, 0x28, 0x02, 0xD9, 0xC8, 0x20, 0x01, 0x22, 0x00, 0xE0,
+ 0x03, 0x22, 0x48, 0x85, 0x02, 0xE0, 0x02, 0x22, 0x03, 0x44, 0x4B, 0x85,
+ 0xC0, 0xB2, 0xCD, 0xE9, 0x00, 0x06, 0x01, 0x23, 0x49, 0x78, 0x18, 0x46,
+ 0xF1, 0xF7, 0x24, 0xFE, 0xE0, 0x68, 0x01, 0x8D, 0x42, 0x8D, 0x91, 0x42,
+ 0x04, 0xD1, 0xA1, 0x78, 0x21, 0xF0, 0x04, 0x01, 0xA1, 0x70, 0x45, 0x85,
+ 0x0C, 0xB0, 0x70, 0xBD, 0x81, 0x07, 0x2C, 0xD5, 0xE1, 0x68, 0x4B, 0x8C,
+ 0x4B, 0xB1, 0x48, 0x6A, 0xC6, 0x18, 0x08, 0x8C, 0xC0, 0x1A, 0x80, 0xB2,
+ 0xC8, 0x28, 0x0C, 0xD9, 0xC8, 0x20, 0x00, 0x22, 0x0A, 0xE0, 0x08, 0x8C,
+ 0x4E, 0x6A, 0xC8, 0x28, 0x02, 0xD9, 0xC8, 0x20, 0x01, 0x22, 0x00, 0xE0,
+ 0x03, 0x22, 0x48, 0x84, 0x02, 0xE0, 0x02, 0x22, 0x03, 0x44, 0x4B, 0x84,
+ 0xC0, 0xB2, 0xCD, 0xE9, 0x00, 0x06, 0x49, 0x78, 0x01, 0x23, 0x00, 0x20,
+ 0xF1, 0xF7, 0xF4, 0xFD, 0xE0, 0x68, 0x01, 0x8C, 0x42, 0x8C, 0x91, 0x42,
+ 0xD4, 0xD1, 0xA1, 0x78, 0x21, 0xF0, 0x02, 0x01, 0xA1, 0x70, 0x45, 0x84,
+ 0xCE, 0xE7, 0x00, 0x07, 0xCC, 0xD5, 0xE0, 0x68, 0x41, 0x78, 0x30, 0x30,
+ 0xF2, 0xF7, 0x5E, 0xFA, 0xA0, 0x78, 0x20, 0xF0, 0x08, 0x00, 0xA0, 0x70,
+ 0xC2, 0xE7, 0x00, 0x00, 0xF8, 0x79, 0x20, 0x00, 0xD4, 0x8B, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x0C, 0x46, 0xFF, 0xF7, 0x7E, 0xFC,
+ 0x28, 0xB1, 0x21, 0x68, 0x01, 0x63, 0xA1, 0x88, 0x81, 0x86, 0x00, 0x20,
+ 0x10, 0xBD, 0x0A, 0x20, 0x10, 0xBD, 0x70, 0xB5, 0x15, 0x46, 0x0C, 0x46,
+ 0xFF, 0xF7, 0x70, 0xFC, 0x20, 0xB1, 0xB4, 0xF5, 0x80, 0x6F, 0x03, 0xD9,
+ 0x03, 0x20, 0x70, 0xBD, 0x0A, 0x20, 0x70, 0xBD, 0xC5, 0x62, 0x04, 0x85,
+ 0x00, 0x20, 0x70, 0xBD, 0x10, 0xB5, 0x0C, 0x46, 0xFF, 0xF7, 0x60, 0xFC,
+ 0x08, 0xB1, 0x14, 0xB1, 0x12, 0xE0, 0x0A, 0x20, 0x10, 0xBD, 0xC1, 0x88,
+ 0x01, 0x24, 0xCA, 0x06, 0x07, 0xD5, 0x4A, 0x07, 0x00, 0xD4, 0x03, 0x24,
+ 0x89, 0x07, 0x07, 0xD5, 0x44, 0xF0, 0x04, 0x04, 0x04, 0xE0, 0x89, 0x07,
+ 0x01, 0xD5, 0x05, 0x24, 0x00, 0xE0, 0x03, 0x24, 0x09, 0x4A, 0xD1, 0x68,
+ 0x09, 0xB1, 0x01, 0x20, 0x10, 0xBD, 0xC1, 0x78, 0x31, 0xB1, 0x02, 0x29,
+ 0x02, 0xD1, 0x14, 0xF0, 0x09, 0x0F, 0x01, 0xD0, 0x02, 0x20, 0x10, 0xBD,
+ 0x94, 0x70, 0xD0, 0x60, 0xFF, 0xF7, 0x14, 0xFF, 0x00, 0x20, 0x10, 0xBD,
+ 0xF8, 0x79, 0x20, 0x00, 0x1C, 0xB5, 0x01, 0x23, 0x8D, 0xF8, 0x04, 0x00,
+ 0x8D, 0xF8, 0x00, 0x30, 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8, 0x02, 0x20,
+ 0x68, 0x46, 0xF5, 0xF7, 0x5D, 0xF8, 0x1C, 0xBD, 0x70, 0xB5, 0x00, 0x24,
+ 0xA0, 0xF5, 0x50, 0x73, 0x0F, 0x4A, 0x10, 0x4D, 0x06, 0x2B, 0x12, 0xD2,
+ 0xDF, 0xE8, 0x03, 0xF0, 0x03, 0x05, 0x08, 0x0A, 0x0C, 0x0E, 0x50, 0x78,
+ 0x00, 0xE0, 0x10, 0x78, 0x08, 0x70, 0x0F, 0xE0, 0x68, 0x78, 0xFB, 0xE7,
+ 0x28, 0x78, 0xF9, 0xE7, 0x50, 0x88, 0x00, 0xE0, 0x90, 0x88, 0x08, 0x80,
+ 0x06, 0xE0, 0x03, 0x46, 0x03, 0x24, 0x01, 0x22, 0x04, 0x49, 0x05, 0x48,
+ 0xE5, 0xF7, 0x5F, 0xDC, 0x20, 0x46, 0x70, 0xBD, 0x08, 0x7A, 0x20, 0x00,
+ 0xBE, 0x74, 0x20, 0x00, 0xCC, 0x8C, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0x41, 0x88, 0xB1, 0xF5, 0xC6, 0x7F, 0x0D, 0xD0, 0xB1, 0xF5, 0xC7, 0x7F,
+ 0x07, 0xD0, 0xB1, 0xF5, 0xD6, 0x7F, 0x0A, 0xD0, 0xB1, 0xF5, 0xD8, 0x7F,
+ 0x0A, 0xD1, 0x02, 0xF0, 0x71, 0xB8, 0x00, 0x1D, 0x02, 0xF0, 0x0A, 0xB8,
+ 0x00, 0x1D, 0x01, 0xF0, 0xE5, 0xBF, 0x00, 0x1D, 0x01, 0xF0, 0xCC, 0xBF,
+ 0x70, 0x47, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x03, 0x46, 0x00, 0x24,
+ 0xA0, 0xF5, 0x50, 0x70, 0x01, 0x27, 0x1A, 0x4E, 0x1A, 0x4D, 0x06, 0x28,
+ 0x0B, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x03, 0x11, 0x17, 0x1E, 0x23, 0x28,
+ 0x01, 0x29, 0x04, 0xD1, 0x10, 0x78, 0x03, 0x28, 0x01, 0xD8, 0x70, 0x70,
+ 0x0A, 0xE0, 0x03, 0x24, 0x01, 0x22, 0x13, 0x49, 0x13, 0x48, 0xE5, 0xF7,
+ 0x1E, 0xDC, 0x1A, 0xE0, 0x01, 0x29, 0xF6, 0xD1, 0x10, 0x78, 0x30, 0x70,
+ 0xAF, 0x70, 0x14, 0xE0, 0x01, 0x29, 0xF0, 0xD1, 0x10, 0x78, 0x05, 0x28,
+ 0xED, 0xD8, 0x68, 0x70, 0xF6, 0xE7, 0x01, 0x29, 0xE9, 0xD1, 0x10, 0x78,
+ 0x28, 0x70, 0x08, 0xE0, 0x02, 0x29, 0xE4, 0xD1, 0x10, 0x88, 0x70, 0x80,
+ 0x03, 0xE0, 0x02, 0x29, 0xDF, 0xD1, 0x10, 0x88, 0xB0, 0x80, 0x20, 0x46,
+ 0xBD, 0xE8, 0xF0, 0x81, 0x08, 0x7A, 0x20, 0x00, 0xBE, 0x74, 0x20, 0x00,
+ 0x9C, 0x8C, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x06, 0x4A, 0x00, 0xEB,
+ 0x40, 0x00, 0x02, 0xEB, 0x40, 0x00, 0x0A, 0x68, 0x02, 0x60, 0x89, 0x88,
+ 0x81, 0x80, 0x02, 0x49, 0x01, 0x20, 0x09, 0x1F, 0x88, 0x70, 0x70, 0x47,
+ 0xC2, 0x74, 0x20, 0x00, 0x70, 0xB5, 0x17, 0x4D, 0x02, 0x24, 0x28, 0x78,
+ 0x10, 0xF0, 0x30, 0x0F, 0x08, 0xD0, 0xC0, 0xF3, 0x01, 0x13, 0x01, 0x22,
+ 0x13, 0x49, 0x14, 0x48, 0xE5, 0xF7, 0xD9, 0xDB, 0x20, 0x46, 0x70, 0xBD,
+ 0x12, 0x48, 0x13, 0x4E, 0x81, 0x78, 0xA1, 0xB1, 0x42, 0x78, 0x03, 0x1D,
+ 0x04, 0x2A, 0x00, 0xD1, 0x9B, 0x1D, 0x31, 0x78, 0x70, 0x78, 0xF1, 0xF7,
+ 0x47, 0xFE, 0x00, 0x28, 0xEE, 0xD0, 0x28, 0x78, 0x00, 0x24, 0x20, 0xF0,
+ 0x30, 0x00, 0x10, 0x30, 0x28, 0x70, 0x20, 0x46, 0xF4, 0xF7, 0x48, 0xFF,
+ 0xE4, 0xE7, 0x01, 0x78, 0xB3, 0x88, 0x72, 0x88, 0x01, 0x20, 0xF1, 0xF7,
+ 0x66, 0xFE, 0xEC, 0xE7, 0x38, 0x78, 0x20, 0x00, 0xFC, 0x8C, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0xBE, 0x74, 0x20, 0x00, 0x08, 0x7A, 0x20, 0x00,
+ 0x70, 0xB5, 0x10, 0x4D, 0x02, 0x24, 0x28, 0x78, 0xC0, 0xF3, 0x01, 0x13,
+ 0x02, 0x2B, 0x06, 0xD0, 0x01, 0x22, 0x0D, 0x49, 0x0D, 0x48, 0xE5, 0xF7,
+ 0xA0, 0xDB, 0x20, 0x46, 0x70, 0xBD, 0x0C, 0x48, 0x83, 0x88, 0x42, 0x88,
+ 0x0B, 0x48, 0x01, 0x78, 0x00, 0x20, 0xF1, 0xF7, 0x44, 0xFE, 0x00, 0x28,
+ 0xF3, 0xD0, 0x28, 0x78, 0x00, 0x24, 0x40, 0xF0, 0x30, 0x00, 0x28, 0x70,
+ 0x20, 0x46, 0xF4, 0xF7, 0x15, 0xFF, 0xEA, 0xE7, 0x38, 0x78, 0x20, 0x00,
+ 0x24, 0x8D, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x08, 0x7A, 0x20, 0x00,
+ 0xBE, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x43, 0x93, 0xB0, 0x0F, 0x46,
+ 0x04, 0x46, 0x01, 0x29, 0x61, 0xD1, 0x60, 0x79, 0xB1, 0xEB, 0x90, 0x1F,
+ 0x5D, 0xD1, 0x00, 0x26, 0xDF, 0xF8, 0xBC, 0x90, 0xDF, 0xF8, 0xBC, 0x80,
+ 0x53, 0xE0, 0xD8, 0xF8, 0x04, 0x00, 0x06, 0xEB, 0x46, 0x01, 0x00, 0xEB,
+ 0xC1, 0x05, 0x28, 0x78, 0x01, 0x28, 0x48, 0xD1, 0xA8, 0x78, 0x00, 0x07,
+ 0x45, 0xD5, 0x69, 0x78, 0x04, 0xA8, 0xF4, 0xF7, 0x53, 0xF8, 0x00, 0x20,
+ 0x00, 0x90, 0x01, 0x90, 0x02, 0x90, 0x03, 0x90, 0x60, 0x79, 0x8D, 0xF8,
+ 0x0D, 0x00, 0x20, 0x79, 0x8D, 0xF8, 0x0E, 0x00, 0xE0, 0x78, 0x8D, 0xF8,
+ 0x0F, 0x00, 0x00, 0x20, 0x04, 0xAA, 0x0E, 0xA9, 0xC0, 0xF1, 0x0F, 0x03,
+ 0xD3, 0x5C, 0x0B, 0x54, 0x40, 0x1C, 0xC0, 0xB2, 0x10, 0x28, 0xF7, 0xD3,
+ 0x0A, 0xAA, 0x68, 0x46, 0xE6, 0xF7, 0xB4, 0xDC, 0x9D, 0xF8, 0x35, 0x00,
+ 0xA1, 0x78, 0x88, 0x42, 0x18, 0xD1, 0x9D, 0xF8, 0x36, 0x00, 0x61, 0x78,
+ 0x88, 0x42, 0x13, 0xD1, 0x9D, 0xF8, 0x37, 0x00, 0x21, 0x78, 0x88, 0x42,
+ 0x0E, 0xD1, 0x6B, 0x78, 0x01, 0x22, 0x10, 0x49, 0x48, 0x46, 0xE5, 0xF7,
+ 0x2E, 0xDB, 0x20, 0x68, 0xA8, 0x60, 0xA0, 0x88, 0xA8, 0x81, 0xAF, 0x73,
+ 0x28, 0x46, 0x13, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x09, 0x49, 0x6B, 0x78,
+ 0x01, 0x22, 0x2C, 0x31, 0x48, 0x46, 0xE5, 0xF7, 0x1E, 0xDB, 0x76, 0x1C,
+ 0xF6, 0xB2, 0x98, 0xF8, 0x00, 0x10, 0x8E, 0x42, 0xA7, 0xD3, 0x00, 0x20,
+ 0xED, 0xE7, 0x00, 0x00, 0x02, 0x35, 0x10, 0x21, 0xBC, 0x78, 0x20, 0x00,
+ 0x38, 0x71, 0xC0, 0x08, 0x2D, 0xE9, 0xF8, 0x43, 0xDF, 0xF8, 0xF4, 0x80,
+ 0x3D, 0x4E, 0x81, 0x46, 0x0C, 0x46, 0x02, 0x29, 0x03, 0xD0, 0x03, 0x2C,
+ 0x01, 0xD0, 0x00, 0x25, 0x35, 0xE0, 0x8C, 0x1E, 0xE4, 0xB2, 0x00, 0x25,
+ 0x17, 0xE0, 0x71, 0x68, 0x05, 0xEB, 0x45, 0x00, 0x01, 0xEB, 0xC0, 0x07,
+ 0x38, 0x78, 0x01, 0x28, 0x0D, 0xD1, 0x06, 0x22, 0x49, 0x46, 0x07, 0xF1,
+ 0x10, 0x00, 0x17, 0xF4, 0xB9, 0xF3, 0x30, 0xB9, 0xB8, 0x7D, 0xA0, 0x42,
+ 0x03, 0xD1, 0x2B, 0x46, 0x01, 0x22, 0x2E, 0x49, 0x3B, 0xE0, 0x6D, 0x1C,
+ 0xED, 0xB2, 0x30, 0x78, 0x85, 0x42, 0xE4, 0xD3, 0x40, 0xE0, 0x71, 0x68,
+ 0x05, 0xEB, 0x45, 0x00, 0x01, 0xEB, 0xC0, 0x07, 0x38, 0x78, 0x01, 0x28,
+ 0x0B, 0xD1, 0x06, 0x22, 0x49, 0x46, 0x07, 0xF1, 0x08, 0x00, 0x17, 0xF4,
+ 0x9D, 0xF3, 0x20, 0xB9, 0xB8, 0x7B, 0xA0, 0x42, 0x08, 0xD0, 0x20, 0x2C,
+ 0x06, 0xD0, 0x6D, 0x1C, 0xED, 0xB2, 0x30, 0x78, 0x85, 0x42, 0xE6, 0xD3,
+ 0x00, 0x25, 0x22, 0xE0, 0x1C, 0x49, 0x01, 0x22, 0x2B, 0x46, 0x28, 0x31,
+ 0x15, 0xE0, 0x71, 0x68, 0x05, 0xEB, 0x45, 0x00, 0x01, 0xEB, 0xC0, 0x07,
+ 0x38, 0x78, 0x01, 0x28, 0x13, 0xD1, 0x06, 0x22, 0x49, 0x46, 0x07, 0xF1,
+ 0x10, 0x00, 0x17, 0xF4, 0x7D, 0xF3, 0x60, 0xB9, 0xB8, 0x7D, 0xA0, 0x42,
+ 0x09, 0xD1, 0x11, 0x49, 0x01, 0x22, 0x2B, 0x46, 0x44, 0x31, 0x40, 0x46,
+ 0xE5, 0xF7, 0xA9, 0xDA, 0x38, 0x46, 0xBD, 0xE8, 0xF8, 0x83, 0x6D, 0x1C,
+ 0xED, 0xB2, 0x30, 0x78, 0x85, 0x42, 0xDE, 0xD3, 0x49, 0x46, 0x0A, 0x48,
+ 0xE5, 0xF7, 0x6C, 0xDC, 0x03, 0x46, 0x07, 0x49, 0x04, 0x48, 0x02, 0x22,
+ 0x6C, 0x31, 0xC0, 0x1E, 0x00, 0x94, 0xE5, 0xF7, 0x94, 0xDA, 0x00, 0x20,
+ 0xE9, 0xE7, 0x00, 0x00, 0x03, 0x35, 0x10, 0x21, 0xBC, 0x78, 0x20, 0x00,
+ 0x4C, 0x6F, 0xC0, 0x08, 0x00, 0x00, 0x30, 0x21, 0x07, 0x4A, 0x01, 0x46,
+ 0x00, 0x20, 0x13, 0x78, 0x99, 0x42, 0x08, 0xD2, 0x52, 0x68, 0x01, 0xEB,
+ 0x41, 0x01, 0x12, 0xF8, 0x31, 0x30, 0x01, 0x2B, 0x01, 0xD1, 0x02, 0xEB,
+ 0xC1, 0x00, 0x70, 0x47, 0xBC, 0x78, 0x20, 0x00, 0x41, 0x88, 0x40, 0xF2,
+ 0x6F, 0x13, 0xA1, 0xF2, 0x6F, 0x12, 0x99, 0x42, 0x3A, 0xD0, 0x18, 0xDC,
+ 0x40, 0xF2, 0x3D, 0x13, 0xA1, 0xF2, 0x3D, 0x12, 0x99, 0x42, 0x3C, 0xD0,
+ 0x08, 0xDC, 0x05, 0x29, 0x24, 0xD0, 0x0C, 0x29, 0x28, 0xD0, 0x0E, 0x29,
+ 0x42, 0xD1, 0x00, 0x1D, 0xF4, 0xF7, 0xB4, 0xBB, 0x20, 0x2A, 0x3A, 0xD0,
+ 0x22, 0x2A, 0x22, 0xD0, 0x2C, 0x2A, 0x39, 0xD1, 0x00, 0x1D, 0xF4, 0xF7,
+ 0x39, 0xBC, 0x1C, 0x49, 0x0F, 0x2A, 0x09, 0x78, 0x28, 0xD0, 0x06, 0xDC,
+ 0x02, 0x2A, 0x1C, 0xD0, 0x03, 0x2A, 0x1D, 0xD0, 0x0D, 0x2A, 0x2B, 0xD1,
+ 0x23, 0xE0, 0x21, 0x2A, 0x21, 0xD0, 0x44, 0x2A, 0x07, 0xD0, 0x46, 0x2A,
+ 0x24, 0xD1, 0x00, 0x1D, 0xF4, 0xF7, 0xCC, 0xBA, 0x00, 0x1D, 0xF4, 0xF7,
+ 0x6D, 0xBA, 0x00, 0x1D, 0xF4, 0xF7, 0xFC, 0xBA, 0x00, 0x1D, 0xF4, 0xF7,
+ 0xFD, 0xBB, 0x00, 0x1D, 0xF4, 0xF7, 0x1C, 0xBB, 0x00, 0x1D, 0xF4, 0xF7,
+ 0x5B, 0xBC, 0x00, 0x1D, 0xF4, 0xF7, 0x44, 0xBB, 0x00, 0x1D, 0xF4, 0xF7,
+ 0x73, 0xBA, 0x00, 0x1D, 0xF4, 0xF7, 0x04, 0xBB, 0x00, 0x1D, 0xF4, 0xF7,
+ 0x91, 0xBA, 0xC8, 0x07, 0x04, 0xD1, 0xF4, 0xF7, 0x87, 0xBC, 0x00, 0x1D,
+ 0xF4, 0xF7, 0x4E, 0xBB, 0x70, 0x47, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00,
+ 0x38, 0xB5, 0x04, 0x46, 0xEE, 0xF7, 0xDA, 0xF8, 0x01, 0x00, 0x16, 0x48,
+ 0x09, 0xD0, 0x16, 0x4B, 0xB3, 0xF8, 0x78, 0x11, 0xCA, 0x05, 0x10, 0xD5,
+ 0x14, 0x4A, 0x95, 0x78, 0x08, 0x2D, 0x05, 0xD0, 0x0B, 0xE0, 0x00, 0x22,
+ 0x12, 0x49, 0xE5, 0xF7, 0x06, 0xDA, 0x11, 0xE0, 0x15, 0x89, 0xC1, 0xF3,
+ 0x42, 0x21, 0x45, 0xF4, 0x80, 0x75, 0x15, 0x81, 0x91, 0x70, 0x93, 0xF8,
+ 0x98, 0x11, 0xA1, 0x42, 0x08, 0xD2, 0x00, 0x91, 0x0A, 0x49, 0x23, 0x46,
+ 0x02, 0x22, 0x28, 0x31, 0xE5, 0xF7, 0xF3, 0xD9, 0x00, 0x20, 0x38, 0xBD,
+ 0x20, 0x46, 0x01, 0xF0, 0xA1, 0xF9, 0xFE, 0xF7, 0x39, 0xFA, 0x01, 0x20,
+ 0x38, 0xBD, 0x00, 0x00, 0x00, 0x35, 0x10, 0x21, 0x64, 0x01, 0x20, 0x00,
+ 0x50, 0x74, 0x20, 0x00, 0x80, 0x5D, 0xC0, 0x08, 0x01, 0x49, 0xC8, 0x70,
+ 0x70, 0x47, 0x00, 0x00, 0x50, 0x74, 0x20, 0x00, 0x01, 0x4A, 0xC2, 0xE9,
+ 0x00, 0x01, 0x70, 0x47, 0x68, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x4F,
+ 0x87, 0xB0, 0x2C, 0x4E, 0xDD, 0xE9, 0x11, 0x87, 0x1D, 0x46, 0x91, 0x46,
+ 0x8A, 0x46, 0x83, 0x46, 0x10, 0x2B, 0x06, 0xD8, 0x28, 0x49, 0x38, 0x78,
+ 0x91, 0xF8, 0xC1, 0x11, 0xB0, 0xEB, 0x81, 0x0F, 0x02, 0xD9, 0x00, 0x22,
+ 0x25, 0x49, 0x3F, 0xE0, 0x51, 0x46, 0x58, 0x46, 0xFF, 0xF7, 0xAC, 0xFE,
+ 0x04, 0x00, 0x12, 0xD1, 0x4A, 0x46, 0x51, 0x46, 0x58, 0x46, 0xFD, 0xF7,
+ 0xC9, 0xFD, 0x04, 0x00, 0x0B, 0xD1, 0x00, 0xF0, 0x37, 0xFA, 0x60, 0xB3,
+ 0xFE, 0xF7, 0x06, 0xFF, 0x4A, 0x46, 0x51, 0x46, 0x58, 0x46, 0xFD, 0xF7,
+ 0xBD, 0xFD, 0x04, 0x00, 0x23, 0xD0, 0x1C, 0x21, 0x68, 0x46, 0x17, 0xF4,
+ 0x57, 0xF3, 0x8D, 0xF8, 0x1A, 0x50, 0x8D, 0xF8, 0x1B, 0x80, 0x2A, 0x46,
+ 0x68, 0x46, 0x10, 0x99, 0x17, 0xF4, 0xAD, 0xF2, 0x6B, 0x46, 0x1C, 0x22,
+ 0x11, 0x21, 0x20, 0x46, 0x01, 0xF0, 0x0A, 0xFC, 0x78, 0xB1, 0x39, 0x46,
+ 0x20, 0x46, 0x01, 0xF0, 0xF1, 0xFB, 0x50, 0xB1, 0x6B, 0x46, 0x1C, 0x22,
+ 0x12, 0x21, 0x20, 0x46, 0x01, 0xF0, 0xFE, 0xFB, 0x18, 0xB1, 0x01, 0x20,
+ 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x06, 0x49, 0x00, 0x22, 0x30, 0x31,
+ 0x30, 0x46, 0xE5, 0xF7, 0x7C, 0xD9, 0x00, 0x20, 0xF4, 0xE7, 0x00, 0x00,
+ 0x00, 0x35, 0x10, 0x21, 0x64, 0x01, 0x20, 0x00, 0xD0, 0x72, 0xC0, 0x08,
+ 0x10, 0xB5, 0xF1, 0xF7, 0x32, 0xFC, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD,
+ 0x07, 0x20, 0x10, 0xBD, 0x01, 0x20, 0x00, 0xF0, 0x81, 0xBE, 0x00, 0x00,
+ 0x01, 0x48, 0x00, 0x78, 0x70, 0x47, 0x00, 0x00, 0xCC, 0x78, 0x20, 0x00,
+ 0x10, 0xB5, 0x0A, 0x46, 0x00, 0x28, 0x07, 0xD0, 0x81, 0x78, 0x49, 0x06,
+ 0x05, 0xD5, 0x41, 0x78, 0x10, 0x46, 0xF3, 0xF7, 0x63, 0xFD, 0x01, 0x20,
+ 0x10, 0xBD, 0x00, 0x20, 0x10, 0xBD, 0x00, 0x00, 0x30, 0xB5, 0x0D, 0x4C,
+ 0x63, 0x78, 0x5B, 0x1E, 0x98, 0x42, 0x12, 0xDC, 0x00, 0xEB, 0x40, 0x03,
+ 0x60, 0x68, 0x00, 0xEB, 0x03, 0x10, 0x05, 0x78, 0x5D, 0xB1, 0x80, 0x79,
+ 0x10, 0x70, 0x60, 0x68, 0x00, 0xEB, 0x03, 0x10, 0x50, 0xF8, 0x07, 0x2F,
+ 0x0A, 0x60, 0x80, 0x88, 0x88, 0x80, 0x01, 0x20, 0x30, 0xBD, 0x00, 0x20,
+ 0x30, 0xBD, 0x00, 0x00, 0x60, 0x78, 0x20, 0x00, 0x10, 0xB5, 0x14, 0x46,
+ 0x00, 0xF0, 0xEC, 0xFD, 0x18, 0xB1, 0xC0, 0x78, 0x20, 0x70, 0x01, 0x20,
+ 0x10, 0xBD, 0xFF, 0x20, 0x20, 0x70, 0x00, 0x20, 0x10, 0xBD, 0x10, 0xB5,
+ 0x0C, 0x46, 0x00, 0xF0, 0x17, 0xFE, 0x18, 0xB1, 0xC0, 0x78, 0x20, 0x70,
+ 0x01, 0x20, 0x10, 0xBD, 0xFF, 0x20, 0x20, 0x70, 0x00, 0x20, 0x10, 0xBD,
+ 0x10, 0xB5, 0x12, 0x4B, 0x00, 0x22, 0x0A, 0x70, 0x5A, 0x78, 0x52, 0x1E,
+ 0x90, 0x42, 0x1B, 0xDC, 0x5A, 0x68, 0x00, 0xEB, 0x40, 0x00, 0x02, 0xEB,
+ 0x00, 0x12, 0x14, 0x78, 0xA4, 0xB1, 0x52, 0x78, 0x0A, 0x70, 0x5A, 0x68,
+ 0x02, 0xEB, 0x00, 0x12, 0x92, 0x78, 0x4A, 0x70, 0x5A, 0x68, 0x02, 0xEB,
+ 0x00, 0x10, 0x82, 0x79, 0x0A, 0x72, 0xD0, 0xF8, 0x07, 0x20, 0xC1, 0xF8,
+ 0x02, 0x20, 0xB0, 0xF8, 0x0B, 0x00, 0xC8, 0x80, 0x01, 0x20, 0x10, 0xBD,
+ 0x00, 0x20, 0x10, 0xBD, 0x60, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x41,
+ 0x0C, 0x46, 0x06, 0x46, 0x17, 0x46, 0x00, 0x25, 0x11, 0x46, 0x32, 0x48,
+ 0x00, 0xF0, 0x3E, 0xFD, 0x70, 0xB1, 0xA6, 0xF5, 0x1C, 0x72, 0x30, 0x49,
+ 0x07, 0xEB, 0x47, 0x00, 0x0C, 0x2A, 0x50, 0xD2, 0xDF, 0xE8, 0x02, 0xF0,
+ 0x09, 0x12, 0x1C, 0x22, 0x27, 0x17, 0x2C, 0x32, 0x37, 0x41, 0x3C, 0x4A,
+ 0x04, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10,
+ 0x50, 0xF8, 0x07, 0x1F, 0x21, 0x60, 0x80, 0x88, 0xA0, 0x80, 0x43, 0xE0,
+ 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x80, 0x79, 0x18, 0xE0, 0x49, 0x68,
+ 0x01, 0xEB, 0x00, 0x10, 0x40, 0x8A, 0x03, 0xE0, 0x49, 0x68, 0x01, 0xEB,
+ 0x00, 0x10, 0x80, 0x8A, 0x20, 0x80, 0x33, 0xE0, 0x49, 0x68, 0x01, 0xEB,
+ 0x00, 0x10, 0xC0, 0x8A, 0xF8, 0xE7, 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10,
+ 0x00, 0x8B, 0xF3, 0xE7, 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x40, 0x79,
+ 0x20, 0x70, 0x23, 0xE0, 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x80, 0x7B,
+ 0xF8, 0xE7, 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x40, 0x7B, 0xF3, 0xE7,
+ 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10, 0xC0, 0x7B, 0xEE, 0xE7, 0x49, 0x68,
+ 0x01, 0xEB, 0x00, 0x10, 0x50, 0xF8, 0x1A, 0x1F, 0x21, 0x60, 0x40, 0x68,
+ 0x60, 0x60, 0x0B, 0xE0, 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x00, 0x8A,
+ 0xD0, 0xE7, 0x03, 0x25, 0x33, 0x46, 0x01, 0x22, 0x04, 0x49, 0x05, 0x48,
+ 0xE5, 0xF7, 0x87, 0xD8, 0x28, 0x46, 0xAE, 0xE7, 0x13, 0xB2, 0x82, 0x00,
+ 0x60, 0x78, 0x20, 0x00, 0x10, 0x60, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0x2D, 0xE9, 0xF8, 0x4F, 0x0F, 0x46, 0x05, 0x00, 0x06, 0xD0, 0x28, 0x78,
+ 0x1C, 0x4B, 0x01, 0x28, 0x05, 0xD0, 0x00, 0x22, 0x1B, 0x49, 0x0B, 0xE0,
+ 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x8F, 0x1A, 0x48, 0x69, 0x78, 0x00, 0x78,
+ 0x40, 0x1E, 0x81, 0x42, 0x06, 0xDD, 0x16, 0x49, 0x00, 0x22, 0x28, 0x39,
+ 0x18, 0x46, 0xE5, 0xF7, 0x62, 0xD8, 0xEF, 0xE7, 0xDF, 0xF8, 0x50, 0x80,
+ 0x38, 0x46, 0xB8, 0xF8, 0x00, 0x10, 0x8E, 0x08, 0x17, 0xF4, 0xEC, 0xF1,
+ 0x00, 0x24, 0xDF, 0xF8, 0x44, 0x90, 0xDF, 0xF8, 0x44, 0xA0, 0x11, 0xE0,
+ 0x68, 0x78, 0x00, 0x90, 0xB9, 0xF8, 0x00, 0x10, 0xBA, 0xF8, 0x00, 0x00,
+ 0x04, 0x23, 0x08, 0x44, 0x00, 0xEB, 0x84, 0x00, 0x81, 0xB2, 0x07, 0xEB,
+ 0x84, 0x00, 0xB8, 0xF8, 0x00, 0x20, 0xFA, 0xF7, 0xFD, 0xFE, 0x64, 0x1C,
+ 0xB4, 0x42, 0xEB, 0xDB, 0x01, 0x20, 0xCC, 0xE7, 0x00, 0x35, 0x10, 0x21,
+ 0x5C, 0x74, 0xC0, 0x08, 0xBC, 0x78, 0x20, 0x00, 0xEE, 0x78, 0x20, 0x00,
+ 0xF0, 0x78, 0x20, 0x00, 0xE0, 0x78, 0x20, 0x00, 0x01, 0x48, 0x00, 0x88,
+ 0x70, 0x47, 0x00, 0x00, 0xEE, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x03, 0x46,
+ 0xA0, 0xF5, 0x08, 0x75, 0x00, 0x24, 0x1E, 0x48, 0x1E, 0x4A, 0x17, 0x2D,
+ 0x30, 0xD2, 0xDF, 0xE8, 0x05, 0xF0, 0x0C, 0x0E, 0x2F, 0x2F, 0x1D, 0x2F,
+ 0x15, 0x1A, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x22, 0x10,
+ 0x13, 0x27, 0x29, 0x2B, 0x2D, 0x00, 0x00, 0x78, 0x0C, 0xE0, 0x40, 0x89,
+ 0x00, 0xE0, 0x80, 0x89, 0x08, 0x80, 0x21, 0xE0, 0xC0, 0x89, 0xFB, 0xE7,
+ 0xD0, 0xF8, 0x1A, 0x20, 0x0A, 0x60, 0xC0, 0x8B, 0x05, 0xE0, 0x80, 0x78,
+ 0x08, 0x70, 0x17, 0xE0, 0x42, 0x69, 0x0A, 0x60, 0x00, 0x8B, 0x88, 0x80,
+ 0x12, 0xE0, 0x02, 0x6A, 0x0A, 0x60, 0x40, 0x6A, 0x48, 0x60, 0x0D, 0xE0,
+ 0x09, 0x48, 0xE2, 0xE7, 0x40, 0x79, 0xEF, 0xE7, 0x10, 0x78, 0xED, 0xE7,
+ 0x50, 0x78, 0xEB, 0xE7, 0x03, 0x24, 0x01, 0x22, 0x05, 0x49, 0x06, 0x48,
+ 0xE4, 0xF7, 0xEB, 0xDF, 0x20, 0x46, 0x70, 0xBD, 0x38, 0x78, 0x20, 0x00,
+ 0x50, 0x74, 0x20, 0x00, 0x60, 0x78, 0x20, 0x00, 0x08, 0x5E, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x01, 0x20, 0xEC, 0xF7, 0x66, 0xFB,
+ 0x06, 0x49, 0x0A, 0x78, 0x90, 0x42, 0x07, 0xD2, 0x49, 0x68, 0x00, 0xEB,
+ 0x40, 0x00, 0x01, 0xEB, 0xC0, 0x00, 0x01, 0x78, 0x00, 0x29, 0x00, 0xD1,
+ 0x00, 0x20, 0x10, 0xBD, 0xBC, 0x78, 0x20, 0x00, 0x00, 0x20, 0x00, 0xF0,
+ 0xE1, 0xBC, 0x00, 0x00, 0xF0, 0xB5, 0x05, 0x46, 0x0E, 0x46, 0xA1, 0xF1,
+ 0x11, 0x00, 0x00, 0x24, 0x69, 0x78, 0x89, 0xB0, 0x17, 0x46, 0x06, 0x28,
+ 0x33, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x03, 0x0A, 0x32, 0x1C, 0x23, 0x2A,
+ 0xA8, 0x78, 0x80, 0x07, 0x2B, 0xD5, 0x68, 0x46, 0xF3, 0xF7, 0x26, 0xFC,
+ 0x05, 0xE0, 0xA8, 0x78, 0x40, 0x07, 0x24, 0xD5, 0x68, 0x46, 0xF3, 0xF7,
+ 0xC9, 0xFC, 0x00, 0xBB, 0x9D, 0xF8, 0x00, 0x20, 0x1C, 0x2A, 0x1C, 0xD8,
+ 0x38, 0x46, 0x01, 0xA9, 0x17, 0xF4, 0xB5, 0xF0, 0x9D, 0xF8, 0x00, 0x40,
+ 0x15, 0xE0, 0xA8, 0x78, 0x00, 0x07, 0x12, 0xD5, 0x38, 0x46, 0xF3, 0xF7,
+ 0x8B, 0xFC, 0x0C, 0xE0, 0xA8, 0x78, 0xC0, 0x06, 0x0B, 0xD5, 0x38, 0x46,
+ 0xF3, 0xF7, 0xDA, 0xFB, 0x05, 0xE0, 0xA8, 0x78, 0x80, 0x06, 0x04, 0xD5,
+ 0x38, 0x46, 0xF3, 0xF7, 0x51, 0xFC, 0x00, 0xB9, 0x18, 0x24, 0xCD, 0xE9,
+ 0x00, 0x64, 0x6B, 0x78, 0x03, 0x22, 0x03, 0x49, 0x03, 0x48, 0xE4, 0xF7,
+ 0x80, 0xDF, 0x09, 0xB0, 0x20, 0x46, 0xF0, 0xBD, 0x34, 0x70, 0xC0, 0x08,
+ 0x03, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x01, 0x20, 0xEC, 0xF7, 0x2C, 0xFB,
+ 0x05, 0x49, 0x0A, 0x78, 0x90, 0x42, 0x05, 0xD2, 0x49, 0x68, 0x00, 0xEB,
+ 0x40, 0x00, 0x01, 0xEB, 0xC0, 0x00, 0x10, 0xBD, 0x00, 0x20, 0x10, 0xBD,
+ 0xBC, 0x78, 0x20, 0x00, 0x01, 0x48, 0x90, 0xF8, 0x98, 0x01, 0x70, 0x47,
+ 0x64, 0x01, 0x20, 0x00, 0x1C, 0xB5, 0x10, 0xB3, 0x02, 0x78, 0x01, 0x2A,
+ 0x1F, 0xD1, 0xC2, 0x7B, 0x4F, 0xF0, 0x00, 0x03, 0xD4, 0x06, 0x4F, 0xF0,
+ 0x01, 0x02, 0x01, 0xD5, 0x0A, 0x70, 0x00, 0xE0, 0x0B, 0x70, 0xC4, 0x7B,
+ 0xA4, 0x06, 0x01, 0xD5, 0x4A, 0x70, 0x00, 0xE0, 0x4B, 0x70, 0xC0, 0x7B,
+ 0x40, 0x06, 0x01, 0xD5, 0x8A, 0x70, 0x00, 0xE0, 0x8B, 0x70, 0x8A, 0x78,
+ 0x48, 0x78, 0xCD, 0xE9, 0x00, 0x02, 0x0B, 0x78, 0x03, 0x22, 0x03, 0x49,
+ 0x03, 0x48, 0xE4, 0xF7, 0x3C, 0xDF, 0x00, 0x20, 0x1C, 0xBD, 0x00, 0x00,
+ 0x78, 0x73, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x42, 0x88,
+ 0x04, 0x46, 0x01, 0x25, 0x40, 0xF2, 0x4D, 0x10, 0xA2, 0xF2, 0x4D, 0x11,
+ 0x82, 0x42, 0x7A, 0xD0, 0x56, 0xDC, 0x40, 0xF2, 0x1B, 0x11, 0xA2, 0xF2,
+ 0x1B, 0x10, 0x8A, 0x42, 0x74, 0xD0, 0x33, 0xDC, 0xB2, 0xF5, 0x80, 0x7F,
+ 0x11, 0xD0, 0x1E, 0xDC, 0x17, 0x2A, 0x0E, 0xD0, 0x0E, 0xDC, 0x0E, 0x2A,
+ 0x06, 0xD0, 0x06, 0xDC, 0x05, 0x2A, 0x03, 0xD0, 0x08, 0x2A, 0x06, 0xD0,
+ 0x0C, 0x2A, 0x7D, 0xD1, 0xA1, 0xE0, 0x12, 0x2A, 0x01, 0xD0, 0x15, 0x2A,
+ 0x78, 0xD1, 0xB9, 0xE0, 0x1E, 0x2A, 0x04, 0xD0, 0x04, 0xDC, 0x19, 0x2A,
+ 0x01, 0xD0, 0x1B, 0x2A, 0x70, 0xD1, 0xB1, 0xE0, 0x1F, 0x2A, 0x6E, 0xD0,
+ 0x24, 0x2A, 0x6B, 0xD1, 0xA4, 0xE0, 0xA2, 0xF2, 0x03, 0x12, 0x15, 0x2A,
+ 0x66, 0xD2, 0xDF, 0xE8, 0x02, 0xF0, 0xAF, 0xCF, 0xAF, 0xAF, 0xCF, 0xAF,
+ 0xCF, 0xAF, 0xCF, 0xAF, 0xCF, 0xAF, 0xCF, 0xAF, 0xAF, 0xCF, 0xB3, 0xB3,
+ 0xCF, 0xCF, 0xB3, 0x00, 0x80, 0x1E, 0x2E, 0x28, 0x56, 0xD2, 0xDF, 0xE8,
+ 0x00, 0xF0, 0xA3, 0xBF, 0xA3, 0xA3, 0xBF, 0xA3, 0xBF, 0x97, 0x97, 0xBF,
+ 0x8F, 0xBF, 0x8F, 0x8F, 0xBF, 0x9B, 0xBF, 0x93, 0x93, 0xBF, 0xBF, 0x85,
+ 0xBF, 0x85, 0xBF, 0x85, 0xBF, 0x8B, 0xBF, 0x8B, 0x8B, 0xBF, 0x7A, 0xBF,
+ 0x8F, 0x8F, 0xBF, 0x8F, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xB8, 0xB8,
+ 0x34, 0x29, 0x71, 0xD0, 0x30, 0xDC, 0x18, 0x29, 0x6D, 0xD0, 0x0F, 0xDC,
+ 0x17, 0x29, 0x35, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, 0x9E, 0x97, 0x9E, 0x9E,
+ 0x97, 0x9E, 0x97, 0x97, 0x9E, 0x97, 0x97, 0x9E, 0x97, 0x9E, 0x97, 0x9E,
+ 0x59, 0x9E, 0x59, 0x9E, 0x9B, 0x9E, 0x9B, 0x00, 0x29, 0x29, 0x51, 0xD0,
+ 0x10, 0xDC, 0x24, 0x29, 0x47, 0xD0, 0x08, 0xDC, 0x1A, 0x29, 0x4F, 0xD0,
+ 0x1C, 0x29, 0x42, 0xD0, 0x22, 0x29, 0x1B, 0xD1, 0x3F, 0xE0, 0x7C, 0xE0,
+ 0x66, 0xE0, 0x25, 0x29, 0x3B, 0xD0, 0x27, 0x29, 0x7E, 0xD1, 0x3F, 0xE0,
+ 0x2B, 0x39, 0x09, 0x29, 0x7A, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, 0x3B, 0x79,
+ 0x3B, 0x79, 0x38, 0x79, 0x34, 0x79, 0x3B, 0x00, 0x5E, 0x29, 0x41, 0xD0,
+ 0x1E, 0xDC, 0x41, 0x29, 0x57, 0xD0, 0x0E, 0xDC, 0xA1, 0xF1, 0x35, 0x01,
+ 0x0B, 0x29, 0x01, 0xE0, 0x26, 0xE0, 0x3F, 0xE0, 0x66, 0xD2, 0xDF, 0xE8,
+ 0x01, 0xF0, 0x56, 0x65, 0x52, 0x65, 0x52, 0x65, 0x52, 0x65, 0x52, 0x65,
+ 0x4E, 0x00, 0x47, 0x29, 0x59, 0xD0, 0x04, 0xDC, 0x43, 0x29, 0x14, 0xD0,
+ 0x45, 0x29, 0x57, 0xD1, 0x26, 0xE0, 0x49, 0x29, 0x51, 0xD0, 0x51, 0x29,
+ 0x52, 0xD1, 0x3E, 0xE0, 0x5F, 0x39, 0x10, 0x29, 0x4E, 0xD2, 0xDF, 0xE8,
+ 0x01, 0xF0, 0x36, 0x4D, 0x4D, 0x4D, 0x36, 0x3A, 0x3A, 0x0C, 0x4D, 0x42,
+ 0x1D, 0x2D, 0x25, 0x25, 0x4D, 0x25, 0x20, 0x46, 0xFF, 0xF7, 0xF6, 0xFB,
+ 0x40, 0xE0, 0x20, 0x46, 0xFF, 0xF7, 0xF2, 0xFB, 0x20, 0x46, 0x00, 0xF0,
+ 0xA5, 0xFE, 0x39, 0xE0, 0x20, 0x46, 0xFD, 0xF7, 0x9B, 0xF8, 0x35, 0xE0,
+ 0x00, 0xE0, 0x30, 0xE0, 0x20, 0x46, 0x01, 0xF0, 0xBB, 0xF9, 0x2F, 0xE0,
+ 0x20, 0x46, 0x00, 0xF0, 0x99, 0xFB, 0x2B, 0xE0, 0x20, 0x46, 0xF2, 0xF7,
+ 0x05, 0xFB, 0xF7, 0xE7, 0x20, 0x46, 0xFD, 0xF7, 0xB1, 0xFC, 0x23, 0xE0,
+ 0x20, 0x46, 0x00, 0xF0, 0x8D, 0xFB, 0xF7, 0xE7, 0x20, 0x46, 0x01, 0xF0,
+ 0x4F, 0xFF, 0x02, 0xE0, 0x20, 0x46, 0xF2, 0xF7, 0xF5, 0xFA, 0x05, 0x46,
+ 0x16, 0xE0, 0x20, 0x46, 0xFF, 0xF7, 0xEA, 0xF9, 0x12, 0xE0, 0x20, 0x46,
+ 0xFE, 0xF7, 0x5E, 0xFE, 0x0E, 0xE0, 0x20, 0x46, 0xFD, 0xF7, 0x70, 0xF8,
+ 0xF7, 0xE7, 0x20, 0x46, 0xFF, 0xF7, 0xBC, 0xFB, 0xF3, 0xE7, 0x20, 0x46,
+ 0x00, 0xF0, 0x06, 0xF8, 0x02, 0xE0, 0x20, 0x46, 0xFE, 0xF7, 0x56, 0xFC,
+ 0x28, 0x46, 0x70, 0xBD, 0x38, 0xB5, 0x1F, 0x4A, 0x43, 0x88, 0x01, 0x24,
+ 0x01, 0x1D, 0x52, 0x68, 0xA3, 0xF2, 0x49, 0x13, 0x13, 0x2B, 0x32, 0xD2,
+ 0xDF, 0xE8, 0x03, 0xF0, 0x0A, 0x0E, 0x31, 0x31, 0x12, 0x16, 0x31, 0x31,
+ 0x32, 0x31, 0x1E, 0x1A, 0x31, 0x22, 0x32, 0x31, 0x26, 0x31, 0x2B, 0x00,
+ 0x00, 0x1D, 0x00, 0xF0, 0x97, 0xF8, 0x23, 0xE0, 0x00, 0x1D, 0x00, 0xF0,
+ 0x5B, 0xF8, 0x1F, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x2B, 0xF9, 0x1B, 0xE0,
+ 0x00, 0x1D, 0x00, 0xF0, 0x05, 0xF9, 0x17, 0xE0, 0x00, 0x1D, 0x00, 0xF0,
+ 0x9F, 0xF8, 0x13, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0xCF, 0xF8, 0x0F, 0xE0,
+ 0x00, 0x1D, 0x00, 0xF0, 0x11, 0xF8, 0x0B, 0xE0, 0x52, 0xB1, 0x00, 0x91,
+ 0x69, 0x46, 0x03, 0x20, 0x03, 0xE0, 0x2A, 0xB1, 0x00, 0x91, 0x69, 0x46,
+ 0x02, 0x20, 0x90, 0x47, 0x00, 0xE0, 0x00, 0x24, 0x20, 0x46, 0x38, 0xBD,
+ 0x70, 0x79, 0x20, 0x00, 0x70, 0xB5, 0x04, 0x46, 0x81, 0x88, 0x40, 0x88,
+ 0xFE, 0xF7, 0xBC, 0xF8, 0x68, 0xB1, 0x45, 0x78, 0x21, 0x88, 0x89, 0xB1,
+ 0x00, 0x26, 0xFE, 0xF7, 0xDD, 0xF8, 0x23, 0x88, 0xA1, 0x88, 0x32, 0x46,
+ 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xFE, 0xF7, 0x8D, 0xB9, 0xBD, 0xE8,
+ 0x70, 0x40, 0x00, 0x22, 0x0B, 0x49, 0x0C, 0x48, 0xE4, 0xF7, 0xCB, 0x9D,
+ 0x21, 0x89, 0x41, 0x82, 0xE1, 0x88, 0x0A, 0x4A, 0x01, 0x82, 0xE1, 0x88,
+ 0x92, 0x88, 0x91, 0x42, 0x00, 0xD3, 0x11, 0x46, 0x01, 0x81, 0x61, 0x89,
+ 0x81, 0x82, 0x02, 0x21, 0x81, 0x70, 0x61, 0x89, 0x81, 0x81, 0x02, 0x26,
+ 0xDD, 0xE7, 0x00, 0x00, 0xB8, 0x88, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0xB6, 0x74, 0x20, 0x00, 0x7C, 0xB5, 0x04, 0x46, 0x41, 0x88, 0x00, 0x25,
+ 0x00, 0x88, 0xFE, 0xF7, 0x85, 0xF8, 0x20, 0xB1, 0x00, 0x22, 0x14, 0x49,
+ 0x14, 0x48, 0xE4, 0xF7, 0xA4, 0xDD, 0xFE, 0xF7, 0x3B, 0xF9, 0xF0, 0xB1,
+ 0x20, 0x88, 0x00, 0xF0, 0x93, 0xFA, 0x78, 0xB1, 0x61, 0x88, 0xC0, 0x78,
+ 0xFE, 0xF7, 0x00, 0xF8, 0x00, 0x28, 0x13, 0xD0, 0x01, 0x21, 0x81, 0x70,
+ 0x21, 0x88, 0x81, 0x80, 0x61, 0x88, 0x40, 0x78, 0x00, 0x23, 0x01, 0x22,
+ 0xFE, 0xF7, 0x48, 0xF9, 0x08, 0x4A, 0x10, 0x78, 0xCD, 0xE9, 0x00, 0x05,
+ 0x93, 0x78, 0x61, 0x88, 0x20, 0x88, 0x92, 0x88, 0xF0, 0xF7, 0x76, 0xFC,
+ 0x7C, 0xBD, 0x4F, 0xF4, 0x01, 0x75, 0xF1, 0xE7, 0x84, 0x88, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0xB6, 0x74, 0x20, 0x00, 0x70, 0xB5, 0x04, 0x46,
+ 0x00, 0x88, 0x00, 0x21, 0xFE, 0xF7, 0x4E, 0xF8, 0x00, 0x28, 0x0E, 0xD0,
+ 0xA1, 0x88, 0x51, 0xB1, 0x45, 0x78, 0xFE, 0xF7, 0x6F, 0xF8, 0xA3, 0x88,
+ 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x22, 0x11, 0x46, 0xFE, 0xF7,
+ 0x1F, 0xB9, 0x61, 0x88, 0xC1, 0x80, 0x70, 0xBD, 0x1F, 0xB5, 0x04, 0x46,
+ 0x41, 0x88, 0x00, 0x88, 0xFE, 0xF7, 0x36, 0xF8, 0xE8, 0xB1, 0x13, 0x49,
+ 0x4A, 0x68, 0x92, 0xB1, 0x61, 0x88, 0xAD, 0xF8, 0x02, 0x10, 0x40, 0x78,
+ 0x8D, 0xF8, 0x00, 0x00, 0xA0, 0x88, 0xAD, 0xF8, 0x04, 0x00, 0xE1, 0x88,
+ 0x04, 0xF1, 0x08, 0x00, 0x08, 0x44, 0x02, 0x90, 0xCD, 0xF8, 0x0C, 0xD0,
+ 0x03, 0xA9, 0x05, 0x20, 0x90, 0x47, 0x61, 0x88, 0x20, 0x88, 0x04, 0xB0,
+ 0x00, 0x22, 0xBD, 0xE8, 0x10, 0x40, 0xF0, 0xF7, 0x8B, 0xBC, 0x04, 0xB0,
+ 0x00, 0x22, 0xBD, 0xE8, 0x10, 0x40, 0x03, 0x49, 0x03, 0x48, 0xE4, 0xF7,
+ 0x34, 0x9D, 0x00, 0x00, 0x70, 0x79, 0x20, 0x00, 0x6C, 0x89, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x3E, 0xB5, 0x04, 0x46, 0x41, 0x88, 0x00, 0x88,
+ 0xFE, 0xF7, 0x02, 0xF8, 0xC0, 0xB1, 0x81, 0x89, 0x49, 0x1C, 0x81, 0x81,
+ 0x0E, 0x49, 0x4A, 0x68, 0x00, 0x2A, 0x10, 0xD0, 0x61, 0x88, 0xAD, 0xF8,
+ 0x02, 0x10, 0x41, 0x78, 0x8D, 0xF8, 0x00, 0x10, 0xA1, 0x88, 0xAD, 0xF8,
+ 0x04, 0x10, 0x00, 0x7B, 0x8D, 0xF8, 0x06, 0x00, 0xCD, 0xF8, 0x08, 0xD0,
+ 0x02, 0xA9, 0x04, 0x20, 0x90, 0x47, 0x3E, 0xBD, 0x03, 0xB0, 0x00, 0x22,
+ 0xBD, 0xE8, 0x30, 0x40, 0x02, 0x49, 0x03, 0x48, 0xE4, 0xF7, 0x05, 0x9D,
+ 0x70, 0x79, 0x20, 0x00, 0xA4, 0x89, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0x70, 0xB5, 0x04, 0x46, 0x41, 0x88, 0x00, 0x88, 0xFD, 0xF7, 0xD4, 0xFF,
+ 0x70, 0xB1, 0x45, 0x78, 0xFD, 0xF7, 0xF8, 0xFF, 0x61, 0x88, 0x20, 0x88,
+ 0xF0, 0xF7, 0x72, 0xFC, 0xA3, 0x88, 0x61, 0x88, 0x28, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0x00, 0x22, 0xFE, 0xF7, 0xA4, 0xB8, 0xBD, 0xE8, 0x70, 0x40,
+ 0x00, 0x22, 0x02, 0x49, 0x02, 0x48, 0xE4, 0xF7, 0xE2, 0x9C, 0x00, 0x00,
+ 0x30, 0x89, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x04, 0x46,
+ 0x41, 0x88, 0x00, 0x88, 0xFD, 0xF7, 0xB2, 0xFF, 0x68, 0xB1, 0xA1, 0x88,
+ 0x00, 0x29, 0x11, 0xD1, 0x45, 0x78, 0xFD, 0xF7, 0xD3, 0xFF, 0xA3, 0x88,
+ 0x61, 0x88, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x22, 0xFE, 0xF7,
+ 0x83, 0xB8, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x22, 0x02, 0x49, 0x03, 0x48,
+ 0xE4, 0xF7, 0xC1, 0x9C, 0x70, 0xBD, 0x00, 0x00, 0xF4, 0x88, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x30, 0xB5, 0xA7, 0xB0, 0x04, 0x00, 0x07, 0xD0,
+ 0x04, 0xF1, 0x08, 0x00, 0x61, 0x78, 0x05, 0x46, 0xF3, 0xF7, 0x52, 0xF9,
+ 0x18, 0xB1, 0x14, 0xE0, 0x00, 0x20, 0x27, 0xB0, 0x30, 0xBD, 0xE0, 0x7B,
+ 0xC1, 0x07, 0x0E, 0xD0, 0x01, 0x21, 0x21, 0x70, 0x62, 0x88, 0x83, 0x07,
+ 0x42, 0xF0, 0x01, 0x02, 0x62, 0x80, 0x02, 0xD5, 0x42, 0xF0, 0x80, 0x02,
+ 0x62, 0x80, 0x40, 0x07, 0x04, 0xD5, 0x21, 0x71, 0x02, 0xE0, 0x20, 0x78,
+ 0x01, 0x28, 0x5C, 0xD1, 0x61, 0x78, 0x0A, 0xA8, 0xF3, 0xF7, 0x08, 0xF9,
+ 0x30, 0xB9, 0x9D, 0xF8, 0x28, 0x00, 0x18, 0xB1, 0x60, 0x88, 0x40, 0xF0,
+ 0x02, 0x00, 0x60, 0x80, 0x61, 0x78, 0x12, 0xA8, 0xF3, 0xF7, 0xA6, 0xF9,
+ 0x30, 0xB9, 0x9D, 0xF8, 0x48, 0x00, 0x18, 0xB1, 0x60, 0x88, 0x40, 0xF0,
+ 0x04, 0x00, 0x60, 0x80, 0x61, 0x78, 0x04, 0xA8, 0xF3, 0xF7, 0x6E, 0xF9,
+ 0x70, 0xB9, 0x9D, 0xF8, 0x27, 0x00, 0x58, 0xB1, 0x08, 0x98, 0x20, 0x61,
+ 0xBD, 0xF8, 0x24, 0x00, 0xA0, 0x82, 0x9D, 0xF8, 0x26, 0x00, 0xA0, 0x75,
+ 0x60, 0x88, 0x40, 0xF0, 0x08, 0x00, 0x60, 0x80, 0x61, 0x78, 0x1A, 0xA8,
+ 0xF3, 0xF7, 0xB0, 0xF8, 0x30, 0xB9, 0x9D, 0xF8, 0x7D, 0x00, 0x18, 0xB1,
+ 0x60, 0x88, 0x40, 0xF0, 0x10, 0x00, 0x60, 0x80, 0x61, 0x78, 0x20, 0xA8,
+ 0xF3, 0xF7, 0x22, 0xF9, 0x30, 0xB9, 0x9D, 0xF8, 0x95, 0x00, 0x18, 0xB1,
+ 0x60, 0x88, 0x40, 0xF0, 0x20, 0x00, 0x60, 0x80, 0x60, 0x78, 0xF3, 0xF7,
+ 0xD7, 0xF9, 0x18, 0xB1, 0x60, 0x88, 0x40, 0xF0, 0x40, 0x00, 0x60, 0x80,
+ 0x29, 0x46, 0x09, 0x48, 0xE4, 0xF7, 0x16, 0xDE, 0x22, 0x79, 0x61, 0x88,
+ 0xA3, 0x7B, 0xCD, 0xE9, 0x02, 0x12, 0xCD, 0xE9, 0x00, 0x03, 0x63, 0x78,
+ 0x05, 0x22, 0x04, 0x49, 0x04, 0x48, 0xE4, 0xF7, 0x3A, 0xDC, 0x01, 0x20,
+ 0x89, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0xF0, 0x6E, 0xC0, 0x08,
+ 0x02, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x13, 0x48, 0x13, 0x4D, 0x7D, 0x23,
+ 0x90, 0xF8, 0xCB, 0x01, 0x28, 0x70, 0x00, 0xEB, 0x40, 0x00, 0xC1, 0x00,
+ 0x10, 0x4A, 0x00, 0x20, 0xEF, 0xF7, 0xB8, 0xD9, 0x68, 0x60, 0x00, 0x28,
+ 0x14, 0xD0, 0xF2, 0xF7, 0xC1, 0xFF, 0x29, 0x78, 0x01, 0x20, 0xEC, 0xF7,
+ 0xBF, 0xF8, 0x00, 0x24, 0x09, 0xE0, 0x69, 0x68, 0x04, 0xEB, 0x44, 0x00,
+ 0x01, 0xEB, 0xC0, 0x00, 0x44, 0x70, 0xFF, 0xF7, 0x55, 0xFF, 0x64, 0x1C,
+ 0xE4, 0xB2, 0x28, 0x78, 0x84, 0x42, 0xF2, 0xD3, 0x70, 0xBD, 0x00, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0xBC, 0x78, 0x20, 0x00, 0xD2, 0xB3, 0x82, 0x00,
+ 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, 0x01, 0x46, 0x26, 0x48, 0xE4, 0xF7,
+ 0xCB, 0xDD, 0x03, 0x46, 0x01, 0x22, 0x25, 0x49, 0x25, 0x48, 0xE4, 0xF7,
+ 0xF6, 0xDB, 0xDF, 0xF8, 0x90, 0x80, 0x00, 0x24, 0xA8, 0xF1, 0x03, 0x08,
+ 0x22, 0x4E, 0x0E, 0xE0, 0x71, 0x68, 0x04, 0xEB, 0x44, 0x00, 0x01, 0xEB,
+ 0x00, 0x17, 0x38, 0x78, 0x28, 0xB1, 0x06, 0x22, 0x29, 0x46, 0xF8, 0x1D,
+ 0x16, 0xF4, 0xAC, 0xF4, 0x38, 0xB1, 0x64, 0x1C, 0xE4, 0xB2, 0x71, 0x78,
+ 0x8C, 0x42, 0xED, 0xD3, 0x00, 0x20, 0x73, 0x68, 0x11, 0xE0, 0x15, 0x49,
+ 0xFB, 0x78, 0x01, 0x22, 0x20, 0x31, 0x40, 0x46, 0xE4, 0xF7, 0xD3, 0xDB,
+ 0x38, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0xEB, 0x40, 0x02, 0x03, 0xEB,
+ 0x02, 0x12, 0x14, 0x78, 0x5C, 0xB1, 0x40, 0x1C, 0xC0, 0xB2, 0x88, 0x42,
+ 0xF5, 0xD3, 0x0B, 0x49, 0x00, 0x22, 0x48, 0x31, 0x40, 0x46, 0xE4, 0xF7,
+ 0xC0, 0xDB, 0x00, 0x20, 0xEB, 0xE7, 0x29, 0x68, 0xC2, 0xF8, 0x07, 0x10,
+ 0xA9, 0x88, 0xA2, 0xF8, 0x0B, 0x10, 0x01, 0x21, 0x11, 0x70, 0xD0, 0x70,
+ 0x00, 0x20, 0x50, 0x70, 0x10, 0x46, 0xDE, 0xE7, 0x00, 0x00, 0x30, 0x21,
+ 0xC8, 0x5E, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x60, 0x78, 0x20, 0x00,
+ 0x7C, 0xB5, 0x0E, 0x46, 0x01, 0x46, 0x0E, 0x48, 0x01, 0x25, 0x05, 0x24,
+ 0x42, 0x78, 0x96, 0x42, 0x07, 0xD2, 0x40, 0x68, 0x06, 0xEB, 0x46, 0x02,
+ 0x00, 0xEB, 0x02, 0x10, 0x44, 0x78, 0x02, 0x2C, 0x0C, 0xD0, 0x00, 0x25,
+ 0x4F, 0xF0, 0x05, 0x50, 0xE4, 0xF7, 0xAD, 0xDD, 0xCD, 0xE9, 0x00, 0x64,
+ 0x03, 0x46, 0x03, 0x22, 0x03, 0x49, 0x04, 0x48, 0xE4, 0xF7, 0x8B, 0xDB,
+ 0x28, 0x46, 0x7C, 0xBD, 0x60, 0x78, 0x20, 0x00, 0xDC, 0x5F, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x0D, 0x46, 0x00, 0xF0, 0x74, 0xF8,
+ 0x04, 0x00, 0x28, 0xD0, 0x18, 0x48, 0x01, 0x22, 0x18, 0x49, 0x03, 0x78,
+ 0x18, 0x48, 0xE4, 0xF7, 0x76, 0xDB, 0x18, 0x49, 0x01, 0x22, 0x08, 0x78,
+ 0xB2, 0xEB, 0x90, 0x1F, 0x0A, 0xD1, 0x62, 0x78, 0x03, 0x2A, 0x07, 0xD1,
+ 0xA2, 0x78, 0x01, 0x2A, 0x04, 0xD1, 0x22, 0x8A, 0x12, 0xB9, 0x20, 0xF0,
+ 0xC0, 0x00, 0x08, 0x70, 0xE0, 0x78, 0x2A, 0x46, 0x00, 0x21, 0xF3, 0xF7,
+ 0xC5, 0xFE, 0x00, 0x20, 0xF3, 0xF7, 0xE6, 0xFE, 0xE0, 0x6A, 0x08, 0xB1,
+ 0xEF, 0xF7, 0x4D, 0xD9, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0,
+ 0x43, 0xBB, 0x05, 0x49, 0xBD, 0xE8, 0x70, 0x40, 0x04, 0x48, 0x00, 0x22,
+ 0x2C, 0x31, 0xC0, 0x1E, 0xE4, 0xF7, 0x4B, 0x9B, 0x60, 0x78, 0x20, 0x00,
+ 0xE4, 0x61, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x38, 0x78, 0x20, 0x00,
+ 0x2D, 0xE9, 0xF8, 0x43, 0x0E, 0x46, 0xB0, 0xF1, 0x00, 0x08, 0x25, 0xD0,
+ 0x00, 0x24, 0x14, 0x4F, 0x13, 0xE0, 0x79, 0x68, 0x04, 0xEB, 0x44, 0x00,
+ 0x01, 0xEB, 0x00, 0x15, 0x28, 0x78, 0x50, 0xB1, 0x06, 0x22, 0x41, 0x46,
+ 0xE8, 0x1D, 0x16, 0xF4, 0xF7, 0xF3, 0x20, 0xB9, 0xA8, 0x79, 0xB0, 0x42,
+ 0x14, 0xD0, 0x20, 0x2E, 0x12, 0xD0, 0x64, 0x1C, 0xE4, 0xB2, 0x78, 0x78,
+ 0x84, 0x42, 0xE8, 0xD3, 0x41, 0x46, 0x08, 0x48, 0xE4, 0xF7, 0xEE, 0xDC,
+ 0x03, 0x46, 0x02, 0x22, 0x06, 0x49, 0x07, 0x48, 0x00, 0x96, 0xE4, 0xF7,
+ 0x18, 0xDB, 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x83, 0x28, 0x46, 0xFB, 0xE7,
+ 0x60, 0x78, 0x20, 0x00, 0x00, 0x00, 0x30, 0x21, 0x80, 0x5F, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x0E, 0x49, 0x03, 0x46, 0x00, 0x20,
+ 0x4C, 0x78, 0x4A, 0x68, 0x0C, 0xE0, 0x00, 0xEB, 0x40, 0x01, 0x02, 0xEB,
+ 0x01, 0x11, 0x0D, 0x78, 0x25, 0xB1, 0x0D, 0x8A, 0x9D, 0x42, 0x01, 0xD1,
+ 0x08, 0x46, 0x70, 0xBD, 0x40, 0x1C, 0xC0, 0xB2, 0xA0, 0x42, 0xF0, 0xD3,
+ 0x01, 0x22, 0x04, 0x49, 0x04, 0x48, 0xE4, 0xF7, 0xF0, 0xDA, 0x00, 0x20,
+ 0x70, 0xBD, 0x00, 0x00, 0x60, 0x78, 0x20, 0x00, 0x48, 0x5F, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x10, 0x4D, 0x00, 0x24, 0x06, 0x46,
+ 0x21, 0x46, 0x6A, 0x78, 0x6B, 0x68, 0x09, 0xE0, 0x01, 0xEB, 0x41, 0x00,
+ 0x03, 0xEB, 0x00, 0x10, 0x00, 0x78, 0x08, 0xB1, 0x64, 0x1C, 0xE4, 0xB2,
+ 0x49, 0x1C, 0xC9, 0xB2, 0x91, 0x42, 0xF3, 0xD3, 0x23, 0x46, 0x01, 0x22,
+ 0x06, 0x49, 0x07, 0x48, 0xE4, 0xF7, 0xCD, 0xDA, 0x0E, 0xB1, 0x20, 0x46,
+ 0x70, 0xBD, 0x68, 0x78, 0x00, 0x1B, 0xC0, 0xB2, 0x70, 0xBD, 0x00, 0x00,
+ 0x60, 0x78, 0x20, 0x00, 0xC0, 0x5F, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21,
+ 0x41, 0x88, 0x40, 0xF2, 0x2F, 0x13, 0xA1, 0xF2, 0x2F, 0x12, 0x99, 0x42,
+ 0x34, 0xD0, 0x17, 0xDC, 0xB1, 0xF5, 0x95, 0x7F, 0x27, 0xD0, 0x0A, 0xDC,
+ 0x24, 0x29, 0x3C, 0xD0, 0xA1, 0xF5, 0x80, 0x71, 0x27, 0x39, 0x2C, 0xD0,
+ 0x02, 0x29, 0x39, 0xD1, 0x00, 0x1D, 0x00, 0xF0, 0xA9, 0xB8, 0xB1, 0xF5,
+ 0x96, 0x7F, 0x1E, 0xD0, 0xB1, 0xF5, 0x97, 0x7F, 0x30, 0xD1, 0x00, 0x1D,
+ 0x00, 0xF0, 0x32, 0xB9, 0x63, 0x2A, 0x22, 0xD0, 0x08, 0xDC, 0x10, 0x2A,
+ 0x1C, 0xD0, 0x11, 0x2A, 0x0E, 0xD0, 0x13, 0x2A, 0x24, 0xD1, 0x00, 0x1D,
+ 0x00, 0xF0, 0x46, 0xB9, 0x7C, 0x2A, 0x19, 0xD0, 0x87, 0x2A, 0x1D, 0xD1,
+ 0x00, 0x1D, 0x00, 0xF0, 0xD1, 0xB9, 0x00, 0x1D, 0x00, 0xF0, 0xB6, 0xB8,
+ 0x00, 0x1D, 0x00, 0xF0, 0x4F, 0xB9, 0x00, 0x1D, 0x00, 0xF0, 0x14, 0xB8,
+ 0x00, 0x1D, 0x00, 0xF0, 0x07, 0xB9, 0x00, 0x1D, 0x00, 0xF0, 0x20, 0xB9,
+ 0x00, 0x1D, 0x00, 0xF0, 0x85, 0xB9, 0x00, 0x1D, 0x00, 0xF0, 0xE2, 0xB9,
+ 0x00, 0x1D, 0x00, 0xF0, 0x93, 0xB9, 0x00, 0x1D, 0x00, 0xF0, 0x00, 0xBA,
+ 0x70, 0x47, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, 0x01, 0x7A,
+ 0x09, 0x30, 0x06, 0x46, 0xFF, 0xF7, 0x24, 0xFF, 0x04, 0x00, 0x0A, 0xD1,
+ 0x20, 0x21, 0x30, 0x46, 0xFF, 0xF7, 0x1E, 0xFF, 0x04, 0x00, 0x04, 0xD1,
+ 0x20, 0x21, 0x2B, 0x48, 0xFF, 0xF7, 0x18, 0xFF, 0x04, 0x46, 0x2A, 0x88,
+ 0x29, 0x4F, 0x32, 0xB1, 0x00, 0x26, 0x00, 0x2C, 0x49, 0xD0, 0xA0, 0x78,
+ 0x01, 0x28, 0x33, 0xD0, 0x33, 0xE0, 0x00, 0x2C, 0x43, 0xD0, 0x68, 0x88,
+ 0x20, 0x82, 0x02, 0x20, 0x60, 0x70, 0xA8, 0x88, 0x60, 0x82, 0xD5, 0xF8,
+ 0x09, 0x00, 0xC4, 0xF8, 0x07, 0x00, 0xB5, 0xF8, 0x0D, 0x10, 0xA4, 0xF8,
+ 0x0B, 0x10, 0x2A, 0x7A, 0xA2, 0x71, 0x2B, 0x8A, 0xA3, 0x82, 0x6B, 0x8A,
+ 0xE3, 0x82, 0xAB, 0x8A, 0x23, 0x83, 0xEB, 0x79, 0x63, 0x71, 0xAB, 0x7D,
+ 0x63, 0x73, 0xEB, 0x7D, 0xA3, 0x73, 0x2B, 0x7E, 0xE3, 0x73, 0x16, 0x4B,
+ 0x18, 0x60, 0x16, 0x48, 0x99, 0x80, 0x02, 0x21, 0x02, 0x70, 0xE0, 0x78,
+ 0x00, 0x22, 0xF3, 0xF7, 0x8B, 0xFD, 0xA0, 0x78, 0x01, 0x28, 0x18, 0xD1,
+ 0x38, 0x78, 0x20, 0xF0, 0xC0, 0x00, 0x38, 0x70, 0x00, 0x20, 0x0E, 0xE0,
+ 0x01, 0x26, 0xE0, 0x78, 0x00, 0x21, 0xF3, 0xF7, 0x7D, 0xFD, 0x20, 0x46,
+ 0x00, 0xF0, 0x04, 0xFA, 0x00, 0x2E, 0x08, 0xD0, 0x38, 0x78, 0x20, 0xF0,
+ 0xC0, 0x00, 0x38, 0x70, 0x28, 0x88, 0xBD, 0xE8, 0xF0, 0x41, 0xF3, 0xF7,
+ 0x93, 0xBD, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, 0x68, 0x78, 0x20, 0x00,
+ 0x38, 0x78, 0x20, 0x00, 0x52, 0x78, 0x20, 0x00, 0x3A, 0x78, 0x20, 0x00,
+ 0x70, 0xB5, 0x05, 0x46, 0x81, 0x79, 0xFF, 0xF7, 0xB7, 0xFE, 0x6A, 0x89,
+ 0x04, 0x46, 0x8A, 0xB1, 0x0E, 0x48, 0x01, 0x78, 0x21, 0xF0, 0xC0, 0x01,
+ 0x01, 0x70, 0x34, 0xB1, 0xE0, 0x78, 0x00, 0x21, 0xF3, 0xF7, 0x52, 0xFD,
+ 0x20, 0x46, 0x00, 0xF0, 0xD9, 0xF9, 0x68, 0x89, 0xBD, 0xE8, 0x70, 0x40,
+ 0xF3, 0xF7, 0x6E, 0xBD, 0x14, 0xB1, 0x28, 0x89, 0x20, 0x82, 0x70, 0xBD,
+ 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x22, 0x03, 0x49, 0x03, 0x48, 0xE4, 0xF7,
+ 0xDA, 0x99, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, 0x44, 0x61, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x2D, 0xE9, 0xF8, 0x43, 0x06, 0x46, 0x01, 0x25,
+ 0x81, 0x79, 0xFF, 0xF7, 0x89, 0xFE, 0xDF, 0xF8, 0x90, 0x80, 0x24, 0x4F,
+ 0x04, 0x00, 0x12, 0xD0, 0xE3, 0x78, 0x01, 0x22, 0x22, 0x49, 0x40, 0x46,
+ 0xE4, 0xF7, 0xC1, 0xD9, 0x38, 0x78, 0x00, 0x22, 0x20, 0xF0, 0x0C, 0x00,
+ 0x40, 0xF0, 0x02, 0x00, 0x38, 0x70, 0xE0, 0x78, 0x01, 0x21, 0xF3, 0xF7,
+ 0x1B, 0xFD, 0x00, 0x20, 0x28, 0xE0, 0x1B, 0x48, 0x40, 0xF6, 0x03, 0x54,
+ 0x00, 0x78, 0x01, 0x28, 0x08, 0xD1, 0x19, 0x48, 0x02, 0x68, 0x2A, 0xB1,
+ 0x69, 0x46, 0x16, 0x20, 0x00, 0x96, 0x90, 0x47, 0xA0, 0x42, 0x11, 0xD1,
+ 0x30, 0x46, 0xFF, 0xF7, 0x9F, 0xFD, 0x04, 0x00, 0x04, 0xD0, 0xB0, 0x79,
+ 0xA0, 0x71, 0x02, 0x20, 0xA0, 0x70, 0xD9, 0xE7, 0x0D, 0x49, 0x02, 0x25,
+ 0x00, 0x22, 0x30, 0x39, 0x40, 0x46, 0xE4, 0xF7, 0x94, 0xD9, 0x00, 0xE0,
+ 0x02, 0x25, 0x38, 0x78, 0x20, 0xF0, 0x0C, 0x00, 0x40, 0xF0, 0x02, 0x00,
+ 0x38, 0x70, 0x28, 0x46, 0xF3, 0xF7, 0x12, 0xFD, 0x29, 0x46, 0x30, 0x46,
+ 0xBD, 0xE8, 0xF8, 0x43, 0xEF, 0xF7, 0x1A, 0xBF, 0x00, 0x35, 0x10, 0x21,
+ 0x38, 0x78, 0x20, 0x00, 0x08, 0x61, 0xC0, 0x08, 0x3C, 0x78, 0x20, 0x00,
+ 0x48, 0x78, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x41, 0x88, 0x00, 0x88,
+ 0xFF, 0xF7, 0xF0, 0xFD, 0x20, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0xF0, 0xF7,
+ 0xDB, 0xB9, 0x00, 0x00, 0x43, 0x88, 0x23, 0xB1, 0x01, 0x22, 0x04, 0x49,
+ 0x04, 0x48, 0xE4, 0xF7, 0x66, 0x99, 0x81, 0x88, 0x00, 0x88, 0xFF, 0xF7,
+ 0xDF, 0xBD, 0x00, 0x00, 0x38, 0x62, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFF, 0xF7, 0x4D, 0xFE, 0x00, 0x28,
+ 0x07, 0xD0, 0x61, 0x88, 0x41, 0x82, 0x61, 0x88, 0xC0, 0x78, 0xBD, 0xE8,
+ 0x10, 0x40, 0xF3, 0xF7, 0x97, 0xBD, 0x10, 0xBD, 0x10, 0xB5, 0x04, 0x46,
+ 0x00, 0x88, 0xFF, 0xF7, 0x3D, 0xFE, 0x00, 0x28, 0x0C, 0xD0, 0x61, 0x88,
+ 0x81, 0x82, 0xA1, 0x88, 0xC1, 0x82, 0xE1, 0x88, 0x01, 0x83, 0xC0, 0x78,
+ 0x00, 0x22, 0xBD, 0xE8, 0x10, 0x40, 0x11, 0x46, 0xF3, 0xF7, 0x7A, 0xBC,
+ 0x10, 0xBD, 0x00, 0x00, 0x7F, 0xB5, 0x1D, 0x4E, 0x04, 0x46, 0x01, 0x25,
+ 0x30, 0x68, 0x10, 0xB3, 0x20, 0x88, 0xFF, 0xF7, 0x23, 0xFE, 0x28, 0xB3,
+ 0xC0, 0x78, 0x8D, 0xF8, 0x00, 0x00, 0xA0, 0x88, 0xAD, 0xF8, 0x04, 0x00,
+ 0x60, 0x88, 0xAD, 0xF8, 0x02, 0x00, 0xE0, 0x88, 0xAD, 0xF8, 0x06, 0x00,
+ 0x20, 0x89, 0xAD, 0xF8, 0x08, 0x00, 0xCD, 0xF8, 0x0C, 0xD0, 0x32, 0x68,
+ 0x03, 0xA9, 0x15, 0x20, 0x90, 0x47, 0xA0, 0xF5, 0x50, 0x61, 0x04, 0x39,
+ 0x05, 0xD1, 0x02, 0x25, 0x00, 0x22, 0x0C, 0x49, 0x0C, 0x48, 0xE4, 0xF7,
+ 0x0E, 0xD9, 0x20, 0x88, 0x04, 0xB0, 0x29, 0x46, 0xBD, 0xE8, 0x70, 0x40,
+ 0xEF, 0xF7, 0x90, 0xBF, 0x06, 0x49, 0x07, 0x48, 0x00, 0x22, 0x38, 0x39,
+ 0x80, 0x1E, 0xE4, 0xF7, 0x00, 0xD9, 0x20, 0x88, 0x02, 0x21, 0xEF, 0xF7,
+ 0x85, 0xFF, 0x7F, 0xBD, 0x48, 0x78, 0x20, 0x00, 0xAC, 0x61, 0xC0, 0x08,
+ 0x02, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFF, 0xF7,
+ 0xE5, 0xFD, 0x00, 0x28, 0x0A, 0xD0, 0x62, 0x88, 0xC0, 0x78, 0x0A, 0xB1,
+ 0x01, 0x21, 0x01, 0xE0, 0x00, 0x22, 0x02, 0x21, 0xBD, 0xE8, 0x10, 0x40,
+ 0xF3, 0xF7, 0x24, 0xBC, 0x10, 0xBD, 0x00, 0x00, 0x3E, 0xB5, 0x04, 0x46,
+ 0x40, 0x88, 0xFF, 0xF7, 0xD1, 0xFD, 0x00, 0x28, 0x1A, 0xD0, 0x21, 0x88,
+ 0x19, 0xB9, 0x61, 0x79, 0x81, 0x73, 0x21, 0x79, 0x41, 0x73, 0x0B, 0x49,
+ 0x0A, 0x68, 0x00, 0x2A, 0x10, 0xD0, 0xC1, 0x78, 0x8D, 0xF8, 0x00, 0x10,
+ 0x21, 0x88, 0xAD, 0xF8, 0x02, 0x10, 0x81, 0x7B, 0x8D, 0xF8, 0x05, 0x10,
+ 0x40, 0x7B, 0x8D, 0xF8, 0x04, 0x00, 0xCD, 0xF8, 0x08, 0xD0, 0x02, 0xA9,
+ 0x17, 0x20, 0x90, 0x47, 0x3E, 0xBD, 0x00, 0x00, 0x48, 0x78, 0x20, 0x00,
+ 0x1F, 0xB5, 0x04, 0x46, 0x40, 0x88, 0xFF, 0xF7, 0xAB, 0xFD, 0x00, 0x28,
+ 0x1A, 0xD0, 0x21, 0x88, 0x29, 0xB9, 0x61, 0x68, 0xC0, 0xF8, 0x1A, 0x10,
+ 0xA1, 0x68, 0xC0, 0xF8, 0x1E, 0x10, 0x0A, 0x49, 0x0A, 0x68, 0x00, 0x2A,
+ 0x0E, 0xD0, 0xC0, 0x78, 0x8D, 0xF8, 0x00, 0x00, 0x20, 0x88, 0xAD, 0xF8,
+ 0x02, 0x00, 0x60, 0x68, 0x01, 0x90, 0xA0, 0x68, 0x02, 0x90, 0xCD, 0xF8,
+ 0x0C, 0xD0, 0x03, 0xA9, 0x19, 0x20, 0x90, 0x47, 0x1F, 0xBD, 0x00, 0x00,
+ 0x48, 0x78, 0x20, 0x00, 0x3E, 0xB5, 0x04, 0x46, 0x00, 0x88, 0x00, 0x28,
+ 0x1A, 0xD0, 0x0E, 0x4D, 0x28, 0x68, 0x00, 0x28, 0x16, 0xD0, 0x60, 0x88,
+ 0xFF, 0xF7, 0x7E, 0xFD, 0x00, 0x28, 0x11, 0xD0, 0xC1, 0x78, 0x8D, 0xF8,
+ 0x00, 0x10, 0x21, 0x88, 0xAD, 0xF8, 0x02, 0x10, 0x81, 0x7B, 0x8D, 0xF8,
+ 0x05, 0x10, 0x40, 0x7B, 0x8D, 0xF8, 0x04, 0x00, 0xCD, 0xF8, 0x08, 0xD0,
+ 0x2A, 0x68, 0x02, 0xA9, 0x17, 0x20, 0x90, 0x47, 0x3E, 0xBD, 0x00, 0x00,
+ 0x48, 0x78, 0x20, 0x00, 0x7F, 0xB5, 0x10, 0x4D, 0x04, 0x46, 0x28, 0x68,
+ 0x00, 0x28, 0x1A, 0xD0, 0xA1, 0x79, 0x20, 0x46, 0xFF, 0xF7, 0x24, 0xFD,
+ 0x00, 0x28, 0x14, 0xD0, 0xC0, 0x78, 0x8D, 0xF8, 0x00, 0x00, 0x20, 0x89,
+ 0xAD, 0xF8, 0x02, 0x00, 0xA0, 0x7A, 0x8D, 0xF8, 0x04, 0x00, 0xA0, 0x89,
+ 0xAD, 0xF8, 0x06, 0x00, 0xE0, 0x89, 0xAD, 0xF8, 0x08, 0x00, 0xCD, 0xF8,
+ 0x0C, 0xD0, 0x2A, 0x68, 0x03, 0xA9, 0x1B, 0x20, 0x90, 0x47, 0x7F, 0xBD,
+ 0x48, 0x78, 0x20, 0x00, 0x1F, 0xB5, 0x1B, 0x4C, 0x00, 0xEB, 0x40, 0x01,
+ 0x09, 0x01, 0x60, 0x70, 0x3E, 0x23, 0x19, 0x4A, 0x00, 0x20, 0xEE, 0xF7,
+ 0xD7, 0xDD, 0x60, 0x60, 0x0A, 0x20, 0xAD, 0xF8, 0x04, 0x00, 0x20, 0x20,
+ 0xAD, 0xF8, 0x06, 0x00, 0x10, 0x20, 0xAD, 0xF8, 0x00, 0x00, 0xAD, 0xF8,
+ 0x02, 0x00, 0x4F, 0xF4, 0x7A, 0x70, 0xAD, 0xF8, 0x0A, 0x00, 0x00, 0x20,
+ 0xAD, 0xF8, 0x08, 0x00, 0x12, 0x20, 0xAD, 0xF8, 0x0C, 0x00, 0x3E, 0x20,
+ 0xAD, 0xF8, 0x0E, 0x00, 0x10, 0x22, 0x69, 0x46, 0x04, 0xF1, 0x0E, 0x00,
+ 0x16, 0xF4, 0x37, 0xF1, 0x10, 0x22, 0x69, 0x46, 0x04, 0xF1, 0x1E, 0x00,
+ 0x16, 0xF4, 0x31, 0xF1, 0x10, 0x22, 0x69, 0x46, 0x04, 0xF1, 0x2E, 0x00,
+ 0x16, 0xF4, 0x2B, 0xF1, 0x1F, 0xBD, 0x00, 0x00, 0x60, 0x78, 0x20, 0x00,
+ 0x06, 0xB2, 0x82, 0x00, 0x10, 0xB5, 0x04, 0x00, 0x0B, 0xD0, 0xE3, 0x78,
+ 0x01, 0x22, 0x05, 0x49, 0x05, 0x48, 0xE4, 0xF7, 0x08, 0xD8, 0x20, 0x46,
+ 0xBD, 0xE8, 0x10, 0x40, 0x30, 0x21, 0x16, 0xF4, 0xB7, 0xB1, 0x10, 0xBD,
+ 0x2C, 0x5F, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x00, 0x28,
+ 0x04, 0xD0, 0x78, 0x22, 0x02, 0x49, 0x16, 0xF4, 0x4F, 0xF1, 0x01, 0x20,
+ 0x10, 0xBD, 0x00, 0x00, 0xBC, 0x02, 0x20, 0x00, 0x10, 0xB5, 0xF0, 0xF7,
+ 0x7F, 0xFB, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD,
+ 0xEC, 0xF7, 0xAC, 0xBE, 0x10, 0xB5, 0x00, 0x24, 0x03, 0x46, 0xB0, 0xF5,
+ 0x40, 0x7F, 0x0E, 0xD0, 0xA3, 0xF5, 0x40, 0x70, 0x0A, 0x4A, 0x01, 0x38,
+ 0x0D, 0xD0, 0x01, 0x28, 0x0D, 0xD0, 0x03, 0x24, 0x01, 0x22, 0x08, 0x49,
+ 0x08, 0x48, 0xE3, 0xF7, 0xD4, 0xDF, 0x20, 0x46, 0x10, 0xBD, 0x07, 0x48,
+ 0x00, 0x88, 0x08, 0x80, 0xF9, 0xE7, 0x10, 0x78, 0x00, 0xE0, 0x50, 0x78,
+ 0x08, 0x70, 0xF4, 0xE7, 0x30, 0x79, 0x20, 0x00, 0xE8, 0x7F, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x86, 0x74, 0x20, 0x00, 0x41, 0x88, 0xB1, 0xF5,
+ 0xBD, 0x7F, 0x20, 0xD0, 0x0B, 0xDC, 0xB1, 0xF5, 0xBA, 0x7F, 0x16, 0xD0,
+ 0xB1, 0xF5, 0xBB, 0x7F, 0x16, 0xD0, 0xB1, 0xF5, 0xBC, 0x7F, 0x0F, 0xD1,
+ 0x00, 0x1D, 0x00, 0xF0, 0x2F, 0xB8, 0xB1, 0xF5, 0xBE, 0x7F, 0x13, 0xD0,
+ 0xB1, 0xF5, 0xC0, 0x7F, 0x13, 0xD0, 0xA1, 0xF5, 0x80, 0x71, 0xB3, 0x39,
+ 0x02, 0xD1, 0x09, 0x49, 0x80, 0x7C, 0x48, 0x70, 0x70, 0x47, 0x00, 0x1D,
+ 0x00, 0xF0, 0x14, 0xB8, 0x00, 0x1D, 0x00, 0xF0, 0x25, 0xB8, 0x00, 0x1D,
+ 0x00, 0xF0, 0x2C, 0xB8, 0x00, 0x1D, 0x00, 0xF0, 0x55, 0xB8, 0x00, 0x1D,
+ 0x00, 0xF0, 0x48, 0xB8, 0x30, 0x79, 0x20, 0x00, 0x01, 0x49, 0x80, 0x7B,
+ 0x48, 0x70, 0x70, 0x47, 0x30, 0x79, 0x20, 0x00, 0x03, 0x4A, 0x52, 0x68,
+ 0x00, 0x2A, 0x02, 0xD0, 0x01, 0x46, 0x02, 0x20, 0x10, 0x47, 0x70, 0x47,
+ 0x30, 0x79, 0x20, 0x00, 0x03, 0x4A, 0x52, 0x68, 0x00, 0x2A, 0x02, 0xD0,
+ 0x01, 0x46, 0x04, 0x20, 0x10, 0x47, 0x70, 0x47, 0x30, 0x79, 0x20, 0x00,
+ 0x03, 0x4A, 0x52, 0x68, 0x00, 0x2A, 0x02, 0xD0, 0x01, 0x46, 0x03, 0x20,
+ 0x10, 0x47, 0x70, 0x47, 0x30, 0x79, 0x20, 0x00, 0x30, 0xB4, 0x0F, 0x4C,
+ 0x03, 0x88, 0x03, 0x22, 0x20, 0x78, 0x00, 0x21, 0x23, 0xB1, 0x01, 0x28,
+ 0x06, 0xD0, 0x02, 0x28, 0x06, 0xD0, 0x06, 0xE0, 0x01, 0x28, 0x03, 0xD0,
+ 0x02, 0x28, 0x02, 0xD1, 0x22, 0x70, 0x00, 0xE0, 0x21, 0x70, 0x62, 0x68,
+ 0x00, 0x2A, 0x07, 0xD0, 0x20, 0x78, 0x30, 0xBC, 0x60, 0xF3, 0x07, 0x01,
+ 0x63, 0xF3, 0x1F, 0x41, 0x00, 0x20, 0x10, 0x47, 0x30, 0xBC, 0x70, 0x47,
+ 0x30, 0x79, 0x20, 0x00, 0x03, 0x4A, 0x52, 0x68, 0x00, 0x2A, 0x02, 0xD0,
+ 0x01, 0x46, 0x05, 0x20, 0x10, 0x47, 0x70, 0x47, 0x30, 0x79, 0x20, 0x00,
+ 0x05, 0x4A, 0x12, 0x78, 0xD2, 0x07, 0x06, 0xD0, 0x04, 0x4A, 0x52, 0x68,
+ 0x00, 0x2A, 0x02, 0xD0, 0x01, 0x46, 0x01, 0x20, 0x10, 0x47, 0x70, 0x47,
+ 0x38, 0x78, 0x20, 0x00, 0x30, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x41,
+ 0x80, 0x46, 0x2C, 0x48, 0x00, 0x25, 0xDF, 0xF8, 0xB0, 0xC0, 0x03, 0x78,
+ 0x8A, 0xB0, 0x0F, 0x46, 0x16, 0x46, 0x2C, 0x46, 0xC3, 0xB1, 0x29, 0x48,
+ 0x00, 0x78, 0x81, 0x06, 0x09, 0x0F, 0x03, 0xD1, 0x01, 0x21, 0xB1, 0xEB,
+ 0x90, 0x1F, 0x0F, 0xD1, 0x82, 0x09, 0xC0, 0xF3, 0x01, 0x11, 0xC0, 0xF3,
+ 0x81, 0x00, 0x8D, 0xE8, 0x07, 0x00, 0x04, 0x22, 0x21, 0x49, 0x60, 0x46,
+ 0xE3, 0xF7, 0x0F, 0xDF, 0x02, 0x20, 0x0A, 0xB0, 0xBD, 0xE8, 0xF0, 0x81,
+ 0x01, 0x2F, 0x0C, 0xD1, 0x70, 0x79, 0x03, 0x21, 0xB1, 0xEB, 0x90, 0x1F,
+ 0x07, 0xD0, 0x1A, 0x49, 0x00, 0x22, 0x64, 0x31, 0x60, 0x46, 0xE3, 0xF7,
+ 0xFE, 0xDE, 0x03, 0x20, 0xED, 0xE7, 0xB8, 0xF1, 0x01, 0x0F, 0x14, 0xD1,
+ 0x15, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x00, 0x06, 0x19, 0xD5, 0x39, 0x46,
+ 0x10, 0x46, 0xFE, 0xF7, 0xE1, 0xFB, 0xA0, 0xB1, 0x41, 0x88, 0x0A, 0x06,
+ 0x00, 0xD5, 0x10, 0x4C, 0x09, 0x07, 0x04, 0xD5, 0x03, 0xAA, 0x14, 0x21,
+ 0xFE, 0xF7, 0x1E, 0xFF, 0x03, 0xAD, 0x2B, 0x46, 0x32, 0x46, 0x39, 0x46,
+ 0x40, 0x46, 0x00, 0x94, 0xF0, 0xF7, 0x2A, 0xFA, 0x18, 0xB1, 0x00, 0x20,
+ 0xCB, 0xE7, 0x0C, 0x20, 0xC9, 0xE7, 0x07, 0x20, 0xC7, 0xE7, 0x00, 0x00,
+ 0x30, 0x79, 0x20, 0x00, 0x00, 0x35, 0x10, 0x21, 0x38, 0x78, 0x20, 0x00,
+ 0x10, 0x81, 0xC0, 0x08, 0x64, 0x01, 0x20, 0x00, 0x28, 0x78, 0x20, 0x00,
+ 0x10, 0xB5, 0xF0, 0xF7, 0xF3, 0xFA, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD,
+ 0x07, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0xF0, 0xF7, 0x17, 0xFB, 0x08, 0xB1,
+ 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, 0x01, 0x49, 0x48, 0x60,
+ 0x70, 0x47, 0x00, 0x00, 0x30, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x41,
+ 0x1F, 0x4C, 0x1E, 0x4D, 0x06, 0x00, 0x23, 0x78, 0x03, 0xD0, 0x5B, 0xB1,
+ 0x01, 0x22, 0x1D, 0x49, 0x04, 0xE0, 0x03, 0x2B, 0x06, 0xD0, 0x1B, 0x49,
+ 0x01, 0x22, 0x3C, 0x31, 0x28, 0x46, 0xE3, 0xF7, 0xA0, 0xDE, 0x15, 0xE0,
+ 0x18, 0x48, 0x00, 0x78, 0x81, 0x06, 0x09, 0x0F, 0x03, 0xD1, 0x01, 0x27,
+ 0xB7, 0xEB, 0x90, 0x1F, 0x0F, 0xD1, 0x82, 0x09, 0xC0, 0xF3, 0x01, 0x11,
+ 0xCD, 0xE9, 0x00, 0x12, 0x10, 0x49, 0xC0, 0xF3, 0x81, 0x03, 0x03, 0x22,
+ 0x78, 0x31, 0x28, 0x46, 0xE3, 0xF7, 0x89, 0xDE, 0x02, 0x20, 0xBD, 0xE8,
+ 0xFC, 0x81, 0x30, 0x46, 0xF0, 0xF7, 0xD1, 0xFC, 0x30, 0xB1, 0x16, 0xB1,
+ 0x02, 0x20, 0x20, 0x70, 0x00, 0xE0, 0x27, 0x70, 0x00, 0x20, 0xF2, 0xE7,
+ 0x05, 0x49, 0x00, 0x22, 0xD0, 0x31, 0x28, 0x46, 0xE3, 0xF7, 0x75, 0xDE,
+ 0xFF, 0x20, 0xEA, 0xE7, 0x00, 0x35, 0x10, 0x21, 0x30, 0x79, 0x20, 0x00,
+ 0x14, 0x80, 0xC0, 0x08, 0x38, 0x78, 0x20, 0x00, 0x10, 0xB5, 0xF0, 0xF7,
+ 0x89, 0xFC, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD,
+ 0x10, 0xB5, 0x00, 0x24, 0x03, 0x46, 0xB0, 0xF5, 0x40, 0x7F, 0x0A, 0xD1,
+ 0x10, 0x88, 0x4A, 0xF2, 0xB7, 0x12, 0x41, 0x1E, 0x91, 0x42, 0x04, 0xD8,
+ 0x06, 0x49, 0x08, 0x80, 0x00, 0xF0, 0x06, 0xFC, 0x05, 0xE0, 0x03, 0x24,
+ 0x01, 0x22, 0x04, 0x49, 0x04, 0x48, 0xE3, 0xF7, 0x4C, 0xDE, 0x20, 0x46,
+ 0x10, 0xBD, 0x00, 0x00, 0x86, 0x74, 0x20, 0x00, 0xBC, 0x7F, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x04, 0x48, 0x10, 0xB5, 0x00, 0x88, 0xF0, 0xF7,
+ 0x9A, 0xFC, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD,
+ 0x86, 0x74, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x01, 0x46, 0x08, 0x48,
+ 0xFF, 0xF7, 0x88, 0xFA, 0x50, 0xB1, 0x07, 0x49, 0x04, 0xEB, 0x44, 0x00,
+ 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x00, 0x8A, 0xF0, 0xF7, 0x2E, 0xFA,
+ 0x00, 0x20, 0x10, 0xBD, 0x04, 0x20, 0x10, 0xBD, 0xC6, 0xB1, 0x82, 0x00,
+ 0x64, 0x78, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x01, 0x46, 0x0A, 0x48,
+ 0xFF, 0xF7, 0x70, 0xFA, 0x70, 0xB1, 0x09, 0x48, 0x04, 0xEB, 0x44, 0x01,
+ 0x40, 0x68, 0x00, 0xEB, 0x01, 0x10, 0x81, 0x79, 0xC0, 0x1D, 0xF0, 0xF7,
+ 0x77, 0xFD, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD,
+ 0x04, 0x20, 0x10, 0xBD, 0x25, 0xB2, 0x82, 0x00, 0x60, 0x78, 0x20, 0x00,
+ 0x10, 0xB5, 0x04, 0x46, 0x01, 0x46, 0x09, 0x48, 0xFF, 0xF7, 0x54, 0xFA,
+ 0x58, 0xB1, 0x08, 0x48, 0x04, 0xEB, 0x44, 0x01, 0x00, 0x68, 0x00, 0xEB,
+ 0x01, 0x10, 0x81, 0x79, 0xC0, 0x1D, 0xF0, 0xF7, 0x89, 0xFD, 0x00, 0x20,
+ 0x10, 0xBD, 0x04, 0x20, 0x10, 0xBD, 0x00, 0x00, 0xB9, 0xB1, 0x82, 0x00,
+ 0x64, 0x78, 0x20, 0x00, 0x01, 0x49, 0x08, 0x61, 0x70, 0x47, 0x00, 0x00,
+ 0x38, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x07, 0x46, 0x0D, 0x46,
+ 0x40, 0x79, 0x01, 0x21, 0xDF, 0xF8, 0x70, 0x80, 0x16, 0x46, 0xB1, 0xEB,
+ 0x90, 0x1F, 0x2F, 0xD1, 0x38, 0x46, 0xFE, 0xF7, 0xC5, 0xFA, 0x04, 0x00,
+ 0x05, 0xD1, 0x01, 0x21, 0x38, 0x46, 0xFE, 0xF7, 0x4D, 0xFA, 0x04, 0x00,
+ 0x18, 0xD0, 0xA0, 0x78, 0x00, 0x07, 0x19, 0xD5, 0x20, 0x69, 0x28, 0x60,
+ 0xA0, 0x8A, 0xA8, 0x80, 0xA0, 0x7D, 0x30, 0x70, 0x29, 0x46, 0x10, 0x48,
+ 0xE3, 0xF7, 0x8E, 0xDF, 0x03, 0x46, 0xA0, 0x7D, 0x00, 0x90, 0x0C, 0x48,
+ 0x02, 0x22, 0x0D, 0x49, 0xC0, 0x1C, 0xE3, 0xF7, 0xB6, 0xDD, 0x01, 0x20,
+ 0xBD, 0xE8, 0xF8, 0x83, 0x09, 0x49, 0x00, 0x22, 0x30, 0x39, 0x02, 0xE0,
+ 0x07, 0x49, 0x00, 0x22, 0x44, 0x31, 0x40, 0x46, 0xE3, 0xF7, 0xA9, 0xDD,
+ 0x00, 0x20, 0xF1, 0xE7, 0x03, 0x49, 0x00, 0x22, 0x74, 0x31, 0xF6, 0xE7,
+ 0x00, 0x35, 0x10, 0x21, 0x00, 0x00, 0x30, 0x21, 0x24, 0x72, 0xC0, 0x08,
+ 0x10, 0xB5, 0x04, 0x46, 0x08, 0x78, 0x0B, 0x46, 0x00, 0x1D, 0xC2, 0xB2,
+ 0x61, 0x78, 0x18, 0x46, 0xF2, 0xF7, 0x6C, 0xFB, 0x08, 0xB1, 0x00, 0x20,
+ 0x10, 0xBD, 0x60, 0x88, 0x40, 0xF0, 0x40, 0x00, 0x60, 0x80, 0x01, 0x20,
+ 0x10, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x43, 0x04, 0x46, 0x59, 0x48,
+ 0x88, 0x46, 0xA1, 0xF1, 0x11, 0x07, 0x00, 0x25, 0x01, 0x21, 0xB0, 0xF8,
+ 0xC2, 0x01, 0x89, 0xB0, 0x16, 0x46, 0x04, 0xF1, 0x08, 0x09, 0x06, 0x2F,
+ 0x70, 0xD2, 0xDF, 0xE8, 0x07, 0xF0, 0x03, 0x19, 0x41, 0x2D, 0x55, 0x61,
+ 0x80, 0x07, 0x01, 0xD4, 0x01, 0x25, 0x68, 0xE0, 0x8D, 0xF8, 0x00, 0x60,
+ 0x32, 0x46, 0x19, 0x46, 0x01, 0xA8, 0x15, 0xF4, 0x7C, 0xF6, 0x61, 0x78,
+ 0x20, 0x22, 0x68, 0x46, 0xF2, 0xF7, 0x96, 0xFB, 0x00, 0x28, 0x7F, 0xD1,
+ 0x60, 0x88, 0x40, 0xF0, 0x02, 0x00, 0x52, 0xE0, 0x40, 0x07, 0xE9, 0xD5,
+ 0x8D, 0xF8, 0x00, 0x60, 0x32, 0x46, 0x19, 0x46, 0x01, 0xA8, 0x15, 0xF4,
+ 0x68, 0xF6, 0x61, 0x78, 0x20, 0x22, 0x68, 0x46, 0xF2, 0xF7, 0x36, 0xFC,
+ 0x00, 0x28, 0x6B, 0xD1, 0x60, 0x88, 0x40, 0xF0, 0x04, 0x00, 0x3E, 0xE0,
+ 0x00, 0x07, 0xD5, 0xD5, 0xD9, 0x75, 0x1F, 0x46, 0x61, 0x78, 0x18, 0x46,
+ 0xF2, 0xF7, 0xFC, 0xFB, 0x00, 0x28, 0x5D, 0xD1, 0x38, 0x69, 0x20, 0x61,
+ 0xB8, 0x8A, 0xA0, 0x82, 0xB8, 0x7D, 0xA0, 0x75, 0x60, 0x88, 0x40, 0xF0,
+ 0x08, 0x00, 0x2A, 0xE0, 0x03, 0x20, 0xE0, 0x73, 0x20, 0x79, 0x01, 0x28,
+ 0x01, 0xD1, 0x07, 0x20, 0xE0, 0x73, 0x61, 0x78, 0x48, 0x46, 0xF2, 0xF7,
+ 0x89, 0xFB, 0xD0, 0xBB, 0x61, 0x78, 0x01, 0x20, 0xEB, 0xF7, 0x02, 0xF9,
+ 0x60, 0x88, 0x40, 0xF0, 0x81, 0x00, 0x16, 0xE0, 0xC0, 0x06, 0xAD, 0xD5,
+ 0x59, 0x75, 0x18, 0x46, 0x61, 0x78, 0xF2, 0xF7, 0x21, 0xFB, 0x50, 0xBB,
+ 0x60, 0x88, 0x40, 0xF0, 0x10, 0x00, 0x0A, 0xE0, 0x80, 0x06, 0xA1, 0xD5,
+ 0x59, 0x75, 0x18, 0x46, 0x61, 0x78, 0xF2, 0xF7, 0x9D, 0xFB, 0xF0, 0xB9,
+ 0x60, 0x88, 0x40, 0xF0, 0x20, 0x00, 0x60, 0x80, 0x96, 0xE7, 0xFF, 0xE7,
+ 0xBD, 0xB1, 0x60, 0x88, 0xC1, 0x07, 0x21, 0xD1, 0xE1, 0x7B, 0x00, 0x06,
+ 0x41, 0xF0, 0x01, 0x01, 0xE1, 0x73, 0x02, 0xD5, 0x41, 0xF0, 0x02, 0x00,
+ 0xE0, 0x73, 0x20, 0x79, 0x01, 0x28, 0xE0, 0x7B, 0x08, 0xD0, 0x20, 0xF0,
+ 0x04, 0x00, 0xE0, 0x73, 0x61, 0x78, 0x48, 0x46, 0xF2, 0xF7, 0x4E, 0xFB,
+ 0x18, 0xB1, 0x0B, 0xE0, 0x40, 0xF0, 0x04, 0x00, 0xF5, 0xE7, 0x61, 0x78,
+ 0x01, 0x20, 0xEB, 0xF7, 0xC3, 0xF8, 0x60, 0x88, 0x01, 0x25, 0x40, 0xF0,
+ 0x01, 0x00, 0x60, 0x80, 0xCD, 0xF8, 0x00, 0x80, 0xCD, 0xE9, 0x01, 0x65,
+ 0x63, 0x78, 0x04, 0x22, 0x04, 0x49, 0x05, 0x48, 0xE3, 0xF7, 0xD7, 0xDC,
+ 0x09, 0xB0, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x83, 0x64, 0x01, 0x20, 0x00,
+ 0x60, 0x70, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x03, 0x46,
+ 0xA0, 0xF5, 0x10, 0x75, 0x00, 0x24, 0x0F, 0x48, 0x0F, 0x4A, 0x06, 0x2D,
+ 0x12, 0xD2, 0xDF, 0xE8, 0x05, 0xF0, 0x03, 0x05, 0x08, 0x0A, 0x0D, 0x0F,
+ 0x80, 0x78, 0x00, 0xE0, 0x10, 0x78, 0x08, 0x70, 0x0E, 0xE0, 0x50, 0x88,
+ 0x00, 0xE0, 0x90, 0x88, 0x08, 0x80, 0x09, 0xE0, 0x00, 0x78, 0xF6, 0xE7,
+ 0x40, 0x78, 0xF4, 0xE7, 0x03, 0x24, 0x01, 0x22, 0x04, 0x49, 0x05, 0x48,
+ 0xE3, 0xF7, 0xAB, 0xDC, 0x20, 0x46, 0x70, 0xBD, 0x63, 0x79, 0x20, 0x00,
+ 0xB0, 0x74, 0x20, 0x00, 0x58, 0x83, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0x41, 0x88, 0xB1, 0xF5, 0x9C, 0x7F, 0x0B, 0xD0, 0xB1, 0xF5, 0x9D, 0x7F,
+ 0x0B, 0xD0, 0xA1, 0xF5, 0x80, 0x71, 0x3B, 0x39, 0x0A, 0xD0, 0x46, 0x29,
+ 0x0B, 0xD1, 0x00, 0x1D, 0x00, 0xF0, 0x0A, 0xB8, 0x00, 0x1D, 0x00, 0xF0,
+ 0x9D, 0xB8, 0x00, 0x1D, 0x00, 0xF0, 0x7A, 0xB8, 0x00, 0x1D, 0x00, 0xF0,
+ 0x6B, 0xB8, 0x70, 0x47, 0x38, 0xB5, 0x04, 0x46, 0x07, 0x49, 0xC0, 0x1D,
+ 0xFC, 0xF7, 0x36, 0xFE, 0x00, 0x28, 0x07, 0xD0, 0x05, 0x48, 0x02, 0x68,
+ 0x00, 0x2A, 0x03, 0xD0, 0x69, 0x46, 0x31, 0x20, 0x00, 0x94, 0x90, 0x47,
+ 0x38, 0xBD, 0x00, 0x00, 0x28, 0x78, 0x20, 0x00, 0x48, 0x78, 0x20, 0x00,
+ 0x38, 0xB5, 0x04, 0x46, 0x08, 0x48, 0x02, 0x68, 0x1A, 0xB1, 0x69, 0x46,
+ 0x50, 0x20, 0x00, 0x94, 0x90, 0x47, 0xE0, 0x69, 0x00, 0x28, 0x06, 0xD0,
+ 0x61, 0x7E, 0x00, 0x29, 0x03, 0xD0, 0xBD, 0xE8, 0x38, 0x40, 0xEC, 0xF7,
+ 0xE3, 0xBA, 0x38, 0xBD, 0x48, 0x78, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46,
+ 0x0C, 0x48, 0x00, 0x21, 0x81, 0x70, 0x21, 0x88, 0x41, 0xB9, 0x0B, 0x49,
+ 0x8B, 0x88, 0x4A, 0x88, 0x01, 0x78, 0x01, 0x20, 0xEF, 0xF7, 0xFB, 0xFE,
+ 0x00, 0x28, 0x09, 0xD1, 0x07, 0x48, 0x01, 0x78, 0x21, 0xF0, 0x30, 0x01,
+ 0x01, 0x70, 0x20, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0xF2, 0xF7, 0xCA, 0xBF,
+ 0x10, 0xBD, 0x00, 0x00, 0xBE, 0x74, 0x20, 0x00, 0x08, 0x7A, 0x20, 0x00,
+ 0x38, 0x78, 0x20, 0x00, 0x30, 0xB4, 0x0C, 0x4C, 0x00, 0x88, 0x21, 0x78,
+ 0x21, 0xF0, 0x30, 0x02, 0x02, 0xF1, 0x20, 0x03, 0xC1, 0xF3, 0x01, 0x11,
+ 0x20, 0xB1, 0x01, 0x29, 0x06, 0xD0, 0x03, 0x29, 0x06, 0xD0, 0x06, 0xE0,
+ 0x01, 0x29, 0x03, 0xD0, 0x03, 0x29, 0x02, 0xD1, 0x22, 0x70, 0x00, 0xE0,
+ 0x23, 0x70, 0x30, 0xBC, 0xF2, 0xF7, 0xA8, 0xBF, 0x38, 0x78, 0x20, 0x00,
+ 0x04, 0x49, 0x08, 0xB5, 0x0A, 0x68, 0x00, 0x2A, 0x03, 0xD0, 0x00, 0x90,
+ 0x69, 0x46, 0x30, 0x20, 0x90, 0x47, 0x08, 0xBD, 0x48, 0x78, 0x20, 0x00,
+ 0x10, 0xB5, 0x0C, 0x49, 0x04, 0x46, 0x00, 0x20, 0x48, 0x70, 0x20, 0x88,
+ 0x30, 0xB9, 0x0A, 0x48, 0x41, 0x78, 0x01, 0x20, 0xF0, 0xF7, 0x0F, 0xF9,
+ 0x00, 0x28, 0x09, 0xD1, 0x07, 0x48, 0x01, 0x78, 0x21, 0xF0, 0x30, 0x01,
+ 0x01, 0x70, 0x20, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0xF2, 0xF7, 0x82, 0xBF,
+ 0x10, 0xBD, 0x00, 0x00, 0xB0, 0x74, 0x20, 0x00, 0x63, 0x79, 0x20, 0x00,
+ 0x38, 0x78, 0x20, 0x00, 0x30, 0xB4, 0x0C, 0x4C, 0x00, 0x88, 0x21, 0x78,
+ 0x21, 0xF0, 0x30, 0x02, 0x02, 0xF1, 0x20, 0x03, 0xC1, 0xF3, 0x01, 0x11,
+ 0x20, 0xB1, 0x01, 0x29, 0x06, 0xD0, 0x03, 0x29, 0x06, 0xD0, 0x06, 0xE0,
+ 0x01, 0x29, 0x03, 0xD0, 0x03, 0x29, 0x02, 0xD1, 0x22, 0x70, 0x00, 0xE0,
+ 0x23, 0x70, 0x30, 0xBC, 0xF2, 0xF7, 0x60, 0xBF, 0x38, 0x78, 0x20, 0x00,
+ 0x10, 0xB5, 0x0A, 0x4C, 0x20, 0x78, 0xC0, 0xF3, 0x01, 0x13, 0x02, 0x2B,
+ 0x04, 0xD0, 0x01, 0x22, 0x07, 0x49, 0x08, 0x48, 0xE3, 0xF7, 0xC9, 0xDB,
+ 0x20, 0x78, 0x20, 0xF0, 0x30, 0x00, 0x20, 0x70, 0xBD, 0xE8, 0x10, 0x40,
+ 0x00, 0x20, 0xF2, 0xF7, 0x49, 0xBF, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00,
+ 0x4C, 0x8D, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41,
+ 0x03, 0x46, 0xA0, 0xF5, 0x10, 0x77, 0x00, 0x24, 0x01, 0x25, 0x19, 0x4E,
+ 0x19, 0x48, 0x06, 0x2F, 0x0B, 0xD2, 0xDF, 0xE8, 0x07, 0xF0, 0x03, 0x11,
+ 0x17, 0x1C, 0x21, 0x26, 0x01, 0x29, 0x04, 0xD1, 0x11, 0x78, 0x03, 0x29,
+ 0x01, 0xD8, 0xB1, 0x70, 0x0A, 0xE0, 0x03, 0x24, 0x01, 0x22, 0x12, 0x49,
+ 0x12, 0x48, 0xE3, 0xF7, 0x9C, 0xDB, 0x18, 0xE0, 0x01, 0x29, 0xF6, 0xD1,
+ 0x11, 0x78, 0x01, 0x70, 0x45, 0x70, 0x12, 0xE0, 0x02, 0x29, 0xF0, 0xD1,
+ 0x11, 0x88, 0x41, 0x80, 0xF8, 0xE7, 0x02, 0x29, 0xEB, 0xD1, 0x11, 0x88,
+ 0x81, 0x80, 0xF3, 0xE7, 0x01, 0x29, 0xE6, 0xD1, 0x11, 0x78, 0x31, 0x70,
+ 0xEE, 0xE7, 0x01, 0x29, 0xE1, 0xD1, 0x10, 0x78, 0x70, 0x70, 0x20, 0x46,
+ 0xBD, 0xE8, 0xF0, 0x81, 0x63, 0x79, 0x20, 0x00, 0xB0, 0x74, 0x20, 0x00,
+ 0x2C, 0x83, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x38, 0xB5, 0x16, 0x4D,
+ 0x02, 0x24, 0x28, 0x78, 0x10, 0xF0, 0x30, 0x0F, 0x08, 0xD0, 0xC0, 0xF3,
+ 0x01, 0x13, 0x01, 0x22, 0x12, 0x49, 0x13, 0x48, 0xE3, 0xF7, 0x69, 0xDB,
+ 0x20, 0x46, 0x38, 0xBD, 0x11, 0x48, 0x12, 0x49, 0x42, 0x78, 0x92, 0xB1,
+ 0x8A, 0x78, 0x00, 0x92, 0x0B, 0x78, 0x82, 0x88, 0x41, 0x88, 0x00, 0x78,
+ 0xF0, 0xF7, 0x4E, 0xF8, 0x0D, 0xE0, 0x28, 0x78, 0x00, 0x24, 0x20, 0xF0,
+ 0x30, 0x00, 0x10, 0x30, 0x28, 0x70, 0x20, 0x46, 0xF2, 0xF7, 0xDA, 0xFE,
+ 0xE6, 0xE7, 0x49, 0x78, 0x01, 0x20, 0xF0, 0xF7, 0x56, 0xF8, 0x00, 0x28,
+ 0xEF, 0xD1, 0xDF, 0xE7, 0x38, 0x78, 0x20, 0x00, 0x84, 0x83, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0xB0, 0x74, 0x20, 0x00, 0x63, 0x79, 0x20, 0x00,
+ 0x70, 0xB5, 0x0F, 0x4D, 0x02, 0x24, 0x28, 0x78, 0xC0, 0xF3, 0x01, 0x13,
+ 0x02, 0x2B, 0x06, 0xD0, 0x01, 0x22, 0x0C, 0x49, 0x0C, 0x48, 0xE3, 0xF7,
+ 0x32, 0xDB, 0x20, 0x46, 0x70, 0xBD, 0x0B, 0x48, 0x41, 0x78, 0x00, 0x20,
+ 0xF0, 0xF7, 0x35, 0xF8, 0x00, 0x28, 0xF6, 0xD0, 0x28, 0x78, 0x00, 0x24,
+ 0x40, 0xF0, 0x30, 0x00, 0x28, 0x70, 0x20, 0x46, 0xF2, 0xF7, 0xAA, 0xFE,
+ 0xED, 0xE7, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, 0xA8, 0x83, 0xC0, 0x08,
+ 0x00, 0x35, 0x10, 0x21, 0x63, 0x79, 0x20, 0x00, 0x04, 0x4A, 0x10, 0xB5,
+ 0x02, 0xEB, 0x00, 0x10, 0x10, 0x22, 0x15, 0xF4, 0x24, 0xF4, 0x00, 0x20,
+ 0x10, 0xBD, 0x00, 0x00, 0x6E, 0x78, 0x20, 0x00, 0x7C, 0xB5, 0x0E, 0x46,
+ 0x04, 0x46, 0x01, 0x46, 0x15, 0x46, 0x12, 0x48, 0xFE, 0xF7, 0x5A, 0xFF,
+ 0xE8, 0xB1, 0x11, 0x49, 0x04, 0xEB, 0x44, 0x00, 0x6A, 0x46, 0x09, 0x68,
+ 0x01, 0xEB, 0x00, 0x10, 0x0C, 0x21, 0x00, 0x8A, 0x8D, 0xF8, 0x00, 0x10,
+ 0x8D, 0xF8, 0x01, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x02, 0x00, 0x8D, 0xF8,
+ 0x03, 0x60, 0x8D, 0xF8, 0x04, 0x50, 0x05, 0x21, 0x4F, 0xF6, 0x80, 0x50,
+ 0xF0, 0xF7, 0x5E, 0xFC, 0x08, 0xB1, 0x00, 0x20, 0x7C, 0xBD, 0x07, 0x20,
+ 0x7C, 0xBD, 0x04, 0x20, 0x7C, 0xBD, 0x00, 0x00, 0xF1, 0xB1, 0x82, 0x00,
+ 0x64, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x0E, 0x46, 0x04, 0x46, 0x01, 0x46,
+ 0x15, 0x46, 0x09, 0x48, 0xFE, 0xF7, 0x2C, 0xFF, 0x60, 0xB1, 0x08, 0x49,
+ 0x04, 0xEB, 0x44, 0x00, 0x2A, 0x46, 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10,
+ 0x31, 0x46, 0x00, 0x8A, 0xF0, 0xF7, 0x7B, 0xF8, 0x00, 0x20, 0x70, 0xBD,
+ 0x04, 0x20, 0x70, 0xBD, 0xA9, 0xB1, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00,
+ 0x2D, 0xE9, 0xFE, 0x43, 0x88, 0x46, 0x33, 0x4D, 0x00, 0x21, 0x11, 0x70,
+ 0x29, 0x88, 0x32, 0x4E, 0x17, 0x46, 0x88, 0x42, 0x02, 0xD0, 0x00, 0x22,
+ 0x30, 0x49, 0x48, 0xE0, 0xD8, 0xF8, 0x00, 0x10, 0x01, 0x91, 0xD8, 0xF8,
+ 0x04, 0x00, 0x02, 0x90, 0x9D, 0xF8, 0x0A, 0x10, 0x01, 0xA8, 0xFD, 0xF7,
+ 0x99, 0xFF, 0x04, 0x00, 0x06, 0xD1, 0x9D, 0xF8, 0x0A, 0x10, 0x01, 0xA8,
+ 0xFD, 0xF7, 0x20, 0xFF, 0x04, 0x00, 0x08, 0xD0, 0x01, 0x20, 0x25, 0x49,
+ 0x38, 0x70, 0x00, 0x22, 0x34, 0x31, 0x30, 0x46, 0xE3, 0xF7, 0x97, 0xDA,
+ 0x38, 0xE0, 0x9D, 0xF8, 0x0B, 0x00, 0x00, 0x27, 0x40, 0x07, 0x00, 0xD5,
+ 0x01, 0x27, 0x9D, 0xF8, 0x0A, 0x10, 0x3A, 0x46, 0x01, 0xA8, 0xFB, 0xF7,
+ 0x9F, 0xFE, 0x04, 0x00, 0x0C, 0xD1, 0xFE, 0xF7, 0x0D, 0xFB, 0x48, 0xB3,
+ 0xFC, 0xF7, 0xDC, 0xFF, 0x9D, 0xF8, 0x0A, 0x10, 0x3A, 0x46, 0x01, 0xA8,
+ 0xFB, 0xF7, 0x92, 0xFE, 0x04, 0x00, 0x1F, 0xD0, 0x60, 0x78, 0x00, 0x90,
+ 0x13, 0x48, 0x14, 0x49, 0x2A, 0x88, 0x00, 0x88, 0x09, 0x88, 0xD3, 0xB2,
+ 0x08, 0x44, 0x81, 0xB2, 0x40, 0x46, 0xF9, 0xF7, 0x3C, 0xF9, 0x40, 0xB1,
+ 0x0C, 0x49, 0x00, 0x22, 0x64, 0x31, 0x30, 0x46, 0xE3, 0xF7, 0x67, 0xDA,
+ 0x00, 0x20, 0xBD, 0xE8, 0xFE, 0x83, 0x61, 0x78, 0x01, 0x20, 0xEA, 0xF7,
+ 0x3D, 0xFE, 0x20, 0x46, 0xFE, 0xF7, 0xA2, 0xFD, 0x20, 0x46, 0xF4, 0xE7,
+ 0x03, 0x49, 0x00, 0x22, 0xA4, 0x31, 0xEC, 0xE7, 0xEE, 0x78, 0x20, 0x00,
+ 0x00, 0x35, 0x10, 0x21, 0x90, 0x74, 0xC0, 0x08, 0xF0, 0x78, 0x20, 0x00,
+ 0xE0, 0x78, 0x20, 0x00, 0x02, 0x48, 0x01, 0x89, 0x41, 0xF0, 0x08, 0x01,
+ 0x01, 0x81, 0x70, 0x47, 0x50, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x41,
+ 0x0C, 0x46, 0x46, 0x49, 0x03, 0x46, 0xA0, 0xF2, 0x21, 0x2C, 0x16, 0x46,
+ 0x08, 0x89, 0x00, 0x25, 0x41, 0x4A, 0x40, 0xF0, 0x40, 0x07, 0xBC, 0xF1,
+ 0x0F, 0x0F, 0x12, 0xD2, 0xDF, 0xE8, 0x0C, 0xF0, 0x08, 0x2C, 0x18, 0x23,
+ 0x11, 0x11, 0x11, 0x3E, 0x45, 0x4C, 0x54, 0x5B, 0x72, 0x66, 0x6B, 0x00,
+ 0x02, 0x2C, 0x06, 0xD1, 0x30, 0x88, 0x50, 0x81, 0x37, 0x4A, 0x02, 0x21,
+ 0x0A, 0x32, 0x01, 0x20, 0x29, 0xE0, 0x03, 0x25, 0x01, 0x22, 0x36, 0x49,
+ 0x36, 0x48, 0xE3, 0xF7, 0x1C, 0xDA, 0x56, 0xE0, 0x01, 0x2C, 0xF6, 0xD1,
+ 0x30, 0x78, 0x01, 0x28, 0xF3, 0xD8, 0xD0, 0x70, 0x00, 0xB1, 0x01, 0x20,
+ 0xEE, 0xF7, 0x59, 0xFF, 0x4B, 0xE0, 0x06, 0x2C, 0xEB, 0xD1, 0x33, 0x68,
+ 0x53, 0x61, 0xB3, 0x88, 0x13, 0x83, 0x40, 0xF0, 0x20, 0x00, 0x37, 0xE0,
+ 0x28, 0x2C, 0x00, 0xD3, 0x27, 0x24, 0x27, 0x48, 0x22, 0x46, 0x31, 0x46,
+ 0x0A, 0x30, 0x15, 0xF4, 0x12, 0xF3, 0x24, 0x49, 0x00, 0x20, 0x0A, 0x31,
+ 0x0A, 0x46, 0x08, 0x55, 0x28, 0x21, 0xF3, 0xF7, 0x05, 0xF8, 0x30, 0xE0,
+ 0x01, 0x2C, 0xD0, 0xD1, 0x30, 0x78, 0x01, 0x28, 0xCD, 0xD8, 0x10, 0x71,
+ 0x29, 0xE0, 0x01, 0x2C, 0xC9, 0xD1, 0x30, 0x78, 0x03, 0x28, 0xC6, 0xD8,
+ 0x90, 0x71, 0x05, 0xE0, 0x01, 0x2C, 0xC2, 0xD1, 0x30, 0x78, 0x07, 0x28,
+ 0xBF, 0xD8, 0xD0, 0x71, 0x0F, 0x81, 0x1A, 0xE0, 0x01, 0x2C, 0xBA, 0xD1,
+ 0x30, 0x78, 0x07, 0x28, 0xB7, 0xD8, 0x10, 0x72, 0xF6, 0xE7, 0x01, 0x2C,
+ 0xB3, 0xD1, 0x34, 0x78, 0x01, 0x2C, 0xB0, 0xD8, 0x54, 0x72, 0x0C, 0xD1,
+ 0x40, 0xF0, 0x80, 0x00, 0x08, 0x81, 0x08, 0xE0, 0x02, 0x2C, 0xA8, 0xD1,
+ 0x30, 0x88, 0x88, 0x80, 0x03, 0xE0, 0x02, 0x2C, 0xA3, 0xD1, 0x30, 0x88,
+ 0xC8, 0x80, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x01, 0x2C, 0x9C, 0xD1,
+ 0x32, 0x78, 0x07, 0x2A, 0x99, 0xD8, 0x8A, 0x70, 0x40, 0xF4, 0x80, 0x70,
+ 0xE8, 0xE7, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, 0x50, 0x74, 0x20, 0x00,
+ 0xE0, 0x5D, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0xFD, 0xF7,
+ 0x9D, 0xFE, 0x00, 0x28, 0x05, 0xD0, 0x41, 0x78, 0xBD, 0xE8, 0x10, 0x40,
+ 0x01, 0x20, 0xEA, 0xF7, 0x6F, 0xBE, 0x10, 0xBD, 0x10, 0xB5, 0xEF, 0xF7,
+ 0x41, 0xFF, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD,
+ 0x2D, 0xE9, 0xF8, 0x43, 0x88, 0x46, 0x04, 0x46, 0x01, 0x46, 0x1D, 0x46,
+ 0x16, 0x46, 0x0B, 0x48, 0x08, 0x9F, 0xFE, 0xF7, 0xE7, 0xFD, 0x78, 0xB1,
+ 0x09, 0x49, 0x00, 0x97, 0x04, 0xEB, 0x44, 0x00, 0x49, 0x68, 0x2B, 0x46,
+ 0x01, 0xEB, 0x00, 0x10, 0x32, 0x46, 0x00, 0x8A, 0x41, 0x46, 0xEF, 0xF7,
+ 0x7B, 0xFF, 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x83, 0x04, 0x20, 0xFB, 0xE7,
+ 0x51, 0xB2, 0x82, 0x00, 0x60, 0x78, 0x20, 0x00, 0x3E, 0xB5, 0x0D, 0x46,
+ 0x04, 0x00, 0x31, 0xD0, 0x20, 0x78, 0x01, 0x28, 0x2E, 0xD1, 0x28, 0x78,
+ 0xAA, 0x78, 0x69, 0x78, 0x8D, 0xE8, 0x07, 0x00, 0x63, 0x78, 0x04, 0x22,
+ 0x15, 0x49, 0x16, 0x48, 0xE3, 0xF7, 0x67, 0xD9, 0x28, 0x78, 0x01, 0x28,
+ 0xE0, 0x7B, 0x09, 0xD0, 0x20, 0xF0, 0x10, 0x00, 0xE0, 0x73, 0x68, 0x78,
+ 0x00, 0x28, 0xE0, 0x7B, 0x05, 0xD0, 0x40, 0xF0, 0x20, 0x00, 0x04, 0xE0,
+ 0x40, 0xF0, 0x10, 0x00, 0xF4, 0xE7, 0x20, 0xF0, 0x20, 0x00, 0xE0, 0x73,
+ 0xA8, 0x78, 0x00, 0x28, 0xE0, 0x7B, 0x02, 0xD0, 0x40, 0xF0, 0x40, 0x00,
+ 0x01, 0xE0, 0x20, 0xF0, 0x40, 0x00, 0xE0, 0x73, 0x61, 0x78, 0x04, 0xF1,
+ 0x08, 0x00, 0xF1, 0xF7, 0xA3, 0xFF, 0x08, 0xB1, 0x00, 0x20, 0x3E, 0xBD,
+ 0x01, 0x20, 0x3E, 0xBD, 0x1C, 0x73, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21,
+ 0x70, 0xB5, 0x04, 0x46, 0x00, 0x25, 0xEF, 0xF7, 0x71, 0xFF, 0x28, 0xB1,
+ 0x04, 0x48, 0x21, 0x68, 0x41, 0x61, 0xA1, 0x88, 0x01, 0x83, 0x00, 0xE0,
+ 0x07, 0x25, 0x28, 0x46, 0x70, 0xBD, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00,
+ 0x2D, 0xE9, 0xFE, 0x4F, 0x8A, 0x46, 0xDD, 0xE9, 0x0D, 0x65, 0x04, 0x46,
+ 0x01, 0x46, 0x98, 0x46, 0x91, 0x46, 0x0C, 0x48, 0x0C, 0x9F, 0xFE, 0xF7,
+ 0x73, 0xFD, 0x88, 0xB1, 0x00, 0x97, 0x0A, 0x49, 0xCD, 0xE9, 0x01, 0x65,
+ 0x49, 0x68, 0x04, 0xEB, 0x44, 0x00, 0x01, 0xEB, 0x00, 0x10, 0x43, 0x46,
+ 0x00, 0x8A, 0x4A, 0x46, 0x51, 0x46, 0xEE, 0xF7, 0xBC, 0xFF, 0x00, 0x20,
+ 0xBD, 0xE8, 0xFE, 0x8F, 0x04, 0x20, 0xFB, 0xE7, 0x3C, 0xB2, 0x82, 0x00,
+ 0x60, 0x78, 0x20, 0x00, 0x30, 0xB5, 0x04, 0x46, 0x80, 0x78, 0x87, 0xB0,
+ 0x0D, 0x46, 0xC0, 0x06, 0x0B, 0xD5, 0x61, 0x78, 0x68, 0x46, 0xF1, 0xF7,
+ 0x41, 0xFD, 0x04, 0x98, 0xA8, 0x42, 0x07, 0xD0, 0x60, 0x78, 0x29, 0x46,
+ 0xF2, 0xF7, 0x40, 0xF8, 0x10, 0xB1, 0x00, 0x20, 0x07, 0xB0, 0x30, 0xBD,
+ 0x01, 0x20, 0xFB, 0xE7, 0x08, 0xB5, 0x02, 0x21, 0x8D, 0xF8, 0x00, 0x10,
+ 0x00, 0xB1, 0x01, 0x20, 0x8D, 0xF8, 0x01, 0x00, 0x6A, 0x46, 0x02, 0x21,
+ 0x4F, 0xF6, 0x80, 0x50, 0xF0, 0xF7, 0x52, 0xFA, 0x08, 0xB1, 0x00, 0x20,
+ 0x08, 0xBD, 0x07, 0x20, 0x08, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xFC, 0x41,
+ 0x1E, 0x46, 0x17, 0x46, 0x04, 0x00, 0x0D, 0x46, 0x24, 0xD0, 0x13, 0x48,
+ 0xE3, 0xF7, 0x9C, 0xDA, 0xCD, 0xE9, 0x00, 0x07, 0x63, 0x78, 0x03, 0x22,
+ 0x10, 0x49, 0x11, 0x48, 0xE3, 0xF7, 0xC5, 0xD8, 0xA7, 0x73, 0x28, 0x68,
+ 0xA0, 0x60, 0xA8, 0x88, 0xA0, 0x81, 0x6E, 0xB1, 0x01, 0x20, 0x20, 0x71,
+ 0xE0, 0x7B, 0x40, 0xF0, 0x04, 0x00, 0xE0, 0x73, 0x61, 0x78, 0x04, 0xF1,
+ 0x08, 0x00, 0xF1, 0xF7, 0x13, 0xFF, 0x01, 0x20, 0xBD, 0xE8, 0xFC, 0x81,
+ 0x00, 0x20, 0x20, 0x71, 0xE0, 0x7B, 0x20, 0xF0, 0x04, 0x00, 0xF0, 0xE7,
+ 0x00, 0x20, 0xF5, 0xE7, 0x00, 0x00, 0x30, 0x21, 0x9C, 0x70, 0xC0, 0x08,
+ 0x02, 0x35, 0x10, 0x21, 0x30, 0xB5, 0x04, 0x46, 0x80, 0x78, 0x87, 0xB0,
+ 0x0D, 0x46, 0x80, 0x06, 0x0B, 0xD5, 0x61, 0x78, 0x68, 0x46, 0xF1, 0xF7,
+ 0x5F, 0xFD, 0x04, 0x98, 0xA8, 0x42, 0x07, 0xD0, 0x60, 0x78, 0x29, 0x46,
+ 0xF2, 0xF7, 0x0E, 0xF8, 0x10, 0xB1, 0x00, 0x20, 0x07, 0xB0, 0x30, 0xBD,
+ 0x01, 0x20, 0xFB, 0xE7, 0x1C, 0xB5, 0x03, 0x24, 0x8D, 0xF8, 0x00, 0x40,
+ 0x8D, 0xF8, 0x01, 0x00, 0x8D, 0xF8, 0x02, 0x10, 0x0C, 0x0A, 0x8D, 0xF8,
+ 0x03, 0x40, 0x14, 0x0A, 0x06, 0x23, 0x8D, 0xF8, 0x04, 0x20, 0x08, 0x43,
+ 0x8D, 0xF8, 0x05, 0x40, 0x10, 0x43, 0x00, 0xD1, 0x01, 0x23, 0x6A, 0x46,
+ 0x19, 0x46, 0x4F, 0xF6, 0x80, 0x50, 0xF0, 0xF7, 0xE5, 0xF9, 0x08, 0xB1,
+ 0x00, 0x20, 0x1C, 0xBD, 0x07, 0x20, 0x1C, 0xBD, 0x08, 0xB5, 0x09, 0x21,
+ 0x8D, 0xF8, 0x00, 0x10, 0x8D, 0xF8, 0x01, 0x00, 0x6A, 0x46, 0x02, 0x21,
+ 0x4F, 0xF6, 0x80, 0x50, 0xF0, 0xF7, 0xD4, 0xF9, 0x08, 0xB1, 0x00, 0x20,
+ 0x08, 0xBD, 0x07, 0x20, 0x08, 0xBD, 0x10, 0xB5, 0xEF, 0xF7, 0x2A, 0xFF,
+ 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, 0xFE, 0xB5,
+ 0x00, 0x26, 0xDD, 0xE9, 0x08, 0x45, 0x8D, 0xE8, 0x70, 0x00, 0x00, 0xF0,
+ 0x0B, 0xF8, 0xFE, 0xBD, 0xFE, 0xB5, 0x08, 0xAF, 0x97, 0xE8, 0x70, 0x00,
+ 0x8D, 0xE8, 0x70, 0x00, 0x00, 0xF0, 0x02, 0xF8, 0xFE, 0xBD, 0x00, 0x00,
+ 0x2D, 0xE9, 0xF8, 0x4F, 0x1F, 0x46, 0x0A, 0xAB, 0x2A, 0x4E, 0x93, 0xE8,
+ 0x00, 0x07, 0x96, 0xF8, 0x00, 0xC0, 0x80, 0xF8, 0x00, 0xC0, 0x33, 0x78,
+ 0xB4, 0x78, 0x01, 0x25, 0x26, 0x48, 0xA3, 0x42, 0x05, 0xD3, 0x02, 0x22,
+ 0x25, 0x49, 0x00, 0x94, 0xE3, 0xF7, 0x29, 0xD8, 0x06, 0xE0, 0xF4, 0x78,
+ 0x3C, 0xB1, 0x22, 0x49, 0x00, 0x22, 0x4C, 0x31, 0xE3, 0xF7, 0x21, 0xD8,
+ 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x8F, 0x70, 0x68, 0xC3, 0xEB, 0xC3, 0x03,
+ 0x00, 0xEB, 0x83, 0x03, 0x83, 0xF8, 0x01, 0xC0, 0x33, 0x78, 0xC3, 0xEB,
+ 0xC3, 0x03, 0x00, 0xEB, 0x83, 0x03, 0x99, 0x60, 0x31, 0x78, 0xC1, 0xEB,
+ 0xC1, 0x01, 0x00, 0xEB, 0x81, 0x01, 0x4A, 0x80, 0x31, 0x78, 0xC1, 0xEB,
+ 0xC1, 0x01, 0x00, 0xEB, 0x81, 0x01, 0x10, 0x31, 0x81, 0xE8, 0x80, 0x03,
+ 0x31, 0x78, 0xC1, 0xEB, 0xC1, 0x01, 0x00, 0xEB, 0x81, 0x00, 0xA0, 0xF8,
+ 0x04, 0xA0, 0x30, 0x78, 0x40, 0x1C, 0x30, 0x70, 0x0C, 0x48, 0x00, 0x78,
+ 0xC0, 0x07, 0x0D, 0xD0, 0x09, 0x49, 0x08, 0x48, 0x00, 0x22, 0x8C, 0x31,
+ 0x80, 0x1C, 0xE2, 0xF7, 0xEE, 0xDF, 0x00, 0xF0, 0x1B, 0xFC, 0x10, 0xB1,
+ 0x01, 0x20, 0xF0, 0x70, 0x00, 0xE0, 0x00, 0x25, 0x28, 0x46, 0xC4, 0xE7,
+ 0xB0, 0x78, 0x20, 0x00, 0x00, 0x33, 0x10, 0x21, 0x18, 0x6A, 0xC0, 0x08,
+ 0x38, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xFE, 0x4F, 0x81, 0x46, 0xDD, 0xE9,
+ 0x0C, 0x67, 0x21, 0x48, 0x0C, 0x46, 0x9B, 0x46, 0x05, 0x88, 0x92, 0x46,
+ 0x49, 0x46, 0x1F, 0x48, 0xFE, 0xF7, 0x26, 0xFC, 0x00, 0x28, 0x29, 0xD0,
+ 0x1D, 0x49, 0xC4, 0xEB, 0xC4, 0x00, 0x49, 0x68, 0x01, 0xEB, 0x80, 0x08,
+ 0x6F, 0xB9, 0x29, 0x46, 0x30, 0x46, 0xEC, 0xF7, 0x63, 0xFE, 0x04, 0x00,
+ 0x05, 0xD0, 0x60, 0x19, 0x32, 0x46, 0x59, 0x46, 0x15, 0xF4, 0xCF, 0xF0,
+ 0x03, 0xE0, 0x40, 0xF2, 0x11, 0x47, 0x00, 0x24, 0x26, 0x46, 0xCD, 0xF8,
+ 0x00, 0xA0, 0xCD, 0xE9, 0x01, 0x65, 0x11, 0x49, 0x09, 0xEB, 0x49, 0x00,
+ 0xD8, 0xF8, 0x0C, 0x20, 0x09, 0x68, 0x3B, 0x46, 0x01, 0xEB, 0x00, 0x10,
+ 0x01, 0x8A, 0x20, 0x46, 0xEC, 0xF7, 0x20, 0xF8, 0x10, 0xB1, 0x01, 0x20,
+ 0xBD, 0xE8, 0xFE, 0x8F, 0x00, 0x22, 0x09, 0x49, 0x09, 0x48, 0xE2, 0xF7,
+ 0x9C, 0xDF, 0x14, 0xB1, 0x20, 0x46, 0xEB, 0xF7, 0x1D, 0xFE, 0x00, 0x20,
+ 0xF2, 0xE7, 0x00, 0x00, 0x46, 0x78, 0x20, 0x00, 0x17, 0xB3, 0x82, 0x00,
+ 0xB0, 0x78, 0x20, 0x00, 0x64, 0x78, 0x20, 0x00, 0xD0, 0x6A, 0xC0, 0x08,
+ 0x00, 0x33, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, 0xC1, 0xEB,
+ 0xC1, 0x00, 0x0F, 0x49, 0x1E, 0x46, 0x90, 0x46, 0x49, 0x68, 0x00, 0x25,
+ 0x01, 0xEB, 0x80, 0x07, 0x21, 0x46, 0x0C, 0x48, 0xFE, 0xF7, 0xD0, 0xFB,
+ 0x00, 0x28, 0x0E, 0xD0, 0x0A, 0x4A, 0x04, 0xEB, 0x44, 0x00, 0xF9, 0x68,
+ 0x12, 0x68, 0x43, 0x46, 0x02, 0xEB, 0x00, 0x10, 0x32, 0x46, 0x00, 0x8A,
+ 0xEC, 0xF7, 0xCE, 0xF9, 0x00, 0xB1, 0x01, 0x25, 0x28, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x81, 0x00, 0x00, 0xB0, 0x78, 0x20, 0x00, 0x30, 0xB3, 0x82, 0x00,
+ 0x64, 0x78, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x22, 0x03, 0x49,
+ 0x03, 0x48, 0xE2, 0xF7, 0x58, 0xDF, 0x03, 0x48, 0x04, 0x70, 0x10, 0xBD,
+ 0xD0, 0x69, 0xC0, 0x08, 0x02, 0x33, 0x10, 0x21, 0x82, 0x74, 0x20, 0x00,
+ 0x10, 0xB5, 0x04, 0x46, 0x01, 0x46, 0x09, 0x48, 0xFE, 0xF7, 0xA0, 0xFB,
+ 0x00, 0x28, 0x0B, 0xD0, 0x07, 0x49, 0x04, 0xEB, 0x44, 0x00, 0x00, 0x22,
+ 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x11, 0x46, 0x00, 0x8A, 0xEB, 0xF7,
+ 0xF3, 0xFE, 0x01, 0x20, 0x10, 0xBD, 0x00, 0x00, 0x4A, 0xB3, 0x82, 0x00,
+ 0x64, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x0B, 0x49, 0x05, 0x46, 0x00, 0x24,
+ 0x49, 0x68, 0xC0, 0xEB, 0xC5, 0x00, 0x11, 0xEB, 0x80, 0x00, 0x03, 0xD0,
+ 0xC0, 0x68, 0xEC, 0xF7, 0xC7, 0xFD, 0x04, 0x46, 0x2B, 0x46, 0x02, 0x22,
+ 0x04, 0x49, 0x05, 0x48, 0x00, 0x94, 0xE2, 0xF7, 0x20, 0xDF, 0x20, 0x46,
+ 0x38, 0xBD, 0x00, 0x00, 0xB0, 0x78, 0x20, 0x00, 0x58, 0x6B, 0xC0, 0x08,
+ 0x02, 0x33, 0x10, 0x21, 0x70, 0xB5, 0x0E, 0x46, 0x04, 0x46, 0x01, 0x46,
+ 0x15, 0x46, 0x0A, 0x48, 0xFE, 0xF7, 0x66, 0xFB, 0x00, 0x28, 0x0D, 0xD0,
+ 0x08, 0x49, 0x04, 0xEB, 0x44, 0x00, 0x0A, 0x68, 0x02, 0xEB, 0x00, 0x12,
+ 0x52, 0x6A, 0x32, 0x60, 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x40, 0x8C,
+ 0x28, 0x80, 0x01, 0x20, 0x70, 0xBD, 0x00, 0x00, 0x75, 0xB3, 0x82, 0x00,
+ 0x64, 0x78, 0x20, 0x00, 0x10, 0xB5, 0x41, 0x88, 0x01, 0x24, 0xB1, 0xF5,
+ 0x86, 0x7F, 0x2F, 0xD0, 0x09, 0xDC, 0xA1, 0xF2, 0x03, 0x11, 0x08, 0x29,
+ 0x31, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, 0x11, 0x30, 0x15, 0x19, 0x30, 0x1D,
+ 0x30, 0x21, 0xB1, 0xF5, 0x87, 0x7F, 0x25, 0xD0, 0xB1, 0xF5, 0x88, 0x7F,
+ 0x16, 0xD0, 0xA1, 0xF5, 0x80, 0x71, 0x11, 0x39, 0x16, 0xD0, 0xA6, 0x29,
+ 0x1F, 0xD1, 0x0F, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x91, 0xFA, 0x1A, 0xE0,
+ 0x00, 0x1D, 0x00, 0xF0, 0x77, 0xF9, 0x16, 0xE0, 0x00, 0x1D, 0x00, 0xF0,
+ 0xB1, 0xF9, 0x12, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x0F, 0xF9, 0x0E, 0xE0,
+ 0x00, 0xF0, 0xCC, 0xF9, 0x04, 0x46, 0x0A, 0xE0, 0x00, 0x1D, 0x00, 0xF0,
+ 0x45, 0xFA, 0x06, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x75, 0xF8, 0x02, 0xE0,
+ 0x00, 0x1D, 0x00, 0xF0, 0x03, 0xF8, 0x20, 0x46, 0x10, 0xBD, 0x00, 0x00,
+ 0x2D, 0xE9, 0xFF, 0x47, 0x00, 0x26, 0x80, 0x46, 0x03, 0x96, 0xB1, 0x46,
+ 0xB2, 0x46, 0x34, 0x46, 0x37, 0x46, 0x00, 0x88, 0xFE, 0xF7, 0xA2, 0xFB,
+ 0x05, 0x00, 0x4F, 0xF4, 0x90, 0x61, 0x02, 0xD0, 0x68, 0x78, 0x02, 0x28,
+ 0x00, 0xD0, 0x0E, 0x46, 0x98, 0xF8, 0x02, 0x00, 0x08, 0xB1, 0x16, 0xB1,
+ 0x22, 0xE0, 0x00, 0x26, 0x2C, 0xE0, 0xE8, 0x6A, 0x48, 0xB3, 0x04, 0x46,
+ 0x40, 0x88, 0x18, 0xB1, 0x06, 0x46, 0xB4, 0xF8, 0x06, 0x90, 0x17, 0xE0,
+ 0x21, 0x49, 0x20, 0x78, 0x49, 0x68, 0xC0, 0xEB, 0xC0, 0x00, 0x01, 0xEB,
+ 0x80, 0x07, 0xD7, 0xF8, 0x14, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, 0x17, 0xD0,
+ 0x20, 0x89, 0x03, 0xAA, 0x04, 0xF1, 0x0A, 0x01, 0x8D, 0xE8, 0x07, 0x00,
+ 0xA2, 0x88, 0x79, 0x78, 0xE8, 0x78, 0x03, 0x23, 0xE0, 0x47, 0x06, 0x46,
+ 0xA6, 0xF5, 0x50, 0x60, 0x01, 0x38, 0x07, 0xD1, 0x00, 0x22, 0x14, 0x49,
+ 0x14, 0x48, 0xE2, 0xF7, 0x74, 0xDE, 0xBD, 0xE8, 0xFF, 0x87, 0x0E, 0x46,
+ 0xB8, 0xF8, 0x00, 0x00, 0x4A, 0x46, 0x31, 0x46, 0xEB, 0xF7, 0x22, 0xFE,
+ 0x03, 0x9E, 0x66, 0xB1, 0x00, 0x2D, 0xF2, 0xD0, 0x5F, 0xB1, 0x54, 0xB1,
+ 0x04, 0xF1, 0x0A, 0x00, 0x00, 0x90, 0x23, 0x89, 0xA2, 0x88, 0x79, 0x78,
+ 0xE8, 0x78, 0xB0, 0x47, 0x01, 0xE0, 0x00, 0x2D, 0xE5, 0xD0, 0xE8, 0x6A,
+ 0x00, 0x28, 0xE2, 0xD0, 0xED, 0xF7, 0x49, 0xDC, 0xC5, 0xF8, 0x2C, 0xA0,
+ 0xDD, 0xE7, 0x00, 0x00, 0xB0, 0x78, 0x20, 0x00, 0xC4, 0x6E, 0xC0, 0x08,
+ 0x02, 0x33, 0x10, 0x21, 0x2D, 0xE9, 0xFE, 0x4F, 0x04, 0x46, 0x41, 0x48,
+ 0x21, 0x8A, 0x67, 0x89, 0x06, 0x88, 0x04, 0xF1, 0x12, 0x00, 0x08, 0x44,
+ 0x00, 0x90, 0x4F, 0xF0, 0x00, 0x0A, 0x20, 0x88, 0xFE, 0xF7, 0x30, 0xFB,
+ 0x80, 0x46, 0x60, 0x68, 0x05, 0xF0, 0x50, 0xF8, 0x5F, 0xEA, 0x00, 0x09,
+ 0x40, 0xF2, 0x11, 0x4B, 0x45, 0xD0, 0xB8, 0xF1, 0x00, 0x0F, 0x42, 0xD0,
+ 0xD8, 0xF8, 0x2C, 0x50, 0x5D, 0xB1, 0x29, 0x78, 0x99, 0xF8, 0x01, 0x00,
+ 0x81, 0x42, 0x03, 0xD1, 0xA8, 0x88, 0x21, 0x89, 0x88, 0x42, 0x15, 0xD0,
+ 0x4F, 0xF4, 0x90, 0x60, 0x27, 0xE0, 0x40, 0xF2, 0x07, 0x43, 0x2D, 0x4A,
+ 0x40, 0xF2, 0x0A, 0x21, 0x00, 0x20, 0xED, 0xF7, 0xAD, 0xDB, 0xC8, 0xF8,
+ 0x2C, 0x00, 0x50, 0xB1, 0x99, 0xF8, 0x01, 0x10, 0x01, 0x70, 0x21, 0x89,
+ 0x81, 0x80, 0xA1, 0x89, 0x05, 0x46, 0xC1, 0x80, 0x68, 0x88, 0x20, 0xB1,
+ 0x1D, 0xE0, 0x00, 0x25, 0xDA, 0x46, 0x2F, 0x46, 0x26, 0xE0, 0xE0, 0x89,
+ 0x4F, 0xF4, 0x00, 0x72, 0x90, 0x42, 0x02, 0xD3, 0x40, 0xF2, 0x07, 0x40,
+ 0x05, 0xE0, 0x61, 0x89, 0x01, 0x44, 0x91, 0x42, 0x03, 0xD9, 0x40, 0xF2,
+ 0x0D, 0x40, 0x68, 0x80, 0x09, 0xE0, 0x05, 0xF1, 0x0A, 0x01, 0x08, 0x44,
+ 0x3A, 0x46, 0x00, 0x99, 0x14, 0xF4, 0x03, 0xF7, 0xE0, 0x89, 0x38, 0x44,
+ 0x28, 0x81, 0x76, 0x1D, 0xB6, 0xB2, 0x31, 0x46, 0x38, 0x46, 0xEC, 0xF7,
+ 0x87, 0xFC, 0x05, 0x00, 0xD9, 0xD0, 0xA8, 0x19, 0x3A, 0x46, 0x00, 0x99,
+ 0x14, 0xF4, 0xF3, 0xF6, 0x20, 0x89, 0xCD, 0xE9, 0x00, 0x07, 0x02, 0x96,
+ 0x21, 0x88, 0x53, 0x46, 0x28, 0x46, 0x62, 0x68, 0xEB, 0xF7, 0xD8, 0xFD,
+ 0x00, 0x28, 0x0B, 0xD1, 0x00, 0x22, 0x08, 0x49, 0x08, 0x48, 0xE2, 0xF7,
+ 0xCE, 0xDD, 0x00, 0x2D, 0x04, 0xD0, 0x28, 0x46, 0xBD, 0xE8, 0xFE, 0x4F,
+ 0xEB, 0xF7, 0x4C, 0xBC, 0xBD, 0xE8, 0xFE, 0x8F, 0x46, 0x78, 0x20, 0x00,
+ 0x96, 0xB3, 0x82, 0x00, 0x84, 0x6E, 0xC0, 0x08, 0x00, 0x33, 0x10, 0x21,
+ 0x2D, 0xE9, 0xF0, 0x41, 0x86, 0xB0, 0x04, 0x46, 0x4F, 0xF0, 0x00, 0x08,
+ 0x29, 0x48, 0xAD, 0xF8, 0x0C, 0x80, 0xCD, 0xF8, 0x10, 0x80, 0x07, 0x88,
+ 0x60, 0x68, 0x04, 0xF0, 0xC7, 0xFF, 0xC0, 0xB1, 0x04, 0xAA, 0x03, 0xA9,
+ 0xCD, 0xE9, 0x00, 0x12, 0x41, 0x78, 0x63, 0x89, 0x22, 0x89, 0x20, 0x88,
+ 0x04, 0xF0, 0xE4, 0xFF, 0xA0, 0xF5, 0x50, 0x61, 0x05, 0x46, 0x01, 0x39,
+ 0x01, 0xD0, 0x5D, 0xB1, 0x1A, 0xE0, 0x00, 0x22, 0x1C, 0x49, 0x1D, 0x48,
+ 0xE2, 0xF7, 0x97, 0xDD, 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x4F, 0xF4,
+ 0x90, 0x65, 0x0F, 0xE0, 0x39, 0x46, 0xBD, 0xF8, 0x0C, 0x00, 0xEC, 0xF7,
+ 0x2D, 0xFC, 0x06, 0x00, 0x06, 0xD0, 0xF0, 0x19, 0xBD, 0xF8, 0x0C, 0x20,
+ 0x04, 0x99, 0x14, 0xF4, 0x98, 0xF6, 0x04, 0xE0, 0x40, 0xF2, 0x11, 0x45,
+ 0x00, 0x26, 0xAD, 0xF8, 0x0C, 0x80, 0x20, 0x89, 0xBD, 0xF8, 0x0C, 0x10,
+ 0x8D, 0xE8, 0x83, 0x00, 0x21, 0x88, 0x2B, 0x46, 0x30, 0x46, 0x62, 0x68,
+ 0xEB, 0xF7, 0xEE, 0xFD, 0x00, 0x28, 0xD9, 0xD1, 0x07, 0x49, 0x08, 0x48,
+ 0x00, 0x22, 0x30, 0x31, 0x80, 0x1E, 0xE2, 0xF7, 0x6A, 0xDD, 0x00, 0x2E,
+ 0xD0, 0xD0, 0x30, 0x46, 0xEB, 0xF7, 0xEA, 0xFB, 0xCC, 0xE7, 0x00, 0x00,
+ 0x46, 0x78, 0x20, 0x00, 0x48, 0x6D, 0xC0, 0x08, 0x02, 0x33, 0x10, 0x21,
+ 0xF8, 0xB5, 0x04, 0x46, 0x00, 0x68, 0x04, 0xF0, 0x71, 0xFF, 0x19, 0x4E,
+ 0x05, 0x46, 0x30, 0x78, 0x40, 0x1C, 0x30, 0x70, 0x20, 0x89, 0xFE, 0xF7,
+ 0x45, 0xFA, 0xB8, 0xB1, 0xB5, 0xB1, 0xC7, 0x78, 0x30, 0x78, 0x00, 0x90,
+ 0x3B, 0x46, 0x02, 0x22, 0x12, 0x49, 0x13, 0x48, 0xE2, 0xF7, 0x45, 0xDD,
+ 0xA3, 0x89, 0xB3, 0xB1, 0xA3, 0xF5, 0x40, 0x60, 0x0C, 0x38, 0x06, 0xD0,
+ 0x30, 0x78, 0x00, 0x90, 0x62, 0x89, 0x68, 0x78, 0x39, 0x46, 0x04, 0xF0,
+ 0xE9, 0xFF, 0xF8, 0xBD, 0x33, 0x78, 0x01, 0xB0, 0x08, 0x49, 0xBD, 0xE8,
+ 0xF0, 0x40, 0x08, 0x48, 0x01, 0x22, 0x44, 0x39, 0xC0, 0x1E, 0xE2, 0xF7,
+ 0x2C, 0x9D, 0x30, 0x78, 0x00, 0x90, 0x62, 0x89, 0x68, 0x78, 0x00, 0x23,
+ 0xEA, 0xE7, 0x00, 0x00, 0x60, 0x78, 0x20, 0x00, 0x04, 0x6D, 0xC0, 0x08,
+ 0x03, 0x33, 0x10, 0x21, 0xF8, 0xB5, 0x04, 0x46, 0x00, 0x68, 0x04, 0xF0,
+ 0x33, 0xFF, 0x06, 0x46, 0x20, 0x89, 0xFE, 0xF7, 0x0B, 0xFA, 0xD4, 0xE9,
+ 0x00, 0x12, 0x05, 0x46, 0x63, 0x89, 0x20, 0x89, 0xEB, 0xF7, 0xF1, 0xFE,
+ 0x00, 0x2D, 0x0C, 0xD0, 0x00, 0x2E, 0x0A, 0xD0, 0x05, 0x48, 0xA3, 0x89,
+ 0x00, 0x78, 0x00, 0x90, 0x62, 0x89, 0xE9, 0x78, 0x70, 0x78, 0x03, 0xB9,
+ 0x00, 0x23, 0x04, 0xF0, 0xB1, 0xFF, 0xF8, 0xBD, 0x60, 0x78, 0x20, 0x00,
+ 0x2D, 0xE9, 0xF0, 0x4F, 0x89, 0xB0, 0x04, 0x46, 0xB0, 0xF8, 0x02, 0x90,
+ 0x01, 0x1D, 0x14, 0x22, 0x03, 0xA8, 0x14, 0xF4, 0x4B, 0xF6, 0x00, 0x20,
+ 0x08, 0x90, 0x40, 0xF2, 0x04, 0x46, 0x4F, 0xF0, 0x01, 0x0A, 0x14, 0x22,
+ 0x21, 0x1D, 0x03, 0xA8, 0x14, 0xF4, 0x40, 0xF6, 0xA1, 0x8A, 0x04, 0xF1,
+ 0x16, 0x00, 0x01, 0xEB, 0x00, 0x08, 0x04, 0x98, 0x04, 0xF0, 0xF8, 0xFE,
+ 0x07, 0x46, 0xBD, 0xF8, 0x0C, 0x00, 0xFE, 0xF7, 0xCF, 0xF9, 0x05, 0x46,
+ 0x4F, 0xF4, 0x85, 0x7B, 0x27, 0xB1, 0x1D, 0xB1, 0xD9, 0x45, 0x04, 0xD1,
+ 0x00, 0x23, 0x07, 0xE0, 0x4F, 0xF4, 0x90, 0x66, 0x1E, 0xE0, 0xA9, 0xF5,
+ 0x80, 0x71, 0xB7, 0x39, 0x13, 0xD0, 0x01, 0x23, 0xA8, 0xEB, 0x04, 0x00,
+ 0x6C, 0x62, 0x68, 0x84, 0x7C, 0x69, 0x74, 0xB1, 0xBD, 0xF8, 0x16, 0x10,
+ 0x08, 0xAA, 0x00, 0x91, 0xCD, 0xE9, 0x01, 0x82, 0xBD, 0xF8, 0x14, 0x20,
+ 0x79, 0x78, 0xE8, 0x78, 0xA0, 0x47, 0x06, 0x46, 0x06, 0xE0, 0x02, 0x23,
+ 0xEA, 0xE7, 0x00, 0x22, 0x17, 0x49, 0x18, 0x48, 0xE2, 0xF7, 0xAF, 0xDC,
+ 0xD9, 0x45, 0x0C, 0xD1, 0xA6, 0xF5, 0x50, 0x60, 0x01, 0x38, 0x14, 0xD0,
+ 0xBD, 0xF8, 0x14, 0x30, 0xBD, 0xF8, 0x0C, 0x00, 0x32, 0x46, 0x04, 0x99,
+ 0xEB, 0xF7, 0x04, 0xFF, 0x0B, 0xE0, 0xA6, 0xF5, 0x50, 0x60, 0x05, 0x38,
+ 0x07, 0xD1, 0x0C, 0x49, 0x00, 0x22, 0x48, 0x31, 0x0B, 0x48, 0xE2, 0xF7,
+ 0x96, 0xDC, 0x4F, 0xF0, 0x00, 0x0A, 0x08, 0x9C, 0x4C, 0xB1, 0x45, 0xB1,
+ 0xCD, 0xF8, 0x00, 0x80, 0xBD, 0xF8, 0x16, 0x30, 0xBD, 0xF8, 0x14, 0x20,
+ 0x79, 0x78, 0xE8, 0x78, 0xA0, 0x47, 0x09, 0xB0, 0x50, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x8F, 0x00, 0x00, 0xB4, 0x6D, 0xC0, 0x08, 0x00, 0x33, 0x10, 0x21,
+ 0x2D, 0xE9, 0xFC, 0x47, 0x07, 0x46, 0x40, 0x68, 0x04, 0xF0, 0x92, 0xFE,
+ 0x05, 0x46, 0x38, 0x88, 0xFE, 0xF7, 0x6A, 0xF9, 0x80, 0x46, 0x00, 0x2D,
+ 0x24, 0xD0, 0xB8, 0xF1, 0x00, 0x0F, 0x21, 0xD0, 0x79, 0x89, 0x07, 0xF1,
+ 0x0C, 0x00, 0x0C, 0x18, 0x00, 0x26, 0x18, 0xE0, 0x34, 0xF8, 0x02, 0xAB,
+ 0x03, 0x22, 0x34, 0xF8, 0x02, 0x9B, 0x0C, 0x49, 0xCD, 0xE9, 0x00, 0xA9,
+ 0x6B, 0x78, 0x0B, 0x48, 0xE2, 0xF7, 0x5D, 0xDC, 0xD5, 0xF8, 0x18, 0xC0,
+ 0xBC, 0xF1, 0x00, 0x0F, 0x05, 0xD0, 0x69, 0x78, 0x98, 0xF8, 0x03, 0x00,
+ 0x4B, 0x46, 0x52, 0x46, 0xE0, 0x47, 0x76, 0x1C, 0xF6, 0xB2, 0x38, 0x89,
+ 0xB0, 0x42, 0xE3, 0xD8, 0xBD, 0xE8, 0xFC, 0x87, 0x44, 0x6E, 0xC0, 0x08,
+ 0x02, 0x33, 0x10, 0x21, 0x70, 0xB5, 0x1E, 0x4C, 0x06, 0x46, 0x00, 0x20,
+ 0xE1, 0x78, 0x01, 0xB1, 0x02, 0x20, 0x1B, 0x49, 0xB3, 0x88, 0x00, 0x25,
+ 0x4A, 0x78, 0x53, 0xB1, 0xE5, 0x70, 0x01, 0x21, 0x04, 0xF0, 0xD4, 0xFE,
+ 0x60, 0x78, 0x61, 0x68, 0xC0, 0xEB, 0xC0, 0x00, 0x01, 0xF8, 0x20, 0x50,
+ 0x70, 0xBD, 0x63, 0x68, 0xC2, 0xEB, 0xC2, 0x02, 0x03, 0xEB, 0x82, 0x02,
+ 0x31, 0x68, 0xD1, 0x60, 0x61, 0x78, 0x49, 0x1C, 0xC9, 0xB2, 0x61, 0x70,
+ 0xE2, 0x78, 0x42, 0xB1, 0xE5, 0x70, 0xB3, 0x88, 0xBD, 0xE8, 0x70, 0x40,
+ 0x49, 0x1E, 0xCA, 0xB2, 0x00, 0x21, 0x04, 0xF0, 0xB7, 0xBE, 0x22, 0x78,
+ 0x91, 0x42, 0x09, 0xD1, 0x49, 0x1E, 0xCA, 0xB2, 0xB3, 0x88, 0x00, 0x21,
+ 0x04, 0xF0, 0xAE, 0xFE, 0xBD, 0xE8, 0x70, 0x40, 0xF2, 0xF7, 0x2E, 0xB9,
+ 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, 0x38, 0xB8, 0xB0, 0x78, 0x20, 0x00,
+ 0x70, 0xB5, 0x04, 0x46, 0xEB, 0xF7, 0xC6, 0xFA, 0xC0, 0xB1, 0x10, 0x4D,
+ 0x28, 0x78, 0x08, 0xB1, 0x64, 0x1C, 0xE4, 0xB2, 0x0E, 0x4E, 0xC4, 0xEB,
+ 0xC4, 0x00, 0x81, 0x00, 0xB4, 0x70, 0x53, 0x23, 0x0C, 0x4A, 0x00, 0x20,
+ 0xED, 0xF7, 0x88, 0xD9, 0x70, 0x60, 0x00, 0x28, 0x0D, 0xD0, 0x28, 0x78,
+ 0x00, 0x28, 0x0A, 0xD0, 0xBD, 0xE8, 0x70, 0x40, 0xF2, 0xF7, 0x60, 0xBA,
+ 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x22, 0x05, 0x49, 0x05, 0x48, 0xE2, 0xF7,
+ 0xE2, 0x9B, 0x70, 0xBD, 0x82, 0x74, 0x20, 0x00, 0xB0, 0x78, 0x20, 0x00,
+ 0x0B, 0xB3, 0x82, 0x00, 0xF0, 0x69, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21,
+ 0x01, 0x49, 0x88, 0x60, 0x70, 0x47, 0x00, 0x00, 0xB0, 0x78, 0x20, 0x00,
+ 0xF8, 0xB5, 0x1A, 0x4D, 0x00, 0x24, 0xA8, 0x78, 0x28, 0xB9, 0x19, 0x48,
+ 0x00, 0x78, 0x50, 0xB3, 0x00, 0x20, 0xFF, 0xF7, 0xBF, 0xFF, 0x6B, 0x78,
+ 0x69, 0x68, 0xC3, 0xEB, 0xC3, 0x00, 0x01, 0xEB, 0x80, 0x01, 0x14, 0x4E,
+ 0x88, 0x68, 0x58, 0xB1, 0xA8, 0x78, 0x83, 0x42, 0x01, 0xD2, 0x0A, 0x78,
+ 0x6A, 0xB1, 0x00, 0x90, 0x02, 0x22, 0x10, 0x49, 0x30, 0x46, 0xE2, 0xF7,
+ 0xB2, 0xDB, 0x12, 0xE0, 0x0D, 0x49, 0x01, 0x22, 0x54, 0x39, 0x30, 0x46,
+ 0xE2, 0xF7, 0xAB, 0xDB, 0x0B, 0xE0, 0x01, 0x20, 0x08, 0x70, 0x48, 0x88,
+ 0x1C, 0x22, 0xB0, 0xFB, 0xF2, 0xF0, 0x8A, 0x88, 0x89, 0x68, 0xEC, 0xF7,
+ 0x0D, 0xF9, 0x00, 0xB1, 0x01, 0x24, 0x20, 0x46, 0xF8, 0xBD, 0x00, 0x00,
+ 0xB0, 0x78, 0x20, 0x00, 0x82, 0x74, 0x20, 0x00, 0x00, 0x33, 0x10, 0x21,
+ 0xEC, 0x6B, 0xC0, 0x08, 0x2D, 0xE9, 0xFF, 0x4F, 0x85, 0xB0, 0x0D, 0x46,
+ 0x1F, 0x46, 0x3C, 0x48, 0x12, 0x9C, 0x05, 0x99, 0xFD, 0xF7, 0xE0, 0xFF,
+ 0x78, 0xB1, 0xDF, 0xF8, 0xE8, 0xB0, 0x05, 0x98, 0xDB, 0xF8, 0x00, 0x10,
+ 0x00, 0xEB, 0x40, 0x09, 0x01, 0xEB, 0x09, 0x10, 0x40, 0x8A, 0xC0, 0x1E,
+ 0x80, 0xB2, 0x84, 0x42, 0x03, 0xD9, 0x02, 0x23, 0x58, 0xE0, 0x01, 0x23,
+ 0x56, 0xE0, 0xDF, 0xF8, 0xC8, 0xA0, 0x9A, 0xF8, 0x00, 0x00, 0x28, 0xB1,
+ 0x30, 0x48, 0x81, 0x78, 0x8D, 0x42, 0x03, 0xD3, 0x04, 0x23, 0x4B, 0xE0,
+ 0x03, 0x23, 0x49, 0xE0, 0x40, 0x68, 0xC5, 0xEB, 0xC5, 0x01, 0x00, 0xEB,
+ 0x81, 0x08, 0x2B, 0x48, 0x2B, 0x49, 0x00, 0x25, 0x00, 0x88, 0x0B, 0x88,
+ 0x1C, 0xB1, 0x17, 0xB1, 0xC0, 0x1C, 0x86, 0xB2, 0x02, 0xE0, 0x00, 0x26,
+ 0x6F, 0xB1, 0x6C, 0xB1, 0x32, 0x46, 0x21, 0x46, 0x18, 0x46, 0xEB, 0xF7,
+ 0xC9, 0xF9, 0x05, 0x00, 0x29, 0xD0, 0xA8, 0x19, 0x22, 0x46, 0x39, 0x46,
+ 0x14, 0xF4, 0x5F, 0xF4, 0x00, 0xE0, 0x00, 0x24, 0x07, 0x99, 0x13, 0x98,
+ 0xCD, 0xE9, 0x00, 0x14, 0xCD, 0xE9, 0x02, 0x60, 0xDB, 0xF8, 0x00, 0x10,
+ 0xD8, 0xF8, 0x0C, 0x20, 0x01, 0xEB, 0x09, 0x10, 0x00, 0x23, 0x01, 0x8A,
+ 0x28, 0x46, 0xEB, 0xF7, 0xBD, 0xFC, 0x90, 0xB1, 0x9A, 0xF8, 0x00, 0x00,
+ 0x02, 0x22, 0x40, 0x1E, 0xC0, 0xB2, 0x8A, 0xF8, 0x00, 0x00, 0x00, 0x90,
+ 0x12, 0x49, 0x13, 0x48, 0x05, 0x9B, 0xE2, 0xF7, 0x2A, 0xDB, 0x01, 0x20,
+ 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x05, 0x23, 0x04, 0xE0, 0x15, 0xB1,
+ 0x28, 0x46, 0xEB, 0xF7, 0xA5, 0xF9, 0x06, 0x23, 0x0A, 0x49, 0x0B, 0x48,
+ 0x01, 0x22, 0x34, 0x31, 0xC0, 0x1E, 0xE2, 0xF7, 0x18, 0xDB, 0x00, 0x20,
+ 0xEC, 0xE7, 0x00, 0x00, 0x64, 0xB3, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00,
+ 0x60, 0x78, 0x20, 0x00, 0xB0, 0x78, 0x20, 0x00, 0x46, 0x78, 0x20, 0x00,
+ 0x44, 0x78, 0x20, 0x00, 0xFC, 0x6A, 0xC0, 0x08, 0x03, 0x33, 0x10, 0x21,
+ 0x70, 0xB5, 0x04, 0x46, 0x0E, 0x48, 0x00, 0x21, 0xC2, 0x69, 0x0E, 0x48,
+ 0x90, 0xF8, 0xAA, 0x31, 0x07, 0xE0, 0x01, 0xEB, 0x41, 0x00, 0x02, 0xEB,
+ 0x40, 0x00, 0x05, 0x78, 0x55, 0xB1, 0x49, 0x1C, 0xC9, 0xB2, 0x8B, 0x42,
+ 0xF5, 0xD8, 0x00, 0x22, 0x07, 0x49, 0x08, 0x48, 0xE2, 0xF7, 0xED, 0xDA,
+ 0x00, 0x20, 0x70, 0xBD, 0x21, 0x68, 0x01, 0x60, 0xA1, 0x88, 0x81, 0x80,
+ 0x70, 0xBD, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0xE8, 0x42, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41,
+ 0x0F, 0x46, 0x06, 0x46, 0x15, 0x48, 0x16, 0x49, 0x00, 0x24, 0x40, 0x68,
+ 0x91, 0xF8, 0x98, 0x11, 0x07, 0xE0, 0xC4, 0xEB, 0xC4, 0x02, 0x00, 0xEB,
+ 0x02, 0x15, 0x2A, 0x79, 0x82, 0xB1, 0x64, 0x1C, 0xE4, 0xB2, 0xA1, 0x42,
+ 0xF5, 0xD8, 0x31, 0x46, 0x0E, 0x48, 0xE2, 0xF7, 0x93, 0xDC, 0x03, 0x46,
+ 0x01, 0x22, 0x0D, 0x49, 0x0D, 0x48, 0xE2, 0xF7, 0xBE, 0xDA, 0x00, 0x20,
+ 0xBD, 0xE8, 0xF0, 0x81, 0x70, 0x21, 0x28, 0x46, 0x14, 0xF4, 0x6C, 0xF4,
+ 0x01, 0x20, 0x28, 0x71, 0x6C, 0x71, 0xAF, 0x74, 0x30, 0x68, 0xE8, 0x60,
+ 0xB0, 0x88, 0x28, 0x82, 0x28, 0x46, 0xEF, 0xE7, 0x88, 0x76, 0x20, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0x00, 0x00, 0x30, 0x21, 0x40, 0x41, 0xC0, 0x08,
+ 0x00, 0x39, 0x10, 0x21, 0x38, 0xB5, 0x04, 0x46, 0x03, 0x79, 0x00, 0x6A,
+ 0x03, 0xB1, 0x38, 0xB1, 0x00, 0x90, 0x02, 0x22, 0x27, 0x49, 0x28, 0x48,
+ 0xE2, 0xF7, 0x97, 0xDA, 0x00, 0x20, 0x38, 0xBD, 0x27, 0x4D, 0x40, 0xF2,
+ 0x29, 0x23, 0x25, 0x4A, 0x88, 0x21, 0x28, 0x78, 0xEA, 0xF7, 0x22, 0xF8,
+ 0x20, 0x62, 0x38, 0xB3, 0x88, 0x21, 0x14, 0xF4, 0x3D, 0xF4, 0x40, 0xF2,
+ 0x2E, 0x23, 0x1F, 0x4A, 0x84, 0x21, 0x28, 0x78, 0xEA, 0xF7, 0x16, 0xF8,
+ 0x21, 0x6A, 0x48, 0x60, 0x84, 0x21, 0x14, 0xF4, 0x31, 0xF4, 0x40, 0xF2,
+ 0x31, 0x23, 0x19, 0x4A, 0x80, 0x21, 0x28, 0x78, 0xEA, 0xF7, 0x0A, 0xF8,
+ 0x21, 0x6A, 0xC8, 0x63, 0x80, 0x21, 0x14, 0xF4, 0x03, 0xF4, 0x21, 0x6A,
+ 0x48, 0x68, 0x58, 0xB1, 0xC9, 0x6B, 0x49, 0xB1, 0x84, 0x21, 0x14, 0xF4,
+ 0x1D, 0xF4, 0x20, 0x6A, 0x80, 0x21, 0xC0, 0x6B, 0x14, 0xF4, 0xF6, 0xF3,
+ 0x20, 0x6A, 0x38, 0xBD, 0x40, 0xF2, 0x35, 0x22, 0x0B, 0x49, 0xEA, 0xF7,
+ 0xDF, 0xF8, 0x20, 0x6A, 0x40, 0xF2, 0x36, 0x22, 0x08, 0x49, 0xC0, 0x6B,
+ 0xEA, 0xF7, 0xD8, 0xF8, 0x40, 0xF2, 0x37, 0x22, 0x05, 0x49, 0x20, 0x6A,
+ 0xEA, 0xF7, 0xD2, 0xF8, 0x00, 0x20, 0x20, 0x62, 0xE8, 0xE7, 0x00, 0x00,
+ 0x94, 0x42, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21, 0xA4, 0xAA, 0x82, 0x00,
+ 0x00, 0x74, 0x20, 0x00, 0x3E, 0xB5, 0x04, 0x46, 0x0D, 0x46, 0x90, 0xF8,
+ 0x24, 0x00, 0xA1, 0x68, 0xCD, 0xE9, 0x00, 0x10, 0x02, 0x95, 0xA3, 0x7C,
+ 0x04, 0x22, 0x1E, 0x49, 0x1E, 0x48, 0xE2, 0xF7, 0x34, 0xDA, 0x60, 0x8B,
+ 0xF4, 0xF7, 0xAC, 0xFD, 0x25, 0xB1, 0x2A, 0x46, 0x0A, 0x21, 0x20, 0x46,
+ 0x00, 0xF0, 0xD0, 0xF8, 0xA0, 0x7C, 0x28, 0xB1, 0x02, 0x28, 0x03, 0xD0,
+ 0x03, 0x28, 0x01, 0xD0, 0x01, 0x28, 0x12, 0xD1, 0x94, 0xF8, 0x24, 0x00,
+ 0x02, 0x28, 0x01, 0xD0, 0x03, 0x28, 0x06, 0xD1, 0xE2, 0x79, 0xA1, 0x79,
+ 0x2B, 0x46, 0x04, 0xF1, 0x0C, 0x00, 0xEC, 0xF7, 0x8B, 0xFE, 0x20, 0x46,
+ 0xEA, 0xF7, 0xBC, 0xFF, 0x20, 0x46, 0x02, 0xF0, 0xCB, 0xFF, 0xA0, 0x68,
+ 0x0B, 0x49, 0x20, 0xF4, 0x80, 0x50, 0xA0, 0x60, 0x00, 0x20, 0x84, 0xF8,
+ 0x24, 0x00, 0x84, 0xF8, 0x6B, 0x00, 0x4F, 0xF6, 0xFF, 0x70, 0x88, 0x85,
+ 0x00, 0xF0, 0x8C, 0xF9, 0x60, 0x8B, 0xBD, 0xE8, 0x3E, 0x40, 0xF7, 0xF7,
+ 0x43, 0xBE, 0x00, 0x00, 0x40, 0x42, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21,
+ 0x88, 0x76, 0x20, 0x00, 0x70, 0xB5, 0x86, 0xB0, 0x40, 0xF2, 0x03, 0x45,
+ 0xDD, 0xE9, 0x0A, 0x46, 0xAD, 0xF8, 0x00, 0x50, 0x05, 0x68, 0x01, 0x95,
+ 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0xAD, 0xF8, 0x0E, 0x20, 0xAD, 0xF8,
+ 0x10, 0x30, 0x09, 0x48, 0xAD, 0xF8, 0x0C, 0x10, 0x8D, 0xF8, 0x0A, 0x40,
+ 0x8D, 0xF8, 0x12, 0x60, 0x40, 0xF2, 0x6D, 0x13, 0x03, 0x4A, 0x69, 0x46,
+ 0x00, 0x78, 0xEA, 0xF7, 0x71, 0xFA, 0x06, 0xB0, 0x70, 0xBD, 0x00, 0x00,
+ 0xE7, 0xA8, 0x82, 0x00, 0x84, 0x76, 0x20, 0x00, 0x10, 0xB5, 0x0D, 0x49,
+ 0x00, 0x68, 0x08, 0x60, 0x08, 0x88, 0x02, 0x07, 0x11, 0xD5, 0x01, 0x22,
+ 0x4A, 0x75, 0x80, 0x05, 0x01, 0xD5, 0x02, 0x20, 0x48, 0x75, 0x4B, 0x7D,
+ 0x01, 0x22, 0x07, 0x49, 0x07, 0x48, 0xE2, 0xF7, 0xBC, 0xD9, 0x00, 0x21,
+ 0xBD, 0xE8, 0x10, 0x40, 0x11, 0x20, 0xEF, 0xF7, 0xCA, 0xB9, 0x00, 0x20,
+ 0xF0, 0xE7, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00, 0x70, 0x22, 0xC0, 0x08,
+ 0x02, 0x39, 0x10, 0x21, 0x70, 0xB5, 0x05, 0x46, 0x00, 0x78, 0x00, 0x24,
+ 0x00, 0x28, 0x28, 0x46, 0x0C, 0xD0, 0x00, 0xF0, 0xF2, 0xF8, 0x30, 0xB1,
+ 0x28, 0x46, 0xFF, 0xF7, 0x9B, 0xFE, 0x40, 0xB9, 0x40, 0xF2, 0xE2, 0x54,
+ 0x05, 0xE0, 0x40, 0xF2, 0xE3, 0x54, 0x02, 0xE0, 0x02, 0xF0, 0x3A, 0xFF,
+ 0x04, 0x46, 0x20, 0x46, 0x70, 0xBD, 0x00, 0x00, 0x41, 0x1C, 0x02, 0xD0,
+ 0x04, 0x49, 0x88, 0x42, 0x03, 0xD2, 0x04, 0x49, 0x08, 0x62, 0x00, 0x20,
+ 0x70, 0x47, 0xE3, 0x20, 0x70, 0x47, 0x00, 0x00, 0x40, 0x42, 0x0F, 0x00,
+ 0x88, 0x76, 0x20, 0x00, 0x03, 0x49, 0x02, 0x68, 0xC1, 0xF8, 0x2E, 0x20,
+ 0x80, 0x88, 0x48, 0x86, 0x70, 0x47, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00,
+ 0x01, 0x49, 0x88, 0x75, 0x70, 0x47, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00,
+ 0x0A, 0x4B, 0x19, 0x46, 0x18, 0x76, 0x11, 0xF8, 0x59, 0x2F, 0x49, 0x78,
+ 0x30, 0xB1, 0x42, 0xF0, 0x04, 0x00, 0x03, 0xF8, 0x59, 0x0F, 0x41, 0xF0,
+ 0x04, 0x00, 0x05, 0xE0, 0x22, 0xF0, 0x04, 0x00, 0x03, 0xF8, 0x59, 0x0F,
+ 0x21, 0xF0, 0x04, 0x00, 0x58, 0x70, 0x70, 0x47, 0x88, 0x76, 0x20, 0x00,
+ 0xFE, 0xB5, 0x15, 0x46, 0x04, 0x00, 0x0E, 0x46, 0x4F, 0xF0, 0x00, 0x07,
+ 0x35, 0xD0, 0x94, 0xF8, 0x25, 0x00, 0x0B, 0x46, 0xCD, 0xE9, 0x00, 0x50,
+ 0x03, 0x22, 0x28, 0x49, 0x28, 0x48, 0xE2, 0xF7, 0x4A, 0xD9, 0xA6, 0xF1,
+ 0x09, 0x00, 0x00, 0x22, 0x04, 0xF1, 0x0C, 0x01, 0x0D, 0x28, 0x2D, 0xD2,
+ 0xDF, 0xE8, 0x00, 0xF0, 0x24, 0x24, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x07,
+ 0x07, 0x07, 0x07, 0x1B, 0x14, 0x00, 0x94, 0xF8, 0x25, 0x00, 0x00, 0x28,
+ 0x17, 0xD1, 0x84, 0xF8, 0x25, 0x60, 0x00, 0x92, 0x01, 0x92, 0x02, 0x92,
+ 0x00, 0x23, 0xA2, 0x7C, 0x03, 0x20, 0x22, 0xE0, 0x94, 0xF8, 0x25, 0x00,
+ 0x12, 0x28, 0x15, 0xD0, 0x11, 0x28, 0x13, 0xD0, 0x05, 0xE0, 0x94, 0xF8,
+ 0x25, 0x00, 0x11, 0x28, 0x0E, 0xD0, 0x13, 0x28, 0x0C, 0xD0, 0x10, 0x28,
+ 0x0A, 0xD0, 0xFE, 0xBD, 0x94, 0xF8, 0x25, 0x00, 0x00, 0x28, 0xFA, 0xD0,
+ 0x25, 0xB9, 0x40, 0xF2, 0x05, 0x15, 0x01, 0xE0, 0x00, 0x2F, 0xF4, 0xD0,
+ 0x84, 0xF8, 0x25, 0x20, 0x45, 0xB1, 0x00, 0x92, 0x01, 0x92, 0x02, 0x92,
+ 0xA2, 0x7C, 0x2B, 0x46, 0x05, 0x20, 0x04, 0xF0, 0x93, 0xF8, 0xFE, 0xBD,
+ 0xE0, 0x79, 0xA3, 0x79, 0x00, 0x93, 0xCD, 0xE9, 0x01, 0x02, 0x00, 0x23,
+ 0xA2, 0x7C, 0x04, 0x20, 0xF3, 0xE7, 0x00, 0x00, 0xF8, 0x41, 0xC0, 0x08,
+ 0x03, 0x39, 0x10, 0x21, 0x00, 0x6A, 0xCA, 0x07, 0x04, 0xD0, 0x02, 0x68,
+ 0x13, 0x05, 0x0D, 0xD5, 0x92, 0x04, 0x0B, 0xD5, 0x8A, 0x07, 0x04, 0xD5,
+ 0x02, 0x68, 0x13, 0x04, 0x06, 0xD5, 0x92, 0x03, 0x04, 0xD5, 0x49, 0x07,
+ 0x04, 0xD5, 0x00, 0x68, 0x00, 0x03, 0x01, 0xD4, 0x00, 0x20, 0x70, 0x47,
+ 0x01, 0x20, 0x70, 0x47, 0x00, 0x6A, 0xCA, 0x07, 0x04, 0xD0, 0x02, 0x68,
+ 0x53, 0x05, 0x0D, 0xD5, 0xD2, 0x04, 0x0B, 0xD5, 0x8A, 0x07, 0x04, 0xD5,
+ 0x02, 0x68, 0x53, 0x04, 0x06, 0xD5, 0xD2, 0x03, 0x04, 0xD5, 0x49, 0x07,
+ 0x04, 0xD5, 0x00, 0x68, 0x40, 0x03, 0x01, 0xD4, 0x00, 0x20, 0x70, 0x47,
+ 0x01, 0x20, 0x70, 0x47, 0x70, 0xB5, 0x00, 0x25, 0x00, 0xF0, 0x8C, 0xF8,
+ 0x60, 0xB1, 0x04, 0x6A, 0x54, 0xB1, 0x02, 0x7F, 0x21, 0x7A, 0x01, 0x2A,
+ 0x08, 0xD0, 0xFF, 0xF7, 0xDB, 0xFF, 0x18, 0xB1, 0x20, 0x68, 0x00, 0x01,
+ 0x00, 0xD5, 0x01, 0x25, 0x28, 0x46, 0x70, 0xBD, 0xFF, 0xF7, 0xBA, 0xFF,
+ 0xF5, 0xE7, 0x10, 0xB5, 0x01, 0x78, 0x01, 0x24, 0x29, 0xB1, 0x80, 0x88,
+ 0x10, 0xB1, 0x00, 0xF0, 0x8D, 0xF8, 0x00, 0xB1, 0x00, 0x24, 0x20, 0x46,
+ 0x10, 0xBD, 0x00, 0x00, 0x08, 0xB5, 0x00, 0xF0, 0x69, 0xF8, 0x68, 0xB1,
+ 0x90, 0xF8, 0x25, 0x30, 0x53, 0xB1, 0x80, 0x68, 0x41, 0x07, 0x07, 0xD5,
+ 0x00, 0x90, 0x02, 0x22, 0x03, 0x49, 0x04, 0x48, 0xE2, 0xF7, 0x95, 0xD8,
+ 0x01, 0x20, 0x08, 0xBD, 0x00, 0x20, 0x08, 0xBD, 0x78, 0x41, 0xC0, 0x08,
+ 0x02, 0x39, 0x10, 0x21, 0x10, 0xB5, 0x04, 0x46, 0x03, 0x88, 0x01, 0x22,
+ 0x05, 0x49, 0x06, 0x48, 0xE2, 0xF7, 0x85, 0xD8, 0x21, 0x46, 0xBD, 0xE8,
+ 0x10, 0x40, 0x24, 0x23, 0x03, 0x4A, 0x04, 0x48, 0xEA, 0xF7, 0x4A, 0xBC,
+ 0xF0, 0x40, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0x67, 0xAA, 0x82, 0x00,
+ 0x94, 0x76, 0x20, 0x00, 0x70, 0xB5, 0x86, 0xB0, 0x0D, 0x4E, 0x0E, 0x4C,
+ 0x0E, 0x4D, 0x0C, 0xE0, 0xBD, 0xF8, 0x00, 0x30, 0x01, 0x22, 0x0D, 0x49,
+ 0x30, 0x46, 0xE2, 0xF7, 0x68, 0xD8, 0x36, 0x23, 0x0B, 0x4A, 0x69, 0x46,
+ 0x20, 0x78, 0xEA, 0xF7, 0xFD, 0xF8, 0x33, 0x23, 0x08, 0x4A, 0x69, 0x46,
+ 0x28, 0x46, 0xEA, 0xF7, 0xFF, 0xFB, 0x00, 0x28, 0xEA, 0xD1, 0x06, 0xB0,
+ 0x70, 0xBD, 0x00, 0x00, 0x03, 0x39, 0x10, 0x21, 0x84, 0x76, 0x20, 0x00,
+ 0x94, 0x76, 0x20, 0x00, 0x18, 0x41, 0xC0, 0x08, 0x7C, 0xAA, 0x82, 0x00,
+ 0x00, 0xB5, 0x08, 0x48, 0x85, 0xB0, 0x21, 0x23, 0x05, 0x4A, 0x69, 0x46,
+ 0x00, 0x78, 0xEA, 0xF7, 0x8D, 0xF8, 0x00, 0x28, 0x02, 0xD0, 0x68, 0x46,
+ 0x01, 0xF0, 0x40, 0xFC, 0x05, 0xB0, 0x00, 0xBD, 0xDE, 0xA8, 0x82, 0x00,
+ 0x84, 0x76, 0x20, 0x00, 0x30, 0xB5, 0x04, 0x46, 0x0A, 0x48, 0x00, 0x21,
+ 0x42, 0x68, 0x0A, 0x48, 0x90, 0xF8, 0x98, 0x31, 0x0A, 0xE0, 0xC1, 0xEB,
+ 0xC1, 0x00, 0x02, 0xEB, 0x00, 0x10, 0x05, 0x79, 0x15, 0xB1, 0x45, 0x8B,
+ 0xA5, 0x42, 0x04, 0xD0, 0x49, 0x1C, 0xC9, 0xB2, 0x8B, 0x42, 0xF2, 0xD8,
+ 0x00, 0x20, 0x30, 0xBD, 0x88, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x30, 0xB5, 0x04, 0x46, 0x0A, 0x48, 0x00, 0x21, 0xC2, 0x69, 0x0A, 0x48,
+ 0x90, 0xF8, 0xAA, 0x31, 0x0A, 0xE0, 0x01, 0xEB, 0x41, 0x00, 0x02, 0xEB,
+ 0x40, 0x00, 0x05, 0x78, 0x15, 0xB1, 0x85, 0x88, 0xA5, 0x42, 0x04, 0xD0,
+ 0x49, 0x1C, 0xC9, 0xB2, 0x8B, 0x42, 0xF2, 0xD8, 0x00, 0x20, 0x30, 0xBD,
+ 0x88, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x47,
+ 0x0E, 0x46, 0x81, 0x46, 0x00, 0x24, 0x10, 0x4F, 0xDF, 0xF8, 0x40, 0x80,
+ 0x12, 0xE0, 0x78, 0x68, 0xC4, 0xEB, 0xC4, 0x01, 0x00, 0xEB, 0x01, 0x15,
+ 0x28, 0x79, 0x48, 0xB1, 0xA8, 0x7C, 0xB0, 0x42, 0x06, 0xD1, 0x06, 0x22,
+ 0x49, 0x46, 0x05, 0xF1, 0x0C, 0x00, 0x14, 0xF4, 0xB1, 0xF0, 0x40, 0xB1,
+ 0x64, 0x1C, 0xE4, 0xB2, 0x98, 0xF8, 0x98, 0x01, 0xA0, 0x42, 0xE8, 0xD8,
+ 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0x28, 0x46, 0xFB, 0xE7, 0x00, 0x00,
+ 0x88, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0x08, 0x49, 0x91, 0xF8,
+ 0x98, 0x11, 0x81, 0x42, 0x09, 0xD9, 0x07, 0x49, 0xC0, 0xEB, 0xC0, 0x00,
+ 0x49, 0x68, 0x11, 0xEB, 0x00, 0x10, 0x02, 0xD0, 0x01, 0x79, 0x00, 0x29,
+ 0x00, 0xD1, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x88, 0x76, 0x20, 0x00, 0x10, 0xB5, 0x0E, 0x4B, 0x00, 0x21, 0x42, 0x18,
+ 0x54, 0x78, 0x92, 0x78, 0x24, 0x02, 0x04, 0xEB, 0x02, 0x42, 0x44, 0x5C,
+ 0x22, 0x44, 0xC2, 0xF3, 0x13, 0x04, 0x9C, 0x42, 0x04, 0xD3, 0x12, 0x09,
+ 0xC2, 0xF3, 0x13, 0x04, 0x9C, 0x42, 0x02, 0xD2, 0xC2, 0xF3, 0x13, 0x00,
+ 0x10, 0xBD, 0x49, 0x1C, 0x89, 0xB2, 0x06, 0x29, 0xE7, 0xD3, 0x4F, 0xF0,
+ 0xFF, 0x30, 0x10, 0xBD, 0x40, 0x42, 0x0F, 0x00, 0x10, 0xB5, 0x00, 0x6A,
+ 0x44, 0x68, 0x50, 0x34, 0x11, 0xF4, 0x44, 0xF1, 0x20, 0x70, 0x01, 0x0A,
+ 0x61, 0x70, 0x01, 0x0C, 0xA1, 0x70, 0x00, 0x0E, 0xE0, 0x70, 0x11, 0xF4,
+ 0x3B, 0xF1, 0x20, 0x71, 0x01, 0x0A, 0x61, 0x71, 0x01, 0x0C, 0xA1, 0x71,
+ 0x00, 0x0E, 0xE0, 0x71, 0x11, 0xF4, 0x32, 0xF1, 0x20, 0x72, 0x01, 0x0A,
+ 0x61, 0x72, 0x01, 0x0C, 0xA1, 0x72, 0x00, 0x0E, 0xE0, 0x72, 0x11, 0xF4,
+ 0x29, 0xF1, 0x20, 0x73, 0x01, 0x0A, 0x61, 0x73, 0x01, 0x0C, 0xA1, 0x73,
+ 0x00, 0x0E, 0xE0, 0x73, 0x10, 0xBD, 0x00, 0x00, 0xF0, 0xB5, 0x8B, 0xB0,
+ 0x0C, 0x00, 0x07, 0x46, 0x4F, 0xF0, 0x01, 0x06, 0x24, 0xD0, 0x11, 0xF4,
+ 0x17, 0xF1, 0x20, 0x70, 0x01, 0x0A, 0x61, 0x70, 0x01, 0x0C, 0xA1, 0x70,
+ 0x00, 0x0E, 0x65, 0x1C, 0xE0, 0x70, 0x11, 0xF4, 0x0D, 0xF1, 0xE8, 0x70,
+ 0xC0, 0xF3, 0x07, 0x21, 0x29, 0x71, 0xAF, 0xB1, 0x00, 0x20, 0x01, 0x2F,
+ 0x2E, 0xD0, 0x02, 0x2F, 0x46, 0xD0, 0x00, 0x26, 0x21, 0x46, 0x41, 0x48,
+ 0xE2, 0xF7, 0x24, 0xD9, 0x03, 0x46, 0x02, 0x22, 0x3F, 0x49, 0x40, 0x48,
+ 0x00, 0x97, 0xE1, 0xF7, 0x4E, 0xDF, 0x30, 0x46, 0x0B, 0xB0, 0xF0, 0xBD,
+ 0x00, 0x20, 0xFB, 0xE7, 0x41, 0xF0, 0xC0, 0x00, 0x60, 0x71, 0x3B, 0xA0,
+ 0x06, 0x22, 0xD0, 0xE9, 0x00, 0x10, 0xCD, 0xE9, 0x00, 0x10, 0x3A, 0xA0,
+ 0xD0, 0xE9, 0x00, 0x10, 0xCD, 0xE9, 0x02, 0x10, 0x69, 0x46, 0x20, 0x46,
+ 0x14, 0xF4, 0x00, 0xF0, 0x30, 0xB1, 0x06, 0x22, 0x02, 0xA9, 0x20, 0x46,
+ 0x13, 0xF4, 0xFA, 0xF7, 0x00, 0x28, 0xD5, 0xD1, 0x66, 0x20, 0x17, 0xE0,
+ 0x01, 0xF0, 0x3F, 0x01, 0x61, 0x71, 0x00, 0x90, 0x01, 0x90, 0x30, 0xA0,
+ 0x06, 0x22, 0xD0, 0xE9, 0x00, 0x10, 0xCD, 0xE9, 0x02, 0x10, 0x69, 0x46,
+ 0x20, 0x46, 0x13, 0xF4, 0xE7, 0xF7, 0x30, 0xB1, 0x06, 0x22, 0x02, 0xA9,
+ 0x20, 0x46, 0x13, 0xF4, 0xE1, 0xF7, 0x00, 0x28, 0xBC, 0xD1, 0x77, 0x20,
+ 0x20, 0x70, 0xB9, 0xE7, 0x01, 0xF0, 0x7F, 0x01, 0x41, 0xF0, 0x40, 0x01,
+ 0x61, 0x71, 0x00, 0x90, 0x01, 0x90, 0x02, 0x90, 0x03, 0x90, 0x04, 0x90,
+ 0x05, 0x90, 0x06, 0x90, 0x07, 0x90, 0x21, 0xA0, 0x03, 0x22, 0x00, 0x68,
+ 0x08, 0x90, 0x20, 0xA0, 0x08, 0xA9, 0x00, 0x68, 0x09, 0x90, 0x20, 0x46,
+ 0x13, 0xF4, 0xC4, 0xF7, 0x28, 0xB1, 0x03, 0x22, 0x09, 0xA9, 0x20, 0x46,
+ 0x13, 0xF4, 0xBE, 0xF7, 0x08, 0xB9, 0x88, 0x20, 0xE0, 0x70, 0xE0, 0x78,
+ 0x8D, 0xF8, 0x00, 0x00, 0x20, 0x79, 0x8D, 0xF8, 0x01, 0x00, 0x60, 0x79,
+ 0x8D, 0xF8, 0x02, 0x00, 0x14, 0x48, 0x90, 0xF8, 0x47, 0x00, 0x30, 0xB1,
+ 0x12, 0x49, 0x04, 0xAA, 0x49, 0x31, 0x68, 0x46, 0xE3, 0xF7, 0xAB, 0xD8,
+ 0x00, 0xE0, 0x00, 0x26, 0xBD, 0xF8, 0x10, 0x00, 0x20, 0x80, 0x9D, 0xF8,
+ 0x12, 0x00, 0xA0, 0x70, 0x7C, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21,
+ 0xC0, 0x25, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+ 0xFF, 0xFF, 0x7F, 0x00, 0x88, 0x76, 0x20, 0x00, 0x0F, 0x4B, 0x10, 0xB5,
+ 0x02, 0x46, 0x19, 0x88, 0x00, 0x20, 0x4C, 0x07, 0x02, 0xD4, 0x14, 0x89,
+ 0xA4, 0x05, 0x05, 0xD5, 0xDB, 0x78, 0x03, 0xF0, 0x07, 0x03, 0x03, 0x2B,
+ 0x00, 0xD0, 0x04, 0x20, 0x8B, 0x07, 0x01, 0xD0, 0x40, 0xF0, 0x01, 0x00,
+ 0x0B, 0x07, 0x02, 0xD4, 0x12, 0x89, 0x52, 0x04, 0x01, 0xD5, 0x40, 0xF0,
+ 0x08, 0x00, 0xC9, 0x06, 0x01, 0xD5, 0x40, 0xF0, 0x10, 0x00, 0x10, 0xBD,
+ 0x88, 0x76, 0x20, 0x00, 0x10, 0xB5, 0xFF, 0xF7, 0x97, 0xFE, 0x20, 0xB1,
+ 0x90, 0xF8, 0x28, 0x10, 0x09, 0xB1, 0x2A, 0x30, 0x10, 0xBD, 0x00, 0x20,
+ 0x10, 0xBD, 0x00, 0x00, 0x04, 0x4A, 0x00, 0x20, 0x12, 0xF8, 0x59, 0x1F,
+ 0x40, 0xEA, 0x01, 0x21, 0x50, 0x78, 0x08, 0x43, 0x70, 0x47, 0x00, 0x00,
+ 0x88, 0x76, 0x20, 0x00, 0x10, 0xB5, 0xFF, 0xF7, 0x7F, 0xFE, 0x00, 0x28,
+ 0x00, 0xD0, 0xC0, 0x6B, 0x10, 0xBD, 0x10, 0xB5, 0xFF, 0xF7, 0x78, 0xFE,
+ 0x20, 0xB1, 0x90, 0xF8, 0x29, 0x10, 0x09, 0xB1, 0x40, 0x30, 0x10, 0xBD,
+ 0x00, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0xFF, 0xF7, 0x6D, 0xFE, 0x00, 0x28,
+ 0x00, 0xD0, 0x00, 0x6D, 0x10, 0xBD, 0x00, 0x00, 0x70, 0xB5, 0x08, 0x4C,
+ 0x00, 0x25, 0x01, 0x22, 0x23, 0x88, 0x07, 0x49, 0x07, 0x48, 0xE1, 0xF7,
+ 0x60, 0xDE, 0x20, 0x78, 0x80, 0x07, 0x02, 0xD0, 0xFF, 0xF7, 0xCC, 0xFF,
+ 0x05, 0x46, 0x28, 0x46, 0x70, 0xBD, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00,
+ 0xC4, 0x42, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x47,
+ 0x06, 0x46, 0x81, 0x7A, 0x00, 0x1D, 0xFF, 0xF7, 0x49, 0xFE, 0x04, 0x46,
+ 0x31, 0x1D, 0xA2, 0x48, 0xE2, 0xF7, 0x14, 0xD8, 0x03, 0x46, 0xF0, 0x7A,
+ 0xB2, 0x89, 0x31, 0x88, 0x8D, 0xE8, 0x07, 0x00, 0xDF, 0xF8, 0x7C, 0xA2,
+ 0x04, 0x22, 0x9D, 0x49, 0x50, 0x46, 0xE1, 0xF7, 0x38, 0xDE, 0xAA, 0xF1,
+ 0x03, 0x05, 0xF4, 0xB1, 0xF0, 0x7A, 0xDF, 0xF8, 0x6C, 0x82, 0x06, 0xF1,
+ 0x10, 0x07, 0xA8, 0xF1, 0x02, 0x09, 0x11, 0x28, 0x1E, 0xD0, 0x12, 0x28,
+ 0x57, 0xD0, 0x01, 0x25, 0x15, 0x28, 0x7D, 0xD0, 0x16, 0x28, 0x0C, 0xD1,
+ 0x30, 0x88, 0x00, 0x28, 0x09, 0xD1, 0x97, 0xE8, 0x0F, 0x00, 0x04, 0xF1,
+ 0x40, 0x06, 0x86, 0xE8, 0x0F, 0x00, 0x84, 0xF8, 0x29, 0x50, 0x38, 0x69,
+ 0x20, 0x65, 0xBD, 0xE8, 0xFF, 0x87, 0x04, 0xB0, 0x28, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x47, 0x88, 0x49, 0x00, 0x22, 0x54, 0x31, 0xE1, 0xF7, 0x0D, 0x9E,
+ 0x20, 0x7F, 0x01, 0x28, 0xF1, 0xD1, 0x30, 0x88, 0x40, 0xBB, 0xA0, 0x68,
+ 0xC1, 0x04, 0x25, 0xD4, 0xB9, 0x7E, 0xE1, 0x71, 0xFB, 0x7E, 0xA3, 0x71,
+ 0x04, 0x2B, 0x15, 0xD0, 0x05, 0x2B, 0x10, 0xD0, 0x07, 0x2B, 0x18, 0xD0,
+ 0x08, 0x2B, 0x13, 0xD0, 0x7B, 0x49, 0x01, 0x22, 0x80, 0x31, 0x28, 0x46,
+ 0xE1, 0xF7, 0xF3, 0xDD, 0x60, 0x8B, 0x04, 0xB0, 0x39, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x47, 0xF5, 0xF7, 0xB5, 0xBC, 0x40, 0xF0, 0x83, 0x00, 0x01, 0xE0,
+ 0x40, 0xF0, 0x81, 0x00, 0xA0, 0x60, 0xF1, 0xE7, 0x40, 0xEA, 0x08, 0x00,
+ 0xFA, 0xE7, 0x40, 0xEA, 0x09, 0x00, 0xF7, 0xE7, 0x6E, 0x49, 0x01, 0x22,
+ 0xC4, 0x31, 0x28, 0x46, 0xA3, 0x68, 0xE1, 0xF7, 0xD8, 0xDD, 0x60, 0x8B,
+ 0xF5, 0xF7, 0x99, 0xFC, 0x4F, 0xF4, 0xBD, 0x61, 0x3B, 0xE0, 0x20, 0x7F,
+ 0x00, 0x28, 0xB6, 0xD1, 0x94, 0xF8, 0x24, 0x00, 0xFB, 0x7E, 0x62, 0x7F,
+ 0xB9, 0x7E, 0x8D, 0xE8, 0x0F, 0x00, 0x63, 0x49, 0x05, 0x22, 0xF0, 0x31,
+ 0x50, 0x46, 0xA3, 0x68, 0xE1, 0xF7, 0xC1, 0xDD, 0x30, 0x88, 0xC0, 0xB9,
+ 0xA0, 0x68, 0xC1, 0x04, 0x15, 0xD4, 0x81, 0x05, 0x04, 0xD5, 0xF9, 0x7E,
+ 0x04, 0x29, 0x10, 0xD0, 0x07, 0x29, 0x0E, 0xD0, 0x94, 0xF8, 0x24, 0x10,
+ 0x08, 0x29, 0x04, 0xD1, 0xF9, 0x7E, 0x04, 0x29, 0x07, 0xD0, 0x07, 0x29,
+ 0x05, 0xD0, 0xB9, 0x7E, 0x62, 0x7F, 0x00, 0xE0, 0x94, 0xE0, 0x91, 0x42,
+ 0x6A, 0xD2, 0x55, 0x4F, 0xF8, 0x78, 0xC0, 0x06, 0x11, 0xD4, 0x94, 0xF8,
+ 0x24, 0x00, 0x07, 0x28, 0x01, 0xD0, 0x08, 0x28, 0x03, 0xD1, 0x05, 0x21,
+ 0x20, 0x46, 0x03, 0xF0, 0x69, 0xFC, 0x40, 0xF2, 0xEA, 0x51, 0x04, 0xB0,
+ 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0xFF, 0xF7, 0x4D, 0xBB, 0x20, 0x6A,
+ 0x00, 0x26, 0x18, 0xB9, 0x20, 0x46, 0xFF, 0xF7, 0xE7, 0xFA, 0xB8, 0xB1,
+ 0x20, 0x46, 0xFF, 0xF7, 0xC9, 0xFE, 0x05, 0x46, 0xC0, 0x07, 0x02, 0xD0,
+ 0xFF, 0xF7, 0x18, 0xFF, 0x06, 0x46, 0x43, 0x48, 0x90, 0xF8, 0x78, 0x01,
+ 0x80, 0x07, 0x29, 0xD5, 0xB8, 0x68, 0x82, 0x38, 0x08, 0x28, 0x25, 0xD2,
+ 0xDF, 0xE8, 0x00, 0xF0, 0x0D, 0x10, 0x13, 0x16, 0x19, 0x1C, 0x1F, 0x22,
+ 0x63, 0x8B, 0x04, 0xB0, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x01, 0x22,
+ 0x39, 0x49, 0xE1, 0xF7, 0x68, 0x9D, 0x05, 0xF0, 0x1F, 0x05, 0x13, 0xE0,
+ 0x45, 0xF0, 0x20, 0x05, 0x10, 0xE0, 0x45, 0xF0, 0x40, 0x05, 0x0D, 0xE0,
+ 0x45, 0xF0, 0x60, 0x05, 0x0A, 0xE0, 0x45, 0xF0, 0x80, 0x05, 0x07, 0xE0,
+ 0x45, 0xF0, 0xA0, 0x05, 0x04, 0xE0, 0x45, 0xF0, 0xC0, 0x05, 0x01, 0xE0,
+ 0x45, 0xF0, 0xE0, 0x05, 0xFA, 0x7D, 0xF1, 0xB2, 0xCD, 0xE9, 0x00, 0x52,
+ 0x30, 0x0A, 0xCD, 0xE9, 0x02, 0x01, 0xF8, 0x78, 0x01, 0x21, 0xC0, 0xF3,
+ 0xC0, 0x03, 0x00, 0xF0, 0x07, 0x02, 0x20, 0x46, 0x03, 0xF0, 0x9A, 0xFB,
+ 0x04, 0xB0, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x03, 0xF0, 0x16, 0xBE,
+ 0xE1, 0x71, 0xFB, 0x7E, 0xA3, 0x71, 0x04, 0x2B, 0x18, 0xD0, 0x05, 0x2B,
+ 0x13, 0xD0, 0x07, 0x2B, 0x1B, 0xD0, 0x08, 0x2B, 0x16, 0xD0, 0x1C, 0x49,
+ 0x01, 0x22, 0x48, 0x31, 0x28, 0x46, 0xE1, 0xF7, 0x2A, 0xDD, 0x3A, 0x8B,
+ 0x60, 0x8B, 0x04, 0xB0, 0x3B, 0x46, 0x07, 0xF1, 0x10, 0x01, 0xBD, 0xE8,
+ 0xF0, 0x47, 0xF5, 0xF7, 0x4C, 0xBE, 0x40, 0xF0, 0x83, 0x00, 0x01, 0xE0,
+ 0x40, 0xF0, 0x81, 0x00, 0xA0, 0x60, 0xEE, 0xE7, 0x40, 0xEA, 0x08, 0x00,
+ 0xFA, 0xE7, 0x40, 0xEA, 0x09, 0x00, 0xF7, 0xE7, 0x30, 0x88, 0x00, 0x28,
+ 0x7F, 0xF4, 0xF7, 0xAE, 0x10, 0x22, 0x39, 0x46, 0x04, 0xF1, 0x2A, 0x00,
+ 0x13, 0xF4, 0x1D, 0xF6, 0x84, 0xF8, 0x28, 0x50, 0x38, 0x69, 0xE0, 0x63,
+ 0xEB, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0x88, 0x27, 0xC0, 0x08,
+ 0x03, 0x39, 0x10, 0x21, 0x83, 0x00, 0x01, 0x00, 0x88, 0x76, 0x20, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0xD8, 0x28, 0xC0, 0x08, 0x7F, 0xB5, 0x04, 0x46,
+ 0x81, 0x7A, 0x00, 0x1D, 0xFF, 0xF7, 0xEE, 0xFC, 0x05, 0x46, 0x21, 0x1D,
+ 0x2E, 0x48, 0xE1, 0xF7, 0xB9, 0xDE, 0xA2, 0x89, 0x21, 0x88, 0xE3, 0x7A,
+ 0xCD, 0xE9, 0x02, 0x12, 0xCD, 0xE9, 0x00, 0x03, 0x2B, 0x46, 0x05, 0x22,
+ 0x29, 0x49, 0x2A, 0x48, 0xE1, 0xF7, 0xDD, 0xDC, 0x7D, 0xB1, 0x28, 0x6A,
+ 0x68, 0xB1, 0x21, 0x88, 0xB1, 0xB1, 0x08, 0x21, 0x28, 0x46, 0x03, 0xF0,
+ 0xA5, 0xFB, 0x04, 0xB0, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x40, 0xF2,
+ 0xEB, 0x51, 0xFF, 0xF7, 0x89, 0xBA, 0x04, 0xB0, 0x2B, 0x46, 0x1E, 0x49,
+ 0xBD, 0xE8, 0x70, 0x40, 0x1D, 0x48, 0x01, 0x22, 0x5C, 0x31, 0xC0, 0x1E,
+ 0xE1, 0xF7, 0xC1, 0x9C, 0xE1, 0x7A, 0x11, 0x39, 0x06, 0x29, 0x2C, 0xD2,
+ 0xDF, 0xE8, 0x01, 0xF0, 0x03, 0x07, 0x17, 0x1B, 0x21, 0x25, 0x41, 0x68,
+ 0x11, 0xF8, 0x80, 0x2F, 0x02, 0xE0, 0x41, 0x68, 0x11, 0xF8, 0x81, 0x2F,
+ 0x42, 0xF0, 0x01, 0x02, 0x0A, 0x70, 0x01, 0x68, 0x21, 0xF0, 0x00, 0x61,
+ 0x01, 0x60, 0x04, 0xB0, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x02, 0xF0,
+ 0x0F, 0xB8, 0x41, 0x68, 0x11, 0xF8, 0x80, 0x2F, 0x02, 0xE0, 0x41, 0x68,
+ 0x11, 0xF8, 0x81, 0x2F, 0x42, 0xF0, 0x02, 0x02, 0xEA, 0xE7, 0x41, 0x68,
+ 0x11, 0xF8, 0x80, 0x2F, 0x02, 0xE0, 0x41, 0x68, 0x11, 0xF8, 0x81, 0x2F,
+ 0x42, 0xF0, 0x04, 0x02, 0xE0, 0xE7, 0x7F, 0xBD, 0x00, 0x00, 0x30, 0x21,
+ 0x64, 0x29, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x47,
+ 0x96, 0xB0, 0x00, 0x26, 0x04, 0x6A, 0x05, 0x46, 0x09, 0x96, 0x0A, 0x96,
+ 0x0B, 0x96, 0x0C, 0x96, 0x60, 0x68, 0x10, 0x22, 0x00, 0xF1, 0x30, 0x08,
+ 0x00, 0xF1, 0x10, 0x0A, 0x09, 0xA8, 0x49, 0x1C, 0x13, 0xF4, 0x89, 0xF5,
+ 0xD5, 0xF8, 0x13, 0x00, 0x11, 0x90, 0xB5, 0xF8, 0x17, 0x00, 0xAD, 0xF8,
+ 0x48, 0x00, 0x68, 0x7E, 0x8D, 0xF8, 0x4A, 0x00, 0x68, 0x6D, 0x13, 0x90,
+ 0xB5, 0xF8, 0x58, 0x00, 0xAD, 0xF8, 0x50, 0x00, 0x95, 0xF8, 0x5A, 0x00,
+ 0x58, 0x4F, 0x8D, 0xF8, 0x52, 0x00, 0x05, 0xF1, 0x13, 0x01, 0x38, 0x46,
+ 0xE1, 0xF7, 0x2A, 0xDE, 0x81, 0x46, 0x55, 0x49, 0x38, 0x46, 0xE1, 0xF7,
+ 0x25, 0xDE, 0xA9, 0x7C, 0x6A, 0x7E, 0xCD, 0xF8, 0x00, 0x90, 0xCD, 0xE9,
+ 0x01, 0x21, 0x03, 0x46, 0x04, 0x22, 0x50, 0x49, 0x50, 0x48, 0xE1, 0xF7,
+ 0x4A, 0xDC, 0x28, 0x7F, 0x68, 0xB1, 0xE0, 0x68, 0x04, 0x90, 0x05, 0x96,
+ 0x06, 0x96, 0x07, 0x96, 0x08, 0x96, 0xA0, 0x7A, 0x02, 0x28, 0x0C, 0xD0,
+ 0x01, 0x28, 0x0A, 0xD0, 0x03, 0x28, 0x18, 0xD0, 0x1D, 0xE0, 0xB4, 0xF8,
+ 0x13, 0x00, 0xAD, 0xF8, 0x10, 0x00, 0x60, 0x7D, 0x8D, 0xF8, 0x12, 0x00,
+ 0xEB, 0xE7, 0xB4, 0xF8, 0x78, 0x00, 0x8D, 0xF8, 0x14, 0x00, 0x00, 0x0A,
+ 0x8D, 0xF8, 0x15, 0x00, 0xA0, 0x6F, 0x00, 0x0C, 0x8D, 0xF8, 0x16, 0x00,
+ 0xA0, 0x6F, 0x00, 0x0E, 0x8D, 0xF8, 0x17, 0x00, 0x05, 0xE0, 0x39, 0x48,
+ 0x05, 0xAF, 0x2E, 0x30, 0x0F, 0xC8, 0x87, 0xE8, 0x0F, 0x00, 0x0D, 0xAB,
+ 0x11, 0xAA, 0x13, 0xA9, 0x04, 0xA8, 0x8D, 0xE8, 0x0F, 0x00, 0x05, 0xAB,
+ 0x52, 0x46, 0x41, 0x46, 0x04, 0xF1, 0x60, 0x00, 0x10, 0xF4, 0x2E, 0xF5,
+ 0x10, 0x22, 0x0D, 0xA9, 0x09, 0xA8, 0x13, 0xF4, 0xD3, 0xF4, 0x58, 0xB3,
+ 0x2F, 0x4F, 0x05, 0xAA, 0x10, 0x21, 0x38, 0x46, 0xE1, 0xF7, 0x6F, 0xDE,
+ 0x81, 0x46, 0x52, 0x46, 0x10, 0x21, 0x38, 0x46, 0xE1, 0xF7, 0x69, 0xDE,
+ 0x06, 0x46, 0x42, 0x46, 0x10, 0x21, 0x38, 0x46, 0xE1, 0xF7, 0x63, 0xDE,
+ 0x05, 0x46, 0x09, 0xAA, 0x10, 0x21, 0x38, 0x46, 0xE1, 0xF7, 0x5D, 0xDE,
+ 0x04, 0x46, 0x0D, 0xAA, 0x10, 0x21, 0x38, 0x46, 0xE1, 0xF7, 0x57, 0xDE,
+ 0x03, 0x46, 0x8D, 0xE8, 0x70, 0x02, 0x1D, 0x49, 0x1D, 0x48, 0x05, 0x22,
+ 0x70, 0x31, 0x80, 0x1E, 0xE1, 0xF7, 0xE1, 0xDB, 0x0B, 0x20, 0x16, 0xB0,
+ 0xBD, 0xE8, 0xF0, 0x87, 0xA0, 0x7A, 0x04, 0x28, 0x17, 0xD0, 0xB0, 0xB1,
+ 0x08, 0x20, 0xA8, 0x71, 0x28, 0x7F, 0x01, 0x28, 0x13, 0xD0, 0x00, 0x96,
+ 0x01, 0x96, 0x20, 0x68, 0x40, 0xF0, 0x00, 0x50, 0x20, 0x60, 0x28, 0x46,
+ 0x03, 0xF0, 0xBE, 0xFC, 0x68, 0x8B, 0x05, 0xF1, 0x5B, 0x03, 0x00, 0x22,
+ 0x69, 0x46, 0xF5, 0xF7, 0xF0, 0xFC, 0x00, 0x20, 0xE1, 0xE7, 0x07, 0x20,
+ 0xE7, 0xE7, 0x94, 0xF8, 0x74, 0x00, 0x18, 0xB1, 0x01, 0x20, 0x84, 0xF8,
+ 0x7F, 0x00, 0xF4, 0xE7, 0x28, 0x46, 0x02, 0xF0, 0xF9, 0xFC, 0x20, 0x68,
+ 0x40, 0xF0, 0x00, 0x50, 0x20, 0x60, 0xEC, 0xE7, 0x00, 0x00, 0x30, 0x21,
+ 0xB6, 0x76, 0x20, 0x00, 0x60, 0x3C, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21,
+ 0x00, 0x00, 0x50, 0x21, 0xF0, 0xB5, 0x49, 0x1C, 0x05, 0x46, 0x0E, 0x46,
+ 0x0A, 0x46, 0x04, 0x6A, 0x87, 0xB0, 0x10, 0x21, 0x1E, 0x48, 0xE1, 0xF7,
+ 0x08, 0xDE, 0x07, 0x46, 0x05, 0xF1, 0x0C, 0x01, 0x1C, 0x48, 0xE1, 0xF7,
+ 0x65, 0xDD, 0x03, 0x46, 0x0D, 0xF1, 0x08, 0x0E, 0x20, 0x68, 0x94, 0xF8,
+ 0x08, 0xC0, 0x62, 0x7A, 0x29, 0x7F, 0x8E, 0xE8, 0x07, 0x10, 0xA8, 0x68,
+ 0x07, 0x22, 0xCD, 0xE9, 0x00, 0x70, 0x15, 0x49, 0x15, 0x48, 0xE1, 0xF7,
+ 0x84, 0xDB, 0x28, 0x7A, 0x40, 0x07, 0x1C, 0xD5, 0x20, 0x88, 0x00, 0x05,
+ 0x19, 0xD4, 0x28, 0x7F, 0x10, 0xB1, 0x01, 0x28, 0x02, 0xD0, 0x04, 0xE0,
+ 0x60, 0x7A, 0x00, 0xE0, 0x20, 0x7A, 0xC0, 0x07, 0x0F, 0xD0, 0x60, 0x68,
+ 0x10, 0x22, 0x31, 0x46, 0x1C, 0x30, 0x13, 0xF4, 0x82, 0xF4, 0x20, 0x68,
+ 0x40, 0xF4, 0x00, 0x60, 0x20, 0x60, 0x28, 0x46, 0x01, 0xF0, 0xD2, 0xFE,
+ 0x00, 0x20, 0x07, 0xB0, 0xF0, 0xBD, 0x08, 0x20, 0xFB, 0xE7, 0x00, 0x00,
+ 0x00, 0x00, 0x50, 0x21, 0x00, 0x00, 0x30, 0x21, 0x84, 0x3E, 0xC0, 0x08,
+ 0x03, 0x39, 0x10, 0x21, 0x7C, 0xB5, 0x0D, 0x46, 0x06, 0x46, 0xFF, 0xF7,
+ 0x1B, 0xFB, 0xCD, 0xE9, 0x00, 0x65, 0x04, 0x46, 0x03, 0x46, 0x03, 0x22,
+ 0x13, 0x49, 0x14, 0x48, 0xE1, 0xF7, 0x4B, 0xDB, 0x00, 0x2C, 0x20, 0xD0,
+ 0x00, 0x2D, 0x1E, 0xD1, 0xA0, 0x68, 0x40, 0xF0, 0x04, 0x00, 0xA0, 0x60,
+ 0x20, 0x6A, 0x68, 0xB1, 0x40, 0x68, 0x84, 0x21, 0x13, 0xF4, 0xF2, 0xF4,
+ 0x20, 0x6A, 0x01, 0x68, 0x21, 0xF0, 0x40, 0x51, 0x01, 0x60, 0x20, 0x46,
+ 0xBD, 0xE8, 0x7C, 0x40, 0x01, 0xF0, 0x9E, 0xBE, 0x00, 0x22, 0x14, 0x21,
+ 0x20, 0x46, 0xFF, 0xF7, 0xD3, 0xF9, 0x20, 0x46, 0xBD, 0xE8, 0x7C, 0x40,
+ 0x00, 0x21, 0xFF, 0xF7, 0xE5, 0xB8, 0x7C, 0xBD, 0x5C, 0x2C, 0xC0, 0x08,
+ 0x02, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, 0x4F, 0x78,
+ 0x8E, 0x1C, 0x04, 0x6A, 0x00, 0x22, 0x1B, 0x49, 0x1B, 0x48, 0xE1, 0xF7,
+ 0x18, 0xDB, 0x28, 0x7A, 0x40, 0x07, 0x0E, 0xD5, 0x20, 0x68, 0x81, 0x03,
+ 0x0B, 0xD4, 0x01, 0x04, 0x09, 0xD5, 0x29, 0x7F, 0x11, 0xB1, 0x01, 0x29,
+ 0x02, 0xD0, 0x07, 0xE0, 0x61, 0x7A, 0x00, 0xE0, 0x21, 0x7A, 0x89, 0x07,
+ 0x02, 0xD4, 0x08, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x40, 0xF4, 0x00, 0x30,
+ 0x20, 0x60, 0xA9, 0x7C, 0x3B, 0x46, 0x32, 0x46, 0x05, 0xF1, 0x0C, 0x00,
+ 0xEC, 0xF7, 0x5C, 0xFD, 0x60, 0x68, 0x00, 0x21, 0x81, 0x64, 0xA0, 0xF8,
+ 0x4C, 0x10, 0x60, 0x68, 0x31, 0x68, 0x81, 0x64, 0xB1, 0x88, 0xA0, 0xF8,
+ 0x4C, 0x10, 0x60, 0x68, 0x80, 0xF8, 0x4E, 0x70, 0x28, 0x46, 0x01, 0xF0,
+ 0x53, 0xFE, 0x00, 0x20, 0xE0, 0xE7, 0x00, 0x00, 0x30, 0x3F, 0xC0, 0x08,
+ 0x02, 0x39, 0x10, 0x21, 0x70, 0xB5, 0x05, 0x46, 0x4E, 0x1C, 0x04, 0x6A,
+ 0x00, 0x22, 0x12, 0x49, 0x12, 0x48, 0xE1, 0xF7, 0xD8, 0xDA, 0x28, 0x7A,
+ 0x40, 0x07, 0x0C, 0xD5, 0x20, 0x68, 0x01, 0x04, 0x09, 0xD4, 0x29, 0x7F,
+ 0x11, 0xB1, 0x01, 0x29, 0x02, 0xD0, 0x06, 0xE0, 0x61, 0x7A, 0x00, 0xE0,
+ 0x21, 0x7A, 0x89, 0x07, 0x01, 0xD4, 0x08, 0x20, 0x70, 0xBD, 0x40, 0xF4,
+ 0x00, 0x40, 0x20, 0x60, 0x60, 0x68, 0x10, 0x22, 0x31, 0x46, 0x38, 0x30,
+ 0x13, 0xF4, 0xD1, 0xF3, 0x28, 0x46, 0x01, 0xF0, 0x25, 0xFE, 0x00, 0x20,
+ 0x70, 0xBD, 0x00, 0x00, 0x18, 0x3F, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21,
+ 0x70, 0xB5, 0x4C, 0x78, 0x05, 0x46, 0x23, 0x46, 0x01, 0x22, 0x06, 0x49,
+ 0x06, 0x48, 0xE1, 0xF7, 0xAA, 0xDA, 0xAA, 0x7C, 0x21, 0x46, 0x05, 0xF1,
+ 0x0C, 0x00, 0xEC, 0xF7, 0x46, 0xFE, 0x00, 0x20, 0x70, 0xBD, 0x00, 0x00,
+ 0x34, 0x3E, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x41,
+ 0x07, 0x46, 0x05, 0x1D, 0x00, 0x8A, 0xFF, 0xF7, 0x5D, 0xFA, 0x04, 0x00,
+ 0x4F, 0xF0, 0x00, 0x06, 0x14, 0xD0, 0x68, 0x89, 0xE2, 0x79, 0xA1, 0x79,
+ 0xA3, 0x68, 0x8D, 0xE8, 0x0F, 0x00, 0x2B, 0x89, 0x05, 0x22, 0x1D, 0x49,
+ 0x1D, 0x48, 0xE1, 0xF7, 0x86, 0xDA, 0x94, 0xF8, 0x24, 0x00, 0x40, 0xB1,
+ 0x04, 0xB0, 0x38, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0xFF, 0xF7, 0xF0, 0xB9,
+ 0x4F, 0xF4, 0x0D, 0x76, 0x22, 0xE0, 0x68, 0x89, 0xFF, 0xF7, 0x5A, 0xFA,
+ 0xF0, 0xB1, 0x41, 0x78, 0x01, 0x29, 0x06, 0xD0, 0x02, 0x29, 0x0C, 0xD0,
+ 0x05, 0x29, 0x10, 0xD1, 0x40, 0xF2, 0x36, 0x26, 0x14, 0xE0, 0xA1, 0x79,
+ 0x05, 0x29, 0x0A, 0xD0, 0x04, 0x29, 0x08, 0xD0, 0x4F, 0xF4, 0x0E, 0x76,
+ 0x0C, 0xE0, 0xA1, 0x79, 0x05, 0x29, 0x02, 0xD0, 0x40, 0xF2, 0x35, 0x26,
+ 0x06, 0xE0, 0xE1, 0x79, 0x21, 0xB1, 0x80, 0x78, 0x88, 0x42, 0x01, 0xD9,
+ 0x40, 0xF2, 0x37, 0x26, 0x28, 0x89, 0x04, 0xB0, 0x31, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x41, 0xF9, 0xF7, 0x43, 0xBA, 0x00, 0x00, 0x18, 0x43, 0xC0, 0x08,
+ 0x03, 0x39, 0x10, 0x21, 0x70, 0xB5, 0x00, 0x1D, 0x05, 0x46, 0x41, 0x7A,
+ 0xFF, 0xF7, 0x44, 0xFA, 0x04, 0x00, 0x0C, 0xD0, 0x94, 0xF8, 0x24, 0x30,
+ 0x63, 0xB1, 0x01, 0x22, 0x41, 0x49, 0x42, 0x48, 0xE1, 0xF7, 0x3B, 0xDA,
+ 0xE2, 0x79, 0xA1, 0x79, 0x40, 0xF2, 0xE6, 0x53, 0x1D, 0xE0, 0x40, 0xF2,
+ 0xE3, 0x53, 0x18, 0xE0, 0x3D, 0x49, 0xC8, 0x78, 0xC0, 0x06, 0x02, 0xD4,
+ 0x20, 0x7F, 0x01, 0x28, 0x0F, 0xD0, 0xA0, 0x68, 0x20, 0xF4, 0x6F, 0x40,
+ 0xA0, 0x60, 0x0A, 0x78, 0x52, 0x07, 0x02, 0xD4, 0xAA, 0x79, 0x52, 0x07,
+ 0x0E, 0xD5, 0x03, 0x22, 0x84, 0xF8, 0x24, 0x20, 0x40, 0xF4, 0xE0, 0x60,
+ 0x0D, 0xE0, 0x40, 0xF2, 0xEF, 0x53, 0x00, 0x22, 0x11, 0x46, 0x28, 0x46,
+ 0xBD, 0xE8, 0x70, 0x40, 0xEB, 0xF7, 0x88, 0xBE, 0x02, 0x22, 0x84, 0xF8,
+ 0x24, 0x20, 0x40, 0xF4, 0xA0, 0x60, 0xA0, 0x60, 0x08, 0x78, 0x00, 0x07,
+ 0x02, 0xD4, 0xA8, 0x79, 0x00, 0x07, 0x03, 0xD5, 0xA0, 0x68, 0x40, 0xF4,
+ 0x80, 0x40, 0xA0, 0x60, 0x08, 0x78, 0xC0, 0x06, 0x02, 0xD4, 0xA8, 0x79,
+ 0xC0, 0x06, 0x03, 0xD5, 0xA0, 0x68, 0x40, 0xF4, 0x00, 0x40, 0xA0, 0x60,
+ 0xE8, 0x88, 0xC0, 0x05, 0xA0, 0x68, 0x02, 0xD5, 0x40, 0xF4, 0x80, 0x50,
+ 0x01, 0xE0, 0x20, 0xF4, 0x80, 0x50, 0xA0, 0x60, 0x28, 0x7A, 0x00, 0xB9,
+ 0xC8, 0x7D, 0x60, 0x77, 0x00, 0x22, 0x10, 0x21, 0x20, 0x46, 0xFF, 0xF7,
+ 0x8B, 0xF8, 0x20, 0x7F, 0x10, 0xB1, 0x20, 0x6A, 0x40, 0xB1, 0x0B, 0xE0,
+ 0xA1, 0x7C, 0x04, 0xF1, 0x0C, 0x00, 0xBD, 0xE8, 0x70, 0x40, 0x12, 0x22,
+ 0xEC, 0xF7, 0x67, 0xBD, 0x20, 0x46, 0xFE, 0xF7, 0x33, 0xFF, 0x40, 0xB1,
+ 0x20, 0x46, 0xFF, 0xF7, 0x15, 0xFB, 0x01, 0x46, 0x20, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0x03, 0xF0, 0x79, 0xB9, 0x00, 0x22, 0x40, 0xF2, 0xE7, 0x53,
+ 0x11, 0x46, 0x28, 0x46, 0xEB, 0xF7, 0x3A, 0xFE, 0x04, 0x49, 0xBD, 0xE8,
+ 0x70, 0x40, 0x04, 0x48, 0x00, 0x22, 0x2C, 0x31, 0xC0, 0x1E, 0xE1, 0xF7,
+ 0xBC, 0x99, 0x00, 0x00, 0x74, 0x43, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21,
+ 0x88, 0x76, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x5F, 0x8B, 0x46, 0xD3, 0xF8,
+ 0x09, 0x10, 0x02, 0x91, 0xB3, 0xF8, 0x0D, 0x10, 0xAD, 0xF8, 0x0C, 0x10,
+ 0x1E, 0x7A, 0x1D, 0x46, 0x90, 0x46, 0x89, 0x46, 0x00, 0x28, 0x7A, 0xD1,
+ 0x31, 0x46, 0x05, 0xF1, 0x09, 0x00, 0xFE, 0xF7, 0xC3, 0xFE, 0x04, 0x00,
+ 0x73, 0xD0, 0x4F, 0xF0, 0x00, 0x0A, 0xCD, 0xF8, 0x00, 0xA0, 0xCD, 0xF8,
+ 0x04, 0xA0, 0xA4, 0xF8, 0x1A, 0xB0, 0x28, 0x78, 0x20, 0x77, 0x07, 0x20,
+ 0x60, 0x77, 0x68, 0x78, 0x01, 0x27, 0x60, 0x76, 0x02, 0x2E, 0x14, 0xD0,
+ 0x03, 0x2E, 0x12, 0xD0, 0x02, 0x99, 0x61, 0x65, 0xA4, 0xF8, 0x58, 0x90,
+ 0x84, 0xF8, 0x5A, 0x60, 0x3C, 0x4E, 0xA0, 0xB1, 0xDF, 0xF8, 0xF0, 0x90,
+ 0x01, 0x28, 0x16, 0xD0, 0x05, 0xF1, 0x0F, 0x01, 0x02, 0x28, 0x29, 0xD0,
+ 0x03, 0x28, 0x33, 0xD0, 0x5B, 0xE0, 0xD5, 0xF8, 0x15, 0x10, 0x61, 0x65,
+ 0xB5, 0xF8, 0x19, 0x10, 0xA4, 0xF8, 0x58, 0x10, 0x84, 0xF8, 0x5A, 0x70,
+ 0xE8, 0xE7, 0xD6, 0xF8, 0x2E, 0x00, 0xC4, 0xF8, 0x13, 0x00, 0x70, 0x8E,
+ 0x49, 0xE0, 0xB8, 0xF1, 0x00, 0x0F, 0x0E, 0xD0, 0x58, 0x46, 0xED, 0xF7,
+ 0x47, 0xFC, 0x20, 0xB1, 0x01, 0x68, 0xC4, 0xF8, 0x13, 0x10, 0x80, 0x88,
+ 0x3D, 0xE0, 0x00, 0x22, 0x29, 0x49, 0x48, 0x46, 0xE1, 0xF7, 0x57, 0xD9,
+ 0x39, 0xE0, 0x70, 0x6B, 0xC4, 0xF8, 0x13, 0x00, 0x30, 0x8F, 0x32, 0xE0,
+ 0x06, 0x22, 0x68, 0x46, 0x13, 0xF4, 0x16, 0xF2, 0x08, 0xB1, 0x67, 0x76,
+ 0x0A, 0xE0, 0x84, 0xF8, 0x19, 0xA0, 0x85, 0xF8, 0x01, 0xA0, 0xD6, 0xE7,
+ 0x67, 0x76, 0x06, 0x22, 0x68, 0x46, 0x13, 0xF4, 0x09, 0xF2, 0x28, 0xB1,
+ 0x55, 0xF8, 0x0F, 0x0F, 0xC4, 0xF8, 0x13, 0x00, 0xA8, 0x88, 0x1A, 0xE0,
+ 0x6F, 0x70, 0xB8, 0xF1, 0x00, 0x0F, 0xDE, 0xD0, 0x58, 0x46, 0xED, 0xF7,
+ 0x17, 0xFC, 0x38, 0xB1, 0x01, 0x68, 0xC4, 0xF8, 0x13, 0x10, 0x80, 0x88,
+ 0xA4, 0xF8, 0x17, 0x00, 0x06, 0xE0, 0x1B, 0xE0, 0x10, 0x49, 0x00, 0x22,
+ 0x3C, 0x31, 0x48, 0x46, 0xE1, 0xF7, 0x23, 0xD9, 0xD6, 0xF8, 0x3A, 0x00,
+ 0xC4, 0xF8, 0x13, 0x00, 0xF0, 0x8F, 0xA4, 0xF8, 0x17, 0x00, 0x30, 0x7E,
+ 0x00, 0x28, 0x0B, 0xD0, 0x04, 0xF1, 0x0C, 0x00, 0xA1, 0x7C, 0x16, 0x22,
+ 0x05, 0x46, 0xEC, 0xF7, 0xA0, 0xFC, 0xA1, 0x7C, 0x15, 0x22, 0x28, 0x46,
+ 0xEC, 0xF7, 0x9B, 0xFC, 0xBD, 0xE8, 0xFF, 0x9F, 0x88, 0x76, 0x20, 0x00,
+ 0x00, 0x39, 0x10, 0x21, 0x8C, 0x30, 0xC0, 0x08, 0x38, 0xB5, 0xFF, 0xF7,
+ 0xC9, 0xF8, 0x04, 0x00, 0x18, 0xD0, 0x94, 0xF8, 0x24, 0x00, 0x00, 0x90,
+ 0x23, 0x46, 0x02, 0x22, 0x0A, 0x49, 0x0B, 0x48, 0xE1, 0xF7, 0xF7, 0xD8,
+ 0x94, 0xF8, 0x24, 0x00, 0x20, 0xB1, 0x40, 0xF2, 0xE9, 0x51, 0x20, 0x46,
+ 0xFE, 0xF7, 0xAC, 0xFE, 0x20, 0x46, 0x01, 0xF0, 0x73, 0xFE, 0x20, 0x46,
+ 0xBD, 0xE8, 0x38, 0x40, 0x01, 0xF0, 0x96, 0xBE, 0x38, 0xBD, 0x00, 0x00,
+ 0xC4, 0x26, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, 0xFE, 0xB5, 0x16, 0x46,
+ 0x0D, 0x46, 0x07, 0x46, 0xFF, 0xF7, 0xA2, 0xF8, 0xCD, 0xE9, 0x00, 0x76,
+ 0x28, 0x4F, 0x04, 0x46, 0x03, 0x46, 0x04, 0x22, 0x25, 0x49, 0x02, 0x95,
+ 0x38, 0x46, 0xE1, 0xF7, 0xD0, 0xD8, 0x00, 0x2C, 0x43, 0xD0, 0x76, 0xB9,
+ 0xE0, 0x79, 0xA1, 0x79, 0xCD, 0xE9, 0x00, 0x10, 0x02, 0x95, 0xA2, 0x7C,
+ 0x0D, 0xB1, 0x06, 0x20, 0x00, 0xE0, 0x08, 0x20, 0x33, 0x46, 0x04, 0xF1,
+ 0x0C, 0x01, 0x03, 0xF0, 0x49, 0xF8, 0xA0, 0x68, 0x45, 0xB3, 0x40, 0xF0,
+ 0x04, 0x00, 0xA0, 0x60, 0x20, 0x6A, 0x00, 0x90, 0x16, 0x49, 0x94, 0xF8,
+ 0x6B, 0x30, 0x02, 0x22, 0x58, 0x31, 0x38, 0x46, 0xE1, 0xF7, 0xAF, 0xD8,
+ 0x20, 0x6A, 0x68, 0xB1, 0x40, 0x68, 0x84, 0x21, 0x13, 0xF4, 0x5E, 0xF2,
+ 0x20, 0x6A, 0x01, 0x68, 0x21, 0xF0, 0x40, 0x51, 0x01, 0x60, 0x20, 0x46,
+ 0xBD, 0xE8, 0xFE, 0x40, 0x01, 0xF0, 0x0A, 0xBC, 0x00, 0x22, 0x14, 0x21,
+ 0x20, 0x46, 0xFE, 0xF7, 0x3F, 0xFF, 0x00, 0x21, 0x03, 0xB0, 0x20, 0x46,
+ 0xBD, 0xE8, 0xF0, 0x40, 0xFE, 0xF7, 0x50, 0xBE, 0x20, 0xF0, 0x04, 0x00,
+ 0xA0, 0x60, 0xFF, 0x20, 0xA0, 0x71, 0x00, 0x20, 0xE0, 0x71, 0x31, 0x46,
+ 0xF0, 0xE7, 0xFE, 0xBD, 0xF8, 0x26, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21,
+ 0x2D, 0xE9, 0xF0, 0x4F, 0x8B, 0xB0, 0x01, 0x46, 0x10, 0x22, 0x02, 0xA8,
+ 0x13, 0xF4, 0x91, 0xF1, 0x79, 0x4E, 0x7A, 0x4D, 0xB3, 0x8D, 0xD8, 0x05,
+ 0x21, 0xD5, 0xD8, 0xB2, 0xFF, 0xF7, 0x9E, 0xF8, 0x04, 0x00, 0x4F, 0xF6,
+ 0xFF, 0x79, 0x12, 0xD0, 0xE0, 0x8C, 0xDF, 0xF8, 0xD0, 0xB1, 0xDF, 0xF8,
+ 0xD0, 0xA1, 0x00, 0x27, 0xC0, 0x1E, 0x25, 0x6A, 0x4F, 0xF0, 0x04, 0x08,
+ 0x0B, 0xF1, 0x03, 0x0B, 0x05, 0x28, 0x0B, 0xD2, 0xDF, 0xE8, 0x00, 0xF0,
+ 0x14, 0x17, 0x3F, 0x47, 0x7F, 0x00, 0x96, 0xF8, 0x2C, 0x30, 0x01, 0x22,
+ 0x6B, 0x49, 0x28, 0x46, 0xE1, 0xF7, 0x57, 0xD8, 0xB4, 0xE0, 0x69, 0x49,
+ 0x01, 0x22, 0x48, 0x31, 0x28, 0x46, 0xE1, 0xF7, 0x50, 0xD8, 0x0B, 0xB0,
+ 0xBD, 0xE8, 0xF0, 0x8F, 0xA4, 0xF8, 0x26, 0x80, 0x29, 0xE0, 0x0D, 0xF1,
+ 0x08, 0x08, 0x68, 0x68, 0x98, 0xE8, 0x0E, 0x10, 0x20, 0x30, 0x80, 0xE8,
+ 0x0E, 0x10, 0xE7, 0x84, 0x6A, 0x68, 0x10, 0x21, 0x50, 0x46, 0x20, 0x32,
+ 0xE1, 0xF7, 0xA7, 0xDA, 0x5B, 0x49, 0x03, 0x46, 0x01, 0x22, 0x94, 0x31,
+ 0x58, 0x46, 0xE1, 0xF7, 0x34, 0xD8, 0x28, 0x68, 0x40, 0xF0, 0x80, 0x50,
+ 0x28, 0x60, 0x21, 0x7F, 0x09, 0xB1, 0x80, 0x06, 0x08, 0xD5, 0x6A, 0x68,
+ 0x03, 0x21, 0x20, 0x46, 0x20, 0x32, 0x02, 0xF0, 0x97, 0xFC, 0x20, 0x46,
+ 0x03, 0xF0, 0xFE, 0xF8, 0x80, 0xE0, 0x06, 0x20, 0xE0, 0x84, 0x02, 0xAA,
+ 0x06, 0xA9, 0x20, 0x46, 0x01, 0xF0, 0x2A, 0xFB, 0x2F, 0xE0, 0xE7, 0x84,
+ 0x02, 0xAA, 0x10, 0x21, 0x50, 0x46, 0xE1, 0xF7, 0x80, 0xDA, 0x48, 0x49,
+ 0x03, 0x46, 0x01, 0x22, 0xCC, 0x31, 0x58, 0x46, 0xE1, 0xF7, 0x0D, 0xD8,
+ 0x68, 0x68, 0x10, 0x22, 0x02, 0xA9, 0x40, 0x30, 0x13, 0xF4, 0xD0, 0xF0,
+ 0x48, 0xB1, 0x04, 0x21, 0x20, 0x46, 0x02, 0xF0, 0xD3, 0xFE, 0x40, 0xF2,
+ 0x04, 0x51, 0x20, 0x46, 0xFE, 0xF7, 0xBA, 0xFD, 0x5A, 0xE0, 0x20, 0x7F,
+ 0x01, 0x28, 0x08, 0xD1, 0x6A, 0x68, 0x04, 0x21, 0x20, 0x46, 0x10, 0x32,
+ 0x02, 0xF0, 0x64, 0xFC, 0x20, 0x46, 0x03, 0xF0, 0xCB, 0xF8, 0x07, 0x20,
+ 0xE0, 0x84, 0x06, 0xA9, 0x20, 0x46, 0x01, 0xF0, 0x3D, 0xFB, 0x60, 0x79,
+ 0x06, 0xAA, 0x40, 0xF4, 0x80, 0x70, 0x69, 0x68, 0x02, 0xF0, 0xB2, 0xFC,
+ 0x40, 0xE0, 0xE7, 0x84, 0xE0, 0x79, 0x10, 0x28, 0x05, 0xD2, 0xC0, 0xF1,
+ 0x10, 0x01, 0x02, 0xAA, 0x10, 0x44, 0x13, 0xF4, 0x6B, 0xF1, 0xA8, 0x7A,
+ 0x01, 0x28, 0x38, 0xD0, 0x02, 0x28, 0x36, 0xD0, 0x03, 0x28, 0x34, 0xD0,
+ 0xA0, 0x68, 0x20, 0xF0, 0x80, 0x00, 0x40, 0xF0, 0x01, 0x00, 0xA0, 0x60,
+ 0x84, 0xF8, 0x06, 0x80, 0x02, 0xAA, 0x10, 0x21, 0x50, 0x46, 0xE1, 0xF7,
+ 0x30, 0xDA, 0x03, 0x46, 0xE1, 0x79, 0xA0, 0x79, 0xCD, 0xE9, 0x00, 0x01,
+ 0x03, 0x22, 0x1E, 0x49, 0x58, 0x46, 0xE0, 0xF7, 0xBA, 0xDF, 0x28, 0x68,
+ 0x40, 0xF0, 0x00, 0x50, 0x28, 0x60, 0x20, 0x7F, 0x00, 0xB3, 0x0D, 0xF1,
+ 0x08, 0x08, 0x68, 0x68, 0x98, 0xE8, 0x8E, 0x00, 0x80, 0xE8, 0x8E, 0x00,
+ 0x28, 0x68, 0x40, 0x00, 0x08, 0xD5, 0x20, 0x6A, 0x01, 0x68, 0x21, 0xF0,
+ 0x80, 0x41, 0x01, 0x60, 0x60, 0x8B, 0x69, 0x68, 0xF4, 0xF7, 0x6A, 0xFE,
+ 0xA6, 0xF8, 0x2C, 0x90, 0x03, 0xF0, 0x92, 0xF8, 0x4B, 0xE7, 0xA0, 0x68,
+ 0x20, 0xF0, 0x80, 0x00, 0x40, 0xF0, 0x03, 0x00, 0xA0, 0x60, 0x05, 0x20,
+ 0xA0, 0x71, 0xC9, 0xE7, 0x06, 0x97, 0x07, 0x97, 0x60, 0x8B, 0x02, 0xAB,
+ 0x00, 0x22, 0x06, 0xA9, 0xF5, 0xF7, 0xB7, 0xF8, 0xE8, 0xE7, 0x00, 0x00,
+ 0x88, 0x76, 0x20, 0x00, 0x00, 0x39, 0x10, 0x21, 0x00, 0x00, 0x50, 0x21,
+ 0xAC, 0x2C, 0xC0, 0x08, 0xB0, 0x2D, 0xC0, 0x08, 0xFE, 0xB5, 0x05, 0x46,
+ 0x0F, 0x46, 0x16, 0x46, 0x10, 0x46, 0xFE, 0xF7, 0x3F, 0xFF, 0x04, 0x46,
+ 0x3A, 0x46, 0x08, 0x21, 0x29, 0x48, 0xE1, 0xF7, 0xDE, 0xD9, 0x00, 0x96,
+ 0xCD, 0xE9, 0x01, 0x50, 0x23, 0x46, 0x04, 0x22, 0x26, 0x49, 0x27, 0x48,
+ 0xE0, 0xF7, 0x69, 0xDF, 0x00, 0x2C, 0x32, 0xD0, 0x20, 0x7F, 0x01, 0x28,
+ 0x0D, 0xD0, 0x00, 0x22, 0x13, 0x21, 0x20, 0x46, 0xFE, 0xF7, 0x04, 0xFE,
+ 0xA1, 0x7C, 0x03, 0xB0, 0x04, 0xF1, 0x0C, 0x00, 0xBD, 0xE8, 0xF0, 0x40,
+ 0x11, 0x22, 0xEC, 0xF7, 0xE4, 0xBA, 0x00, 0x20, 0x1B, 0x4E, 0x00, 0x90,
+ 0x76, 0x1C, 0x01, 0x90, 0xE5, 0xB9, 0x08, 0x22, 0x69, 0x46, 0x38, 0x46,
+ 0x13, 0xF4, 0x14, 0xF0, 0xB0, 0xB9, 0x20, 0x6A, 0xA0, 0xB1, 0x00, 0x68,
+ 0x80, 0x00, 0x11, 0xD5, 0x12, 0x49, 0x00, 0x22, 0x4C, 0x31, 0x30, 0x46,
+ 0xE0, 0xF7, 0x3F, 0xDF, 0x94, 0xF8, 0x6B, 0x00, 0x10, 0xB1, 0x04, 0xF1,
+ 0x5B, 0x01, 0x01, 0xE0, 0x20, 0x6A, 0x41, 0x68, 0x60, 0x8B, 0xF4, 0xF7,
+ 0xFD, 0xFD, 0xFE, 0xBD, 0x09, 0x49, 0x00, 0x22, 0x98, 0x31, 0x30, 0x46,
+ 0xE0, 0xF7, 0x2D, 0xDF, 0x00, 0x22, 0x13, 0x21, 0x20, 0x46, 0xFE, 0xF7,
+ 0xCD, 0xFD, 0xA1, 0x7C, 0x11, 0x22, 0x04, 0xF1, 0x0C, 0x00, 0xEC, 0xF7,
+ 0xB0, 0xFA, 0xFE, 0xBD, 0x00, 0x00, 0x50, 0x21, 0xF4, 0x25, 0xC0, 0x08,
+ 0x02, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x4F, 0x87, 0xB0, 0x01, 0x68,
+ 0x05, 0x91, 0xE7, 0x4E, 0x40, 0x68, 0x06, 0x90, 0x00, 0x25, 0xB3, 0x8D,
+ 0xE5, 0x4F, 0x2C, 0x46, 0xD8, 0x05, 0x4F, 0xF6, 0xFF, 0x7A, 0x0E, 0xD5,
+ 0xD8, 0xB2, 0xFE, 0xF7, 0x31, 0xFF, 0x05, 0x00, 0x03, 0xD0, 0xB5, 0xF8,
+ 0x26, 0x80, 0x2C, 0x6A, 0x09, 0xE0, 0x96, 0xF8, 0x2C, 0x30, 0x01, 0x22,
+ 0xDD, 0x49, 0x38, 0x46, 0xAC, 0xE1, 0x58, 0x05, 0x1F, 0xD5, 0x96, 0xF8,
+ 0x48, 0x80, 0xDA, 0x49, 0xD8, 0x48, 0x43, 0x46, 0x01, 0x22, 0x8C, 0x31,
+ 0xC0, 0x1C, 0xE0, 0xF7, 0xF0, 0xDE, 0xDF, 0xF8, 0x5C, 0xB3, 0x4F, 0xF0,
+ 0x00, 0x09, 0x00, 0x2D, 0x7E, 0xD0, 0xB8, 0xF1, 0x11, 0x0F, 0x7C, 0xD0,
+ 0x14, 0xDC, 0x4F, 0xF0, 0x02, 0x07, 0xB8, 0xF1, 0x01, 0x0F, 0x19, 0xD0,
+ 0xB8, 0xF1, 0x02, 0x0F, 0x1D, 0xD0, 0xB8, 0xF1, 0x08, 0x0F, 0x49, 0xD1,
+ 0xC0, 0xE0, 0xCB, 0x49, 0x01, 0x22, 0x44, 0x31, 0x38, 0x46, 0xE0, 0xF7,
+ 0xD4, 0xDE, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xB8, 0xF1, 0x12, 0x0F,
+ 0x7E, 0xD0, 0xB8, 0xF1, 0x13, 0x0F, 0x7C, 0xD0, 0xB8, 0xF1, 0x14, 0x0F,
+ 0xEB, 0xD1, 0x1B, 0xE1, 0xDD, 0xE9, 0x05, 0x12, 0x60, 0x68, 0xC0, 0xE9,
+ 0x04, 0x12, 0xEF, 0x84, 0xD6, 0xE0, 0xDD, 0xE9, 0x05, 0x12, 0x60, 0x68,
+ 0xC0, 0xE9, 0x06, 0x12, 0x62, 0x68, 0x10, 0x21, 0x58, 0x46, 0x10, 0x32,
+ 0xE1, 0xF7, 0x21, 0xD9, 0x03, 0x46, 0xB8, 0x49, 0xB6, 0x48, 0x01, 0x22,
+ 0xB8, 0x31, 0xC0, 0x1C, 0xE0, 0xF7, 0xAD, 0xDE, 0x95, 0xF8, 0x6B, 0x00,
+ 0x48, 0xB1, 0x84, 0xF8, 0x80, 0x70, 0x94, 0xF8, 0x81, 0x00, 0x04, 0x28,
+ 0x12, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x11, 0x12, 0x6D, 0x83, 0x03, 0x20,
+ 0xE8, 0x84, 0x62, 0x68, 0x69, 0x46, 0x28, 0x46, 0x10, 0x32, 0x01, 0xF0,
+ 0x6B, 0xF9, 0x68, 0x79, 0x6A, 0x46, 0x40, 0xF4, 0x80, 0x70, 0x61, 0x68,
+ 0x02, 0xF0, 0x60, 0xFB, 0x42, 0xE1, 0x01, 0xA8, 0xCD, 0xF8, 0x04, 0x90,
+ 0xCD, 0xF8, 0x08, 0x90, 0xCD, 0xF8, 0x0C, 0x90, 0xCD, 0xF8, 0x10, 0x90,
+ 0x00, 0x90, 0xE0, 0x6B, 0x62, 0x68, 0x4F, 0x46, 0x00, 0xF1, 0x40, 0x01,
+ 0x00, 0x23, 0x10, 0x32, 0x0F, 0xF4, 0x31, 0xF7, 0x01, 0xAA, 0x10, 0x21,
+ 0x58, 0x46, 0xE1, 0xF7, 0xE4, 0xD8, 0x03, 0x46, 0x99, 0x49, 0x98, 0x48,
+ 0x01, 0x22, 0xEC, 0x31, 0x80, 0x1C, 0xE0, 0xF7, 0x70, 0xDE, 0x98, 0x48,
+ 0x90, 0xF8, 0x78, 0x01, 0x80, 0x07, 0x01, 0xE0, 0xE9, 0xE0, 0x83, 0xE0,
+ 0x27, 0xD5, 0xB0, 0x68, 0xB0, 0xF5, 0x87, 0x7F, 0x02, 0xD0, 0xB0, 0xF5,
+ 0x82, 0x7F, 0x20, 0xD1, 0x0B, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x09, 0x21,
+ 0x8D, 0xF8, 0x05, 0x10, 0x8D, 0xF8, 0x06, 0x00, 0x8D, 0xF8, 0x07, 0x00,
+ 0x0A, 0x20, 0x8D, 0xF8, 0x08, 0x00, 0x0D, 0x20, 0x8D, 0xF8, 0x09, 0x00,
+ 0x0C, 0x20, 0x01, 0xE0, 0x6F, 0xE0, 0x9A, 0xE0, 0x8D, 0xF8, 0x0A, 0x00,
+ 0x0F, 0x20, 0x8D, 0xF8, 0x0C, 0x00, 0x8D, 0xF8, 0x0D, 0x70, 0x8D, 0xF8,
+ 0x0E, 0x70, 0x8D, 0xF8, 0x0B, 0x00, 0x8D, 0xF8, 0x0F, 0x70, 0x01, 0xAA,
+ 0x03, 0x21, 0x28, 0x46, 0x02, 0xF0, 0xAC, 0xFA, 0x28, 0x46, 0x02, 0xF0,
+ 0x13, 0xFF, 0x84, 0xF8, 0x81, 0x70, 0xE7, 0xE0, 0x62, 0x68, 0x10, 0x21,
+ 0x58, 0x46, 0x10, 0x32, 0xE1, 0xF7, 0x9B, 0xD8, 0x03, 0x46, 0x74, 0x48,
+ 0x01, 0x22, 0x77, 0x49, 0x80, 0x1C, 0xE0, 0xF7, 0x28, 0xDE, 0x62, 0x68,
+ 0x04, 0x21, 0x28, 0x46, 0x10, 0x32, 0x02, 0xF0, 0x93, 0xFA, 0x28, 0x46,
+ 0x02, 0xF0, 0xFA, 0xFE, 0x28, 0x46, 0x02, 0xF0, 0x8D, 0xF9, 0x84, 0xF8,
+ 0x81, 0x90, 0xCB, 0xE0, 0x05, 0xA8, 0xFE, 0xF7, 0x55, 0xFE, 0x07, 0x46,
+ 0x30, 0x6A, 0x41, 0x1C, 0x08, 0xD0, 0x07, 0x46, 0x69, 0x49, 0x65, 0x48,
+ 0x3B, 0x46, 0x01, 0x22, 0x34, 0x31, 0xC0, 0x1C, 0xE0, 0xF7, 0x09, 0xDE,
+ 0x78, 0x1C, 0x1B, 0xD0, 0x95, 0xF8, 0x6B, 0x00, 0x08, 0xB1, 0xA7, 0x67,
+ 0x07, 0xE0, 0x60, 0x68, 0x07, 0x70, 0x61, 0x68, 0x38, 0x0A, 0x48, 0x70,
+ 0x61, 0x68, 0x38, 0x0C, 0x88, 0x70, 0x5E, 0x49, 0x59, 0x48, 0x3B, 0x46,
+ 0x01, 0x22, 0x70, 0x31, 0x80, 0x1C, 0xE0, 0xF7, 0xF2, 0xDD, 0xAA, 0x7C,
+ 0x39, 0x46, 0x05, 0xF1, 0x0C, 0x00, 0xED, 0xF7, 0x07, 0xFF, 0x9D, 0xE0,
+ 0x08, 0x20, 0xE8, 0x84, 0x68, 0x79, 0x40, 0xF4, 0x80, 0x70, 0x76, 0xE0,
+ 0xDD, 0xE9, 0x05, 0x12, 0x60, 0x68, 0xC0, 0xE9, 0x00, 0x12, 0x12, 0x20,
+ 0xF3, 0xE7, 0xDD, 0xE9, 0x05, 0x12, 0x60, 0x68, 0xC0, 0xE9, 0x02, 0x12,
+ 0xA5, 0xF8, 0x26, 0x90, 0xE8, 0x79, 0x10, 0x28, 0x06, 0xD2, 0x61, 0x68,
+ 0x0A, 0x18, 0xC0, 0xF1, 0x10, 0x01, 0x10, 0x46, 0x12, 0xF4, 0x60, 0xF7,
+ 0x10, 0x21, 0x58, 0x46, 0x62, 0x68, 0xE1, 0xF7, 0x34, 0xD8, 0x03, 0x46,
+ 0xE8, 0x79, 0x00, 0x90, 0x43, 0x49, 0x3F, 0x48, 0x02, 0x22, 0xA8, 0x31,
+ 0x80, 0x1C, 0xE0, 0xF7, 0xBE, 0xDD, 0x06, 0x21, 0x28, 0x46, 0x62, 0x68,
+ 0x02, 0xF0, 0x2A, 0xFA, 0x28, 0x46, 0x02, 0xF0, 0x91, 0xFE, 0x28, 0x46,
+ 0x01, 0xF0, 0x1E, 0xF9, 0x64, 0xE0, 0xDD, 0xE9, 0x05, 0x12, 0x60, 0x68,
+ 0xC0, 0xE9, 0x04, 0x12, 0x14, 0x20, 0xC0, 0xE7, 0x9D, 0xF8, 0x14, 0x00,
+ 0x9D, 0xF8, 0x15, 0x10, 0x00, 0xEB, 0x01, 0x20, 0x61, 0x68, 0x08, 0x83,
+ 0xA5, 0xF8, 0x26, 0x90, 0x62, 0x68, 0x08, 0x21, 0x58, 0x46, 0x10, 0x32,
+ 0xE1, 0xF7, 0x07, 0xD8, 0x00, 0x90, 0x60, 0x68, 0x2D, 0x49, 0x02, 0x22,
+ 0x03, 0x8B, 0x28, 0x48, 0xDC, 0x31, 0x80, 0x1C, 0xE0, 0xF7, 0x91, 0xDD,
+ 0x60, 0x68, 0x00, 0xF1, 0x10, 0x02, 0x01, 0x8B, 0x28, 0x46, 0x02, 0xF0,
+ 0x99, 0xFB, 0x28, 0x46, 0x02, 0xF0, 0x62, 0xFE, 0x61, 0x68, 0xE8, 0x79,
+ 0x88, 0x76, 0x61, 0x68, 0xA8, 0x79, 0xC8, 0x76, 0xC9, 0xE7, 0xB8, 0xF1,
+ 0x21, 0x0F, 0x03, 0xD0, 0xB8, 0xF1, 0x22, 0x0F, 0x2C, 0xD1, 0x0D, 0xE0,
+ 0x05, 0x98, 0xC6, 0xF8, 0x49, 0x00, 0x06, 0x98, 0xC6, 0xF8, 0x4D, 0x00,
+ 0x22, 0x20, 0x86, 0xF8, 0x48, 0x00, 0x4F, 0xF4, 0x80, 0x60, 0x02, 0xF0,
+ 0x71, 0xFA, 0x1D, 0xE0, 0x05, 0x98, 0xC6, 0xF8, 0x51, 0x00, 0x06, 0x98,
+ 0xC6, 0xF8, 0x55, 0x00, 0x01, 0x20, 0x0E, 0x4A, 0x86, 0xF8, 0x48, 0x90,
+ 0x86, 0xF8, 0x47, 0x00, 0x49, 0x32, 0x01, 0x46, 0x14, 0x46, 0x00, 0x20,
+ 0xEC, 0xF7, 0x74, 0xFA, 0x22, 0x46, 0x10, 0x21, 0x58, 0x46, 0xE0, 0xF7,
+ 0xC0, 0xDF, 0x03, 0x46, 0x06, 0x48, 0x01, 0x22, 0x0A, 0x49, 0x80, 0x1C,
+ 0xE0, 0xF7, 0x4D, 0xDD, 0xA6, 0xF8, 0x2C, 0xA0, 0x02, 0xF0, 0x3E, 0xFE,
+ 0x73, 0xE6, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00, 0x00, 0x39, 0x10, 0x21,
+ 0x00, 0x2A, 0xC0, 0x08, 0x00, 0x00, 0x50, 0x21, 0x64, 0x01, 0x20, 0x00,
+ 0x20, 0x2B, 0xC0, 0x08, 0x30, 0x2C, 0xC0, 0x08, 0x2D, 0xE9, 0xF0, 0x47,
+ 0x34, 0x4E, 0x80, 0x46, 0x00, 0x25, 0xB3, 0x8D, 0xDF, 0xF8, 0xCC, 0x90,
+ 0x8A, 0x46, 0xD8, 0x05, 0x1B, 0xD5, 0xD8, 0xB2, 0xFE, 0xF7, 0x54, 0xFD,
+ 0x04, 0x00, 0x4F, 0xF6, 0xFF, 0x77, 0x0E, 0xD0, 0x20, 0x6A, 0x90, 0xF8,
+ 0x71, 0x30, 0x01, 0x2B, 0x17, 0xD0, 0x2C, 0x49, 0x01, 0x22, 0x48, 0x46,
+ 0xE0, 0xF7, 0x1D, 0xDD, 0xB7, 0x85, 0xBD, 0xE8, 0xF0, 0x47, 0x02, 0xF0,
+ 0x0D, 0xBE, 0x27, 0x49, 0x01, 0x22, 0x96, 0xF8, 0x2C, 0x30, 0x44, 0x39,
+ 0xF1, 0xE7, 0x48, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x22, 0x49, 0x01, 0x22,
+ 0x38, 0x31, 0xE0, 0xF7, 0x0A, 0x9D, 0xB8, 0xF1, 0x00, 0x0F, 0x1F, 0xD0,
+ 0x02, 0x21, 0x80, 0xF8, 0x71, 0x10, 0x20, 0x6A, 0x20, 0x22, 0x51, 0x46,
+ 0x40, 0x30, 0x12, 0xF4, 0x12, 0xF6, 0x20, 0x6A, 0x90, 0xF8, 0x7D, 0x00,
+ 0x18, 0xB1, 0x20, 0x46, 0x01, 0xF0, 0x3E, 0xFC, 0x05, 0x46, 0x20, 0x6A,
+ 0x90, 0xF8, 0x72, 0x10, 0x89, 0xB1, 0x41, 0x68, 0x20, 0x46, 0x30, 0x31,
+ 0x01, 0xF0, 0x70, 0xFD, 0x21, 0x6A, 0x05, 0x46, 0x00, 0x20, 0x81, 0xF8,
+ 0x72, 0x00, 0x06, 0xE0, 0x0E, 0x49, 0x08, 0x25, 0x00, 0x22, 0x80, 0x31,
+ 0x48, 0x46, 0xE0, 0xF7, 0xE0, 0xDC, 0xB7, 0x85, 0x02, 0xF0, 0xD2, 0xFD,
+ 0x00, 0x2D, 0x0A, 0xD0, 0x29, 0x46, 0x20, 0x46, 0x02, 0xF0, 0xA8, 0xFB,
+ 0x45, 0xF4, 0xA0, 0x61, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0xFE, 0xF7,
+ 0x8D, 0xBA, 0xBD, 0xE8, 0xF0, 0x87, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00,
+ 0x00, 0x39, 0x10, 0x21, 0xE8, 0x2F, 0xC0, 0x08, 0x2D, 0xE9, 0xF7, 0x4F,
+ 0xDF, 0xF8, 0xFC, 0xA0, 0x93, 0x46, 0x80, 0x46, 0x03, 0x46, 0x01, 0x22,
+ 0x3B, 0x49, 0x50, 0x46, 0xE0, 0xF7, 0xBB, 0xDC, 0x3B, 0x4E, 0xAA, 0xF1,
+ 0x02, 0x09, 0xB3, 0x8D, 0xD8, 0x05, 0x18, 0xD5, 0xD8, 0xB2, 0xFE, 0xF7,
+ 0xDB, 0xFC, 0x04, 0x00, 0x4F, 0xF6, 0xFF, 0x77, 0x0B, 0xD0, 0x25, 0x6A,
+ 0x95, 0xF8, 0x70, 0x30, 0x01, 0x2B, 0x15, 0xD0, 0x30, 0x49, 0x01, 0x22,
+ 0x68, 0x31, 0x48, 0x46, 0xE0, 0xF7, 0xA3, 0xDC, 0x54, 0xE0, 0x2D, 0x49,
+ 0x01, 0x22, 0x96, 0xF8, 0x2C, 0x30, 0x28, 0x31, 0xF5, 0xE7, 0x03, 0xB0,
+ 0x48, 0x46, 0xBD, 0xE8, 0xF0, 0x4F, 0x28, 0x49, 0x01, 0x22, 0xA4, 0x31,
+ 0xE0, 0xF7, 0x93, 0x9C, 0xB8, 0xF1, 0x00, 0x0F, 0x33, 0xD0, 0x40, 0x22,
+ 0xE8, 0x6B, 0x01, 0x99, 0x12, 0xF4, 0x9F, 0xF5, 0x20, 0x6A, 0x20, 0x22,
+ 0x59, 0x46, 0x19, 0x30, 0x12, 0xF4, 0x99, 0xF5, 0x02, 0x20, 0x85, 0xF8,
+ 0x70, 0x00, 0x21, 0x6A, 0x01, 0x20, 0x81, 0xF8, 0x80, 0x00, 0xA9, 0x7A,
+ 0x01, 0x29, 0x00, 0xD1, 0x08, 0x20, 0xE0, 0x84, 0x60, 0x79, 0x40, 0xF4,
+ 0x80, 0x70, 0x02, 0xF0, 0x79, 0xF9, 0x95, 0xF8, 0x73, 0x00, 0x18, 0xB3,
+ 0x20, 0x46, 0x02, 0xF0, 0x41, 0xF8, 0x20, 0x46, 0x02, 0xF0, 0x46, 0xFD,
+ 0x20, 0x7F, 0x01, 0x28, 0x1A, 0xD1, 0x10, 0x49, 0x00, 0x22, 0xEC, 0x31,
+ 0x50, 0x46, 0xE0, 0xF7, 0x62, 0xDC, 0x20, 0x46, 0x01, 0xF0, 0xFC, 0xFA,
+ 0x05, 0x00, 0x06, 0xD1, 0x0E, 0xE0, 0x08, 0x25, 0x00, 0x22, 0x0C, 0x49,
+ 0x48, 0x46, 0xE0, 0xF7, 0x56, 0xDC, 0x29, 0x46, 0x20, 0x46, 0x02, 0xF0,
+ 0x23, 0xFB, 0x45, 0xF4, 0xA0, 0x61, 0x20, 0x46, 0xFE, 0xF7, 0x0A, 0xFA,
+ 0xB7, 0x85, 0xBD, 0xE8, 0xFE, 0x4F, 0x02, 0xF0, 0x3D, 0xBD, 0x00, 0x00,
+ 0x44, 0x2E, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, 0x88, 0x76, 0x20, 0x00,
+ 0x78, 0x2F, 0xC0, 0x08, 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, 0x04, 0x6A,
+ 0x11, 0xF8, 0x01, 0x0F, 0x8F, 0x1C, 0x4A, 0x78, 0x19, 0x49, 0x00, 0xEB,
+ 0x02, 0x20, 0x86, 0xB2, 0x00, 0x22, 0x18, 0x48, 0xE0, 0xF7, 0x2F, 0xDC,
+ 0x28, 0x7A, 0x40, 0x07, 0x26, 0xD5, 0x20, 0x68, 0x81, 0x04, 0x23, 0xD4,
+ 0x01, 0x05, 0x21, 0xD5, 0x29, 0x7F, 0x11, 0xB1, 0x01, 0x29, 0x02, 0xD0,
+ 0x04, 0xE0, 0x61, 0x7A, 0x00, 0xE0, 0x21, 0x7A, 0xC9, 0x07, 0x17, 0xD0,
+ 0x40, 0xF4, 0x00, 0x50, 0x20, 0x60, 0x60, 0x68, 0x39, 0x68, 0xC1, 0x62,
+ 0x79, 0x68, 0x01, 0x63, 0x60, 0x68, 0x86, 0x86, 0x61, 0x68, 0xE8, 0x79,
+ 0x81, 0xF8, 0x36, 0x00, 0x61, 0x68, 0xA8, 0x79, 0x81, 0xF8, 0x37, 0x00,
+ 0x28, 0x46, 0x00, 0xF0, 0x73, 0xFF, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81,
+ 0x08, 0x20, 0xFB, 0xE7, 0xFC, 0x3E, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21,
+ 0x10, 0xB5, 0x03, 0x88, 0x04, 0x46, 0x18, 0x46, 0xB3, 0xF5, 0x81, 0x6F,
+ 0x27, 0xD0, 0x06, 0xDC, 0xA0, 0xF5, 0x80, 0x63, 0x02, 0x3B, 0x17, 0xD0,
+ 0x01, 0x2B, 0x08, 0xD1, 0x0F, 0xE0, 0xA0, 0xF5, 0x80, 0x63, 0x09, 0x3B,
+ 0x26, 0xD0, 0xA3, 0xF5, 0x80, 0x73, 0xF7, 0x3B, 0x11, 0xD0, 0x03, 0x46,
+ 0xBD, 0xE8, 0x10, 0x40, 0x01, 0x22, 0x16, 0x49, 0x16, 0x48, 0xE0, 0xF7,
+ 0xE0, 0x9B, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0xFF, 0xF7, 0x3E, 0xB9,
+ 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0xFF, 0xF7, 0x8B, 0xB9, 0xE1, 0x88,
+ 0x60, 0x79, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0x8F, 0xBD, 0xE1, 0x68,
+ 0x01, 0xF1, 0x41, 0x02, 0x08, 0x78, 0x49, 0x1C, 0xFF, 0xF7, 0x02, 0xFF,
+ 0x40, 0xF2, 0x3D, 0x12, 0xE0, 0x68, 0x07, 0xE0, 0xE1, 0x68, 0x11, 0xF8,
+ 0x01, 0x0B, 0xFF, 0xF7, 0x87, 0xFE, 0xE0, 0x68, 0x4F, 0xF4, 0xA3, 0x72,
+ 0xBD, 0xE8, 0x10, 0x40, 0x03, 0x49, 0xE8, 0xF7, 0x3B, 0xBA, 0x00, 0x00,
+ 0xC8, 0x41, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21, 0x92, 0xAA, 0x82, 0x00,
+ 0x70, 0xB5, 0x04, 0x6A, 0x05, 0x46, 0x10, 0x22, 0x60, 0x68, 0x49, 0x1C,
+ 0x40, 0x30, 0x12, 0xF4, 0xBC, 0xF4, 0x20, 0x68, 0x00, 0x22, 0x40, 0xF0,
+ 0x20, 0x00, 0x20, 0x60, 0x16, 0x49, 0x17, 0x48, 0xE0, 0xF7, 0x9F, 0xDB,
+ 0x95, 0xF8, 0x6B, 0x00, 0x88, 0xB1, 0x01, 0x20, 0x84, 0xF8, 0x7E, 0x00,
+ 0x13, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x80, 0x07, 0x03, 0xD5, 0x12, 0x48,
+ 0x80, 0x68, 0xA0, 0x28, 0x03, 0xD0, 0x28, 0x46, 0x01, 0xF0, 0x98, 0xFA,
+ 0x0F, 0xE0, 0x04, 0x20, 0x70, 0xBD, 0x28, 0x7F, 0x68, 0xB1, 0x20, 0x68,
+ 0xC0, 0x00, 0x05, 0xD5, 0x62, 0x68, 0x03, 0x21, 0x28, 0x46, 0x20, 0x32,
+ 0x01, 0xF0, 0xF0, 0xFF, 0x28, 0x46, 0x02, 0xF0, 0x57, 0xFC, 0x00, 0x20,
+ 0x70, 0xBD, 0x62, 0x68, 0x04, 0x21, 0x28, 0x46, 0x10, 0x32, 0xF3, 0xE7,
+ 0x64, 0x3E, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, 0x64, 0x01, 0x20, 0x00,
+ 0x88, 0x76, 0x20, 0x00, 0x38, 0xB5, 0x4C, 0x78, 0x05, 0x46, 0x00, 0xF1,
+ 0x0C, 0x01, 0x08, 0x48, 0xE0, 0xF7, 0x34, 0xDD, 0x03, 0x46, 0x02, 0x22,
+ 0x06, 0x49, 0x07, 0x48, 0x00, 0x94, 0xE0, 0xF7, 0x5E, 0xDB, 0x28, 0x6A,
+ 0x01, 0x68, 0x41, 0xF4, 0x00, 0x71, 0x01, 0x60, 0x20, 0x46, 0x38, 0xBD,
+ 0x00, 0x00, 0x30, 0x21, 0x04, 0x3E, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21,
+ 0x7F, 0xB5, 0x04, 0x6A, 0x4E, 0x1C, 0x05, 0x46, 0xA1, 0x7A, 0x90, 0xF8,
+ 0x6B, 0x00, 0xCD, 0xE9, 0x00, 0x01, 0x20, 0x78, 0x03, 0x22, 0x00, 0xF0,
+ 0x80, 0x03, 0x33, 0x49, 0x33, 0x48, 0xE0, 0xF7, 0x40, 0xDB, 0x20, 0x78,
+ 0x00, 0x06, 0x0F, 0xD5, 0x95, 0xF8, 0x6B, 0x00, 0x20, 0xB1, 0xA0, 0x7A,
+ 0x02, 0x28, 0x09, 0xD0, 0x01, 0x28, 0x07, 0xD0, 0x2B, 0x49, 0x2C, 0x48,
+ 0x00, 0x22, 0x60, 0x31, 0x40, 0x1E, 0xE0, 0xF7, 0x2E, 0xDB, 0x4D, 0xE0,
+ 0x60, 0x68, 0x10, 0x22, 0x31, 0x46, 0x30, 0x30, 0x12, 0xF4, 0x3B, 0xF4,
+ 0x20, 0x68, 0x40, 0xF0, 0x80, 0x00, 0x20, 0x60, 0x95, 0xF8, 0x6B, 0x00,
+ 0x80, 0xB3, 0x23, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x80, 0x07, 0x05, 0xD5,
+ 0x21, 0x48, 0x80, 0x68, 0x9A, 0x28, 0x09, 0xD0, 0xA1, 0x28, 0x0A, 0xD0,
+ 0x94, 0xF8, 0x71, 0x00, 0x02, 0x28, 0x08, 0xD0, 0x01, 0x20, 0x84, 0xF8,
+ 0x72, 0x00, 0x2D, 0xE0, 0x02, 0x20, 0x04, 0xB0, 0x70, 0xBD, 0x04, 0x20,
+ 0xFB, 0xE7, 0x61, 0x68, 0x28, 0x46, 0x30, 0x31, 0x01, 0xF0, 0x86, 0xFB,
+ 0x04, 0x00, 0x21, 0xD0, 0x03, 0x46, 0x11, 0x49, 0x11, 0x48, 0x01, 0x22,
+ 0x98, 0x31, 0x80, 0x1E, 0xE0, 0xF7, 0xF9, 0xDA, 0x21, 0x46, 0x28, 0x46,
+ 0x02, 0xF0, 0xC6, 0xF9, 0x44, 0xF4, 0xA0, 0x61, 0x28, 0x46, 0xFE, 0xF7,
+ 0xAD, 0xF8, 0x0F, 0xE0, 0xFF, 0xE7, 0x62, 0x68, 0x69, 0x46, 0x28, 0x46,
+ 0x30, 0x32, 0x00, 0xF0, 0xBB, 0xFD, 0x05, 0x20, 0xE8, 0x84, 0x68, 0x79,
+ 0x6A, 0x46, 0x40, 0xF4, 0x80, 0x70, 0x61, 0x68, 0x01, 0xF0, 0xAE, 0xFF,
+ 0x00, 0x20, 0xD0, 0xE7, 0x34, 0x3D, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21,
+ 0x64, 0x01, 0x20, 0x00, 0x88, 0x76, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x4F,
+ 0x89, 0xB0, 0x88, 0x46, 0x05, 0x46, 0x04, 0x6A, 0xFE, 0xF7, 0x64, 0xFC,
+ 0x81, 0x46, 0x28, 0x46, 0xFE, 0xF7, 0x0C, 0xFC, 0x06, 0x46, 0x04, 0xF1,
+ 0x0C, 0x00, 0xCD, 0xE9, 0x07, 0x08, 0x98, 0xF8, 0x01, 0x00, 0x98, 0xF8,
+ 0x02, 0xB0, 0x98, 0xF8, 0x03, 0x70, 0x98, 0xF8, 0x04, 0xA0, 0x98, 0xF8,
+ 0x05, 0x20, 0x06, 0x92, 0x98, 0xF8, 0x06, 0x80, 0xCD, 0xE9, 0x00, 0x0B,
+ 0xCD, 0xE9, 0x04, 0x28, 0xCD, 0xE9, 0x02, 0x7A, 0x07, 0x22, 0xD5, 0x49,
+ 0xD5, 0x48, 0x23, 0x68, 0xE0, 0xF7, 0xAB, 0xDA, 0x28, 0x7F, 0x01, 0x28,
+ 0x03, 0xD0, 0x08, 0x20, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x20, 0x78,
+ 0x80, 0x07, 0x01, 0xD5, 0x09, 0x20, 0xF7, 0xE7, 0xCE, 0x48, 0x40, 0x7D,
+ 0x02, 0x28, 0x03, 0xD1, 0x38, 0x07, 0x01, 0xD4, 0x03, 0x20, 0xEF, 0xE7,
+ 0xB8, 0x07, 0x05, 0xD1, 0x06, 0x98, 0x50, 0xEA, 0x08, 0x00, 0x01, 0xD0,
+ 0x0A, 0x20, 0xE7, 0xE7, 0x00, 0x22, 0x12, 0x21, 0x28, 0x46, 0xFE, 0xF7,
+ 0x2F, 0xF9, 0x08, 0x98, 0x01, 0x68, 0xC4, 0xF8, 0x0B, 0x10, 0x81, 0x88,
+ 0xA4, 0xF8, 0x0F, 0x10, 0x80, 0x79, 0x60, 0x74, 0x20, 0x68, 0x00, 0x21,
+ 0x40, 0xF0, 0x02, 0x00, 0x20, 0x60, 0xBD, 0x48, 0x42, 0x7D, 0xC2, 0xB1,
+ 0x3A, 0x07, 0x16, 0xD5, 0x01, 0x22, 0x85, 0xF8, 0x6B, 0x20, 0x84, 0xF8,
+ 0x80, 0x10, 0x84, 0xF8, 0x81, 0x10, 0xC2, 0x78, 0x02, 0xF0, 0x07, 0x02,
+ 0x03, 0x2A, 0x01, 0xD1, 0x06, 0xF0, 0xFB, 0x06, 0x82, 0x7D, 0x46, 0xF0,
+ 0x08, 0x06, 0x32, 0xB1, 0x4F, 0xF6, 0xFE, 0x63, 0x09, 0xEA, 0x03, 0x09,
+ 0x01, 0xE0, 0x85, 0xF8, 0x6B, 0x10, 0x95, 0xF8, 0x24, 0x20, 0x32, 0xB9,
+ 0x09, 0x22, 0x85, 0xF8, 0x24, 0x20, 0xAA, 0x68, 0x42, 0xF4, 0xA8, 0x52,
+ 0xAA, 0x60, 0x06, 0x9A, 0xA8, 0x48, 0x22, 0x72, 0x84, 0xF8, 0x09, 0x80,
+ 0xC0, 0x78, 0xC0, 0x06, 0x01, 0xD4, 0x05, 0x20, 0xA2, 0xE7, 0x28, 0x89,
+ 0x80, 0x05, 0x03, 0xD4, 0xA2, 0x48, 0x00, 0x78, 0x40, 0x07, 0x01, 0xD5,
+ 0x01, 0x20, 0x00, 0xE0, 0x00, 0x20, 0x84, 0x46, 0x00, 0x20, 0xA0, 0x72,
+ 0x95, 0xF8, 0x6B, 0x20, 0x03, 0x20, 0xD2, 0xB1, 0xBB, 0xF1, 0x01, 0x0F,
+ 0x03, 0xD0, 0x9A, 0x49, 0xC9, 0x78, 0x09, 0x07, 0x1B, 0xD5, 0xA0, 0x72,
+ 0x84, 0xF8, 0x83, 0x00, 0x96, 0x48, 0xBB, 0xF1, 0x01, 0x0F, 0xC0, 0x78,
+ 0x4F, 0xEA, 0x00, 0x70, 0x05, 0xD0, 0x00, 0x28, 0x20, 0xDA, 0x02, 0x20,
+ 0x84, 0xF8, 0x83, 0x00, 0x1C, 0xE0, 0x00, 0x28, 0x1A, 0xDB, 0x01, 0x20,
+ 0xF8, 0xE7, 0xBB, 0xF1, 0x01, 0x0F, 0x04, 0xD1, 0x8C, 0x49, 0xC9, 0x78,
+ 0x09, 0x07, 0x00, 0xD5, 0x7A, 0xB1, 0x07, 0x98, 0x00, 0x21, 0x00, 0x78,
+ 0xCD, 0xE9, 0x00, 0x01, 0x87, 0x48, 0xC0, 0x78, 0x00, 0xF0, 0x07, 0x03,
+ 0x07, 0x98, 0x80, 0x78, 0x00, 0xF0, 0x04, 0x01, 0x60, 0x46, 0x01, 0xF0,
+ 0x3D, 0xFE, 0xA0, 0x72, 0xF8, 0x06, 0x04, 0xD5, 0xF0, 0x06, 0x02, 0xD5,
+ 0x01, 0x20, 0x85, 0xF8, 0x6C, 0x00, 0xDF, 0xF8, 0xF8, 0xB1, 0x07, 0x99,
+ 0xA0, 0x7A, 0x9B, 0xF8, 0x03, 0x20, 0x09, 0x78, 0x02, 0xF0, 0x07, 0x02,
+ 0x00, 0x92, 0xCD, 0xE9, 0x01, 0x10, 0x76, 0x49, 0x95, 0xF8, 0x6B, 0x30,
+ 0x04, 0x22, 0x90, 0x31, 0x74, 0x48, 0xE0, 0xF7, 0xEA, 0xD9, 0x95, 0xF8,
+ 0x6B, 0x00, 0xA8, 0xB1, 0xA0, 0x7A, 0x01, 0x28, 0x02, 0xD0, 0x02, 0x28,
+ 0x04, 0xD0, 0x0F, 0xE0, 0x00, 0x20, 0x84, 0xF8, 0x7C, 0x00, 0x0B, 0xE0,
+ 0x00, 0x20, 0xA0, 0x67, 0x84, 0xF8, 0x7C, 0x00, 0x84, 0xF8, 0x74, 0x00,
+ 0x84, 0xF8, 0x7E, 0x00, 0x84, 0xF8, 0x7F, 0x00, 0x84, 0xF8, 0x7D, 0x00,
+ 0x69, 0x7F, 0x51, 0x45, 0x02, 0xD8, 0xBA, 0xF1, 0x10, 0x0F, 0x01, 0xD9,
+ 0x06, 0x20, 0x21, 0xE7, 0x9B, 0xF8, 0x17, 0x00, 0xE8, 0x71, 0x50, 0x45,
+ 0x01, 0xD9, 0x85, 0xF8, 0x07, 0xA0, 0xB8, 0x07, 0x3C, 0xD0, 0xB0, 0x07,
+ 0x3A, 0xD0, 0x01, 0x20, 0x84, 0xF8, 0x82, 0x00, 0xCD, 0xE9, 0x00, 0x89,
+ 0x59, 0x49, 0xDF, 0xF8, 0x68, 0x81, 0x03, 0x22, 0xDC, 0x31, 0x40, 0x46,
+ 0x06, 0x9B, 0xE0, 0xF7, 0xB0, 0xD9, 0x21, 0x7A, 0x5F, 0x46, 0x01, 0xEA,
+ 0x19, 0x21, 0x21, 0x72, 0x60, 0x7A, 0x00, 0xEA, 0x09, 0x00, 0x60, 0x72,
+ 0x9B, 0xF8, 0x17, 0x20, 0xCD, 0xE9, 0x03, 0x10, 0xCD, 0xE9, 0x01, 0x62,
+ 0x9B, 0xF8, 0x03, 0x00, 0x06, 0x22, 0xC0, 0xF3, 0xC0, 0x01, 0x00, 0xF0,
+ 0x07, 0x03, 0x00, 0x91, 0x4C, 0x49, 0x40, 0x46, 0xE0, 0xF7, 0x95, 0xD9,
+ 0x4B, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x80, 0x07, 0x27, 0xD5, 0xB8, 0x68,
+ 0x8C, 0x38, 0x0E, 0x28, 0x23, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x0B, 0x0E,
+ 0x11, 0x14, 0x17, 0x1A, 0x1D, 0x20, 0x22, 0x22, 0x48, 0x4A, 0x4F, 0x51,
+ 0x4F, 0xF0, 0x00, 0x09, 0x48, 0x46, 0xC1, 0xE7, 0x06, 0xF0, 0x1F, 0x06,
+ 0x13, 0xE0, 0x46, 0xF0, 0x20, 0x06, 0x10, 0xE0, 0x46, 0xF0, 0x40, 0x06,
+ 0x0D, 0xE0, 0x46, 0xF0, 0x60, 0x06, 0x0A, 0xE0, 0x46, 0xF0, 0x80, 0x06,
+ 0x07, 0xE0, 0x46, 0xF0, 0xA0, 0x06, 0x04, 0xE0, 0x46, 0xF0, 0xC0, 0x06,
+ 0x01, 0xE0, 0x46, 0xF0, 0xE0, 0x06, 0xFA, 0x7D, 0x61, 0x7A, 0x20, 0x7A,
+ 0xCD, 0xE9, 0x00, 0x62, 0xCD, 0xE9, 0x02, 0x01, 0xF8, 0x78, 0x02, 0x21,
+ 0xC0, 0xF3, 0xC0, 0x03, 0x00, 0xF0, 0x07, 0x02, 0x28, 0x46, 0x01, 0xF0,
+ 0xB1, 0xFF, 0x28, 0x46, 0x02, 0xF0, 0x30, 0xFA, 0x95, 0xF8, 0x6B, 0x10,
+ 0x05, 0xF1, 0x0C, 0x00, 0x00, 0x29, 0xA1, 0x7A, 0x1E, 0xD0, 0xC9, 0xB1,
+ 0x03, 0x29, 0x13, 0xD0, 0x00, 0x20, 0x84, 0xF8, 0x73, 0x00, 0x09, 0xB0,
+ 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x4F, 0x01, 0xF0, 0x1D, 0xB8, 0x03, 0x21,
+ 0x00, 0xE0, 0x08, 0x21, 0x28, 0x46, 0x02, 0xF0, 0x0D, 0xF8, 0x32, 0xE0,
+ 0x05, 0x21, 0xF9, 0xE7, 0x09, 0x21, 0xF7, 0xE7, 0x02, 0x20, 0x84, 0xF8,
+ 0x70, 0x00, 0x2A, 0xE0, 0xA9, 0x7C, 0xEB, 0xF7, 0xAB, 0xFC, 0x26, 0xE0,
+ 0x01, 0x29, 0x0A, 0xD0, 0x02, 0x29, 0x15, 0xD0, 0x03, 0x29, 0x1D, 0xD0,
+ 0x62, 0x68, 0x00, 0x21, 0x11, 0x60, 0x51, 0x60, 0x91, 0x60, 0xD1, 0x60,
+ 0xEE, 0xE7, 0x08, 0x20, 0xE8, 0x84, 0x68, 0x79, 0x40, 0xF4, 0x80, 0x70,
+ 0x01, 0xF0, 0x20, 0xFE, 0x01, 0x20, 0x04, 0xF8, 0x80, 0x0F, 0x00, 0x20,
+ 0x60, 0x70, 0x0C, 0xE0, 0x95, 0xF8, 0x6C, 0x20, 0xA9, 0x7C, 0xED, 0xF7,
+ 0x24, 0xF8, 0x01, 0x20, 0x04, 0xF8, 0x74, 0x0F, 0x20, 0x74, 0x02, 0xE0,
+ 0xA9, 0x7C, 0xED, 0xF7, 0x09, 0xF9, 0x00, 0x20, 0x5E, 0xE6, 0x00, 0x00,
+ 0x84, 0x39, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, 0x88, 0x76, 0x20, 0x00,
+ 0xB0, 0x3A, 0xC0, 0x08, 0x64, 0x01, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x4F,
+ 0x04, 0x6A, 0x89, 0xB0, 0x05, 0x46, 0x04, 0xF1, 0x0C, 0x06, 0xF0, 0x1D,
+ 0x8A, 0x46, 0x07, 0x90, 0x11, 0xF8, 0x01, 0x0F, 0x08, 0x22, 0x91, 0xF8,
+ 0x01, 0x90, 0x91, 0xF8, 0x02, 0x80, 0xCF, 0x78, 0x91, 0xF8, 0x04, 0xB0,
+ 0x49, 0x79, 0x08, 0x91, 0xCD, 0xE9, 0x05, 0xB1, 0xA2, 0x49, 0xCD, 0xE9,
+ 0x03, 0x87, 0x49, 0x7D, 0xCD, 0xE9, 0x00, 0x10, 0xCD, 0xF8, 0x08, 0x90,
+ 0x9F, 0x49, 0xA0, 0x48, 0x23, 0x68, 0xE0, 0xF7, 0xD6, 0xD8, 0x20, 0x68,
+ 0xC1, 0x07, 0x01, 0xD0, 0x00, 0x07, 0x0A, 0xD5, 0x9A, 0x49, 0x9B, 0x48,
+ 0x00, 0x22, 0x98, 0x31, 0x80, 0x1E, 0xE0, 0xF7, 0xCA, 0xD8, 0x08, 0x20,
+ 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x94, 0x49, 0x48, 0x7D, 0x02, 0x28,
+ 0x04, 0xD1, 0x5F, 0xEA, 0x08, 0x70, 0x01, 0xD4, 0x03, 0x20, 0xF3, 0xE7,
+ 0xDA, 0xF8, 0x00, 0x20, 0xC4, 0xF8, 0x12, 0x20, 0xBA, 0xF8, 0x04, 0x20,
+ 0xE2, 0x82, 0x9A, 0xF8, 0x06, 0x00, 0x20, 0x76, 0xB0, 0x78, 0x4F, 0xF0,
+ 0x01, 0x0A, 0x02, 0x07, 0x4F, 0xF0, 0x00, 0x00, 0x0F, 0xD5, 0x4A, 0x7D,
+ 0x6A, 0xB1, 0x5F, 0xEA, 0x08, 0x72, 0x0A, 0xD5, 0x85, 0xF8, 0x6B, 0xA0,
+ 0x84, 0xF8, 0x80, 0x00, 0x84, 0xF8, 0x81, 0x00, 0xAA, 0x68, 0x42, 0xF4,
+ 0x00, 0x72, 0xAA, 0x60, 0x01, 0xE0, 0x85, 0xF8, 0x6B, 0x00, 0xB2, 0x78,
+ 0xD2, 0x06, 0x04, 0xD5, 0x5F, 0xEA, 0xC8, 0x62, 0x01, 0xD5, 0x85, 0xF8,
+ 0x6C, 0xA0, 0x22, 0x68, 0x79, 0x49, 0x42, 0xF0, 0x08, 0x02, 0x22, 0x60,
+ 0x84, 0xF8, 0x08, 0xB0, 0x08, 0x9A, 0x62, 0x72, 0xC9, 0x78, 0xC9, 0x06,
+ 0x01, 0xD4, 0x05, 0x20, 0xBA, 0xE7, 0xA0, 0x72, 0x83, 0x46, 0x95, 0xF8,
+ 0x6B, 0x20, 0x03, 0x20, 0xDA, 0xB1, 0xB9, 0xF1, 0x01, 0x0F, 0x03, 0xD0,
+ 0x6E, 0x49, 0xC9, 0x78, 0x09, 0x07, 0x1C, 0xD5, 0xA0, 0x72, 0x84, 0xF8,
+ 0x83, 0x00, 0x6B, 0x48, 0xB9, 0xF1, 0x01, 0x0F, 0xC0, 0x78, 0x4F, 0xEA,
+ 0x00, 0x70, 0x05, 0xD0, 0x00, 0x28, 0x1F, 0xDA, 0x02, 0x20, 0x84, 0xF8,
+ 0x83, 0x00, 0x1B, 0xE0, 0x00, 0x28, 0x19, 0xDB, 0x84, 0xF8, 0x83, 0xA0,
+ 0x16, 0xE0, 0xB9, 0xF1, 0x01, 0x0F, 0x04, 0xD1, 0x60, 0x49, 0xC9, 0x78,
+ 0x09, 0x07, 0x00, 0xD5, 0x6A, 0xB1, 0x07, 0x99, 0x07, 0x98, 0x09, 0x78,
+ 0xCD, 0xE9, 0x00, 0x1A, 0x80, 0x78, 0x33, 0x78, 0x00, 0xF0, 0x04, 0x01,
+ 0xB0, 0x78, 0x00, 0xF0, 0x04, 0x00, 0x01, 0xF0, 0x83, 0xFC, 0xA0, 0x72,
+ 0x68, 0x7F, 0xB8, 0x42, 0x01, 0xD8, 0x10, 0x2F, 0x01, 0xD9, 0x06, 0x20,
+ 0x7A, 0xE7, 0x53, 0x49, 0xC8, 0x7D, 0xE8, 0x71, 0xB8, 0x42, 0x00, 0xD9,
+ 0xEF, 0x71, 0xB0, 0x78, 0x80, 0x07, 0x13, 0xD0, 0x5F, 0xEA, 0x88, 0x70,
+ 0x10, 0xD0, 0x84, 0xF8, 0x82, 0xA0, 0x4F, 0x48, 0x90, 0xF8, 0x78, 0x01,
+ 0x80, 0x07, 0x1D, 0xD5, 0x88, 0x68, 0xA0, 0xF5, 0x8C, 0x70, 0x06, 0x28,
+ 0x18, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x06, 0x08, 0x0D, 0x0F, 0x11, 0x13,
+ 0x84, 0xF8, 0x82, 0xB0, 0xED, 0xE7, 0x03, 0x21, 0x00, 0xE0, 0x08, 0x21,
+ 0x28, 0x46, 0x01, 0xF0, 0xEF, 0xFE, 0x7D, 0xE0, 0x05, 0x21, 0xF9, 0xE7,
+ 0x09, 0x21, 0xF7, 0xE7, 0x01, 0x21, 0xF5, 0xE7, 0x02, 0x21, 0x28, 0x46,
+ 0x01, 0xF0, 0xE4, 0xFE, 0x95, 0xF8, 0x6B, 0x10, 0x05, 0xF1, 0x0C, 0x00,
+ 0x00, 0x29, 0xA1, 0x7A, 0x43, 0xD0, 0xE9, 0xB3, 0x01, 0x29, 0x04, 0xD0,
+ 0x02, 0x29, 0x07, 0xD0, 0x03, 0x29, 0x19, 0xD1, 0x20, 0xE0, 0xC4, 0xF8,
+ 0x78, 0xB0, 0x84, 0xF8, 0x7C, 0xB0, 0x13, 0xE0, 0xC4, 0xF8, 0x78, 0xB0,
+ 0x84, 0xF8, 0x7C, 0xB0, 0x84, 0xF8, 0x7D, 0xB0, 0x84, 0xF8, 0x7E, 0xB0,
+ 0x84, 0xF8, 0x7F, 0xB0, 0x95, 0xF8, 0x6C, 0x20, 0xA9, 0x7C, 0x74, 0x34,
+ 0xEC, 0xF7, 0x03, 0xFF, 0x04, 0xF8, 0x10, 0xAB, 0x04, 0xF8, 0x84, 0xA9,
+ 0x28, 0x46, 0x84, 0xF8, 0x73, 0xA0, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F,
+ 0x00, 0xF0, 0xBE, 0xBE, 0x02, 0x20, 0x84, 0xF8, 0x70, 0x00, 0x28, 0x46,
+ 0x01, 0xF0, 0xB0, 0xFB, 0x28, 0x46, 0x02, 0xF0, 0xB5, 0xF8, 0x28, 0x7F,
+ 0x01, 0x28, 0x37, 0xD1, 0x1D, 0x49, 0x00, 0x22, 0xBC, 0x31, 0x1D, 0x48,
+ 0xDF, 0xF7, 0xD1, 0xDF, 0x28, 0x46, 0x00, 0xF0, 0x6B, 0xFE, 0x2D, 0xE0,
+ 0xFF, 0xE7, 0xA9, 0x7C, 0xEB, 0xF7, 0x44, 0xFB, 0x28, 0xE0, 0x01, 0x29,
+ 0x0D, 0xD0, 0x02, 0x29, 0x17, 0xD0, 0x03, 0x29, 0x1F, 0xD0, 0x62, 0x68,
+ 0xC2, 0xF8, 0x00, 0xB0, 0xC2, 0xF8, 0x04, 0xB0, 0xC2, 0xF8, 0x08, 0xB0,
+ 0xC2, 0xF8, 0x0C, 0xB0, 0xEB, 0xE7, 0x08, 0x20, 0xE8, 0x84, 0x68, 0x79,
+ 0x40, 0xF4, 0x80, 0x70, 0x01, 0xF0, 0xB6, 0xFC, 0x84, 0xF8, 0x80, 0xA0,
+ 0x84, 0xF8, 0x81, 0xB0, 0x0C, 0xE0, 0x95, 0xF8, 0x6C, 0x20, 0xA9, 0x7C,
+ 0xEC, 0xF7, 0xBB, 0xFE, 0x04, 0xF8, 0x74, 0xAF, 0x84, 0xF8, 0x10, 0xA0,
+ 0x02, 0xE0, 0xA9, 0x7C, 0xEC, 0xF7, 0xA0, 0xFF, 0x00, 0x20, 0xD3, 0xE6,
+ 0x88, 0x76, 0x20, 0x00, 0x2C, 0x3B, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21,
+ 0x64, 0x01, 0x20, 0x00, 0x70, 0xB5, 0x04, 0x46, 0x00, 0x6A, 0x40, 0x22,
+ 0x49, 0x1C, 0xC0, 0x6B, 0x40, 0x30, 0x12, 0xF4, 0xA0, 0xF0, 0x20, 0x6A,
+ 0x01, 0x25, 0x80, 0xF8, 0x7D, 0x50, 0x27, 0x48, 0x90, 0xF8, 0x78, 0x01,
+ 0x80, 0x07, 0x04, 0xD5, 0x25, 0x48, 0x80, 0x68, 0xB0, 0xF5, 0x8F, 0x7F,
+ 0x09, 0xD0, 0x20, 0x6A, 0xC0, 0x6B, 0x40, 0x30, 0x10, 0xF4, 0x72, 0xF0,
+ 0x28, 0xB1, 0x20, 0x7F, 0x01, 0x28, 0x04, 0xD0, 0x19, 0xE0, 0x02, 0x20,
+ 0x70, 0xBD, 0x0B, 0x20, 0x70, 0xBD, 0x20, 0x6A, 0x01, 0x22, 0x1C, 0x49,
+ 0x90, 0xF8, 0x70, 0x30, 0x1B, 0x48, 0xDF, 0xF7, 0x68, 0xDF, 0x20, 0x6A,
+ 0x90, 0xF8, 0x70, 0x10, 0x02, 0x29, 0x02, 0xD0, 0x80, 0xF8, 0x73, 0x50,
+ 0x1D, 0xE0, 0x20, 0x46, 0x01, 0xF0, 0x30, 0xFB, 0x20, 0x46, 0x02, 0xF0,
+ 0x35, 0xF8, 0x20, 0x6A, 0x90, 0xF8, 0x71, 0x10, 0x11, 0xB1, 0x02, 0x29,
+ 0x15, 0xD0, 0x10, 0xE0, 0x90, 0xF8, 0x70, 0x10, 0x02, 0x29, 0x0C, 0xD1,
+ 0x00, 0xF1, 0x19, 0x02, 0xC1, 0x6B, 0x60, 0x79, 0x40, 0x31, 0x40, 0xF4,
+ 0x80, 0x70, 0x01, 0xF0, 0x5D, 0xFE, 0x20, 0xB1, 0x20, 0x6A, 0x80, 0xF8,
+ 0x71, 0x50, 0x00, 0x20, 0x70, 0xBD, 0x08, 0x20, 0x70, 0xBD, 0x20, 0x46,
+ 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, 0x80, 0xBE, 0x64, 0x01, 0x20, 0x00,
+ 0x88, 0x76, 0x20, 0x00, 0x28, 0x3C, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21,
+ 0xFE, 0xB5, 0x4D, 0x78, 0x00, 0xF1, 0x0C, 0x01, 0x04, 0x46, 0x06, 0x6A,
+ 0x0F, 0x46, 0x1F, 0x48, 0xE0, 0xF7, 0xF6, 0xD8, 0x03, 0x46, 0x21, 0x7F,
+ 0x30, 0x68, 0x00, 0x95, 0xCD, 0xE9, 0x01, 0x10, 0x04, 0x22, 0x1B, 0x49,
+ 0x1B, 0x48, 0xDF, 0xF7, 0x1C, 0xDF, 0x20, 0x7F, 0x10, 0xB9, 0x30, 0x68,
+ 0x81, 0x02, 0x01, 0xD5, 0x08, 0x20, 0xFE, 0xBD, 0x17, 0x49, 0x49, 0x7D,
+ 0x02, 0x29, 0x03, 0xD1, 0x29, 0x07, 0x01, 0xD4, 0x03, 0x20, 0xFE, 0xBD,
+ 0xC1, 0x07, 0x1C, 0xD1, 0x40, 0xF4, 0x00, 0x10, 0x30, 0x60, 0x94, 0xF8,
+ 0x24, 0x00, 0xB0, 0xB9, 0x00, 0x22, 0x11, 0x21, 0x20, 0x46, 0xFD, 0xF7,
+ 0xA5, 0xFD, 0x68, 0x07, 0x01, 0xD5, 0x08, 0x20, 0x00, 0xE0, 0x07, 0x20,
+ 0x84, 0xF8, 0x24, 0x00, 0xA0, 0x68, 0x12, 0x22, 0x20, 0xF4, 0x80, 0x50,
+ 0x40, 0xF4, 0xA0, 0x60, 0xA0, 0x60, 0xA1, 0x7C, 0x38, 0x46, 0xEB, 0xF7,
+ 0x7C, 0xFA, 0x00, 0x20, 0xFE, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21,
+ 0x68, 0x3F, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0x88, 0x76, 0x20, 0x00,
+ 0x70, 0xB5, 0x04, 0x46, 0x4E, 0x1C, 0x05, 0x6A, 0x00, 0x22, 0x17, 0x49,
+ 0x17, 0x48, 0xDF, 0xF7, 0xDA, 0xDE, 0x20, 0x7A, 0x40, 0x07, 0x0C, 0xD5,
+ 0x28, 0x68, 0x01, 0x03, 0x09, 0xD4, 0x21, 0x7F, 0x11, 0xB1, 0x01, 0x29,
+ 0x02, 0xD0, 0x06, 0xE0, 0x69, 0x7A, 0x00, 0xE0, 0x29, 0x7A, 0x49, 0x07,
+ 0x01, 0xD4, 0x08, 0x20, 0x70, 0xBD, 0x40, 0xF4, 0x00, 0x20, 0x28, 0x60,
+ 0x68, 0x68, 0x10, 0x22, 0x31, 0x46, 0x68, 0x30, 0x11, 0xF4, 0xD3, 0xF7,
+ 0x10, 0x22, 0x31, 0x46, 0x04, 0xF1, 0x40, 0x00, 0x11, 0xF4, 0xCD, 0xF7,
+ 0x01, 0x20, 0x84, 0xF8, 0x29, 0x00, 0x00, 0x20, 0x20, 0x65, 0x20, 0x46,
+ 0x00, 0xF0, 0x1C, 0xFA, 0x00, 0x20, 0x70, 0xBD, 0x50, 0x3F, 0xC0, 0x08,
+ 0x03, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xF8, 0x43, 0x0C, 0x46, 0x80, 0x46,
+ 0xFD, 0xF7, 0x6C, 0xFE, 0x05, 0x00, 0xE1, 0x88, 0xE0, 0x68, 0x2D, 0x4F,
+ 0x00, 0xEB, 0x01, 0x04, 0x26, 0x78, 0x09, 0xD0, 0x00, 0x96, 0x6B, 0x8B,
+ 0x02, 0x22, 0x2A, 0x49, 0xB8, 0x1C, 0xDF, 0xF7, 0x96, 0xDE, 0x28, 0x6A,
+ 0x50, 0xB1, 0x15, 0xE0, 0x01, 0xB0, 0x43, 0x46, 0x38, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x43, 0x24, 0x49, 0x01, 0x22, 0x40, 0x39, 0xDF, 0xF7, 0x89, 0x9E,
+ 0x01, 0x2E, 0x05, 0xD0, 0x0B, 0x2E, 0x03, 0xD0, 0x1F, 0x49, 0x00, 0x22,
+ 0x68, 0x31, 0x14, 0xE0, 0x28, 0x46, 0xFD, 0xF7, 0xDB, 0xFB, 0x68, 0xB1,
+ 0x10, 0x2E, 0x30, 0xD2, 0x1B, 0x48, 0x21, 0x46, 0x50, 0xF8, 0x26, 0x20,
+ 0x28, 0x46, 0x90, 0x47, 0x04, 0x46, 0x08, 0x28, 0x0A, 0xD0, 0x09, 0x2C,
+ 0x08, 0xD0, 0x13, 0xE0, 0x14, 0x49, 0x00, 0x22, 0x34, 0x31, 0x38, 0x46,
+ 0xDF, 0xF7, 0x69, 0xDE, 0x08, 0x24, 0x0D, 0xE0, 0x05, 0x2E, 0x09, 0xD0,
+ 0x28, 0x6A, 0x0F, 0x49, 0x02, 0x22, 0x00, 0x68, 0x00, 0x90, 0x2B, 0x7F,
+ 0x94, 0x31, 0x38, 0x46, 0xDF, 0xF7, 0x5B, 0xDE, 0x00, 0x2C, 0x0E, 0xD0,
+ 0x05, 0x2E, 0x05, 0xD0, 0x28, 0x6A, 0x18, 0xB1, 0x21, 0x46, 0x28, 0x46,
+ 0x01, 0xF0, 0x22, 0xFD, 0x44, 0xF4, 0xA0, 0x61, 0x28, 0x46, 0xBD, 0xE8,
+ 0xF8, 0x43, 0xFD, 0xF7, 0x07, 0xBC, 0xBD, 0xE8, 0xF8, 0x83, 0x00, 0x00,
+ 0x00, 0x39, 0x10, 0x21, 0x18, 0x40, 0xC0, 0x08, 0x08, 0x74, 0x20, 0x00,
+ 0x70, 0xB5, 0x05, 0x46, 0xC8, 0xB2, 0xFD, 0xF7, 0x65, 0xFE, 0x04, 0x46,
+ 0x00, 0x22, 0x0E, 0x49, 0x0E, 0x48, 0xDF, 0xF7, 0x36, 0xDE, 0x00, 0x2C,
+ 0x15, 0xD0, 0x20, 0x46, 0xE8, 0xF7, 0xDA, 0xFB, 0x02, 0x2D, 0x10, 0xD1,
+ 0x20, 0x79, 0x00, 0x28, 0x0D, 0xD0, 0x20, 0x6A, 0x00, 0x28, 0x0A, 0xD0,
+ 0x40, 0xF2, 0xEC, 0x51, 0x20, 0x46, 0xFD, 0xF7, 0xE1, 0xFB, 0x60, 0x8B,
+ 0xBD, 0xE8, 0x70, 0x40, 0x05, 0x21, 0xF3, 0xF7, 0x8B, 0xBB, 0x70, 0xBD,
+ 0xB0, 0x41, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21, 0x10, 0xB5, 0x0B, 0x78,
+ 0x01, 0x22, 0x03, 0x49, 0x03, 0x48, 0xDF, 0xF7, 0x12, 0xDE, 0x07, 0x20,
+ 0x10, 0xBD, 0x00, 0x00, 0xB0, 0x3F, 0xC0, 0x08, 0x01, 0x39, 0x10, 0x21,
+ 0x70, 0xB5, 0x24, 0x4A, 0x24, 0x49, 0x10, 0x1F, 0xE7, 0xF7, 0x54, 0xFD,
+ 0x00, 0x28, 0x1E, 0xD0, 0x20, 0x48, 0x0C, 0x30, 0xE8, 0xF7, 0x55, 0xF9,
+ 0x1E, 0x4C, 0x10, 0x20, 0x1F, 0x4D, 0xE0, 0x75, 0x01, 0x20, 0x60, 0x75,
+ 0xA0, 0x75, 0x1E, 0x20, 0x20, 0x75, 0x00, 0x26, 0x26, 0x76, 0x95, 0xF8,
+ 0x98, 0x01, 0x3D, 0x23, 0xC0, 0xEB, 0xC0, 0x00, 0x01, 0x01, 0x19, 0x4A,
+ 0x30, 0x46, 0xEA, 0xF7, 0x7F, 0xDB, 0x60, 0x60, 0x20, 0xB9, 0x95, 0xF8,
+ 0x98, 0x01, 0x08, 0xB1, 0x00, 0x20, 0x70, 0xBD, 0x10, 0x48, 0x24, 0x30,
+ 0xE8, 0xF7, 0x35, 0xF9, 0x84, 0xF8, 0x46, 0x60, 0x4F, 0xF6, 0xFF, 0x70,
+ 0xA0, 0x85, 0x4F, 0xF0, 0xFF, 0x30, 0x20, 0x62, 0x03, 0x20, 0x84, 0xF8,
+ 0x59, 0x00, 0x84, 0xF8, 0x5A, 0x00, 0x95, 0xF8, 0xAA, 0x01, 0x50, 0xB1,
+ 0x00, 0xEB, 0x40, 0x00, 0x41, 0x00, 0x52, 0x23, 0x07, 0x4A, 0x00, 0x20,
+ 0xEA, 0xF7, 0x5C, 0xDB, 0xE0, 0x61, 0x00, 0x28, 0xDF, 0xD0, 0x01, 0x20,
+ 0x70, 0xBD, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00, 0xBD, 0x5F, 0x82, 0x00,
+ 0x64, 0x01, 0x20, 0x00, 0xD6, 0xA8, 0x82, 0x00, 0x70, 0xB5, 0x15, 0x46,
+ 0xFD, 0xF7, 0xB4, 0xFD, 0x04, 0x00, 0x29, 0xD0, 0x20, 0x6A, 0x00, 0x28,
+ 0x26, 0xD0, 0x01, 0x2D, 0x0A, 0xD0, 0x08, 0x21, 0x20, 0x46, 0x01, 0xF0,
+ 0x7B, 0xFC, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x4F, 0xF4, 0xA1, 0x61,
+ 0xFD, 0xF7, 0x60, 0xBB, 0x94, 0xF8, 0x6B, 0x10, 0x01, 0x25, 0x41, 0xB1,
+ 0x21, 0x7F, 0x09, 0xB9, 0x80, 0xF8, 0x73, 0x50, 0x20, 0x46, 0xBD, 0xE8,
+ 0x70, 0x40, 0x00, 0xF0, 0x71, 0xBC, 0xE5, 0x84, 0x60, 0x79, 0x40, 0xF4,
+ 0x80, 0x70, 0x01, 0xF0, 0x95, 0xFA, 0x20, 0x6A, 0x80, 0xF8, 0x80, 0x50,
+ 0x21, 0x6A, 0x00, 0x20, 0x81, 0xF8, 0x81, 0x00, 0x70, 0xBD, 0x00, 0x00,
+ 0x2D, 0xE9, 0xFC, 0x41, 0x15, 0x46, 0x0E, 0x46, 0x07, 0x46, 0x00, 0x24,
+ 0xFD, 0xF7, 0x7E, 0xFD, 0xDF, 0xF8, 0x54, 0xC0, 0x28, 0xB1, 0x03, 0x6A,
+ 0xC3, 0xB1, 0x99, 0x7A, 0x02, 0x29, 0x15, 0xD1, 0x06, 0xE0, 0x00, 0x22,
+ 0x11, 0x49, 0x60, 0x46, 0xDF, 0xF7, 0x71, 0xDD, 0x04, 0x24, 0x05, 0xE0,
+ 0x90, 0xF8, 0x6C, 0x10, 0x51, 0xB1, 0x29, 0x46, 0x01, 0xF0, 0xA2, 0xF8,
+ 0x02, 0xB0, 0x32, 0x46, 0x39, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x41,
+ 0xEB, 0xF7, 0x30, 0xB9, 0x01, 0x7F, 0x90, 0xF8, 0x6C, 0x00, 0xCD, 0xE9,
+ 0x00, 0x01, 0x05, 0x49, 0x03, 0x22, 0x2C, 0x31, 0x60, 0x46, 0xDF, 0xF7,
+ 0x56, 0xDD, 0x05, 0x24, 0xEA, 0xE7, 0x00, 0x00, 0x00, 0x39, 0x10, 0x21,
+ 0x74, 0x24, 0xC0, 0x08, 0x00, 0xB5, 0x85, 0xB0, 0x8D, 0xF8, 0x0C, 0x30,
+ 0x8D, 0xF8, 0x0D, 0x10, 0x03, 0x21, 0xAD, 0xF8, 0x0A, 0x20, 0x8D, 0xF8,
+ 0x0E, 0x10, 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00,
+ 0x40, 0xF2, 0x02, 0x40, 0xAD, 0xF8, 0x00, 0x00, 0x05, 0x48, 0x40, 0xF2,
+ 0x71, 0x23, 0x03, 0x4A, 0x69, 0x46, 0x00, 0x78, 0xE7, 0xF7, 0xCE, 0xFD,
+ 0x05, 0xB0, 0x00, 0xBD, 0xF5, 0xA8, 0x82, 0x00, 0x84, 0x76, 0x20, 0x00,
+ 0xF8, 0xB5, 0x04, 0x46, 0x07, 0x6A, 0x90, 0xF8, 0x5A, 0x00, 0x00, 0x90,
+ 0x16, 0x46, 0x0D, 0x46, 0x63, 0x7E, 0x02, 0x22, 0x16, 0x49, 0x17, 0x48,
+ 0xDF, 0xF7, 0x1F, 0xDD, 0x60, 0x7E, 0x21, 0x7F, 0x29, 0xB1, 0x94, 0xF8,
+ 0x5A, 0x10, 0x29, 0x70, 0x21, 0x7F, 0x11, 0xB1, 0x03, 0xE0, 0x01, 0x46,
+ 0xF9, 0xE7, 0x94, 0xF8, 0x5A, 0x00, 0x68, 0x70, 0xD7, 0xF8, 0x0B, 0x00,
+ 0xC5, 0xF8, 0x02, 0x00, 0xB7, 0xF8, 0x0F, 0x00, 0xE8, 0x80, 0x78, 0x7C,
+ 0x28, 0x72, 0xD7, 0xF8, 0x12, 0x00, 0xC5, 0xF8, 0x09, 0x00, 0xF8, 0x8A,
+ 0xA5, 0xF8, 0x0D, 0x00, 0x38, 0x7E, 0xE8, 0x73, 0x00, 0x20, 0x29, 0x5C,
+ 0x32, 0x5C, 0x51, 0x40, 0x29, 0x54, 0x40, 0x1C, 0x80, 0xB2, 0x10, 0x28,
+ 0xF7, 0xD3, 0xF8, 0xBD, 0xD8, 0x43, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21,
+ 0x2D, 0xE9, 0xFC, 0x47, 0x00, 0xF1, 0x54, 0x06, 0xDF, 0xF8, 0x70, 0x90,
+ 0x90, 0x46, 0x0C, 0x46, 0x05, 0x46, 0x00, 0xF1, 0x13, 0x07, 0x32, 0x46,
+ 0x06, 0x21, 0x48, 0x46, 0xDF, 0xF7, 0x4D, 0xDF, 0x82, 0x46, 0x3A, 0x46,
+ 0x06, 0x21, 0x48, 0x46, 0xDF, 0xF7, 0x47, 0xDF, 0xCD, 0xE9, 0x00, 0x0A,
+ 0x6B, 0x7E, 0x03, 0x22, 0x12, 0x49, 0x13, 0x48, 0xDF, 0xF7, 0xD3, 0xDC,
+ 0x28, 0x7F, 0xC8, 0xB1, 0x38, 0x46, 0x01, 0x68, 0x21, 0x60, 0x80, 0x88,
+ 0xA0, 0x80, 0x28, 0x7F, 0xA0, 0xB1, 0x32, 0x46, 0x10, 0x68, 0xC4, 0xF8,
+ 0x06, 0x00, 0x90, 0x88, 0x60, 0x81, 0x00, 0x20, 0xE0, 0x60, 0x21, 0x5C,
+ 0x18, 0xF8, 0x00, 0x20, 0x51, 0x40, 0x21, 0x54, 0x40, 0x1C, 0x80, 0xB2,
+ 0x10, 0x28, 0xF6, 0xD3, 0xBD, 0xE8, 0xFC, 0x87, 0x30, 0x46, 0xE4, 0xE7,
+ 0x3A, 0x46, 0xE9, 0xE7, 0x00, 0x00, 0x50, 0x21, 0x20, 0x44, 0xC0, 0x08,
+ 0x02, 0x39, 0x10, 0x21, 0x10, 0xB5, 0x02, 0x6A, 0x03, 0x7F, 0x52, 0x68,
+ 0x6B, 0xB1, 0x02, 0xF1, 0x30, 0x03, 0x1C, 0x68, 0x0C, 0x60, 0x5B, 0x68,
+ 0x4B, 0x60, 0x00, 0x7F, 0x40, 0xB1, 0x10, 0x32, 0x10, 0x68, 0x88, 0x60,
+ 0x50, 0x68, 0xC8, 0x60, 0x10, 0xBD, 0x02, 0xF1, 0x10, 0x03, 0xF0, 0xE7,
+ 0x30, 0x32, 0xF5, 0xE7, 0x2D, 0xE9, 0xF0, 0x4F, 0x8B, 0xB0, 0x05, 0x46,
+ 0x2C, 0x6A, 0x2A, 0x7F, 0x60, 0x7A, 0x27, 0x7A, 0x01, 0x2A, 0x7D, 0xD0,
+ 0x3E, 0x46, 0x07, 0x46, 0x95, 0xF8, 0x6B, 0x00, 0x38, 0xB3, 0x94, 0xF8,
+ 0x82, 0x00, 0x20, 0xB3, 0x1C, 0x21, 0x68, 0x46, 0x11, 0xF4, 0x34, 0xF6,
+ 0xE8, 0x79, 0x8D, 0xF8, 0x1A, 0x00, 0xA8, 0x79, 0x8D, 0xF8, 0x1B, 0x00,
+ 0x10, 0x22, 0x05, 0xF1, 0x5B, 0x01, 0x68, 0x46, 0x11, 0xF4, 0x87, 0xF5,
+ 0x28, 0x6A, 0x1C, 0x22, 0x69, 0x46, 0x40, 0x68, 0x11, 0xF4, 0xC6, 0xF5,
+ 0x28, 0x6A, 0x1C, 0x22, 0x69, 0x46, 0x40, 0x68, 0x1C, 0x30, 0x11, 0xF4,
+ 0xBF, 0xF5, 0x20, 0x68, 0x26, 0xF0, 0x01, 0x06, 0x40, 0xF4, 0x70, 0x50,
+ 0x27, 0xF0, 0x01, 0x07, 0x20, 0x60, 0x60, 0x68, 0x05, 0x22, 0x90, 0xF8,
+ 0x81, 0x10, 0x90, 0xF8, 0x80, 0x00, 0xCD, 0xE9, 0x02, 0x01, 0xCD, 0xE9,
+ 0x00, 0x67, 0x7B, 0x49, 0x7B, 0x48, 0x23, 0x68, 0xDF, 0xF7, 0x4F, 0xDC,
+ 0x20, 0x68, 0x01, 0x01, 0x78, 0xD4, 0xDF, 0xF8, 0xE4, 0x91, 0x05, 0xF1,
+ 0x0C, 0x01, 0x08, 0x91, 0x09, 0xF1, 0x49, 0x01, 0x42, 0x05, 0x4F, 0xF0,
+ 0x00, 0x08, 0x09, 0xF1, 0x2E, 0x0A, 0x09, 0xF1, 0x40, 0x0B, 0x09, 0x91,
+ 0x06, 0xD5, 0xC1, 0x04, 0x04, 0xD5, 0x63, 0x68, 0x93, 0xF8, 0x80, 0x10,
+ 0xC9, 0x07, 0x31, 0xD0, 0x01, 0x05, 0x06, 0xD5, 0x81, 0x04, 0x04, 0xD5,
+ 0x63, 0x68, 0x93, 0xF8, 0x81, 0x10, 0xC9, 0x07, 0x2E, 0xD0, 0x41, 0x04,
+ 0x36, 0xD5, 0xC1, 0x03, 0x34, 0xD5, 0x61, 0x68, 0x91, 0xF8, 0x80, 0x10,
+ 0x89, 0x07, 0x2F, 0xD4, 0x18, 0x21, 0x02, 0xA8, 0x11, 0xF4, 0xD4, 0xF5,
+ 0x10, 0x22, 0x02, 0xA8, 0x09, 0x99, 0x11, 0xF4, 0x2E, 0xF5, 0x99, 0xF8,
+ 0x46, 0x10, 0x09, 0xB3, 0x58, 0x46, 0x02, 0x68, 0x06, 0x92, 0x80, 0x88,
+ 0xAD, 0xF8, 0x1C, 0x00, 0x8D, 0xF8, 0x1E, 0x10, 0x13, 0x21, 0x00, 0xE0,
+ 0x06, 0xE0, 0xCD, 0xE9, 0x00, 0x18, 0xA9, 0x7C, 0x02, 0xAB, 0x17, 0x22,
+ 0x08, 0x98, 0x40, 0xE0, 0x06, 0x46, 0x79, 0xE7, 0x11, 0x21, 0xCD, 0xE9,
+ 0x00, 0x18, 0xA9, 0x7C, 0x1C, 0x22, 0xF5, 0xE7, 0x12, 0x21, 0xCD, 0xE9,
+ 0x00, 0x18, 0x1C, 0x22, 0xA9, 0x7C, 0x1C, 0x33, 0x08, 0x98, 0x30, 0xE0,
+ 0x50, 0x46, 0xDC, 0xE7, 0x01, 0x04, 0x0E, 0xD5, 0x81, 0x03, 0x0C, 0xD5,
+ 0x63, 0x68, 0x93, 0xF8, 0x81, 0x10, 0x89, 0x07, 0x07, 0xD4, 0x14, 0x21,
+ 0xCD, 0xE9, 0x00, 0x18, 0x17, 0x22, 0xA9, 0x7C, 0x38, 0x33, 0x08, 0x98,
+ 0x1D, 0xE0, 0x41, 0x03, 0x0D, 0xD5, 0x63, 0x68, 0x93, 0xF8, 0x80, 0x10,
+ 0x49, 0x07, 0x08, 0xD4, 0x15, 0x21, 0xCD, 0xE9, 0x00, 0x18, 0x18, 0x22,
+ 0xA9, 0x7C, 0x50, 0x33, 0x08, 0x98, 0x0E, 0xE0, 0x70, 0xE0, 0x00, 0x03,
+ 0x13, 0xD5, 0x63, 0x68, 0x93, 0xF8, 0x81, 0x00, 0x40, 0x07, 0x0E, 0xD4,
+ 0x16, 0x21, 0xCD, 0xE9, 0x00, 0x18, 0xA9, 0x7C, 0x18, 0x22, 0x68, 0x33,
+ 0x08, 0x98, 0xE8, 0xF7, 0x15, 0xFA, 0x20, 0x68, 0x40, 0xF0, 0x00, 0x60,
+ 0x20, 0x60, 0x00, 0x01, 0x5A, 0xD4, 0x28, 0x7F, 0x28, 0xB9, 0x39, 0x46,
+ 0x28, 0x46, 0xFD, 0xF7, 0xBD, 0xFA, 0x00, 0x28, 0x52, 0xD0, 0xF0, 0x07,
+ 0x10, 0xD0, 0x20, 0x68, 0x41, 0x05, 0x01, 0xD4, 0x11, 0x20, 0x02, 0xE0,
+ 0xC0, 0x04, 0x09, 0xD4, 0x13, 0x20, 0xE8, 0x84, 0x68, 0x79, 0x0B, 0xB0,
+ 0x40, 0xF4, 0x80, 0x70, 0xBD, 0xE8, 0xF0, 0x4F, 0x01, 0xF0, 0xA6, 0xB8,
+ 0xB0, 0x07, 0x23, 0xD5, 0x20, 0x88, 0x40, 0x04, 0x20, 0xD4, 0x28, 0x46,
+ 0x09, 0x99, 0x01, 0xF0, 0x09, 0xF9, 0x20, 0x68, 0xC0, 0x03, 0x06, 0xD4,
+ 0x99, 0xF8, 0x46, 0x10, 0xA1, 0xB1, 0x5A, 0x46, 0x28, 0x46, 0x01, 0xF0,
+ 0xAF, 0xF8, 0x70, 0x07, 0x7F, 0xF5, 0xFA, 0xAE, 0x20, 0x68, 0x40, 0x03,
+ 0x3F, 0xF5, 0xF6, 0xAE, 0x28, 0x46, 0xFD, 0xF7, 0xE3, 0xFB, 0x28, 0x6A,
+ 0x41, 0x68, 0x28, 0x46, 0x50, 0x31, 0x01, 0xF0, 0x6F, 0xFB, 0xEB, 0xE6,
+ 0x52, 0x46, 0xE9, 0xE7, 0x70, 0x07, 0x02, 0xD5, 0x20, 0x68, 0x40, 0x03,
+ 0xEE, 0xD5, 0x28, 0x7F, 0x01, 0x28, 0x05, 0xD1, 0x39, 0x46, 0x28, 0x46,
+ 0xFD, 0xF7, 0x76, 0xFA, 0x00, 0x28, 0x0B, 0xD0, 0x00, 0x22, 0x15, 0x21,
+ 0x28, 0x46, 0xFD, 0xF7, 0x0D, 0xFA, 0x0B, 0xB0, 0x28, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x4F, 0x00, 0x21, 0xFD, 0xF7, 0x1E, 0xB9, 0x0B, 0xB0, 0xBD, 0xE8,
+ 0xF0, 0x8F, 0x00, 0x00, 0x30, 0x39, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21,
+ 0x88, 0x76, 0x20, 0x00, 0x10, 0xB5, 0x00, 0x28, 0x05, 0xD0, 0x01, 0x46,
+ 0x87, 0x22, 0x02, 0x48, 0x11, 0xF4, 0x63, 0xF4, 0x01, 0x20, 0x10, 0xBD,
+ 0xE3, 0x76, 0x20, 0x00, 0x10, 0xB5, 0x20, 0xB1, 0x01, 0x46, 0x27, 0x22,
+ 0x02, 0x48, 0x11, 0xF4, 0x58, 0xF4, 0x01, 0x20, 0x10, 0xBD, 0x00, 0x00,
+ 0x6A, 0x77, 0x20, 0x00, 0x38, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0xFD, 0xF7,
+ 0x39, 0xFB, 0x00, 0x28, 0x0A, 0xD1, 0x29, 0x46, 0x05, 0x48, 0xDF, 0xF7,
+ 0x03, 0xDD, 0x03, 0x46, 0x02, 0x22, 0x04, 0x49, 0x04, 0x48, 0x00, 0x94,
+ 0xDF, 0xF7, 0x2D, 0xDB, 0x38, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21,
+ 0xE4, 0x22, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xFE, 0x4F,
+ 0x1D, 0x46, 0x16, 0x46, 0x88, 0x46, 0x82, 0x46, 0x00, 0x27, 0xFD, 0xF7,
+ 0x1B, 0xFB, 0x04, 0x00, 0x7E, 0xD0, 0x4B, 0x48, 0x90, 0xF8, 0x78, 0x01,
+ 0x80, 0x07, 0x07, 0xD5, 0x49, 0x48, 0x80, 0x68, 0xFA, 0x28, 0x03, 0xD1,
+ 0x01, 0x21, 0x20, 0x46, 0x01, 0xF0, 0xDE, 0xF9, 0x20, 0x6A, 0x00, 0x28,
+ 0x6E, 0xD0, 0x94, 0xF8, 0x6B, 0x10, 0x40, 0xF2, 0x01, 0x59, 0xD9, 0xB3,
+ 0x90, 0xF8, 0x7D, 0x00, 0x21, 0x7F, 0x00, 0x95, 0xCD, 0xE9, 0x01, 0x10,
+ 0x33, 0x46, 0x04, 0x22, 0x3E, 0x49, 0x3F, 0x48, 0xDF, 0xF7, 0xF9, 0xDA,
+ 0x20, 0x6A, 0x00, 0x22, 0x81, 0x7A, 0x02, 0x29, 0x02, 0xD0, 0x05, 0x29,
+ 0x19, 0xD0, 0x56, 0xE0, 0x3E, 0xBB, 0x80, 0xF8, 0x7C, 0x20, 0x20, 0x6A,
+ 0x85, 0x67, 0x20, 0x6A, 0x80, 0xF8, 0x74, 0x20, 0x20, 0x7F, 0x01, 0x28,
+ 0x20, 0x6A, 0x07, 0xD0, 0x90, 0xF8, 0x7D, 0x00, 0x38, 0xB3, 0x0C, 0x21,
+ 0x20, 0x46, 0x00, 0xF0, 0xEF, 0xFC, 0x42, 0xE0, 0x90, 0xF8, 0x7E, 0x00,
+ 0xF8, 0xB1, 0x03, 0x21, 0xF6, 0xE7, 0x85, 0x67, 0x20, 0x6A, 0x80, 0xF8,
+ 0x74, 0x20, 0x20, 0x6A, 0x81, 0x6F, 0x01, 0x29, 0x08, 0xD0, 0x0C, 0x21,
+ 0x20, 0x46, 0x01, 0xF0, 0x9D, 0xF9, 0x40, 0xF2, 0x0C, 0x51, 0x20, 0xE0,
+ 0x0E, 0xE0, 0x19, 0xE0, 0x21, 0x7F, 0x01, 0x29, 0x06, 0xD1, 0x90, 0xF8,
+ 0x7F, 0x10, 0x31, 0xB1, 0x01, 0x68, 0x41, 0xF0, 0x00, 0x51, 0x01, 0x60,
+ 0x20, 0x46, 0x00, 0xF0, 0xFD, 0xFB, 0x1E, 0xE0, 0x81, 0x7A, 0x02, 0x29,
+ 0x01, 0xD0, 0x05, 0x29, 0x19, 0xD1, 0x40, 0x68, 0x29, 0x0A, 0x05, 0x70,
+ 0x41, 0x70, 0x29, 0x0C, 0x81, 0x70, 0x4E, 0xB1, 0x01, 0x21, 0x20, 0x46,
+ 0x01, 0xF0, 0x7A, 0xF9, 0x49, 0x46, 0x20, 0x46, 0xFD, 0xF7, 0x62, 0xF8,
+ 0x09, 0xE0, 0x07, 0xE0, 0x01, 0x20, 0xE0, 0x84, 0x60, 0x79, 0x40, 0xF4,
+ 0x80, 0x70, 0x00, 0xF0, 0xA1, 0xFF, 0x00, 0xE0, 0x05, 0x27, 0x39, 0x46,
+ 0x15, 0x20, 0xEC, 0xF7, 0xAA, 0xFA, 0x00, 0x2C, 0x0D, 0xD1, 0x51, 0x46,
+ 0x0B, 0x48, 0xDF, 0xF7, 0x5F, 0xDC, 0x03, 0x46, 0x07, 0x49, 0x08, 0x48,
+ 0x02, 0x22, 0x68, 0x31, 0xC0, 0x1E, 0xCD, 0xF8, 0x00, 0x80, 0xDF, 0xF7,
+ 0x86, 0xDA, 0xBD, 0xE8, 0xFE, 0x8F, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00,
+ 0x88, 0x76, 0x20, 0x00, 0x2C, 0x23, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21,
+ 0x00, 0x00, 0x30, 0x21, 0x10, 0xB5, 0x0A, 0x4C, 0xA1, 0x8D, 0xCA, 0x05,
+ 0x0F, 0xD5, 0x40, 0x79, 0xCB, 0xB2, 0x98, 0x42, 0x0B, 0xD1, 0x01, 0x22,
+ 0x06, 0x49, 0x07, 0x48, 0xDF, 0xF7, 0x6B, 0xDA, 0x4F, 0xF6, 0xFF, 0x70,
+ 0xA0, 0x85, 0xBD, 0xE8, 0x10, 0x40, 0x01, 0xF0, 0x59, 0xBB, 0x10, 0xBD,
+ 0x88, 0x76, 0x20, 0x00, 0xC8, 0x44, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21,
+ 0x00, 0xB5, 0x80, 0x88, 0xFD, 0xF7, 0x3C, 0xFA, 0x18, 0xB1, 0x00, 0x21,
+ 0x01, 0x70, 0x08, 0x46, 0x00, 0xBD, 0x40, 0xF2, 0xE1, 0x50, 0x00, 0xBD,
+ 0x10, 0xB5, 0x04, 0x00, 0x06, 0xD0, 0xE7, 0xF7, 0xF5, 0xFF, 0x20, 0x46,
+ 0x00, 0xF0, 0x04, 0xF8, 0x00, 0x20, 0x20, 0x71, 0x10, 0xBD, 0x00, 0x00,
+ 0x10, 0xB5, 0x04, 0x46, 0x00, 0x6A, 0x00, 0x28, 0x14, 0xD0, 0x40, 0x68,
+ 0x40, 0xF2, 0x5D, 0x22, 0x09, 0x49, 0xE7, 0xF7, 0xBD, 0xF8, 0x20, 0x6A,
+ 0x40, 0xF2, 0x5F, 0x22, 0x06, 0x49, 0xC0, 0x6B, 0xE7, 0xF7, 0xB6, 0xF8,
+ 0x40, 0xF2, 0x61, 0x22, 0x03, 0x49, 0x20, 0x6A, 0xE7, 0xF7, 0xB0, 0xF8,
+ 0x00, 0x20, 0x20, 0x62, 0x10, 0xBD, 0x00, 0x00, 0xB6, 0xAA, 0x82, 0x00,
+ 0x2D, 0xE9, 0xFE, 0x43, 0x90, 0x46, 0x0E, 0x46, 0x07, 0x46, 0x0A, 0x9D,
+ 0xFD, 0xF7, 0x1E, 0xFA, 0x04, 0x46, 0x39, 0x46, 0x18, 0x48, 0xDF, 0xF7,
+ 0xE9, 0xDB, 0x03, 0x46, 0x00, 0x96, 0x04, 0x22, 0x16, 0x49, 0x17, 0x48,
+ 0xCD, 0xE9, 0x01, 0x45, 0xDF, 0xF7, 0x11, 0xDA, 0x00, 0x2C, 0x20, 0xD0,
+ 0x20, 0x6A, 0x00, 0x28, 0x1D, 0xD0, 0x81, 0x7A, 0x03, 0x29, 0x1A, 0xD1,
+ 0x40, 0x68, 0x10, 0x22, 0x41, 0x46, 0x11, 0xF4, 0x18, 0xF3, 0x5D, 0xB1,
+ 0x02, 0x21, 0x20, 0x46, 0x01, 0xF0, 0xD0, 0xF8, 0x03, 0xB0, 0x20, 0x46,
+ 0xBD, 0xE8, 0xF0, 0x43, 0x40, 0xF2, 0x02, 0x51, 0xFC, 0xF7, 0xB4, 0xBF,
+ 0x01, 0x20, 0xE0, 0x84, 0x60, 0x79, 0xBD, 0xE8, 0xFE, 0x43, 0x40, 0xF4,
+ 0x80, 0x70, 0x00, 0xF0, 0xF3, 0xBE, 0xBD, 0xE8, 0xFE, 0x83, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x21, 0x94, 0x22, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21,
+ 0x2D, 0xE9, 0xF0, 0x43, 0x04, 0x46, 0x00, 0x6A, 0x21, 0x7F, 0x8F, 0xB0,
+ 0x00, 0x29, 0x41, 0x68, 0x0A, 0x46, 0x58, 0xD0, 0x63, 0x6D, 0x06, 0x93,
+ 0xB4, 0xF8, 0x58, 0x30, 0xAD, 0xF8, 0x1C, 0x30, 0x94, 0xF8, 0x5A, 0x30,
+ 0x8D, 0xF8, 0x1E, 0x30, 0xD4, 0xF8, 0x13, 0x30, 0x08, 0x93, 0xB4, 0xF8,
+ 0x17, 0x30, 0xAD, 0xF8, 0x24, 0x30, 0x63, 0x7E, 0x30, 0x31, 0x8D, 0xF8,
+ 0x26, 0x30, 0x10, 0x32, 0x00, 0xF1, 0x60, 0x05, 0x08, 0xAE, 0x0A, 0xAB,
+ 0x00, 0x96, 0xCD, 0xE9, 0x01, 0x53, 0x40, 0x30, 0x06, 0xAB, 0x07, 0x46,
+ 0x0E, 0xF4, 0x87, 0xF2, 0x04, 0xF1, 0x5B, 0x00, 0x10, 0x22, 0x0A, 0xA9,
+ 0x06, 0x46, 0x11, 0xF4, 0xC6, 0xF2, 0x32, 0x46, 0x22, 0x4E, 0x10, 0x21,
+ 0x30, 0x46, 0xDF, 0xF7, 0x18, 0xDC, 0x80, 0x46, 0x2A, 0x46, 0x10, 0x21,
+ 0x30, 0x46, 0xDF, 0xF7, 0x12, 0xDC, 0x05, 0x46, 0x3A, 0x46, 0x20, 0x21,
+ 0x30, 0x46, 0xDF, 0xF7, 0x0C, 0xDC, 0x07, 0x46, 0x04, 0xF1, 0x13, 0x02,
+ 0x06, 0x21, 0x30, 0x46, 0xDF, 0xF7, 0x05, 0xDC, 0x81, 0x46, 0x17, 0x4A,
+ 0x06, 0x21, 0x30, 0x46, 0xDF, 0xF7, 0xFF, 0xDB, 0x03, 0x46, 0xA0, 0x7C,
+ 0xCD, 0xE9, 0x02, 0x07, 0xCD, 0xE9, 0x04, 0x58, 0x61, 0x7E, 0x07, 0x22,
+ 0xCD, 0xE9, 0x00, 0x91, 0x10, 0x49, 0x11, 0x48, 0xDF, 0xF7, 0x85, 0xD9,
+ 0x0F, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0xD4, 0xF8, 0x13, 0x30, 0x06, 0x93,
+ 0xB4, 0xF8, 0x17, 0x30, 0xAD, 0xF8, 0x1C, 0x30, 0x63, 0x7E, 0x8D, 0xF8,
+ 0x1E, 0x30, 0x63, 0x6D, 0x08, 0x93, 0xB4, 0xF8, 0x58, 0x30, 0xAD, 0xF8,
+ 0x24, 0x30, 0x94, 0xF8, 0x5A, 0x30, 0x10, 0x31, 0x8D, 0xF8, 0x26, 0x30,
+ 0x30, 0x32, 0xA5, 0xE7, 0x00, 0x00, 0x50, 0x21, 0xB6, 0x76, 0x20, 0x00,
+ 0x60, 0x34, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0x70, 0xB5, 0x02, 0x6A,
+ 0x04, 0x46, 0x00, 0x25, 0x92, 0xF8, 0x71, 0x00, 0x02, 0x28, 0x01, 0xD0,
+ 0x28, 0xB1, 0x2D, 0xE0, 0x20, 0x46, 0x00, 0xF0, 0x9D, 0xF8, 0x05, 0x46,
+ 0x28, 0xE0, 0x60, 0x79, 0xD1, 0x6B, 0x40, 0xF4, 0x80, 0x70, 0x40, 0x31,
+ 0x19, 0x32, 0x01, 0xF0, 0x63, 0xF8, 0x01, 0x26, 0x38, 0xB1, 0x20, 0x6A,
+ 0x80, 0xF8, 0x71, 0x60, 0x20, 0x6A, 0x81, 0x7A, 0x02, 0x29, 0x07, 0xD0,
+ 0x16, 0xE0, 0x00, 0x22, 0x0B, 0x49, 0x0C, 0x48, 0xDF, 0xF7, 0x3D, 0xD9,
+ 0x08, 0x25, 0xF3, 0xE7, 0x90, 0xF8, 0x84, 0x00, 0x60, 0xB9, 0x94, 0xF8,
+ 0x6C, 0x20, 0xA1, 0x7C, 0x04, 0xF1, 0x0C, 0x00, 0xEC, 0xF7, 0x45, 0xF8,
+ 0x20, 0x6A, 0x80, 0xF8, 0x74, 0x60, 0x20, 0x6A, 0x80, 0xF8, 0x84, 0x60,
+ 0x28, 0x46, 0x70, 0xBD, 0x1C, 0x2E, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21,
+ 0x10, 0xB5, 0x04, 0x46, 0x00, 0x6A, 0x01, 0x22, 0x13, 0x49, 0x90, 0xF8,
+ 0x70, 0x30, 0x13, 0x48, 0xDF, 0xF7, 0x1B, 0xD9, 0x20, 0x6A, 0x90, 0xF8,
+ 0x70, 0x00, 0x48, 0xB9, 0x60, 0x79, 0x40, 0xF4, 0x80, 0x70, 0x01, 0xF0,
+ 0x6D, 0xF8, 0x60, 0xB1, 0x21, 0x6A, 0x01, 0x20, 0x81, 0xF8, 0x70, 0x00,
+ 0x20, 0x6A, 0x90, 0xF8, 0x73, 0x10, 0x61, 0xB1, 0x90, 0xF8, 0x70, 0x00,
+ 0x02, 0x28, 0x02, 0xD0, 0x07, 0xE0, 0x08, 0x20, 0x10, 0xBD, 0x20, 0x46,
+ 0x00, 0xF0, 0xD2, 0xFC, 0x20, 0x46, 0x01, 0xF0, 0xD7, 0xF9, 0x00, 0x20,
+ 0x10, 0xBD, 0x00, 0x00, 0xF0, 0x2D, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21,
+ 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x6A, 0x05, 0x46, 0xA0, 0x7A, 0x02, 0x28,
+ 0x0E, 0xD0, 0x01, 0x28, 0x0C, 0xD0, 0x28, 0x7F, 0x00, 0x28, 0x07, 0xD1,
+ 0x94, 0xF8, 0x80, 0x00, 0x02, 0x28, 0x0B, 0xD0, 0x02, 0x26, 0xC8, 0xB1,
+ 0x84, 0xF8, 0x81, 0x60, 0xBD, 0xE8, 0xF0, 0x81, 0x28, 0x46, 0xBD, 0xE8,
+ 0xF0, 0x41, 0x03, 0x21, 0x00, 0xF0, 0xEA, 0xBA, 0x00, 0x22, 0x0D, 0x49,
+ 0x0D, 0x48, 0xDF, 0xF7, 0xD4, 0xD8, 0x62, 0x68, 0x04, 0x21, 0x28, 0x46,
+ 0x10, 0x32, 0x00, 0xF0, 0x3F, 0xFD, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x41,
+ 0x01, 0xF0, 0xA4, 0xB9, 0x01, 0x27, 0xEF, 0x84, 0x68, 0x79, 0x40, 0xF4,
+ 0x80, 0x70, 0x00, 0xF0, 0xC7, 0xFD, 0x04, 0xF8, 0x80, 0x7F, 0x66, 0x70,
+ 0xDC, 0xE7, 0x00, 0x00, 0x24, 0x37, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21,
+ 0x2D, 0xE9, 0xF0, 0x4F, 0xDF, 0xF8, 0x5C, 0x82, 0x04, 0x6A, 0x05, 0x46,
+ 0x87, 0xB0, 0x04, 0xF1, 0x19, 0x02, 0x20, 0x21, 0x46, 0x46, 0x40, 0x46,
+ 0xDF, 0xF7, 0x17, 0xDB, 0xE2, 0x6B, 0x81, 0x46, 0x40, 0x21, 0x30, 0x46,
+ 0x40, 0x32, 0xDF, 0xF7, 0x10, 0xDB, 0x07, 0x46, 0x04, 0xF1, 0x40, 0x02,
+ 0x20, 0x21, 0x30, 0x46, 0xDF, 0xF7, 0x09, 0xDB, 0xCD, 0xE9, 0x00, 0x79,
+ 0x03, 0x46, 0x03, 0x22, 0x89, 0x49, 0x8A, 0x48, 0xDF, 0xF7, 0x95, 0xD8,
+ 0xA0, 0x7A, 0x01, 0x26, 0x02, 0x28, 0x19, 0xD0, 0x01, 0x28, 0x35, 0xD0,
+ 0x00, 0x27, 0xDF, 0xF8, 0x18, 0x92, 0x03, 0x28, 0x37, 0xD0, 0x28, 0x7F,
+ 0x00, 0x28, 0x0C, 0xD0, 0x94, 0xF8, 0x80, 0x30, 0x02, 0x2B, 0x71, 0xD0,
+ 0x7E, 0x49, 0x84, 0xF8, 0x81, 0x60, 0x01, 0x22, 0xD0, 0x31, 0x7D, 0x48,
+ 0xDF, 0xF7, 0x7B, 0xD8, 0x00, 0x20, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F,
+ 0x28, 0x7F, 0x01, 0x28, 0x0B, 0xD0, 0x94, 0xF8, 0x74, 0x00, 0x00, 0x28,
+ 0xF4, 0xD1, 0x20, 0x78, 0xC0, 0x06, 0xF1, 0xD4, 0x0C, 0x21, 0x28, 0x46,
+ 0x00, 0xF0, 0x7A, 0xFA, 0xEC, 0xE7, 0x94, 0xF8, 0x84, 0x00, 0x00, 0x28,
+ 0xE8, 0xD1, 0x95, 0xF8, 0x6C, 0x20, 0xA9, 0x7C, 0x05, 0xF1, 0x0C, 0x00,
+ 0xEB, 0xF7, 0x71, 0xFF, 0x04, 0xF8, 0x74, 0x6F, 0x26, 0x74, 0xDD, 0xE7,
+ 0x07, 0xB0, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x4F, 0x0C, 0x21, 0x00, 0xF0,
+ 0x63, 0xBA, 0x29, 0x6A, 0x91, 0xF8, 0x83, 0x00, 0x02, 0x28, 0x01, 0xD0,
+ 0x03, 0x28, 0x3A, 0xD1, 0x02, 0xA8, 0x00, 0x90, 0x63, 0x4A, 0xC8, 0x6B,
+ 0xE3, 0x32, 0x40, 0x30, 0x00, 0x23, 0x93, 0x46, 0x01, 0x46, 0x0E, 0xF4,
+ 0xF4, 0xF0, 0x02, 0xAA, 0x10, 0x21, 0x46, 0x46, 0x40, 0x46, 0xDF, 0xF7,
+ 0xA6, 0xDA, 0x82, 0x46, 0x5A, 0x46, 0x10, 0x21, 0x30, 0x46, 0xDF, 0xF7,
+ 0xA0, 0xDA, 0x80, 0x46, 0x28, 0x6A, 0x10, 0x21, 0xC2, 0x6B, 0x30, 0x46,
+ 0x40, 0x32, 0xDF, 0xF7, 0x98, 0xDA, 0x53, 0x49, 0xCD, 0xE9, 0x00, 0x8A,
+ 0x03, 0x46, 0x03, 0x22, 0x4C, 0x31, 0x51, 0x48, 0xDF, 0xF7, 0x23, 0xD8,
+ 0x50, 0x48, 0x10, 0x22, 0x02, 0xA9, 0xF3, 0x30, 0x11, 0xF4, 0xE6, 0xF0,
+ 0x58, 0xB1, 0x04, 0x21, 0x28, 0x46, 0x00, 0xF0, 0xE9, 0xFE, 0x40, 0xF2,
+ 0x04, 0x51, 0x28, 0x46, 0xFC, 0xF7, 0xD0, 0xFD, 0x04, 0x20, 0x96, 0xE7,
+ 0x3E, 0xE0, 0x28, 0x7F, 0x68, 0xBB, 0x66, 0x68, 0x0E, 0xF4, 0xB4, 0xF1,
+ 0x30, 0x74, 0x01, 0x0A, 0x71, 0x74, 0x01, 0x0C, 0xB1, 0x74, 0x00, 0x0E,
+ 0xF0, 0x74, 0x0E, 0xF4, 0xAB, 0xF1, 0x30, 0x75, 0x01, 0x0A, 0x71, 0x75,
+ 0x01, 0x0C, 0xB1, 0x75, 0x00, 0x0E, 0xF0, 0x75, 0x0E, 0xF4, 0xA2, 0xF1,
+ 0x30, 0x76, 0x01, 0x0A, 0x71, 0x76, 0x01, 0x0C, 0xB1, 0x76, 0x00, 0x0E,
+ 0xF0, 0x76, 0x0E, 0xF4, 0x99, 0xF1, 0x30, 0x77, 0x01, 0x0A, 0x71, 0x77,
+ 0x01, 0x0C, 0xB1, 0x77, 0x00, 0x0E, 0xF0, 0x77, 0x62, 0x68, 0x04, 0x21,
+ 0x28, 0x46, 0x10, 0x32, 0x00, 0xF0, 0x54, 0xFC, 0x28, 0x46, 0x01, 0xF0,
+ 0xBB, 0xF8, 0x28, 0x6A, 0x90, 0xF8, 0x83, 0x00, 0x02, 0x28, 0x7F, 0xF4,
+ 0x71, 0xAF, 0xC9, 0xF8, 0x5C, 0x70, 0xC9, 0xF8, 0x60, 0x70, 0xC9, 0xF8,
+ 0x64, 0x70, 0xC9, 0xF8, 0x68, 0x70, 0x55, 0xE7, 0x01, 0xA8, 0x00, 0x90,
+ 0xE0, 0x6B, 0x62, 0x68, 0x00, 0xF1, 0x40, 0x01, 0x00, 0x23, 0x10, 0x32,
+ 0x0E, 0xF4, 0x7B, 0xF0, 0x01, 0xAA, 0x10, 0x21, 0x40, 0x46, 0xDF, 0xF7,
+ 0x2E, 0xDA, 0x1E, 0x49, 0x03, 0x46, 0x01, 0x22, 0x9C, 0x31, 0x1D, 0x48,
+ 0xDE, 0xF7, 0xBB, 0xDF, 0x1D, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x80, 0x07,
+ 0x25, 0xD5, 0xD9, 0xF8, 0x08, 0x00, 0xB0, 0xF5, 0x87, 0x7F, 0x02, 0xD0,
+ 0xB0, 0xF5, 0x82, 0x7F, 0x1D, 0xD1, 0x0B, 0x20, 0x8D, 0xF8, 0x04, 0x00,
+ 0x09, 0x21, 0x8D, 0xF8, 0x05, 0x10, 0x8D, 0xF8, 0x06, 0x00, 0x8D, 0xF8,
+ 0x07, 0x00, 0x0A, 0x20, 0x8D, 0xF8, 0x08, 0x00, 0x0D, 0x20, 0x8D, 0xF8,
+ 0x09, 0x00, 0x0C, 0x20, 0x8D, 0xF8, 0x0A, 0x00, 0x0F, 0x20, 0x8D, 0xF8,
+ 0x0C, 0x00, 0x8D, 0xF8, 0x0D, 0x70, 0x8D, 0xF8, 0x0E, 0x70, 0x8D, 0xF8,
+ 0x0B, 0x00, 0x8D, 0xF8, 0x0F, 0x70, 0x01, 0xAA, 0x03, 0x21, 0x28, 0x46,
+ 0x00, 0xF0, 0xFC, 0xFB, 0x28, 0x46, 0x01, 0xF0, 0x63, 0xF8, 0x0B, 0xE7,
+ 0x00, 0x00, 0x50, 0x21, 0x54, 0x37, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21,
+ 0x88, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x41,
+ 0x86, 0xB0, 0x05, 0x46, 0x04, 0x6A, 0x00, 0x20, 0x05, 0x90, 0xA0, 0x7A,
+ 0x88, 0x46, 0x02, 0x28, 0x0E, 0xD0, 0x01, 0x28, 0x0C, 0xD0, 0x29, 0x7F,
+ 0x55, 0x4F, 0x81, 0xB1, 0x00, 0x22, 0x55, 0x49, 0x38, 0x46, 0xDE, 0xF7,
+ 0x68, 0xDF, 0x28, 0x6A, 0x80, 0x7A, 0x03, 0x28, 0x36, 0xD0, 0x5A, 0xE0,
+ 0x04, 0x21, 0x28, 0x46, 0x00, 0xF0, 0x70, 0xF9, 0x06, 0xB0, 0xBD, 0xE8,
+ 0xF0, 0x81, 0x03, 0x28, 0x5C, 0xD0, 0x01, 0xA8, 0x00, 0x90, 0xE0, 0x6B,
+ 0x00, 0x23, 0x01, 0x46, 0x42, 0x46, 0x40, 0x30, 0x0E, 0xF4, 0x05, 0xF0,
+ 0x48, 0x4E, 0x01, 0xAA, 0x10, 0x21, 0x30, 0x46, 0xDF, 0xF7, 0xB7, 0xD9,
+ 0x44, 0x49, 0x03, 0x46, 0x01, 0x22, 0x70, 0x39, 0x38, 0x46, 0xDE, 0xF7,
+ 0x44, 0xDF, 0x60, 0x68, 0x10, 0x22, 0x01, 0xA9, 0x40, 0x30, 0x11, 0xF4,
+ 0x07, 0xF0, 0xE0, 0xB3, 0x62, 0x68, 0x10, 0x21, 0x30, 0x46, 0x40, 0x32,
+ 0xDF, 0xF7, 0xA3, 0xD9, 0x03, 0x46, 0x3A, 0x49, 0x38, 0x48, 0x01, 0x22,
+ 0x38, 0x39, 0x80, 0x1E, 0xDE, 0xF7, 0x2F, 0xDF, 0x04, 0x20, 0xCD, 0xE7,
+ 0x66, 0x68, 0x0E, 0xF4, 0xD3, 0xF0, 0x30, 0x74, 0x01, 0x0A, 0x71, 0x74,
+ 0x01, 0x0C, 0xB1, 0x74, 0x00, 0x0E, 0xF0, 0x74, 0x0E, 0xF4, 0xCA, 0xF0,
+ 0x30, 0x75, 0x01, 0x0A, 0x71, 0x75, 0x01, 0x0C, 0xB1, 0x75, 0x00, 0x0E,
+ 0xF0, 0x75, 0x0E, 0xF4, 0xC1, 0xF0, 0x30, 0x76, 0x01, 0x0A, 0x71, 0x76,
+ 0x01, 0x0C, 0xB1, 0x76, 0x00, 0x0E, 0xF0, 0x76, 0x0E, 0xF4, 0xB8, 0xF0,
+ 0x30, 0x77, 0x01, 0x0A, 0x71, 0x77, 0x01, 0x0C, 0xB1, 0x77, 0x00, 0x0E,
+ 0xF0, 0x77, 0x62, 0x68, 0x04, 0x21, 0x28, 0x46, 0x10, 0x32, 0x00, 0xF0,
+ 0x73, 0xFB, 0x28, 0x46, 0x00, 0xE0, 0x01, 0xE0, 0x00, 0xF0, 0xD8, 0xFF,
+ 0x28, 0x46, 0xFF, 0xF7, 0x15, 0xFD, 0x28, 0x6A, 0x80, 0x7A, 0x28, 0xB3,
+ 0x04, 0x28, 0x23, 0xD0, 0x03, 0x28, 0x21, 0xD0, 0x29, 0x7F, 0x05, 0xA8,
+ 0x00, 0x90, 0x21, 0xB3, 0xE1, 0x6B, 0x63, 0x68, 0x01, 0xF1, 0x40, 0x00,
+ 0x42, 0x46, 0x10, 0x33, 0x0E, 0xF4, 0x4F, 0xF0, 0x28, 0x6A, 0x80, 0x7A,
+ 0x03, 0x28, 0x0F, 0xD0, 0xA9, 0x7C, 0x05, 0xF1, 0x0C, 0x00, 0x05, 0x9A,
+ 0xEB, 0xF7, 0xCA, 0xFF, 0x0D, 0x49, 0x01, 0x22, 0x2C, 0x31, 0x38, 0x46,
+ 0x05, 0x9B, 0xDE, 0xF7, 0xD6, 0xDE, 0x01, 0x20, 0x84, 0xF8, 0x74, 0x00,
+ 0x00, 0x20, 0x71, 0xE7, 0x28, 0x7F, 0x00, 0x28, 0xFA, 0xD1, 0x28, 0x46,
+ 0x00, 0xF0, 0x0E, 0xF8, 0xF6, 0xE7, 0xE0, 0x6B, 0x62, 0x68, 0x00, 0xF1,
+ 0x40, 0x01, 0x43, 0x46, 0x10, 0x32, 0xD9, 0xE7, 0x02, 0x39, 0x10, 0x21,
+ 0xE4, 0x38, 0xC0, 0x08, 0x00, 0x00, 0x50, 0x21, 0x2D, 0xE9, 0xF0, 0x4F,
+ 0x05, 0x6A, 0x95, 0xB0, 0x04, 0x46, 0x6E, 0x68, 0x06, 0xF1, 0x30, 0x00,
+ 0x13, 0x90, 0x00, 0x20, 0x06, 0x90, 0x07, 0x90, 0x08, 0x90, 0x09, 0x90,
+ 0xA8, 0x7A, 0x10, 0x36, 0x02, 0x28, 0x04, 0xD0, 0x01, 0x28, 0x02, 0xD0,
+ 0x03, 0x28, 0x10, 0xD0, 0x19, 0xE0, 0xB5, 0xF8, 0x78, 0x00, 0x8D, 0xF8,
+ 0x18, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x19, 0x00, 0xA8, 0x6F, 0x00, 0x0C,
+ 0x8D, 0xF8, 0x1A, 0x00, 0xA8, 0x6F, 0x00, 0x0E, 0x8D, 0xF8, 0x1B, 0x00,
+ 0x09, 0xE0, 0x20, 0x6A, 0x90, 0xF8, 0x83, 0x00, 0x01, 0x28, 0x04, 0xD0,
+ 0x10, 0x22, 0x35, 0x49, 0x06, 0xA8, 0x10, 0xF4, 0xA0, 0xF7, 0xD4, 0xF8,
+ 0x13, 0x00, 0x0E, 0x90, 0xB4, 0xF8, 0x17, 0x00, 0xAD, 0xF8, 0x3C, 0x00,
+ 0x60, 0x7E, 0x8D, 0xF8, 0x3E, 0x00, 0x20, 0x7F, 0x00, 0x28, 0x56, 0xD0,
+ 0xB5, 0xF8, 0x13, 0x00, 0xAD, 0xF8, 0x48, 0x00, 0x68, 0x7D, 0x8D, 0xF8,
+ 0x4A, 0x00, 0x60, 0x6D, 0x10, 0x90, 0xB4, 0xF8, 0x58, 0x00, 0xAD, 0xF8,
+ 0x44, 0x00, 0x94, 0xF8, 0x5A, 0x00, 0x26, 0x4F, 0x8D, 0xF8, 0x46, 0x00,
+ 0x06, 0xAA, 0x10, 0x21, 0x38, 0x46, 0xDF, 0xF7, 0xD4, 0xD8, 0x81, 0x46,
+ 0x10, 0x21, 0x38, 0x46, 0x13, 0x9A, 0xDF, 0xF7, 0xCE, 0xD8, 0x83, 0x46,
+ 0x32, 0x46, 0x10, 0x21, 0x38, 0x46, 0xDF, 0xF7, 0xC8, 0xD8, 0x82, 0x46,
+ 0x04, 0xF1, 0x13, 0x02, 0x06, 0x21, 0x38, 0x46, 0xDF, 0xF7, 0xC1, 0xD8,
+ 0x17, 0x4A, 0x80, 0x46, 0xB5, 0x3A, 0x06, 0x21, 0x38, 0x46, 0xDF, 0xF7,
+ 0xBA, 0xD8, 0x03, 0x46, 0xA7, 0x7C, 0x02, 0xA8, 0xCD, 0xF8, 0x14, 0x90,
+ 0x80, 0xE8, 0x80, 0x0C, 0x61, 0x7E, 0x07, 0x22, 0xCD, 0xE9, 0x00, 0x81,
+ 0x10, 0x49, 0x11, 0x48, 0xDE, 0xF7, 0x3F, 0xDE, 0x0A, 0xAB, 0x10, 0xAA,
+ 0x0E, 0xA9, 0x12, 0xA8, 0x8D, 0xE8, 0x0F, 0x00, 0x06, 0xAB, 0x31, 0x46,
+ 0x05, 0xF1, 0x60, 0x00, 0x13, 0x9A, 0x0D, 0xF4, 0x51, 0xF7, 0x0A, 0xA9,
+ 0x20, 0x46, 0x00, 0xF0, 0x1F, 0xF9, 0x20, 0x46, 0x00, 0xF0, 0x06, 0xFF,
+ 0x15, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xE8, 0x68, 0x12, 0x90, 0xAC, 0xE7,
+ 0x6B, 0x77, 0x20, 0x00, 0x00, 0x00, 0x50, 0x21, 0xD4, 0x33, 0xC0, 0x08,
+ 0x03, 0x39, 0x10, 0x21, 0x30, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0x89, 0xB0,
+ 0x00, 0x22, 0x07, 0x49, 0x07, 0x48, 0xDE, 0xF7, 0x14, 0xDE, 0x6A, 0x46,
+ 0x21, 0x46, 0x28, 0x46, 0x0E, 0xF4, 0xDF, 0xF6, 0x69, 0x46, 0x00, 0xF0,
+ 0xC1, 0xFB, 0x09, 0xB0, 0x30, 0xBD, 0x00, 0x00, 0x94, 0x8D, 0xC0, 0x08,
+ 0x03, 0x39, 0x10, 0x21, 0x00, 0xB5, 0x99, 0xB0, 0x00, 0x22, 0x07, 0x49,
+ 0x07, 0x48, 0xDE, 0xF7, 0xFE, 0xDD, 0x00, 0x22, 0x10, 0xA9, 0x68, 0x46,
+ 0x0E, 0xF4, 0x30, 0xF6, 0x10, 0xAA, 0x69, 0x46, 0x00, 0xF0, 0xD4, 0xFB,
+ 0x19, 0xB0, 0x00, 0xBD, 0x84, 0x8D, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21,
+ 0x2D, 0xE9, 0xF0, 0x47, 0x04, 0x6A, 0x05, 0x46, 0xDF, 0xF8, 0xA4, 0x91,
+ 0x94, 0xF8, 0x7C, 0x00, 0x88, 0xB0, 0x14, 0x28, 0x03, 0xD3, 0x00, 0x22,
+ 0x66, 0x49, 0x48, 0x46, 0x93, 0xE0, 0x03, 0x26, 0x01, 0x27, 0x03, 0x29,
+ 0x7D, 0xD0, 0x04, 0x29, 0x10, 0xD0, 0x28, 0x7F, 0x01, 0x28, 0x77, 0xD0,
+ 0x94, 0xF8, 0x80, 0x30, 0x01, 0x22, 0x60, 0x49, 0x48, 0x46, 0xDE, 0xF7,
+ 0xD0, 0xDD, 0x94, 0xF8, 0x80, 0x00, 0x02, 0x28, 0x6E, 0xD0, 0x01, 0x28,
+ 0x6D, 0xD0, 0xA5, 0xE0, 0xA1, 0x6F, 0xC1, 0x40, 0x01, 0xF0, 0x01, 0x00,
+ 0x40, 0xF0, 0x80, 0x08, 0x03, 0xA8, 0x00, 0x90, 0xE0, 0x6B, 0x62, 0x68,
+ 0x01, 0x46, 0x43, 0x46, 0x40, 0x30, 0x30, 0x32, 0x0D, 0xF4, 0x6D, 0xF6,
+ 0xDF, 0xF8, 0x4C, 0xA1, 0x03, 0xAA, 0x10, 0x21, 0x50, 0x46, 0xDF, 0xF7,
+ 0x1E, 0xD8, 0x94, 0xF8, 0x7C, 0x10, 0xA2, 0x6F, 0xCD, 0xE9, 0x00, 0x21,
+ 0x4B, 0x49, 0x02, 0x90, 0x43, 0x46, 0x04, 0x22, 0x38, 0x31, 0x48, 0x46,
+ 0xDE, 0xF7, 0xA5, 0xDD, 0x60, 0x68, 0x10, 0x22, 0x03, 0xA9, 0x40, 0x30,
+ 0x10, 0xF4, 0x68, 0xF6, 0x88, 0xB1, 0x62, 0x68, 0x10, 0x21, 0x50, 0x46,
+ 0x40, 0x32, 0xDF, 0xF7, 0x04, 0xD8, 0x03, 0x46, 0x40, 0x49, 0x3F, 0x48,
+ 0x01, 0x22, 0x98, 0x31, 0xC0, 0x1E, 0xDE, 0xF7, 0x90, 0xDD, 0x04, 0x20,
+ 0x08, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x94, 0xF8, 0x7C, 0x00, 0x40, 0x1C,
+ 0xC0, 0xB2, 0x84, 0xF8, 0x7C, 0x00, 0x14, 0x28, 0x02, 0xD1, 0x28, 0x46,
+ 0xFF, 0xF7, 0x9C, 0xFB, 0x28, 0x7F, 0x01, 0x28, 0x0A, 0xD0, 0x94, 0xF8,
+ 0x7C, 0x00, 0x14, 0x28, 0x1E, 0xD0, 0x33, 0x49, 0x00, 0x22, 0xF4, 0x39,
+ 0x48, 0x46, 0xDE, 0xF7, 0x74, 0xDD, 0x4F, 0xE0, 0x2E, 0x49, 0x00, 0x22,
+ 0xD0, 0x31, 0x48, 0x46, 0xDE, 0xF7, 0x6D, 0xDD, 0x62, 0x68, 0x04, 0x21,
+ 0x28, 0x46, 0x10, 0x32, 0x00, 0xF0, 0xD8, 0xF9, 0x28, 0x46, 0x00, 0xF0,
+ 0x3F, 0xFE, 0x00, 0x20, 0x84, 0xF8, 0x80, 0x00, 0x84, 0xF8, 0x81, 0x00,
+ 0x43, 0xE0, 0x05, 0xE0, 0x34, 0xE0, 0x20, 0xE0, 0x28, 0x46, 0xFF, 0xF7,
+ 0x9B, 0xFE, 0x3C, 0xE0, 0xA0, 0x7A, 0x02, 0x28, 0x0A, 0xD1, 0x94, 0xF8,
+ 0x74, 0x00, 0x38, 0xB1, 0x1E, 0x49, 0x1C, 0x48, 0x00, 0x22, 0xA8, 0x39,
+ 0x40, 0x1E, 0xDE, 0xF7, 0x4A, 0xDD, 0x2E, 0xE0, 0x28, 0x7F, 0x78, 0xB1,
+ 0x19, 0x49, 0x94, 0xF8, 0x80, 0x30, 0x01, 0x22, 0x3C, 0x39, 0x48, 0x46,
+ 0xDE, 0xF7, 0x3F, 0xDD, 0x94, 0xF8, 0x80, 0x00, 0x02, 0x28, 0x13, 0xD0,
+ 0xB0, 0xB1, 0x84, 0xF8, 0x81, 0x60, 0x1C, 0xE0, 0x11, 0x49, 0x00, 0x22,
+ 0x7C, 0x39, 0x48, 0x46, 0xDE, 0xF7, 0x31, 0xDD, 0x62, 0x68, 0x04, 0x21,
+ 0x28, 0x46, 0x10, 0x32, 0x00, 0xF0, 0x9C, 0xF9, 0x28, 0x46, 0x00, 0xF0,
+ 0x03, 0xFE, 0x0C, 0xE0, 0x28, 0x46, 0x00, 0xF0, 0x95, 0xF8, 0x08, 0xE0,
+ 0xEF, 0x84, 0x68, 0x79, 0x40, 0xF4, 0x80, 0x70, 0x00, 0xF0, 0x22, 0xFA,
+ 0x04, 0xF8, 0x80, 0x7F, 0x66, 0x70, 0x00, 0x20, 0x88, 0xE7, 0x00, 0x00,
+ 0x03, 0x39, 0x10, 0x21, 0xF8, 0x34, 0xC0, 0x08, 0xFC, 0x36, 0xC0, 0x08,
+ 0x00, 0x00, 0x50, 0x21, 0x30, 0xB5, 0x05, 0x46, 0x0C, 0x46, 0x0A, 0x46,
+ 0x85, 0xB0, 0x10, 0x21, 0x1B, 0x48, 0xDE, 0xF7, 0x72, 0xDF, 0x03, 0x46,
+ 0x01, 0x22, 0x1A, 0x49, 0x1A, 0x48, 0xDE, 0xF7, 0x00, 0xDD, 0x1B, 0x48,
+ 0x40, 0xF2, 0x6D, 0x23, 0x18, 0x4A, 0x2D, 0x21, 0x00, 0x78, 0xE6, 0xF7,
+ 0x8D, 0xFA, 0x01, 0x00, 0x21, 0xD0, 0x01, 0xF1, 0x1C, 0x00, 0x0D, 0x22,
+ 0x00, 0xF8, 0x01, 0x2B, 0x00, 0x23, 0xE2, 0x5C, 0x5B, 0x1C, 0x00, 0xF8,
+ 0x01, 0x2B, 0x10, 0x2B, 0xF9, 0xD3, 0x4F, 0xF4, 0x80, 0x60, 0xAD, 0xF8,
+ 0x00, 0x00, 0x1C, 0x20, 0xAD, 0xF8, 0x06, 0x00, 0x11, 0x20, 0xAD, 0xF8,
+ 0x08, 0x00, 0x01, 0x20, 0xAD, 0xF8, 0x04, 0x00, 0x06, 0x20, 0x03, 0x91,
+ 0xAD, 0xF8, 0x0A, 0x00, 0x68, 0x8B, 0x04, 0x90, 0x68, 0x46, 0xF6, 0xF7,
+ 0xEF, 0xFC, 0x05, 0xB0, 0x30, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x50, 0x21,
+ 0x64, 0x33, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0x3A, 0xAA, 0x82, 0x00,
+ 0x00, 0x74, 0x20, 0x00, 0x30, 0xB5, 0x05, 0x46, 0x0C, 0x46, 0x0B, 0x46,
+ 0x85, 0xB0, 0x01, 0x22, 0x14, 0x49, 0x15, 0x48, 0xDE, 0xF7, 0xBD, 0xDC,
+ 0x15, 0x48, 0x4F, 0xF4, 0x11, 0x73, 0x13, 0x4A, 0x1E, 0x21, 0x00, 0x78,
+ 0xE6, 0xF7, 0x4A, 0xFA, 0x00, 0x28, 0x18, 0xD0, 0x0E, 0x21, 0x01, 0x77,
+ 0x44, 0x77, 0x03, 0x90, 0x1C, 0x20, 0xAD, 0xF8, 0x06, 0x00, 0x02, 0x20,
+ 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x20, 0xAD, 0xF8, 0x04, 0x00, 0x4F, 0xF4,
+ 0x80, 0x61, 0x06, 0x20, 0xAD, 0xF8, 0x00, 0x10, 0xAD, 0xF8, 0x0A, 0x00,
+ 0x68, 0x8B, 0x04, 0x90, 0x68, 0x46, 0xF6, 0xF7, 0xB5, 0xFC, 0x05, 0xB0,
+ 0x30, 0xBD, 0x00, 0x00, 0x2C, 0x33, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21,
+ 0x19, 0xAA, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46,
+ 0x00, 0x6A, 0x86, 0xB0, 0x90, 0xF8, 0x7C, 0x20, 0x81, 0x6F, 0xD1, 0x40,
+ 0x01, 0xF0, 0x01, 0x01, 0x41, 0xF0, 0x80, 0x03, 0x01, 0xA9, 0x00, 0x91,
+ 0x42, 0x68, 0xC0, 0x6B, 0x10, 0x32, 0x00, 0xF1, 0x40, 0x01, 0x0D, 0xF4,
+ 0x2E, 0xF5, 0x01, 0xAA, 0x10, 0x21, 0x20, 0x48, 0xDE, 0xF7, 0xE1, 0xDE,
+ 0x03, 0x46, 0x01, 0x22, 0x1E, 0x49, 0x1F, 0x48, 0xDE, 0xF7, 0x6F, 0xDC,
+ 0x1E, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x80, 0x07, 0x26, 0xD5, 0x1D, 0x48,
+ 0x80, 0x68, 0xB0, 0xF5, 0x82, 0x7F, 0x02, 0xD0, 0xB0, 0xF5, 0x87, 0x7F,
+ 0x1E, 0xD1, 0x0B, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x09, 0x21, 0x8D, 0xF8,
+ 0x05, 0x10, 0x8D, 0xF8, 0x06, 0x00, 0x8D, 0xF8, 0x07, 0x00, 0x0A, 0x20,
+ 0x8D, 0xF8, 0x08, 0x00, 0x0D, 0x20, 0x8D, 0xF8, 0x09, 0x00, 0x0C, 0x20,
+ 0x8D, 0xF8, 0x0A, 0x00, 0x0F, 0x20, 0x8D, 0xF8, 0x0B, 0x00, 0x8D, 0xF8,
+ 0x0C, 0x00, 0x00, 0x20, 0x8D, 0xF8, 0x0D, 0x00, 0x8D, 0xF8, 0x0E, 0x00,
+ 0x8D, 0xF8, 0x0F, 0x00, 0x01, 0xAA, 0x03, 0x21, 0x20, 0x46, 0x00, 0xF0,
+ 0xAF, 0xF8, 0x20, 0x46, 0x00, 0xF0, 0x16, 0xFD, 0x06, 0xB0, 0x00, 0x20,
+ 0x10, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x50, 0x21, 0xB4, 0x33, 0xC0, 0x08,
+ 0x03, 0x39, 0x10, 0x21, 0x64, 0x01, 0x20, 0x00, 0x88, 0x76, 0x20, 0x00,
+ 0x30, 0xB5, 0x05, 0x46, 0x2B, 0x48, 0x85, 0xB0, 0x40, 0xF2, 0x91, 0x23,
+ 0x28, 0x4A, 0x5D, 0x21, 0x00, 0x78, 0xE6, 0xF7, 0xB7, 0xF9, 0x00, 0x28,
+ 0x47, 0xD0, 0x00, 0xF1, 0x1C, 0x04, 0x03, 0x90, 0x1C, 0x20, 0xAD, 0xF8,
+ 0x06, 0x00, 0x41, 0x20, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x20, 0xAD, 0xF8,
+ 0x04, 0x00, 0x4F, 0xF4, 0x80, 0x61, 0x06, 0x20, 0xAD, 0xF8, 0x00, 0x10,
+ 0xAD, 0xF8, 0x0A, 0x00, 0x68, 0x8B, 0x04, 0x90, 0x28, 0x6A, 0x81, 0x7A,
+ 0x03, 0x29, 0x13, 0xD1, 0x20, 0x22, 0x1A, 0x49, 0x19, 0x30, 0x10, 0xF4,
+ 0x16, 0xF5, 0x28, 0x6A, 0x17, 0x49, 0x40, 0x22, 0xC0, 0x6B, 0x20, 0x31,
+ 0x10, 0xF4, 0x0F, 0xF5, 0x28, 0x6A, 0x14, 0x49, 0x10, 0x22, 0x40, 0x68,
+ 0x71, 0x31, 0x40, 0x30, 0x10, 0xF4, 0x07, 0xF5, 0x0C, 0x20, 0x04, 0xF8,
+ 0x01, 0x0B, 0x00, 0x20, 0x29, 0x6A, 0xC9, 0x6B, 0x09, 0x5C, 0x40, 0x1C,
+ 0x04, 0xF8, 0x01, 0x1B, 0x40, 0x28, 0xF7, 0xD3, 0x28, 0x6A, 0x40, 0x21,
+ 0xC2, 0x6B, 0x0A, 0x48, 0xDE, 0xF7, 0x4D, 0xDE, 0x03, 0x46, 0x01, 0x22,
+ 0x08, 0x49, 0x09, 0x48, 0xDE, 0xF7, 0xDB, 0xDB, 0x68, 0x46, 0xF6, 0xF7,
+ 0xF3, 0xFB, 0x05, 0xB0, 0x30, 0xBD, 0x00, 0x00, 0x51, 0xAA, 0x82, 0x00,
+ 0x00, 0x74, 0x20, 0x00, 0x0A, 0x77, 0x20, 0x00, 0x00, 0x00, 0x50, 0x21,
+ 0x88, 0x33, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0xF0, 0xB5, 0x87, 0xB0,
+ 0x06, 0x46, 0xDD, 0xE9, 0x0C, 0x50, 0x56, 0xEA, 0x01, 0x04, 0x06, 0xD0,
+ 0x04, 0x2B, 0x01, 0xD8, 0x04, 0x2D, 0x04, 0xD9, 0x04, 0x20, 0x07, 0xB0,
+ 0xF0, 0xBD, 0x00, 0x20, 0xFB, 0xE7, 0x05, 0xEB, 0x85, 0x04, 0x1A, 0xB1,
+ 0x0F, 0x4F, 0x3C, 0x44, 0xE4, 0x5C, 0x05, 0xE0, 0x0D, 0x4F, 0x19, 0x3F,
+ 0x3C, 0x44, 0xE4, 0x5C, 0x06, 0x2C, 0x02, 0xD0, 0x04, 0x2C, 0x05, 0xD0,
+ 0x06, 0xE0, 0x08, 0xB1, 0x01, 0x24, 0x03, 0xE0, 0x02, 0x24, 0x01, 0xE0,
+ 0x00, 0xB1, 0x00, 0x24, 0x8D, 0xE8, 0x2E, 0x00, 0xCD, 0xE9, 0x04, 0x04,
+ 0x33, 0x46, 0x07, 0x22, 0x03, 0x49, 0x04, 0x48, 0xDE, 0xF7, 0x97, 0xDB,
+ 0x20, 0x46, 0xD8, 0xE7, 0x56, 0xA9, 0x82, 0x00, 0x28, 0x31, 0xC0, 0x08,
+ 0x03, 0x39, 0x10, 0x21, 0xF0, 0xB5, 0x17, 0x46, 0x0D, 0x46, 0x06, 0x46,
+ 0x04, 0x6A, 0x85, 0xB0, 0x00, 0x22, 0x27, 0x49, 0x27, 0x48, 0xDE, 0xF7,
+ 0x84, 0xDB, 0x28, 0x48, 0x4F, 0xF4, 0x83, 0x73, 0x25, 0x4A, 0x2D, 0x21,
+ 0x00, 0x78, 0xE6, 0xF7, 0x11, 0xF9, 0x02, 0x00, 0x32, 0xD0, 0x02, 0xF1,
+ 0x1C, 0x01, 0x00, 0x20, 0x01, 0xF8, 0x01, 0x5B, 0x3B, 0x5C, 0x40, 0x1C,
+ 0x01, 0xF8, 0x01, 0x3B, 0x10, 0x28, 0xF9, 0xD3, 0x4F, 0xF4, 0x80, 0x60,
+ 0xAD, 0xF8, 0x00, 0x00, 0x1C, 0x20, 0xAD, 0xF8, 0x06, 0x00, 0x11, 0x20,
+ 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x20, 0x03, 0x92, 0xAD, 0xF8, 0x04, 0x00,
+ 0x70, 0x8B, 0xED, 0x1E, 0x04, 0x90, 0x09, 0x2D, 0x0E, 0xD2, 0xDF, 0xE8,
+ 0x05, 0xF0, 0x09, 0x05, 0x0D, 0x15, 0x0D, 0x19, 0x0D, 0x0D, 0x1D, 0x00,
+ 0x20, 0x68, 0x40, 0xF0, 0x40, 0x00, 0x02, 0xE0, 0x20, 0x68, 0x40, 0xF0,
+ 0x10, 0x00, 0x20, 0x60, 0x06, 0x20, 0xAD, 0xF8, 0x0A, 0x00, 0x68, 0x46,
+ 0xF6, 0xF7, 0x62, 0xFB, 0x05, 0xB0, 0xF0, 0xBD, 0x20, 0x68, 0x40, 0xF4,
+ 0x80, 0x60, 0xF2, 0xE7, 0x20, 0x68, 0x40, 0xF4, 0x80, 0x40, 0xEE, 0xE7,
+ 0x20, 0x68, 0x40, 0xF4, 0x80, 0x20, 0xEA, 0xE7, 0x2C, 0x32, 0xC0, 0x08,
+ 0x02, 0x39, 0x10, 0x21, 0x88, 0xA9, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00,
+ 0xF0, 0xB5, 0x85, 0xB0, 0x0F, 0x46, 0x05, 0x46, 0x16, 0x46, 0x14, 0x21,
+ 0x68, 0x46, 0x10, 0xF4, 0xDD, 0xF4, 0x14, 0x48, 0x40, 0xF2, 0x5C, 0x43,
+ 0x11, 0x4A, 0x20, 0x21, 0x00, 0x78, 0xE6, 0xF7, 0xB5, 0xF8, 0x04, 0x00,
+ 0x19, 0xD0, 0x10, 0x22, 0x39, 0x46, 0x10, 0xF4, 0x2E, 0xF4, 0x10, 0x22,
+ 0x31, 0x46, 0x04, 0xF1, 0x10, 0x00, 0x10, 0xF4, 0x28, 0xF4, 0x40, 0xF2,
+ 0x06, 0x40, 0xAD, 0xF8, 0x00, 0x00, 0x03, 0x94, 0xAD, 0xF8, 0x0A, 0x50,
+ 0x40, 0xF2, 0x69, 0x43, 0x04, 0x4A, 0x69, 0x46, 0x05, 0x48, 0xE6, 0xF7,
+ 0xD3, 0xFE, 0x00, 0xF0, 0xF9, 0xFB, 0x05, 0xB0, 0xF0, 0xBD, 0x00, 0x00,
+ 0xCA, 0xAA, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0xAC, 0x76, 0x20, 0x00,
+ 0x10, 0xB5, 0x86, 0xB0, 0x04, 0x46, 0x14, 0x21, 0x68, 0x46, 0x10, 0xF4,
+ 0xA9, 0xF4, 0x40, 0xF2, 0x07, 0x41, 0xAD, 0xF8, 0x00, 0x10, 0xAD, 0xF8,
+ 0x0A, 0x40, 0x40, 0xF2, 0x7E, 0x43, 0x04, 0x4A, 0x69, 0x46, 0x04, 0x48,
+ 0xE6, 0xF7, 0xB4, 0xFE, 0x00, 0xF0, 0xDA, 0xFB, 0x06, 0xB0, 0x10, 0xBD,
+ 0xE1, 0xAA, 0x82, 0x00, 0xAC, 0x76, 0x20, 0x00, 0x70, 0xB5, 0x0E, 0x46,
+ 0x05, 0x46, 0x86, 0xB0, 0x14, 0x46, 0x11, 0x46, 0x1F, 0x48, 0xDE, 0xF7,
+ 0xA5, 0xDC, 0x00, 0x90, 0x33, 0x46, 0x02, 0x22, 0x1D, 0x49, 0x1E, 0x48,
+ 0xDE, 0xF7, 0xCF, 0xDA, 0x1E, 0x48, 0x40, 0xF2, 0xFB, 0x13, 0x1C, 0x4A,
+ 0x24, 0x21, 0x00, 0x78, 0xE6, 0xF7, 0x5C, 0xF8, 0x02, 0x00, 0x28, 0xD0,
+ 0x02, 0xF1, 0x1C, 0x00, 0x09, 0x21, 0x00, 0xF8, 0x01, 0x1B, 0x00, 0x21,
+ 0x00, 0xF8, 0x01, 0x6B, 0x63, 0x5C, 0x49, 0x1C, 0x00, 0xF8, 0x01, 0x3B,
+ 0x06, 0x29, 0xF9, 0xD3, 0x4F, 0xF4, 0x80, 0x60, 0xAD, 0xF8, 0x04, 0x00,
+ 0x1C, 0x20, 0xAD, 0xF8, 0x0A, 0x00, 0x08, 0x20, 0xAD, 0xF8, 0x0C, 0x00,
+ 0x01, 0x20, 0x04, 0x92, 0xAD, 0xF8, 0x08, 0x00, 0x68, 0x8B, 0x05, 0x90,
+ 0x28, 0x6A, 0x01, 0x68, 0x41, 0xF4, 0x80, 0x31, 0x01, 0x60, 0x06, 0x20,
+ 0xAD, 0xF8, 0x0E, 0x00, 0x01, 0xA8, 0xF6, 0xF7, 0xB7, 0xFA, 0x06, 0xB0,
+ 0x70, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0xD0, 0x32, 0xC0, 0x08,
+ 0x03, 0x39, 0x10, 0x21, 0xEF, 0xA9, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00,
+ 0x30, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x85, 0xB0, 0x00, 0x22, 0x1B, 0x49,
+ 0x1B, 0x48, 0xDE, 0xF7, 0x86, 0xDA, 0x1C, 0x48, 0x40, 0xF2, 0xCD, 0x13,
+ 0x19, 0x4A, 0x2D, 0x21, 0x00, 0x78, 0xE6, 0xF7, 0x13, 0xF8, 0x01, 0x00,
+ 0x26, 0xD0, 0x01, 0xF1, 0x1C, 0x00, 0x08, 0x22, 0x00, 0xF8, 0x01, 0x2B,
+ 0x00, 0x22, 0xAB, 0x5C, 0x52, 0x1C, 0x00, 0xF8, 0x01, 0x3B, 0x10, 0x2A,
+ 0xF9, 0xD3, 0x4F, 0xF4, 0x80, 0x60, 0xAD, 0xF8, 0x00, 0x00, 0x1C, 0x20,
+ 0xAD, 0xF8, 0x06, 0x00, 0x11, 0x20, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x20,
+ 0x03, 0x91, 0xAD, 0xF8, 0x04, 0x00, 0x60, 0x8B, 0x04, 0x90, 0x20, 0x6A,
+ 0x01, 0x68, 0x41, 0xF4, 0x80, 0x41, 0x01, 0x60, 0x06, 0x20, 0xAD, 0xF8,
+ 0x0A, 0x00, 0x68, 0x46, 0xF6, 0xF7, 0x70, 0xFA, 0x05, 0xB0, 0x30, 0xBD,
+ 0xBC, 0x32, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0xDC, 0xA9, 0x82, 0x00,
+ 0x00, 0x74, 0x20, 0x00, 0x70, 0xB5, 0x05, 0x46, 0x11, 0x48, 0x0E, 0x46,
+ 0x86, 0xB0, 0x40, 0xF2, 0x8F, 0x23, 0x0E, 0x4A, 0x21, 0x21, 0x00, 0x78,
+ 0xE5, 0xF7, 0xD4, 0xFF, 0x04, 0x00, 0x12, 0xD0, 0x20, 0x22, 0x31, 0x46,
+ 0x60, 0x1C, 0x10, 0xF4, 0x4C, 0xF3, 0x25, 0x70, 0x40, 0xF2, 0x09, 0x40,
+ 0xAD, 0xF8, 0x00, 0x00, 0x07, 0x48, 0x03, 0x94, 0x4F, 0xF4, 0x27, 0x73,
+ 0x03, 0x4A, 0x69, 0x46, 0x00, 0x78, 0xE6, 0xF7, 0xC5, 0xFA, 0x06, 0xB0,
+ 0x70, 0xBD, 0x00, 0x00, 0x21, 0xA9, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00,
+ 0x84, 0x76, 0x20, 0x00, 0xF0, 0xB5, 0x05, 0x46, 0x14, 0x48, 0x16, 0x46,
+ 0x0F, 0x46, 0x85, 0xB0, 0x40, 0xF2, 0x7A, 0x23, 0x10, 0x4A, 0x61, 0x21,
+ 0x00, 0x78, 0xE5, 0xF7, 0xA9, 0xFF, 0x04, 0x00, 0x18, 0xD0, 0x40, 0x22,
+ 0x39, 0x46, 0x60, 0x1C, 0x10, 0xF4, 0x21, 0xF3, 0x20, 0x22, 0x31, 0x46,
+ 0x04, 0xF1, 0x41, 0x00, 0x10, 0xF4, 0x1B, 0xF3, 0x25, 0x70, 0x4F, 0xF4,
+ 0x81, 0x60, 0xAD, 0xF8, 0x00, 0x00, 0x07, 0x48, 0x03, 0x94, 0x40, 0xF2,
+ 0x87, 0x23, 0x03, 0x4A, 0x69, 0x46, 0x00, 0x78, 0xE6, 0xF7, 0x94, 0xFA,
+ 0x05, 0xB0, 0xF0, 0xBD, 0x06, 0xA9, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00,
+ 0x84, 0x76, 0x20, 0x00, 0x70, 0xB5, 0x15, 0x46, 0x0E, 0x46, 0x04, 0x46,
+ 0x86, 0xB0, 0x00, 0x22, 0x1D, 0x49, 0x1E, 0x48, 0xDE, 0xF7, 0xE7, 0xD9,
+ 0x1E, 0x48, 0x40, 0xF2, 0x77, 0x13, 0x1C, 0x4A, 0x27, 0x21, 0x00, 0x78,
+ 0xE5, 0xF7, 0x74, 0xFF, 0x02, 0x00, 0x2B, 0xD0, 0x02, 0xF1, 0x1C, 0x00,
+ 0x07, 0x21, 0x00, 0xF8, 0x01, 0x1B, 0x31, 0x0A, 0x00, 0xF8, 0x01, 0x6B,
+ 0x00, 0xF8, 0x01, 0x1B, 0x00, 0x21, 0x6B, 0x5C, 0x49, 0x1C, 0x00, 0xF8,
+ 0x01, 0x3B, 0x08, 0x29, 0xF9, 0xD3, 0x4F, 0xF4, 0x80, 0x60, 0xAD, 0xF8,
+ 0x00, 0x00, 0x1C, 0x20, 0xAD, 0xF8, 0x06, 0x00, 0x0B, 0x20, 0xAD, 0xF8,
+ 0x08, 0x00, 0x01, 0x20, 0xAD, 0xF8, 0x04, 0x00, 0x06, 0x20, 0x03, 0x92,
+ 0xAD, 0xF8, 0x0A, 0x00, 0x60, 0x8B, 0x04, 0x90, 0x20, 0x6A, 0x01, 0x68,
+ 0x41, 0xF4, 0x80, 0x51, 0x01, 0x60, 0x68, 0x46, 0xF6, 0xF7, 0xCC, 0xF9,
+ 0x06, 0xB0, 0x70, 0xBD, 0x70, 0x32, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21,
+ 0xB2, 0xA9, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x4F,
+ 0x8B, 0xB0, 0x0E, 0x46, 0xDD, 0xE9, 0x15, 0xB9, 0x05, 0x46, 0x00, 0xF1,
+ 0x0C, 0x01, 0x04, 0x6A, 0x1F, 0x46, 0x90, 0x46, 0xDD, 0xF8, 0x50, 0xA0,
+ 0x2F, 0x48, 0xDE, 0xF7, 0x65, 0xDB, 0x03, 0x46, 0x17, 0x98, 0xCD, 0xF8,
+ 0x00, 0x80, 0xCD, 0xE9, 0x04, 0x90, 0x0D, 0xF1, 0x04, 0x0C, 0x07, 0x22,
+ 0x8C, 0xE8, 0x80, 0x0C, 0x29, 0x49, 0x2A, 0x48, 0xDE, 0xF7, 0x87, 0xD9,
+ 0x2A, 0x48, 0xC9, 0x23, 0x28, 0x4A, 0x23, 0x21, 0x00, 0x78, 0xE5, 0xF7,
+ 0x15, 0xFF, 0x00, 0x28, 0x40, 0xD0, 0x06, 0x77, 0x80, 0xF8, 0x1D, 0x80,
+ 0x87, 0x77, 0x80, 0xF8, 0x1F, 0xA0, 0x80, 0xF8, 0x20, 0xB0, 0x22, 0x21,
+ 0x80, 0xF8, 0x21, 0x90, 0x17, 0x9A, 0x0A, 0x54, 0x4F, 0xF4, 0x80, 0x61,
+ 0xAD, 0xF8, 0x18, 0x10, 0x1C, 0x21, 0xAD, 0xF8, 0x1E, 0x10, 0x07, 0x21,
+ 0xAD, 0xF8, 0x20, 0x10, 0x01, 0x21, 0x09, 0x90, 0xAD, 0xF8, 0x1C, 0x10,
+ 0x69, 0x8B, 0x0A, 0x91, 0x01, 0x2E, 0x02, 0xD0, 0x02, 0x2E, 0x0D, 0xD0,
+ 0x18, 0xE0, 0xC1, 0x69, 0xC4, 0xF8, 0x0B, 0x10, 0x01, 0x8C, 0xA4, 0xF8,
+ 0x0F, 0x10, 0x90, 0xF8, 0x22, 0x00, 0x60, 0x74, 0x20, 0x68, 0x40, 0xF0,
+ 0x01, 0x00, 0x0A, 0xE0, 0xC1, 0x69, 0xC4, 0xF8, 0x12, 0x10, 0x01, 0x8C,
+ 0xE1, 0x82, 0x90, 0xF8, 0x22, 0x00, 0x20, 0x76, 0x20, 0x68, 0x40, 0xF0,
+ 0x04, 0x00, 0x20, 0x60, 0x06, 0x20, 0xAD, 0xF8, 0x22, 0x00, 0x06, 0xA8,
+ 0xF6, 0xF7, 0x58, 0xF9, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x21, 0xA4, 0x31, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21,
+ 0x6F, 0xA9, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x30, 0xB5, 0x0D, 0x46,
+ 0x04, 0x46, 0x00, 0xF1, 0x0C, 0x01, 0x87, 0xB0, 0x1A, 0x48, 0xDE, 0xF7,
+ 0xF5, 0xDA, 0x03, 0x46, 0x02, 0x22, 0x19, 0x49, 0x19, 0x48, 0x00, 0x95,
+ 0xDE, 0xF7, 0x1F, 0xD9, 0x19, 0x48, 0x4F, 0xF4, 0xA4, 0x73, 0x17, 0x4A,
+ 0x1E, 0x21, 0x00, 0x78, 0xE5, 0xF7, 0xAC, 0xFE, 0x00, 0x28, 0x1E, 0xD0,
+ 0x05, 0x21, 0x01, 0x77, 0x45, 0x77, 0x04, 0x90, 0x1C, 0x20, 0xAD, 0xF8,
+ 0x0A, 0x00, 0x02, 0x20, 0xAD, 0xF8, 0x0C, 0x00, 0x4F, 0xF4, 0x80, 0x61,
+ 0x01, 0x20, 0xAD, 0xF8, 0x04, 0x10, 0xAD, 0xF8, 0x08, 0x00, 0x60, 0x8B,
+ 0x05, 0x90, 0x20, 0x6A, 0x18, 0xB1, 0x01, 0x68, 0x41, 0xF4, 0x80, 0x71,
+ 0x01, 0x60, 0x06, 0x20, 0xAD, 0xF8, 0x0E, 0x00, 0x01, 0xA8, 0xF6, 0xF7,
+ 0x11, 0xF9, 0x07, 0xB0, 0x30, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21,
+ 0x44, 0x32, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0x9D, 0xA9, 0x82, 0x00,
+ 0x00, 0x74, 0x20, 0x00, 0xF0, 0xB5, 0x85, 0xB0, 0x0F, 0x46, 0x05, 0x46,
+ 0x16, 0x46, 0x14, 0x21, 0x68, 0x46, 0x10, 0xF4, 0x95, 0xF2, 0x19, 0x48,
+ 0x40, 0xF2, 0xA2, 0x43, 0x16, 0x4A, 0x60, 0x21, 0x00, 0x78, 0xE5, 0xF7,
+ 0x6D, 0xFE, 0x04, 0x00, 0x23, 0xD0, 0x00, 0x22, 0x14, 0x49, 0x15, 0x48,
+ 0xDE, 0xF7, 0xD1, 0xD8, 0x40, 0x22, 0x39, 0x46, 0x20, 0x46, 0x10, 0xF4,
+ 0xE0, 0xF1, 0x20, 0x22, 0x31, 0x46, 0x04, 0xF1, 0x40, 0x00, 0x10, 0xF4,
+ 0xDA, 0xF1, 0x40, 0xF2, 0x09, 0x40, 0xAD, 0xF8, 0x00, 0x00, 0x03, 0x94,
+ 0xAD, 0xF8, 0x0A, 0x50, 0x4F, 0xF4, 0x96, 0x63, 0x06, 0x4A, 0x69, 0x46,
+ 0x09, 0x48, 0xE6, 0xF7, 0x85, 0xFC, 0x04, 0x46, 0x00, 0xF0, 0xAA, 0xF9,
+ 0x20, 0x46, 0x05, 0xB0, 0xF0, 0xBD, 0x00, 0x20, 0xFB, 0xE7, 0x00, 0x00,
+ 0x0D, 0xAB, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0xAC, 0x44, 0xC0, 0x08,
+ 0x03, 0x39, 0x10, 0x21, 0xAC, 0x76, 0x20, 0x00, 0x10, 0xB5, 0x86, 0xB0,
+ 0x04, 0x46, 0x14, 0x21, 0x68, 0x46, 0x10, 0xF4, 0x53, 0xF2, 0x4F, 0xF4,
+ 0x81, 0x61, 0xAD, 0xF8, 0x00, 0x10, 0xAD, 0xF8, 0x0A, 0x40, 0x00, 0x22,
+ 0x0C, 0x49, 0x0D, 0x48, 0xDE, 0xF7, 0x93, 0xD8, 0x40, 0xF2, 0x8F, 0x43,
+ 0x0B, 0x4A, 0x69, 0x46, 0x0B, 0x48, 0xE6, 0xF7, 0x59, 0xFC, 0x04, 0x00,
+ 0x06, 0xD1, 0x06, 0x49, 0x06, 0x48, 0x00, 0x22, 0x18, 0x31, 0xC0, 0x1E,
+ 0xDE, 0xF7, 0x83, 0xD8, 0x00, 0xF0, 0x76, 0xF9, 0x06, 0xB0, 0x20, 0x46,
+ 0x10, 0xBD, 0x00, 0x00, 0x70, 0x44, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21,
+ 0xF5, 0xAA, 0x82, 0x00, 0xAC, 0x76, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x47,
+ 0x81, 0x46, 0xDD, 0xE9, 0x0D, 0x50, 0x0C, 0x9C, 0x8D, 0xF8, 0x09, 0x50,
+ 0x17, 0x46, 0x88, 0x46, 0x8D, 0xF8, 0x08, 0x40, 0x1E, 0x46, 0xAD, 0xF8,
+ 0x0C, 0x30, 0x8D, 0xF8, 0x0A, 0x00, 0x02, 0xAB, 0x4A, 0x46, 0x39, 0x46,
+ 0x40, 0x46, 0xE6, 0xF7, 0x09, 0xFE, 0x33, 0x46, 0x3A, 0x46, 0x41, 0x46,
+ 0x48, 0x46, 0xCD, 0xE9, 0x00, 0x45, 0xEF, 0xF7, 0xD7, 0xFF, 0xBD, 0xE8,
+ 0xFF, 0x87, 0x00, 0x00, 0x30, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x00, 0xF1,
+ 0x0C, 0x01, 0x87, 0xB0, 0x19, 0x48, 0xDE, 0xF7, 0x19, 0xDA, 0x03, 0x46,
+ 0x02, 0x22, 0x18, 0x49, 0x18, 0x48, 0x00, 0x95, 0xDE, 0xF7, 0x43, 0xD8,
+ 0x18, 0x48, 0x4F, 0xF4, 0xD2, 0x73, 0x16, 0x4A, 0x1E, 0x21, 0x00, 0x78,
+ 0xE5, 0xF7, 0xD0, 0xFD, 0x00, 0x28, 0x1D, 0xD0, 0x0B, 0x21, 0x01, 0x77,
+ 0x45, 0x77, 0x04, 0x90, 0x1C, 0x20, 0xAD, 0xF8, 0x0A, 0x00, 0x02, 0x20,
+ 0xAD, 0xF8, 0x0C, 0x00, 0x01, 0x20, 0xAD, 0xF8, 0x08, 0x00, 0x4F, 0xF4,
+ 0x80, 0x61, 0x06, 0x20, 0xAD, 0xF8, 0x04, 0x10, 0xAD, 0xF8, 0x0E, 0x00,
+ 0x60, 0x8B, 0x05, 0x90, 0x20, 0x6A, 0x01, 0x68, 0x41, 0xF4, 0x80, 0x11,
+ 0x01, 0x60, 0x01, 0xA8, 0xF6, 0xF7, 0x36, 0xF8, 0x07, 0xB0, 0x30, 0xBD,
+ 0x00, 0x00, 0x30, 0x21, 0x88, 0x32, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21,
+ 0xC7, 0xA9, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x70, 0xB5, 0x04, 0x46,
+ 0x0D, 0x46, 0x0A, 0x46, 0x86, 0xB0, 0x10, 0x21, 0x26, 0x48, 0xDE, 0xF7,
+ 0x72, 0xDA, 0x06, 0x46, 0x04, 0xF1, 0x0C, 0x01, 0x24, 0x48, 0xDE, 0xF7,
+ 0xCF, 0xD9, 0x03, 0x46, 0x02, 0x22, 0x23, 0x49, 0x23, 0x48, 0x00, 0x96,
+ 0xDD, 0xF7, 0xF9, 0xDF, 0x23, 0x48, 0x40, 0xF2, 0x1E, 0x23, 0x21, 0x4A,
+ 0x2D, 0x21, 0x00, 0x78, 0xE5, 0xF7, 0x86, 0xFD, 0x02, 0x00, 0x30, 0xD0,
+ 0x02, 0xF1, 0x1C, 0x00, 0x0A, 0x21, 0x00, 0xF8, 0x01, 0x1B, 0x00, 0x21,
+ 0x6B, 0x5C, 0x49, 0x1C, 0x00, 0xF8, 0x01, 0x3B, 0x10, 0x29, 0xF9, 0xD3,
+ 0x4F, 0xF4, 0x80, 0x60, 0xAD, 0xF8, 0x04, 0x00, 0x1C, 0x20, 0xAD, 0xF8,
+ 0x0A, 0x00, 0x11, 0x20, 0x01, 0x26, 0x04, 0x92, 0xAD, 0xF8, 0x0C, 0x00,
+ 0xAD, 0xF8, 0x08, 0x60, 0x60, 0x8B, 0x05, 0x90, 0x20, 0x6A, 0x10, 0x22,
+ 0x01, 0x68, 0x41, 0xF4, 0x80, 0x21, 0x01, 0x60, 0x29, 0x46, 0x04, 0xF1,
+ 0x2A, 0x00, 0x10, 0xF4, 0xDC, 0xF0, 0x84, 0xF8, 0x28, 0x60, 0x00, 0x20,
+ 0xE0, 0x63, 0x06, 0x20, 0xAD, 0xF8, 0x0E, 0x00, 0x01, 0xA8, 0xF5, 0xF7,
+ 0xD9, 0xFF, 0x06, 0xB0, 0x70, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x50, 0x21,
+ 0x00, 0x00, 0x30, 0x21, 0x00, 0x33, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21,
+ 0x07, 0xAA, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x0B, 0x46, 0x00, 0x28,
+ 0x03, 0xD1, 0x11, 0x46, 0x18, 0x46, 0xEA, 0xF7, 0xF3, 0xB9, 0x70, 0x47,
+ 0x01, 0x49, 0x88, 0x60, 0x70, 0x47, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00,
+ 0xF8, 0xB5, 0x16, 0x4D, 0x0E, 0x46, 0x04, 0x00, 0x18, 0xD0, 0x01, 0x46,
+ 0x14, 0x48, 0xDE, 0xF7, 0x67, 0xD9, 0x00, 0x90, 0x33, 0x46, 0x02, 0x22,
+ 0x12, 0x49, 0x13, 0x48, 0xDD, 0xF7, 0x91, 0xDF, 0xBE, 0xB1, 0x60, 0x79,
+ 0x03, 0x21, 0xB1, 0xEB, 0x90, 0x1F, 0x10, 0xD1, 0x20, 0x68, 0x45, 0xF8,
+ 0x40, 0x0F, 0xA0, 0x88, 0xA8, 0x80, 0x01, 0x20, 0xA8, 0x71, 0x0D, 0xE0,
+ 0x4E, 0xB1, 0x0B, 0x46, 0x08, 0x49, 0x09, 0x48, 0x01, 0x22, 0x34, 0x31,
+ 0x80, 0x1E, 0xDD, 0xF7, 0x7A, 0xDF, 0x00, 0x20, 0xF8, 0xBD, 0x00, 0x20,
+ 0x85, 0xF8, 0x46, 0x00, 0x01, 0x20, 0xF8, 0xBD, 0x88, 0x76, 0x20, 0x00,
+ 0x00, 0x00, 0x30, 0x21, 0x54, 0x25, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21,
+ 0x02, 0x4A, 0x02, 0xF8, 0x59, 0x0F, 0x51, 0x70, 0x70, 0x47, 0x00, 0x00,
+ 0x88, 0x76, 0x20, 0x00, 0x01, 0x49, 0xC8, 0x75, 0x70, 0x47, 0x00, 0x00,
+ 0x88, 0x76, 0x20, 0x00, 0x00, 0x28, 0x04, 0xD1, 0x02, 0x48, 0x0A, 0x68,
+ 0x42, 0x63, 0x89, 0x88, 0x01, 0x87, 0x70, 0x47, 0x88, 0x76, 0x20, 0x00,
+ 0x10, 0xB5, 0x04, 0x46, 0x03, 0x28, 0x09, 0xD2, 0x03, 0x46, 0x01, 0x22,
+ 0x04, 0x49, 0x05, 0x48, 0xDD, 0xF7, 0x49, 0xDF, 0x04, 0x48, 0x44, 0x75,
+ 0x01, 0x20, 0x10, 0xBD, 0x00, 0x20, 0x10, 0xBD, 0x08, 0x31, 0xC0, 0x08,
+ 0x02, 0x39, 0x10, 0x21, 0x88, 0x76, 0x20, 0x00, 0x10, 0xB5, 0x0A, 0x4C,
+ 0x48, 0xB1, 0x01, 0x46, 0x10, 0x22, 0x04, 0xF1, 0x49, 0x00, 0x10, 0xF4,
+ 0x48, 0xF0, 0x01, 0x20, 0x84, 0xF8, 0x47, 0x00, 0x10, 0xBD, 0x21, 0x20,
+ 0x84, 0xF8, 0x48, 0x00, 0xBD, 0xE8, 0x10, 0x40, 0x4F, 0xF4, 0x80, 0x60,
+ 0xFF, 0xF7, 0x2C, 0xBC, 0x88, 0x76, 0x20, 0x00, 0x08, 0x49, 0x42, 0x79,
+ 0x4F, 0xF4, 0x00, 0x33, 0x09, 0x78, 0x43, 0xEA, 0x01, 0x61, 0x0A, 0x43,
+ 0x05, 0x49, 0x4F, 0xF4, 0x7A, 0x73, 0x09, 0x7D, 0x11, 0xFB, 0x03, 0xF3,
+ 0x03, 0xA1, 0xE6, 0xF7, 0xA5, 0xBC, 0x00, 0x00, 0x84, 0x76, 0x20, 0x00,
+ 0x88, 0x76, 0x20, 0x00, 0x73, 0x6D, 0x70, 0x00, 0xE6, 0xF7, 0xB4, 0xBC,
+ 0x2D, 0xE9, 0xF0, 0x43, 0x36, 0x4C, 0x4F, 0xF6, 0xFF, 0x77, 0x87, 0xB0,
+ 0xA0, 0x8D, 0xB8, 0x42, 0x34, 0xD1, 0x40, 0xF2, 0x06, 0x45, 0x40, 0xF2,
+ 0xD3, 0x49, 0x04, 0xF1, 0x24, 0x08, 0xEE, 0x1C, 0x4B, 0x46, 0x30, 0x4A,
+ 0x01, 0xA9, 0x40, 0x46, 0xE6, 0xF7, 0x98, 0xFA, 0x00, 0x28, 0x25, 0xD0,
+ 0xBD, 0xF8, 0x04, 0x00, 0x00, 0x90, 0x94, 0xF8, 0x2C, 0x30, 0x02, 0x22,
+ 0x2A, 0x49, 0x2B, 0x48, 0xDD, 0xF7, 0xE9, 0xDE, 0xBD, 0xF8, 0x0E, 0x00,
+ 0xA0, 0x85, 0xC1, 0x05, 0x03, 0xD5, 0xC0, 0xB2, 0xFB, 0xF7, 0x0A, 0xFF,
+ 0xA8, 0xB1, 0xBD, 0xF8, 0x04, 0x00, 0xA0, 0xF5, 0x80, 0x61, 0x07, 0x39,
+ 0x0A, 0xD0, 0xA8, 0x42, 0x27, 0xD1, 0x04, 0x98, 0x00, 0xF1, 0x10, 0x01,
+ 0xF1, 0xF7, 0x04, 0xFD, 0x40, 0xF2, 0xF4, 0x42, 0x04, 0x98, 0x2B, 0xE0,
+ 0xF1, 0xF7, 0xC3, 0xFD, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0xBD, 0xF8,
+ 0x04, 0x00, 0x00, 0x90, 0x17, 0x49, 0x18, 0x48, 0x94, 0xF8, 0x2C, 0x30,
+ 0x02, 0x22, 0x34, 0x31, 0xC0, 0x1E, 0xDD, 0xF7, 0xBE, 0xDE, 0xBD, 0xF8,
+ 0x04, 0x00, 0xA8, 0x42, 0x01, 0xD0, 0xB0, 0x42, 0x05, 0xD1, 0x40, 0xF2,
+ 0xE4, 0x42, 0x0E, 0x49, 0x04, 0x98, 0xE5, 0xF7, 0x35, 0xFD, 0xA7, 0x85,
+ 0xB4, 0xE7, 0xB0, 0xF5, 0x81, 0x6F, 0x0D, 0xD0, 0xB0, 0x42, 0xDD, 0xD1,
+ 0x04, 0x98, 0x00, 0xF1, 0x40, 0x01, 0xFF, 0xF7, 0x89, 0xF8, 0x04, 0x98,
+ 0x4F, 0xF4, 0xA0, 0x62, 0x04, 0x49, 0xE5, 0xF7, 0x23, 0xFD, 0xD1, 0xE7,
+ 0xFF, 0xF7, 0x98, 0xF8, 0xCE, 0xE7, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00,
+ 0x26, 0xAB, 0x82, 0x00, 0xF8, 0x44, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21,
+ 0x10, 0xB5, 0x14, 0x46, 0xFB, 0xF7, 0x8E, 0xFE, 0x00, 0x28, 0x00, 0xD0,
+ 0xC4, 0x63, 0x10, 0xBD, 0x10, 0xB5, 0x14, 0x46, 0xFB, 0xF7, 0x86, 0xFE,
+ 0x00, 0x28, 0x00, 0xD0, 0x04, 0x65, 0x10, 0xBD, 0x2D, 0xE9, 0xF8, 0x43,
+ 0x16, 0x46, 0x0F, 0x46, 0x80, 0x46, 0xFB, 0xF7, 0x7B, 0xFE, 0x24, 0x4D,
+ 0x04, 0x00, 0x37, 0xD0, 0x20, 0x6A, 0x00, 0x28, 0x40, 0xD0, 0x94, 0xF8,
+ 0x6B, 0x10, 0x49, 0xB3, 0x81, 0x7A, 0x05, 0x29, 0x3A, 0xD1, 0x00, 0x21,
+ 0x80, 0xF8, 0x74, 0x10, 0x33, 0x46, 0x01, 0x22, 0x1C, 0x49, 0xE8, 0x1C,
+ 0xDD, 0xF7, 0x67, 0xDE, 0x01, 0x2E, 0x0A, 0xD0, 0x0C, 0x21, 0x20, 0x46,
+ 0xFF, 0xF7, 0x32, 0xFD, 0x20, 0x46, 0xBD, 0xE8, 0xF8, 0x43, 0x40, 0xF2,
+ 0x0C, 0x51, 0xFB, 0xF7, 0x17, 0xBC, 0x20, 0x7F, 0x01, 0x28, 0x08, 0xD1,
+ 0x20, 0x6A, 0x90, 0xF8, 0x7F, 0x10, 0x00, 0x29, 0x1C, 0xD0, 0x01, 0x68,
+ 0x41, 0xF0, 0x00, 0x51, 0x01, 0x60, 0x20, 0x46, 0xBD, 0xE8, 0xF8, 0x43,
+ 0xFE, 0xF7, 0x8C, 0xBF, 0x28, 0x46, 0xBD, 0xE8, 0xF8, 0x43, 0x0A, 0x49,
+ 0x00, 0x22, 0x20, 0x31, 0xDD, 0xF7, 0x41, 0x9E, 0x41, 0x46, 0x08, 0x48,
+ 0xDE, 0xF7, 0x0C, 0xD8, 0x05, 0x49, 0x03, 0x46, 0x02, 0x22, 0x4C, 0x31,
+ 0x28, 0x46, 0x00, 0x97, 0xDD, 0xF7, 0x35, 0xDE, 0xBD, 0xE8, 0xF8, 0x83,
+ 0x00, 0x39, 0x10, 0x21, 0xE0, 0x23, 0xC0, 0x08, 0x00, 0x00, 0x30, 0x21,
+ 0xF8, 0xB5, 0x15, 0x46, 0x0E, 0x46, 0x07, 0x46, 0xFB, 0xF7, 0x26, 0xFE,
+ 0x04, 0x00, 0x29, 0xD0, 0x20, 0x6A, 0x00, 0x28, 0x33, 0xD0, 0x81, 0x7A,
+ 0x01, 0x29, 0x30, 0xD1, 0x00, 0x21, 0x80, 0xF8, 0x74, 0x10, 0x2B, 0x46,
+ 0x01, 0x22, 0x16, 0x49, 0x16, 0x48, 0xDD, 0xF7, 0x16, 0xDE, 0x01, 0x2D,
+ 0x0A, 0xD0, 0x08, 0x21, 0x20, 0x46, 0xFF, 0xF7, 0xE1, 0xFC, 0x20, 0x46,
+ 0xBD, 0xE8, 0xF8, 0x40, 0x40, 0xF2, 0x0C, 0x51, 0xFB, 0xF7, 0xC6, 0xBB,
+ 0x01, 0x25, 0xE5, 0x84, 0x60, 0x79, 0x40, 0xF4, 0x80, 0x70, 0xFF, 0xF7,
+ 0x07, 0xFB, 0x20, 0x6A, 0x80, 0xF8, 0x80, 0x50, 0xBD, 0xE8, 0xF8, 0x40,
+ 0xFF, 0xF7, 0xF0, 0xBE, 0x39, 0x46, 0x08, 0x48, 0xDD, 0xF7, 0xC6, 0xDF,
+ 0x03, 0x46, 0x04, 0x49, 0x04, 0x48, 0x02, 0x22, 0x28, 0x31, 0xC0, 0x1E,
+ 0x00, 0x96, 0xDD, 0xF7, 0xEE, 0xDD, 0xF8, 0xBD, 0xE0, 0x24, 0xC0, 0x08,
+ 0x03, 0x39, 0x10, 0x21, 0x00, 0x00, 0x30, 0x21, 0x70, 0xB5, 0x10, 0x4B,
+ 0x00, 0x21, 0x5A, 0x68, 0x1B, 0x78, 0x10, 0xE0, 0xC1, 0xEB, 0xC1, 0x04,
+ 0x12, 0xF8, 0x24, 0x50, 0x4D, 0xB1, 0x02, 0xEB, 0x84, 0x04, 0xE4, 0x68,
+ 0x84, 0x42, 0x04, 0xD1, 0xC1, 0xEB, 0xC1, 0x00, 0x02, 0xEB, 0x80, 0x00,
+ 0x70, 0xBD, 0x49, 0x1C, 0xC9, 0xB2, 0x99, 0x42, 0xEC, 0xD3, 0x03, 0x46,
+ 0x01, 0x22, 0x04, 0x49, 0x04, 0x48, 0xDD, 0xF7, 0xC8, 0xDD, 0x00, 0x20,
+ 0x70, 0xBD, 0x00, 0x00, 0xB0, 0x78, 0x20, 0x00, 0x94, 0x6C, 0xC0, 0x08,
+ 0x00, 0x33, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x4F, 0x83, 0xB0, 0x8B, 0x46,
+ 0xDD, 0xE9, 0x10, 0x48, 0x01, 0x46, 0x00, 0x20, 0x20, 0x80, 0x1F, 0x46,
+ 0x40, 0xF2, 0x04, 0x45, 0x08, 0x46, 0xF9, 0xF7, 0xA5, 0xFA, 0x06, 0x00,
+ 0x4F, 0xF4, 0x90, 0x69, 0x09, 0xD0, 0x73, 0x78, 0xDF, 0xF8, 0x80, 0xA0,
+ 0x02, 0x2B, 0x08, 0xD0, 0x01, 0x22, 0x1F, 0x49, 0x50, 0x46, 0xDD, 0xF7,
+ 0xA2, 0xDD, 0x48, 0x46, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x1C, 0x48,
+ 0xCB, 0xEB, 0xCB, 0x01, 0x40, 0x68, 0x00, 0xEB, 0x81, 0x00, 0xD0, 0xF8,
+ 0x10, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, 0x13, 0xD0, 0xCD, 0xE9, 0x00, 0x48,
+ 0xF0, 0x78, 0x3B, 0x46, 0x59, 0x46, 0x05, 0x9A, 0xE0, 0x47, 0x05, 0x00,
+ 0x0C, 0xD0, 0xA5, 0xF5, 0x50, 0x60, 0x01, 0x38, 0x06, 0xD0, 0x0F, 0x49,
+ 0x2B, 0x46, 0x01, 0x22, 0x2C, 0x31, 0x50, 0x46, 0xDD, 0xF7, 0x7F, 0xDD,
+ 0x28, 0x46, 0xDB, 0xE7, 0x72, 0x8A, 0x21, 0x88, 0x78, 0x1E, 0x10, 0x44,
+ 0x81, 0x42, 0x00, 0xDD, 0x20, 0x80, 0x20, 0x88, 0xC0, 0x1B, 0x06, 0xD4,
+ 0x20, 0x80, 0xD8, 0xF8, 0x00, 0x00, 0xC1, 0x19, 0xC8, 0xF8, 0x00, 0x10,
+ 0xEC, 0xE7, 0x40, 0xF2, 0x07, 0x45, 0xE9, 0xE7, 0x00, 0x33, 0x10, 0x21,
+ 0x44, 0x6C, 0xC0, 0x08, 0xB0, 0x78, 0x20, 0x00, 0x0E, 0xB5, 0x8D, 0xF8,
+ 0x00, 0x00, 0x07, 0x48, 0x8D, 0xF8, 0x02, 0x10, 0x8D, 0xF8, 0x03, 0x20,
+ 0xAD, 0xF8, 0x04, 0x30, 0x82, 0x68, 0x00, 0x2A, 0x02, 0xD0, 0x69, 0x46,
+ 0xFF, 0x20, 0x90, 0x47, 0x0E, 0xBD, 0x00, 0x00, 0xB0, 0x78, 0x20, 0x00,
+ 0x3E, 0xB5, 0x01, 0x25, 0x06, 0x9C, 0x8D, 0xF8, 0x05, 0x00, 0x09, 0x48,
+ 0x8D, 0xF8, 0x00, 0x50, 0xAD, 0xF8, 0x06, 0x20, 0xAD, 0xF8, 0x08, 0x30,
+ 0xAD, 0xF8, 0x02, 0x40, 0x8D, 0xF8, 0x04, 0x10, 0x82, 0x68, 0x00, 0x2A,
+ 0x02, 0xD0, 0x69, 0x46, 0xFF, 0x20, 0x90, 0x47, 0x3E, 0xBD, 0x00, 0x00,
+ 0xB0, 0x78, 0x20, 0x00, 0x7F, 0xB5, 0x1E, 0x4C, 0x01, 0x22, 0x1E, 0x49,
+ 0xA3, 0x78, 0x1E, 0x48, 0xDD, 0xF7, 0x2D, 0xDD, 0xA0, 0x78, 0x1D, 0x4D,
+ 0x81, 0x07, 0x0F, 0xD5, 0x28, 0x79, 0x63, 0x78, 0xAA, 0x78, 0xA9, 0x1D,
+ 0x8D, 0xE8, 0x0F, 0x00, 0xE3, 0x88, 0xA2, 0x88, 0xE9, 0x78, 0x68, 0x78,
+ 0xE9, 0xF7, 0xDC, 0xF9, 0xA0, 0x78, 0x20, 0xF0, 0x02, 0x00, 0x0A, 0xE0,
+ 0x41, 0x07, 0x0A, 0xD5, 0x12, 0x4A, 0x29, 0x78, 0x0C, 0x32, 0x01, 0x20,
+ 0xE9, 0xF7, 0x8A, 0xF9, 0xA0, 0x78, 0x20, 0xF0, 0x04, 0x00, 0xA0, 0x70,
+ 0x7F, 0xBD, 0xC1, 0x07, 0x09, 0xD0, 0x09, 0x4A, 0x21, 0x78, 0x08, 0x32,
+ 0x00, 0x20, 0xE9, 0xF7, 0x7D, 0xF9, 0xA0, 0x78, 0x20, 0xF0, 0x01, 0x00,
+ 0xF1, 0xE7, 0x00, 0x07, 0xF0, 0xD5, 0x01, 0x20, 0xE9, 0xF7, 0xE2, 0xF9,
+ 0xA0, 0x78, 0x20, 0xF0, 0x08, 0x00, 0xE8, 0xE7, 0x88, 0x74, 0x20, 0x00,
+ 0xFC, 0x81, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x38, 0x79, 0x20, 0x00,
+ 0x62, 0x74, 0x65, 0x5F, 0x70, 0x6F, 0x6F, 0x6C, 0x5F, 0x68, 0x65, 0x61,
+ 0x70, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x62, 0x74, 0x65, 0x5F, 0x73,
+ 0x63, 0x68, 0x65, 0x64, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x62, 0x74,
+ 0x65, 0x5F, 0x73, 0x79, 0x73, 0x5F, 0x70, 0x6F, 0x6F, 0x6C, 0x5F, 0x69,
+ 0x6E, 0x69, 0x74, 0x00, 0x62, 0x74, 0x65, 0x5F, 0x6C, 0x65, 0x5F, 0x70,
+ 0x6F, 0x6F, 0x6C, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x62, 0x74, 0x65,
+ 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x5F, 0x63, 0x61, 0x6C, 0x6C, 0x62,
+ 0x61, 0x63, 0x6B, 0x00, 0x68, 0x63, 0x69, 0x5F, 0x6C, 0x65, 0x5F, 0x61,
+ 0x64, 0x76, 0x5F, 0x72, 0x65, 0x70, 0x6F, 0x72, 0x74, 0x5F, 0x65, 0x76,
+ 0x74, 0x00, 0x68, 0x63, 0x69, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65,
+ 0x5F, 0x61, 0x63, 0x6C, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x68, 0x63, 0x69,
+ 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x6C, 0x6F, 0x77, 0x65,
+ 0x72, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x72, 0x73, 0x70, 0x00, 0x68,
+ 0x63, 0x69, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x75, 0x70,
+ 0x70, 0x65, 0x72, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x72, 0x65, 0x71,
+ 0x00, 0x68, 0x63, 0x69, 0x5F, 0x69, 0x66, 0x5F, 0x63, 0x61, 0x6C, 0x6C,
+ 0x62, 0x61, 0x63, 0x6B, 0x00, 0x68, 0x63, 0x69, 0x5F, 0x77, 0x72, 0x69,
+ 0x74, 0x65, 0x00, 0x68, 0x63, 0x69, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F,
+ 0x70, 0x6B, 0x74, 0x00, 0x68, 0x63, 0x69, 0x5F, 0x65, 0x6E, 0x74, 0x72,
+ 0x79, 0x00, 0x68, 0x63, 0x69, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x68,
+ 0x63, 0x69, 0x5F, 0x66, 0x72, 0x65, 0x65, 0x5F, 0x6C, 0x69, 0x6E, 0x6B,
+ 0x00, 0x68, 0x63, 0x69, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x63, 0x6D,
+ 0x64, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x70, 0x64,
+ 0x75, 0x5F, 0x63, 0x61, 0x6C, 0x6C, 0x62, 0x61, 0x63, 0x6B, 0x00, 0x6C,
+ 0x32, 0x63, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x68, 0x63, 0x69, 0x5F,
+ 0x70, 0x6B, 0x74, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x6C, 0x32, 0x63, 0x5F,
+ 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x66, 0x72, 0x61, 0x67, 0x6D, 0x65, 0x6E,
+ 0x74, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x73, 0x65,
+ 0x6E, 0x64, 0x5F, 0x70, 0x64, 0x75, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x6C,
+ 0x32, 0x63, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x73, 0x69, 0x67, 0x6E,
+ 0x61, 0x6C, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x6C, 0x32, 0x63, 0x75, 0x5F,
+ 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x00, 0x6C, 0x32,
+ 0x63, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x73, 0x69, 0x67,
+ 0x6E, 0x61, 0x6C, 0x5F, 0x70, 0x6B, 0x74, 0x00, 0x6C, 0x32, 0x63, 0x5F,
+ 0x72, 0x65, 0x63, 0x6F, 0x6D, 0x62, 0x5F, 0x63, 0x61, 0x6C, 0x6C, 0x62,
+ 0x61, 0x63, 0x6B, 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x68, 0x61, 0x6E, 0x64,
+ 0x6C, 0x65, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x69, 0x6E, 0x64, 0x00,
+ 0x6C, 0x32, 0x63, 0x5F, 0x65, 0x6E, 0x74, 0x72, 0x79, 0x00, 0x6C, 0x32,
+ 0x63, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x66,
+ 0x72, 0x65, 0x65, 0x5F, 0x61, 0x63, 0x6C, 0x5F, 0x6C, 0x69, 0x6E, 0x6B,
+ 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x5F,
+ 0x63, 0x68, 0x61, 0x6E, 0x6E, 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x68, 0x61,
+ 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x6C, 0x65, 0x5F, 0x70, 0x64, 0x75, 0x5F,
+ 0x6D, 0x73, 0x67, 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x6C, 0x65, 0x5F, 0x73,
+ 0x64, 0x75, 0x5F, 0x63, 0x61, 0x6C, 0x6C, 0x62, 0x61, 0x63, 0x6B, 0x00,
+ 0x6C, 0x32, 0x63, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x6C, 0x65, 0x5F,
+ 0x73, 0x65, 0x67, 0x6D, 0x65, 0x6E, 0x74, 0x5F, 0x6D, 0x73, 0x67, 0x00,
+ 0x6C, 0x32, 0x63, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x6C, 0x65, 0x5F,
+ 0x73, 0x64, 0x75, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x6C, 0x32, 0x63, 0x5F,
+ 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x6C, 0x65, 0x5F, 0x73, 0x64,
+ 0x75, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x73, 0x6D, 0x5F, 0x69, 0x6E, 0x69,
+ 0x74, 0x00, 0x73, 0x6D, 0x5F, 0x65, 0x6E, 0x74, 0x72, 0x79, 0x00, 0x73,
+ 0x6D, 0x5F, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x5F, 0x69, 0x6E, 0x64,
+ 0x00, 0x73, 0x6D, 0x5F, 0x6C, 0x65, 0x5F, 0x61, 0x75, 0x74, 0x68, 0x65,
+ 0x6E, 0x5F, 0x72, 0x65, 0x71, 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x65, 0x6E,
+ 0x64, 0x5F, 0x6C, 0x65, 0x5F, 0x73, 0x63, 0x5F, 0x6D, 0x61, 0x6B, 0x65,
+ 0x5F, 0x6B, 0x65, 0x79, 0x5F, 0x72, 0x73, 0x70, 0x00, 0x73, 0x6D, 0x5F,
+ 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x6C, 0x65, 0x5F, 0x73, 0x63, 0x5F, 0x67,
+ 0x65, 0x6E, 0x5F, 0x64, 0x68, 0x6B, 0x65, 0x79, 0x5F, 0x72, 0x73, 0x70,
+ 0x00, 0x00, 0x04, 0x02, 0x00, 0x02, 0x00, 0x04, 0x02, 0x00, 0x02, 0x01,
+ 0x01, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x04, 0x01, 0x01, 0x02,
+ 0x00, 0x06, 0x00, 0x04, 0x02, 0x00, 0x02, 0x00, 0x05, 0x02, 0x00, 0x05,
+ 0x01, 0x01, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x04, 0x01, 0x05,
+ 0x02, 0x00, 0x05, 0x73, 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x70,
+ 0x61, 0x69, 0x72, 0x69, 0x6E, 0x67, 0x5F, 0x65, 0x78, 0x63, 0x68, 0x61,
+ 0x6E, 0x67, 0x65, 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F,
+ 0x31, 0x32, 0x38, 0x62, 0x69, 0x74, 0x5F, 0x76, 0x61, 0x6C, 0x75, 0x65,
+ 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x70, 0x61, 0x69,
+ 0x72, 0x69, 0x6E, 0x67, 0x5F, 0x66, 0x61, 0x69, 0x6C, 0x00, 0x73, 0x6D,
+ 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72,
+ 0x5F, 0x69, 0x64, 0x65, 0x6E, 0x74, 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x65,
+ 0x6E, 0x64, 0x5F, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5F,
+ 0x72, 0x65, 0x71, 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F,
+ 0x69, 0x64, 0x65, 0x6E, 0x74, 0x5F, 0x69, 0x6E, 0x66, 0x6F, 0x00, 0x73,
+ 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x69, 0x64, 0x65, 0x6E, 0x74,
+ 0x5F, 0x61, 0x64, 0x64, 0x72, 0x5F, 0x69, 0x6E, 0x66, 0x6F, 0x00, 0x73,
+ 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x73, 0x69, 0x67, 0x6E, 0x5F,
+ 0x69, 0x6E, 0x66, 0x6F, 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x63, 0x5F, 0x73,
+ 0x65, 0x6E, 0x64, 0x5F, 0x6B, 0x65, 0x79, 0x70, 0x72, 0x65, 0x73, 0x73,
+ 0x5F, 0x6E, 0x6F, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F,
+ 0x6E, 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x63, 0x5F, 0x73, 0x65, 0x6E, 0x64,
+ 0x5F, 0x64, 0x68, 0x6B, 0x65, 0x79, 0x5F, 0x63, 0x68, 0x65, 0x63, 0x6B,
+ 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x63, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F,
+ 0x70, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x5F, 0x6B, 0x65, 0x79, 0x00, 0x73,
+ 0x6D, 0x5F, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5F, 0x71,
+ 0x75, 0x65, 0x75, 0x65, 0x5F, 0x69, 0x6E, 0x00, 0x73, 0x6D, 0x5F, 0x64,
+ 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5F, 0x71, 0x75, 0x65, 0x75,
+ 0x65, 0x5F, 0x6F, 0x75, 0x74, 0x00, 0x73, 0x6D, 0x5F, 0x68, 0x61, 0x6E,
+ 0x64, 0x6C, 0x65, 0x5F, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x00,
+ 0x73, 0x6D, 0x5F, 0x61, 0x6C, 0x6C, 0x6F, 0x63, 0x5F, 0x73, 0x6D, 0x70,
+ 0x5F, 0x64, 0x61, 0x74, 0x61, 0x00, 0x73, 0x6D, 0x5F, 0x72, 0x65, 0x6C,
+ 0x65, 0x61, 0x73, 0x65, 0x5F, 0x73, 0x6D, 0x70, 0x5F, 0x64, 0x61, 0x74,
+ 0x61, 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x68, 0x63,
+ 0x69, 0x5F, 0x6C, 0x65, 0x5F, 0x65, 0x6E, 0x63, 0x72, 0x79, 0x70, 0x74,
+ 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x68, 0x63, 0x69,
+ 0x5F, 0x6C, 0x65, 0x5F, 0x72, 0x61, 0x6E, 0x64, 0x00, 0x73, 0x6D, 0x5F,
+ 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x73, 0x63, 0x5F, 0x6D, 0x61, 0x6B, 0x65,
+ 0x5F, 0x6B, 0x65, 0x79, 0x5F, 0x72, 0x65, 0x71, 0x00, 0x73, 0x6D, 0x5F,
+ 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x73, 0x63, 0x5F, 0x67, 0x65, 0x6E, 0x5F,
+ 0x64, 0x68, 0x6B, 0x65, 0x79, 0x5F, 0x72, 0x65, 0x71, 0x00, 0x73, 0x6D,
+ 0x5F, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5F, 0x63, 0x72, 0x79,
+ 0x70, 0x74, 0x5F, 0x71, 0x75, 0x65, 0x75, 0x65, 0x00, 0x61, 0x74, 0x74,
+ 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x00, 0x61,
+ 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x72, 0x65, 0x71, 0x00,
+ 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x77, 0x72, 0x69,
+ 0x74, 0x65, 0x5F, 0x72, 0x65, 0x71, 0x5F, 0x63, 0x6D, 0x64, 0x00, 0x61,
+ 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x65, 0x78, 0x65, 0x63,
+ 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x72, 0x65, 0x71, 0x00, 0x61,
+ 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x72, 0x65, 0x61, 0x64,
+ 0x5F, 0x62, 0x79, 0x5F, 0x74, 0x79, 0x70, 0x65, 0x5F, 0x72, 0x73, 0x70,
+ 0x00, 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x70, 0x72,
+ 0x65, 0x70, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x72, 0x73, 0x70,
+ 0x00, 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x6E, 0x6F,
+ 0x74, 0x69, 0x66, 0x79, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x67, 0x61, 0x74,
+ 0x74, 0x5F, 0x65, 0x6E, 0x74, 0x72, 0x79, 0x00, 0x67, 0x61, 0x74, 0x74,
+ 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x68,
+ 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x69,
+ 0x6E, 0x64, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64,
+ 0x5F, 0x64, 0x65, 0x76, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x69, 0x6E,
+ 0x64, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F,
+ 0x63, 0x63, 0x63, 0x64, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x67, 0x61, 0x74,
+ 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F,
+ 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x67, 0x61,
+ 0x74, 0x74, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x61, 0x74,
+ 0x74, 0x72, 0x5F, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5F, 0x72, 0x65,
+ 0x71, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C,
+ 0x65, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F,
+ 0x63, 0x66, 0x6D, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x68, 0x61, 0x6E,
+ 0x64, 0x6C, 0x65, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x77, 0x72, 0x69,
+ 0x74, 0x65, 0x5F, 0x63, 0x66, 0x6D, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F,
+ 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x64, 0x69, 0x73, 0x63, 0x6F, 0x76, 0x65,
+ 0x72, 0x79, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F,
+ 0x61, 0x74, 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x63, 0x6D,
+ 0x70, 0x6C, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x68, 0x61, 0x6E, 0x64,
+ 0x6C, 0x65, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x77, 0x72, 0x69, 0x74,
+ 0x65, 0x5F, 0x72, 0x65, 0x71, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x68,
+ 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x6C, 0x65, 0x5F, 0x61, 0x64, 0x76,
+ 0x5F, 0x72, 0x65, 0x71, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x68, 0x61,
+ 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x6C, 0x65, 0x5F, 0x65, 0x78, 0x74, 0x65,
+ 0x6E, 0x64, 0x65, 0x64, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x72, 0x65, 0x71,
+ 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x66, 0x72, 0x65, 0x65, 0x5F, 0x63,
+ 0x68, 0x61, 0x6E, 0x6E, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x66, 0x72,
+ 0x65, 0x65, 0x5F, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5F,
+ 0x6D, 0x73, 0x67, 0x5F, 0x6C, 0x6C, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F,
+ 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x6E, 0x6F, 0x74, 0x69, 0x66,
+ 0x79, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x68,
+ 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x66,
+ 0x69, 0x6E, 0x64, 0x5F, 0x72, 0x65, 0x71, 0x00, 0x67, 0x61, 0x74, 0x74,
+ 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x72, 0x65, 0x61, 0x64,
+ 0x5F, 0x72, 0x65, 0x71, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x72, 0x65,
+ 0x61, 0x64, 0x5F, 0x72, 0x65, 0x73, 0x75, 0x6D, 0x65, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x73,
+ 0x65, 0x6E, 0x64, 0x5F, 0x63, 0x6D, 0x64, 0x00, 0x62, 0x74, 0x69, 0x66,
+ 0x5F, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5F, 0x67, 0x65, 0x74, 0x00,
+ 0x62, 0x74, 0x69, 0x66, 0x5F, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5F,
+ 0x70, 0x75, 0x74, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x76, 0x65, 0x6E,
+ 0x64, 0x6F, 0x72, 0x5F, 0x63, 0x6D, 0x64, 0x5F, 0x72, 0x65, 0x71, 0x00,
+ 0x62, 0x74, 0x69, 0x66, 0x5F, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65,
+ 0x72, 0x76, 0x65, 0x72, 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x63,
+ 0x66, 0x6D, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x67, 0x61, 0x74, 0x74,
+ 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
+ 0x5F, 0x72, 0x65, 0x71, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x67, 0x61,
+ 0x74, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61, 0x64,
+ 0x5F, 0x63, 0x66, 0x6D, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x67, 0x61,
+ 0x74, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x70, 0x72, 0x65, 0x70,
+ 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x63, 0x66, 0x6D, 0x00, 0x62,
+ 0x74, 0x69, 0x66, 0x5F, 0x6C, 0x65, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x64,
+ 0x61, 0x74, 0x61, 0x5F, 0x73, 0x65, 0x74, 0x5F, 0x72, 0x65, 0x71, 0x00,
+ 0x62, 0x74, 0x69, 0x66, 0x5F, 0x6C, 0x65, 0x5F, 0x65, 0x78, 0x74, 0x5F,
+ 0x61, 0x64, 0x76, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x73, 0x65, 0x74,
+ 0x5F, 0x72, 0x65, 0x71, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x65, 0x6E,
+ 0x74, 0x72, 0x79, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x69, 0x6E, 0x69,
+ 0x74, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F,
+ 0x65, 0x76, 0x65, 0x6E, 0x74, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x68,
+ 0x63, 0x69, 0x5F, 0x76, 0x65, 0x6E, 0x64, 0x6F, 0x72, 0x5F, 0x63, 0x6D,
+ 0x64, 0x5F, 0x72, 0x73, 0x70, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x68,
+ 0x63, 0x69, 0x5F, 0x76, 0x65, 0x6E, 0x64, 0x6F, 0x72, 0x5F, 0x65, 0x76,
+ 0x74, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x64,
+ 0x65, 0x66, 0x65, 0x72, 0x5F, 0x75, 0x70, 0x5F, 0x6D, 0x73, 0x67, 0x00,
+ 0x62, 0x74, 0x69, 0x66, 0x5F, 0x70, 0x72, 0x6F, 0x63, 0x65, 0x73, 0x73,
+ 0x5F, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5F, 0x6D, 0x73,
+ 0x67, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x67, 0x61, 0x74, 0x74, 0x5F,
+ 0x61, 0x74, 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x72, 0x73,
+ 0x70, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x6C, 0x65, 0x5F, 0x64, 0x69,
+ 0x72, 0x65, 0x63, 0x74, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x69, 0x6E, 0x66,
+ 0x6F, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x6C, 0x65, 0x5F, 0x65, 0x78,
+ 0x74, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x72, 0x65, 0x70, 0x6F, 0x72, 0x74,
+ 0x5F, 0x69, 0x6E, 0x66, 0x6F, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x6C,
+ 0x65, 0x5F, 0x73, 0x63, 0x61, 0x6E, 0x5F, 0x72, 0x65, 0x71, 0x5F, 0x72,
+ 0x63, 0x76, 0x64, 0x5F, 0x69, 0x6E, 0x66, 0x6F, 0x00, 0x62, 0x74, 0x69,
+ 0x66, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x67, 0x61, 0x74,
+ 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x75, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x5F, 0x72, 0x65, 0x71, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x68,
+ 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x61,
+ 0x74, 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x63, 0x66, 0x6D,
+ 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65,
+ 0x5F, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
+ 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x63, 0x66, 0x6D, 0x00, 0x62,
+ 0x74, 0x69, 0x66, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x63,
+ 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F,
+ 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F,
+ 0x70, 0x72, 0x65, 0x70, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x72,
+ 0x73, 0x70, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x68, 0x61, 0x6E, 0x64,
+ 0x6C, 0x65, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61, 0x64,
+ 0x5F, 0x72, 0x73, 0x70, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x6C, 0x65,
+ 0x5F, 0x65, 0x78, 0x74, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x73, 0x65, 0x74,
+ 0x5F, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5F, 0x72, 0x61, 0x6E, 0x64,
+ 0x5F, 0x61, 0x64, 0x64, 0x72, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x6C,
+ 0x65, 0x5F, 0x65, 0x78, 0x74, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x73, 0x65,
+ 0x74, 0x5F, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5F, 0x6F, 0x77, 0x6E,
+ 0x5F, 0x61, 0x64, 0x64, 0x72, 0x5F, 0x74, 0x79, 0x70, 0x65, 0x00, 0x62,
+ 0x74, 0x69, 0x66, 0x5F, 0x6C, 0x65, 0x5F, 0x72, 0x65, 0x6D, 0x6F, 0x76,
+ 0x65, 0x5F, 0x65, 0x78, 0x74, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x73, 0x65,
+ 0x74, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x6C, 0x65, 0x5F, 0x63, 0x6C,
+ 0x65, 0x61, 0x72, 0x5F, 0x65, 0x78, 0x74, 0x5F, 0x61, 0x64, 0x76, 0x5F,
+ 0x73, 0x65, 0x74, 0x00, 0x67, 0x61, 0x70, 0x5F, 0x62, 0x74, 0x69, 0x66,
+ 0x5F, 0x6D, 0x73, 0x67, 0x5F, 0x63, 0x62, 0x00, 0x67, 0x61, 0x70, 0x5F,
+ 0x73, 0x74, 0x61, 0x72, 0x74, 0x5F, 0x62, 0x74, 0x5F, 0x73, 0x74, 0x61,
+ 0x63, 0x6B, 0x00, 0x67, 0x61, 0x70, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C,
+ 0x65, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x6C, 0x65, 0x5F, 0x62, 0x6F, 0x6E,
+ 0x64, 0x5F, 0x70, 0x61, 0x69, 0x72, 0x00, 0x6C, 0x65, 0x5F, 0x62, 0x6F,
+ 0x6E, 0x64, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x6B, 0x65, 0x79, 0x5F, 0x69,
+ 0x6E, 0x70, 0x75, 0x74, 0x5F, 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x72, 0x6D,
+ 0x00, 0x6C, 0x65, 0x5F, 0x62, 0x6F, 0x6E, 0x64, 0x5F, 0x6F, 0x6F, 0x62,
+ 0x5F, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5F, 0x63, 0x6F, 0x6E, 0x66, 0x69,
+ 0x72, 0x6D, 0x00, 0x6C, 0x65, 0x5F, 0x62, 0x6F, 0x6E, 0x64, 0x5F, 0x67,
+ 0x65, 0x74, 0x5F, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x5F, 0x6B,
+ 0x65, 0x79, 0x00, 0x6C, 0x65, 0x5F, 0x62, 0x6F, 0x6E, 0x64, 0x5F, 0x75,
+ 0x73, 0x65, 0x72, 0x5F, 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x72, 0x6D, 0x00,
+ 0x6C, 0x65, 0x5F, 0x62, 0x6F, 0x6E, 0x64, 0x5F, 0x70, 0x61, 0x73, 0x73,
+ 0x6B, 0x65, 0x79, 0x5F, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x5F,
+ 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x72, 0x6D, 0x00, 0x6C, 0x65, 0x5F, 0x62,
+ 0x6F, 0x6E, 0x64, 0x5F, 0x6B, 0x65, 0x79, 0x70, 0x72, 0x65, 0x73, 0x73,
+ 0x5F, 0x6E, 0x6F, 0x74, 0x69, 0x66, 0x79, 0x00, 0x6C, 0x65, 0x5F, 0x62,
+ 0x6F, 0x6E, 0x64, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x67,
+ 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5F, 0x73,
+ 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x6C, 0x65, 0x5F,
+ 0x73, 0x65, 0x74, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x6C, 0x65, 0x6E,
+ 0x00, 0x6C, 0x65, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x72, 0x73, 0x73,
+ 0x69, 0x00, 0x6C, 0x65, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x63, 0x68,
+ 0x61, 0x6E, 0x6E, 0x5F, 0x6D, 0x61, 0x70, 0x00, 0x6C, 0x65, 0x5F, 0x64,
+ 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, 0x5F, 0x73, 0x6C, 0x61, 0x76, 0x65,
+ 0x5F, 0x6C, 0x61, 0x74, 0x65, 0x6E, 0x63, 0x79, 0x00, 0x6C, 0x65, 0x5F,
+ 0x73, 0x65, 0x74, 0x5F, 0x63, 0x6F, 0x6E, 0x6E, 0x5F, 0x74, 0x78, 0x5F,
+ 0x70, 0x6F, 0x77, 0x65, 0x72, 0x00, 0x6C, 0x65, 0x5F, 0x6C, 0x69, 0x6E,
+ 0x6B, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x6C, 0x65, 0x5F, 0x67, 0x65,
+ 0x74, 0x5F, 0x63, 0x6F, 0x6E, 0x6E, 0x5F, 0x70, 0x61, 0x72, 0x61, 0x6D,
+ 0x00, 0x6C, 0x65, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x72, 0x65, 0x6D,
+ 0x6F, 0x74, 0x65, 0x5F, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x00,
+ 0x6C, 0x65, 0x5F, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5F, 0x63, 0x6F,
+ 0x6E, 0x6E, 0x5F, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x00, 0x6C, 0x65, 0x5F,
+ 0x73, 0x65, 0x74, 0x5F, 0x70, 0x68, 0x79, 0x00, 0x63, 0x6C, 0x69, 0x65,
+ 0x6E, 0x74, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x63, 0x6C, 0x69, 0x65,
+ 0x6E, 0x74, 0x5F, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x5F, 0x70, 0x61, 0x72,
+ 0x61, 0x6D, 0x00, 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x5F, 0x61, 0x74,
+ 0x74, 0x72, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x00, 0x63, 0x6C, 0x69,
+ 0x65, 0x6E, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x69, 0x6E, 0x64,
+ 0x5F, 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x72, 0x6D, 0x00, 0x63, 0x6C, 0x69,
+ 0x65, 0x6E, 0x74, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x67,
+ 0x61, 0x74, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61,
+ 0x64, 0x5F, 0x62, 0x79, 0x5F, 0x75, 0x75, 0x69, 0x64, 0x00, 0x63, 0x6C,
+ 0x69, 0x65, 0x6E, 0x74, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F,
+ 0x67, 0x61, 0x74, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x62, 0x61,
+ 0x73, 0x69, 0x63, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x00, 0x63, 0x6C, 0x69,
+ 0x65, 0x6E, 0x74, 0x5F, 0x67, 0x65, 0x74, 0x5F, 0x6E, 0x6F, 0x74, 0x69,
+ 0x66, 0x79, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x62, 0x75, 0x66, 0x66,
+ 0x65, 0x72, 0x00, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5F, 0x69, 0x6E,
+ 0x69, 0x74, 0x00, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5F, 0x61, 0x74,
+ 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x63, 0x6F, 0x6E, 0x66,
+ 0x69, 0x72, 0x6D, 0x00, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5F, 0x61,
+ 0x74, 0x74, 0x72, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x63, 0x6F,
+ 0x6E, 0x66, 0x69, 0x72, 0x6D, 0x00, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
+ 0x5F, 0x65, 0x78, 0x65, 0x63, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F,
+ 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x72, 0x6D, 0x00, 0x73, 0x65, 0x72, 0x76,
+ 0x65, 0x72, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x64, 0x61, 0x74, 0x61,
+ 0x00, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5F, 0x67, 0x65, 0x74, 0x5F,
+ 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x63, 0x6D, 0x64, 0x5F, 0x64, 0x61,
+ 0x74, 0x61, 0x5F, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x00, 0x73, 0x65,
+ 0x72, 0x76, 0x65, 0x72, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F,
+ 0x67, 0x61, 0x74, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x70, 0x72,
+ 0x65, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x69, 0x6E, 0x64, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x65,
+ 0x5F, 0x6B, 0x65, 0x79, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x00, 0x00,
+ 0x02, 0x08, 0x00, 0x28, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x28, 0x20, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x05, 0x2A,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x12, 0x00, 0x02, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x28, 0x00, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x28,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x84, 0x74, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x0C, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x28, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x83, 0x74, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x2A,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x03, 0x28, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x2A, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+ 0xFC, 0x78, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x28,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xA6, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xF4, 0x78, 0x20, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x28, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, 0x2A,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x2C, 0x79, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x29, 0x7B, 0x81, 0x00, 0x79, 0x7B, 0x81, 0x00, 0x41, 0x7C, 0x81, 0x00,
+ 0xA4, 0x01, 0x67, 0x61, 0x70, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x6D,
+ 0x73, 0x67, 0x5F, 0x74, 0x6F, 0x5F, 0x61, 0x70, 0x70, 0x00, 0x6C, 0x65,
+ 0x5F, 0x63, 0x6F, 0x63, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x6C, 0x65,
+ 0x5F, 0x63, 0x6F, 0x63, 0x5F, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00,
+ 0x6C, 0x65, 0x5F, 0x65, 0x78, 0x74, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x69,
+ 0x6E, 0x69, 0x74, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x25, 0x84, 0x82, 0x00, 0xAD, 0x7A, 0x82, 0x00, 0x61, 0x7E, 0x82, 0x00,
+ 0xF5, 0x78, 0x82, 0x00, 0xB5, 0x79, 0x82, 0x00, 0x7D, 0x79, 0x82, 0x00,
+ 0x09, 0x69, 0x82, 0x00, 0xD9, 0x77, 0x82, 0x00, 0x95, 0x6A, 0x82, 0x00,
+ 0x11, 0x6A, 0x82, 0x00, 0x91, 0x82, 0x82, 0x00, 0xF5, 0x81, 0x82, 0x00,
+ 0x2D, 0x81, 0x82, 0x00, 0x45, 0x67, 0x82, 0x00, 0xF1, 0x6A, 0x82, 0x00,
+ 0x25, 0x84, 0x82, 0x00, 0x1C, 0x00, 0x01, 0x03, 0x01, 0x00, 0x07, 0x00,
+ 0x7F, 0x7F, 0x08, 0x01, 0xFB, 0x00, 0x48, 0x08, 0x07, 0x02, 0x47, 0x41,
+ 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x84, 0x03, 0x03, 0x07, 0x07, 0x00,
+ 0x20, 0x00, 0x00, 0x04, 0x02, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x01, 0x10, 0x00, 0x10, 0x00, 0x02, 0x08, 0x08, 0x00, 0xC8, 0x00,
+ 0xFF, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x40, 0x00, 0x20, 0x00,
+ 0x01, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00,
+};
+const unsigned long upperstack_lib_img_termination = 0x00000000;
+const unsigned long upperstack_lib_img_start = 0x00000000;
+const unsigned long upperstack_lib_img_finish = 0x0001D2A0;
+const unsigned long upperstack_lib_img_length = 0x0001D2A0;
+
+#define UPPERSTACK_LIB_IMG_TERMINATION 0x00000000
+#define UPPERSTACK_LIB_IMG_START 0x00000000
+#define UPPERSTACK_LIB_IMG_FINISH 0x0001D2A0
+#define UPPERSTACK_LIB_IMG_LENGTH 0x0001D2A0
diff --git a/src/ble/upperstack_lib.h b/src/ble/upperstack_lib.h
new file mode 100644
index 0000000..d506b89
--- /dev/null
+++ b/src/ble/upperstack_lib.h
@@ -0,0 +1,10 @@
+#ifndef ______SDK_SRC_BLE_UPPERSTACK_LIB_H
+#define ______SDK_SRC_BLE_UPPERSTACK_LIB_H
+
+extern const unsigned long upperstack_lib_img_termination;
+extern const unsigned long upperstack_lib_img_start;
+extern const unsigned long upperstack_lib_img_finish;
+extern const unsigned long upperstack_lib_img_length;
+extern const unsigned char upperstack_lib_img[];
+
+#endif /* ______SDK_SRC_BLE_UPPERSTACK_LIB_H */
diff --git a/src/dfu/dfu_application.c b/src/dfu/dfu_application.c
new file mode 100644
index 0000000..62ffb50
--- /dev/null
+++ b/src/dfu/dfu_application.c
@@ -0,0 +1,617 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file dfu_application.c
+* @brief dfu task application implementation
+* @details dfu task application implementation
+* @author
+* @date
+* @version
+* *********************************************************************************************************
+*/
+#include <trace.h>
+#include <string.h>
+#include "app_msg.h"
+#include "gap.h"
+#include "gap_adv.h"
+#include "gap_bond_le.h"
+#include "gap_conn_le.h"
+#include "gap_msg.h"
+#include "profile_server.h"
+#include "os_timer.h"
+#include "otp.h"
+#include "dfu_api.h"
+#include "dfu_service.h"
+//#include "ota_service.h"
+#include "dfu_main.h"
+#include "dfu_flash.h"
+#include "dfu_application.h"
+#include "dfu_task.h"
+#include "board.h"
+
+#if (SUPPORT_NORMAL_OTA == 1)
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+
+
+/*============================================================================*
+ * Local Variables
+ *============================================================================*/
+T_GAP_DEV_STATE dfu_gap_cur_state = {0, 0, 0, 0};
+T_GAP_CONN_STATE dfu_gap_conn_state = GAP_CONN_STATE_DISCONNECTED;
+static bool rtk_dfu_active_reset_pending = false;
+static uint8_t rtk_active_reset_mode = 0;
+
+void dfu_peripheral_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/*============================================================================*
+ * External Variables
+ *============================================================================*/
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/*
+ * @fn app_handle_io_msg
+ * @brief All the application events are pre-handled in this function.
+ * All the IO MSGs are sent to this function, Then the event handling function
+ * shall be called according to the MSG type.
+ *
+ * @param io_msg - bee io msg data
+ * @return void
+ */
+void dfu_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ dfu_peripheral_handle_gap_msg(&io_msg);
+ }
+ break;
+ case IO_MSG_TYPE_DFU_VALID_FW:
+ {
+ APP_PRINT_INFO0("IO_MSG_TYPE_DFU_VALID_FW");
+ dfu_service_handle_valid_fw(io_msg.u.param);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/******************************************************************
+ * @fn peripheral_HandleBtDevStateChangeEvt
+ * @brief All the gaprole_States_t events are pre-handled in this function.
+ * Then the event handling function shall be called according to the newState.
+ *
+ * @param newState - new gap state
+ * @return void
+ */
+void dfu_periph_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ DFU_PRINT_INFO4("dfu_periph_handle_dev_state_evt: init state %d, adv state %d, conn state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state,
+ new_state.gap_conn_state, cause);
+ if (dfu_gap_cur_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ dfu_set_rand_addr();
+
+ /*stack ready*/
+ le_adv_start();
+ }
+ }
+
+ if (dfu_gap_cur_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ DFU_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ DFU_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ DFU_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ if (dfu_gap_cur_state.gap_conn_state != new_state.gap_conn_state)
+ {
+ DFU_PRINT_INFO2("conn state: %d -> %d",
+ dfu_gap_cur_state.gap_conn_state,
+ new_state.gap_conn_state);
+ }
+ dfu_gap_cur_state = new_state;
+}
+
+void dfu_periph_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state,
+ uint16_t disc_cause)
+{
+ DFU_PRINT_INFO3("dfu_periph_handle_conn_state_evt: conn_id = %d old_state = %d new_state = %d",
+ conn_id, dfu_gap_conn_state, new_state);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ DFU_PRINT_ERROR1("connection lost: cause 0x%x", disc_cause);
+ }
+
+ if (rtk_dfu_active_reset_pending)
+ {
+ rtk_dfu_active_reset_pending = false;
+
+ /*when multi image in temp, need goto OTA mode*/
+ if (rtk_active_reset_mode)
+ {
+ DBG_DIRECT("comb Mormal OTA, Reset to OTA Mode");
+ rtk_active_reset_mode = false;
+ dfu_switch_to_ota_mode();
+ }
+ else
+ {
+ //unlock_flash_bp_all();
+ dfu_fw_reboot(true);
+ }
+
+ }
+ else
+ {
+ if (OTP->ota_link_loss_reset)
+ {
+ dfu_fw_reboot(false);
+ }
+ else
+ {
+ le_adv_start();
+ }
+ }
+
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, (unsigned char *)&remote_bd_type);
+ DFU_PRINT_INFO5("GAPSTATE_CONN_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+
+ g_dfu_para.dfu_conn_para_update_in_progress = false;
+ g_dfu_para.dfu_conn_interval = conn_interval;
+ g_dfu_para.dfu_conn_lantency = conn_latency;
+
+ os_timer_stop(&wait4_conn_timer_handle); //to check?
+ }
+ break;
+
+ default:
+ break;
+ }
+ dfu_gap_conn_state = new_state;
+}
+
+/******************************************************************
+ * @fn peripheral_HandleBtGapAuthenStateChangeEvt
+ * @brief All the bonding state change events are pre-handled in this function.
+ * Then the event handling function shall be called according to the newState.
+ *
+ * @param newState - new bonding state
+ * @return void
+ */
+void dfu_periph_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ DFU_PRINT_INFO1("dfu_periph_handle_authen_state_evt:conn_id=%d", conn_id);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ DFU_PRINT_INFO0("GAPSEC_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ DFU_PRINT_INFO0("GAPSEC_AUTHEN_STATE_COMPLETE");
+ if (cause == 0)
+ {
+ DFU_PRINT_INFO0("LE_GAP_MSG_TYPE_AUTHEN_STATE_CHANGE pair success");
+ }
+ else
+ {
+ DFU_PRINT_INFO0("LE_GAP_MSG_TYPE_AUTHEN_STATE_CHANGE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ DFU_PRINT_INFO1("LE_GAP_MSG_TYPE_AUTHEN_STATE_CHANGE: unknown newstate=%d!", new_state);
+ }
+ break;
+ }
+}
+
+/******************************************************************
+ * @fn peripheral_HandleBtGapConnParaChangeEvt
+ * @brief All the connection parameter update change events are pre-handled in this function.
+ * Then the event handling function shall be called according to the status.
+ *
+ * @param status - connection parameter result, 0 - success, otherwise fail.
+ * @return void
+ */
+void dfu_periph_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ DFU_PRINT_INFO3("LE_GAP_MSG_TYPE_CONN_PARA_UPDATE_CHANGE success(Normal OTA): interval=0x%x, slave_latency=0x%x, supervision_timeout=0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+
+ g_dfu_para.dfu_conn_interval = conn_interval;
+ g_dfu_para.dfu_conn_lantency = conn_slave_latency;
+ dfu_notify_conn_para_update_req(conn_id, DFU_ARV_SUCCESS);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ DFU_PRINT_ERROR1("LE_GAP_MSG_TYPE_CONN_PARA_UPDATE_CHANGE failed(Normal OTA): cause 0x%x", cause);
+ dfu_notify_conn_para_update_req(conn_id, DFU_ARV_FAIL_OPERATION);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ DFU_PRINT_INFO0("LE_GAP_MSG_TYPE_CONN_PARA_UPDATE_CHANGE Request success but pending(Normal OTA).");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+/**
+ * @brief Handle msg LE_GAP_MSG_TYPE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void dfu_periph_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ DFU_PRINT_INFO2("dfu_periph_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+/******************************************************************
+ * @fn peripheral_HandleBtGapMessage
+ * @brief All the bt gap msg events are pre-handled in this function.
+ * Then the event handling function shall be called according to the subType
+ * of BEE_IO_MSG.
+ *
+ * @param pBeeIoMsg - pointer to bee io msg
+ * @return void
+ */
+void dfu_peripheral_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ DFU_PRINT_TRACE1("dfu_peripheral_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ dfu_periph_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ dfu_periph_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ dfu_periph_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ dfu_periph_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ dfu_periph_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ DFU_PRINT_INFO0("LE_GAP_MSG_TYPE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ DFU_PRINT_INFO1("LE_GAP_MSG_TYPE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ DFU_PRINT_INFO1("LE_GAP_MSG_TYPE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ DFU_PRINT_INFO1("LE_GAP_MSG_TYPE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ DFU_PRINT_INFO0("LE_GAP_MSG_TYPE_BOND_OOB_INPUT");
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ }
+ break;
+
+ default:
+ DFU_PRINT_ERROR1("dfu_peripheral_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @defgroup DFU_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT dfu_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ DFU_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_BOND_MODIFY_INFO:
+ DFU_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x",
+ p_data->p_le_bond_modify_info->type);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ DFU_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+ case GAP_MSG_LE_SET_RAND_ADDR:
+ DFU_PRINT_INFO1("GAP_MSG_LE_SET_RAND_ADDR: cause 0x%x",
+ p_data->p_le_set_rand_addr_rsp->cause);
+ break;
+ default:
+ DFU_PRINT_INFO1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+
+/******************************************************************
+ * @fn app_profile_callback
+ * @brief All the bt profile callbacks are handled in this function.
+ * Then the event handling function shall be called according to the serviceID
+ * of BEE_IO_MSG.
+ *
+ * @param serviceID - service id of profile
+ * @param pData - pointer to callback data
+ * @return void
+ */
+
+T_APP_RESULT dfu_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ DFU_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ DFU_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits = %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ DFU_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ DFU_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == rtk_dfu_service_id)
+ {
+ T_DFU_CALLBACK_DATA *p_dfu_cb_data = (T_DFU_CALLBACK_DATA *)p_data;
+ switch (p_dfu_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ if (p_dfu_cb_data->msg_data.notification_indification_index == DFU_NOTIFY_ENABLE)
+ {
+ DFU_PRINT_INFO0("dfu notification enable");
+ }
+ else if (p_dfu_cb_data->msg_data.notification_indification_index ==
+ DFU_NOTIFY_DISABLE)
+ {
+ DFU_PRINT_INFO0("dfu notification disable");
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ uint8_t dfu_write_opcode = p_dfu_cb_data->msg_data.write.opcode;
+ if (DFU_WRITE_ATTR_EXIT == dfu_write_opcode)
+ {
+ if (p_dfu_cb_data->msg_data.write.write_attrib_index == INDEX_DFU_CONTROL_POINT_CHAR_VALUE)
+ {
+ uint8_t control_point_opcode = *p_dfu_cb_data->msg_data.write.p_value;
+ switch (control_point_opcode)
+ {
+ case DFU_OPCODE_VALID_FW:
+ {
+ T_IO_MSG dfu_valid_fw_msg;
+ dfu_valid_fw_msg.type = IO_MSG_TYPE_DFU_VALID_FW;
+ dfu_valid_fw_msg.u.param = p_dfu_cb_data->conn_id;
+ if (app_send_msg_to_dfutask(&dfu_valid_fw_msg) == false)
+ {
+ DBG_DIRECT("DFU send Valid FW msg fail!");
+ }
+ }
+ break;
+ case DFU_OPCODE_ACTIVE_IMAGE_RESET:
+ {
+ DFU_PRINT_INFO1("DFU_OPCODE_ACTIVE_IMAGE_RESET cmd length=%d",
+ p_dfu_cb_data->msg_data.write.length);
+ if (DFU_LENGTH_ACTIVE_IMAGE_RESET_TO_OTA_MODE == p_dfu_cb_data->msg_data.write.length)
+ {
+ /*Optional, 0:Reset to Normal Mode, 1: Reset to OTA mode*/
+ rtk_active_reset_mode = *(p_dfu_cb_data->msg_data.write.p_value + 1);
+ }
+#if (ENABLE_AUTO_BANK_SWITCH == 1)
+ if (is_ota_support_bank_switch())
+ {
+ uint32_t ota_addr;
+ ota_addr = get_header_addr_by_img_id(OTA);
+ DFU_PRINT_INFO1("DFU_OPCODE_ACTIVE_IMAGE_RESET: Bank switch erase ota_addr=0x%x", ota_addr);
+ unlock_flash_bp_all();
+ flash_erase_locked(FLASH_ERASE_SECTOR, ota_addr);
+ lock_flash_bp();
+ }
+#endif
+ le_disconnect(0);
+ rtk_dfu_active_reset_pending = true;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else if (DFU_WRITE_START == dfu_write_opcode)
+ {
+ T_IMG_CTRL_HEADER_FORMAT *p_header = (T_IMG_CTRL_HEADER_FORMAT *)
+ p_dfu_cb_data->msg_data.write.p_value;
+ if (p_header->image_id >= OTA && p_header->image_id < IMAGE_MAX &&
+ p_header->payload_len < flash_get_bank_size(FLASH_OTA_BANK_0))
+ {
+ uint32_t total_period = timeout_value_total * ((p_header->payload_len + 1024) / 102400 + 1);
+ os_timer_restart(&total_timer_handle,
+ total_period);
+ uint32_t transfer_period = timeout_value_image_transfer * ((p_header->payload_len + 1024) / 102400 +
+ 1);
+ os_timer_restart(&image_transfer_timer_handle, transfer_period);
+ DBG_DIRECT("[Normal OTA] restart timer, total=%dms, transfer=%dms!", total_period, transfer_period);
+ }
+ }
+ else if (DFU_WRITE_FAIL == dfu_write_opcode)
+ {
+ DBG_DIRECT("DFU FAIL! reason=%d", *p_dfu_cb_data->msg_data.write.p_value);
+ }
+ else
+ {
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ }
+
+
+ return app_result;
+}
+
+#endif //end SUPPORT_NORMAL_OTA
diff --git a/src/dfu/dfu_application.h b/src/dfu/dfu_application.h
new file mode 100644
index 0000000..af50dda
--- /dev/null
+++ b/src/dfu/dfu_application.h
@@ -0,0 +1,33 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file simple_ble_peripheral_application.h
+* @brief simple_ble_peripheral_application
+* @details simple_ble_peripheral_application
+* @author jane
+* @date 2015-12-22
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _PERIPHERAL_APPLICATION__
+#define _PERIPHERAL_APPLICATION__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "app_msg.h"
+//#include <gap_le.h>
+#include "profile_server.h"
+
+void dfu_handle_io_msg(T_IO_MSG io_driver_msg_recv);
+T_APP_RESULT dfu_profile_callback(T_SERVER_ID service_id, void *p_data);
+T_APP_RESULT dfu_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/dfu/dfu_main.c b/src/dfu/dfu_main.c
new file mode 100644
index 0000000..8662f3e
--- /dev/null
+++ b/src/dfu/dfu_main.c
@@ -0,0 +1,303 @@
+/*
+ * Routines to access hardware
+ *
+ * Copyright (c) 2014 Realtek Semiconductor Corp.
+ *
+ * This module is a confidential and proprietary property of RealTek and
+ * possession or use of this module requires written permission of RealTek.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include "gap.h"
+#include "gap_adv.h"
+#include "gap_bond_le.h"
+#include "profile_server.h"
+#include "os_timer.h"
+#include "otp_config.h" //todo: when open otp needn't
+#include "otp.h"
+#include "trace.h"
+#include "dfu_api.h"
+#include "dfu_flash.h"
+#include "dfu_service.h"
+#include "dfu_main.h"
+#include "dfu_task.h"
+#include "dfu_application.h"
+#include "board.h"
+
+#if (SUPPORT_NORMAL_OTA == 1)
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define TIMER_ID_DFU_TOTAL 1
+#define TIMER_ID_DFU_WAIT4_CONN 2
+#define TIMER_ID_DFU_IMAGE_TRANSFER 3
+#define TIMER_ID_DFU_CTITTV 4
+
+#define BD_ADDR_SIZE 6
+
+/* What is the advertising interval when device is discoverable (units of 625us, 160=100ms)*/
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 160 /* 100ms */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 176 /* 110ms */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *total_timer_handle;
+void *wait4_conn_timer_handle;
+void *image_transfer_timer_handle;
+void *ctittv_timer_handle;
+uint32_t timeout_value_total;
+uint32_t timeout_value_wait4_conn;
+uint32_t timeout_value_image_transfer;
+uint32_t timeout_value_ctittv;
+T_SERVER_ID rtk_dfu_service_id;
+
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+/*
+ * @fn Initial gap parameters
+ * @brief Initialize peripheral and gap bond manager related parameters
+ *
+ * @return void
+ */
+void dfu_le_gap_init(void)
+{
+
+ uint8_t bt_bd_addr[6];
+ gap_get_param(GAP_PARAM_BD_ADDR, bt_bd_addr); //get OTP->bt_bd_addr
+
+ //device name and device appearance
+ char fmt[] = "%02x%02x%02x%02x%02x%02x";
+ char device_name[GAP_DEVICE_NAME_LEN];
+ sprintf(device_name, fmt,
+ bt_bd_addr[5], bt_bd_addr[4], bt_bd_addr[3],
+ bt_bd_addr[2], bt_bd_addr[1], bt_bd_addr[0]
+ );
+ uint16_t appearance = GAP_GATT_APPEARANCE_KEYBOARD;
+ uint8_t slave_init_mtu_req = true;
+
+ //advertising parameters
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint8_t local_bd_type = GAP_LOCAL_ADDR_LE_RANDOM;
+ //advertising data
+ uint8_t adv_data_uuid128[31] =
+ {
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="flags" */
+ GAP_ADTYPE_FLAGS_GENERAL | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+
+ /* Service */
+ 0x11, /* length */
+ GAP_ADTYPE_128BIT_COMPLETE, /* type="Complete list of 128-bit UUIDs" */
+ GATT_UUID128_DFU_SERVICE,
+
+ 9,
+ 0xFF,
+ 0x5D,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ };
+ adv_data_uuid128[25] = bt_bd_addr[5];
+ adv_data_uuid128[26] = bt_bd_addr[4];
+ adv_data_uuid128[27] = bt_bd_addr[3];
+ adv_data_uuid128[28] = bt_bd_addr[2];
+ adv_data_uuid128[29] = bt_bd_addr[1];
+ adv_data_uuid128[30] = bt_bd_addr[0];
+
+ //scan response data
+ uint8_t scan_rsp_data[] =
+ {
+ /*Complete local name*/
+ 7, /* default target name length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE, /* type="Complete local name" */
+ '\0',
+ '\0',
+ '\0',
+ '\0',
+ '\0',
+ '\0',
+ '\0',
+ '\0',
+ };
+
+ scan_rsp_data[2] = OTP->ota_rst_tgt_name[0];
+ scan_rsp_data[3] = OTP->ota_rst_tgt_name[1];
+ scan_rsp_data[4] = OTP->ota_rst_tgt_name[2];
+ scan_rsp_data[5] = OTP->ota_rst_tgt_name[3];
+ scan_rsp_data[6] = OTP->ota_rst_tgt_name[4];
+ scan_rsp_data[7] = OTP->ota_rst_tgt_name[5];
+ scan_rsp_data[8] = OTP->ota_rst_tgt_name[6];
+ scan_rsp_data[9] = OTP->ota_rst_tgt_name[7];
+ if (scan_rsp_data[9] != '\0')
+ {
+ scan_rsp_data[0] = 0x09; /* target name length */
+ }
+ else
+ {
+ scan_rsp_data[0] = strlen((char *)(scan_rsp_data + 2)) + 1;
+ }
+
+ //GAP Bond Manager parameters
+ uint8_t gap_param_cccd_storage = false;
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG | GAP_AUTHEN_BIT_MITM_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+ uint8_t auth_sec_req_enable = false;
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_NONE;
+
+ //Register gap callback
+ le_register_app_cb(dfu_gap_callback);
+
+ //Set device name and device appearance
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ //Set advertising parameters
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data_uuid128), adv_data_uuid128);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, scan_rsp_data[0] + 1, scan_rsp_data);
+
+ // Setup the GAP Bond Manager
+ le_bond_set_param(GAP_PARAM_BOND_CCCD_STORAGE, sizeof(gap_param_cccd_storage),
+ &gap_param_cccd_storage);
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+}
+
+/******************************************************************
+ * @fn Initial profile
+ * @brief Add simple profile service and register callbacks
+ *
+ * @return void
+ */
+void dfu_le_profile_init(void)
+{
+ server_init(1);
+ rtk_dfu_service_id = dfu_add_service(dfu_profile_callback);
+ server_register_app_cb(dfu_profile_callback);
+}
+
+void dfu_monitor_timeout_handler(void *p_xtimer)
+{
+ uint32_t timer_id = 0;
+
+ os_timer_id_get(&p_xtimer, &timer_id);
+
+ APP_PRINT_ERROR1("dfu_monitor_timeout_handler, TimerID(%u)", timer_id);
+
+ switch (timer_id)
+ {
+ case TIMER_ID_DFU_TOTAL:
+ case TIMER_ID_DFU_WAIT4_CONN:
+ case TIMER_ID_DFU_IMAGE_TRANSFER:
+ case TIMER_ID_DFU_CTITTV:
+ dfu_fw_reboot(false);
+ break;
+ }
+}
+
+void dfu_timer_init(void)
+{
+ timeout_value_total = OTP->ota_timeout_total * 1000;
+ timeout_value_wait4_conn = OTP->ota_timeout_wait4_conn * 1000;
+ timeout_value_image_transfer = OTP->ota_timeout_wait4_image_transfer * 1000;
+ timeout_value_ctittv = OTP->ota_timeout_ctittv * 1000; //will open when rom otp table is fixed
+
+ os_timer_create(&total_timer_handle, "dfuTotalTimer", TIMER_ID_DFU_TOTAL,
+ timeout_value_total, false, dfu_monitor_timeout_handler);
+
+ os_timer_create(&wait4_conn_timer_handle, "dfuWait4ConTimer", TIMER_ID_DFU_WAIT4_CONN,
+ timeout_value_wait4_conn, false, dfu_monitor_timeout_handler);
+
+ os_timer_create(&image_transfer_timer_handle, "dfuImageTransferTimer",
+ TIMER_ID_DFU_IMAGE_TRANSFER, timeout_value_image_transfer,
+ false, dfu_monitor_timeout_handler);
+
+ os_timer_create(&ctittv_timer_handle, "dfuCtittvTimer", TIMER_ID_DFU_CTITTV,
+ timeout_value_ctittv, false, dfu_monitor_timeout_handler);
+
+ os_timer_start(&total_timer_handle);
+
+ os_timer_start(&wait4_conn_timer_handle);
+}
+
+void dfu_init(void)
+{
+ WDG_Disable();
+
+ if (unlock_flash_bp_all())
+ {
+ DFU_PRINT_INFO0("[==>dfu_init: Flash unlock BP all success!");
+ }
+ else
+ {
+ DBG_DIRECT("dfu init unlock BP fail!");
+ }
+}
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+void dfu_set_rand_addr(void)
+{
+ T_GAP_RAND_ADDR_TYPE rand_addr_type = GAP_RAND_ADDR_NON_RESOLVABLE;
+ uint8_t random_bd[BD_ADDR_SIZE] = {0};
+ le_gen_rand_addr(rand_addr_type, random_bd);
+ DFU_PRINT_INFO1("dfu_set_rand_addr: rand_addr %b", TRACE_BDADDR(random_bd));
+ le_set_rand_addr(random_bd);
+}
+
+void dfu_main(void)
+{
+ DBG_DIRECT("Enter DFU mode");
+ le_gap_init(1);
+ gap_lib_init();
+ dfu_le_gap_init();
+ dfu_le_profile_init();
+ dfu_init();
+ dfu_task_init();
+}
+
+#endif //end SUPPORT_NORMAL_OTA
+
+
+
diff --git a/src/dfu/dfu_main.h b/src/dfu/dfu_main.h
new file mode 100644
index 0000000..2acd95c
--- /dev/null
+++ b/src/dfu/dfu_main.h
@@ -0,0 +1,37 @@
+/**
+************************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+************************************************************************************************************
+* @file dfu_main.h
+* @brief Normal ota APIs
+* @details
+* @author
+* @date
+* @version
+*************************************************************************************************************
+*/
+
+#ifndef _DFU_MAIN_H_
+#define _DFU_MAIN_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "profile_server.h"
+
+extern void *total_timer_handle;
+extern void *wait4_conn_timer_handle;
+extern void *image_transfer_timer_handle;
+extern void *ctittv_timer_handle;
+extern uint32_t timeout_value_total;
+extern uint32_t timeout_value_wait4_conn;
+extern uint32_t timeout_value_image_transfer;
+extern uint32_t timeout_value_ctittv;
+extern T_SERVER_ID rtk_dfu_service_id;
+
+void dfu_timer_init(void);
+
+void dfu_set_rand_addr(void);
+
+void dfu_main(void);
+
+#endif
diff --git a/src/dfu/dfu_task.c b/src/dfu/dfu_task.c
new file mode 100644
index 0000000..d98b15b
--- /dev/null
+++ b/src/dfu/dfu_task.c
@@ -0,0 +1,104 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file dfu_task.c
+ * @brief dfu task for normal ota.
+ * @details
+ * @author
+ * @date
+ * @version
+ ******************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2016 Realtek Semiconductor Corporation</center></h2>
+ ******************************************************************************
+ */
+#include "os_msg.h"
+#include "os_task.h"
+#include "gap_msg.h"
+#include "app_msg.h"
+#include "trace.h"
+#include "dfu_application.h"
+#include "dfu_main.h"
+#include "dfu_task.h"
+#include "board.h"
+
+#if (SUPPORT_NORMAL_OTA == 1)
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define DFU_TASK_PRIORITY 1
+#define DFU_TASK_STACK_SIZE 512 * 8 //todo: sync with bee2, may modify
+
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE)
+
+void *dfu_task_handle;
+void *dfu_evt_queue_handle;
+void *dfu_io_queue_handle;
+
+void dfu_main_task(void *p_param);
+
+bool app_send_msg_to_dfutask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(dfu_io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(dfu_evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+void dfu_task_init()
+{
+ os_task_create(&dfu_task_handle, "dfu", dfu_main_task, 0, DFU_TASK_STACK_SIZE,
+ DFU_TASK_PRIORITY);
+}
+
+/**
+* @brief
+*
+*
+* @param pvParameters
+* @return void
+*/
+void dfu_main_task(void *p_param)
+{
+ uint8_t event;
+
+ os_msg_queue_create(&dfu_io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&dfu_evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(dfu_evt_queue_handle, dfu_io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ dfu_timer_init();
+
+ while (true)
+ {
+ if (os_msg_recv(dfu_evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ //DBG_DIRECT("***os_msg_recv***");
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(dfu_io_queue_handle, &io_msg, 0) == true)
+ {
+ dfu_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+#endif //end SUPPORT_NORMAL_OTA
diff --git a/src/dfu/dfu_task.h b/src/dfu/dfu_task.h
new file mode 100644
index 0000000..0d65697
--- /dev/null
+++ b/src/dfu/dfu_task.h
@@ -0,0 +1,21 @@
+
+/*
+ * Routines to access hardware
+ *
+ * Copyright (c) 2013 Realtek Semiconductor Corp.
+ *
+ * This module is a confidential and proprietary property of RealTek and
+ * possession or use of this module requires written permission of RealTek.
+ */
+#ifndef _DFU_TASK_H_
+#define _DFU_TASK_H_
+#include <stdint.h>
+#include <stdbool.h>
+#include "app_msg.h"
+
+
+void dfu_task_init(void);
+bool app_send_msg_to_dfutask(T_IO_MSG *p_msg);
+
+#endif
+
diff --git a/src/mcu/module/data_uart_cmd/data_uart.c b/src/mcu/module/data_uart_cmd/data_uart.c
new file mode 100644
index 0000000..4c7c60b
--- /dev/null
+++ b/src/mcu/module/data_uart_cmd/data_uart.c
@@ -0,0 +1,278 @@
+#include <data_uart.h>
+#include <os_msg.h>
+#include <trace.h>
+#include <app_msg.h>
+#include <board.h>
+#include <rtl876x.h>
+#include <rtl876x_nvic.h>
+#include <rtl876x_uart.h>
+#include <rtl876x_rcc.h>
+#include <rtl876x_pinmux.h>
+
+static void *h_event_q;
+static void *h_io_q;
+
+int data_uart_send_char(int ch)
+{
+ UART_SendData(UART0, (uint8_t *)&ch, 1);
+ /* wait tx fifo empty */
+ while (UART_GetFlagState(UART0, UART_FLAG_THR_TSR_EMPTY) != SET);
+
+ return ch;
+}
+
+int data_uart_vsprintf(char *buf, const char *fmt, const int *dp)
+{
+ char *p, *s;
+
+ s = buf;
+ for (; *fmt != '\0'; ++fmt)
+ {
+ if (*fmt != '%')
+ {
+ buf ? *s++ = *fmt : data_uart_send_char(*fmt);
+ continue;
+ }
+ if (*++fmt == 's')
+ {
+ for (p = (char *)*dp++; *p != '\0'; p++)
+ {
+ buf ? *s++ = *p : data_uart_send_char(*p);
+ }
+ }
+ else /* Length of item is bounded */
+ {
+ char tmp[20], *q = tmp;
+ int shift = 28;
+
+ if ((*fmt >= '0') && (*fmt <= '9'))
+ {
+ int width;
+ unsigned char fch = *fmt;
+ for (width = 0; (fch >= '0') && (fch <= '9'); fch = *++fmt)
+ {
+ width = width * 10 + fch - '0';
+ }
+ shift = (width - 1) * 4;
+ }
+ /*
+ * Before each format q points to tmp buffer
+ * After each format q points past end of item
+ */
+
+ if ((*fmt == 'x') || (*fmt == 'X') || (*fmt == 'p') || (*fmt == 'P'))
+ {
+ /* With x86 gcc, sizeof(long) == sizeof(int) */
+ const long *lp = (const long *)dp;
+ long h = *lp++;
+ int ncase = (*fmt & 0x20);
+ int alt = 0;
+
+ dp = (const int *)lp;
+ if ((*fmt == 'p') || (*fmt == 'P'))
+ {
+ alt = 1;
+ }
+ if (alt)
+ {
+ *q++ = '0';
+ *q++ = 'X' | ncase;
+ }
+ for (; shift >= 0 && shift < 32; shift -= 4)
+ {
+ * q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase;
+ }
+ }
+ else if (*fmt == 'd')
+ {
+ int i = *dp++;
+ char *r;
+ if (i < 0)
+ {
+ *q++ = '-';
+ i = -i;
+ }
+ p = q; /* save beginning of digits */
+ do
+ {
+ *q++ = '0' + (i % 10);
+ i /= 10;
+ }
+ while (i);
+ /* reverse digits, stop in middle */
+ r = q; /* don't alter q */
+ while (--r > p)
+ {
+ i = *r;
+ *r = *p;
+ *p++ = i;
+ }
+ }
+ else if (*fmt == 'c')
+ {
+ *q++ = *dp++;
+ }
+ else
+ {
+ *q++ = *fmt;
+ }
+ /* now output the saved string */
+ for (p = tmp; p < q; ++p)
+ {
+ buf ? *s++ = *p : data_uart_send_char(*p);
+ }
+ }
+ }
+ if (buf)
+ {
+ *s = '\0';
+ }
+ return (s - buf);
+}
+
+/**
+ * @brief Print the trace information through data uart.
+ * @param[in] fmt Print parameters.
+ * @return void
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ data_uart_print("GAP scan stop\r\n");
+ }
+ * \endcode
+ */
+void data_uart_print(char *fmt, ...)
+{
+ (void)data_uart_vsprintf(0, fmt, ((const int *)&fmt) + 1);
+}
+
+/****************************************************************************/
+/* UART interrupt */
+/****************************************************************************/
+void UART0_Handler(void)
+{
+ uint8_t rx_char;
+ T_IO_MSG io_driver_msg_send;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_driver_msg_send.type = IO_MSG_TYPE_UART;
+
+ uint32_t interrupt_id = 0;
+ /* read interrupt id */
+ interrupt_id = UART_GetIID(UART0);
+
+ /* disable interrupt */
+ UART_INTConfig(UART0, UART_INT_RD_AVA | UART_INT_LINE_STS, DISABLE);
+
+ switch (interrupt_id)
+ {
+ /* tx fifo empty, not enable */
+ case UART_INT_ID_TX_EMPTY:
+ break;
+
+ /* rx data valiable */
+ case UART_INT_ID_RX_LEVEL_REACH:
+ UART_ReceiveData(UART0, &rx_char, 1);
+ io_driver_msg_send.subtype = rx_char;
+
+ if (os_msg_send(h_io_q, &io_driver_msg_send, 0) == false)
+ {
+ }
+ else if (os_msg_send(h_event_q, &event, 0) == false)
+ {
+ }
+ break;
+
+ case UART_INT_ID_RX_TMEOUT:
+ break;
+
+ /* receive line status interrupt */
+ case UART_INT_ID_LINE_STATUS:
+ {
+ DBG_DIRECT("Line status error!!!!\n");
+ }
+ break;
+
+ case UART_INT_ID_MODEM_STATUS:
+ break;
+
+ default:
+ break;
+ }
+
+ /* enable interrupt again */
+ UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+
+ return;
+}
+
+/**
+ * @brief Initializes the Data UART.
+ *
+ * When data uart receives data, data uart will send an event IO_MSG_TYPE_UART to evt_queue_handle and send the data to io_queue_handle.
+ * @param[in] event_queue_handle Event queue handle which is created by APP.
+ * @param[in] io_queue_handle IO message queue handle which is created by APP.
+ * @return void
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_main_task(void *p_param)
+ {
+ char event;
+
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(unsigned char));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ data_uart_init(evt_queue_handle, io_queue_handle);
+ ......
+ }
+ void app_handle_io_msg(T_IO_MSG io_msg)
+ {
+ uint16_t msg_type = io_msg.type;
+ uint8_t rx_char;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_UART:
+ // We handle user command informations from Data UART in this branch.
+ rx_char = (uint8_t)io_msg.subtype;
+ user_cmd_collect(&user_cmd_if, &rx_char, sizeof(rx_char), user_cmd_table);
+ break;
+ default:
+ break;
+ }
+ }
+ * \endcode
+ */
+void data_uart_init(void *event_queue_handle, void *io_queue_handle)
+{
+
+ h_event_q = event_queue_handle;
+ h_io_q = io_queue_handle;
+
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+ Pinmux_Config(DATA_UART_TX_PIN, UART0_TX);
+ Pinmux_Config(DATA_UART_RX_PIN, UART0_RX);
+ Pad_Config(DATA_UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(DATA_UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+
+ /* uart init */
+ UART_InitTypeDef uartInitStruct;
+ UART_StructInit(&uartInitStruct);
+ uartInitStruct.rxTriggerLevel = 1;
+ UART_Init(UART0, &uartInitStruct);
+ UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+
+ /* Enable UART IRQ */
+ NVIC_InitTypeDef nvic_init_struct;
+ nvic_init_struct.NVIC_IRQChannel = UART0_IRQn;
+ nvic_init_struct.NVIC_IRQChannelCmd = ENABLE;
+ nvic_init_struct.NVIC_IRQChannelPriority = 5;
+ NVIC_Init(&nvic_init_struct);
+}
+
diff --git a/src/mcu/module/data_uart_cmd/data_uart.h b/src/mcu/module/data_uart_cmd/data_uart.h
new file mode 100644
index 0000000..3d5a7c7
--- /dev/null
+++ b/src/mcu/module/data_uart_cmd/data_uart.h
@@ -0,0 +1,100 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file data_uart.h
+* @brief Data uart operations for testing multilink.
+* @details Data uart init and print data through data uart.
+* @author jane
+* @date 2016-02-18
+* @version v0.1
+*********************************************************************************************************
+*/
+#ifndef _DATA_UART_H_
+#define _DATA_UART_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** @defgroup DATA_UART_CMD Data Uart Command Module
+ * @brief Application uses this module to receive user command and send information through data uart.
+ * @{
+ */
+/** @defgroup DATA_UART_APIs Data Uart Interface
+ * @{
+ */
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup DATA_UART_APIs_Exported_Functions Data Uart Interface Exported Functions
+ * @{
+ */
+/**
+ * @brief Initializes the Data UART.
+ *
+ * When data uart receives data, data uart will send an event IO_MSG_TYPE_UART to evt_queue_handle and send the data to io_queue_handle.
+ * @param[in] event_queue_handle Event queue handle which is created by APP.
+ * @param[in] io_queue_handle IO message queue handle which is created by APP.
+ * @return void
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_main_task(void *p_param)
+ {
+ char event;
+
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(unsigned char));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ data_uart_init(evt_queue_handle, io_queue_handle);
+ ......
+ }
+ void app_handle_io_msg(T_IO_MSG io_msg)
+ {
+ uint16_t msg_type = io_msg.type;
+ uint8_t rx_char;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_UART:
+ // We handle user command informations from Data UART in this branch.
+ rx_char = (uint8_t)io_msg.subtype;
+ user_cmd_collect(&user_cmd_if, &rx_char, sizeof(rx_char), user_cmd_table);
+ break;
+ default:
+ break;
+ }
+ }
+ * \endcode
+ */
+void data_uart_init(void *event_queue_handle, void *io_queue_handle);
+
+/**
+ * @brief Print the trace information through data uart.
+ * @param[in] fmt Print parameters.
+ * @return void
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void test(void)
+ {
+ data_uart_print("GAP scan stop\r\n");
+ }
+ * \endcode
+ */
+void data_uart_print(char *fmt, ...);
+/** End of DATA_UART_APIs_Exported_Functions
+ * @}
+ */
+
+/** @} */ /* End of group DATA_UART_APIs */
+/** @} */ /* End of group DATA_UART_CMD */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/src/mcu/module/data_uart_cmd/data_uart_dlps.c b/src/mcu/module/data_uart_cmd/data_uart_dlps.c
new file mode 100644
index 0000000..7381fac
--- /dev/null
+++ b/src/mcu/module/data_uart_cmd/data_uart_dlps.c
@@ -0,0 +1,61 @@
+#include <trace.h>
+#include <board.h>
+#include <rtl876x_pinmux.h>
+#include "rtl876x_io_dlps.h"
+#include <dlps.h>
+
+#if F_BT_DLPS_EN
+bool can_enter_dlps = true;
+
+void data_uart_dlps_exit_cb(void)
+{
+ Pad_ControlSelectValue(DATA_UART_TX_PIN, PAD_PINMUX_MODE);
+ Pad_ControlSelectValue(DATA_UART_RX_PIN, PAD_PINMUX_MODE);
+
+}
+
+void data_uart_dlps_enter_cb(void)
+{
+ Pad_ControlSelectValue(DATA_UART_TX_PIN, PAD_SW_MODE);
+ Pad_ControlSelectValue(DATA_UART_RX_PIN, PAD_SW_MODE);
+ System_WakeUpPinEnable(DATA_UART_RX_PIN, PAD_WAKEUP_POL_LOW, 0);
+}
+
+bool data_uart_dlps_check_cb(void)
+{
+ if (can_enter_dlps)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void System_Handler(void)
+{
+ if (System_WakeUpInterruptValue(DATA_UART_RX_PIN) == SET)
+ {
+ can_enter_dlps = false;
+ }
+ Pad_ClearAllWakeupINT();
+}
+
+void data_uart_can_enter_dlps(bool enter)
+{
+ can_enter_dlps = enter;
+}
+
+void data_uart_dlps_init(void)
+{
+ DLPS_IORegister();
+ if (dlps_check_cb_reg(data_uart_dlps_check_cb) == false)
+ {
+ APP_PRINT_ERROR0("data_uart_dlps_init: dlps_check_cb_reg register failed");
+ }
+ DLPS_IORegUserDlpsEnterCb(data_uart_dlps_enter_cb);
+ DLPS_IORegUserDlpsExitCb(data_uart_dlps_exit_cb);
+}
+#endif
+
diff --git a/src/mcu/module/data_uart_cmd/data_uart_dlps.h b/src/mcu/module/data_uart_cmd/data_uart_dlps.h
new file mode 100644
index 0000000..fc6a810
--- /dev/null
+++ b/src/mcu/module/data_uart_cmd/data_uart_dlps.h
@@ -0,0 +1,91 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file data_uart_dlps.h
+* @brief Data uart dlps reference api.
+* @details
+* @author jane
+* @date 2016-02-18
+* @version v0.1
+*********************************************************************************************************
+*/
+#ifndef _DATA_UART_DLPS_H_
+#define _DATA_UART_DLPS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+/** @defgroup DATA_UART_CMD
+ * @{
+ */
+/** @defgroup DATA_UART_DLPS Data Uart DLPS
+ * @{
+ */
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup DATA_UART_DLPS_Exported_Functions Data Uart DLPS Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes the Data uart dlps.
+ * @return void
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void pwr_mgr_init(void)
+ {
+#if F_BT_DLPS_EN
+ data_uart_dlps_init();
+ lps_mode_set(LPM_DLPS_MODE);
+ lps_mode_pause();
+#endif
+ }
+ * \endcode
+ */
+void data_uart_dlps_init(void);
+
+/**
+ * @brief Set data uart dlps
+ *
+ * @param[in] enter Whether allow data uart to enter dlps.
+ * @arg true Allow data uart to enter dlps
+ * @arg false Not allow data uart to enter dlps
+ * @return void
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ static T_USER_CMD_PARSE_RESULT cmd_dlps(T_USER_CMD_PARSED_VALUE *p_parse_value)
+ {
+#if F_BT_DLPS_EN
+ if (p_parse_value->dw_param[0] == 0)
+ {
+ lps_mode_pause();
+ data_uart_print("Active Mode\r\n");
+ }
+ else
+ {
+ lps_mode_resume();
+ data_uart_can_enter_dlps(true);
+ data_uart_print("LPS Mode\r\n");
+ }
+#endif
+ return (RESULT_SUCCESS);
+ }
+ * \endcode
+ */
+void data_uart_can_enter_dlps(bool enter);
+/** End of DATA_UART_DLPS_Exported_Functions
+ * @}
+ */
+
+/** @} */ /* End of group DATA_UART_DLPS */
+/** @} */ /* End of group DATA_UART_CMD */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/src/mcu/module/data_uart_cmd/user_cmd_parse.c b/src/mcu/module/data_uart_cmd/user_cmd_parse.c
new file mode 100644
index 0000000..9315fc4
--- /dev/null
+++ b/src/mcu/module/data_uart_cmd/user_cmd_parse.c
@@ -0,0 +1,642 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file user_cmd_parse.c
+* @brief Parse user command from lower Data UART data.
+* @details Parse user commands and execute right commands.
+* @author
+* @date 2016-02-18
+* @version v0.1
+*********************************************************************************************************
+*/
+#include <string.h>
+#include <data_uart.h>
+#include <user_cmd_parse.h>
+#if F_BT_DLPS_EN
+#include <data_uart_dlps.h>
+#endif
+
+/**
+ * @brief Check if a character is a white space.
+ *
+ * @param c Char data to check.
+ * @return Check result.
+ * @retval 1 true.
+ * @retval 0 false.
+ */
+static bool user_cmd_is_white_space(char c)
+{
+ return (((c >= 9) && (c <= 13)) || (c == 32));
+}
+
+/**
+ * @brief Skip white spaces in buffer.
+ *
+ * @param buffer Address of the buffer.
+ * @return pointer to skipped white spaces' new buffer.
+ */
+static char *user_cmd_skip_spaces(char *buffer)
+{
+ char *p = buffer;
+
+ while (user_cmd_is_white_space(*p)) /* white space */
+ {
+ p++;
+ }
+ return p;
+}
+
+/**
+ * @brief Find end of a word.
+ *
+ * @param buffer Address of the buffer.
+ * @return
+ */
+static char *user_cmd_find_end_of_word(char *buffer)
+{
+ char *p = buffer;
+
+ while (!user_cmd_is_white_space(*p) && (*p != '\0'))
+ {
+ p++;
+ }
+ return p;
+}
+
+/**
+ * @brief Read ASCII string and convert to uint32_t.
+ *
+ * @param p String address.
+ * @return
+ */
+static uint32_t user_cmd_str_to_uint32(char *p)
+{
+ uint32_t result = 0;
+ bool hex = false;
+
+ /* check if value is dec */
+ if (p[0] == 'x')
+ {
+ hex = true;
+ p = &p[1];
+ }
+ else if ((p[0] == '0') && (p[1] == 'x'))
+ {
+ hex = true;
+ p = &p[2];
+ }
+
+ for (;;)
+ {
+ char ch;
+ ch = *(p++) | 0x20; /* convert to lower case */
+
+ if (hex) /* dec value */
+ {
+ /* hex value */
+ if ((ch >= 'a') && (ch <= 'f'))
+ {
+ ch -= ('a' - 10);
+ }
+ else if ((ch >= '0') && (ch <= '9'))
+ {
+ ch -= '0';
+ }
+ else
+ {
+ break;
+ }
+ result = (result << 4);
+ result += (ch & 0x0f);
+ }
+ else
+ {
+ if (ch < '0' || ch > '9')
+ {
+ break; /* end of string reached */
+ }
+ result = 10 * result + ch - '0';
+ }
+ }
+ return (result);
+}
+
+/**
+ * @brief Send result, display in UART Assistant.
+ *
+ * @param result Command parse result.
+ * @return none
+*/
+static void cmd_send_result(T_USER_CMD_PARSE_RESULT result)
+{
+ switch (result)
+ {
+ case RESULT_ERR:
+ data_uart_print("%s\r\n", "CMD:Error");
+ break;
+ case RESULT_GAP_CAUSE_ALREADY_IN_REQ:
+ data_uart_print("%s\r\n", "GAP_CAUSE_ALREADY_IN_REQ");
+ break;
+ case RESULT_GAP_CAUSE_INVALID_STATE:
+ data_uart_print("%s\r\n", "GAP_CAUSE_INVALID_STATE");
+ break;
+ case RESULT_GAP_CAUSE_INVALID_PARAM:
+ data_uart_print("%s\r\n", "GAP_CAUSE_INVALID_PARAM");
+ break;
+ case RESULT_GAP_CAUSE_NON_CONN:
+ data_uart_print("%s\r\n", "GAP_CAUSE_NON_CONN");
+ break;
+ case RESULT_GAP_CAUSE_NOT_FIND_IRK:
+ data_uart_print("%s\r\n", "GAP_CAUSE_NOT_FIND_IRK");
+ break;
+ case RESULT_GAP_CAUSE_ERROR_CREDITS:
+ data_uart_print("%s\r\n", "GAP_CAUSE_ERROR_CREDITS");
+ break;
+ case RESULT_GAP_CAUSE_SEND_REQ_FAILED:
+ data_uart_print("%s\r\n", "GAP_CAUSE_SEND_REQ_FAILED");
+ break;
+ case RESULT_GAP_CAUSE_NO_RESOURCE:
+ data_uart_print("%s\r\n", "GAP_CAUSE_NO_RESOURCE");
+ break;
+ case RESULT_GAP_CAUSE_INVALID_PDU_SIZE:
+ data_uart_print("%s\r\n", "GAP_CAUSE_INVALID_PDU_SIZE");
+ break;
+ case RESULT_GAP_CAUSE_NOT_FIND:
+ data_uart_print("%s\r\n", "GAP_CAUSE_NOT_FIND");
+ break;
+ case RESULT_GAP_CAUSE_CONN_LIMIT:
+ data_uart_print("%s\r\n", "GAP_CAUSE_CONN_LIMIT");
+ break;
+ case RESULT_CMD_NOT_FOUND:
+ data_uart_print("%s\r\n", "CMD:Command not found");
+ break;
+ case RESULT_CMD_ERR_PARAM_NUM:
+ data_uart_print("%s\r\n", "CMD:Wrong number of parameters");
+ break;
+ case RESULT_CMD_ERR_PARAM:
+ data_uart_print("%s\r\n", "CMD:Wrong parameter");
+ break;
+ case RESULT_CMD_OUT_OF_RANGE:
+ data_uart_print("%s\r\n", "CMD:Value out of range");
+ break;
+ case RESULT_CMD_NOT_SUPPORT:
+ data_uart_print("%s\r\n", "CMD:Not support");
+ break;
+ case RESULT_GAP_CAUSE_ERROR_UNKNOWN:
+ data_uart_print("%s\r\n", "GAP_CAUSE_ERROR_UNKNOWN");
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief List cmd.
+ *
+ * @param p_cmd_table Command table, include user self-definition command function.
+ * @return Command execute result.
+*/
+static T_USER_CMD_PARSE_RESULT user_cmd_list(const T_USER_CMD_TABLE_ENTRY *p_cmd_table)
+{
+ int32_t i = 0;
+ T_USER_CMD_PARSE_RESULT result = RESULT_CMD_NOT_FOUND;
+
+ /* find command in table */
+ while ((p_cmd_table + i)->p_cmd != NULL)
+ {
+ data_uart_print("%s", (p_cmd_table + i)->p_option);
+ data_uart_print("%s", " *");
+ data_uart_print("%s", (p_cmd_table + i)->p_help);
+ result = RESULT_SUCCESS;
+ i++;
+ };
+
+ data_uart_print(",.\r\n *up down\r\n");
+ data_uart_print("[]\r\n *left right\r\n");
+ data_uart_print("/\\\r\n *home end\r\n");
+ data_uart_print("backspace\r\n *delete\r\n");
+
+ return result;
+}
+
+/**
+ * @brief Execute command.
+ *
+ * @param p_parse_value Command parse value.
+ * @param p_cmd_table Command table, include user self-definition command function.
+ * @return Command execute result.
+*/
+static T_USER_CMD_PARSE_RESULT user_cmd_execute(T_USER_CMD_PARSED_VALUE *p_parse_value,
+ const T_USER_CMD_TABLE_ENTRY *p_cmd_table)
+{
+ int32_t i = 0;
+ T_USER_CMD_PARSE_RESULT result = RESULT_CMD_NOT_FOUND;
+
+ if (strcmp((const char *)p_parse_value->p_cmd, (const char *)"?") == 0)
+ {
+ user_cmd_list(p_cmd_table);
+ return RESULT_SUCCESS;
+ }
+
+ /* find command in table */
+ while ((p_cmd_table + i)->p_cmd != NULL)
+ {
+ if (strcmp((const char *)(p_cmd_table + i)->p_cmd, (const char *)p_parse_value->p_cmd) == 0)
+ {
+ /* check if user wants help */
+ if (p_parse_value->param_count && *p_parse_value->p_param[0] == '?')
+ {
+ data_uart_print("%s", (p_cmd_table + i)->p_option);
+ data_uart_print("%s", " *");
+ data_uart_print("%s", (p_cmd_table + i)->p_help);
+ result = RESULT_SUCCESS;
+ }
+ else
+ {
+ /* execute command function */
+ result = (p_cmd_table + i)->func(p_parse_value);
+ }
+ /* exit while */
+ break;
+ }
+ i++;
+ };
+
+ return result;
+}
+
+/**
+ * @brief Parse a command line and return the found command and parameters in "p_parse_value"
+ *
+ * @param p_user_cmd_if Command parsed.
+ * @param p_parse_value Command parse value.
+ * @return Command parse result.
+*/
+static T_USER_CMD_PARSE_RESULT user_cmd_parse(T_USER_CMD_IF *p_user_cmd_if,
+ T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ int32_t i;
+ char *p, *q;
+
+ /* clear all results */
+ p_parse_value->p_cmd = NULL;
+ p_parse_value->param_count = 0;
+ for (i = 0 ; i < USER_CMD_MAX_PARAMETERS; i++)
+ {
+ p_parse_value->p_param[i] = NULL;
+ p_parse_value->dw_param[i] = 0;
+ }
+
+ /* Parse line */
+ p = p_user_cmd_if->cmdline_buf;
+
+ /*ignore leading spaces */
+ p = user_cmd_skip_spaces(p);
+ if (*p == '\0') /* empty command line ? */
+ {
+ return RESULT_CMD_EMPTY_LINE;
+ }
+
+ /* find end of word */
+ q = user_cmd_find_end_of_word(p);
+ if (p == q) /* empty command line ? */
+ {
+ return RESULT_CMD_EMPTY_LINE;
+ }
+
+ p_parse_value->p_cmd = p;
+ *q = '\0'; /* mark end of command */
+ p = q + 1;
+
+ /* parse parameters */
+ if (*p != '\0') /* end of line ? */
+ {
+ int32_t j;
+
+ j = 0;
+ do
+ {
+ uint32_t d;
+ /* ignore leading spaces */
+ p = user_cmd_skip_spaces(p);
+ d = user_cmd_str_to_uint32(p);
+
+ p_parse_value->p_param[j] = p;
+ p_parse_value->dw_param[j++] = d;
+
+ if (j >= USER_CMD_MAX_PARAMETERS)
+ {
+ break;
+ }
+
+ /* find next parameter */
+ p = user_cmd_find_end_of_word(p);
+ *p++ = '\0'; /* mark end of parameter */
+ }
+ while (*p != '\0');
+
+ p_parse_value->param_count = j;
+ }
+
+ return RESULT_SUCCESS;
+}
+
+/**
+ * @brief Clear command line buffer.
+ *
+ * @param p_user_cmd_if Command parsed.
+ * @return none.
+*/
+static void cmd_clear(T_USER_CMD_IF *p_user_cmd_if)
+{
+ p_user_cmd_if->accum_cmd_len = 0;
+ p_user_cmd_if->cmd_cur = 0;
+ memset(p_user_cmd_if->cmdline_buf, 0, sizeof(p_user_cmd_if->cmdline_buf));
+}
+
+static void cmd_move_back(T_USER_CMD_IF *p_user_cmd_if)
+{
+ for (uint8_t loop = 0; loop < p_user_cmd_if->accum_cmd_len - p_user_cmd_if->cmd_cur; loop ++)
+ {
+ p_user_cmd_if->cmdline_buf[p_user_cmd_if->accum_cmd_len - loop] =
+ p_user_cmd_if->cmdline_buf[p_user_cmd_if->accum_cmd_len - loop - 1];
+ }
+}
+
+static void cmd_move_forward(T_USER_CMD_IF *p_user_cmd_if)
+{
+ for (uint8_t loop = 0; loop < p_user_cmd_if->accum_cmd_len - p_user_cmd_if->cmd_cur; loop ++)
+ {
+ p_user_cmd_if->cmdline_buf[p_user_cmd_if->cmd_cur + loop - 1] =
+ p_user_cmd_if->cmdline_buf[p_user_cmd_if->cmd_cur + loop];
+ }
+}
+static void cmd_clear_screen(T_USER_CMD_IF *p_user_cmd_if)
+{
+ if (p_user_cmd_if->cmd_cur < p_user_cmd_if->accum_cmd_len)
+ {
+ data_uart_print("%s", p_user_cmd_if->cmdline_buf + p_user_cmd_if->cmd_cur);
+ }
+
+ while (p_user_cmd_if->accum_cmd_len != 0)
+ {
+ p_user_cmd_if->accum_cmd_len--;
+ p_user_cmd_if->cmdline_buf[p_user_cmd_if->accum_cmd_len] = '\0';
+ data_uart_print("\b \b");
+ }
+ p_user_cmd_if->cmd_cur = 0;
+}
+
+/**
+ * @brief Collect command characters.
+ *
+ * @param[in] p_user_cmd_if Store parsed commands.
+ * @param[in] p_data Data to be parsed.
+ * @param[in] len Length of data to be command parsed.
+ * @param[in] p_cmd_table Command table to execute function.
+ * @return Command collect result.
+ * @retval 1 true.
+ * @retval 0 false.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_handle_io_msg(T_IO_MSG io_msg)
+ {
+ uint16_t msg_type = io_msg.type;
+ uint8_t rx_char;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_UART:
+ // We handle user command informations from Data UART in this branch.
+ rx_char = (uint8_t)io_msg.subtype;
+ user_cmd_collect(&user_cmd_if, &rx_char, sizeof(rx_char), user_cmd_table);
+ break;
+ default:
+ break;
+ }
+ }
+ * \endcode
+ */
+bool user_cmd_collect(T_USER_CMD_IF *p_user_cmd_if, uint8_t *p_data, int32_t len,
+ const T_USER_CMD_TABLE_ENTRY *p_cmd_table)
+{
+ T_USER_CMD_PARSED_VALUE parse_result;
+
+ while (len--)
+ {
+ char c = *p_data++;
+
+ if (c != 0x0) /* not ESC character received */
+ {
+ switch (c) /* Normal handling */
+ {
+ case '\n':
+ case '\r': /* end of line */
+ data_uart_print("\r\n");
+ p_user_cmd_if->history_cur = USER_CMD_MAX_HISTORY_LINE;
+#if F_BT_DLPS_EN
+ data_uart_can_enter_dlps(true);
+#endif
+ if (p_user_cmd_if->accum_cmd_len > 0) /* at least one character in command line ? */
+ {
+ T_USER_CMD_PARSE_RESULT result;
+
+ // save cmd first
+ if (p_user_cmd_if->history_head == USER_CMD_MAX_HISTORY_LINE)
+ {
+ p_user_cmd_if->history_head = 0;
+ p_user_cmd_if->history_tail = 0;
+ }
+ else
+ {
+ p_user_cmd_if->history_tail = (p_user_cmd_if->history_tail + 1) % USER_CMD_MAX_HISTORY_LINE;
+ if (p_user_cmd_if->history_tail == p_user_cmd_if->history_head)
+ {
+ p_user_cmd_if->history_head = (p_user_cmd_if->history_head + 1) % USER_CMD_MAX_HISTORY_LINE;
+ }
+ }
+ p_user_cmd_if->cmd_history_len[p_user_cmd_if->history_tail] = p_user_cmd_if->accum_cmd_len;
+ memcpy(p_user_cmd_if->cmd_history[p_user_cmd_if->history_tail], p_user_cmd_if->cmdline_buf,
+ p_user_cmd_if->accum_cmd_len);
+
+ p_user_cmd_if->cmdline_buf[p_user_cmd_if->accum_cmd_len] = '\0';
+ result = user_cmd_parse(p_user_cmd_if, &parse_result);
+ if (result == RESULT_SUCCESS)
+ {
+ result = user_cmd_execute(&parse_result, p_cmd_table);
+ }
+
+ if (result != RESULT_SUCCESS)
+ {
+ cmd_send_result(result);
+ }
+ }
+
+ cmd_clear(p_user_cmd_if);
+ break;
+
+ case '\b': /* backspace */
+ if (p_user_cmd_if->accum_cmd_len > 0 && p_user_cmd_if->cmd_cur > 0)
+ {
+ uint8_t loop;
+
+ cmd_move_forward(p_user_cmd_if);
+ p_user_cmd_if->accum_cmd_len--;
+ p_user_cmd_if->cmd_cur--;
+ p_user_cmd_if->cmdline_buf[p_user_cmd_if->accum_cmd_len] = '\0';
+ data_uart_print("\b%s", p_user_cmd_if->cmdline_buf + p_user_cmd_if->cmd_cur);
+ data_uart_print(" \b");
+ for (loop = 0; loop < p_user_cmd_if->accum_cmd_len - p_user_cmd_if->cmd_cur; loop++)
+ {
+ data_uart_print("\b");
+ }
+ }
+ break;
+
+ case 44: /* up: < */
+ if (p_user_cmd_if->history_head != USER_CMD_MAX_HISTORY_LINE)
+ {
+ cmd_clear_screen(p_user_cmd_if);
+ if (p_user_cmd_if->history_cur == USER_CMD_MAX_HISTORY_LINE)
+ {
+ p_user_cmd_if->history_cur = p_user_cmd_if->history_tail;
+ }
+ else
+ {
+ if (p_user_cmd_if->history_cur != p_user_cmd_if->history_head)
+ {
+ p_user_cmd_if->history_cur = (p_user_cmd_if->history_cur + USER_CMD_MAX_HISTORY_LINE - 1) %
+ USER_CMD_MAX_HISTORY_LINE;
+ }
+ else
+ {
+ p_user_cmd_if->history_cur = USER_CMD_MAX_HISTORY_LINE;
+ break;
+ }
+ }
+ p_user_cmd_if->accum_cmd_len = p_user_cmd_if->cmd_history_len[p_user_cmd_if->history_cur];
+ p_user_cmd_if->cmd_cur = p_user_cmd_if->accum_cmd_len;
+ memcpy(p_user_cmd_if->cmdline_buf, p_user_cmd_if->cmd_history[p_user_cmd_if->history_cur],
+ p_user_cmd_if->accum_cmd_len);
+ data_uart_print("%s", p_user_cmd_if->cmdline_buf);
+ }
+ break;
+
+ case 46: /* down: > */
+ if (p_user_cmd_if->history_head != USER_CMD_MAX_HISTORY_LINE)
+ {
+ cmd_clear_screen(p_user_cmd_if);
+ if (p_user_cmd_if->history_cur == USER_CMD_MAX_HISTORY_LINE)
+ {
+ p_user_cmd_if->history_cur = p_user_cmd_if->history_head;
+ }
+ else
+ {
+ if (p_user_cmd_if->history_cur != p_user_cmd_if->history_tail)
+ {
+ p_user_cmd_if->history_cur = (p_user_cmd_if->history_cur + 1) % USER_CMD_MAX_HISTORY_LINE;
+ }
+ else
+ {
+ p_user_cmd_if->history_cur = USER_CMD_MAX_HISTORY_LINE;
+ break;
+ }
+ }
+ p_user_cmd_if->accum_cmd_len = p_user_cmd_if->cmd_history_len[p_user_cmd_if->history_cur];
+ p_user_cmd_if->cmd_cur = p_user_cmd_if->accum_cmd_len;
+ memcpy(p_user_cmd_if->cmdline_buf, p_user_cmd_if->cmd_history[p_user_cmd_if->history_cur],
+ p_user_cmd_if->accum_cmd_len);
+ data_uart_print("%s", p_user_cmd_if->cmdline_buf);
+ }
+ break;
+
+ case 91: /* left: { */
+ if (p_user_cmd_if->cmd_cur > 0)
+ {
+ data_uart_print("\b");
+ p_user_cmd_if->cmd_cur--;
+ }
+ break;
+
+ case 93: /* right: } */
+ if (p_user_cmd_if->cmd_cur < p_user_cmd_if->accum_cmd_len)
+ {
+ data_uart_print("%c", p_user_cmd_if->cmdline_buf[p_user_cmd_if->cmd_cur]);
+ p_user_cmd_if->cmd_cur++;
+ }
+ break;
+
+ case 92: /* end: \ */
+ if (p_user_cmd_if->cmd_cur < p_user_cmd_if->accum_cmd_len)
+ {
+ data_uart_print("%s", p_user_cmd_if->cmdline_buf + p_user_cmd_if->cmd_cur);
+ p_user_cmd_if->cmd_cur = p_user_cmd_if->accum_cmd_len;
+ }
+ break;
+
+ case 47: /* begin: / */
+ while (p_user_cmd_if->cmd_cur > 0)
+ {
+ data_uart_print("\b");
+ p_user_cmd_if->cmd_cur--;
+ }
+ break;
+
+ default:
+ /* Put character in command buffer */
+ if (p_user_cmd_if->accum_cmd_len < USER_CMD_MAX_COMMAND_LINE)
+ {
+ uint8_t loop;
+
+ cmd_move_back(p_user_cmd_if);
+ p_user_cmd_if->cmdline_buf[p_user_cmd_if->cmd_cur] = c;
+ data_uart_print("%s", p_user_cmd_if->cmdline_buf + p_user_cmd_if->cmd_cur);
+ p_user_cmd_if->accum_cmd_len++;
+ p_user_cmd_if->cmd_cur++;
+ for (loop = 0; loop < p_user_cmd_if->accum_cmd_len - p_user_cmd_if->cmd_cur; loop++)
+ {
+ data_uart_print("\b");
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+/**
+ * @brief Initiate command interface structure
+ * @param[in] p_user_cmd_if Store parsed commands.
+ * @param[in] project_name Initiate project name.
+ * @return void
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_main_task(void *p_param)
+ {
+ char event;
+
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(unsigned char));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ data_uart_init(evt_queue_handle, io_queue_handle);
+ user_cmd_init(&user_cmd_if, "central");
+ ......
+ }
+ * \endcode
+ */
+void user_cmd_init(T_USER_CMD_IF *p_user_cmd_if, char *project_name)
+{
+ memset(p_user_cmd_if, 0, sizeof(T_USER_CMD_IF));
+ p_user_cmd_if->history_head = USER_CMD_MAX_HISTORY_LINE;
+ p_user_cmd_if->history_tail = USER_CMD_MAX_HISTORY_LINE;
+ p_user_cmd_if->history_cur = USER_CMD_MAX_HISTORY_LINE;
+ data_uart_print(">> Command Parse Init (%s) <<\r\n", project_name);
+}
+
diff --git a/src/mcu/module/data_uart_cmd/user_cmd_parse.h b/src/mcu/module/data_uart_cmd/user_cmd_parse.h
new file mode 100644
index 0000000..db5884b
--- /dev/null
+++ b/src/mcu/module/data_uart_cmd/user_cmd_parse.h
@@ -0,0 +1,202 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file user_cmd_parse.h
+* @brief Parse user command from lower Data UART data.
+* @details Structure of command parse results.
+* @author
+* @date 2016-02-18
+* @version v0.1
+*********************************************************************************************************
+*/
+#ifndef __USER_CMD_PARSE_CMD_H
+#define __USER_CMD_PARSE_CMD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/** @defgroup DATA_UART_CMD Data Uart Command Module
+ * @{
+ */
+/** @defgroup USER_CMD_PARSE User Command Parse Module
+ * @{
+ */
+/*============================================================================*
+ * Micros
+ *============================================================================*/
+/** @defgroup USER_CMD_PARSE_Exported_Micros User Command Parse Module Exported Micros
+ @brief command parse related macros.
+ * @{
+ */
+
+#define USER_CMD_MAX_COMMAND_LINE 80 /**< max. length of command line in bytes */
+#define USER_CMD_MAX_HISTORY_LINE 3 /**< max. num of history command line */
+#define USER_CMD_MAX_PARAMETERS 20 /**< max. number of parameters that the parser will scan */
+/** End of USER_CMD_PARSE_Exported_Micros
+ * @}
+ */
+
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup USER_CMD_PARSE_Exported_Types User Command Parse Module Exported Types
+ * @{
+ */
+
+/**
+* @brief Data UART command parse result.
+*
+* This is the structure where the command line parser puts its result.
+*/
+typedef enum
+{
+ RESULT_SUCCESS, //!< Operation success.
+ RESULT_GAP_CAUSE_ALREADY_IN_REQ = 0x01,//!< Operation already in progress.
+ RESULT_GAP_CAUSE_INVALID_STATE = 0x02,//!< Invalid state.
+ RESULT_GAP_CAUSE_INVALID_PARAM = 0x03,//!< Invalid parameter.
+ RESULT_GAP_CAUSE_NON_CONN = 0x04,//!< No connection establishment.
+ RESULT_GAP_CAUSE_NOT_FIND_IRK = 0x05,//!< IRK not found.
+ RESULT_GAP_CAUSE_ERROR_CREDITS = 0x06,//!< Credits error.
+ RESULT_GAP_CAUSE_SEND_REQ_FAILED = 0x07,//!< Send Request failed.
+ RESULT_GAP_CAUSE_NO_RESOURCE = 0x08,//!< No resource.
+ RESULT_GAP_CAUSE_INVALID_PDU_SIZE = 0x09,//!< Invalid PDU size.
+ RESULT_GAP_CAUSE_NOT_FIND = 0x0a,//!< Not Found.
+ RESULT_GAP_CAUSE_CONN_LIMIT = 0x0b,//!< Connection reachs limited count.
+
+ RESULT_ERR = 0x20,
+ RESULT_CMD_EMPTY_LINE = 0x21,
+ RESULT_CMD_NOT_FOUND = 0x22,
+ RESULT_CMD_ERR_PARAM = 0x23,
+ RESULT_CMD_ERR_PARAM_NUM = 0x24,
+ RESULT_CMD_OUT_OF_RANGE = 0x25,
+ RESULT_CMD_NOT_SUPPORT = 0x26,
+ RESULT_GAP_CAUSE_ERROR_UNKNOWN = 0xFF,//!< Unknown error.
+} T_USER_CMD_PARSE_RESULT;
+
+/**
+ * @brief Data UART command parse value.
+ *
+ * This is the structure where the command line parser puts its values.
+ */
+typedef struct
+{
+ char *p_cmd; /**< pointer to command */
+ int32_t param_count; /**< number of found parameters */
+ uint32_t dw_param[USER_CMD_MAX_PARAMETERS]; /**< automatically parsed parameters */
+ char *p_param[USER_CMD_MAX_PARAMETERS]; /**< automatically parsed parameters */
+} T_USER_CMD_PARSED_VALUE;
+
+/** @brief Command interface. */
+typedef struct
+{
+ char cmdline_buf[USER_CMD_MAX_COMMAND_LINE + 2];
+ uint8_t cmd_cur;
+ uint8_t cmd_history[USER_CMD_MAX_HISTORY_LINE][USER_CMD_MAX_COMMAND_LINE + 2];
+ uint8_t cmd_history_len[USER_CMD_MAX_HISTORY_LINE];
+ uint8_t history_head;
+ uint8_t history_tail;
+ uint8_t history_cur;
+ int32_t accum_cmd_len; /**< accumulated length of command */
+} T_USER_CMD_IF;
+
+/** @brief Prototype of functions that can be called from command table. */
+typedef T_USER_CMD_PARSE_RESULT(*T_USER_CMD_FUNC)(T_USER_CMD_PARSED_VALUE *p_parse_value);
+
+/**
+ * @brief Command table entry.
+ *
+ */
+typedef struct
+{
+ char *p_cmd;
+ char *p_option;
+ char *p_help;
+ T_USER_CMD_FUNC func;
+} T_USER_CMD_TABLE_ENTRY;
+/** End of USER_CMD_PARSE_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup USER_CMD_PARSE_Exported_Functions User Command Parse Module Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Initiate command interface structure
+ * @param[in] p_user_cmd_if Store parsed commands.
+ * @param[in] project_name Initiate project name.
+ * @return void
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_main_task(void *p_param)
+ {
+ char event;
+
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(unsigned char));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ data_uart_init(evt_queue_handle, io_queue_handle);
+ user_cmd_init(&user_cmd_if, "central");
+ ......
+ }
+ * \endcode
+ */
+void user_cmd_init(T_USER_CMD_IF *p_user_cmd_if, char *project_name);
+
+/**
+ * @brief Collect command characters.
+ *
+ * @param[in] p_user_cmd_if Store parsed commands.
+ * @param[in] p_data Data to be parsed.
+ * @param[in] len Length of data to be command parsed.
+ * @param[in] p_cmd_table Command table to execute function.
+ * @return Command collect result.
+ * @retval 1 true.
+ * @retval 0 false.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_handle_io_msg(T_IO_MSG io_msg)
+ {
+ uint16_t msg_type = io_msg.type;
+ uint8_t rx_char;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_UART:
+ // We handle user command informations from Data UART in this branch.
+ rx_char = (uint8_t)io_msg.subtype;
+ user_cmd_collect(&user_cmd_if, &rx_char, sizeof(rx_char), user_cmd_table);
+ break;
+ default:
+ break;
+ }
+ }
+ * \endcode
+ */
+bool user_cmd_collect(T_USER_CMD_IF *p_user_cmd_if, uint8_t *p_data, int32_t len,
+ const T_USER_CMD_TABLE_ENTRY *p_cmd_table);
+/** End of USER_CMD_PARSE_Exported_Functions
+ * @}
+ */
+
+/** @} */ /* End of group USER_CMD_PARSE */
+/** @} */ /* End of group DATA_UART_CMD */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __USER_CMD_PARSE_CMD_H */
+
diff --git a/src/mcu/peripheral/readme b/src/mcu/peripheral/readme
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/mcu/peripheral/readme
diff --git a/src/mcu/peripheral/rtl876x_3wire_spi.c b/src/mcu/peripheral/rtl876x_3wire_spi.c
new file mode 100644
index 0000000..36e9a47
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_3wire_spi.c
@@ -0,0 +1,301 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_3wire_spi.c
+* @brief This file provides all the 3 wire SPI firmware functions.
+* @details
+* @author elliot chen
+* @date 2016-12-13
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_rcc.h"
+#include "rtl876x_3wire_spi.h"
+
+/**
+ * @brief Deinitializes the 3WIRE SPI peripheral registers to their default reset values.
+ * @retval None
+ */
+void SPI3WIRE_DeInit(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_SPI2W, APBPeriph_SPI2W_CLOCK, DISABLE);
+}
+
+/**
+ * @brief Initializes the SPI_3WIRE peripheral according to the specified
+ * parameters in the SPI_3WIRE_InitStruct
+ * @param SPI3WIRE_InitStruct: pointer to a SPI3WIRE_InitTypeDef structure that
+ * contains the configuration information for the specified SPI_3WIRE peripheral
+ * @retval None
+ */
+void SPI3WIRE_Init(SPI3WIRE_InitTypeDef *SPI3WIRE_InitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI3WIRE_MODE(SPI3WIRE_InitStruct->SPI3WIRE_Mode));
+ assert_param(IS_SPI3WIRE_OE_DELAY_CFG(SPI3WIRE_InitStruct->SPI3WIRE_OutputDelay));
+ assert_param(IS_SPI3WIRE_END_EXTEND_MODE(SPI3WIRE_InitStruct->SPI3WIRE_ExtMode));
+ assert_param(IS_SPI3WIRE_READ_CYCLE_DELAY(SPI3WIRE_InitStruct->SPI3WIRE_ReadDelay));
+
+ uint32_t divValue = 0;
+
+ divValue = (((SPI3WIRE_InitStruct->SPI3WIRE_SysClock) / (SPI3WIRE_InitStruct->SPI3WIRE_Speed * 2) -
+ 1)) & 0xFF;
+
+ /* Initialize the parameters */
+ SPI3WIRE->CFGR = (SPI3WIRE_InitStruct->SPI3WIRE_Mode) | \
+ (SPI3WIRE_InitStruct->SPI3WIRE_OutputDelay) | \
+ (SPI3WIRE_InitStruct->SPI3WIRE_ExtMode) | \
+ (divValue << SPI3WIRE_SSI_DIV_NUM_Pos) | \
+ (SPI3WIRE_InitStruct->SPI3WIRE_ReadDelay << SPI3WIRE_SSI_DLY_CYCLE_Pos);
+
+ /* Clear all read data registers, read number and interrupt */
+ SPI3WIRE->INTCR = SPI3WIRE_FIFO_INT_ALL_CLR;
+}
+
+/**
+ * @brief Fills each SPI3WIRE_InitStruct member with its default value.
+ * @param SPI3WIRE_InitStruct: pointer to an SPI3WIRE_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void SPI3WIRE_StructInit(SPI3WIRE_InitTypeDef *SPI3WIRE_InitStruct)
+{
+ SPI3WIRE_InitStruct->SPI3WIRE_SysClock = 20000000;
+ SPI3WIRE_InitStruct->SPI3WIRE_Speed = 1000000;
+ SPI3WIRE_InitStruct->SPI3WIRE_Mode = SPI3WIRE_2WIRE_MODE;
+ SPI3WIRE_InitStruct->SPI3WIRE_ReadDelay =
+ 0;/* Delay time = (SPI3WIRE_ReadDelay+1)/(2*SPI3WIRE_Speed) */
+ SPI3WIRE_InitStruct->SPI3WIRE_OutputDelay = SPI3WIRE_OE_DELAY_1T;
+ SPI3WIRE_InitStruct->SPI3WIRE_ExtMode = SPI3WIRE_NORMAL_MODE;
+}
+
+/**
+ * @brief Enables or disables the specified SPI3WIRE peripheral.
+ * @param NewState: new state of the SPI3WIRE peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI3WIRE_Cmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SPI3WIRE peripheral */
+ SPI3WIRE->CFGR |= SPI3WIRE_SSI_EN_Msk;
+ }
+ else
+ {
+ /* Disable the selected SPI3WIRE peripheral */
+ SPI3WIRE->CFGR &= SPI3WIRE_SSI_EN_CLR;
+ }
+}
+
+/**
+ * @brief Enables or disables the specified SPI3WIRE interrupts.
+ * @param SPI3WIRE_INT: specifies the SPI3WIRE interrupts sources to be enabled or disabled.
+ * This parameter can be only be the following value:
+ * @arg SPI3WIRE_INT_BIT: enable SPI3WIRE interrupt.
+ * @param NewState: new state of the specified SPI3WIRE interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI3WIRE_INTConfig(uint32_t SPI3WIRE_INT, FunctionalState newState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(newState));
+ assert_param(IS_SPI3WIRE_INT(SPI3WIRE_INT));
+
+ if (newState == ENABLE)
+ {
+ /* Enable the selected 3WIRE_SPI interrupts */
+ SPI3WIRE->CFGR |= SPI3WIRE_INT;
+ }
+ else
+ {
+ /* Disable the selected 3WIRE_SPI interrupts */
+ SPI3WIRE->CFGR &= (uint32_t)(~SPI3WIRE_INT);
+ }
+}
+
+/**
+ * @brief Configure resync signal time value.
+ * @param value: Resync signal time value whose uint is 1/(2*SPI3WIRE_Speed).
+ * This parameter can be only be the following value: 0x0 to 0xf.
+ * @retval None
+ */
+void SPI3WIRE_SetResyncTime(uint32_t value)
+{
+ SPI3WIRE->CFGR &= SPI3WIRE_SSI_RESYNC_TIME_CLR;
+ SPI3WIRE->CFGR |= value << SPI3WIRE_SSI_RESYNC_TIME_Pos;
+}
+
+/**
+ * @brief Send resync signal or not .Must send when SPI3WIRE is disable.
+ * @param NewState: new state of the SPI3WIRE peripheral.
+ * This parameter can be only be the following value:
+ * @param ENABLE: trigger resync signal.
+ * @param ENABLE: disable resync signal.
+ * @retval None
+ */
+void SPI3WIRE_ResyncSignalCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ SPI3WIRE->INTCR |= SPI3WIRE_RESYNV_EN_Msk;
+ }
+ else
+ {
+ SPI3WIRE->INTCR &= SPI3WIRE_RESYNV_EN_CLR;
+ }
+}
+
+/**
+ * @brief Get total number of data byte in each SPI reading.
+ * @param None.
+ * @retval The total number of data byte in each SPI reading.
+ */
+uint8_t SPI3WIRE_GetRxDataLen(void)
+{
+ return (uint8_t)(SPI3WIRE->SR & SPI3WIRE_RDATA_NUM_Msk);
+}
+
+/**
+ * @brief Clear read data number status.
+ * @param None.
+ * @retval None
+ */
+void SPI3WIRE_ClearRxDataLen(void)
+{
+ SPI3WIRE->INTCR |= SPI3WIRE_RD_NUM_CLEAR_Msk;
+}
+
+/**
+ * @brief Clear all read data registers.
+ * @param None.
+ * @retval None.
+ */
+void SPI3WIRE_ClearRxFIFO(void)
+{
+ SPI3WIRE->INTCR |= SPI3WIRE_RD_DATA_CLEAR_Msk;
+}
+
+/**
+ * @brief start to write data.
+ * @param address: write address.
+ * @param data: write data.
+ * @retval None
+ */
+void SPI3WIRE_StartWrite(uint8_t address, uint8_t data)
+{
+ SPI3WIRE->CR = (uint32_t)(SPI3WIRE_RW_MODE_Msk) | ((uint32_t)address << SPI3WIRE_ADDRESS_Pos) |
+ (uint32_t)data;
+}
+
+/**
+ * @brief start read.
+ * @param address: read address.
+ * @param readNum: number of data to read.This value can be 0x1 to 0xf.
+ * @retval None.
+ */
+void SPI3WIRE_StartRead(uint8_t address, uint32_t len)
+{
+ if (len == 1)
+ {
+ /* Disable burst read */
+ SPI3WIRE->CFGR &= SPI3WIRE_SSI_BURST_READ_EN_CLR;
+ /* Read address */
+ SPI3WIRE->CR = ((uint32_t)address << SPI3WIRE_ADDRESS_Pos);
+ }
+ else
+ {
+ /* Enable burst read */
+ SPI3WIRE->CFGR |= SPI3WIRE_SSI_BURST_READ_EN_Msk;
+ /* Read num */
+ SPI3WIRE->CFGR &= SPI3WIRE_SSI_BURST_READ_NUM_CLR;
+ SPI3WIRE->CFGR |= ((len - 1) << SPI3WIRE_SSI_BURST_READ_NUM_Pos);
+ /* Set read command and read address */
+ SPI3WIRE->CR = ((uint32_t)address << SPI3WIRE_ADDRESS_Pos);
+ }
+}
+
+/**
+ * @brief write data.
+ * @param outBuf: buffer to store read datas.
+ * @param readNum: read number.
+ * @retval None
+ */
+void SPI3WIRE_ReadBuf(uint8_t *pBuf, uint8_t readNum)
+{
+ uint8_t i = 0;
+ uint8_t j = 0;
+ uint32_t regVal = 0;
+ uint8_t regIndex = readNum / 4;
+
+ for (i = 0; i < regIndex; i++)
+ {
+ regVal = *((volatile uint32_t *)(&(SPI3WIRE->RD0) + i));
+
+ for (j = 0; j < 4; j++)
+ {
+ *pBuf++ = (uint8_t)(regVal >> (8 * j));
+ }
+ }
+
+ if (readNum > regIndex * 4)
+ {
+ regVal = *((volatile uint32_t *)(&(SPI3WIRE->RD0) + regIndex));
+
+ for (j = 0; j < (readNum - regIndex * 4); j++)
+ {
+ *pBuf++ = (uint8_t)(regVal >> (8 * j));
+ }
+ }
+}
+
+/**
+ * @brief Checks whether the specified 3WIRE_SPI flag is set or not.
+ * @param SPI3WIRE_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg SPI3WIRE_FLAG_BUSY: 3wire spi is busy.
+ * @arg SPI3WIRE_FLAG_INT_IND: there is 3wire spi interrupt.
+ * @arg SPI3WIRE_FLAG_RESYNC_BUSY: resync busy or not.
+ * @retval The new state of UART_FLAG (SET or RESET).
+ */
+FlagStatus SPI3WIRE_GetFlagStatus(uint32_t SPI3WIRE_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_SPI3WIRE_FLAG(SPI3WIRE_FLAG));
+
+ if (SPI3WIRE->SR & SPI3WIRE_FLAG)
+ {
+ bitstatus = SET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the 3WIRE_SPI interrupt pending bits.
+ * @param SPI3WIRE_INT: specifies the SPI3WIRE interrupts sources to be enabled or disabled.
+ * This parameter can be only be the following value:
+ * @arg SPI3WIRE_INT_BIT: enable SPI3WIRE interrupt.
+ * @retval None
+ */
+void SPI3WIRE_ClearINTPendingBit(uint32_t SPI3WIRE_INT)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI3WIRE_INT(SPI3WIRE_INT));
+
+ SPI3WIRE->INTCR |= SPI3WIRE_INT;
+}
+
+/******************* (C) COPYRIGHT 2016 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/mcu/peripheral/rtl876x_adc.c b/src/mcu/peripheral/rtl876x_adc.c
new file mode 100644
index 0000000..04c8f0c
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_adc.c
@@ -0,0 +1,575 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2021, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_adc.c
+* @brief This file provides all the ADC firmware functions.
+* @details
+* @author yuan
+* @date 2021-05-10
+* @version v1.0.2
+*********************************************************************************************************
+*/
+#include "rtl876x_rcc.h"
+#include "rtl876x_adc.h"
+
+
+/**
+ * @brief Deinitializes the ADC peripheral registers to their default reset values(turn off ADC clock).
+ *
+ * @param ADCx: selected ADC peripheral.
+ * @return None.
+ */
+void ADC_DeInit(ADC_TypeDef *ADCx)
+{
+ assert_param(IS_ADC_PERIPH(ADCx));
+
+ RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, DISABLE);
+
+ return;
+}
+
+/**
+ * @brief Initializes the ADC peripheral according to the specified
+ * parameters in the ADC_InitStruct
+ * @param ADCx: selected ADC peripheral.
+ * @param ADC_InitStruct: pointer to a ADCInitTypeDef structure that
+ * contains the configuration information for the specified ADC peripheral
+ * @return None.
+ */
+void ADC_Init(ADC_TypeDef *ADCx, ADC_InitTypeDef *ADC_InitStruct)
+{
+ assert_param(IS_ADC_PERIPH(ADCx));
+ assert_param(IS_ADC_DATA_WRITE_TO_FIFO_CMD(ADC_InitStruct->ADC_DataWriteToFifo));
+ assert_param(IS_ADC_FIFO_THRESHOLD(ADC_InitStruct->ADC_FifoThdLevel));
+ assert_param(IS_ADC_WATER_LEVEL_CONFIG(ADC_InitStruct->ADC_WaterLevel));
+ assert_param(IS_ADC_OVERWRITE_MODE(ADC_InitStruct->ADC_FifoOverWriteEn));
+ assert_param(IS_ADC_LATCH_DATA_EDGE(ADC_InitStruct->ADC_DataLatchEdge));
+ assert_param(IS_ADC_DATA_AVG_NUM(ADC_InitStruct->ADC_DataAvgSel));
+ assert_param(IS_ADC_DATA_AVG_EN(ADC_InitStruct->ADC_DataAvgEn));
+ assert_param(IS_ADC_POWER_ON_MODE(ADC_InitStruct->ADC_PowerOnMode));
+ assert_param(IS_ADC_RG2X_0_DELAY_TIME(ADC_InitStruct->ADC_RG2X0Dly));
+ assert_param(IS_ADC_RG0X_1_DELAY_TIME(ADC_InitStruct->ADC_RG0X1Dly));
+ assert_param(IS_ADC_RG0X_0_DELAY_TIME(ADC_InitStruct->ADC_RG0X0Dly));
+ assert_param(IS_ADC_DATA_MINUS_CMD(ADC_InitStruct->ADC_DataMinusEn));
+ assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->ADC_DataAlign));
+ assert_param(IS_ADC_TIMER_TRIGGER_CMD(ADC_InitStruct->ADC_TimerTriggerEn));
+ assert_param(IS_ADC_POWER_ALWAYS_ON(ADC_InitStruct->ADC_PowerAlwaysOnEn));
+ assert_param(IS_ADC_CONVERT_TIME(ADC_InitStruct->ADC_ConvertTime));
+
+
+ /* Added to stabilize the power supply! */
+ uint16_t reg_value = 0;
+
+ /* enable cmp low noise for 3 bit */
+ reg_value = btaon_fast_read_safe(0x116);
+ btaon_fast_write(0x116, reg_value | BIT(10));
+
+ /* vref_sel = 0.85V */
+ reg_value = btaon_fast_read_safe(0x116);
+ btaon_fast_write(0x116, reg_value | BIT(5) | BIT(4));
+
+ /*Disable all interrupt.*/
+ ADCx->INTCR &= (~0x1f);
+
+ /* Set power mode first */
+ ADCx->PWRDLY = (((ADC_InitStruct->ADC_DataLatchDly & 0x7) << 6) |
+ ADC_InitStruct->ADC_PowerAlwaysOnEn |
+ ADC_InitStruct->ADC_PowerOnMode);
+
+ if (ADC_InitStruct->ADC_PowerOnMode == ADC_POWER_ON_AUTO)
+ {
+ ADCx->PWRDLY |= (ADC_InitStruct->ADC_RG2X0Dly \
+ | ADC_InitStruct->ADC_RG0X1Dly \
+ | ADC_InitStruct->ADC_RG0X0Dly);
+ }
+
+ if (ADC_InitStruct->ADC_DataAvgEn == ADC_DATA_AVERAGE_ENABLE)
+ {
+ ADCx->PWRDLY |= (ADC_InitStruct->ADC_DataAvgEn | ADC_InitStruct->ADC_DataAvgSel);
+ /* Disable schedule table */
+ ADCx->SCHCR &= (~0xffff);
+ /* Set schedule table */
+ ADCx->SCHTAB0 = ADC_InitStruct->ADC_SchIndex[0];
+ ADCx->SCHCR |= (uint16_t)0x0001;
+ }
+ else
+ {
+ /* Disable schedule table */
+ ADCx->SCHCR &= (~0xffff);
+
+ /* Set schedule table */
+ for (uint8_t index = 0; index < MAX_ADC_SCH_NUM; index++)
+ {
+ *(__IO uint32_t *)((uint32_t *)(&ADCx->SCHTAB0) + index) = ((ADC_InitStruct->ADC_SchIndex[index * 2]
+ & 0x1F)
+ | ((ADC_InitStruct->ADC_SchIndex[index * 2 + 1] & 0x1F) << 16));
+ }
+ ADCx->SCHCR = ADC_InitStruct->ADC_Bitmap;
+ }
+
+ /* Set ADC mode */
+ ADCx->CR = ((ADC_InitStruct->ADC_DataWriteToFifo)
+ | ((ADC_InitStruct->ADC_FifoThdLevel & 0x3F) << 20)
+ | ((ADC_InitStruct->ADC_WaterLevel & 0x3F) << 14)
+ | (ADC_InitStruct->ADC_FifoOverWriteEn)
+ | (ADC_InitStruct->ADC_DataLatchEdge));
+
+ ADCx->DATCLK = ((ADC_InitStruct->ADC_DataMinusEn)
+ | (ADC_InitStruct->ADC_DataAlign)
+ | ((ADC_InitStruct->ADC_DataMinusOffset & 0xFFF) << 16));
+
+ ADCx->ANACTL |= (0x03 << 10);
+ if ((ADC_InitStruct->ADC_SampleTime & 0x3FFF) < 19)
+ {
+ /* adc sample period max 400kHz */
+ ADC_InitStruct->ADC_SampleTime = 19;
+ }
+ ADCx->SAMTIM = ((ADC_InitStruct->ADC_ConvertTime)
+ | (ADC_InitStruct->ADC_SampleTime & 0x3FFF));
+
+ /*clear adc fifo*/
+ ADCx->CR |= BIT26;
+
+ /*clear all interrupt*/
+ ADCx->INTCR |= (0x1f << 8);
+
+ return;
+}
+
+/**
+ * @brief Fills each ADC_InitStruct member with its default value.
+ * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void ADC_StructInit(ADC_InitTypeDef *ADC_InitStruct)
+{
+ ADC_InitStruct->ADC_SampleTime = 255; /* (n + 1) cycle of 10MHz,n = 0 to 16383 */
+ ADC_InitStruct->ADC_ConvertTime = ADC_CONVERT_TIME_500NS;
+
+ ADC_InitStruct->ADC_DataWriteToFifo = ADC_DATA_WRITE_TO_FIFO_DISABLE;
+ ADC_InitStruct->ADC_FifoThdLevel = 0x0A;
+ ADC_InitStruct->ADC_WaterLevel = 0x1;
+ ADC_InitStruct->ADC_FifoOverWriteEn = ADC_FIFO_OVER_WRITE_ENABLE;
+ ADC_InitStruct->ADC_DataLatchEdge = ADC_LATCH_DATA_Positive;
+
+ ADC_InitStruct->ADC_SchIndex[0] = 0;
+ ADC_InitStruct->ADC_SchIndex[1] = 0;
+ ADC_InitStruct->ADC_SchIndex[2] = 0;
+ ADC_InitStruct->ADC_SchIndex[3] = 0;
+ ADC_InitStruct->ADC_SchIndex[4] = 0;
+ ADC_InitStruct->ADC_SchIndex[5] = 0;
+ ADC_InitStruct->ADC_SchIndex[6] = 0;
+ ADC_InitStruct->ADC_SchIndex[7] = 0;
+ ADC_InitStruct->ADC_SchIndex[8] = 0;
+ ADC_InitStruct->ADC_SchIndex[9] = 0;
+ ADC_InitStruct->ADC_SchIndex[10] = 0;
+ ADC_InitStruct->ADC_SchIndex[11] = 0;
+ ADC_InitStruct->ADC_SchIndex[12] = 0;
+ ADC_InitStruct->ADC_SchIndex[13] = 0;
+ ADC_InitStruct->ADC_SchIndex[14] = 0;
+ ADC_InitStruct->ADC_SchIndex[15] = 0;
+ ADC_InitStruct->ADC_Bitmap = 0x0;
+
+ ADC_InitStruct->ADC_DataAlign = ADC_DATA_ALIGN_LSB;
+ ADC_InitStruct->ADC_DataMinusEn = ADC_DATA_MINUS_DISABLE;
+ ADC_InitStruct->ADC_DataMinusOffset = 0;
+
+ ADC_InitStruct->ADC_DataAvgEn = ADC_DATA_AVERAGE_DISABLE;
+ ADC_InitStruct->ADC_DataAvgSel = ADC_DATA_AVERAGE_OF_2;
+ /* Reserved parameter, please do not change values*/
+ ADC_InitStruct->ADC_PowerOnMode = ADC_POWER_ON_AUTO;
+ ADC_InitStruct->ADC_PowerAlwaysOnEn = ADC_POWER_ALWAYS_ON_DISABLE;
+ ADC_InitStruct->ADC_DataLatchDly = 0x1;
+ ADC_InitStruct->ADC_RG2X0Dly = ADC_RG2X_0_DELAY_10_US;
+ ADC_InitStruct->ADC_RG0X1Dly = ADC_RG0X_1_DELAY_20_US;
+ ADC_InitStruct->ADC_RG0X0Dly = ADC_RG0X_0_DELAY_30_US;
+
+ return;
+}
+
+/**
+ * @brief Enables or disables the ADC peripheral.
+ * @param ADCx: selected ADC peripheral.
+ * @param adcMode: adc mode select.
+ This parameter can be one of the following values:
+ * @arg ADC_ONE_SHOT_MODE: one shot mode.
+ * @arg ADC_CONTINUOUS_MODE: continuous mode.
+ * @param NewState: new state of the ADC peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_Cmd(ADC_TypeDef *ADCx, uint8_t adcMode, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+ assert_param(IS_ADC_SAMPLE_MODE(adcMode));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ uint8_t reg_value = 0;
+
+ if (NewState == ENABLE)
+ {
+ reg_value = btaon_fast_read_safe(0x113);
+ btaon_fast_write(0x113, reg_value & ~BIT2);
+ /* In case manual mode */
+ if (ADCx->PWRDLY & ADC_POWER_ON_MANUAL)
+ {
+ ADCx->PWRDLY |= 0x3C00;
+// ADC_DelayUs(80);
+ platform_delay_us(80);
+ ADCx->PWRDLY |= (BIT14 | BIT15);
+// ADC_DelayUs(320);
+ platform_delay_us(320);
+ ADCx->PWRDLY |= (BIT16 | BIT17);
+// ADC_DelayUs(240);
+ platform_delay_us(240);
+ ADCx->PWRDLY |= BIT18;
+ }
+ /* Reset ADC mode first */
+ ADCx->CR &= ~0x03;
+ /* Enable ADC */
+ ADCx->CR |= adcMode;
+ }
+ else
+ {
+ ADCx->CR &= ~0x03;
+ reg_value = btaon_fast_read_safe(0x113);
+ btaon_fast_write(0x113, reg_value | BIT2);
+ }
+
+ return;
+}
+
+/**
+ * @brief Enables or disables the specified ADC interrupts.
+ * @param ADCx: selected ADC peripheral.
+ * @param ADC_INT: specifies the ADC interrupts sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg ADC_INT_FIFO_RD_REQ :FIFO read request
+ * @arg ADC_INT_FIFO_RD_ERR :FIFO read error
+ * @arg ADC_INT_FIFO_THD :ADC FIFO size > thd
+ * @arg ADC_INT_FIFO_FULL :ADC FIFO overflow
+ * @arg ADC_INT_ONE_SHOT_DONE :ADC one shot mode done
+ * @param NewState: new state of the specified ADC interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_INTConfig(ADC_TypeDef *ADCx, uint32_t ADC_INT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+ assert_param(IS_ADC_INT(ADC_INT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC interrupts */
+ ADCx->INTCR |= ADC_INT;
+ }
+ else
+ {
+ /* Disable the selected ADC interrupts */
+ ADCx->INTCR &= (uint32_t)~ADC_INT;
+ }
+}
+
+/**
+ * @brief Read ADC data according to specific channel.
+ * @param ADCx: selected ADC peripheral.
+ * @param index: can be 0 to 15
+ * @retval The 10-bit converted ADC data.
+ */
+uint16_t ADC_ReadRawData(ADC_TypeDef *ADCx, uint8_t index)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+ assert_param(index < 16);
+
+ if (index & BIT(0))
+ {
+ return ((*(uint32_t *)((uint32_t *)(&ADCx->SCHD0) + (index >> 1))) >> 16);
+ }
+ else
+ {
+ return (*(uint32_t *)((uint32_t *)(&ADCx->SCHD0) + (index >> 1)));
+ }
+}
+
+/**
+ * @brief Read ADC average data from ADC schedule table0.
+ * @param ADCx: selected ADC peripheral.
+ * @param[out] OutBuf: buffer to save data read from ADC FIFO.
+ * @retval The 10-bit converted ADC data.
+ */
+uint16_t ADC_ReadAvgRawData(ADC_TypeDef *ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+
+ uint16_t data = 0;
+ data = (uint16_t)ADCx->SCHD0;
+
+ return data;
+}
+
+/**
+ * @brief Get one data from ADC FIFO.
+ * @param ADCx: selected ADC peripheral.
+ * @retval adc FIFO data.
+ */
+uint16_t ADC_ReadFIFO(ADC_TypeDef *ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+
+ return (uint16_t)((ADCx->FIFO) & 0xFFF);
+}
+
+/**
+ * @brief Read data from ADC FIFO.
+ * @param ADCx: selected ADC peripheral.
+ * @param[out] outBuf: buffer to save data read from ADC FIFO.
+ * @param num: number of data to be read.
+ * @retval None
+ */
+void ADC_ReadFIFOData(ADC_TypeDef *ADCx, uint16_t *outBuf, uint16_t num)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+
+ while (num--)
+ {
+ *outBuf++ = (uint16_t)ADCx->FIFO;
+ }
+
+ return;
+}
+
+/**
+ * @brief Get ADC fifo data number.
+ * @param ADCx: selected ADC peripheral.
+ * @retval current data number in adc fifo.
+ */
+uint8_t ADC_GetFIFODataLen(ADC_TypeDef *ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+
+ return ((uint8_t)(((ADCx->SCHCR) >> 16) & 0x3F));
+}
+
+/**
+ * @brief Config ADC schedule table.
+ * @param ADCx: selected ADC peripheral.
+ * @param adcMode: ADC mode.
+ * This parameter can be one of the following values:
+ * @arg EXT_SINGLE_ENDED(index)
+ * @arg EXT_DIFFERENTIAL(index)
+ * @arg INTERNAL_VBAT_MODE
+ * @param Index: Schedule table index.
+ * @return none.
+ */
+void ADC_SchIndexConfig(ADC_TypeDef *ADCx, uint8_t adcMode, uint16_t index)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+ assert_param(IS_ADC_SCHEDULE_INDEX_CONFIG(adcMode));
+
+ if (index & BIT0)
+ {
+ *(uint32_t *)((uint32_t *)(&ADCx->SCHTAB0) + (index >> 1)) |= (adcMode << 16);
+ }
+ else
+ {
+ *(uint32_t *)((uint32_t *)(&ADCx->SCHTAB0) + (index >> 1)) |= adcMode;
+ }
+
+ return;
+}
+
+/**
+ * @brief Same as function ADC_SchIndexConfig,this function is version bee2.
+ * @param ADCx: selected ADC peripheral.
+ * @param adcMode: ADC mode.
+ * This parameter can be one of the following values:
+ * @arg EXT_SINGLE_ENDED(index)
+ * @arg EXT_DIFFERENTIAL(index)
+ * @arg INTERNAL_VBAT_MODE
+ * @param Index: Schedule table index.
+ * @return none.
+ */
+void ADC_SchTableConfig(ADC_TypeDef *ADCx, uint16_t Index, uint8_t adcMode)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+ assert_param(IS_ADC_SCHEDULE_INDEX_CONFIG(adcMode));
+
+ if (Index & BIT0)
+ {
+ *(uint32_t *)((uint32_t *)(&ADCx->SCHTAB0) + (Index >> 1)) |= (adcMode << 16);
+ }
+ else
+ {
+ *(uint32_t *)((uint32_t *)(&ADCx->SCHTAB0) + (Index >> 1)) |= adcMode;
+ }
+
+ return;
+}
+
+/**
+ * @brief Set adc schedule table.
+ * @param ADCx: selected ADC peripheral.
+ * @param channelMap: ADC channel map.
+ * @param NewState: new state of the ADC peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @return none.
+ */
+void ADC_BitMapConfig(ADC_TypeDef *ADCx, uint16_t bitMap, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState == ENABLE)
+ {
+ ADCx->SCHCR |= bitMap;
+ }
+ else
+ {
+ ADCx->SCHCR &= (~bitMap);
+ }
+
+ return;
+}
+
+/**
+ * @brief Power on ADC manually.
+ * @param ADCx: selected ADC peripheral.
+ * @param NewState: new state of the ADC power on.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note If enable, ADC power will always on.
+ * @retval None
+ */
+void ADC_ManualPowerOnCmd(ADC_TypeDef *ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ ADCx->PWRDLY |= BIT19;
+ }
+ else
+ {
+ ADCx->PWRDLY &= ~(BIT19);
+ }
+}
+
+/**
+ * @brief Enable or disable stop fifo from writing data.
+ * @param ADCx: selected ADC peripheral.
+ * @param NewState: new state of the ADC fifo write.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_WriteFIFOCmd(ADC_TypeDef *ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState == DISABLE)
+ {
+ ADCx->PWRDLY |= BIT21;
+ }
+ else
+ {
+ ADCx->PWRDLY &= ~(BIT21);
+ }
+}
+
+/**
+ * @brief Config ADC bypass resistor.Attention!!!Channels using bypass mode cannot over 0.9V!!!!
+ * @param channelNum: external channel number, can be 0~3.
+ * @param NewState: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_BypassCmd(uint8_t ChannelNum, FunctionalState NewState)
+{
+ assert_param(ChannelNum <= 3);
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (ChannelNum > 3)
+ {
+ return;
+ }
+
+ uint16_t reg_value = 0;
+
+ if (NewState != DISABLE)
+ {
+ reg_value = btaon_fast_read_safe(0x118);
+ reg_value |= BIT(ChannelNum);
+ btaon_fast_write(0x118, reg_value);
+ }
+ else
+ {
+ reg_value = btaon_fast_read_safe(0x118);
+ reg_value &= ~BIT(ChannelNum);
+ btaon_fast_write(0x118, reg_value);
+ }
+}
+
+/**
+ * @brief Checks whether the specified ADC interrupt status flag is set or not.
+ * @param ADCx: selected ADC peripheral.
+ * @param ADC_INT_FLAG: specifies the interrupt status flag to check.
+ * This parameter can be one of the following values:
+ * @arg ADC_INT_ONE_SHOT_DONE: ADC once convert end interrupt
+ * @arg ADC_INT_FIFO_OVERFLOW: ADC FIFO overflow interrupt
+ * @arg ADC_INT_FIFO_THD: fifo larger than threshold
+ * @arg ADC_INT_FIFO_RD_ERR: ADC read FIFO error interrupt
+ * @arg ADC_INT_FIFO_RD_REQ: ADC read FIFO request interrupt
+ * @retval The new state of ADC_INT (SET or RESET).
+ */
+ITStatus ADC_GetINTStatus(ADC_TypeDef *ADCx, uint32_t ADC_INT)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+ assert_param(IS_ADC_INT(ADC_INT));
+
+ FlagStatus bitstatus = RESET;
+
+ if ((ADCx->INTCR & (ADC_INT << 16)) != 0)
+ {
+ bitstatus = SET;
+ }
+
+ return bitstatus;
+}
+
+/**
+ * @brief Clear the ADC interrupt pending bit.
+ * @param ADCx: selected ADC peripheral.
+ * @param ADC_INT: specifies the interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg ADC_INT_ONE_SHOT_DONE: ADC once convert end interrupt
+ * @arg ADC_INT_FIFO_OVERFLOW: ADC FIFO overflow interrupt
+ * @arg ADC_INT_FIFO_THD: fifo larger than threshold
+ * @arg ADC_INT_FIFO_RD_ERR: ADC read FIFO error interrupt
+ * @arg ADC_INT_FIFO_RD_REQ: ADC read FIFO request interrupt
+ * @retval None
+ */
+void ADC_ClearINTPendingBit(ADC_TypeDef *ADCx, uint32_t ADC_INT)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_PERIPH(ADCx));
+ assert_param(IS_ADC_INT(ADC_INT));
+
+ ADCx->INTCR |= (ADC_INT << 8);
+
+ return;
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/mcu/peripheral/rtl876x_aon_wdg.c b/src/mcu/peripheral/rtl876x_aon_wdg.c
new file mode 100644
index 0000000..04c3c83
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_aon_wdg.c
@@ -0,0 +1,152 @@
+/**
+***************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+***************************************************************************************************
+* @file rtl876x_aon_wdg.c
+* @brief This file provides all the AON Watch Dog firmware functions.
+* @details
+* @author Serval Li
+* @date 2017-06-27
+* @version v0.1
+***************************************************************************************************
+*/
+
+#include "rtl876x.h"
+#include "rtl876x_aon_wdg.h"
+
+
+#define REG_RTC_FAST_WRITE_BASE_ADDR (0x40000100UL)
+#define REG_RTC_FAST_WDATA (0x400001f0UL)
+#define REG_RTC_FAST_ADDR (0x400001f4UL)
+#define REG_RTC_WR_STROBE (0x400001f8UL)
+
+/* Enable Write to CRT register */
+#define AON_WDG_EnableWriteCRT() AON_WDG_WriteReg((uint32_t)&AON_WDG->WP - SYSTEM_REG_BASE, AON_WDG->WP | BIT0)
+
+/* Disable Write to CRT register */
+#define AON_WDG_DisableWriteCRT() AON_WDG_WriteReg((uint32_t)&AON_WDG->WP - SYSTEM_REG_BASE, AON_WDG->WP & ~BIT0);
+
+/**
+ * @brief Fast write RTC register.
+ * @param offset: the offset of RTC register.
+ * @param data: data which write to register.
+ * @retval None
+ */
+static void AON_WDG_WriteReg(uint32_t offset, uint32_t data)
+{
+ static bool is_called = false;
+
+ if (is_called == false)
+ {
+ *((volatile uint32_t *)0x40000014) |= BIT(9);//no need run this every time
+ is_called = true;
+ }
+
+ /* Write data */
+ *((volatile uint32_t *)REG_RTC_FAST_WDATA) = data;
+ /* Write RTC register address. Only offset */
+ *((volatile uint32_t *)REG_RTC_FAST_ADDR) = offset - REG_RTC_FAST_WRITE_BASE_ADDR;
+ *((volatile uint32_t *)REG_RTC_WR_STROBE) = 1;
+}
+
+void AON_WDG_Config(uint8_t reset_level, uint32_t comp, uint8_t cnt_ctl, uint8_t cnt_reload)
+{
+ AON_WDG_TypeDef aon_wdg;
+
+ aon_wdg.u.CRT = AON_WDG->u.CRT;
+
+ aon_wdg.u.CRT_BITS.RST_LVL = reset_level;
+ aon_wdg.u.CRT_BITS.COMP = comp;
+ aon_wdg.u.CRT_BITS.CNT_CTL = cnt_ctl;
+ aon_wdg.u.CRT_BITS.CNT_RELOAD = cnt_reload;
+
+ AON_WDG_EnableWriteCRT();
+ AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT);
+ AON_WDG_DisableWriteCRT();
+}
+
+void AON_WDG_ConfigResetLevel(uint8_t reset_level)
+{
+ AON_WDG_TypeDef aon_wdg;
+
+ aon_wdg.u.CRT = AON_WDG->u.CRT;
+ aon_wdg.u.CRT_BITS.RST_LVL = reset_level;
+
+ AON_WDG_EnableWriteCRT();
+ AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT);
+ AON_WDG_DisableWriteCRT();
+}
+
+void AON_WDG_ConfigComp(uint32_t comp)
+{
+ AON_WDG_TypeDef aon_wdg;
+
+ aon_wdg.u.CRT = AON_WDG->u.CRT;
+ aon_wdg.u.CRT_BITS.COMP = comp;
+
+ AON_WDG_EnableWriteCRT();
+ AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT);
+ AON_WDG_DisableWriteCRT();
+}
+
+void AON_WDG_ConfigCntCtl(uint8_t cnt_ctl)
+{
+ AON_WDG_TypeDef aon_wdg;
+
+ aon_wdg.u.CRT = AON_WDG->u.CRT;
+ aon_wdg.u.CRT_BITS.CNT_CTL = cnt_ctl;
+
+ AON_WDG_EnableWriteCRT();
+ AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT);
+ AON_WDG_DisableWriteCRT();
+}
+
+void AON_WDG_ConfigCntReload(uint8_t cnt_reload)
+{
+ AON_WDG_TypeDef aon_wdg;
+
+ aon_wdg.u.CRT = AON_WDG->u.CRT;
+ aon_wdg.u.CRT_BITS.CNT_RELOAD = cnt_reload;
+
+ AON_WDG_EnableWriteCRT();
+ AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT);
+ AON_WDG_DisableWriteCRT();
+}
+
+void AON_WDG_Enable(void)
+{
+ AON_WDG_TypeDef aon_wdg;
+
+ aon_wdg.u.CRT = AON_WDG->u.CRT;
+ aon_wdg.u.CRT_BITS.EN = 1;
+
+ AON_WDG_EnableWriteCRT();
+ AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT);
+ AON_WDG_DisableWriteCRT();
+}
+
+void AON_WDG_Disable(void)
+{
+ AON_WDG_TypeDef aon_wdg;
+
+ aon_wdg.u.CRT = AON_WDG->u.CRT;
+ aon_wdg.u.CRT_BITS.EN = 2;
+
+ AON_WDG_EnableWriteCRT();
+ AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT);
+ AON_WDG_DisableWriteCRT();
+}
+
+void AON_WDG_Restart(void)
+{
+ AON_WDG_WriteReg((uint32_t)&AON_WDG->CNT_CLR, 1);
+ AON_WDG_WriteReg((uint32_t)&AON_WDG->CNT_CLR, 0);
+}
+
+void AON_WDG_SystemReset(void)
+{
+ AON_WDG_Config(1, 1, 1, 0);
+ AON_WDG_Enable();
+
+ while (1); /* wait until reset */
+}
diff --git a/src/mcu/peripheral/rtl876x_captouch.c b/src/mcu/peripheral/rtl876x_captouch.c
new file mode 100644
index 0000000..7f7e073
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_captouch.c
@@ -0,0 +1,352 @@
+/**
+**********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_captouch.c
+* @brief This file provides all the Cap Touch functions.
+* @details
+* @author Yuan
+* @date 2020.09.29
+* @version v1.0.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_rcc.h"
+#include "rtl876x_captouch.h"
+#include "platform_utils.h"
+
+#define CTC_FUNC_EN_REG 0x26
+#define CTC_CLK_SRC_REG (*((volatile uint32_t *)0x4000020CUL))
+#define CTC_CLK_EN_REG (*((volatile uint32_t *)0x40000234UL))
+#define CTC_CLK_SRC_SEL_REG (*((volatile uint32_t *)0x400003F8UL))
+#define CTC_WK_EN_REG (*((volatile uint32_t *)0x40009000UL))
+#define CTC_WK_EN_REG_1 (*((volatile uint32_t *)0x40009048UL))
+
+/**
+ * @brief Enable the CTCx peripheral IP clock and function..
+ * @param None.
+ * @retval None.
+ */
+void CTC_RCCConfig(uint32_t clock_source)
+{
+ /* Enable Cap Touch IP clock and function */
+ if (clock_source == CTC_CLOCK_SOURCE_1M)
+ {
+ CTC_CLK_SRC_REG |= BIT29;
+ CTC_CLK_SRC_SEL_REG |= BIT0;
+ }
+ else if (clock_source == CTC_CLOCK_SOURCE_40M)
+ {
+ CTC_CLK_SRC_SEL_REG &= ~BIT0;
+ }
+
+ CTC_CLK_EN_REG |= BIT12;
+
+ /* Enable CTC function */
+ uint16_t reg_value = btaon_fast_read_safe(CTC_FUNC_EN_REG);
+ reg_value |= BIT(15);
+ btaon_fast_write_safe(CTC_FUNC_EN_REG, reg_value);
+}
+
+/**
+ * @brief Deinitializes the CTCx peripheral registers to their default reset values.
+ * @param None.
+ * @retval None.
+ */
+void CTC_DeInit()
+{
+ /* Enable Cap Touch IP clock and function */
+ CTC_CLK_EN_REG &= ~BIT12;
+
+ uint16_t reg_value = btaon_fast_read_safe(CTC_FUNC_EN_REG);
+ reg_value &= ~BIT(15);
+ btaon_fast_write_safe(CTC_FUNC_EN_REG, reg_value);
+}
+
+/**
+ * @brief Initializes the CTCx peripheral according to
+ * the specified parameters in the CTC_InitStruct.
+ * @param CTCx: CTC peripheral.
+ * @param CTC_InitStruct: pointer to a CTC_InitTypeDef structure that
+ * contains the configuration information for the specified CTC peripheral.
+ * @retval None.
+ */
+void CTC_Init(CTC_TypeDef *CTCx, CTC_InitTypeDef *CTC_InitStruct)
+{
+ uint32_t temp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_CTC_ALL_PERIPH(CTCx));
+
+ /* Disable CTC */
+ CTCx->CR &= CTC_CT_EN_Clr;
+
+ temp |= ((CTC_InitStruct->CTC_DebounceEn & 0x01) << CTC_DEBOUNCE_EN_Pos) |
+ (CTC_InitStruct->CTC_DebounceTime & 0x03) << CTC_DEBOUNCE_TIME_Pos;
+ CTCx->CR = temp;
+
+ temp = ((CTC_InitStruct->CTC_SampleTime & 0x07) << 16)
+ | (CTC_InitStruct->CTC_ScanInterval & 0xFFF);
+ CTCx->SCAN_PERIOD = temp;
+
+ temp = ((CTC_InitStruct->CTC_BaselineUpdateStep & 0x0F) << 12)
+ | ((CTC_InitStruct->CTC_BaselineWeightFactor & 0x0F) << 8)
+ | ((CTC_InitStruct->CTC_ETCScanInterval & 0x7F) << 1)
+ | ((CTC_InitStruct->CTC_ETCEn & 0x01) << 0);
+ CTCx->ETC_CR = temp;
+
+ temp = ((CTC_InitStruct->CTC_DelayGuardInterval & 0x1F) << 16)
+ | ((CTC_InitStruct->CTC_AdvancedGuardInterval & 0x1F) << 0);
+ CTCx->GUARD_CNT = temp;
+
+ temp = ((CTC_InitStruct->CTC_FastMatchCnt & 0x07) << 16)
+ | ((CTC_InitStruct->CTC_FastScanInerval & 0xFFF) << 0);
+ CTC_FAST->SCAN_INI = temp;
+
+ temp = ((CTC_InitStruct->CTC_FalseTouchCnt & 0x3FF) << 16)
+ | ((CTC_InitStruct->CTC_FalseAlarmCnt & 0xF) << 10)
+ | ((CTC_InitStruct->CTC_ReleaseActiveCnt & 0x3FF) << 0);
+ CTC_FAST->SET_CNT = temp;
+
+ uint16_t reg_value = btaon_fast_read_safe(0x116);
+ btaon_fast_write(0x116, reg_value | BIT(10) | BIT(15));
+
+ /* vref_sel = 0.85V */
+ reg_value = btaon_fast_read_safe(0x116);
+ btaon_fast_write(0x116, reg_value | BIT(5) | BIT(4));
+}
+
+/**
+ * @brief Initializes the specified channel.
+ * @param channel: specified channel
+ * @retval None
+ */
+void CTC_ChannelInit(CTC_ChannelTypeDef *CTC_Channelx,
+ CTC_ChannelInitTypeDef *CTC_ChannelInitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_CTC_CHANNEL(CH));
+
+ CTC_Channelx->TOUCH_TH |= ((CTC_ChannelInitStruct->CTC_NNoiseThd & 0xFF) << 24)
+ | ((CTC_ChannelInitStruct->CTC_PNoiseThd & 0xFF) << 16);
+ CTC_Channelx->CR |= ((CTC_ChannelInitStruct->CTC_DifferenceTouchThd & 0xFFF) << 16) | \
+ ((CTC_ChannelInitStruct->CTC_ChannelEn & 0x1) << 0);
+ CTC_Channelx->MBIAS |= ((CTC_ChannelInitStruct->CTC_MBias & 0x3F) << 0);
+}
+
+
+/**
+ * @brief Fills each CTC_InitStruct member with its default value.
+ * @param CTC_InitStruct: Pointer to a CTC_InitStruct structure which will be initialized.
+ * @return None.
+ */
+void CTC_StructInit(CTC_InitTypeDef *CTC_InitStruct)
+{
+ CTC_InitStruct->CTC_BaselineIniEn = CTC_BASELINEINI_ENABLE;
+ CTC_InitStruct->CTC_DebounceEn = CTC_DEBOUNCE_ENABLE;
+ CTC_InitStruct->CTC_DebounceTime = CTC_DEBOUNCE_TIMES_2;
+ CTC_InitStruct->CTC_SampleTime = CTC_SAMPLE_TIME_AVE_256;
+ CTC_InitStruct->CTC_ScanInterval = CTC_SCAN_INTERVAL_60ms;//60ms
+ CTC_InitStruct->CTC_BaselineUpdateStep = 0x0001;
+ CTC_InitStruct->CTC_BaselineWeightFactor = 0x0002;
+ CTC_InitStruct->CTC_ETCScanInterval = 0x02;
+ CTC_InitStruct->CTC_ETCEn = ENABLE;
+ CTC_InitStruct->CTC_SNRUpdateMode = 0x0;
+ CTC_InitStruct->CTC_ScanChannel = 0x0;
+ CTC_InitStruct->CTC_ScanChannelSwitchMode = 0x1;
+ CTC_InitStruct->CTC_DelayGuardInterval = 0x0;
+ CTC_InitStruct->CTC_AdvancedGuardInterval = 0x203;
+
+ CTC_InitStruct->CTC_FastMatchCnt =
+ CTC_FS_Match_Cnt_1DB; /*!< FS_MATCH_CNT must smaller than debounce time. */
+ CTC_InitStruct->CTC_FastScanInerval = 0x1D;
+ CTC_InitStruct->CTC_FalseTouchCnt = 0x3FF;
+ CTC_InitStruct->CTC_FalseAlarmCnt = 0x5;
+ CTC_InitStruct->CTC_ReleaseActiveCnt = 0xFF;
+}
+
+/**
+ * @brief Fills each CTC_InitStruct member with its default value.
+ * @param CTC_InitStruct: Pointer to a CTC_InitStruct structure which will be initialized.
+ * @return None.
+ */
+void CTC_ChannelStructInit(CTC_ChannelInitTypeDef *CTC_ChannelInitStruct)
+{
+ CTC_ChannelInitStruct->CTC_ChannelEn = DISABLE;
+ CTC_ChannelInitStruct->CTC_BaselineData = 0x0;
+ CTC_ChannelInitStruct->CTC_DifferenceTouchThd = 0x64;
+ CTC_ChannelInitStruct->CTC_AbsoluteTouchThd = 0x0;
+ CTC_ChannelInitStruct->CTC_PNoiseThd = 0xFF;
+ CTC_ChannelInitStruct->CTC_NNoiseThd = 0xFF;
+ CTC_ChannelInitStruct->CTC_MBias = CTC_MBIAS_8uA;
+}
+
+/**
+ * @brief Enable or disable the specified Cap Touch interrupt.
+ * \param[in] CTCx: The Cap Touch peripheral.
+ * \param[in] CTC_INT: Specifies the Cap Touch interrupt source which to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * \arg CTC_INT_FALSE_TOUCH_CH1: Channel 1 Touch cnt reach false touch cnt interrupt.
+ * \arg CTC_INT_FALSE_TOUCH_CH0: Channel 0 Touch cnt reach false touch cnt interrupt.
+ * \arg CTC_INT_N_NOISE_THD: Negative noise threshold overflow interrupt.
+ * \arg CTC_INT_FIFO_OVERFLOW: Raw code FIFO over flow interrupt
+ * \arg CTC_INT_P_NOISE_THD: Positive noise threshold overflow interrupt.
+ * \arg CTC_INT_TOUCH_RELEASE_CH1: Channel x release interrupt.
+ * \arg CTC_INT_TOUCH_RELEASE_CH0: Channel x release interrupt.
+ * \arg CTC_INT_TOUCH_PRESS_CH1: Channel x press interrupt.
+ * \arg CTC_INT_TOUCH_PRESS_CH0: Channel x press interrupt.
+ * @param NewState: New state of the Cap Touch interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void CTC_INTConfig(uint32_t CTC_INT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_CTC_INT(CTC_INT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected GPIO pin interrupts */
+ CTC->INT_EN |= CTC_INT;
+ }
+ else
+ {
+ /* Disable the selected GPIO pin interrupts */
+ CTC->INT_EN &= ~CTC_INT;
+ }
+}
+
+/**
+ * @brief Enables or disables the specified Cap Touch peripheral.
+ * @param CTCx: Cap Touch peripheral.
+ * @param NewState: New state of the Cap Touch peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retutn None.
+ */
+void CTC_Cmd(CTC_TypeDef *CTCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_CTC_ALL_PERIPH(CTCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the Cap Touch */
+ CTCx->CR |= CTC_BASELINE_INI_Msk | CTC_CT_EN_Msk;
+ }
+ else
+ {
+ /* Disable the Cap Touch */
+ CTCx->CR &= CTC_CT_EN_Clr;
+ CTCx->CR &= CTC_BASELINE_INI_CLR;
+ }
+}
+
+/**
+ * @brief Enable or disable system wake up of CTC.
+ * @param NewState: new state of the wake up function.
+ * This parameter can be: ENABLE or DISABLE.
+ * @return None
+ */
+void CTC_SystemWakeupConfig(E_CTC_CH channel, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState == ENABLE)
+ {
+ /* Enable system wake up */
+ if (channel == CTC_CH0)
+ {
+ CTC_WK_EN_REG |= BIT16;
+ }
+ else
+ {
+ CTC_WK_EN_REG_1 |= BIT(channel);
+ }
+ }
+ else
+ {
+ /* Disable system wake up */
+ if (channel == CTC_CH0)
+ {
+ CTC_WK_EN_REG &= ~BIT16;
+ }
+ else
+ {
+ CTC_WK_EN_REG_1 &= ~BIT(channel);
+ }
+ }
+}
+
+/**
+ * @brief Check the fast mode scan interval param to be set is in available range.
+ * @param fast_scan_interval: fast scan interval in units of ms.
+ * @retval "TRUE" for in available range; "FALSE" for out of available range.
+ */
+bool CTC_CheckFastScanIntervalGuardTime(uint8_t fast_scan_interval)
+{
+ uint8_t adv_guard_interval = CTC->GUARD_CNT & 0x3FF;
+ uint8_t dly_guard_interval = (CTC->GUARD_CNT >> 16) & 0x3FF;
+ return (fast_scan_interval * 125 > ((adv_guard_interval + dly_guard_interval + 2)) * 4);
+}
+
+/**
+ * @brief Set CTC scan interval for slow mode or fast mode.
+ * @param scan_interval: scan interval in units of 1s/1.024KHz (= 0.9765625 ms)
+ * Configurable range: 0x0~0xFFF (0~4095)
+ * @param CTCMode: CTC_SLOW_MODE or CTC_FAST_MODE.
+ * @retval true: success, false: interval is out of range.
+ * @note Note that slow mode interval should not be lower then fast mode interval,
+ * Fast mode interval should be greater than total guard time for AUXADC.
+ */
+bool CTC_SetScanInterval(uint16_t scan_interval, E_CTC_MODE CTC_Mode)
+{
+ /* Check the parameters */
+ assert_param(interval <= 4095);
+ assert_param(IS_CTC_MODE(CTC_Mode));
+
+ if (CTC_Mode == CTC_SLOW_MODE)
+ {
+ CTC->SCAN_PERIOD |= scan_interval & 0xFFF;
+ }
+ else
+ {
+// if (CTC_CheckFastScanIntervalGuardTime(scan_interval))
+// {
+// return false;
+// }
+ CTC_FAST->SCAN_INI |= scan_interval & 0xFFF;
+ }
+
+ if (((CTC->SCAN_PERIOD & 0xFFF) < (CTC_FAST->SCAN_INI & 0xFFF)))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * @brief Get touch active count from specified channel under fast mode.
+ * @param channel: specified channel
+ * @retval touch active count
+ */
+uint16_t CTC_GetChannelTouchCount(E_CTC_CH channel)
+{
+ /* Set strobe signal for the Touch active count value. */
+ CTC_FAST->SCAN_INI |= BIT(24);
+ platform_delay_us(2);
+
+ FS_TOUCH_CNT_TYPE fs_touch_cnt = {0};
+
+ /* Read touch active count */
+ fs_touch_cnt.fs_touch_cnt_01.d32 = CTC_FAST->TOUCH_CNT01;
+
+ /* Return touch active count of specified channel(10 bit) */
+ return (fs_touch_cnt.d16[channel] & 0x3FF);
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/mcu/peripheral/rtl876x_codec.c b/src/mcu/peripheral/rtl876x_codec.c
new file mode 100644
index 0000000..494e5b9
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_codec.c
@@ -0,0 +1,329 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_codec.c
+* @brief This file provides all the CODEC firmware functions.
+* @details
+* @author Yuan
+* @date 2020-11-16
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_rcc.h"
+#include "rtl876x_codec.h"
+//#include "rtl876x_pinmux.h"
+#include "platform_utils.h"
+
+/**
+ * @brief Initialize the CODEC analog registers in AON area.
+ * @param None.
+ * @retval None
+ */
+void CODEC_AnalogCircuitInit(void)
+{
+ uint16_t reg_value = 0;
+
+ /* Enable ADC 1V1 power cut */
+ reg_value = btaon_fast_read_safe(0x110);
+ btaon_fast_write(0x110, reg_value | 0x01);
+}
+
+/**
+ * @brief Deinitialize the CODEC analog registers in AON area.
+ * @param None.
+ * @retval None
+ */
+void CODEC_AnalogCircuitDeInit(void)
+{
+ uint16_t reg_value = 0;
+
+ /* Disable 1V1 power cut */
+ reg_value = btaon_fast_read_safe(0x110);
+ btaon_fast_write(0x110, reg_value & (~0x01));
+}
+
+/**
+ * @brief Deinitializes the CODEC peripheral registers to their default reset values(turn off CODEC clock).
+ * @param CODECx: selected CODEC peripheral.
+ * @retval None
+ */
+void CODEC_DeInit(CODEC_TypeDef *CODECx)
+{
+ /* Check the parameters */
+ assert_param(IS_CODEC_PERIPH(CODECx));
+
+ CODECx->ADC0_CTRL1 &= ~0x7F;
+
+ platform_delay_ms(30);
+
+ CODECx->ADC0_CTRL0 |= CODEC_ADC_CH0_AD_MUTE_MSK;
+
+ CODECx->CLK_CR1 &= ~0x3FFF;
+
+ CODECx->I2S_CTRL &= ~BIT0;
+
+ CODECx->CR0 &= ~BIT0;
+
+ if (CODEC->ADC0_CTRL0 & CODEC_AMIC_DMIC_CH0_SEL_MSK)
+ {
+ CODEC_ANA->ANA_CR0 &= CODEC_ADC_ANA_POW_CLR;
+ CODEC_ANA->ANA_CR1 &= ~0x3000000;
+ CODEC_ANA->ANA_CR1 &= ~BIT15;
+ CODEC_ANA->ANA_CR1 &= ~BIT10;
+ CODECx->ANA_CR1 &= ~BIT3;
+ CODEC_ANA->ANA_CR0 &= CODEC_DAC_ADDACK_POW_CLR;
+ }
+ else
+ {
+ CODEC_ANA->ANA_CR1 &= ~BIT15;
+ CODEC_ANA->ANA_CR1 &= ~BIT10;
+ CODECx->ANA_CR1 &= ~BIT3;
+ CODECx->CLK_CR2 &= ~BIT3;
+ }
+
+ RCC_PeriphClockCmd(APBPeriph_CODEC, APBPeriph_CODEC_CLOCK, DISABLE);
+ CODEC_AnalogCircuitDeInit();
+}
+
+/**
+ * @brief Initializes the CODEC peripheral according to the specified
+ * parameters in the CODEC_InitStruct
+ * @param CODECx: selected CODEC peripheral.
+ * @param CODEC_InitStruct: pointer to a CODEC_InitTypeDef structure that
+ * contains the configuration information for the specified CODEC peripheral
+ * @retval None
+ */
+void CODEC_Init(CODEC_TypeDef *CODECx, CODEC_InitTypeDef *CODEC_InitStruct)
+{
+ /* Check the parameters */
+ /* MIC initialization parameters for input */
+ assert_param(IS_CODEC_PERIPH(CODECx));
+ assert_param(IS_SAMPLE_RATE(CODEC_InitStruct->CODEC_SampleRate));
+ assert_param(IS_CODEC_I2S_DATA_FORMAT(CODEC_InitStruct->CODEC_I2SFormat));
+ assert_param(IS_CODEC_I2S_DATA_WIDTH(CODEC_InitStruct->CODEC_I2SDataWidth));
+ assert_param(IS_MICBIAS_CONFIG(CODEC_InitStruct->CODEC_MicBIAS));
+ assert_param(IS_MICBST_MODE(CODEC_InitStruct->CODEC_MicBstMode));
+ assert_param(IS_MICBST_GAIN(CODEC_InitStruct->CODEC_MicBstGain));
+ assert_param(IS_CODEC_DMIC_CLOCK(CODEC_InitStruct->CODEC_DmicClock));
+ /* MIC channel 0 initialization parameters */
+ assert_param(IS_CODEC_CH0_MIC_MUTE(CODEC_InitStruct->CODEC_Ch0Mute));
+ assert_param(IS_CODEC_CH0_MIC_TYPE(CODEC_InitStruct->CODEC_Ch0MicType));
+ assert_param(IS_DMIC_CH0_LATCH_EDGE(CODEC_InitStruct->CODEC_Ch0DmicDataLatch));
+ assert_param(IS_AD_GAIN(CODEC_InitStruct->CODEC_Ch0AdGain));
+ assert_param(IS_CH0_BOOST_GAIN(CODEC_InitStruct->CODEC_Ch0BoostGain));
+ assert_param(IS_CH0_ADC_ZERO_DET_TIMEOUT(CODEC_InitStruct->CODEC_Ch0ZeroDetTimeout));
+
+ uint16_t reg_value = 0;
+
+ /* Enable ADC 1V8 LDO current limit */
+ reg_value = btaon_fast_read_safe(0x110);
+ btaon_fast_write(0x110, reg_value | BIT3);
+
+ /* Smaller LDO BW for LDO PSRR improvement */
+ reg_value = btaon_fast_read_safe(0x112);
+ btaon_fast_write(0x112, reg_value & (~0x6000));
+
+ /* Enable ADC 1V8 LDO */
+ reg_value = btaon_fast_read_safe(0x110);
+ btaon_fast_write(0x110, reg_value | BIT2);
+
+ /* Delay 30us */
+ platform_delay_us(30);
+
+ /* Power on Vref */
+ CODEC_ANA->ANA_CR1 |= CODEC_MICBST_VREF_POW_MSK;
+
+ /* MICBIAS voltage selection (default 1.8V) */
+ CODEC_ANA->ANA_CR1 &= CODEC_MICBIAS_VSET_CLR;
+// CODEC_ANA->ANA_CR1 |= (3 << CODEC_MICBIAS_VSET_POS);
+ CODEC_ANA->ANA_CR1 |= CODEC_InitStruct->CODEC_MicBIAS;
+
+ /* Enable MICBIAS current limit & OCP */
+ CODEC_ANA->ANA_CR2 |= CODEC_MICBIAS_LIMIT_MSK;
+
+ /* Delay 1.5 ms */
+ platform_delay_us(1500);
+
+ /* Power on MICBIAS & chopper */
+ CODEC_ANA->ANA_CR1 |= CODEC_MICBIAS_POW_MSK;
+ CODEC_ANA->ANA_CR1 |= CODEC_MICBIAS_ENCHX_MSK;
+
+ /* Enable ckx_micbias 312.5KHz */
+ CODECx->ANA_CR1 |= CODEC_CKX_MICBIAS_EN_MSK;
+
+ /* Delay 5 ms */
+ platform_delay_ms(5);
+
+ /* Disable MICBIAS current limit */
+ CODEC_ANA->ANA_CR2 &= CODEC_MICBIAS_LIMIT_CLR;
+
+ /* Disable ADC 1V8 LDO current limit */
+ reg_value = btaon_fast_read_safe(0x110);
+ btaon_fast_write(0x110, reg_value & (~(BIT3)));
+
+ /* Enable Vref RC bypass mode */
+ reg_value = btaon_fast_read_safe(0x110);
+ btaon_fast_write(0x110, reg_value | (BIT5));
+
+ /* Enable audio IP*/
+ CODECx->CR0 |= CODEC_AUDIO_IP_EN_MSK;
+
+ /* Sample Rate selection. */
+ CODECx->CLK_CR3 &= CODEC_SAMPLE_RATE_CLR;
+// CODECx->CLK_CR3 |= 0x5;
+ CODECx->CLK_CR3 |= CODEC_InitStruct->CODEC_SampleRate;
+
+// /* I2S rx data length select to 16bits */
+// CODECx->I2S_CTRL &= CODEC_I2S_RX_DATA_LEN_CLR;
+
+// /* I2S rx data format select to I2S */
+// CODECx->I2S_CTRL &= CODEC_I2S_RX_DATA_FORMAT_CLR;
+
+// /* Enable digital codec */
+// CODECx->I2S_CTRL |= CODEC_AUDIO_RST_N_MSK;
+
+ /* Configure I2S parameters */
+ CODECx->I2S_CTRL = CODEC_InitStruct->CODEC_I2SChSequence | \
+ CODEC_InitStruct->CODEC_I2SDataWidth | \
+ CODEC_InitStruct->CODEC_I2SFormat | \
+ CODEC_AUDIO_RST_N_MSK;
+
+ if (CODEC_InitStruct->CODEC_Ch0MicType == CODEC_CH0_AMIC)
+ {
+ /* Enable AD/DA clock and ADC analog power */
+ CODEC_ANA->ANA_CR0 = CODEC_DAC_ADDACK_POW_MSK | \
+ CODEC_ADC_ANA_POW_MSK | \
+ CODEC_DTSDM_CLK_EN_MSK;
+
+ CODEC_ANA->ANA_CR1 &= ~0x3000000;
+ CODEC_ANA->ANA_CR1 |= CODEC_MICBST_POW_MSK;
+
+ CODEC_ANA->ANA_CR1 &= ~0x30000;
+ CODEC_ANA->ANA_CR1 |= CODEC_InitStruct->CODEC_MicBstGain;
+
+ CODEC_ANA->ANA_CR1 |= CODEC_MICBST_MUTE_MIC_MSK;
+
+ if (CODEC_InitStruct->CODEC_MicBstMode == MICBST_Mode_Single)
+ {
+ CODEC_ANA->ANA_CR1 &= CODEC_MICBST_ENDFL_CLR;
+ reg_value = btaon_fast_read_safe(0x110);
+ btaon_fast_write(0x110, reg_value | (BIT4));
+ }
+ else if (CODEC_InitStruct->CODEC_MicBstMode == MICBST_Mode_Differential)
+ {
+ CODEC_ANA->ANA_CR1 |= CODEC_MICBST_ENDFL_MSK;
+ reg_value = btaon_fast_read_safe(0x110);
+ btaon_fast_write(0x110, reg_value & (~BIT4));
+ }
+ CODECx->ADC0_CTRL0 |= CODEC_AMIC_DMIC_CH0_SEL_MSK;
+// CODECx->ADC0_CTRL0 |= CODEC_ADC_CH0_AD_MUTE_MSK;
+ }
+ else if (CODEC_InitStruct->CODEC_Ch0MicType == CODEC_CH0_DMIC)
+ {
+ CODECx->CLK_CR2 = CODEC_DMIC1_CLK_EN_MSK | \
+ CODEC_InitStruct->CODEC_DmicClock;
+ CODECx->ADC0_CTRL0 &= CODEC_AMIC_DMIC_CH0_SEL_CLR;
+ CODECx->ADC0_CTRL0 &= CODEC_ADC0_DMIC_SRC_SEL_CLR;
+ CODECx->ADC0_CTRL0 |= CODEC_InitStruct->CODEC_Ch0DmicDataLatch;
+// CODECx->ADC0_CTRL0 |= CODEC_ADC_CH0_AD_MUTE_MSK;
+ }
+ CODECx->ADC0_CTRL0 |= CODEC_ADC_CH0_AD_MUTE_MSK;
+
+ /* AD LPF clock 10M(default 5M) */
+ CODECx->CLK_CR3 &= CODEC_AD_LPF_CLK_SEL_CLR;
+
+ /* ADC HPF FC sel */
+ CODECx->ADC0_CTRL0 &= CODEC_ADC0_DCHPF_FC_SEL_CLR;
+
+ /* Enable ADC0 HPF */
+ CODECx->ADC0_CTRL0 |= CODEC_ADC0_DCHPF_EN_MSK;
+
+ /* Configuer mic channel 0 parameters */
+ CODECx->ADC0_CTRL0 &= CODEC_ADC_CH0_BOOST_GAIN_CLR;
+ CODECx->ADC0_CTRL0 &= CODEC_ADC_CH0_ZDET_TOUT_CLR;
+ CODECx->ADC0_CTRL0 |= CODEC_InitStruct->CODEC_Ch0BoostGain | \
+ CODEC_InitStruct->CODEC_Ch0ZeroDetTimeout;
+ CODECx->ADC0_CTRL1 &= ~0x7F;
+ CODECx->ADC0_CTRL1 |= CODEC_InitStruct->CODEC_Ch0AdGain;
+
+ /* Enable codec clock control */
+ CODECx->CLK_CR1 &= ~0x3FFF;
+// CODECx->CLK_CR1 = 0x1C40;
+
+ /* Clock configuration */
+ CODECx->CLK_CR1 = CODEC_AD_ANA_CLK_EN_MSK | \
+ CODEC_AD_FIFO_CLK_EN_MSK;
+ if (CODEC_InitStruct->CODEC_Ch0Mute == CODEC_CH0_UNMUTE)
+ {
+ CODECx->CLK_CR1 |= CODEC_AD_FILTER_CH0_CLK_MSK | \
+ CODEC_AD_CH0_CLK_MSK;
+ platform_delay_ms(60);
+ CODECx->ADC0_CTRL0 &= CODEC_ADC_CH0_AD_MUTE_CLR;
+ }
+}
+
+/**
+ * @brief Fills each CODEC_InitStruct member with its default value.
+ * @param CODEC_InitStruct: pointer to a CODEC_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void CODEC_StructInit(CODEC_InitTypeDef *CODEC_InitStruct)
+{
+ /* Basic parameters section */
+ CODEC_InitStruct->CODEC_SampleRate = SAMPLE_RATE_16KHz;
+ CODEC_InitStruct->CODEC_I2SFormat = CODEC_I2S_DataFormat_I2S;
+ CODEC_InitStruct->CODEC_I2SDataWidth = CODEC_I2S_DataWidth_16Bits;
+ CODEC_InitStruct->CODEC_I2SChSequence = CODEC_I2S_CH_L_L;
+ CODEC_InitStruct->CODEC_MicBIAS = MICBIAS_VOLTAGE_1_8;
+ CODEC_InitStruct->CODEC_MicBstMode = MICBST_Mode_Single;
+ CODEC_InitStruct->CODEC_MicBstGain = MICBST_Gain_0dB;
+ CODEC_InitStruct->CODEC_DmicClock = DMIC_Clock_2500KHz;
+ /* MIC channel 0 initialization parameters section */
+ CODEC_InitStruct->CODEC_Ch0MicType = CODEC_CH0_AMIC;
+ CODEC_InitStruct->CODEC_Ch0BoostGain = Ch0_Boost_Gain_0dB;
+ CODEC_InitStruct->CODEC_Ch0Mute = CODEC_CH0_UNMUTE;
+ CODEC_InitStruct->CODEC_Ch0ZeroDetTimeout = Ch0_ADC_Zero_DetTimeout_1024_32_Sample;
+ CODEC_InitStruct->CODEC_Ch0DmicDataLatch = DMIC_Ch0_Rising_Latch;
+ CODEC_InitStruct->CODEC_Ch0AdGain = 0x2F;
+}
+
+/**
+ * @brief Enable or disable mic_bias output.
+ * @param CODECx: selected CODEC peripheral.
+ * @param NewState: new state of MICBIAS.
+ * This parameter can be: ENABLE or DISABLE.
+ * @return none.
+ */
+void CODEC_MICBIASCmd(CODEC_TypeDef *CODECx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_CODEC_PERIPH(CODECx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState == ENABLE)
+ {
+ if (!(CODEC_ANA->ANA_CR1 & CODEC_MICBIAS_POW_MSK))
+ {
+ /* Analog initialization in AON register */
+ CODEC_AnalogCircuitInit();
+
+ /* MICBIAS power on */
+ CODEC_ANA->ANA_CR1 |= CODEC_MICBIAS_ENCHX_MSK | \
+ CODEC_MICBST_VREF_POW_MSK | \
+ CODEC_MICBIAS_POW_MSK;
+
+ /* Clock enable */
+ CODECx->ANA_CR1 = CODEC_CKX_MICBIAS_EN_MSK;
+ }
+ }
+ else
+ {
+ CODEC_ANA->ANA_CR1 &= CODEC_MICBIAS_POW_CLR;
+ }
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/mcu/peripheral/rtl876x_enh_tim.c b/src/mcu/peripheral/rtl876x_enh_tim.c
new file mode 100644
index 0000000..f59c337
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_enh_tim.c
@@ -0,0 +1,424 @@
+/**
+**********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_enh_tim.c
+* @brief This file provides all the Timer firmware functions.
+* @details
+* @author Yuan
+* @date 2020.09.29
+* @version v1.0.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_rcc.h"
+#include "rtl876x_enh_tim.h"
+
+/* ENHTIM Private Defines */
+#define TIMER_CLK_SOURCE_REG_35C (*((volatile uint32_t *)0x4000035CUL))
+#define TIMER_CLK_SOURCE_REG_360 (*((volatile uint32_t *)0x40000360UL))
+
+/**
+ * @brief Initializes the ENHTIMx peripheral according to
+ * the specified parameters in the ENHTIM_InitStruct.
+ * @param ENHTIMx: where x can be 0 to 1 to select the ENHTIM peripheral.
+ * @param ENHTIM_InitStruct: pointer to a ENHTIM_InitTypeDef structure
+ * that contains the configuration information for the specified ENHTIM peripheral.
+ * @retval None
+ */
+void ENHTIM_Init(ENHTIM_TypeDef *ENHTIMx, ENHTIM_InitTypeDef *ENHTIM_InitStruct)
+{
+ uint32_t enhtim_id = 0;
+ uint32_t temp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+
+ enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0x24;
+
+ ENH_TIM_SHARE->CMD &= ~BIT(enhtim_id);
+ ENH_TIM_SHARE->INT_CMD &= ~BIT(enhtim_id);
+
+ /* Clock source config */
+ if (TIMER_CLK_SOURCE_REG_360 & BIT(10))
+ {
+ TIMER_CLK_SOURCE_REG_360 &= ~(BIT(10));
+ }
+
+ TIMER_CLK_SOURCE_REG_360 |= ((ENHTIM_InitStruct->ENHTIM_ClockDiv & 0x07) << (enhtim_id * 3 + 25));
+
+ if (ENHTIM_InitStruct->ENHTIM_PWMDeadZoneClockSource == ENHTIM_PWM_DZCLKSRCE_32K)
+ {
+ TIMER_CLK_SOURCE_REG_360 |= BIT8;
+ }
+
+ TIMER_CLK_SOURCE_REG_35C |= ((ENHTIM_InitStruct->ENHTIM_ClockSource & 0x01) << (enhtim_id + 1));
+
+ temp = 0;
+ for (uint8_t i = 0; i < 3; i++)
+ {
+ temp |= ((ENHTIM_InitStruct->ENHTIM_LatchCountEn[i] & 0x01) << (i + 10)) \
+ | ((ENHTIM_InitStruct->ENHTIM_LatchCountTrigger[i] & 0x03) << (i * 2 + 4));
+ }
+ ENHTIMx->CR |= temp;
+
+ /*Config latch count2. */
+ temp = 0x3F;
+ if (ENHTIM_InitStruct->ENHTIM_LatchCountEn[2] == ENHTIM_LATCH_COUNT_ENABLE)
+ {
+ /* Clear Latch Count2 thd */
+ ENHTIMx->CR &= ~(0x1F << 23);
+ ENHTIMx->CR |= (ENHTIM_InitStruct->ENHTIM_LatchCount2Thd & 0x1F) << 23;
+
+ /* Config Latch Count2 trigger GPIO pin. */
+ if ((ENHTIM_InitStruct->ENHTIM_LatchTriggerPad >= P1_6) &&
+ (ENHTIM_InitStruct->ENHTIM_LatchTriggerPad <= P3_6))
+ {
+ temp = (ENHTIM_InitStruct->ENHTIM_LatchTriggerPad - 4);
+ }
+ else if ((ENHTIM_InitStruct->ENHTIM_LatchTriggerPad >= P4_0) &&
+ (ENHTIM_InitStruct->ENHTIM_LatchTriggerPad <= P5_2))
+ {
+ temp = (ENHTIM_InitStruct->ENHTIM_LatchTriggerPad - 5);
+ }
+ }
+
+ ENHTIM_LATCH_COUNT_CR &= ~(0x1FF);
+ ENHTIM_LATCH_COUNT_CR |= (ENHTIM_InitStruct->ENHTIM_TimerGPIOTriggerEn << 8) | \
+ (ENHTIM_InitStruct->ENHTIM_BTGPIOTriggerEn << 7) | \
+ ((enhtim_id & 0x01) << 6) | ((temp) & 0x3F);
+
+ /* Config PWM mode. */
+ temp = 0;
+ if ((ENHTIM_InitStruct->ENHTIM_Mode == ENHTIM_MODE_PWM_AUTO) ||
+ (ENHTIM_InitStruct->ENHTIM_Mode == ENHTIM_MODE_PWM_MANUAL))
+ {
+ temp = (ENHTIM_InitStruct->ENHTIM_PWMStartPolarity & 0x04) |
+ (ENHTIM_InitStruct->ENHTIM_PWMOutputEn & 0x08) |
+ ENHTIM_InitStruct->ENHTIM_Mode;
+ ENHTIMx->CR |= temp;
+ temp = 0;
+ ENHTIMx->MAX_CNT = ENHTIM_InitStruct->ENHTIM_MaxCount;
+ }
+
+ if (ENHTIM_InitStruct->ENHTIM_Mode == ENHTIM_MODE_PWM_MANUAL)
+ {
+ ENHTIMx->CCR = ENHTIM_InitStruct->ENHTIM_CCValue;
+ }
+
+ /* Set pwm1 deadzone mode, pwm1_pn based on enhance timer0 */
+ if (ENHTIM_InitStruct->ENHTIM_PWMDeadZoneEn == ENHTIM_PWM_DEADZONE_ENABLE)
+ {
+ if (enhtim_id == 0)
+ {
+ /* Set pwm deadzone time. */
+ ENHTIM_PWM_DEADZONE_CR |= ((ENHTIM_InitStruct->ENHTIM_PWMDeadZoneClockSource & 0x90000) \
+ | ((ENHTIM_InitStruct->ENHTIM_PWMStopStateP << 10) & (BIT10)) \
+ | ((ENHTIM_InitStruct->ENHTIM_PWMStopStateN << 9) & (BIT9)) \
+ | (ENHTIM_InitStruct->ENHTIM_DeadZoneSize & 0xFF) \
+ | BIT12 | BIT17 | BIT18);
+ }
+ }
+ else
+ {
+ if (enhtim_id == 0)
+ {
+ /* Disable pwm1 deadzone mode. */
+ ENHTIM_PWM_DEADZONE_CR &= ~(BIT12 | BIT17 | BIT18);
+ }
+ }
+
+ /* Clear the IT status */
+ ENH_TIM_SHARE->FIFO_SR0 |= BIT(16 + enhtim_id);
+ ENH_TIM_SHARE->FIFO_SR2 |= BIT(16 + enhtim_id * 2);
+ ENH_TIM_SHARE->INT_SR |= BIT(enhtim_id);
+}
+
+/**
+ * @brief Fills each ENHTIM_InitStruct member with its default value.
+ * @param ENHTIM_InitStruct: Pointer to a ENHTIM_InitStruct structure which will be initialized.
+ * @return None.
+ */
+void ENHTIM_StructInit(ENHTIM_InitTypeDef *ENHTIM_InitStruct)
+{
+ ENHTIM_InitStruct->ENHTIM_ClockSource = ENHTIM_DIVIDER_CLOCK;
+ ENHTIM_InitStruct->ENHTIM_ClockDiv = ENHTIM_CLOCK_DIVIDER_1;
+ ENHTIM_InitStruct->ENHTIM_Mode = ENHTIM_MODE_FreeRun;
+ ENHTIM_InitStruct->ENHTIM_PWMOutputEn = ENHTIM_PWM_DISABLE;
+ ENHTIM_InitStruct->ENHTIM_PWMStartPolarity = ENHTIM_PWM_START_WITH_LOW;
+ ENHTIM_InitStruct->ENHTIM_LatchCountEn[0] = ENHTIM_LATCH_COUNT_DISABLE;
+ ENHTIM_InitStruct->ENHTIM_LatchCountTrigger[0] = ENHTIM_LATCH_TRIGGER_RISING_EDGE;
+ ENHTIM_InitStruct->ENHTIM_LatchCountEn[1] = ENHTIM_LATCH_COUNT_DISABLE;
+ ENHTIM_InitStruct->ENHTIM_LatchCountTrigger[1] = ENHTIM_LATCH_TRIGGER_RISING_EDGE;
+ ENHTIM_InitStruct->ENHTIM_LatchCountEn[2] = ENHTIM_LATCH_COUNT_DISABLE;
+ ENHTIM_InitStruct->ENHTIM_LatchCountTrigger[2] = ENHTIM_LATCH_TRIGGER_RISING_EDGE;
+ ENHTIM_InitStruct->ENHTIM_LatchCount2Thd = 3;
+ ENHTIM_InitStruct->ENHTIM_TimerGPIOTriggerEn = DISABLE;
+ ENHTIM_InitStruct->ENHTIM_BTGPIOTriggerEn = DISABLE;
+ ENHTIM_InitStruct->ENHTIM_MaxCount = 0xFFFFFFFE;//range 0x1~0xFFFFFFFE
+ ENHTIM_InitStruct->ENHTIM_CCValue = 0x0;
+
+ ENHTIM_InitStruct->ENHTIM_PWMDeadZoneClockSource = ENHTIM_PWM_DZCLKSRCE_32K;
+ ENHTIM_InitStruct->ENHTIM_PWMDeadZoneEn = ENHTIM_PWM_DEADZONE_DISABLE;
+ ENHTIM_InitStruct->ENHTIM_PWMStopStateP = ENHTIM_PWM_STOP_AT_HIGH;
+ ENHTIM_InitStruct->ENHTIM_PWMStopStateN = ENHTIM_PWM_STOP_AT_LOW;
+ ENHTIM_InitStruct->ENHTIM_DeadZoneSize = 0xFF;/*!< range 0x1 ~ 0xFF */
+}
+
+/**
+ * @brief Enables or disables the specified ENHTIM peripheral.
+ * @param ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * @param NewState: New state of the ENHTIMx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retutn None.
+ */
+void ENHTIM_Cmd(ENHTIM_TypeDef *ENHTIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24;
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the TIM Counter */
+ ENH_TIM_SHARE->CMD |= BIT(enhtim_id);
+ }
+ else
+ {
+ /* Disable the TIM Counter */
+ ENH_TIM_SHARE->CMD &= ~(BIT(enhtim_id));
+ }
+}
+
+/**
+ * @brief Mask or unmask the latch count2 fifo interrupt.
+ * @param ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * @param NewState: New state of the specified ENHTIMx peripheral latch count2 fifo interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None.
+ */
+void ENHTIM_LCFIFOMaskConfig(ENHTIM_TypeDef *ENHTIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24;
+
+ if (NewState != DISABLE)
+ {
+ ENH_TIM_SHARE->INT_CMD |= BIT(24) << enhtim_id;
+ }
+ else
+ {
+ ENH_TIM_SHARE->INT_CMD &= ~(BIT(24) << enhtim_id);
+ }
+}
+
+/**
+ * @brief Enables or disables ENHTIMx interrupt.
+ * @param ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] ENHTIM_INT: Specifies the ENHTIMx interrupt source which to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * \arg ENHTIM_INT_TIM: Enhance Timer interrupt source.
+ * \arg ENHTIM_INT_LATCH_CNT2_FIFO_FULL: Enhance Timer latch count0 interrupt source.
+ * \arg ENHTIM_INT_LATCH_CNT2_FIFO_THD: Enhance Timer latch count2 interrupt source.
+ * @param NewState: New state of the ENHTIMx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @return None.
+ */
+void ENHTIM_INTConfig(ENHTIM_TypeDef *ENHTIMx, uint8_t ENHTIM_INT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+ assert_param(IS_ENHTIM_INT(ENHTIM_INT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24;
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the ENHTIM Interrupt */
+ if (ENHTIM_INT & 0x40)
+ {
+ *((volatile uint32_t *)(&(ENH_TIM_SHARE->LC_INT_CMD0) + (ENHTIM_INT & 0xF))) |= BIT(
+ 24) << enhtim_id;
+ }
+ else
+ {
+ ENH_TIM_SHARE->INT_CMD |= BIT(enhtim_id);
+ }
+ }
+ else
+ {
+ /* Disable the ENHTIM Interrupt */
+ if (ENHTIM_INT & 0x40)
+ {
+ *((volatile uint32_t *)(&(ENH_TIM_SHARE->LC_INT_CMD0) + (ENHTIM_INT & 0xF))) &= ~(BIT(
+ 24) << enhtim_id);;
+ }
+ else
+ {
+ ENH_TIM_SHARE->INT_CMD &= ~BIT(enhtim_id);
+ }
+ }
+}
+
+/**
+ * \brief Read ENHTIMx latch counter2 fifo data.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] length: Latch count2 fifo length, max 4.
+ * \pBuf[out] pBuf: FIFO data out buffer.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * uint8_t length = ENHTIM_GetLatchCount2FIFOLength(ENH_TIM0);
+ * }
+ * \endcode
+ */
+void ENHTIM_ReadLatchCount2FIFO(ENHTIM_TypeDef *ENHTIMx, uint32_t *pBuf, uint8_t length)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+
+ if ((pBuf == 0) || (length > 4))
+ {
+ return;
+ }
+
+ for (uint8_t i = 0; i < length; i++)
+ {
+ pBuf[i] = ENHTIMx->LATCH_CNT2;
+ }
+}
+
+/**
+ * \brief Check whether the ENHTIM latch count2 fifo has data or not.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \return The new state of the specified ENHTIMx peripheral
+ * latch count2 fifo (SET or RESET).
+ */
+ITStatus ENHTIM_GetLCFIFOStatus(ENHTIM_TypeDef *ENHTIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+
+ uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24;
+ ITStatus itstatus = RESET;
+
+ if (ENH_TIM_SHARE->INT_SR & ((BIT(24) << enhtim_id)))
+ {
+ itstatus = SET;
+ }
+
+ return itstatus;
+}
+
+/**
+ * \brief Check whether the ENHTIM latch count2 fifo interrupt has occurred or not.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \return The new state of the specified ENHTIMx peripheral
+ * latch count2 fifo interrupt(SET or RESET).
+ */
+ITStatus ENHTIM_GetLCFIFOMaskStatus(ENHTIM_TypeDef *ENHTIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+
+ uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24;
+ ITStatus itstatus = RESET;
+
+ if (ENH_TIM_SHARE->MASK_INT_SR & ((BIT(24) << enhtim_id)))
+ {
+ itstatus = SET;
+ }
+
+ return itstatus;
+}
+
+/**
+ * \brief Check whether the ENHTIM interrupt has occurred or not.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] ENHTIM_INT: Specifies the ENHTIMx interrupt source which to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * \arg ENHTIM_INT_TIM: Enhance Timer interrupt source.
+ * \arg ENHTIM_INT_LATCH_CNT2_FIFO_FULL: Enhance Timer latch count2 fifo full interrupt source.
+// * \arg ENHTIM_INT_LATCH_CNT2_FIFO_EMPTY: Enhance Timer latch count2 fifo empty interrupt source.
+ * \arg ENHTIM_INT_LATCH_CNT2_FIFO_THD: Enhance Timer latch count2 fifo threshold interrupt source.
+ * \return The new state of the ENHTIM_INT(SET or RESET).
+ */
+ITStatus ENHTIM_GetINTStatus(ENHTIM_TypeDef *ENHTIMx, uint8_t ENHTIM_INT)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+ assert_param(IS_ENHTIM_INT(INT));
+
+ uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24;
+ ITStatus itstatus = RESET;
+
+ if (ENHTIM_INT == ENHTIM_INT_TIM)
+ {
+ itstatus = (ITStatus)((ENH_TIM_SHARE->INT_SR) >> (enhtim_id));
+ }
+ else if (ENHTIM_INT == ENHTIM_INT_LATCH_CNT2_FIFO_FULL)
+ {
+ itstatus = (ITStatus)(((ENH_TIM_SHARE->FIFO_SR2) >> (16 + enhtim_id * 2)) & 0x01);
+ }
+ else if (ENHTIM_INT == ENHTIM_INT_LATCH_CNT2_FIFO_THD)
+ {
+ itstatus = (ITStatus)(((ENH_TIM_SHARE->FIFO_SR0) >> (16 + enhtim_id)) & 0x01);
+ }
+
+ return itstatus;
+}
+
+/**
+ * \brief Clear ENHTIM interrupt.
+ * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral.
+ * \param[in] ENHTIM_INT: Specifies the ENHTIMx interrupt source which to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * \arg ENHTIM_INT_TIM: Enhance Timer interrupt source.
+ * \arg ENHTIM_INT_LATCH_CNT2_FIFO_FULL: Enhance Timer latch count2 fifo full interrupt source.
+ * \arg ENHTIM_INT_LATCH_CNT2_FIFO_THD: Enhance Timer latch count2 fifo threshold interrupt source.
+ * \return None.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ *
+ * void enhance_timer_demo(void)
+ * {
+ * ENHTIM_ClearINTPendingBit(ENH_TIM0, ENHTIM_INT_TIM);
+ * }
+ * \endcode
+ */
+void ENHTIM_ClearINTPendingBit(ENHTIM_TypeDef *ENHTIMx, uint8_t ENHTIM_INT)
+{
+ /* Check the parameters */
+ assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx));
+
+ uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24;
+
+ /* Clear the IT */
+ if (ENHTIM_INT == ENHTIM_INT_TIM)
+ {
+ ENH_TIM_SHARE->INT_SR |= BIT(enhtim_id);
+ }
+ else if (ENHTIM_INT == ENHTIM_INT_LATCH_CNT2_FIFO_FULL)
+ {
+ ENH_TIM_SHARE->FIFO_SR2 |= BIT(16 + enhtim_id * 2);
+ }
+ else if (ENHTIM_INT == ENHTIM_INT_LATCH_CNT2_FIFO_THD)
+ {
+ ENH_TIM_SHARE->FIFO_SR0 |= BIT(16 + enhtim_id);
+ }
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/mcu/peripheral/rtl876x_gdma.c b/src/mcu/peripheral/rtl876x_gdma.c
new file mode 100644
index 0000000..1d8601d
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_gdma.c
@@ -0,0 +1,403 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_gdma.c
+* @brief This file provides all the DMA firmware functions.
+* @details
+* @author Yuan
+* @date 2020-11-09
+* @version v1.0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_rcc.h"
+#include "rtl876x_gdma.h"
+
+/*fifo depth*/
+#define UART_RX_FIFO_DEPTH 32
+#define UART_TX_FIFO_DEPTH 16
+#define SPI_RX_FIFO_DEPTH 36
+#define SPI_TX_FIFO_DEPTH 36
+#define I2C_RX_FIFO_DEPTH 16
+#define I2C_TX_FIFO_DEPTH 24
+
+#define REG_GDMA_TIMER *((volatile uint32_t *)0x40006024UL)
+
+/**
+ * @brief Deinitializes the GDMA registers to their default reset values.
+ * @param None
+ * @return None
+ */
+void GDMA_DeInit(void)
+{
+ /* Disable GDMA block in REG_SOC_FUNC_EN */
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, DISABLE);
+}
+
+/**
+ * @brief Initializes the GDMA Channelx according to the specified
+ * parameters in the GDMA_InitStruct.
+ * @param GDMA_Channelx: where x can be 0 to 3 to select the DMA Channel.
+ * @param GDMA_InitStruct: pointer to a GDMA_InitTypeDef structure that
+ * contains the configuration information for the specified DMA Channel.
+ * @return None
+ */
+void GDMA_Init(GDMA_ChannelTypeDef *GDMA_Channelx, GDMA_InitTypeDef *GDMA_InitStruct)
+{
+ uint32_t temp_bit = 0;
+ uint32_t autoreload_temp;
+ uint32_t llp_temp;
+
+ /* Check the parameters */
+ assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx));
+ assert_param(IS_GDMA_ChannelNum(GDMA_InitStruct->GDMA_ChannelNum));
+ assert_param(IS_GDMA_DIR(GDMA_InitStruct->GDMA_DIR));
+ assert_param(IS_GDMA_SourceInc(GDMA_InitStruct->GDMA_SourceInc));
+ assert_param(IS_GDMA_DestinationInc(GDMA_InitStruct->GDMA_DestinationInc));
+ assert_param(IS_GDMA_DATA_SIZE(GDMA_InitStruct->GDMA_SourceDataSize));
+ assert_param(IS_GDMA_DATA_SIZE(GDMA_InitStruct->GDMA_DestinationDataSize));
+
+ /*------------------configure source and destination address of GDMA---------*/
+ /* program SARx register to set source address */
+ GDMA_Channelx->SAR = GDMA_InitStruct->GDMA_SourceAddr;
+ /* program DARx register to set destination address */
+ GDMA_Channelx->DAR = GDMA_InitStruct->GDMA_DestinationAddr;
+
+ /* Enable GDMA in DmaCfgReg*/
+ GDMA_BASE->DmaCfgReg = 0x01;
+
+ /* read ChEnReg to check channel is busy or not */
+ if (GDMA_BASE->ChEnReg & BIT(GDMA_InitStruct->GDMA_ChannelNum))
+ {
+ //channel is be used
+ //error handle code
+ //while (1);
+ }
+
+ /*--------------------------- GDMA Configuration -----------------*/
+ /* clear pending interrupts of corresponding GDMA channel */
+ temp_bit = BIT(GDMA_InitStruct->GDMA_ChannelNum);
+ GDMA_BASE->CLEAR_TFR |= temp_bit;
+ GDMA_BASE->CLEAR_BLOCK |= temp_bit;
+ GDMA_BASE->CLEAR_DST_TRAN |= temp_bit;
+ GDMA_BASE->CLEAR_SRC_TRAN |= temp_bit;
+ GDMA_BASE->CLEAR_ERR |= temp_bit;
+
+ /* mask pending interrupts of corresponding GDMA channel */
+ temp_bit = BIT(GDMA_InitStruct->GDMA_ChannelNum + 8);
+ GDMA_BASE->MASK_TFR = temp_bit;
+ GDMA_BASE->MASK_BLOCK = temp_bit;
+ GDMA_BASE->MASK_DST_TRAN = temp_bit;
+ GDMA_BASE->MASK_SRC_TRAN = temp_bit;
+ GDMA_BASE->MASK_ERR = temp_bit;
+
+ /*---------------------------- configure CTL register --------------------------------*/
+
+ /* configure low 32 bit of CTL register */
+ GDMA_Channelx->CTL_LOW = BIT(0)
+ | (GDMA_InitStruct->GDMA_DestinationDataSize << 1)
+ | (GDMA_InitStruct->GDMA_SourceDataSize << 4)
+ | (GDMA_InitStruct->GDMA_DestinationInc << 7)
+ | (GDMA_InitStruct->GDMA_SourceInc << 9)
+ | (GDMA_InitStruct->GDMA_DestinationMsize << 11)
+ | (GDMA_InitStruct->GDMA_SourceMsize << 14)
+ | (GDMA_InitStruct->GDMA_DIR << 20);
+ /* configure high 32 bit of CTL register */
+ GDMA_Channelx->CTL_HIGH = GDMA_InitStruct->GDMA_BufferSize;
+
+ /*---------------------------- configure CFG register --------------------------------*/
+
+ switch (GDMA_InitStruct->GDMA_DIR)
+ {
+ case GDMA_DIR_MemoryToMemory:
+ GDMA_Channelx->CFG_LOW = (0x03 << 10);
+ break;
+ case GDMA_DIR_MemoryToPeripheral:
+ GDMA_Channelx->CFG_LOW = BIT11;
+ break;
+ case GDMA_DIR_PeripheralToMemory:
+ GDMA_Channelx->CFG_LOW = BIT10;
+ break;
+ case GDMA_DIR_PeripheralToPeripheral:
+ GDMA_Channelx->CFG_LOW = 0;
+ break;
+ default:
+ GDMA_Channelx->CFG_LOW = 0;
+ break;
+ }
+
+ if (GDMA_InitStruct->GDMA_Multi_Block_En == 1 &&
+ ((GDMA_Channelx == GDMA_Channel0) | (GDMA_Channelx == GDMA_Channel1)))
+ {
+ /* Config multi-block mode */
+ GDMA_Channelx->CFG_LOW &= ~AUTO_RELOAD_SELECTED_BIT;
+ GDMA_Channelx->CTL_LOW &= ~LLP_SELECTED_BIT;
+ autoreload_temp = (GDMA_InitStruct->GDMA_Multi_Block_Mode & AUTO_RELOAD_SELECTED_BIT);
+ llp_temp = (GDMA_InitStruct->GDMA_Multi_Block_Mode & LLP_SELECTED_BIT);
+ if (llp_temp)
+ {
+ GDMA_Channelx->LLP = GDMA_InitStruct->GDMA_Multi_Block_Struct;
+ GDMA_Channelx->CTL_LOW |= llp_temp;
+ }
+ GDMA_Channelx->CFG_LOW |= autoreload_temp;
+ }
+
+ /* Set Vendor register about timer handshake */
+ if ((GDMA_InitStruct->GDMA_DestHandshake == 2) || (GDMA_InitStruct->GDMA_DestHandshake == 3))
+ {
+ REG_GDMA_TIMER |= BIT(GDMA_InitStruct->GDMA_DestHandshake + 20);
+ }
+ else if ((GDMA_InitStruct->GDMA_DestHandshake >= 24) && (GDMA_InitStruct->GDMA_DestHandshake <= 26))
+ {
+ REG_GDMA_TIMER |= BIT(GDMA_InitStruct->GDMA_DestHandshake - 8);
+ }
+ else if ((GDMA_InitStruct->GDMA_DestHandshake >= 29) && (GDMA_InitStruct->GDMA_DestHandshake <= 31))
+ {
+ REG_GDMA_TIMER |= BIT(GDMA_InitStruct->GDMA_DestHandshake - 10);
+ }
+
+ /* configure peripheral parameters and configure source or destination hardware handshaking interface */
+ GDMA_Channelx->CFG_HIGH &= ~(0x03ff << 7);
+
+ GDMA_Channelx->CFG_HIGH |= (((((GDMA_InitStruct->GDMA_SourceHandshake) & 0x10) << 4) \
+ | ((GDMA_InitStruct->GDMA_SourceHandshake) & 0x0f)) << 7);
+ GDMA_Channelx->CFG_HIGH |= (((((GDMA_InitStruct->GDMA_DestHandshake) & 0x10) << 1) \
+ | ((GDMA_InitStruct->GDMA_DestHandshake) & 0x0f)) << 11);
+
+ /* Enable FIFO mode and Flow control mode */
+ GDMA_Channelx->CFG_HIGH &= ~0x03;
+ GDMA_Channelx->CFG_HIGH |= 0x02;
+
+ /* ---------------clear pending interrupts of corresponding GDMA channel------------------ */
+ temp_bit = BIT(GDMA_InitStruct->GDMA_ChannelNum);
+ GDMA_BASE->CLEAR_TFR |= temp_bit;
+ GDMA_BASE->CLEAR_BLOCK |= temp_bit;
+ GDMA_BASE->CLEAR_DST_TRAN |= temp_bit;
+ GDMA_BASE->CLEAR_SRC_TRAN |= temp_bit;
+ GDMA_BASE->CLEAR_ERR |= temp_bit;
+}
+
+/**
+ * @brief Fills each GDMA_InitStruct member with its default value.
+ * @param GDMA_InitStruct : pointer to a GDMA_InitTypeDef structure which will
+ * be initialized.
+ * @return None
+ */
+void GDMA_StructInit(GDMA_InitTypeDef *GDMA_InitStruct)
+{
+ /*-------------- Reset DMA init structure parameters values ------------------*/
+ GDMA_InitStruct->GDMA_ChannelNum = 0;
+ GDMA_InitStruct->GDMA_DIR = GDMA_DIR_PeripheralToMemory;
+ GDMA_InitStruct->GDMA_BufferSize = 200;
+ GDMA_InitStruct->GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct->GDMA_DestinationInc = DMA_DestinationInc_Inc;
+ GDMA_InitStruct->GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct->GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct->GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct->GDMA_DestinationMsize = GDMA_Msize_1;
+ GDMA_InitStruct->GDMA_SourceAddr = 0;
+ GDMA_InitStruct->GDMA_DestinationAddr = 0;
+ GDMA_InitStruct->GDMA_SourceHandshake = 0;
+ GDMA_InitStruct->GDMA_DestHandshake = 0;
+ GDMA_InitStruct->GDMA_ChannelPriority = 0;
+
+ GDMA_InitStruct->GDMA_Multi_Block_En = DISABLE;
+ GDMA_InitStruct->GDMA_Multi_Block_Mode = LLI_TRANSFER;
+}
+
+/**
+ * @brief Enables or disables the specified GDMA Channelx.
+ * @param GDMA_Channelx: x can be 0 to 3 to select the DMA Channel.
+ * @param NewState: new state of the DMA Channelx.
+ * This parameter can be: ENABLE or DISABLE.
+ * @return None
+ */
+void GDMA_Cmd(uint8_t GDMA_ChannelNum, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_GDMA_ChannelNum(GDMA_ChannelNum));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ GDMA_ChannelTypeDef *GDMA_Channelx;
+ GDMA_Channelx = (GDMA_ChannelTypeDef *)DMA_CH_BASE(GDMA_ChannelNum);
+
+ uint8_t bit_need_set_times = 10;
+ uint8_t bit_need_check_times = 50;
+ uint8_t timeout = bit_need_check_times ;
+ uint8_t bit_set_time = 0;
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected DMAy Channelx */
+ GDMA_BASE->ChEnReg |= BIT(GDMA_ChannelNum) | BIT(GDMA_ChannelNum + 8);
+ }
+ else
+ {
+ /*gdma transfor not finished */
+ if (GDMA_BASE->ChEnReg & BIT(GDMA_ChannelNum))
+ /* suspend gdma channel */
+ {
+ GDMA_Channelx->CFG_LOW |= GDMA_SUSPEND_TRANSMISSSION;
+ }
+ /* Disable the selected DMAy Channelx */
+ /* polling fifo empty */
+ while ((GDMA_GetSuspendChannelStatus(GDMA_Channelx) != SET) && --timeout);
+ /*cfg bit0 not set */
+ if (GDMA_GetSuspendChannelStatus(GDMA_Channelx) != SET)
+ {
+ timeout = bit_need_check_times;
+ /*polling cfg[1:2] 10 times set in 100timer check */
+ while (--timeout)
+ {
+ if ((GDMA_Channelx->CFG_LOW & BIT1) && (GDMA_Channelx->CFG_LOW & BIT2))
+ {
+ bit_set_time++;
+ if (bit_set_time >= bit_need_set_times)
+ {
+ break;
+ }
+ }
+ }
+// if (timeout == 0)
+// {
+// /*abort disable dma return fail*/
+// return GDMA_DISABLE_FAIL;
+// }
+ }
+
+ /* Disable the selected DMAy Channelx */
+ GDMA_BASE->ChEnReg = BIT(GDMA_ChannelNum + 8);
+ /* unsuspend dma channel */
+ GDMA_Channelx->CFG_LOW &= ~(GDMA_SUSPEND_TRANSMISSSION);
+ }
+}
+
+/**
+ * @brief Enables or disables the specified DMA Channelx interrupts.
+ * @param GDMA_Channelx: where x can be 0 to 3 to select the GDMA Channel.
+ * @param GDMA_IT: specifies the GDMA interrupts sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg GDMA_INT_Transfer: Transfer complete interrupt unmask
+ * @arg GDMA_INT_Block: Block transfer interrupt unmask
+ * @arg GDMA_INT_SrcTransfer: SourceTransfer interrupt unmask
+ * @arg GDMA_INT_DstTransfer: Destination Transfer interrupt unmask
+ * @arg GDMA_INT_Error: Transfer error interrupt unmask
+ * @param NewState: new state of the specified DMA interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @return None
+ */
+void GDMA_INTConfig(uint8_t GDMA_ChannelNum, uint32_t GDMA_IT, FunctionalState NewState)
+{
+ uint32_t temp_bit = 0;
+
+ /* Check the parameters */
+ assert_param(IS_GDMA_ChannelNum(GDMA_ChannelNum));
+ assert_param(IS_GDMA_CONFIG_IT(GDMA_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected DMA interrupts */
+ temp_bit = BIT(GDMA_ChannelNum) | BIT(GDMA_ChannelNum + 8);
+
+ if (GDMA_IT & GDMA_INT_Transfer)
+ {
+ GDMA_BASE->MASK_TFR |= temp_bit;
+ }
+ if (GDMA_IT & GDMA_INT_Block)
+ {
+ GDMA_BASE->MASK_BLOCK |= temp_bit;
+ }
+ if (GDMA_IT & GDMA_INT_SrcTransfer)
+ {
+ GDMA_BASE->MASK_SRC_TRAN |= temp_bit;
+ }
+ if (GDMA_IT & GDMA_INT_DstTransfer)
+ {
+ GDMA_BASE->MASK_DST_TRAN |= temp_bit;
+ }
+ if (GDMA_IT & GDMA_INT_Error)
+ {
+ GDMA_BASE->MASK_ERR |= temp_bit;
+ }
+ }
+ else
+ {
+ /* Disable the selected DMA interrupts */
+ temp_bit = BIT(GDMA_ChannelNum + 8);
+ if (GDMA_IT & GDMA_INT_Transfer)
+ {
+ GDMA_BASE->MASK_TFR = temp_bit;
+ }
+ if (GDMA_IT & GDMA_INT_Block)
+ {
+ GDMA_BASE->MASK_BLOCK = temp_bit;
+ }
+ if (GDMA_IT & GDMA_INT_SrcTransfer)
+ {
+ GDMA_BASE->MASK_SRC_TRAN = temp_bit;
+ }
+ if (GDMA_IT & GDMA_INT_DstTransfer)
+ {
+ GDMA_BASE->MASK_DST_TRAN = temp_bit;
+ }
+ if (GDMA_IT & GDMA_INT_Error)
+ {
+ GDMA_BASE->MASK_ERR = temp_bit;
+ }
+ }
+}
+
+/**
+ * @brief Enables or disables the specified DMA Channelx interrupts.
+ * @param GDMA_Channelx: where x can be 0 to 3 to select the GDMA Channel.
+ * @param GDMA_IT: specifies the GDMA interrupts sources to be enabled
+ * or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg GDMA_INT_Transfer: clear transfer complete interrupt
+ * @arg GDMA_INT_Block: clear Block transfer interrupt
+ * @arg GDMA_INT_SrcTransfer: clear SourceTransfer interrupt
+ * @arg GDMA_INT_DstTransfer: clear Destination Transfer interrupt
+ * @arg GDMA_INT_Error: clear Transfer error interrupt
+ * @param NewState: new state of the specified DMA interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @return None
+ */
+void GDMA_ClearINTPendingBit(uint8_t GDMA_ChannelNum, uint32_t GDMA_IT)
+{
+ uint32_t temp_bit = 0;
+
+ /* Check the parameters */
+ assert_param(IS_GDMA_ChannelNum(GDMA_ChannelNum));
+ assert_param(IS_GDMA_CONFIG_IT(GDMA_IT));
+
+ /* clear the selected DMA interrupts */
+ //temp_bit = BIT(GDMA_ChannelNum) | BIT(GDMA_ChannelNum + 8);
+ temp_bit = BIT(GDMA_ChannelNum);
+
+ if (GDMA_IT & GDMA_INT_Transfer)
+ {
+ GDMA_BASE->CLEAR_TFR = temp_bit;
+ }
+ if (GDMA_IT & GDMA_INT_Block)
+ {
+ GDMA_BASE->CLEAR_BLOCK = temp_bit;
+ }
+ if (GDMA_IT & GDMA_INT_SrcTransfer)
+ {
+ GDMA_BASE->CLEAR_SRC_TRAN = temp_bit;
+ }
+ if (GDMA_IT & GDMA_INT_DstTransfer)
+ {
+ GDMA_BASE->CLEAR_DST_TRAN = temp_bit;
+ }
+ if (GDMA_IT & GDMA_INT_Error)
+ {
+ GDMA_BASE->CLEAR_ERR = temp_bit;
+ }
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/mcu/peripheral/rtl876x_gpio.c b/src/mcu/peripheral/rtl876x_gpio.c
new file mode 100644
index 0000000..397de42
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_gpio.c
@@ -0,0 +1,311 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_gpio.c
+* @brief This file provides all the GPIO firmware functions.
+* @details
+* @author Yuan
+* @date 2020-10-13
+* @version v1.0.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_rcc.h"
+#include "rtl876x_gpio.h"
+
+#ifdef _IS_ASIC_
+#define GPIO_CLOCK_SOURCE (40000000)
+#define GPIO_CLOCK_SOURCE_KHZ (40000)
+#else
+#define GPIO_CLOCK_SOURCE (20000000)
+#define GPIO_CLOCK_SOURCE_KHZ (20000)
+#endif
+
+/**
+ * @brief Deinitializes the GPIO peripheral registers to their default reset values.
+ * @param None.
+ * @retval None.
+ */
+void GPIO_DeInit(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, DISABLE);
+}
+
+/**
+ * @brief Initializes the GPIO peripheral according to the specified
+ * parameters in the GPIO_InitStruct.
+ * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that
+ * contains the configuration information for the specified GPIO peripheral.
+ * @retval None
+ */
+void GPIO_Init(GPIO_InitTypeDef *GPIO_InitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
+ assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
+ assert_param(IS_GPIOIT_LEVEL_TYPE(GPIO_InitStruct->GPIO_ITTrigger));
+ assert_param(IS_GPIOIT_POLARITY_TYPE(GPIO_InitStruct->GPIO_ITPolarity));
+ assert_param(IS_GPIOIT_DEBOUNCE_TYPE(GPIO_InitStruct->GPIO_ITDebounce));
+
+ /* GPIO configure */
+ if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT)
+ {
+ GPIO->DATADIR |= GPIO_InitStruct->GPIO_Pin;
+
+ if (GPIO_InitStruct->GPIO_ControlMode == GPIO_SOFTWARE_MODE)
+ {
+ /* Config GPIO control software mode */
+ GPIO->DATASRC &= (~GPIO_InitStruct->GPIO_Pin);
+ }
+ else
+ {
+ /* Config GPIO hardware control mode */
+ GPIO->DATASRC |= (GPIO_InitStruct->GPIO_Pin);
+ }
+
+ }
+ else
+ {
+ /*Configure GPIO input mode */
+ GPIO->DATADIR = GPIO->DATADIR & (~GPIO_InitStruct->GPIO_Pin);
+
+ if (GPIO_InitStruct->GPIO_ITCmd == ENABLE)
+ {
+
+ GPIO->INTMASK = ~GPIO_Pin_All;
+
+ /* configure GPIO interrupt trigger type */
+ if (GPIO_InitStruct->GPIO_ITTrigger == GPIO_INT_Trigger_LEVEL)
+ {
+ GPIO->INTTYPE = GPIO->INTTYPE & (~GPIO_InitStruct->GPIO_Pin);
+
+ /* Level-sensitive synchronization enable register */
+ GPIO->LSSYNC |= GPIO_InitStruct->GPIO_Pin;
+ }
+ else if (GPIO_InitStruct->GPIO_ITTrigger == GPIO_INT_Trigger_EDGE)
+ {
+ GPIO->INTTYPE = (GPIO->INTTYPE & (~GPIO_InitStruct->GPIO_Pin))
+ | GPIO_InitStruct->GPIO_Pin;
+ }
+ else
+ {
+ GPIO->INTBOTHEDGE |= GPIO_InitStruct->GPIO_Pin;
+ }
+
+ /* configure Interrupt polarity register */
+ if (GPIO_InitStruct->GPIO_ITPolarity == GPIO_INT_POLARITY_ACTIVE_LOW)
+ {
+ GPIO->INTPOLARITY = GPIO->INTPOLARITY & (~GPIO_InitStruct->GPIO_Pin);
+ }
+ else
+ {
+ GPIO->INTPOLARITY = (GPIO->INTPOLARITY & (~GPIO_InitStruct->GPIO_Pin))
+ | GPIO_InitStruct->GPIO_Pin;
+ }
+ /* Configure Debounce enable register */
+ if (GPIO_InitStruct->GPIO_ITDebounce == GPIO_INT_DEBOUNCE_DISABLE)
+ {
+ GPIO->DEBOUNCE = GPIO->DEBOUNCE & (~GPIO_InitStruct->GPIO_Pin);
+ }
+ else
+ {
+ GPIO->DEBOUNCE = (GPIO->DEBOUNCE & (~GPIO_InitStruct->GPIO_Pin))
+ | GPIO_InitStruct->GPIO_Pin;
+
+#ifdef _IS_ASIC_
+ /* Config debounce time , default debounce DIV is 14*/
+ GPIO_DBCLK_DIV = (((0xd) << 8) | (1 << 12));
+ GPIO_DBCLK_DIV |= ((((GPIO_InitStruct->GPIO_DebounceTime) * (GPIO_CLOCK_SOURCE_KHZ) >>
+ (14)) - 1) & 0xff);
+#else
+ /* Config debounce time , default debounce DIV is 13*/
+ GPIO_DBCLK_DIV = (((0x3) << 10) | (1 << 12));
+ GPIO_DBCLK_DIV |= ((((GPIO_InitStruct->GPIO_DebounceTime) * (GPIO_CLOCK_SOURCE_KHZ) >>
+ (13)) - 1) & 0xff);
+#endif
+ }
+
+ /* Configure Interrupt enable register */
+ //GPIO->INTEN |= GPIO_InitStruct->GPIO_Pin;
+ }
+ }
+}
+
+/**
+ * @brief Fills each GPIO_InitStruct member with its default value.
+ * @param GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void GPIO_StructInit(GPIO_InitTypeDef *GPIO_InitStruct)
+{
+ /* Reset GPIO init structure parameters values */
+ GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All;
+ GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN;
+ GPIO_InitStruct->GPIO_ITCmd = DISABLE;
+ GPIO_InitStruct->GPIO_ITTrigger = GPIO_INT_Trigger_LEVEL;
+ GPIO_InitStruct->GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW;
+ GPIO_InitStruct->GPIO_ITDebounce = GPIO_INT_DEBOUNCE_DISABLE;
+ GPIO_InitStruct->GPIO_ControlMode = GPIO_SOFTWARE_MODE;
+ GPIO_InitStruct->GPIO_DebounceTime = 20; /* ms , can be 1~64 ms */
+}
+
+/**
+ * @brief enable the specified GPIO interrupt.
+ * @param GPIO_Pin_x: where x can be 0 or 31.
+ * @retval None
+ */
+void GPIO_INTConfig(uint32_t GPIO_Pin, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected GPIO pin interrupts */
+ GPIO->INTEN |= GPIO_Pin;
+ }
+ else
+ {
+ /* Disable the selected GPIO pin interrupts */
+ GPIO->INTEN &= ~GPIO_Pin;
+ }
+}
+
+/**
+ * @brief clear the specified GPIO interrupt.
+ * @param GPIO_Pin_x: where x can be 0 or 31.
+ * @retval None
+ */
+void GPIO_ClearINTPendingBit(uint32_t GPIO_Pin)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ GPIO->INTCLR = GPIO_Pin;
+}
+
+/**
+ * @brief mask the specified GPIO interrupt.
+ * @param GPIO_Pin_x: where x can be 0 or 31.
+ * @retval None
+ */
+void GPIO_MaskINTConfig(uint32_t GPIO_Pin, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ GPIO->INTMASK |= GPIO_Pin;
+ }
+ else
+ {
+ GPIO->INTMASK &= ~(GPIO_Pin);
+ }
+}
+
+/**
+ * \brief Get the GPIO_Pin through the given PAD num.
+ * \param[in] Pin_num: Pad num which can be from P0_0 to P5_2, please refer to rtl876x.h "Pin_Number" part.
+ * \return GPIO_Pin for GPIO initialization.
+ */
+uint32_t GPIO_GetPin(uint8_t Pin_num)
+{
+ /* Check the parameters */
+ assert_param(IS_PIN_NUM(Pin_num));
+
+ if (Pin_num <= P3_6)
+ {
+ return BIT(Pin_num);
+ }
+#if (IC_TYPE == IC_TYPE_BEE3)
+ else if (Pin_num == P4_0)
+ {
+ return BIT(13);
+ }
+ else if ((Pin_num <= P4_3) && (Pin_num >= P4_1))
+ {
+ return BIT(Pin_num - 4);
+ }
+ else if ((Pin_num <= P5_2) && (Pin_num >= H_0))
+ {
+ return BIT(Pin_num - 26);
+ }
+#else
+ else if ((Pin_num <= P4_3) && (Pin_num >= P4_0))
+ {
+ return BIT(Pin_num - 4);
+ }
+ else if ((Pin_num == H_0) || (Pin_num == H_1) || (Pin_num == H_2))
+ {
+ return BIT(Pin_num - 11);
+ }
+#endif
+ return 0xFF;
+}
+
+/**
+ * \brief Get GPIOx(x is 0~31) value through the given pad.
+ * \param[in] Pin_num: Pad num which can be from P0_0 to P5_2, please refer to rtl876x.h "Pin_Number" part.
+ * \return GPIOx(x is 0~31) value.
+ */
+uint8_t GPIO_GetNum(uint8_t Pin_num)
+{
+ /* Check the parameters */
+ assert_param(IS_PIN_NUM(Pin_num));
+
+ if (Pin_num <= P3_6)
+ {
+ return (Pin_num);
+ }
+#if (IC_TYPE == IC_TYPE_BEE3)
+ else if (Pin_num == P4_0)
+ {
+ return 13;
+ }
+ else if ((Pin_num <= P4_3) && (Pin_num >= P4_1))
+ {
+ return (Pin_num - 4);
+ }
+ else if ((Pin_num <= P5_2) && (Pin_num >= H_0))
+ {
+ return (Pin_num - 26);
+ }
+#else
+ else if ((Pin_num <= P4_3) && (Pin_num >= P4_0))
+ {
+ return (Pin_num - 4);
+ }
+ else if ((Pin_num == H_0) || (Pin_num == H_1) || (Pin_num == H_2))
+ {
+ return (Pin_num - 11);
+ }
+#endif
+
+ return 0xFF;
+}
+
+/**
+ * \brief Enable GPIO debounce clock.
+ * \param[in] NewState: Disable or enable debounce clock.
+ * \return None.
+ */
+void GPIO_DBClkCmd(FunctionalState NewState)
+{
+ if (NewState != DISABLE)
+ {
+ GPIO_DBCLK_DIV |= BIT12;
+ }
+ else
+ {
+ GPIO_DBCLK_DIV &= ~BIT12;
+ }
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/mcu/peripheral/rtl876x_i2c.c b/src/mcu/peripheral/rtl876x_i2c.c
new file mode 100644
index 0000000..e60effe
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_i2c.c
@@ -0,0 +1,622 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_i2c.c
+* @brief This file provides all the I2C firmware functions.
+* @details
+* @author elliot chen
+* @date 2015-04-29
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_rcc.h"
+#include "rtl876x_i2c.h"
+
+uint32_t I2C_TimeOut = 0xFFFFF;
+
+/**
+ * @brief Initializes the I2Cx peripheral according to the specified
+ * parameters in the I2C_InitStruct.
+ * @param I2Cx: where x can be 0 or 1 to select the I2C peripheral.
+ * @param I2C_InitStruct: pointer to a I2C_InitTypeDef structure that
+ * contains the configuration information for the specified I2C peripheral.
+ * @retval None
+ */
+void I2C_Init(I2C_TypeDef *I2Cx, I2C_InitTypeDef *I2C_InitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_CLOCK_SPEED(I2C_InitStruct->I2C_ClockSpeed));
+
+ volatile uint32_t I2CSrcClk;
+
+ I2CSrcClk = I2C_InitStruct->I2C_Clock;
+ /* Disable I2C device before change configuration */
+ I2Cx->IC_ENABLE &= ~0x0001;
+
+ /* ------------------------------ Initialize I2C device ------------------------------*/
+ if (I2C_DeviveMode_Master == I2C_InitStruct->I2C_DeviveMode)
+ {
+ /*configure I2C device mode which can be selected for master or slave*/
+ I2Cx->IC_CON = I2C_InitStruct->I2C_DeviveMode | (I2C_InitStruct->I2C_AddressMode << 4) | BIT(5);
+
+ /*set target address*/
+ I2Cx->IC_TAR = (I2C_InitStruct->I2C_SlaveAddress & 0x3ff)
+ | (I2C_InitStruct->I2C_AddressMode << 12);
+ /*set SDA hold time in master mode*/
+ I2Cx->IC_SDA_HOLD = 0x01;
+
+ }
+ else
+ {
+ /* set to slave mode */
+ I2Cx->IC_CON = (I2C_InitStruct->I2C_DeviveMode) | (I2C_InitStruct->I2C_AddressMode << 3);
+ /* set Ack in slave mode */
+ I2Cx->IC_ACK_GENERAL_CALL &= I2C_InitStruct->I2C_Ack;
+ /* set slave address */
+ I2Cx->IC_SAR = I2C_InitStruct->I2C_SlaveAddress;
+ /* set SDA hold time in slave mode */
+ I2Cx->IC_SDA_HOLD = 0x08;
+ /* set SDA setup time delay only in slave transmitter mode(greater than 2) ,delay time:[(IC_SDA_SETUP - 1) * (ic_clk_period)]*/
+ I2Cx->IC_SDA_SETUP = 0x02;
+ }
+
+#if 1
+ /*set Tx empty level*/
+ I2Cx->IC_TX_TL = I2C_InitStruct->I2C_TxThresholdLevel;
+ /*set Rx full level*/
+ I2Cx->IC_RX_TL = I2C_InitStruct->I2C_RxThresholdLevel;
+#endif
+
+ /*------------------------------ configure I2C speed ------------------------------*/
+ /*Configure I2C speed in standard mode*/
+ if (I2C_InitStruct->I2C_ClockSpeed <= 100000)
+ {
+ I2Cx->IC_CON |= (0x3 << 1);
+ I2Cx->IC_CON &= 0xfffb;
+ /*configure I2C speed*/
+ I2Cx->IC_SS_SCL_HCNT = 20 + (4000 * (I2CSrcClk / 10000)) / (I2C_InitStruct->I2C_ClockSpeed);
+ I2Cx->IC_SS_SCL_LCNT = 20 + (4700 * (I2CSrcClk / 10000)) / (I2C_InitStruct->I2C_ClockSpeed);
+ }
+ /*Configure I2C speed in fast mode*/
+ else if (I2C_InitStruct->I2C_ClockSpeed <= 400000)
+ {
+
+ I2Cx->IC_CON |= (0x3 << 1);
+ I2Cx->IC_CON &= 0xfffd;
+ if (I2C_InitStruct->I2C_ClockSpeed == 200000)
+ {
+ /*configure I2C speed*/
+ I2Cx->IC_FS_SCL_HCNT = 32 + (600 * (I2CSrcClk / 10000) * 4) / (I2C_InitStruct->I2C_ClockSpeed);
+ I2Cx->IC_FS_SCL_LCNT = (1300 * (I2CSrcClk / 10000) * 4) / (I2C_InitStruct->I2C_ClockSpeed);
+ }
+ else if (I2C_InitStruct->I2C_ClockSpeed == 400000)
+ {
+ /*configure I2C speed*/
+ I2Cx->IC_FS_SCL_HCNT = 8 + (600 * (I2CSrcClk / 10000) * 4) / (I2C_InitStruct->I2C_ClockSpeed);
+ I2Cx->IC_FS_SCL_LCNT = 1 + (1300 * (I2CSrcClk / 10000) * 4) / (I2C_InitStruct->I2C_ClockSpeed);
+ }
+ else
+ {
+ I2Cx->IC_FS_SCL_HCNT = 20 + (600 * (I2CSrcClk / 10000) * 4) / (I2C_InitStruct->I2C_ClockSpeed);
+ I2Cx->IC_FS_SCL_LCNT = (1300 * (I2CSrcClk / 10000) * 4) / (I2C_InitStruct->I2C_ClockSpeed);
+ }
+ }
+ /*Configure I2C speed in high mode*/
+ else
+ {
+ if (I2C_InitStruct->I2C_ClockSpeed > 3400000)
+ {
+ I2C_InitStruct->I2C_ClockSpeed = 3400000;
+ }
+
+ I2Cx->IC_CON |= (0x3 << 1);
+ /*configure I2C speed*/
+ I2Cx->IC_HS_SCL_HCNT = 8 + (60 * (I2CSrcClk / 10000) * 30) / (I2C_InitStruct->I2C_ClockSpeed);
+ I2Cx->IC_HS_SCL_LCNT = 1 + (120 * (I2CSrcClk / 10000) * 30) / (I2C_InitStruct->I2C_ClockSpeed);
+
+ }
+
+ /*Config I2C dma mode*/
+ I2Cx->IC_DMA_CR = ((I2C_InitStruct->I2C_RxDmaEn)\
+ | ((I2C_InitStruct->I2C_TxDmaEn) << 1));
+
+ /*Config I2C waterlevel*/
+ I2Cx->IC_DMA_RDLR = I2C_InitStruct->I2C_RxWaterlevel;
+ I2Cx->IC_DMA_TDLR = I2C_InitStruct->I2C_TxWaterlevel;
+
+ I2Cx->IC_INTR_MASK = 0;
+}
+
+/**
+ * @brief Deinitializes the I2Cx peripheral registers to their default reset values.
+ * @param I2Cx: where x can be 0 or 1 to select the I2C peripheral.
+ * @retval None
+ */
+void I2C_DeInit(I2C_TypeDef *I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /*Disable I2C IP*/
+ if (I2Cx == I2C0)
+ {
+ RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, DISABLE);
+ }
+ else if (I2Cx == I2C1)
+ {
+ RCC_PeriphClockCmd(APBPeriph_I2C1, APBPeriph_I2C1_CLOCK, DISABLE);
+ }
+}
+
+/**
+ * @brief Fills each I2C_InitStruct member with its default value.
+ * @param I2C_InitStruct : pointer to a I2C_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void I2C_StructInit(I2C_InitTypeDef *I2C_InitStruct)
+{
+ I2C_InitStruct->I2C_Clock = 40000000; /* depend on clock divider */
+ I2C_InitStruct->I2C_ClockSpeed = 400000;
+ I2C_InitStruct->I2C_DeviveMode = I2C_DeviveMode_Master; /* Master mode */
+ I2C_InitStruct->I2C_AddressMode = I2C_AddressMode_7BIT; /* 7-bit address mode */
+ I2C_InitStruct->I2C_SlaveAddress = 0;
+ I2C_InitStruct->I2C_Ack = I2C_Ack_Enable;
+ I2C_InitStruct->I2C_TxThresholdLevel = 0x00; /* tx fifo depth: 24 * 8bits */
+ I2C_InitStruct->I2C_RxThresholdLevel = 0x00; /* rx fifo depth: 16 * 8bits */
+ I2C_InitStruct->I2C_TxDmaEn = DISABLE;
+ I2C_InitStruct->I2C_RxDmaEn = DISABLE;
+ I2C_InitStruct->I2C_RxWaterlevel = 1; /* Best to equal GDMA Source MSize */
+ I2C_InitStruct->I2C_TxWaterlevel = 15; /* Best to equal Tx fifo minus
+ GDMA Source MSize */
+}
+
+
+/**
+ * @brief Enables or disables the specified I2C peripheral.
+ * @param I2Cx: where x can be 0 or 1 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_Cmd(I2C_TypeDef *I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C peripheral */
+ I2Cx->IC_ENABLE |= 0x0001;
+ }
+ else
+ {
+ /* Disable the selected I2C peripheral */
+ I2Cx->IC_ENABLE &= ~0x0001;
+ }
+}
+
+
+/**
+ * @brief Checks whether the last I2Cx abort status.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @retval I2C_Status: the status of I2Cx.
+ */
+I2C_Status I2C_CheckAbortStatus(I2C_TypeDef *I2Cx)
+{
+ uint32_t abort_status = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Get abort status */
+ abort_status = I2Cx->IC_TX_ABRT_SOURCE;
+
+ if (abort_status & MS_ALL_ABORT)
+ {
+ /* Clear abort status */
+ I2Cx->IC_CLR_TX_ABRT;
+
+ /* Check abort type */
+ if (abort_status & ABRT_TXDATA_NOACK)
+ {
+ return I2C_ABRT_TXDATA_NOACK;
+ }
+
+ if (abort_status & ABRT_7B_ADDR_NOACK)
+ {
+ return I2C_ABRT_7B_ADDR_NOACK;
+ }
+
+ if (abort_status & ARB_LOST)
+ {
+ return I2C_ARB_LOST;
+ }
+
+ if (abort_status & ABRT_MASTER_DIS)
+ {
+ return I2C_ABRT_MASTER_DIS;
+ }
+
+ if (abort_status & ABRT_10ADDR1_NOACK)
+ {
+ return I2C_ABRT_10ADDR1_NOACK;
+ }
+
+ if (abort_status & ABRT_10ADDR2_NOACK)
+ {
+ return I2C_ABRT_10ADDR2_NOACK;
+ }
+ }
+
+ return I2C_Success;
+}
+
+/**
+ * @brief Send data in master mode through the I2Cx peripheral.
+ * @param I2Cx: where x can be 0 or 1 to select the I2C peripheral.
+ * @param Data: Byte to be transmitted..
+ * @retval None
+ */
+I2C_Status I2C_MasterWrite(I2C_TypeDef *I2Cx, uint8_t *pBuf, uint16_t len)
+{
+ uint16_t cnt = 0;
+ uint32_t time_out = I2C_TimeOut;
+ I2C_Status abort_status = I2C_Success;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Write in the DR register the data to be sent */
+ for (cnt = 0; cnt < len; cnt++)
+ {
+ if (cnt >= len - 1)
+ {
+ /*generate stop signal*/
+ I2Cx->IC_DATA_CMD = (*pBuf++) | (1 << 9);
+ }
+ else
+ {
+ I2Cx->IC_DATA_CMD = *pBuf++;
+ }
+
+ /* wait for flag of I2C_FLAG_TFNF */
+ time_out = I2C_TimeOut;
+ while (((I2Cx->IC_STATUS & (1 << 1)) == 0) && (time_out != 0))
+ {
+ /* Check abort status */
+ abort_status = I2C_CheckAbortStatus(I2Cx);
+ if (abort_status != I2C_Success)
+ {
+ return abort_status;
+ }
+
+ time_out--;
+ if (time_out == 0)
+ {
+ return I2C_ERR_TIMEOUT;
+ }
+ }
+
+ /* Check abort status */
+ abort_status = I2C_CheckAbortStatus(I2Cx);
+ if (abort_status != I2C_Success)
+ {
+ return abort_status;
+ }
+ }
+
+ return abort_status;
+}
+
+/**
+ * @brief Read data in master mode through the I2Cx peripheral.
+ * @param I2Cx: where x can be 0 or 1 to select the I2C peripheral.
+ * @param Data: Byte to be transmitted..
+ * @retval None
+ */
+I2C_Status I2C_MasterRead(I2C_TypeDef *I2Cx, uint8_t *pBuf, uint16_t len)
+{
+ uint16_t cnt = 0;
+ uint32_t reg_value = 0;
+ uint32_t time_out = I2C_TimeOut;
+ I2C_Status abort_status = I2C_Success;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* read in the DR register the data to be sent */
+ for (cnt = 0; cnt < len; cnt++)
+ {
+ if (cnt >= len - 1)
+ {
+ /* generate stop signal */
+ I2Cx->IC_DATA_CMD = (reg_value) | (0x0003 << 8);
+ }
+ else
+ {
+ I2Cx->IC_DATA_CMD = (reg_value) | (0x0001 << 8);
+ }
+
+ /* read data */
+ if (cnt > 0)
+ {
+ /* wait for I2C_FLAG_RFNE flag */
+ time_out = I2C_TimeOut;
+ while (((I2Cx->IC_STATUS & (1 << 3)) == 0) && (time_out != 0))
+ {
+ /* Check abort status */
+ abort_status = I2C_CheckAbortStatus(I2Cx);
+ if (abort_status != I2C_Success)
+ {
+ return abort_status;
+ }
+
+ time_out--;
+ if (time_out == 0)
+ {
+ return I2C_ERR_TIMEOUT;
+ }
+ }
+
+ *pBuf++ = (uint8_t)I2Cx->IC_DATA_CMD;
+ }
+ }
+
+ /* wait for I2C_FLAG_RFNE flag */
+ time_out = I2C_TimeOut;
+ while (((I2Cx->IC_STATUS & (1 << 3)) == 0) && (time_out != 0))
+ {
+ /* Check abort status */
+ abort_status = I2C_CheckAbortStatus(I2Cx);
+ if (abort_status != I2C_Success)
+ {
+ return abort_status;
+ }
+
+ time_out--;
+ if (time_out == 0)
+ {
+ return I2C_ERR_TIMEOUT;
+ }
+ }
+
+ *pBuf = (uint8_t)I2Cx->IC_DATA_CMD;
+
+ return abort_status;
+}
+
+/**
+ * @brief Sends data and read data in master mode through the I2Cx peripheral.Attention:Read data with time out mechanism.
+ * @param I2Cx: where x can be 0 or 1 to select the I2C peripheral.
+ * @param Data: Byte to be transmitted..
+ * @retval Actual length of read data
+ */
+I2C_Status I2C_RepeatRead(I2C_TypeDef *I2Cx, uint8_t *pWriteBuf, uint16_t Writelen,
+ uint8_t *pReadBuf, uint16_t Readlen)
+{
+ uint16_t cnt = 0;
+ uint32_t reg_value = 0;
+ uint32_t time_out = I2C_TimeOut;
+ I2C_Status abort_status = I2C_Success;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /*------------------------------ write data section ------------------------------*/
+ /* write data in the IC_DATA_CMD register */
+ for (cnt = 0; cnt < Writelen; cnt++)
+ {
+ I2Cx->IC_DATA_CMD = *pWriteBuf++;
+
+ /*wait for I2C_FLAG_TFNF flag that Tx FIFO is not full*/
+ time_out = I2C_TimeOut;
+ while (((I2Cx->IC_STATUS & BIT(1)) == 0) && (time_out != 0))
+ {
+ /* Check abort status */
+ abort_status = I2C_CheckAbortStatus(I2Cx);
+ if (abort_status != I2C_Success)
+ {
+ return abort_status;
+ }
+
+ time_out--;
+ if (time_out == 0)
+ {
+ return I2C_ERR_TIMEOUT;
+ }
+ }
+
+ /* Check abort status */
+ abort_status = I2C_CheckAbortStatus(I2Cx);
+ if (abort_status != I2C_Success)
+ {
+ return abort_status;
+ }
+ }
+
+ /*------------------------------ read data section ------------------------------*/
+ for (cnt = 0; cnt < Readlen; cnt++)
+ {
+ if (cnt >= Readlen - 1)
+ {
+ /*generate stop signal in last byte which to be sent*/
+ I2Cx->IC_DATA_CMD = reg_value | BIT(8) | BIT(9);
+ }
+ else
+ {
+ I2Cx->IC_DATA_CMD = reg_value | BIT(8);
+ }
+
+ /*read data */
+ if (cnt > 0)
+ {
+ /*wait for I2C_FLAG_RFNE flag*/
+ time_out = I2C_TimeOut;
+ while (((I2Cx->IC_STATUS & BIT(3)) == 0) && (time_out != 0))
+ {
+ /* Check abort status */
+ abort_status = I2C_CheckAbortStatus(I2Cx);
+ if (abort_status != I2C_Success)
+ {
+ return abort_status;
+ }
+
+ time_out--;
+ if (time_out == 0)
+ {
+ return I2C_ERR_TIMEOUT;
+ }
+ }
+
+ *pReadBuf++ = (uint8_t)I2Cx->IC_DATA_CMD;
+ }
+ }
+
+ /*read data*/
+ time_out = I2C_TimeOut;
+ while (((I2Cx->IC_STATUS & BIT(3)) == 0) && (time_out != 0))
+ {
+ /* Check abort status */
+ abort_status = I2C_CheckAbortStatus(I2Cx);
+ if (abort_status != I2C_Success)
+ {
+ return abort_status;
+ }
+
+ time_out--;
+ if (time_out == 0)
+ {
+ return I2C_ERR_TIMEOUT;
+ }
+ }
+
+ *pReadBuf = (uint8_t)I2Cx->IC_DATA_CMD;
+
+ return abort_status;
+}
+
+/**
+ * @brief mask the specified I2C interrupt.
+ * @param I2Cx: where x can be 0 or 1
+ * @param I2C_INT
+ * This parameter can be one of the following values:
+ * @arg I2C_INT_GEN_CALL: Set only when a General Call address is received and it is acknowledged.
+ * @arg I2C_INT_START_DET: Indicates whether a START or RESTART condition has occurred on the I2C
+ interface regardless of whether I2C is operating in slave or master mode.
+ * @arg I2C_INT_STOP_DET: Indicates whether a STOP condition has occurred on the I2C interface regardless
+ of whether I2C is operating in slave or master mode
+ * @arg I2C_INT_ACTIVITY: This bit captures I2C activity and stays set until it is cleared.
+ * @arg I2C_INT_RX_DONE: When the I2C is acting as a slave-transmitter, this bit is set to 1 if the
+ master does not acknowledge a transmitted byte. This occurs on the last byte of
+ the transmission, indicating that the transmission is done.
+ * @arg I2C_INT_TX_ABRT: This bit indicates if I2C as an I2C transmitter, is unable to complete the
+ intended actions on the contents of the transmit FIFO.
+ * @arg I2C_INT_RD_REQ: This bit is set to 1 when acting as a slave and another I2C master
+ is attempting to read data.
+ * @arg I2C_INT_TX_EMPTY: This bit is set to 1 when the transmit buffer is at or below the threshold value set
+ in the IC_TX_TL register.
+ * @arg I2C_INT_TX_OVER: Set during transmit if the transmit buffer is filled to IC_TX_BUFFER_DEPTH and
+ the processor attempts to issue another I2C command.
+ * @arg I2C_INT_RX_FULL: Set when the receive buffer reaches or goes above the RX_TL threshold in the
+ IC_RX_TL register
+ * @arg I2C_INT_RX_OVER: Set if the receive buffer is completely filled to IC_RX_BUFFER_DEPTH and an
+ additional byte is received from an external I2C device.
+ * @arg I2C_INT_RX_UNDER: Set if the processor attempts to read the receive buffer when it is empty by reading.
+ * @retval None.
+ */
+void I2C_INTConfig(I2C_TypeDef *I2Cx, uint16_t I2C_INT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(I2C_GET_INT(I2C_INT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C interrupts */
+ I2Cx->IC_INTR_MASK |= I2C_INT;
+ }
+ else
+ {
+ /* Disable the selected I2C interrupts */
+ I2Cx->IC_INTR_MASK &= (uint16_t)~I2C_INT;
+ }
+}
+
+/**
+ * @brief clear the specified I2C interrupt.
+ * @param I2Cx: where x can be 0 or 1
+ * @retval None.
+ */
+void I2C_ClearINTPendingBit(I2C_TypeDef *I2Cx, uint16_t I2C_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(I2C_GET_INT(I2C_IT));
+
+ switch (I2C_IT)
+ {
+ case I2C_INT_RX_UNDER:
+ {
+ I2Cx->IC_CLR_RX_UNDER;
+ break;
+ }
+ case I2C_INT_RX_OVER:
+ {
+ I2Cx->IC_CLR_RX_OVER;
+ break;
+ }
+ case I2C_INT_TX_OVER:
+ {
+ I2Cx->IC_CLR_TX_OVER;
+ break;
+ }
+ case I2C_INT_RD_REQ:
+ {
+ I2Cx->IC_CLR_RD_REQ;
+ break;
+ }
+ case I2C_INT_TX_ABRT:
+ {
+ I2Cx->IC_CLR_TX_ABRT;
+ break;
+ }
+ case I2C_INT_RX_DONE:
+ {
+ I2Cx->IC_CLR_RX_DONE;
+ break;
+ }
+ case I2C_INT_ACTIVITY:
+ {
+ I2Cx->IC_CLR_ACTIVITY;
+ break;
+ }
+ case I2C_INT_STOP_DET:
+ {
+ I2Cx->IC_CLR_STOP_DET;
+ break;
+ }
+ case I2C_INT_START_DET:
+ {
+ I2Cx->IC_CLR_START_DET;
+ break;
+ }
+ case I2C_INT_GEN_CALL:
+ {
+ I2Cx->IC_CLR_GEN_CALL;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/mcu/peripheral/rtl876x_i2s.c b/src/mcu/peripheral/rtl876x_i2s.c
new file mode 100644
index 0000000..48ccf86
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_i2s.c
@@ -0,0 +1,226 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_i2s.c
+* @brief This file provides all the I2S interface firmware functions.
+* @details
+* @author elliot chen
+* @date 2020-11-30
+* @version v1.0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_rcc.h"
+#include "rtl876x_i2s.h"
+
+/**
+ * @brief Initializes the I2S peripheral according to the specified
+ * parameters in the I2S_InitStruct
+ * @param I2S: selected I2S peripheral.
+ * @param I2S_InitStruct: pointer to a I2S_InitTypeDef structure that
+ * contains the configuration information for the specified I2S peripheral
+ * @retval None
+ */
+void I2S_Init(I2S_TypeDef *I2Sx, I2S_InitTypeDef *I2S_InitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_PERIPH(I2Sx));
+ assert_param(IS_I2S_CLK_SOURCE(I2S_InitStruct->I2S_ClockSource));
+ assert_param(IS_I2S_DEVICE_MODE(I2S_InitStruct->I2S_DeviceMode));
+ assert_param(IS_I2S_CHANNEL_TYPE(I2S_InitStruct->I2S_ChannelType));
+ assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat));
+ assert_param(IS_I2S_DATA_WIDTH(I2S_InitStruct->I2S_DataWidth));
+ assert_param(IS_I2S_MCLK_OUTPUT_TYPE(I2S_InitStruct->I2S_MCLKOutput));
+ assert_param(IS_I2S_DMA_CMD(I2S_InitStruct->I2S_DMACmd));
+
+ /* Reset I2S module */
+ I2Sx->CTRL0 |= I2S_RESET_MSK;
+ I2Sx->CTRL0 &= I2S_RESET_CLR;
+
+ /* Configure BCLK parameters */
+ I2Sx->BCLK_DIV = I2S_InitStruct->I2S_BClockMi | (I2S_InitStruct->I2S_BClockNi << I2S_BCLK_NI_POS) |
+ I2S_MI_NI_UPDATE_MSK;
+
+ /* Configure I2S initialization parameters */
+ I2Sx->CTRL0 = I2S_InitStruct->I2S_MCLKOutput | I2S_InitStruct->I2S_TxChSequence | I2S_RX_DISABLE_MSK
+ | \
+ I2S_InitStruct->I2S_RxBitSequence | I2S_InitStruct->I2S_TxBitSequence | \
+ I2S_InitStruct->I2S_RxChSequence | I2S_TX_DISABLE_MSK | \
+ I2S_InitStruct->I2S_DataWidth | I2S_InitStruct->I2S_ChannelType | \
+ I2S_InitStruct->I2S_DataFormat | I2S_InitStruct->I2S_DeviceMode | I2S_InitStruct->I2S_DMACmd;
+
+ /* Configure I2S Clock Source parameters */
+ I2Sx->CTRL1 = I2S_InitStruct->I2S_ClockSource | I2S_CLR_RX_ERR_CNT_MSK | \
+ I2S_CLR_TX_ERR_CNT_MSK | I2S_FRAME_SYNC_OFFSET_DEFAULT;
+ /* Clear error counter */
+ I2Sx->CTRL1 &= I2S_CLR_RX_ERR_CNT_CLR & I2S_CLR_TX_ERR_CNT_CLR;
+
+ /* Configure GDMA burst size */
+ I2Sx->DMA_TRDLR = (I2S_InitStruct->I2S_RxWaterlevel << I2S_RX_DMA_BURST_SIZE_POS) | \
+ (I2S_InitStruct->I2S_TxWaterlevel << I2S_TX_DMA_BURST_SIZE_POS);
+}
+
+/**
+ * @brief Deinitializes the I2S peripheral registers to their default values.
+ * @param None.
+ * @retval None
+ */
+void I2S_DeInit(I2S_TypeDef *I2Sx)
+{
+ if (I2Sx == I2S0)
+ {
+ RCC_PeriphClockCmd(APBPeriph_I2S0, APBPeriph_I2S0_CLOCK, DISABLE);
+ }
+}
+
+/**
+ * @brief Fills each I2S_InitStruct member with its default value.
+ * @param I2S_InitStruct: pointer to an I2S_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void I2S_StructInit(I2S_InitTypeDef *I2S_InitStruct)
+{
+ I2S_InitStruct->I2S_ClockSource = I2S_CLK_40M;
+ I2S_InitStruct->I2S_BClockMi = 0x271;/* <!BCLK = 16K */
+ I2S_InitStruct->I2S_BClockNi = 0x10;
+ I2S_InitStruct->I2S_DeviceMode = I2S_DeviceMode_Master;
+ I2S_InitStruct->I2S_ChannelType = I2S_Channel_Mono;
+ I2S_InitStruct->I2S_TxChSequence = I2S_TX_CH_L_R;
+ I2S_InitStruct->I2S_RxChSequence = I2S_RX_CH_L_R;
+ I2S_InitStruct->I2S_DataFormat = I2S_Mode;
+ I2S_InitStruct->I2S_TxBitSequence = I2S_TX_MSB_First;
+ I2S_InitStruct->I2S_RxBitSequence = I2S_RX_MSB_First;
+ I2S_InitStruct->I2S_DataWidth = I2S_Width_16Bits;
+ I2S_InitStruct->I2S_MCLKOutput = I2S_MCLK_128fs;
+ I2S_InitStruct->I2S_DMACmd = I2S_DMA_ENABLE;
+ I2S_InitStruct->I2S_TxWaterlevel = 1;
+ I2S_InitStruct->I2S_RxWaterlevel = 1;
+}
+
+/**
+ * @brief Enable or disable the selected I2S mode.
+ * @param I2S: selected I2S peripheral.
+ * @param mode: selected I2S operation mode.
+ * This parameter can be the following values:
+ * @arg I2S_MODE_TX: transmission mode.
+ * @arg I2S_MODE_RX: receiving mode.
+ * @param NewState: new state of the operation mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2S_Cmd(I2S_TypeDef *I2Sx, uint32_t mode, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_PERIPH(I2Sx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState == ENABLE)
+ {
+ if (mode & I2S_MODE_TX)
+ {
+ I2Sx->CTRL0 &= I2S_TX_DISABLE_CLR;
+ }
+
+ if (mode & I2S_MODE_RX)
+ {
+ I2Sx->CTRL0 &= I2S_RX_DISABLE_CLR;
+ }
+ I2Sx->CTRL0 |= mode;
+ }
+ else
+ {
+ if (mode & I2S_MODE_TX)
+ {
+ I2Sx->CTRL0 |= I2S_TX_DISABLE_MSK;
+ }
+
+ if (mode & I2S_MODE_RX)
+ {
+ I2Sx->CTRL0 |= I2S_RX_DISABLE_MSK;
+ }
+ I2Sx->CTRL0 &= ~(mode);
+ }
+}
+
+/**
+ * @brief Enable or disable the specified I2S interrupts.
+ * @param I2S_INT: specifies the I2S interrupts sources to be enable or disable.
+ * This parameter can be the following values:
+ * @arg I2S_INT_TX_IDLE: Transmit idle interrupt.
+ * @arg I2S_INT_RF_EMPTY: Receive FIFO empty interrupt.
+ * @arg I2S_INT_TF_EMPTY: Transmit FIFO empty interrupt.
+ * @arg I2S_INT_RF_FULL: Receive FIFO full interrupt.
+ * @arg I2S_INT_TF_FULL: Transmit FIFO full interrupt.
+ * @arg I2S_INT_RX_READY: Ready to receive interrupt.
+ * @arg I2S_INT_TX_READY: Ready to transmit interrupt.
+ * @param NewState: new state of the specified I2S interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2S_INTConfig(I2S_TypeDef *I2Sx, uint32_t I2S_INT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_INT_CONFIG(I2S_INT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState == ENABLE)
+ {
+ I2Sx->CTRL1 |= I2S_INT;
+ }
+ else
+ {
+ I2Sx->CTRL1 &= ~(I2S_INT);
+ }
+}
+
+/**
+ * @brief Get the specified I2S flag status.
+ * @param I2S_INT: the specified I2S interrupt.
+ * This parameter can be one of the following values:
+ * This parameter can be the following values:
+ * @arg I2S_INT_TX_IDLE: Transmit idle interrupt.
+ * @arg I2S_INT_RF_EMPTY: Receive FIFO empty interrupt.
+ * @arg I2S_INT_TF_EMPTY: Transmit FIFO empty interrupt.
+ * @arg I2S_INT_RF_FULL: Receive FIFO full interrupt.
+ * @arg I2S_INT_TF_FULL: Transmit FIFO full interrupt.
+ * @arg I2S_INT_RX_READY: Ready to receive interrupt.
+ * @arg I2S_INT_TX_READY: Ready to transmit interrupt.
+ * @retval The new state of LCD_FLAG (SET or RESET).
+ */
+ITStatus I2S_GetINTStatus(I2S_TypeDef *I2Sx, uint32_t I2S_INT)
+{
+ ITStatus bit_status = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_I2S_INT_CONFIG(I2S_INT));
+
+ if (I2Sx->SR & (I2S_INT >> I2S_READY_TO_TX_POS))
+ {
+ bit_status = SET;
+ }
+
+ /* Return the I2S_INT status */
+ return bit_status;
+}
+
+/**
+ * @brief Clears the I2S interrupt pending bits.
+ * @param I2S_CLEAR_INT: specifies the interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg I2S_CLEAR_INT_RX_READY: Clear ready to receive interrupt.
+ * @arg I2S_CLEAR_INT_TX_READY: Clear ready to transmit interrupt.
+ * @retval None
+ */
+void I2S_ClearINTPendingBit(I2S_TypeDef *I2Sx, uint32_t I2S_CLEAR_INT)
+{
+ /* Check the parameters */
+ assert_param(IS_I2S_INT_CONFIG(I2S_CLEAR_INT));
+
+ I2Sx->DSP_INT_CR |= I2S_CLEAR_INT;
+ I2Sx->DSP_INT_CR &= ~I2S_CLEAR_INT;
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/mcu/peripheral/rtl876x_io_dlps.c b/src/mcu/peripheral/rtl876x_io_dlps.c
new file mode 100644
index 0000000..b768e6c
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_io_dlps.c
@@ -0,0 +1,1627 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_io_dlps.c
+* @brief This file provides all the IO DLPS control firmware functions.
+* @details
+* @author
+* @date 2020-06-02
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#include <stddef.h>
+#include "rtl876x_io_dlps.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "app_section.h"
+#include "board.h"
+#include "dlps.h"
+#include "otp.h"
+#include "platform_autoconf.h"
+#include "trace.h"
+
+/*============================================================================*
+ * IO DLPS
+ *============================================================================*/
+
+/********************************************** ********************************************************/
+/**************************************** [PINMUX DLPS] **************************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+
+__STATIC_INLINE void Pinmux_DLPS_Enter(void);
+__STATIC_INLINE void Pinmux_DLPS_Exit(void);
+
+volatile uint32_t
+Pinmux_StoreReg[10]; /* This array should be placed in RAM ON/Buffer ON. */
+
+/**
+ * @brief PINMUX enter dlps callback function(Save PINMUX register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void Pinmux_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void Pinmux_DLPS_Enter(void)
+{
+ uint8_t i = 0;
+
+ for (i = 0; i < 10; i++)
+ {
+ Pinmux_StoreReg[i] = PINMUX->CFG[i];
+ }
+
+ return;
+}
+
+/**
+ * @brief PINMUX exit dlps callback function(Resume PINMUX register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void Pinmux_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void Pinmux_DLPS_Exit(void)
+{
+ uint8_t i;
+
+ for (i = 0; i < 10; i++)
+ {
+ PINMUX->CFG[i] = Pinmux_StoreReg[i];
+ }
+
+ return;
+}
+
+/********************************************** ********************************************************/
+/**************************************** [ADC DLPS] **************************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+
+#if USE_ADC_DLPS
+__STATIC_INLINE void ADC_DLPS_Enter(void);
+__STATIC_INLINE void ADC_DLPS_Exit(void);
+
+volatile uint32_t
+ADC_StoreReg[15]; /* This array should be placed in RAM ON/Buffer ON. */
+
+/**
+ * @brief ADC enter dlps callback function(Save ADC register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void ADC_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void ADC_DLPS_Enter(void)
+{
+ /*Open 10M clock source*/
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26;
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT28;
+
+ PERIPH->PERI_FUNC1_EN |= (1 << 0);
+ PERIPH->PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_ADC_EN_Msk | SYSBLK_SLPCK_ADC_EN_Msk);
+
+ ADC_StoreReg[0] = ADC->CR; //0x04
+ ADC_StoreReg[1] = ADC->SCHCR; //0x08
+ ADC_StoreReg[2] = ADC->INTCR; //0x0C
+ ADC_StoreReg[3] = ADC->SCHTAB0; //0x10
+ ADC_StoreReg[4] = ADC->SCHTAB1; //0x14
+ ADC_StoreReg[5] = ADC->SCHTAB2; //0x18
+ ADC_StoreReg[6] = ADC->SCHTAB3; //0x1C
+ ADC_StoreReg[7] = ADC->SCHTAB4; //0x20
+ ADC_StoreReg[8] = ADC->SCHTAB5; //0x24
+ ADC_StoreReg[9] = ADC->SCHTAB6; //0x28
+ ADC_StoreReg[10] = ADC->SCHTAB7; //0x2C
+ ADC_StoreReg[11] = ADC->PWRDLY;
+ ADC_StoreReg[12] = ADC->DATCLK;
+ ADC_StoreReg[13] = ADC->ANACTL;
+ ADC_StoreReg[14] = ADC->SAMTIM;
+
+ uint8_t reg_value = 0;
+ reg_value = btaon_fast_read_safe(0x110);
+ btaon_fast_write(0x110, reg_value & (~0x04));
+
+ return;
+}
+
+/**
+ * @brief ADC exit dlps callback function(Resume ADC register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void ADC_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void ADC_DLPS_Exit(void)
+{
+ /*Open 10M clock source*/
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26;
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT28;
+
+ PERIPH->PERI_FUNC1_EN |= (1 << 0);
+ PERIPH->PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_ADC_EN_Msk | SYSBLK_SLPCK_ADC_EN_Msk);
+
+#if 0
+ //Todo
+ ADC->PWRDLY = ADC_StoreReg[10];
+ ADC->CR = (ADC_StoreReg[0] & (~((uint32_t)0x03)));
+ ADC->SCHTAB0 = ADC_StoreReg[3];
+ ADC->SCHTAB1 = ADC_StoreReg[4];
+ ADC->SCHTAB2 = ADC_StoreReg[5];
+ ADC->SCHTAB3 = ADC_StoreReg[6];
+ ADC->SCHTAB4 = ADC_StoreReg[7];
+ ADC->SCHTAB5 = ADC_StoreReg[8];
+ ADC->SCHTAB6 = ADC_StoreReg[9];
+ ADC->SCHCR = ADC_StoreReg[1];
+ ADC->INTCR = (ADC_StoreReg[2] & 0x1F);
+#else
+ /*Disable all interrupt.*/
+ ADC->INTCR &= (~0x1f);
+
+ /* Set power mode first */
+ ADC->PWRDLY = ADC_StoreReg[11];
+
+ /* Disable schedule table */
+ ADC->SCHCR &= (~0xffff);
+
+ ADC->SCHTAB0 = ADC_StoreReg[3];
+ ADC->SCHTAB1 = ADC_StoreReg[4];
+ ADC->SCHTAB2 = ADC_StoreReg[5];
+ ADC->SCHTAB3 = ADC_StoreReg[6];
+ ADC->SCHTAB4 = ADC_StoreReg[7];
+ ADC->SCHTAB5 = ADC_StoreReg[8];
+ ADC->SCHTAB6 = ADC_StoreReg[9];
+ ADC->SCHTAB7 = ADC_StoreReg[10];
+ ADC->SCHCR = ADC_StoreReg[1];
+ ADC->CR = (ADC_StoreReg[0] & (~((uint32_t)0x03)));
+ ADC->DATCLK = ADC_StoreReg[12];
+ ADC->ANACTL = ADC_StoreReg[13];
+ ADC->SAMTIM = ADC_StoreReg[14];
+
+ /*Clear ADC FIFO */
+ ADC->CR |= BIT26;
+ /* Clear all interrupt */
+ ADC->INTCR |= (0x1f << 8);
+
+ /* Restore specify interrupt */
+ ADC->INTCR = ADC_StoreReg[2];
+
+#endif
+
+ uint8_t reg_value = 0;
+ reg_value = btaon_fast_read_safe(0x110);
+ btaon_fast_write(0x110, reg_value | 0x04);
+
+ return;
+}
+
+#endif
+
+/********************************************** ********************************************************/
+/**************************************** [CODEC DLPS] ************************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+#if USE_CODEC_DLPS
+
+volatile uint32_t CODEC_StoreReg[12];
+
+/**
+ * @brief CODEC enter dlps callback function(Save CODEC register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void CODEC_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void CODEC_DLPS_Enter(void)
+{
+ /* Enable codec function and clock */
+ PERIPH->PERI_BD_FUNC0_EN |= (1 << 0) | (1 << 4);
+
+ CODEC_StoreReg[0] = CODEC->CR0;
+ CODEC_StoreReg[1] = CODEC->ADC0_CTRL0;
+ CODEC_StoreReg[2] = CODEC->ADC0_CTRL1;
+ CODEC_StoreReg[3] = CODEC->ANA_CR1;
+ CODEC_StoreReg[4] = CODEC->CLK_CR1;
+ CODEC_StoreReg[5] = CODEC->CLK_CR2;
+ CODEC_StoreReg[6] = CODEC->CLK_CR3;
+ CODEC_StoreReg[7] = CODEC->I2S_CTRL;
+ CODEC_StoreReg[8] = CODEC_ANA->ANA_CR0;
+ CODEC_StoreReg[9] = CODEC_ANA->ANA_CR1;
+ CODEC_StoreReg[10] = CODEC_ANA->ANA_CR2;
+}
+
+/**
+ * @brief CODEC exit dlps callback function(Resume CODEC register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void CODEC_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void CODEC_DLPS_Exit(void)
+{
+ /* Enable codec function and clock */
+ PERIPH->PERI_BD_FUNC0_EN |= (1 << 0) | (1 << 4);
+
+ /* Initialize CODEC */
+ if ((CODEC_StoreReg[3] & 0x900) == 0x900)
+ {
+ /* Configure AMIC parameters */
+ CODEC->CR0 = CODEC_StoreReg[0];
+ }
+
+ CODEC->ADC0_CTRL0 = CODEC_StoreReg[1];
+ CODEC->ADC0_CTRL1 = CODEC_StoreReg[2];
+ CODEC->ANA_CR1 = CODEC_StoreReg[3];
+ CODEC->CLK_CR1 = CODEC_StoreReg[4];
+ CODEC->CLK_CR2 = CODEC_StoreReg[5];
+ CODEC->CLK_CR3 = CODEC_StoreReg[6];
+ CODEC->I2S_CTRL = CODEC_StoreReg[7];
+ CODEC_ANA->ANA_CR0 = CODEC_StoreReg[8];
+ CODEC_ANA->ANA_CR1 = CODEC_StoreReg[9];
+ CODEC_ANA->ANA_CR2 = CODEC_StoreReg[10];
+}
+#endif
+
+/********************************************** ********************************************************/
+/**************************************** [GPIO DLPS] **************************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+#if USE_GPIO_DLPS
+
+__STATIC_INLINE void GPIO_DLPS_Enter(void);
+__STATIC_INLINE void GPIO_DLPS_Exit(void);
+
+volatile uint32_t
+GPIO_StoreReg[10]; /* This array should be placed in RAM ON/Buffer ON. */
+
+/**
+ * @brief GPIO enter dlps callback function(Save GPIO register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void GPIO_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void GPIO_DLPS_Enter(void)
+{
+ PERIPH->PERI_FUNC1_EN |= BIT_PERI_GPIO_EN;
+ PERIPH->PERI_CLK_CTRL |= (BIT_SOC_ACTCK_GPIO_EN | SYSBLK_SLPCK_GPIO_EN_Msk);
+
+ GPIO_StoreReg[0] = GPIO->DATAOUT;
+ GPIO_StoreReg[1] = GPIO->DATADIR;
+ GPIO_StoreReg[2] = GPIO->DATASRC;
+ GPIO_StoreReg[3] = GPIO->INTEN;
+ GPIO_StoreReg[4] = GPIO->INTMASK;
+ GPIO_StoreReg[5] = GPIO->INTTYPE;
+ GPIO_StoreReg[6] = GPIO->INTPOLARITY;
+ GPIO_StoreReg[7] = GPIO->DEBOUNCE;
+ GPIO_StoreReg[8] = *(__IO uint32_t *)(0x40000344UL);
+ GPIO_StoreReg[9] = GPIO->INTBOTHEDGE;
+
+ return;
+}
+
+/**
+ * @brief GPIO exit dlps callback function(Resume GPIO register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void GPIO_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void GPIO_DLPS_Exit(void)
+{
+ PERIPH->PERI_FUNC1_EN |= BIT_PERI_GPIO_EN;
+ PERIPH->PERI_CLK_CTRL |= (BIT_SOC_ACTCK_GPIO_EN | SYSBLK_SLPCK_GPIO_EN_Msk);
+
+ GPIO->DATADIR = GPIO_StoreReg[1];
+ GPIO->DATASRC = GPIO_StoreReg[2];
+ GPIO->INTMASK = GPIO_StoreReg[4];
+ GPIO->INTTYPE = GPIO_StoreReg[5];
+ GPIO->INTPOLARITY = GPIO_StoreReg[6];
+ GPIO->DEBOUNCE = GPIO_StoreReg[7];
+ GPIO->DATAOUT = GPIO_StoreReg[0];
+ GPIO->INTCLR = ~(GPIO_StoreReg[1]);
+ GPIO->INTEN = GPIO_StoreReg[3];
+ *(__IO uint32_t *)(0x40000344UL) = GPIO_StoreReg[8];
+ GPIO->INTBOTHEDGE = GPIO_StoreReg[9];
+
+ return;
+}
+#endif /* USE_GPIO_DLPS */
+
+/********************************************** ********************************************************/
+/**************************************** [I2C0 DLPS] **************************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+#if USE_I2C0_DLPS
+__STATIC_INLINE void I2C0_DLPS_Enter(void);
+__STATIC_INLINE void I2C0_DLPS_Exit(void);
+
+volatile uint32_t
+I2C0_StoreReg[20]; /* This array should be placed in RAM ON/Buffer ON. */
+
+/**
+ * @brief I2C0 enter dlps callback function(Save I2C0 register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void I2C0_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void I2C0_DLPS_Enter(void)
+{
+ PERIPH->PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_I2C0_EN_Msk | SYSBLK_SLPCK_I2C0_EN_Msk);
+ PERIPH->PERI_FUNC0_EN |= SYSBLK_I2C0_EN_Msk;
+
+ I2C0_StoreReg[0] = I2C0->IC_CON;
+ I2C0_StoreReg[1] = I2C0->IC_TAR;
+ I2C0_StoreReg[2] = I2C0->IC_SAR;
+ I2C0_StoreReg[3] = I2C0->IC_HS_MADDR;
+
+ I2C0_StoreReg[4] = I2C0->IC_SS_SCL_HCNT;
+ I2C0_StoreReg[5] = I2C0->IC_SS_SCL_LCNT;
+ I2C0_StoreReg[6] = I2C0->IC_FS_SCL_HCNT;
+ I2C0_StoreReg[7] = I2C0->IC_FS_SCL_LCNT;
+ I2C0_StoreReg[8] = I2C0->IC_HS_SCL_HCNT;
+ I2C0_StoreReg[9] = I2C0->IC_HS_SCL_LCNT;
+
+ I2C0_StoreReg[10] = I2C0->IC_INTR_MASK;
+ I2C0_StoreReg[11] = I2C0->IC_RX_TL;
+ I2C0_StoreReg[12] = I2C0->IC_TX_TL;
+ I2C0_StoreReg[13] = I2C0->IC_ENABLE;
+ I2C0_StoreReg[14] = I2C0->IC_SDA_HOLD;
+ I2C0_StoreReg[15] = I2C0->IC_SLV_DATA_NACK_ONLY;
+ I2C0_StoreReg[16] = I2C0->IC_DMA_CR;
+ I2C0_StoreReg[17] = I2C0->IC_DMA_TDLR;
+ I2C0_StoreReg[18] = I2C0->IC_DMA_RDLR;
+
+ I2C0_StoreReg[19] = I2C0->IC_SDA_SETUP;
+}
+
+/**
+ * @brief I2C0 exit dlps callback function(Resume I2C0 register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void I2C0_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void I2C0_DLPS_Exit(void)
+{
+ PERIPH->PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_I2C0_EN_Msk | SYSBLK_SLPCK_I2C0_EN_Msk);
+ PERIPH->PERI_FUNC0_EN |= SYSBLK_I2C0_EN_Msk;
+
+ I2C0->IC_CON = I2C0_StoreReg[0];
+ I2C0->IC_TAR = I2C0_StoreReg[1];
+ I2C0->IC_SAR = I2C0_StoreReg[2];
+ I2C0->IC_HS_MADDR = I2C0_StoreReg[3];
+
+ I2C0->IC_SS_SCL_HCNT = I2C0_StoreReg[4];
+ I2C0->IC_SS_SCL_LCNT = I2C0_StoreReg[5];
+ I2C0->IC_FS_SCL_HCNT = I2C0_StoreReg[6];
+ I2C0->IC_FS_SCL_LCNT = I2C0_StoreReg[7];
+ I2C0->IC_HS_SCL_HCNT = I2C0_StoreReg[8];
+ I2C0->IC_HS_SCL_LCNT = I2C0_StoreReg[9];
+
+ I2C0->IC_INTR_MASK = I2C0_StoreReg[10];
+ I2C0->IC_RX_TL = I2C0_StoreReg[11];
+ I2C0->IC_TX_TL = I2C0_StoreReg[12];
+ I2C0->IC_SDA_HOLD = I2C0_StoreReg[14];
+ I2C0->IC_SLV_DATA_NACK_ONLY = I2C0_StoreReg[15];
+ I2C0->IC_DMA_CR = I2C0_StoreReg[16];
+ I2C0->IC_DMA_TDLR = I2C0_StoreReg[17];
+ I2C0->IC_DMA_RDLR = I2C0_StoreReg[18];
+ I2C0->IC_SDA_SETUP = I2C0_StoreReg[19];
+
+ I2C0->IC_ENABLE = I2C0_StoreReg[13];
+}
+#endif
+
+/********************************************** ********************************************************/
+/**************************************** [I2C1 DLPS] **************************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+#if USE_I2C1_DLPS
+__STATIC_INLINE void I2C1_DLPS_Enter(void);
+__STATIC_INLINE void I2C1_DLPS_Exit(void);
+
+volatile uint32_t
+I2C1_StoreReg[20]; /* This array should be placed in RAM ON/Buffer ON. */
+
+/**
+ * @brief I2C1 enter dlps callback function(Save I2C1 register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void I2C1_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void I2C1_DLPS_Enter(void)
+{
+ PERIPH->PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_I2C1_EN_Msk | SYSBLK_SLPCK_I2C1_EN_Msk);
+ PERIPH->PERI_FUNC0_EN |= SYSBLK_I2C1_EN_Msk;
+
+ I2C1_StoreReg[0] = I2C1->IC_CON;
+ I2C1_StoreReg[1] = I2C1->IC_TAR;
+ I2C1_StoreReg[2] = I2C1->IC_SAR;
+ I2C1_StoreReg[3] = I2C1->IC_HS_MADDR;
+
+ I2C1_StoreReg[4] = I2C1->IC_SS_SCL_HCNT;
+ I2C1_StoreReg[5] = I2C1->IC_SS_SCL_LCNT;
+ I2C1_StoreReg[6] = I2C1->IC_FS_SCL_HCNT;
+ I2C1_StoreReg[7] = I2C1->IC_FS_SCL_LCNT;
+ I2C1_StoreReg[8] = I2C1->IC_HS_SCL_HCNT;
+ I2C1_StoreReg[9] = I2C1->IC_HS_SCL_LCNT;
+
+ I2C1_StoreReg[10] = I2C1->IC_INTR_MASK;
+ I2C1_StoreReg[11] = I2C1->IC_RX_TL;
+ I2C1_StoreReg[12] = I2C1->IC_TX_TL;
+ I2C1_StoreReg[13] = I2C1->IC_ENABLE;
+ I2C1_StoreReg[14] = I2C1->IC_SDA_HOLD;
+ I2C1_StoreReg[15] = I2C1->IC_SLV_DATA_NACK_ONLY;
+ I2C1_StoreReg[16] = I2C1->IC_DMA_CR;
+ I2C1_StoreReg[17] = I2C1->IC_DMA_TDLR;
+ I2C1_StoreReg[18] = I2C1->IC_DMA_RDLR;
+
+ I2C1_StoreReg[19] = I2C1->IC_SDA_SETUP;
+}
+
+/**
+ * @brief I2C1 exit dlps callback function(Resume I2C1 register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void I2C1_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void I2C1_DLPS_Exit(void)
+{
+ PERIPH->PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_I2C1_EN_Msk | SYSBLK_SLPCK_I2C1_EN_Msk);
+ PERIPH->PERI_FUNC0_EN |= SYSBLK_I2C1_EN_Msk;
+
+ I2C1->IC_CON = I2C1_StoreReg[0];
+ I2C1->IC_TAR = I2C1_StoreReg[1];
+ I2C1->IC_SAR = I2C1_StoreReg[2];
+ I2C1->IC_HS_MADDR = I2C1_StoreReg[3];
+
+ I2C1->IC_SS_SCL_HCNT = I2C1_StoreReg[4];
+ I2C1->IC_SS_SCL_LCNT = I2C1_StoreReg[5];
+ I2C1->IC_FS_SCL_HCNT = I2C1_StoreReg[6];
+ I2C1->IC_FS_SCL_LCNT = I2C1_StoreReg[7];
+ I2C1->IC_HS_SCL_HCNT = I2C1_StoreReg[8];
+ I2C1->IC_HS_SCL_LCNT = I2C1_StoreReg[9];
+
+ I2C1->IC_INTR_MASK = I2C1_StoreReg[10];
+ I2C1->IC_RX_TL = I2C1_StoreReg[11];
+ I2C1->IC_TX_TL = I2C1_StoreReg[12];
+ I2C1->IC_SDA_HOLD = I2C1_StoreReg[14];
+ I2C1->IC_SLV_DATA_NACK_ONLY = I2C1_StoreReg[15];
+ I2C1->IC_DMA_CR = I2C1_StoreReg[16];
+ I2C1->IC_DMA_TDLR = I2C1_StoreReg[17];
+ I2C1->IC_DMA_RDLR = I2C1_StoreReg[18];
+ I2C1->IC_SDA_SETUP = I2C1_StoreReg[19];
+
+ I2C1->IC_ENABLE = I2C1_StoreReg[13];
+}
+#endif
+
+/********************************************** ********************************************************/
+/**************************************** [I2S0 DLPS] **************************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+#if USE_I2S0_DLPS
+
+volatile uint32_t I2S0_StoreReg[4];
+
+/**
+ * @brief I2S0 enter dlps callback function(Save I2S0 register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void I2S0_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void I2S0_DLPS_Enter(void)
+{
+ PERIPH->PERI_BD_FUNC0_EN |= BIT(1) | BIT(5) | BIT(8);
+
+ I2S0_StoreReg[0] = I2S0->BCLK_DIV;
+ I2S0_StoreReg[1] = I2S0->CTRL0;
+ I2S0_StoreReg[2] = I2S0->CTRL1;
+ I2S0_StoreReg[3] = I2S0->DMA_TRDLR;
+}
+
+/**
+ * @brief I2S0 exit dlps callback function(Resume I2S0 register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void I2S0_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void I2S0_DLPS_Exit(void)
+{
+ PERIPH->PERI_BD_FUNC0_EN |= BIT(1) | BIT(5) | BIT(8);
+
+ /* Reset I2S0 module */
+ I2S0->CTRL0 |= 1 << 0;
+ I2S0->CTRL0 &= ~(1 << 0);
+
+ /* Initialize I2S0 */
+ I2S0->BCLK_DIV = I2S0_StoreReg[0];
+ I2S0->CTRL1 = I2S0_StoreReg[2];
+ I2S0->DMA_TRDLR = I2S0_StoreReg[3];
+ I2S0->CTRL0 = I2S0_StoreReg[1];
+}
+#endif
+
+/********************************************** ********************************************************/
+/**************************************** [IR DLPS] **************************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+
+#if USE_IR_DLPS
+__STATIC_INLINE void IR_DLPS_Enter(void);
+__STATIC_INLINE void IR_DLPS_Exit(void);
+
+volatile uint32_t IR_StoreReg[6]; /* This array should be placed in RAM ON/Buffer ON. */
+
+/**
+ * @brief IR enter dlps callback function(Save IR register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void IR_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void IR_DLPS_Enter(void)
+{
+ PERIPH->PERI_FUNC0_EN |= (1 << 10);
+ PERIPH->PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_IR_EN_Msk | SYSBLK_SLPCK_IR_EN_Msk);
+
+ IR_StoreReg[0] = IR->CLK_DIV;
+ IR_StoreReg[1] = IR->TX_CONFIG;
+ IR_StoreReg[2] = IR->RX_CONFIG;
+ IR_StoreReg[3] = IR->RX_CNT_INT_SEL;
+
+ return;
+}
+
+/**
+ * @brief IR exit dlps callback function(Resume IR register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void IR_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void IR_DLPS_Exit(void)
+{
+ PERIPH->PERI_FUNC0_EN |= (1 << 10);
+ PERIPH->PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_IR_EN_Msk | SYSBLK_SLPCK_IR_EN_Msk);
+
+ IR->CLK_DIV = IR_StoreReg[0];
+ if (IR_StoreReg[1] & BIT31)
+ {
+ /* RX MODE */
+ IR->TX_CONFIG = IR_StoreReg[1];
+ IR->RX_CONFIG = IR_StoreReg[2];
+ IR->RX_CNT_INT_SEL = IR_StoreReg[3];
+ }
+ else
+ {
+ /* TX MODE */
+ IR->TX_CONFIG = IR_StoreReg[1];
+ /* If IR TX mode is idle, must write one data firstly */
+ IR->TX_FIFO = 0;
+ }
+
+ return;
+}
+
+#endif
+
+/********************************************** ********************************************************/
+/**************************************** [KEYSCAN DLPS] ***********************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+#if USE_KEYSCAN_DLPS
+
+__STATIC_INLINE void KeyScan_DLPS_Enter(void);
+__STATIC_INLINE void KeyScan_DLPS_Exit(void);
+
+volatile uint32_t
+KeyScan_StoreReg[7]; /* This array should be placed in RAM ON/Buffer ON. */
+
+/**
+ * @brief KEYSCAN enter dlps callback function(Save KEYSCAN register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void KeyScan_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void KeyScan_DLPS_Enter(void)
+{
+ /*Open 5M clock source*/
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26;
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT29;
+
+ PERIPH->PERI_FUNC0_EN |= BIT_PERI_KEYSCAN_EN;
+ PERIPH->PERI_CLK_CTRL1 |= (BIT_SOC_ACTCK_KEYSCAN_EN | SYSBLK_SLPCK_KEYSCAN_EN_Msk);
+
+ KeyScan_StoreReg[0] = KEYSCAN->CLKDIV; /* 0x00 */
+ KeyScan_StoreReg[1] = KEYSCAN->TIMERCR; /* 0x04 */
+ KeyScan_StoreReg[2] = KEYSCAN->CR; /* 0x08 */
+ KeyScan_StoreReg[3] = KEYSCAN->COLCR; /* 0x0C */
+ KeyScan_StoreReg[4] = KEYSCAN->ROWCR; /* 0x10 */
+ KeyScan_StoreReg[6] = KEYSCAN->INTMASK; /* 0x18 */
+
+ return;
+}
+
+/**
+ * @brief KEYSCAN exit dlps callback function(Resume KEYSCAN register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void KeyScan_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void KeyScan_DLPS_Exit(void)
+{
+ /*Open 5M clock source*/
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26;
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT29;
+
+ PERIPH->PERI_FUNC0_EN |= BIT_PERI_KEYSCAN_EN;
+ PERIPH->PERI_CLK_CTRL1 |= (BIT_SOC_ACTCK_KEYSCAN_EN | SYSBLK_SLPCK_KEYSCAN_EN_Msk);
+
+ /* Set FSM to idle state */
+ KEYSCAN->CR &= ~BIT31;
+ KEYSCAN->CLKDIV = KeyScan_StoreReg[0];
+ KEYSCAN->CR = (KeyScan_StoreReg[2] & (~(BIT31)));
+ KEYSCAN->TIMERCR = KeyScan_StoreReg[1];
+ KEYSCAN->COLCR = KeyScan_StoreReg[3];
+ KEYSCAN->ROWCR = KeyScan_StoreReg[4];
+ KEYSCAN->INTMASK = KeyScan_StoreReg[6];
+ KEYSCAN->CR |= (KeyScan_StoreReg[2] & ((BIT31)));
+
+ return;
+}
+#endif /* USE_KEYSCAN_DLPS */
+
+/********************************************** ********************************************************/
+/**************************************** [QDEC DLPS] **************************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+#if USE_QDECODER_DLPS
+__STATIC_INLINE void QuadDecoder_DLPS_Enter(void);
+__STATIC_INLINE void QuadDecoder_DLPS_Exit(void);
+
+volatile uint32_t
+QuadDecoder_StoreReg[5]; /* This array should be placed in RAM ON/Buffer ON. */
+
+/**
+ * @brief QDEC enter dlps callback function(Save QDEC register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void QuadDecoder_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void QuadDecoder_DLPS_Enter(void)
+{
+ /*Open 20M clock source*/
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26;
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT27;
+ SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_QDECODE_EN_Msk;
+ SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_QDECODE_EN_Msk |
+ SYSBLK_SLPCK_QDECODE_EN_Msk);
+
+ QuadDecoder_StoreReg[0] = QDEC->REG_DIV;
+ QuadDecoder_StoreReg[1] = QDEC->REG_CR_X;
+ QuadDecoder_StoreReg[2] = QDEC->REG_CR_Y;
+ QuadDecoder_StoreReg[3] = QDEC->REG_CR_Z;
+ QuadDecoder_StoreReg[4] = QDEC->INT_MASK;
+
+ return;
+}
+
+/**
+ * @brief QDEC exit dlps callback function(Resume QDEC register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void QuadDecoder_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void QuadDecoder_DLPS_Exit(void)
+{
+ /*Open 20M clock source*/
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26;
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT27;
+ SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_QDECODE_EN_Msk;
+ SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_QDECODE_EN_Msk |
+ SYSBLK_SLPCK_QDECODE_EN_Msk);
+
+ //clear flags
+ QDEC->REG_DIV = QuadDecoder_StoreReg[0];
+ QDEC->REG_CR_X = QuadDecoder_StoreReg[1];
+ QDEC->REG_CR_Y = QuadDecoder_StoreReg[2];
+ QDEC->REG_CR_Z = QuadDecoder_StoreReg[3];
+ QDEC->INT_MASK = QuadDecoder_StoreReg[4];
+
+ return;
+}
+#endif
+
+/********************************************** ********************************************************/
+/**************************************** [SPI0 DLPS] **************************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+#if USE_SPI0_DLPS
+__STATIC_INLINE void SPI0_DLPS_Enter(void);
+__STATIC_INLINE void SPI0_DLPS_Exit(void);
+
+volatile uint32_t
+SPI0_StoreReg[14]; /* This array should be placed in RAM ON/Buffer ON. */
+
+/**
+ * @brief SPI0 enter dlps callback function(Save SPI0 register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void SPI0_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void SPI0_DLPS_Enter(void)
+{
+ SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_SPI0_EN_Msk;
+ SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_SPI0_EN_Msk |
+ SYSBLK_SLPCK_SPI0_EN_Msk);
+
+ SPI0_StoreReg[0] = SPI0->CTRLR0;
+ SPI0_StoreReg[1] = SPI0->CTRLR1;
+ SPI0_StoreReg[2] = SPI0->SSIENR;
+ SPI0_StoreReg[3] = SPI0->SER;
+ SPI0_StoreReg[4] = SPI0->BAUDR;
+ SPI0_StoreReg[5] = SPI0->TXFTLR;
+ SPI0_StoreReg[6] = SPI0->RXFTLR;
+ SPI0_StoreReg[7] = SPI0->IMR;
+ SPI0_StoreReg[8] = SPI0->DMACR;
+ SPI0_StoreReg[9] = SPI0->DMATDLR;
+ SPI0_StoreReg[10] = SPI0->DMARDLR;
+ SPI0_StoreReg[11] = SPI0->RX_SAMPLE_DLY;
+ SPI0_StoreReg[12] = *(volatile uint32_t *)0x40000308;
+ SPI0_StoreReg[13] = *(volatile uint32_t *)0x4000035CUL;
+}
+
+/**
+ * @brief SPI0 exit dlps callback function(Resume SPI0 register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void SPI0_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void SPI0_DLPS_Exit(void)
+{
+ *(volatile uint32_t *)0x4000035CUL = SPI0_StoreReg[13];
+ *(volatile uint32_t *)0x40000308 = SPI0_StoreReg[12];
+ SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_SPI0_EN_Msk;
+ SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_SPI0_EN_Msk |
+ SYSBLK_SLPCK_SPI0_EN_Msk);
+
+ SPI0->CTRLR0 = SPI0_StoreReg[0];
+ SPI0->CTRLR1 = SPI0_StoreReg[1];
+ SPI0->SER = SPI0_StoreReg[3];
+ SPI0->BAUDR = SPI0_StoreReg[4];
+ SPI0->TXFTLR = SPI0_StoreReg[5];
+ SPI0->RXFTLR = SPI0_StoreReg[6];
+ SPI0->IMR = SPI0_StoreReg[7];
+ SPI0->DMACR = SPI0_StoreReg[8];
+ SPI0->DMATDLR = SPI0_StoreReg[9];
+ SPI0->DMARDLR = SPI0_StoreReg[10];
+ SPI0->RX_SAMPLE_DLY = SPI0_StoreReg[11];
+
+ /* Enable the selected SPI peripheral */
+ SPI0->SSIENR = SPI0_StoreReg[2];
+}
+#endif
+
+
+/********************************************** ********************************************************/
+/**************************************** [SPI1 DLPS] **************************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+#if USE_SPI1_DLPS
+__STATIC_INLINE void SPI1_DLPS_Enter(void);
+__STATIC_INLINE void SPI1_DLPS_Exit(void);
+
+volatile uint32_t
+SPI1_StoreReg[14]; /* This array should be placed in RAM ON/Buffer ON. */
+
+/**
+ * @brief SPI1 enter dlps callback function(Save SPI1 register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void SPI1_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void SPI1_DLPS_Enter(void)
+{
+ SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_SPI1_EN_Msk;
+ SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_SPI1_EN_Msk |
+ SYSBLK_SLPCK_SPI1_EN_Msk);
+
+ SPI1_StoreReg[0] = SPI1->CTRLR0;
+ SPI1_StoreReg[1] = SPI1->CTRLR1;
+ SPI1_StoreReg[2] = SPI1->SSIENR;
+ SPI1_StoreReg[3] = SPI1->SER;
+ SPI1_StoreReg[4] = SPI1->BAUDR;
+ SPI1_StoreReg[5] = SPI1->TXFTLR;
+ SPI1_StoreReg[6] = SPI1->RXFTLR;
+ SPI1_StoreReg[7] = SPI1->IMR;
+ SPI1_StoreReg[8] = SPI1->DMACR;
+ SPI1_StoreReg[9] = SPI1->DMATDLR;
+ SPI1_StoreReg[10] = SPI1->DMARDLR;
+ SPI1_StoreReg[11] = SPI1->RX_SAMPLE_DLY;
+ SPI1_StoreReg[12] = *(volatile uint32_t *)0x40000308;
+ SPI1_StoreReg[13] = *(volatile uint32_t *)0x4000035CUL;
+}
+
+/**
+ * @brief SPI1 exit dlps callback function(Resume SPI1 register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void SPI1_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void SPI1_DLPS_Exit(void)
+{
+ *(volatile uint32_t *)0x4000035CUL = SPI1_StoreReg[13];
+ *(volatile uint32_t *)0x40000308 = SPI1_StoreReg[12];
+ SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_SPI1_EN_Msk;
+ SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_SPI1_EN_Msk |
+ SYSBLK_SLPCK_SPI1_EN_Msk);
+
+ SPI1->CTRLR0 = SPI1_StoreReg[0];
+ SPI1->CTRLR1 = SPI1_StoreReg[1];
+ SPI1->SER = SPI1_StoreReg[3];
+ SPI1->BAUDR = SPI1_StoreReg[4];
+ SPI1->TXFTLR = SPI1_StoreReg[5];
+ SPI1->RXFTLR = SPI1_StoreReg[6];
+ SPI1->IMR = SPI1_StoreReg[7];
+ SPI1->DMACR = SPI1_StoreReg[8];
+ SPI1->DMATDLR = SPI1_StoreReg[9];
+ SPI1->DMARDLR = SPI1_StoreReg[10];
+ SPI1->RX_SAMPLE_DLY = SPI1_StoreReg[11];
+
+ /* Enable the selected SPI peripheral */
+ SPI1->SSIENR = SPI1_StoreReg[2];
+}
+#endif
+
+/********************************************** ********************************************************/
+/**************************************** [SPI2W DLPS] **************************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+#if USE_SPI2W_DLPS
+__STATIC_INLINE void SPI2W_DLPS_Enter(void);
+__STATIC_INLINE void SPI2W_DLPS_Exit(void);
+
+volatile uint32_t
+SPI2W_StoreReg[1]; /* This array should be placed in RAM ON/Buffer ON. */
+
+/**
+ * @brief SPI2W enter dlps callback function(Save SPI2W register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void SPI2W_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void SPI2W_DLPS_Enter(void)
+{
+ /*Open 20M clock source*/
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26;
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT27;
+
+ SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_SPI2W_EN_Msk;
+ SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_SPI2WIRE_EN_Msk |
+ SYSBLK_SLPCK_SPI2WIRE_EN_Msk);
+
+ SPI2W_StoreReg[0] = SPI3WIRE->CFGR;
+}
+
+/**
+ * @brief SPI2W exit dlps callback function(Resume SPI2W register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void SPI2W_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void SPI2W_DLPS_Exit(void)
+{
+ /*Open 20M clock source*/
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26;
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT27;
+
+ SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_SPI2W_EN_Msk;
+ SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_SPI2WIRE_EN_Msk |
+ SYSBLK_SLPCK_SPI2WIRE_EN_Msk);
+
+ SPI3WIRE->CFGR = SPI2W_StoreReg[0];
+}
+#endif
+
+
+/********************************************** ********************************************************/
+/**************************************** [Timer & PWM DLPS] *******************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+#ifdef USE_TIM_DLPS
+#undef USE_TIM_DLPS
+#endif
+
+#define USE_TIM_DLPS 1 //ROM WDG use HW Timer, so defined to 1 by default
+
+#if USE_TIM_DLPS
+
+#include "rtl876x_tim.h"
+__STATIC_INLINE void TIM_DLPS_Enter(void);
+__STATIC_INLINE void TIM_DLPS_Exit(void);
+
+//uint32_t TIM_StoreReg[26]; /* This array should be placed in RAM ON/Buffer ON. */
+volatile uint32_t TIM_StoreReg[28];
+/* PWM, use with timer */
+volatile uint32_t PWM2_StoreReg; /* This array should be placed in RAM ON/Buffer ON. */
+
+/**
+ * @brief TIMER enter dlps callback function(Save TIMER register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void TIM_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void TIM_DLPS_Enter(void)
+{
+ SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN |= BIT(16);
+ SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= (SYSBLK_ACTCK_TIMER_EN_Msk |
+ SYSBLK_SLPCK_TIMER_EN_Msk);
+
+ TIM_StoreReg[0] = TIM0->LoadCount;
+ TIM_StoreReg[1] = TIM0->ControlReg;
+ TIM_StoreReg[2] = TIMER0_LOAD_COUNT2;
+
+ TIM_StoreReg[3] = TIM1->LoadCount;
+ TIM_StoreReg[4] = TIM1->ControlReg;
+ TIM_StoreReg[5] = TIMER1_LOAD_COUNT2;
+
+ TIM_StoreReg[6] = TIM2->LoadCount;
+ TIM_StoreReg[7] = TIM2->ControlReg;
+ TIM_StoreReg[8] = TIMER2_LOAD_COUNT2;
+
+ TIM_StoreReg[9] = TIM3->LoadCount;
+ TIM_StoreReg[10] = TIM3->ControlReg;
+ TIM_StoreReg[11] = TIMER3_LOAD_COUNT2;
+
+ TIM_StoreReg[12] = TIM4->LoadCount;
+ TIM_StoreReg[13] = TIM4->ControlReg;
+ TIM_StoreReg[14] = TIMER4_LOAD_COUNT2;
+
+ TIM_StoreReg[15] = TIM5->LoadCount;
+ TIM_StoreReg[16] = TIM5->ControlReg;
+ TIM_StoreReg[17] = TIMER5_LOAD_COUNT2;
+
+ TIM_StoreReg[18] = *((volatile uint32_t *)0x40000360UL);
+ TIM_StoreReg[19] = *((volatile uint32_t *)0x4000600CUL);
+ TIM_StoreReg[20] = *((volatile uint32_t *)0x40000384UL);
+ PWM2_StoreReg = TIMER_PWM2_CR;
+}
+
+/**
+ * @brief TIMER exit dlps callback function(Resume TIMER register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void TIM_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void TIM_DLPS_Exit(void)
+{
+ /* Enable timer IP clock and function */
+ SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN |= BIT(16);
+ SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= (SYSBLK_ACTCK_TIMER_EN_Msk |
+ SYSBLK_SLPCK_TIMER_EN_Msk);
+
+ *((volatile uint32_t *)0x40000360UL) = TIM_StoreReg[18];
+
+ TIM0->LoadCount = TIM_StoreReg[0];
+ TIM0->ControlReg = TIM_StoreReg[1];
+ TIMER0_LOAD_COUNT2 = TIM_StoreReg[2];
+
+ TIM1->LoadCount = TIM_StoreReg[3];
+ TIM1->ControlReg = TIM_StoreReg[4];
+ TIMER1_LOAD_COUNT2 = TIM_StoreReg[5];
+
+ TIM2->LoadCount = TIM_StoreReg[6];
+ TIM2->ControlReg = TIM_StoreReg[7];
+ TIMER2_LOAD_COUNT2 = TIM_StoreReg[8];
+
+ TIM3->LoadCount = TIM_StoreReg[9];
+ TIM3->ControlReg = TIM_StoreReg[10];
+ TIMER3_LOAD_COUNT2 = TIM_StoreReg[11];
+
+ TIM4->LoadCount = TIM_StoreReg[12];
+ TIM4->ControlReg = TIM_StoreReg[13];
+ TIMER4_LOAD_COUNT2 = TIM_StoreReg[14];
+
+ TIM5->LoadCount = TIM_StoreReg[15];
+ TIM5->ControlReg = TIM_StoreReg[16];
+ TIMER5_LOAD_COUNT2 = TIM_StoreReg[17];
+
+ TIMER_PWM2_CR = PWM2_StoreReg;
+}
+#endif /* USE_TIM_DLPS */
+
+/********************************************** ********************************************************/
+/**************************************** [Enhance Timer & PWM DLPS] *******************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+#if USE_ENHTIM_DLPS
+
+#include "rtl876x_enh_tim.h"
+
+volatile uint32_t
+ENHTIM_StoreReg[20]; /* This array should be placed in RAM ON/Buffer ON. */
+/* PWM, use with timer */
+volatile uint32_t
+ENHPWM0_StoreReg; /* This array should be placed in RAM ON/Buffer ON. */
+
+/**
+ * @brief Enhance TIMER enter dlps callback function(Save TIMER register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void ENHTIM_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void ENHTIM_DLPS_Enter(void)
+{
+ SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN |= BIT(16);
+ SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= (SYSBLK_ACTCK_TIMER_EN_Msk |
+ SYSBLK_SLPCK_TIMER_EN_Msk);
+
+ ENHTIM_StoreReg[0] = ENH_TIM0->CR;
+ ENHTIM_StoreReg[1] = ENH_TIM0->MAX_CNT;
+ ENHTIM_StoreReg[2] = ENH_TIM0->CCR;
+ ENHTIM_StoreReg[3] = ENH_TIM0->CCR_FIFO;
+
+ ENHTIM_StoreReg[4] = ENH_TIM1->CR;
+ ENHTIM_StoreReg[5] = ENH_TIM1->MAX_CNT;
+ ENHTIM_StoreReg[6] = ENH_TIM1->CCR;
+ ENHTIM_StoreReg[7] = ENH_TIM1->CCR_FIFO;
+
+ ENHTIM_StoreReg[8] = ENH_TIM_SHARE->FIFO_CLR;
+ ENHTIM_StoreReg[9] = ENH_TIM_SHARE->CMD;
+ ENHTIM_StoreReg[10] = ENH_TIM_SHARE->INT_CMD;
+ ENHTIM_StoreReg[11] = ENH_TIM_SHARE->INT_SR;
+ ENHTIM_StoreReg[12] = ENH_TIM_SHARE->LC_INT_CMD0;
+ ENHTIM_StoreReg[13] = ENH_TIM_SHARE->LC_INT_CMD2;
+ ENHTIM_StoreReg[14] = ENH_TIM_SHARE->LC_FIFO_LEVEL0;
+ ENHTIM_StoreReg[15] = ENH_TIM_SHARE->LC_FIFO_LEVEL1;
+
+ ENHTIM_StoreReg[16] = *((volatile uint32_t *)0x40000360UL);
+ ENHTIM_StoreReg[17] = *((volatile uint32_t *)0x4000600CUL);
+ ENHTIM_StoreReg[18] = *((volatile uint32_t *)0x40000384UL);
+
+ ENHPWM0_StoreReg = ENHTIM_PWM_DEADZONE_CR;
+}
+
+/**
+ * @brief Enhance TIMER exit dlps callback function(Resume TIMER register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void ENHTIM_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void ENHTIM_DLPS_Exit(void)
+{
+ /* Enable timer IP clock and function */
+ SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN |= BIT(16);
+ SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= (SYSBLK_ACTCK_TIMER_EN_Msk |
+ SYSBLK_SLPCK_TIMER_EN_Msk);
+
+ *((volatile uint32_t *)0x40000360UL) = ENHTIM_StoreReg[18];
+
+ ENH_TIM0->CR = ENHTIM_StoreReg[0];
+ ENH_TIM0->MAX_CNT = ENHTIM_StoreReg[1];
+ ENH_TIM0->CCR = ENHTIM_StoreReg[2];
+ ENH_TIM0->CCR_FIFO = ENHTIM_StoreReg[3];
+
+ ENH_TIM1->CR = ENHTIM_StoreReg[4];
+ ENH_TIM1->MAX_CNT = ENHTIM_StoreReg[5];
+ ENH_TIM1->CCR = ENHTIM_StoreReg[6];
+ ENH_TIM1->CCR_FIFO = ENHTIM_StoreReg[7];
+
+ ENH_TIM_SHARE->FIFO_CLR = ENHTIM_StoreReg[8];
+ ENH_TIM_SHARE->CMD = ENHTIM_StoreReg[9] ;
+ ENH_TIM_SHARE->INT_CMD = ENHTIM_StoreReg[10];
+ ENH_TIM_SHARE->INT_SR = ENHTIM_StoreReg[11];
+ ENH_TIM_SHARE->LC_INT_CMD0 = ENHTIM_StoreReg[12];
+ ENH_TIM_SHARE->LC_INT_CMD2 = ENHTIM_StoreReg[13];
+ ENH_TIM_SHARE->LC_FIFO_LEVEL0 = ENHTIM_StoreReg[14];
+ ENH_TIM_SHARE->LC_FIFO_LEVEL1 = ENHTIM_StoreReg[15];
+
+ ENHTIM_PWM_DEADZONE_CR = ENHPWM0_StoreReg;
+}
+#endif /* USE_ENHTIM_DLPS */
+
+/********************************************** ********************************************************/
+/**************************************** [UART DLPS] **************************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+#if USE_UART0_DLPS
+#include "rtl876x_uart.h"
+
+__STATIC_INLINE void UART0_DLPS_Enter(void);
+__STATIC_INLINE void UART0_DLPS_Exit(void);
+
+volatile uint32_t
+UART0_StoreReg[12]; /* This array should be placed in RAM ON/Buffer ON. */
+
+/**
+ * @brief UART0 enter dlps callback function(Save UART0 register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void UART0_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void UART0_DLPS_Enter(void)
+{
+ PERIPH->PERI_FUNC0_EN |= (1 << 0);
+ PERIPH->PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_UART0DATA_EN_Msk | SYSBLK_SLPCK_UART0DATA_EN_Msk);
+
+ //access DLH and DLL
+ UART0->LCR |= (1 << 7);
+ UART0_StoreReg[0] = UART0->DLL;
+ UART0_StoreReg[1] = UART0->DLH_INTCR;
+ UART0->LCR &= (~(1 << 7));
+
+ //save other registers
+ UART0_StoreReg[2] = UART0->DLH_INTCR;
+ UART0_StoreReg[4] = UART0->LCR;
+ UART0_StoreReg[5] = UART0->MCR;
+ UART0_StoreReg[6] = UART0->SPR;
+ UART0_StoreReg[7] = UART0->STSR;
+ UART0_StoreReg[8] = UART0->RX_IDLE_TOCR;
+ UART0_StoreReg[9] = UART0->RX_IDLE_INTCR;
+ UART0_StoreReg[10] = UART0->MISCR;
+ UART0_StoreReg[11] = UART0->INTMASK;
+
+ return;
+}
+
+/**
+ * @brief UART0 exit dlps callback function(Resume UART0 register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void UART0_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void UART0_DLPS_Exit(void)
+{
+ PERIPH->PERI_FUNC0_EN |= (1 << 0);
+ PERIPH->PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_UART0DATA_EN_Msk | SYSBLK_SLPCK_UART0DATA_EN_Msk);
+
+ //access DLH and DLL
+ UART0->LCR |= (1 << 7);
+ UART0->DLL = UART0_StoreReg[0];
+ UART0->DLH_INTCR = UART0_StoreReg[1];
+ UART0->LCR &= (~(1 << 7));
+
+ //access other registers
+ UART0->INTID_FCR = (((UART0_StoreReg[7] & BIT24) >> 21) | ((UART0_StoreReg[7] & 0x7C000000) >> 18) |
+ (1));
+ UART0->LCR = UART0_StoreReg[4];
+ UART0->MCR = UART0_StoreReg[5];
+ UART0->SPR = UART0_StoreReg[6];
+ UART0->STSR = UART0_StoreReg[7];
+ UART0->DLH_INTCR = UART0_StoreReg[2];
+ UART0->RX_IDLE_TOCR = UART0_StoreReg[8];
+ UART0->RX_IDLE_INTCR = UART0_StoreReg[9];
+ UART0->MISCR = UART0_StoreReg[10];
+ UART0->INTMASK = UART0_StoreReg[11];
+
+ return;
+}
+#endif
+
+
+#if USE_UART1_DLPS
+#include "rtl876x_uart.h"
+
+__STATIC_INLINE void UART1_DLPS_Enter(void);
+__STATIC_INLINE void UART1_DLPS_Exit(void);
+
+volatile uint32_t
+UART1_StoreReg[12]; /* This array should be placed in RAM ON/Buffer ON. */
+
+/**
+ * @brief UART1 enter dlps callback function(Save UART1 register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void UART1_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void UART1_DLPS_Enter(void)
+{
+ //enable log uart peripheral & clock
+ SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN |= (1 << 12);
+ SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= ((1 << 12) | (1 << 13));
+
+ //access DLH and DLL
+ UART1->LCR |= (1 << 7);
+ UART1_StoreReg[0] = UART1->DLL;
+ UART1_StoreReg[1] = UART1->DLH_INTCR;
+ UART1->LCR &= (~(1 << 7));
+
+ //save other registers
+ UART1_StoreReg[2] = UART1->DLH_INTCR;
+ UART1_StoreReg[4] = UART1->LCR;
+ UART1_StoreReg[5] = UART1->MCR;
+ UART1_StoreReg[6] = UART1->SPR;
+ UART1_StoreReg[7] = UART1->STSR;
+ UART1_StoreReg[8] = UART1->RX_IDLE_TOCR;
+ UART1_StoreReg[9] = UART1->RX_IDLE_INTCR;
+ UART1_StoreReg[10] = UART1->MISCR;
+ UART1_StoreReg[11] = UART1->INTMASK;
+
+ return;
+}
+
+/**
+ * @brief UART1 exit dlps callback function(Resume UART1 register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void UART1_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void UART1_DLPS_Exit(void)
+{
+ //enable log uart peripheral & clock
+ SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN |= (1 << 12);
+ SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= ((1 << 12) | (1 << 13));
+
+ //access DLH and DLL
+ UART1->LCR |= (1 << 7);
+ UART1->DLL = UART1_StoreReg[0];
+ UART1->DLH_INTCR = UART1_StoreReg[1];
+ UART1->LCR &= (~(1 << 7));
+
+ //access other registers
+ UART1->INTID_FCR = (((UART1_StoreReg[7] & BIT24) >> 21) | ((UART1_StoreReg[7] & 0x7C000000)
+ >> 18) | (1));
+ UART1->LCR = UART1_StoreReg[4];
+ UART1->MCR = UART1_StoreReg[5];
+ UART1->SPR = UART1_StoreReg[6];
+ UART1->STSR = UART1_StoreReg[7];
+ UART1->DLH_INTCR = UART1_StoreReg[2];
+ UART1->RX_IDLE_TOCR = UART1_StoreReg[8];
+ UART1->RX_IDLE_INTCR = UART1_StoreReg[9];
+ UART1->MISCR = UART1_StoreReg[10];
+ UART1->INTMASK = UART1_StoreReg[11];
+
+ return;
+}
+#endif
+
+
+/*============================================================================*
+ * Platform DLPS
+ *============================================================================*/
+
+/********************************************** ********************************************************/
+/*********************************** [USER Enter DLPS CALLBACK FUCN] *****************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+#if USE_USER_DEFINE_DLPS_ENTER_CB
+
+DLPS_IO_EnterDlpsCB User_IO_EnterDlpsCB = NULL;
+
+#endif /* USE_USER_DEFINE_DLPS_EXIT_CB */
+
+/********************************************** ********************************************************/
+/*********************************** [USER Exit DLPS CALLBACK FUCN] *****************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+#if USE_USER_DEFINE_DLPS_EXIT_CB
+
+DLPS_IO_ExitDlpsCB User_IO_ExitDlpsCB = NULL;
+
+#endif /* USE_USER_DEFINE_DLPS_EXIT_CB */
+
+
+#if USE_IO_DRIVER_DLPS
+
+/********************************************** ********************************************************/
+/**************************************** [CPU & PINMUX DLPS]*******************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+
+__STATIC_INLINE void CPU_DLPS_Enter(void);
+__STATIC_INLINE void CPU_DLPS_Exit(void);
+__STATIC_INLINE void Log_SWD_DLPS_Enter(void);
+__STATIC_INLINE void Log_SWD_DLPS_Exit(void);
+
+volatile uint32_t
+CPU_StoreReg[3]; /* This array should be placed in RAM ON/Buffer ON. */
+volatile uint8_t CPU_StoreReg_IP[32];
+volatile uint32_t PeriIntStoreReg = 0;
+
+/**
+ * @brief CPU enter dlps callback function(Save CPU register values when system enter DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void CPU_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void CPU_DLPS_Enter(void)
+{
+ //NVIC store
+ uint32_t i;
+
+ CPU_StoreReg[0] = NVIC->ISER[0];
+ CPU_StoreReg[1] = NVIC->ISPR[0];
+
+ //The priority of system on interrupt is 0 at first DLPS ENTER CB, so store and restore is skipped
+ const uint8_t *IP_pt = (const uint8_t *)NVIC->IP;
+ for (i = 3; i < 32; ++i) //skip System_IRQn, WDG_IRQn, BTMAC_IRQn which are handled in rom
+ {
+ CPU_StoreReg_IP[i] = IP_pt[i];
+ }
+
+ CPU_StoreReg[2] = SCB->VTOR;
+ /* Save Vendor register */
+ PeriIntStoreReg = PERIPHINT->EN;
+
+ return;
+}
+
+/**
+ * @brief CPU exit dlps callback function(Resume CPU register values when system exit DLPS)
+ * @param None
+ * @retval None
+ */
+__STATIC_INLINE void CPU_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void CPU_DLPS_Exit(void)
+{
+ //NVIC restore
+ uint32_t i;
+
+ //Don't restore NVIC pending register, but report warning
+ //NVIC->ISPR[0] = CPU_StoreReg[1];
+ if (CPU_StoreReg[0] & CPU_StoreReg[1])
+ {
+ /* During enter and exit dlps, system will disable all interrupts. If any interrupt occurs during this period, this log will be printed.
+ Every bit of pending register corresponds to an interrupt. Please refer to IRQn_Type from System_IRQn to UART2_IRQn.
+ For example: "miss interrupt: pending register: 0x42000"
+ It means that RTC and ADC interrupt occur during dlps store and restore flow. But because all interrupts are masked, these interrupts are pending.
+ */
+ OS_PRINT_WARN1("miss interrupt: pending register: 0x%x", CPU_StoreReg[1]);
+ }
+
+ //The priority of system on interrupt is 0 at first DLPS ENTER CB, so store and restore is skipped
+ uint8_t *IP_pt = (uint8_t *)NVIC->IP;
+ for (i = 3; i < 32; ++i) //skip System_IRQn, WDG_IRQn, BTMAC_IRQn which are handled in rom
+ {
+ IP_pt[i] = CPU_StoreReg_IP[i];
+ }
+
+ SCB->VTOR = CPU_StoreReg[2];
+ PERIPHINT->EN = PeriIntStoreReg;
+ NVIC->ISER[0] = CPU_StoreReg[0];
+
+ return;
+}
+
+/********************************************** ********************************************************/
+/**************************************** [LOG & SWD DLPS]*******************************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+
+/**
+ * @brief Set Log and SWD pins to SW mode.
+ * @param void.
+ * @retval void.
+ */
+__STATIC_INLINE void Log_SWD_DLPS_Enter(void) DATA_RAM_FUNCTION;
+void Log_SWD_DLPS_Enter(void)
+{
+ if (OTP->SWD_ENABLE)
+ {
+ Pad_Config(P1_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_DOWN, PAD_OUT_DISABLE, PAD_OUT_LOW);
+ Pad_Config(P1_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_DOWN, PAD_OUT_DISABLE, PAD_OUT_LOW);
+ }
+
+ Pad_Config(OTP->logPin, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
+}
+
+/**
+ * @brief Set Log and SWD pins to PINMUX mode.
+ * @param void.
+ * @retval void.
+ */
+__STATIC_INLINE void Log_SWD_DLPS_Exit(void) DATA_RAM_FUNCTION;
+void Log_SWD_DLPS_Exit(void)
+{
+ Pad_Config(OTP->logPin, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW);
+
+ if (OTP->SWD_ENABLE)
+ {
+ Pad_Config(P1_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
+ Pad_Config(P1_1, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
+ }
+}
+
+/********************************************** ********************************************************/
+/*********************************** [Enter & Exit DLPS CALLBACK FUNC] *********************************/
+/*******************************************************************************************************/
+/*******************************************************************************************************/
+
+/**
+ * @brief IO enter dlps callback function
+ * @param None
+ * @retval None
+ */
+void DLPS_IO_EnterDlpsCb(void) DATA_RAM_FUNCTION;
+void DLPS_IO_EnterDlpsCb(void)
+{
+ /* low stack do it instead */
+// Pad_ClearAllWakeupINT();
+
+// DBG_DIRECT("DLPS_IO_EnterDlpsCb");
+ NVIC_DisableIRQ(System_IRQn);
+ CPU_DLPS_Enter();
+
+ Pinmux_DLPS_Enter();
+
+#if USE_USER_DEFINE_DLPS_ENTER_CB
+ if (User_IO_EnterDlpsCB)
+ {
+ User_IO_EnterDlpsCB();
+ }
+#endif
+
+#if USE_ADC_DLPS
+ ADC_DLPS_Enter();
+#endif
+
+#if USE_CODEC_DLPS
+ CODEC_DLPS_Enter();
+#endif
+
+#if USE_GPIO_DLPS
+ GPIO_DLPS_Enter();
+#endif
+
+#if USE_I2C0_DLPS
+ I2C0_DLPS_Enter();
+#endif
+
+#if USE_I2C1_DLPS
+ I2C1_DLPS_Enter();
+#endif
+
+#if USE_I2S0_DLPS
+ I2S0_DLPS_Enter();
+#endif
+
+#if USE_IR_DLPS
+ IR_DLPS_Enter();
+#endif
+
+#if USE_KEYSCAN_DLPS
+ KeyScan_DLPS_Enter();
+#endif
+
+#if USE_QDECODER_DLPS
+ QuadDecoder_DLPS_Enter();
+#endif
+
+#if USE_SPI0_DLPS
+ SPI0_DLPS_Enter();
+#endif
+
+#if USE_SPI1_DLPS
+ SPI1_DLPS_Enter();
+#endif
+
+#if USE_SPI2W_DLPS
+ SPI2W_DLPS_Enter();
+#endif
+
+#if USE_TIM_DLPS
+ TIM_DLPS_Enter();
+#endif
+
+#if USE_ENHTIM_DLPS
+ ENHTIM_DLPS_Enter();
+#endif
+
+#if USE_UART0_DLPS
+ UART0_DLPS_Enter();
+#endif
+
+#if USE_UART1_DLPS
+ UART1_DLPS_Enter();
+#endif
+
+ Log_SWD_DLPS_Enter();
+}
+
+/**
+ * @brief IO exit dlps callback function.
+ * @param None
+ * @retval None
+ */
+void DLPS_IO_ExitDlpsCb(void) DATA_RAM_FUNCTION;
+void DLPS_IO_ExitDlpsCb(void)
+{
+
+// DBG_BUFFER(TYPE_BUMBLEBEE3, SUBTYPE_FORMAT, MODULE_DLPS, LEVEL_INFO,
+// "DLPS_IO_ExitDlpsCb",0);
+
+ Pinmux_DLPS_Exit();
+
+ Log_SWD_DLPS_Exit();
+
+#if USE_ADC_DLPS
+ ADC_DLPS_Exit();
+#endif
+
+#if USE_CODEC_DLPS
+ CODEC_DLPS_Exit();
+#endif
+
+#if USE_GPIO_DLPS
+ GPIO_DLPS_Exit();
+#endif
+
+#if USE_I2C0_DLPS
+ I2C0_DLPS_Exit();
+#endif
+
+#if USE_I2C1_DLPS
+ I2C1_DLPS_Exit();
+#endif
+
+#if USE_I2S0_DLPS
+ I2S0_DLPS_Exit();
+#endif
+
+#if USE_IR_DLPS
+ IR_DLPS_Exit();
+#endif
+
+#if USE_KEYSCAN_DLPS
+ KeyScan_DLPS_Exit();
+#endif
+
+#if USE_QDECODER_DLPS
+ QuadDecoder_DLPS_Exit();
+#endif
+
+#if USE_SPI0_DLPS
+ SPI0_DLPS_Exit();
+#endif
+
+#if USE_SPI1_DLPS
+ SPI1_DLPS_Exit();
+#endif
+
+#if USE_SPI2W_DLPS
+ SPI2W_DLPS_Exit();
+#endif
+
+#if USE_TIM_DLPS
+ TIM_DLPS_Exit();
+#endif
+
+#if USE_ENHTIM_DLPS
+ ENHTIM_DLPS_Exit();
+#endif
+
+#if USE_UART0_DLPS
+ UART0_DLPS_Exit();
+#endif
+
+#if USE_UART1_DLPS
+ UART1_DLPS_Exit();
+#endif
+
+#if USE_USER_DEFINE_DLPS_EXIT_CB
+ if (User_IO_ExitDlpsCB)
+ {
+ User_IO_ExitDlpsCB();
+ }
+#endif
+
+ NVIC_InitTypeDef nvic_init_struct;
+ nvic_init_struct.NVIC_IRQChannel = System_IRQn;
+ nvic_init_struct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ nvic_init_struct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&nvic_init_struct); //Enable SYSTEM_ON Interrupt
+
+ CPU_DLPS_Exit();
+}
+
+/**
+ * @brief register IO DLPS callback function
+ * @param None
+ * @retval None
+ */
+void DLPS_IORegister(void)
+{
+ dlps_hw_control_cb_reg(DLPS_IO_EnterDlpsCb, PLATFORM_PM_STORE);
+ dlps_hw_control_cb_reg(DLPS_IO_ExitDlpsCb, PLATFORM_PM_PEND);
+
+ return;
+}
+
+#endif /* USE_IO_DRIVER_DLPS */
+
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/mcu/peripheral/rtl876x_ir.c b/src/mcu/peripheral/rtl876x_ir.c
new file mode 100644
index 0000000..3fffcc1
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_ir.c
@@ -0,0 +1,596 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_ir.c
+* @brief This file provides all the IR firmware functions.
+* @details
+* @author yuan
+* @date 2020-10-13
+* @version v1.0.2
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_rcc.h"
+#include "rtl876x_ir.h"
+
+/**
+ * @brief Deinitializes the IR peripheral registers to their default values.
+ * @param None
+ * @retval None
+ */
+void IR_DeInit(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, DISABLE);
+}
+
+/**
+ * @brief Initializes the IR peripheral according to the specified
+ * parameters in the IR_InitStruct
+ * @param IRx: selected IR peripheral.
+ * @param IR_InitStruct: pointer to a IR_InitTypeDef structure that
+ * contains the configuration information for the specified IR peripheral
+ * @retval None
+ */
+void IR_Init(IR_InitTypeDef *IR_InitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_IR_CLOCK(IR_InitStruct->IR_Clock));
+
+ if (IR_InitStruct->IR_Clock == 40000000)
+ {
+ assert_param(IS_IR_FREQUENCY_40M(IR_InitStruct->IR_Freq));
+ }
+ else if (IR_InitStruct->IR_Clock == 90000000)
+ {
+ assert_param(IS_IR_FREQUENCY_90M(IR_InitStruct->IR_Freq));
+ }
+ else if (IR_InitStruct->IR_Clock == 100000000)
+ {
+ assert_param(IS_IR_FREQUENCY_100M(IR_InitStruct->IR_Freq));
+ }
+ assert_param(IS_IR_MODE(IR_InitStruct->IR_Mode));
+
+ /* Configure IR clock divider. Formula: IR_CLK = IO_CLK/(1+IR_CLK_DIV) */
+ uint32_t ir_clk_div_num = (IR_InitStruct->IR_Clock / IR_InitStruct->IR_Freq) - 1;
+ uint32_t duty_cycle_num = ((double)(ir_clk_div_num + 1.0)) / (IR_InitStruct->IR_DutyCycle) - 1;
+
+ IR->CLK_DIV = ir_clk_div_num;
+ if (IR_InitStruct->IR_Mode == IR_MODE_TX)
+ {
+ /* Check the parameters in TX mode */
+ assert_param(IS_IR_IDLE_STATUS(IR_InitStruct->IR_TxIdleLevel));
+ assert_param(IS_IR_TX_DATA_TYPE(IR_InitStruct->IR_TxInverse));
+ assert_param(IS_IR_TX_THRESHOLD(IR_InitStruct->IR_TxFIFOThrLevel));
+
+ /* Configure TX mode parameters and disable all TX interrupt */
+ IR->TX_CONFIG = (IR_InitStruct->IR_Mode) | \
+ (IR_InitStruct->IR_TxIdleLevel) | \
+ (IR_InitStruct->IR_TxInverse) | \
+ ((IR_InitStruct->IR_TxFIFOThrLevel) << IR_TX_FIFO_THRESHOLD_Pos) | \
+ ((duty_cycle_num & 0x3FFF) << IR_TX_DUTY_NUM_Pos);
+ /* Clear all TX interrupt and TX FIFO */
+ IR->TX_INT_CLR = IR_INT_ALL_CLR | IR_TX_FIFO_CLR_Msk;
+
+ if (IR_InitStruct->IR_TxDmaEn != DISABLE)
+ {
+ IR->DMA_CONFIG = ((IR_InitStruct->IR_TxDmaEn << IR_TX_DMA_EN_Pos) & IR_TX_DMA_EN_Msk) | \
+ ((IR_InitStruct->IR_TxWaterLevel << IR_TX_WATER_LEVEL_Pos) & IR_TX_WATER_LEVEL_Msk);
+ }
+ else
+ {
+ IR->DMA_CONFIG = ((IR_InitStruct->IR_TxDmaEn << IR_TX_DMA_EN_Pos) & IR_TX_DMA_EN_CLR) | \
+ ((IR_InitStruct->IR_TxWaterLevel << IR_TX_WATER_LEVEL_Pos) & IR_TX_WATER_LEVEL_CLR);
+ }
+ }
+ else
+ {
+ /* Check the parameters in RX mode */
+ assert_param(IS_RX_START_MODE(IR_InitStruct->IR_RxStartMode));
+ assert_param(IS_IR_RX_THRESHOLD(IR_InitStruct->IR_RxFIFOThrLevel));
+ assert_param(IS_IR_RX_FIFO_FULL_CTRL(IR_InitStruct->IR_RxFIFOFullCtrl));
+ assert_param(IS_RX_RX_TRIGGER_EDGE(IR_InitStruct->IR_RxTriggerMode));
+ assert_param(IS_IR_RX_FILTER_TIME_CTRL(IR_InitStruct->IR_RxFilterTime));
+ assert_param(IS_IR_RX_COUNT_LEVEL_CTRL(IR_InitStruct->IR_RxCntThrType));
+ assert_param(IS_IR_RX_COUNTER_THRESHOLD(IR_InitStruct->IR_RxCntThr));
+
+ /* Enable RX mode */
+ IR->TX_CONFIG |= (IR_InitStruct->IR_Mode);
+ /* Configure RX mode parameters and disable all RX interrupt */
+ IR->RX_CONFIG = (IR_InitStruct->IR_RxStartMode) | \
+ (IR_InitStruct->IR_RxTriggerMode) | \
+ (IR_InitStruct->IR_RxFilterTime) | \
+ (IR_InitStruct->IR_RxFIFOFullCtrl) | \
+ (IR_InitStruct->IR_RxFIFOThrLevel << IR_RX_FIFO_LEVEL_Pos);
+ /* Configure IR RX counter threshold parameters */
+ IR->RX_CNT_INT_SEL = (IR_InitStruct->IR_RxCntThrType) | (IR_InitStruct->IR_RxCntThr);
+ /* Clear all RX interrupt and RX FIFO */
+ IR->RX_INT_CLR = IR_RX_INT_ALL_CLR | IR_RX_FIFO_CLR_Msk;
+ IR->RX_EX_INT |= IR_RX_RISING_EDGE_INT_CLR_Msk | IR_RX_FALLING_EDGE_INT_CLR_Msk;
+
+ if (IR_InitStruct->IR_RxDmaEn != DISABLE)
+ {
+ IR->DMA_CONFIG = ((IR_InitStruct->IR_RxDmaEn << IR_RX_DMA_EN_Pos) & IR_RX_DMA_EN_Msk) | \
+ ((IR_InitStruct->IR_RxWaterLevel << IR_RX_WATER_LEVEL_Pos) & IR_RX_WATER_LEVEL_Msk);
+ }
+ else
+ {
+ IR->DMA_CONFIG = ((IR_InitStruct->IR_RxDmaEn << IR_RX_DMA_EN_Pos) & IR_RX_DMA_EN_CLR) | \
+ ((IR_InitStruct->IR_RxWaterLevel << IR_RX_WATER_LEVEL_Pos) & IR_RX_WATER_LEVEL_CLR);
+ }
+ }
+}
+
+/**
+ * @brief Fills each IR_InitStruct member with its default value.
+ * @param IR_InitStruct: pointer to an IR_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void IR_StructInit(IR_InitTypeDef *IR_InitStruct)
+{
+ IR_InitStruct->IR_Clock = IR_CLOCK_40M;
+ IR_InitStruct->IR_Freq = 38000;
+ IR_InitStruct->IR_DutyCycle = 3;
+ IR_InitStruct->IR_Mode = IR_MODE_TX;
+ IR_InitStruct->IR_TxIdleLevel = IR_IDLE_OUTPUT_LOW;
+ IR_InitStruct->IR_TxInverse = IR_TX_DATA_NORMAL;
+ IR_InitStruct->IR_TxFIFOThrLevel = 0;
+ IR_InitStruct->IR_RxStartMode = IR_RX_AUTO_MODE;
+ IR_InitStruct->IR_RxFIFOThrLevel = 0;
+ IR_InitStruct->IR_RxFIFOFullCtrl = IR_RX_FIFO_FULL_DISCARD_NEWEST;
+ IR_InitStruct->IR_RxTriggerMode = IR_RX_FALL_EDGE;
+ IR_InitStruct->IR_RxFilterTime = IR_RX_FILTER_TIME_50ns;
+ IR_InitStruct->IR_RxCntThrType = IR_RX_Count_Low_Level;
+ IR_InitStruct->IR_RxCntThr = 0x23a; /* This value can be 0 to 0x7fffffff */
+ IR_InitStruct->IR_TxDmaEn = DISABLE; /* */
+ IR_InitStruct->IR_TxWaterLevel = 15; /* */
+ IR_InitStruct->IR_RxDmaEn = DISABLE; /* */
+ IR_InitStruct->IR_RxWaterLevel = 0; /* */
+}
+
+/**
+ * @brief Enable or disable the selected IR mode.
+ * @param mode: selected IR operation mode.
+ * This parameter can be the following values:
+ * @arg IR_MODE_TX: Transmission mode.
+ * @arg IR_MODE_RX: Receiving mode.
+ * @param NewState: new state of the operation mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void IR_Cmd(uint32_t mode, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_IR_MODE(mode));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ if (mode == IR_MODE_TX)
+ {
+ /* Start Transmission mode */
+ IR->TX_CONFIG |= IR_TX_START_Msk;
+ }
+ else
+ {
+ /* Start Receiving mode */
+ IR->RX_CONFIG |= IR_RX_START_Msk;
+ }
+ }
+ else
+ {
+ if (mode == IR_MODE_TX)
+ {
+ /* Stop Transmission mode */
+ IR->TX_CONFIG &= IR_TX_START_CLR;
+ }
+ else
+ {
+ /* Stop Receiving mode */
+ IR->RX_CONFIG &= IR_RX_START_CLR;
+ }
+ }
+}
+
+/**
+ * @brief Mask or unmask the specified IR interrupts.
+ * @param IR_INT: specifies the IR interrupts sources to be mask or unmask.
+ * This parameter can be the following values:
+ * @arg IR_INT_TF_EMPTY: TX FIFO empty interrupt.
+ * @arg IR_INT_TF_LEVEL: TX FIFO threshold interrupt.
+ * @arg IR_INT_TF_OF: TX FIFO overflow interrupt.
+ * @arg IR_INT_RF_FULL: RX FIFO full interrupt.
+ * @arg IR_INT_RF_LEVEL: RX FIFO threshold interrupt.
+ * @arg IR_INT_RX_CNT_OF: RX counter overflow interrupt.
+ * @arg IR_INT_RF_OF: RX FIFO overflow interrupt.
+ * @arg IR_INT_RX_CNT_THR: RX counter threshold interrupt.
+ * @arg IR_INT_RF_ERROR: RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO.
+ * @arg IR_INT_RISING_EDGE: IR RX Rising edge interrupt.
+ * @arg IR_INT_FALLING_EDGE: IR RX Falling edge interrupt.
+ * @param NewState: new state of the specified IR interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void IR_MaskINTConfig(uint32_t IR_INT, FunctionalState newState)
+{
+ /* Check the parameters */
+ assert_param(IS_IR_INT_CONFIG(IR_INT));
+ assert_param(IS_FUNCTIONAL_STATE(newState));
+
+ if (newState == ENABLE)
+ {
+ if ((IR->TX_CONFIG) & IR_MODE_SEL_Msk)
+ {
+ /* Enable the selected IR interrupts in RX mode */
+ if (IR_INT & IR_RX_EXTENSION_INT)
+ {
+ IR->RX_EX_INT |= (IR_INT & 0x03) << 2;
+ }
+ else
+ {
+ IR->RX_CONFIG |= (IR_INT << IR_RX_MSK_TO_EN_Pos);
+ }
+ }
+ else
+ {
+ /* Enable the selected IR interrupts in TX mode */
+ if (IR_INT == IR_INT_TF_OF)
+ {
+ IR->TX_CONFIG |= (IR_INT << IR_TX_FIFO_OVER_MSK_TO_EN_Pos);
+ }
+ else
+ {
+ IR->TX_CONFIG |= (IR_INT << IR_TX_MSK_TO_EN_Pos);
+ }
+ }
+ }
+ else
+ {
+ if ((IR->TX_CONFIG) & IR_MODE_SEL_Msk)
+ {
+ /* Disable the selected IR interrupts in RX mode */
+ if (IR_INT & IR_RX_EXTENSION_INT)
+ {
+ IR->RX_EX_INT &= ~((IR_INT & 0x03) << 2);
+ }
+ else
+ {
+ IR->RX_CONFIG &= (~(IR_INT << IR_RX_MSK_TO_EN_Pos));
+ }
+ }
+ else
+ {
+ /* Disable the selected IR interrupts in TX mode */
+ if (IR_INT == IR_INT_TF_OF)
+ {
+ IR->TX_CONFIG &= (~(IR_INT << IR_TX_FIFO_OVER_MSK_TO_EN_Pos));
+ }
+ else
+ {
+ IR->TX_CONFIG &= (~(IR_INT << IR_TX_MSK_TO_EN_Pos));
+ }
+ }
+ }
+}
+
+/**
+ * @brief Enables or disables the specified IR interrupts.
+ * @param IR_INT: specifies the IR interrupts sources to be enabled or disabled.
+ * This parameter can be the following values:
+ * @arg IR_INT_TF_EMPTY: TX FIFO empty interrupt.
+ * @arg IR_INT_TF_LEVEL: TX FIFO threshold interrupt.
+ * @arg IR_INT_TF_OF: TX FIFO overflow interrupt.
+ * @arg IR_INT_RF_FULL: RX FIFO full interrupt.
+ * @arg IR_INT_RF_LEVEL: RX FIFO threshold interrupt.
+ * @arg IR_INT_RX_CNT_OF: RX counter overflow interrupt.
+ * @arg IR_INT_RF_OF: RX FIFO overflow interrupt.
+ * @arg IR_INT_RX_CNT_THR: RX counter threshold interrupt.
+ * @arg IR_INT_RF_ERROR: RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO.
+ * @arg IR_INT_RISING_EDGE: IR RX Rising edge interrupt.
+ * @arg IR_INT_FALLING_EDGE: IR RX Falling edge interrupt.
+ * @param NewState: new state of the specified IR interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void IR_INTConfig(uint32_t IR_INT, FunctionalState newState)
+{
+ /* Check the parameters */
+ assert_param(IS_IR_INT_CONFIG(IR_INT));
+ assert_param(IS_FUNCTIONAL_STATE(newState));
+
+ if (newState == ENABLE)
+ {
+ if (IR->TX_CONFIG & IR_MODE_SEL_Msk)
+ {
+ /* Enable the selected IR interrupts in RX mode */
+ if (IR_INT & IR_RX_EXTENSION_INT)
+ {
+ IR->RX_EX_INT |= IR_INT & (~IR_RX_EXTENSION_INT);
+ }
+ else
+ {
+ IR->RX_CONFIG |= IR_INT;
+ }
+ }
+ else
+ {
+ /* Enable the selected IR interrupts in TX mode */
+ IR->TX_CONFIG |= IR_INT;
+ }
+ }
+ else
+ {
+ if (IR->TX_CONFIG & IR_MODE_SEL_Msk)
+ {
+ /* Disable the selected IR interrupts in RX mode */
+ if (IR_INT & IR_RX_EXTENSION_INT)
+ {
+ IR->RX_EX_INT &= ~(IR_INT & 0x03);
+ }
+ else
+ {
+ IR->RX_CONFIG &= (~IR_INT);
+ }
+ }
+ else
+ {
+ /* Disable the selected IR interrupts in TX mode */
+ IR->TX_CONFIG &= (~IR_INT);
+ }
+ }
+}
+
+/**
+ * @brief Start trigger only in manual receive mode.
+ * @param None.
+ * @retval None
+ */
+void IR_StartManualRxTrigger(void)
+{
+ /* Start Rx manual mode */
+ IR->RX_CONFIG |= IR_RX_MAN_START_Msk;
+}
+
+/**
+ * @brief Configure counter threshold value in receiving mode.You can use it to stop receiving IR data.
+ * @param IR_RxCntThrType:
+ * This parameter can be the following values:
+ * @arg IR_RX_Count_Low_Level: Low level counter value >= IR_RxCntThr, trigger IR_INT_RX_CNT_THR interrupt.
+ * @arg IR_RX_Count_High_Level: High level counter value >= IR_RxCntThr, trigger IR_INT_RX_CNT_THR interrupt.
+ * @param IR_RxCntThr: Configure IR Rx counter threshold value which can be 0 to 0x7fffffffUL.
+ * @retval None
+ */
+void IR_SetRxCounterThreshold(uint32_t IR_RxCntThrType, uint32_t IR_RxCntThr)
+{
+ /* Check the parameters */
+ assert_param(IS_IR_RX_COUNT_LEVEL_CTRL(IR_RxCntThrType));
+ assert_param(IS_IR_RX_COUNTER_THRESHOLD(IR_RxCntThr));
+
+ /* Configure IR RX counter threshold parameters */
+ IR->RX_CNT_INT_SEL = (IR_RxCntThrType) | (IR_RxCntThr);
+}
+
+/**
+ * @brief Send data.
+ * @param buf: data buffer to send.
+ * @param length: buffer length.
+ * @param IsLastPacket:
+ * This parameter can be the following values:
+ * @arg ENABLE: The last data in IR packet and there is no continuous data.In other words, An infrared data transmission is completed.
+ * @arg DISABLE: There is data to be transmitted continuously.
+ * @retval None
+ */
+void IR_SendBuf(uint32_t *pBuf, uint32_t len, FunctionalState IsLastPacket)
+{
+ uint32_t i = 0;
+
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(IsLastPacket));
+
+ if (len > 0)
+ {
+ i = len - 1;
+ while (i--)
+ {
+ IR->TX_FIFO = *pBuf++;
+ }
+
+ /* If send the last IR packet, SET the following bit */
+ if (IsLastPacket == ENABLE)
+ {
+ IR->TX_FIFO = (IR_TX_LAST_PACKEET_Msk | *pBuf);
+ }
+ else
+ {
+ IR->TX_FIFO = *pBuf;
+ }
+ }
+}
+
+/**
+ * @brief Send compensation data.
+ * @param comp_type:
+ * @arg IR_COMPEN_FLAG_1_2_CARRIER: 1/2 carrier freqency.
+ * @arg IR_COMPEN_FLAG_1_4_CARRIER: 1/4 carrier freqency.
+ * @arg IR_COMPEN_FLAG_1_N_SYSTEM_CLK: MOD((0x48[27:16]+0x00[11:0]), 4095)/40MHz.
+ User can call function of IR_ConfigCompParam to configure 0x48[27:16].
+ * @param buf: data buffer to send.
+ * @param length: buffer length.
+ * @param IsLastPacket:
+ * This parameter can be the following values:
+ * @arg ENABLE: The last data in IR packet and there is no continuous data.In other words, An infrared data transmission is completed.
+ * @arg DISABLE: There is data to be transmitted continuously.
+ * @retval None
+ */
+void IR_SendCompenBuf(IR_TX_COMPEN_TYPE comp_type, uint32_t *pBuf, uint32_t len,
+ FunctionalState IsLastPacket)
+{
+ uint32_t i = 0;
+
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(IsLastPacket));
+
+ if (len > 0)
+ {
+ i = len - 1;
+ while (i--)
+ {
+ if (*pBuf & IR_DATA_TYPE_Msk)
+ {
+ IR->TX_FIFO = *pBuf++;
+ }
+ else
+ {
+ IR->TX_FIFO = *pBuf++ | comp_type;
+ }
+ }
+
+ /* If send the last IR packet, SET the following bit */
+ if (IsLastPacket == ENABLE)
+ {
+ if (*pBuf & IR_DATA_TYPE_Msk)
+ {
+ IR->TX_FIFO = (IR_TX_LAST_PACKEET_Msk | *pBuf);
+ }
+ else
+ {
+ IR->TX_FIFO = (IR_TX_LAST_PACKEET_Msk | *pBuf | comp_type);
+ }
+ }
+ else
+ {
+ if (*pBuf & IR_DATA_TYPE_Msk)
+ {
+ IR->TX_FIFO = *pBuf;
+ }
+ else
+ {
+ IR->TX_FIFO = *pBuf | comp_type;
+ }
+ }
+ }
+}
+
+/**
+ * @brief Read data From RX FIO.
+ * @param buf: buffer address to receive data.
+ * @param length: read data length.
+ * @retval None
+ */
+void IR_ReceiveBuf(uint32_t *pBuf, uint32_t len)
+{
+ while (len--)
+ {
+ *pBuf++ = IR->RX_FIFO;
+ }
+}
+
+/**
+ * @brief Get the specified IR interrupt status.
+ * @param IR_INT: the specified IR interrupts.
+ * This parameter can be one of the following values:
+ * @arg IR_INT_TF_EMPTY: TX FIFO empty interrupt.
+ * @arg IR_INT_TF_LEVEL: TX FIFO threshold interrupt.
+ * @arg IR_INT_TF_OF: TX FIFO overflow interrupt.
+ * @arg IR_INT_RF_FULL: RX FIFO full interrupt.
+ * @arg IR_INT_RF_LEVEL: RX FIFO threshold interrupt.
+ * @arg IR_INT_RX_CNT_OF: RX counter overflow interrupt.
+ * @arg IR_INT_RF_OF: RX FIFO overflow interrupt.
+ * @arg IR_INT_RX_CNT_THR: RX counter threshold interrupt.
+ * @arg IR_INT_RF_ERROR: RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO.
+ * @arg IR_INT_RISING_EDGE: IR RX Rising edge interrupt.
+ * @arg IR_INT_FALLING_EDGE: IR RX Falling edge interrupt.
+ * @retval The new state of IR_INT (SET or RESET).
+ */
+ITStatus IR_GetINTStatus(uint32_t IR_INT)
+{
+ ITStatus bit_status = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_IR_INT_CONFIG(IR_INT));
+
+ if (IR->TX_CONFIG & IR_MODE_SEL_Msk)
+ {
+ /* Get the selected IR interrupts in RX mode */
+ if (IR_INT & IR_RX_EXTENSION_INT)
+ {
+ if ((IR->RX_EX_INT & ((IR_INT & 0x03) << 4)) != (uint32_t)RESET)
+ {
+ bit_status = SET;
+ }
+ }
+ else
+ {
+ if ((IR->RX_SR & IR_INT) != (uint32_t)RESET)
+ {
+ bit_status = SET;
+ }
+ }
+ }
+ else
+ {
+ /* Get the selected IR interrupts in TX mode */
+ if (IR_INT != IR_INT_TF_OF)
+ {
+ if ((IR->TX_SR & IR_INT) != (uint32_t)RESET)
+ {
+ bit_status = SET;
+ }
+ }
+ else
+ {
+ if ((IR->TX_SR & (IR_INT >> IR_TX_STATUS_TO_EN_Pos)) != (uint32_t)RESET)
+ {
+ bit_status = SET;
+ }
+ }
+ }
+
+ /* Return the IR_INT status */
+ return bit_status;
+}
+
+/**
+ * @brief Clears the IR interrupt pending bits.
+ * @param IR_IT: specifies the interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg IR_INT_TF_EMPTY_CLR: Clear TX FIFO empty interrupt.
+ * @arg IR_INT_TF_LEVEL_CLR: Clear TX FIFO threshold interrupt.
+ * @arg IR_INT_TF_OF_CLR: Clear TX FIFO overflow interrupt.
+ * @arg IR_INT_RF_FULL_CLR: Clear RX FIFO full interrupt.
+ * @arg IR_INT_RF_LEVEL_CLR: Clear RX FIFO threshold interrupt.
+ * @arg IR_INT_RX_CNT_OF_CLR: Clear RX counter overflow interrupt.
+ * @arg IR_INT_RF_OF_CLR: Clear RX FIFO overflow interrupt.
+ * @arg IR_INT_RX_CNT_THR_CLR: Clear RX counter threshold interrupt.
+ * @arg IR_INT_RF_ERROR_CLR: Clear RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO.
+ * @arg IR_INT_RX_RISING_EDGE_CLR: Clear RX Rising edge interrupt.
+ * @arg IR_INT_RX_FALLING_EDGE_CLR: Clear RX Falling edge interrupt.
+ * @retval None
+ */
+void IR_ClearINTPendingBit(uint32_t IR_CLEAR_INT)
+{
+ /* Check the parameters */
+ assert_param(IS_IR_INT_CLEAR(IR_CLEAR_INT));
+
+ if (IR->TX_CONFIG & IR_MODE_SEL_Msk)
+ {
+ /* Clear the selected IR interrupts in RX mode */
+ if (IR_CLEAR_INT & IR_RX_EXTENSION_INT)
+ {
+ IR->RX_EX_INT |= (IR_CLEAR_INT & 0xC0);
+ }
+ else
+ {
+ IR->RX_INT_CLR |= IR_CLEAR_INT;
+ }
+ }
+ else
+ {
+ /* Clear the selected IR interrupts in TX mode */
+ IR->TX_INT_CLR |= IR_CLEAR_INT;
+ }
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/mcu/peripheral/rtl876x_keyscan.c b/src/mcu/peripheral/rtl876x_keyscan.c
new file mode 100644
index 0000000..ed64b28
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_keyscan.c
@@ -0,0 +1,266 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_keyscan.c
+* @brief This file provides all the KEYSCAN firmware functions.
+* @details
+* @author tifnan_ge
+* @date 2015-04-30
+* @version v0.1
+*********************************************************************************************************
+*/
+
+#include "rtl876x_rcc.h"
+#include "rtl876x_keyscan.h"
+
+/**
+ * @brief Initializes the KeyScan peripheral according to the specified
+ * parameters in the KeyScan_InitStruct
+ * @param KeyScan: selected KeyScan peripheral.
+ * @param KeyScan_InitStruct: pointer to a KEYSCAN_InitTypeDef structure that
+ * contains the configuration information for the specified KeyScan peripheral
+ * @retval None
+ */
+void KeyScan_Init(KEYSCAN_TypeDef *KeyScan, KEYSCAN_InitTypeDef *KeyScan_InitStruct)
+{
+ assert_param(IS_KeyScan_PERIPH(KeyScan));
+ assert_param(IS_KEYSCAN_ROW_NUM(KeyScan_InitStruct->rowSize));
+ assert_param(IS_KEYSCAN_COL_NUM(KeyScan_InitStruct->colSize));
+ assert_param(IS_KEYSCAN_DEBOUNCE_EN(KeyScan_InitStruct->debounceEn));
+ assert_param(IS_KEYSCAN_DETECT_MODE(KeyScan_InitStruct->detectMode));
+ assert_param(IS_KEYSCAN_FIFO_OVR_CTRL(KeyScan_InitStruct->fifoOvrCtrl));
+ assert_param(IS_KEYSCAN_MAX_SCAN_DATA(KeyScan_InitStruct->maxScanData));
+
+ /* Set FSM to idle state */
+ KeyScan->CR &= ~BIT31;
+
+ /* Mask all keyscan interrupt */
+ KeyScan->INTMASK |= 0x1f;
+
+ /* clock divider config */
+ KeyScan->CLKDIV &= ~((0x3FF << 8) | 0x1F);
+ KeyScan->CLKDIV |= ((KeyScan_InitStruct->clockdiv << 8)\
+ | (KeyScan_InitStruct->delayclk));
+
+ /* Config scan mode and detect mode*/
+ KeyScan->CR = (KeyScan_InitStruct-> scanmode | KeyScan_InitStruct-> detectMode |
+ KeyScan_InitStruct-> manual_sel | KeyScan_InitStruct->fifoOvrCtrl);
+ /* fifo threshol setting */
+ KeyScan->CR |= (KeyScan_InitStruct ->fifotriggerlevel << 5);
+ /* key limit setting */
+ KeyScan->CR |= (KeyScan_InitStruct ->keylimit << 23);
+
+ /* time config */
+ KeyScan->TIMERCR = ((KeyScan_InitStruct ->debounceEn)\
+ | (KeyScan_InitStruct->detecttimerEn)\
+ | (KeyScan_InitStruct->scantimerEn));
+ /* time count config */
+ KeyScan->TIMERCR |= ((KeyScan_InitStruct->debouncecnt << 18)\
+ | (KeyScan_InitStruct->scanInterval << 9)\
+ | (KeyScan_InitStruct->releasecnt));
+
+ /* Set col map, config which col to work */
+ KeyScan->COLCR = ((((1 << KeyScan_InitStruct->colSize) - 1) << 8) \
+ | (KeyScan_InitStruct->colSize - 1));
+
+ /* Set col map, config which col to work */
+ KeyScan->ROWCR = ((KeyScan_InitStruct->rowSize - 1) << 16\
+ | ((1 << KeyScan_InitStruct->rowSize) - 1));
+
+ /* clear all interrupt status and status flag */
+ KeyScan->INTCLR |= 0xff;
+ /* Unmask all keyscan interrupt */
+ KeyScan->INTMASK &= ~0x1f;
+
+ return;
+}
+
+/**
+ * @brief Deinitializes the Keyscan peripheral registers to their default reset values(turn off keyscan clock).
+ * @param KeyScan: selected KeyScan peripheral.
+ * @retval None
+ */
+void KeyScan_DeInit(KEYSCAN_TypeDef *KeyScan)
+{
+ /* Check the parameters */
+ assert_param(IS_KeyScan_PERIPH(KeyScan));
+
+ RCC_PeriphClockCmd(APBPeriph_KEYSCAN, APBPeriph_KEYSCAN_CLOCK, DISABLE);
+
+ return;
+}
+
+
+/**
+ * @brief Fills each I2C_InitStruct member with its default value.
+ * @param KeyScan_InitStruct: pointer to a KEYSCAN_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void KeyScan_StructInit(KEYSCAN_InitTypeDef *KeyScan_InitStruct)
+{
+ KeyScan_InitStruct->colSize = 2;
+ KeyScan_InitStruct->rowSize = 2;
+
+ KeyScan_InitStruct->scanmode = KeyScan_Auto_Scan_Mode;
+ KeyScan_InitStruct->detectMode = KeyScan_Detect_Mode_Level;
+ KeyScan_InitStruct->clockdiv = 0x1f8;
+ KeyScan_InitStruct->delayclk = 0x01;
+ KeyScan_InitStruct->fifotriggerlevel = 1;
+ KeyScan_InitStruct->fifoOvrCtrl = KeyScan_FIFO_OVR_CTRL_DIS_LAST;
+
+ KeyScan_InitStruct->debounceEn = KeyScan_Debounce_Enable;
+ KeyScan_InitStruct->scantimerEn = KeyScan_ScanInterval_Enable;
+ KeyScan_InitStruct->detecttimerEn = KeyScan_Release_Detect_Enable;
+
+ KeyScan_InitStruct->scanInterval = 0x10;
+ KeyScan_InitStruct->debouncecnt = 0x10;
+ KeyScan_InitStruct->releasecnt = 0x1;
+
+ KeyScan_InitStruct->keylimit = 0x03;
+ KeyScan_InitStruct->manual_sel = KeyScan_Manual_Sel_Bit;
+
+ return;
+}
+
+/**
+ * @brief Enables or disables the specified KeyScan interrupts.
+ * @param KeyScan: selected KeyScan peripheral.
+ * @param KeyScan_IT: specifies the KeyScan interrupts sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg KEYSCAN_INT_TIMEOUT: KeyScan timeout interrupt mask
+ * @arg KEYSCAN_INT_OVER_THRESHOLD: Kescan FIFO data over threshold interrupt mask
+ * @arg KEYSCAN_INT_SCAN_END: KeyScan scan end interrupt mask
+ * @param NewState: new state of the specified KeyScan interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void KeyScan_INTConfig(KEYSCAN_TypeDef *KeyScan, uint32_t KeyScan_IT, FunctionalState newState)
+{
+ /* Check the parameters */
+ assert_param(IS_KeyScan_PERIPH(KeyScan));
+ assert_param(IS_FUNCTIONAL_STATE(newState));
+ assert_param(IS_KEYSCAN_CONFIG_IT(KeyScan_IT));
+
+ if (newState == ENABLE)
+ {
+ /* Enable the selected KeyScan interrupts */
+ KeyScan->CR |= KeyScan_IT;
+ }
+ else
+ {
+ /* Disable the selected KeyScan interrupts */
+ KeyScan->CR &= (uint32_t)~KeyScan_IT;
+ }
+}
+
+/**
+ * @brief Enables or disables the specified KeyScan interrupts mask.
+ * @param KeyScan: selected KeyScan peripheral.
+ * @param NewState: new state of the specified KeyScan interrupts mask.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void KeyScan_INTMask(KEYSCAN_TypeDef *KeyScan, uint32_t KeyScan_IT, FunctionalState newState)
+{
+ /* Check the parameters */
+ assert_param(IS_KeyScan_PERIPH(KeyScan));
+ assert_param(IS_FUNCTIONAL_STATE(newState));
+
+ if (newState == ENABLE)
+ {
+ /* mask KeyScan interrupts */
+ KeyScan->INTMASK |= KeyScan_IT;
+ }
+ else
+ {
+ /* enable KeyScan interrupts */
+ KeyScan->INTMASK &= (~KeyScan_IT);
+ }
+}
+
+/**
+ * @brief Read data from keyscan FIFO.
+ * @param KeyScan: selected KeyScan peripheral.
+ * @param[out] outBuf: buffer to save data read from KeyScan FIFO.
+ * @param count: number of data to be read.
+ * @retval None
+ */
+void KeyScan_Read(KEYSCAN_TypeDef *KeyScan, uint16_t *outBuf, uint16_t count)
+{
+ /* Check the parameters */
+ assert_param(IS_KeyScan_PERIPH(KeyScan));
+
+ uint16_t i = 0;
+
+ for (i = 0; i < count; i++)
+ {
+ *outBuf++ = (uint16_t)KeyScan->FIFODATA;
+ }
+
+ return;
+}
+
+/**
+ * @brief Enables or disables the KeyScan peripheral.
+ * @param KeyScan: selected KeyScan peripheral.
+ * @param NewState: new state of the KeyScan peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void KeyScan_Cmd(KEYSCAN_TypeDef *KeyScan, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_KeyScan_PERIPH(KeyScan));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected KeyScan peripheral */
+ /* In manual mode, bit22 must be write 1 to trigger scan,
+ and will be clear to 0 automatically after scan finish */
+ if (((KeyScan->CR & BIT30) == 0) && ((KeyScan->CR & BIT11) == 0))
+ {
+ KeyScan->CR |= BIT22;
+ }
+
+ KeyScan->CR |= BIT31;
+ }
+ else
+ {
+ /* Disable the selected KeyScan peripheral */
+ KeyScan->CR &= ~BIT31;
+ }
+}
+
+/**
+ * @brief Set filter data.
+ * @param KeyScan: selected KeyScan peripheral.
+ * @param data: config the data to be filtered.
+ * This parameter should not be more than 9 bits
+ * @retval none.
+ */
+void KeyScan_FilterDataConfig(KEYSCAN_TypeDef *KeyScan, uint16_t data, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_KeyScan_PERIPH(KeyScan));
+
+ if (NewState == ENABLE)
+ {
+ KeyScan->CR &= ~BIT21;
+
+ KeyScan->CR &= ~(0x1ff << 12);
+ KeyScan->CR |= ((data & 0x1ff) << 12);
+
+ KeyScan->CR |= BIT21;
+ }
+ else
+ {
+ KeyScan->CR &= ~BIT21;
+
+ KeyScan->CR &= ~(0x1ff << 12);
+ KeyScan->CR |= ((data & 0x1ff) << 12);
+ }
+
+ return;
+}
diff --git a/src/mcu/peripheral/rtl876x_lpc.c b/src/mcu/peripheral/rtl876x_lpc.c
new file mode 100644
index 0000000..26c15a3
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_lpc.c
@@ -0,0 +1,379 @@
+/**
+**********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_lpc.c
+* @brief This file provides all the lpcomp firmware functions.
+* @details
+* @author yuan
+* @date 2020-11-16
+* @version v1.0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_lpc.h"
+
+/* Internal defines ------------------------------------------------------------*/
+/* Fast operation register address defines */
+#define REG_FAST_WRITE_BASE_ADDR (0x40000100UL)
+#define REG_LPC_FAST_WDATA (0x400001f0UL)
+#define REG_LPC_FAST_ADDR (0x400001f4UL)
+#define REG_LPC_WR_STROBE (0x400001f8UL)
+/* AON register address defines */
+#define LPC_AON_52 (0x52)
+#define LPC_AON_114 (0x114)
+
+/**
+ * @brief Fast write LPC register
+ * @param address: the address of LPC register .
+ * @param data: dta which write to LPC register.
+ * @retval None
+ */
+void LPC_WriteReg(uint32_t offset, uint32_t data)
+{
+ static bool is_called = false;
+
+ if (is_called == false)
+ {
+ *((volatile uint32_t *)0x40000014) |= BIT(9);//no need run this every time
+ is_called = true;
+ }
+
+ /* Write data */
+ *((volatile uint32_t *)REG_LPC_FAST_WDATA) = data;
+ /* Write RTC register address. Only offset */
+ *((volatile uint32_t *)REG_LPC_FAST_ADDR) = offset - REG_FAST_WRITE_BASE_ADDR;
+ *((volatile uint32_t *)REG_LPC_WR_STROBE) = 1;
+}
+
+/**
+ * @brief Reset LPC.
+ * @param None
+ * @return None
+ */
+void LPC_DeInit(void)
+{
+ /* Disable the LPC power */
+ uint16_t reg_value = btaon_fast_read_safe(LPC_AON_114);
+ reg_value &= LPC_AON_114_POWER_EN_CLR;
+ btaon_fast_write_safe(LPC_AON_114, reg_value);
+
+ /* Stop LPC counter */
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_COUNTER_START_CLR));
+
+ /* Disable out signal */
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_LPCOMP_OUTPUT_EN_CLR));
+
+ /* Disable int signal */
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_INT_LPCOMP_AON_EN_CLR));
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_INT_LPCOMP_NV_EN_CLR));
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_INT_LPCOMP_CNT_EN_CLR));
+
+ /* Clear LPC comp value */
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CMP)), 0);
+
+ /* Reset counter */
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), LPC->LPC_CR0 | LPC_COUNTER_RESET_Msk);
+ __NOP();
+ __NOP();
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), LPC->LPC_CR0 & LPC_COUNTER_RESET_CLR);
+}
+
+/**
+ * @brief Initializes LPC peripheral according to
+ * the specified parameters in the LPC_InitStruct.
+ * @param LPC_InitStruct: pointer to a LPC_InitTypeDef
+ * structure that contains the configuration information for the
+ * specified LPC peripheral.
+ * @retval None
+ */
+void LPC_Init(LPC_InitTypeDef *LPC_InitStruct)
+{
+ uint16_t reg_value = 0;
+
+ /* Check the parameters */
+ assert_param(IS_LPC_CHANNEL(LPC_InitStruct->LPC_Channel));
+ assert_param(IS_LPC_EDGE(LPC_InitStruct->LPC_Edge));
+ assert_param(IS_LPC_THRESHOLD(LPC_InitStruct->LPC_Threshold));
+
+ /* Configure parameters */
+ reg_value = btaon_fast_read_safe(LPC_AON_52);
+ reg_value &= LPC_AON_52_THRESHOLD_Clr;
+ reg_value |= LPC_InitStruct->LPC_Threshold & LPC_AON_52_THRESHOLD_Msk;
+ btaon_fast_write_safe(LPC_AON_52, reg_value);
+
+ reg_value = btaon_fast_read_safe(LPC_AON_114);
+ reg_value &= LPC_AON_114_DEFAULT_Clr;
+ reg_value |= ((LPC_InitStruct->LPC_Channel) << LPC_AON_114_CH_NUM_Pos) | \
+ (LPC_InitStruct->LPC_Edge);
+ btaon_fast_write_safe(LPC_AON_114, reg_value);
+
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), LPC->LPC_CR0 | LPC_LPCOMP_CNT_CLEAR_Msk);
+ __NOP();
+ __NOP();
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), LPC->LPC_CR0 & LPC_LPCOMP_CNT_CLEAR_CLR);
+}
+
+/**
+ * @brief Fills each LPC_InitStruct member with its default value.
+ * @param LPC_InitStruct : pointer to a LPC_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void LPC_StructInit(LPC_InitTypeDef *LPC_InitStruct)
+{
+ LPC_InitStruct->LPC_Channel = LPC_CHANNEL_P2_2;
+ LPC_InitStruct->LPC_Edge = LPC_Vin_Below_Vth;
+ LPC_InitStruct->LPC_Threshold = LPC_2000_mV;
+}
+
+/**
+ * @brief Enables or disables LPC peripheral.
+ * @param NewState: new state of LPC peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void LPC_Cmd(FunctionalState NewState)
+{
+ uint16_t reg_value = 0;
+
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the LPC power */
+ reg_value = btaon_fast_read_safe(LPC_AON_114);
+ reg_value |= LPC_AON_114_POWER_EN_Msk;
+ btaon_fast_write_safe(LPC_AON_114, reg_value);
+ }
+ else
+ {
+ /* Disable the LPC power */
+ reg_value = btaon_fast_read_safe(LPC_AON_114);
+ reg_value &= LPC_AON_114_POWER_EN_CLR;
+ btaon_fast_write_safe(LPC_AON_114, reg_value);
+ }
+}
+
+/**
+ * @brief Start or stop the LPC counter.
+ * @param NewState: new state of the LPC counter.
+ * This parameter can be one of the following values:
+ * @arg ENABLE: Start LPCOMP counter.
+ * @arg DISABLE: Stop LPCOMP counter.
+ * @retval None
+ */
+void LPC_CounterCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Start the LPCOMP counter */
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), ((LPC->LPC_CR0) | LPC_COUNTER_START_Msk));
+ }
+ else
+ {
+ /* Stop the LPCOMP counter */
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), ((LPC->LPC_CR0) & (LPC_COUNTER_START_CLR)));
+ }
+}
+
+/**
+ * @brief Enables or disables the specified LPC interrupts.
+ * @param LPC_INT: specifies the LPC interrupt source to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * @arg LPC_INT_LPCOMP_VOL: voltage detection interrupt.
+ * @arg LPC_INT_LPCOMP_CNT: low power comparator couter interrupt.
+ * @param NewState: new state of the specified LPC interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void LPC_INTConfig(uint32_t LPC_INT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_LPC_CONFIG_INT(LPC_INT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected LPC interrupt */
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), ((LPC->LPC_CR0) | LPC_INT));
+ }
+ else
+ {
+ /* Disable the selected LPC interrupt */
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), ((LPC->LPC_CR0) & (~LPC_INT)));
+ }
+}
+
+/**
+ * @brief Enable interrupt signal to CPU NVIC.
+ * @param This parameter can be: ENABLE or DISABLE.
+ * @return None.
+ */
+void LPC_INTCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 | LPC_INT_LPCOMP_NV_EN_Msk));
+ }
+ else
+ {
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_INT_LPCOMP_NV_EN_CLR));
+ }
+}
+
+/**
+ * @brief Enable wakeup signal to power sequence.
+ * @param This parameter can be: ENABLE or DISABLE.
+ * @return None.
+ */
+void LPC_WKCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 | LPC_INT_LPCOMP_AON_EN_Msk));
+ }
+ else
+ {
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_INT_LPCOMP_AON_EN_CLR));
+ }
+}
+
+/**
+ * @brief Configure LPCOMP counter's comparator value.
+ * @param value: LPCOMP counter's comparator value which can be 0 to 0xfff.
+ * @retval None
+ */
+void LPC_SetCompValue(uint32_t value)
+{
+ LPC_WriteReg((uint32_t) & (LPC->LPC_CMP), (value & 0xFFF));
+}
+
+/**
+ * @brief Reset the LPC counter.
+ * @retval none
+ */
+void LPC_ResetCounter(void)
+{
+ /* Reset the LPCOMP counter */
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 | LPC_COUNTER_RESET_Msk));
+ __NOP();
+ __NOP();
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_COUNTER_RESET_CLR));
+}
+
+/**
+ * @brief Checks whether the specified LPC interrupt is set or not.
+ * @param LPC_FLAG: specifies the LPC interrupt to check.
+ * This parameter can be one of the following values:
+ * @arg LPC_FLAG_LPCOMP_AON: couter comparator AON flag.
+ * @arg LPC_FLAG_LPCOMP_CNT: couter comparator flag.
+ * @retval The new state of SPI_IT (SET or RESET).
+ */
+FlagStatus LPC_GetFlagStatus(uint32_t LPC_FLAG)
+{
+ ITStatus int_status = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_LPC_STATUS_INT(LPC_FLAG));
+
+ if (LPC_FLAG == LPC_FLAG_LPCOMP_AON)
+ {
+ if (((LPC->LPC_SR) & LPC_LPCOMP_OUTPUT_AON_Msk) != (uint32_t)RESET)
+ {
+ int_status = SET;
+ }
+ }
+ else if (LPC_FLAG == LPC_FLAG_LPCOMP_CNT)
+ {
+ if (((LPC->LPC_SR) & LPC_LPCOMP_CNT_Msk) != (uint32_t)RESET)
+ {
+ int_status = SET;
+ }
+ }
+
+ /* Return the LPC_FLAG status */
+ return int_status;
+}
+
+/**
+ * @brief Clear the specified LPC interrupt.
+ * @param LPC_FLAG: specifies the LPC interrupt to clear.
+ * This parameter can be one of the following values:
+ * @arg LPC_INT_COUNT_COMP: couter comparator interrupt.
+ * @retval None
+ */
+void LPC_ClearFlag(uint32_t LPC_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_LPC_CLEAR_INT(LPC_FLAG));
+
+ /* Clear counter comparator interrupt */
+ if (LPC_FLAG == LPC_FLAG_LPCOMP_CNT)
+ {
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), ((LPC->LPC_CR0) | LPC_LPCOMP_CNT_CLEAR_Msk));
+ __NOP();
+ __NOP();
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_LPCOMP_CNT_CLEAR_CLR));
+ }
+}
+
+/**
+ * @brief Checks whether the specified LPC interrupt is set or not.
+ * @param LPC_INT: specifies the LPC interrupt to check.
+ * This parameter can be one of the following values:
+ * @arg LPC_INT_COUNT_COMP: couter comparator interrupt.
+ * @retval The new state of SPI_IT (SET or RESET).
+ */
+ITStatus LPC_GetINTStatus(uint32_t LPC_INT)
+{
+ ITStatus int_status = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_LPC_STATUS_INT(LPC_INT));
+
+ if (LPC_INT == LPC_INT_LPCOMP_CNT)
+ {
+ if (((LPC->LPC_SR) & LPC_LPCOMP_CNT_Msk) != (uint32_t)RESET)
+ {
+ int_status = SET;
+ }
+ }
+
+ /* Return the LPC_INT status */
+ return int_status;
+}
+
+/**
+ * @brief Clear the specified LPC interrupt.
+ * @param LPC_INT: specifies the LPC interrupt to clear.
+ * This parameter can be one of the following values:
+ * @arg LPC_INT_COUNT_COMP: couter comparator interrupt.
+ * @retval None.
+ */
+void LPC_ClearINTPendingBit(uint32_t LPC_INT)
+{
+ /* Check the parameters */
+ assert_param(IS_LPC_CLEAR_INT(LPC_INT));
+
+ /* Clear counter comparator interrupt */
+ if (LPC_INT == LPC_INT_LPCOMP_CNT)
+ {
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), ((LPC->LPC_CR0) | LPC_LPCOMP_CNT_CLEAR_Msk));
+ __NOP();
+ __NOP();
+ LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_LPCOMP_CNT_CLEAR_CLR));
+ }
+}
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/mcu/peripheral/rtl876x_nvic.c b/src/mcu/peripheral/rtl876x_nvic.c
new file mode 100644
index 0000000..f438338
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_nvic.c
@@ -0,0 +1,64 @@
+/**
+**********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_nvic.c
+* @brief This file provides all the NVIC firmware functions.
+* @details
+* @author elliot chen
+* @date 2015-05-19
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_nvic.h"
+
+/**
+ * @brief Initializes the NVIC peripheral according to the specified
+ * parameters in the NVIC_InitStruct.
+ * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains
+ * the configuration information for the specified NVIC peripheral.
+ * @retval None
+ */
+void NVIC_Init(NVIC_InitTypeDef *NVIC_InitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
+
+ if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
+ {
+ if (NVIC_InitStruct->NVIC_IRQChannel >= Peripheral_First_IRQn)
+ {
+ PERIPHINT->EN |= BIT(NVIC_InitStruct->NVIC_IRQChannel - Peripheral_First_IRQn);
+ NVIC_InitStruct->NVIC_IRQChannel = Peripheral_IRQn;
+ }
+
+ NVIC_ClearPendingIRQ(NVIC_InitStruct->NVIC_IRQChannel);
+ NVIC_SetPriority(NVIC_InitStruct->NVIC_IRQChannel,
+ NVIC_InitStruct->NVIC_IRQChannelPriority);
+ NVIC_EnableIRQ(NVIC_InitStruct->NVIC_IRQChannel);
+ }
+ else
+ {
+ if (NVIC_InitStruct->NVIC_IRQChannel >= Peripheral_First_IRQn)
+ {
+ PERIPHINT->EN &= ~BIT(NVIC_InitStruct->NVIC_IRQChannel - Peripheral_First_IRQn);
+
+ if (PERIPHINT->EN == 0)
+ {
+ /* Disable Peripheral IRQ Channel */
+ NVIC_DisableIRQ(Peripheral_IRQn);
+ }
+ }
+ else
+ {
+ /* Disable the Selected IRQ Channels */
+ NVIC_DisableIRQ(NVIC_InitStruct->NVIC_IRQChannel);
+ }
+ }
+}
+
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/mcu/peripheral/rtl876x_pinmux.c b/src/mcu/peripheral/rtl876x_pinmux.c
new file mode 100644
index 0000000..98a0ee7
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_pinmux.c
@@ -0,0 +1,501 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_pinmux.c
+* @brief This file provides all the PINMUX firmware functions.
+* @details
+* @author Yuan
+* @date 2020-11-09
+* @version v1.0.0
+*********************************************************************************************************
+*/
+
+#include "rtl876x_rcc.h"
+#include "rtl876x_pinmux.h"
+
+const uint16_t PINADDR_TABLE[MAX_PIN_NUM] = //static
+{
+ 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xa0, 0xa2, 0xa4,
+ 0xea, 0xec, 0xee, 0xf0, 0xf2, 0x80, 0x82, 0x84,
+ 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce,
+ 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x00,
+ 0xa6, 0xa8, 0xaa, 0xac, 0xd0, 0x96, 0x98
+};
+
+const uint16_t WKSTATUS_TABLE[MAX_PIN_NUM] =
+{
+ // Px-0 Px-1 Px-2 Px-3 Px-4 Px-5 Px-6 Px-7
+ ((0 << 12) | 0xf4), ((1 << 12) | 0xf4), ((2 << 12) | 0xf4), ((3 << 12) | 0xf4), ((4 << 12) | 0xf4), ((0 << 12) | 0xae), ((1 << 12) | 0xae), ((2 << 12) | 0xae),
+ ((5 << 12) | 0xf4), ((6 << 12) | 0xf4), ((7 << 12) | 0xf4), ((8 << 12) | 0xf4), ((9 << 12) | 0xf4), ((0 << 12) | 0x9a), ((1 << 12) | 0x9a), ((2 << 12) | 0x9a),
+ ((0 << 12) | 0xd2), ((1 << 12) | 0xd2), ((2 << 12) | 0xd2), ((3 << 12) | 0xd2), ((4 << 12) | 0xd2), ((5 << 12) | 0xd2), ((6 << 12) | 0xd2), ((7 << 12) | 0xd2),
+ ((3 << 12) | 0x9a), ((4 << 12) | 0x9a), ((5 << 12) | 0x9a), ((6 << 12) | 0x9a), ((7 << 12) | 0x9a), ((8 << 12) | 0x9a), ((9 << 12) | 0x9a), ((0 << 00) | 0x00),
+ ((3 << 12) | 0xae), ((4 << 12) | 0xae), ((5 << 12) | 0xae), ((6 << 12) | 0xae), ((8 << 12) | 0xd2), ((11 << 12) | 0x9a), ((12 << 12) | 0x9a)
+};
+
+/**
+ * @brief Reset all pin to default value.
+ * @param None.
+ * @note: two SWD pins will also be reset. Please use this function carefully.
+ * @retval None
+ */
+void Pinmux_Reset(void)
+{
+ uint8_t i;
+
+ for (i = 0; i < 10; i++)
+ {
+ PINMUX->CFG[i] = 0x00;
+ }
+
+ return;
+}
+
+/**
+ * @brief Deinit the IO function of one pin.
+ * @param Pin_Num: pin number.
+ * This parameter is from ADC_0 to P4_1, please refer to rtl876x.h "Pin_Number" part.
+ * @retval None
+ */
+void Pinmux_Deinit(uint8_t Pin_Num)
+{
+ uint8_t pinmux_reg_num;
+
+ pinmux_reg_num = Pin_Num >> 2;
+ PINMUX->CFG[pinmux_reg_num] &= ~(0xff << ((Pin_Num % 4) << 3));
+ return;
+}
+
+/**
+ * @brief Config pin to its corresponding IO function.
+ * @param Pin_Num: pin number.
+ * This parameter is from ADC_0 to P4_1, please refer to rtl876x.h "Pin_Number" part.
+ * @param Pin_Func: mean one IO function, please refer to rtl876x_pinmux.h "Pin_Function_Number" part.
+ * @retval None
+ */
+void Pinmux_Config(uint8_t Pin_Num, uint8_t Pin_Func)
+{
+ uint8_t pinmux_reg_num;
+ uint8_t reg_offset;
+
+ pinmux_reg_num = Pin_Num >> 2;
+ reg_offset = (Pin_Num & 0x03) << 3;
+
+ PINMUX->CFG[pinmux_reg_num] = (PINMUX->CFG[pinmux_reg_num] & ~(0xFF << reg_offset))
+ | Pin_Func << reg_offset;
+
+ return;
+}
+
+/**
+ * @brief config the corresponding pad.
+ * @param Pin_Num: pin number.
+ * This parameter is from ADC_0 to P4_1, please refer to rtl876x.h "Pin_Number" part.
+ * @param AON_PAD_MODE: use software mode or pinmux mode.
+ * This parameter can be one of the following values:
+ * @arg PAD_SW_MODE: use software mode.
+ * @arg PAD_PINMUX_MODE: use pinmux mode.
+ * @param AON_PAD_PwrOn: config power of pad.
+ * This parameter can be one of the following values:
+ * @arg PAD_NOT_PWRON: shutdown power of pad.
+ * @arg PAD_IS_PWRON: enable power of pad.
+ * @param AON_PAD_Pull: config pad pull mode.
+ * This parameter can be one of the following values:
+ * @arg PAD_PULL_NONE: no pull.
+ * @arg PAD_PULL_UP: pull this pin up.
+ * @arg PAD_PULL_DOWN: pull thi pin down.
+ * @param AON_PAD_E: config pad out put function.
+ * This parameter can be one of the following values:
+ * @arg PAD_OUT_DISABLE: disable pin output.
+ * @arg PAD_OUT_ENABLE: enable pad output.
+ * @param AON_PAD_O: config pin output level.
+ * This parameter can be one of the following values:
+ * @arg PAD_OUT_LOW: pad output low.
+ * @arg PAD_OUT_HIGH: pad output high.
+ * @retval None
+ */
+
+void Pad_Config(uint8_t Pin_Num,
+ PAD_Mode AON_PAD_Mode,
+ PAD_PWR_Mode AON_PAD_PwrOn,
+ PAD_Pull_Mode AON_PAD_Pull,
+ PAD_OUTPUT_ENABLE_Mode AON_PAD_E,
+ PAD_OUTPUT_VAL AON_PAD_O)
+{
+ uint16_t tmpVal;
+ uint8_t addr = PINADDR_TABLE[Pin_Num];
+
+ tmpVal = btaon_fast_read_safe(addr);
+
+ /* Clear reg value first*/
+ tmpVal &= ~0xF;
+
+ /* Pull Config */
+ if (AON_PAD_Pull == PAD_PULL_UP)
+ {
+ tmpVal |= Pull_En;
+ }
+ else if (AON_PAD_Pull == PAD_PULL_DOWN)
+ {
+ tmpVal |= (Pull_En | Pull_Direction);
+ }
+
+ /* Output Config */
+ tmpVal |= (AON_PAD_O | (AON_PAD_E << 1));
+
+ if (AON_PAD_Mode)
+ {
+ tmpVal |= Pin_Mode;
+ }
+ else
+ {
+ tmpVal &= ~Pin_Mode;
+ }
+
+ btaon_fast_write_safe(addr, tmpVal | SHDN);
+
+ /* Pad control mode */
+ if (AON_PAD_PwrOn == PAD_NOT_PWRON)
+ {
+ tmpVal &= ~SHDN;
+ btaon_fast_write_safe(addr, tmpVal);
+ }
+
+}
+
+/**
+ * @brief Enable pin wakeup function.
+ * @param Pin_Num: pin number.
+ * This parameter is from ADC_0 to P4_1, please refer to rtl876x.h "Pin_Number" part.
+ * @param Polarity: PAD_WAKEUP_POL_HIGH--use high level wakeup, PAD_WAKEUP_POL_LOW-- use low level wakeup.
+ * @retval None
+ */
+void System_WakeUpPinEnable(uint8_t Pin_Num, uint8_t Polarity, uint8_t DebounceEn)
+{
+ Pad_WakeupPolarityValue(Pin_Num, Polarity);
+ Pad_WKDebounceConfig(Pin_Num, DebounceEn);
+ Pad_WakeupEnableValue(Pin_Num, 1);
+}
+
+/**
+ * @brief Disable pin wakeup function.
+ * @param Pin_Num: pin number.
+ * This parameter is from ADC_0 to P4_1, please refer to rtl876x.h "Pin_Number" part.
+ * @retval None
+ */
+
+void System_WakeUpPinDisable(uint8_t Pin_Num)
+{
+ Pad_WakeupEnableValue(Pin_Num, 0);
+}
+
+//1ms~64ms
+void System_WakeUpDebounceTime(uint8_t time)
+{
+ uint16_t tmpVal;
+ tmpVal = btaon_fast_read_safe(0x2a);
+ /* clear reg value first */
+ tmpVal &= ~(0x3f00);
+ /* set value */
+ tmpVal |= (time & 0x3f) << 8;
+ /* clear debounce status */
+ tmpVal |= (BIT15 | BIT14);
+ btaon_fast_write_safe(0x2a, tmpVal);
+}
+
+/**
+ * @brief Check debounce wake up status.
+ * @note: Call this API will clear the debunce wakeup status bit.
+ * @param None
+ * @retval Debounce wakeup status
+ */
+uint8_t System_DebounceWakeupStatus(void)
+{
+ return Pad_DebounceWakeupStatus();
+}
+
+/**
+ * @brief Check wake up pin interrupt status.
+ * @param Pin_Num: pin number.
+ * This parameter is from ADC_0 to P4_1, please refer to rtl876x.h "Pin_Number" part.
+ * @retval Pin interrupt status
+ */
+uint8_t System_WakeUpInterruptValue(uint8_t Pin_Num)
+{
+ return Pad_WakeupInterruptValue(Pin_Num);
+}
+
+void Pad_OutputControlValue(uint8_t Pin_Num, uint8_t value)
+{
+ uint16_t tmpVal;
+ uint8_t addr = PINADDR_TABLE[Pin_Num];
+
+ tmpVal = btaon_fast_read_safe(addr);
+ if (value)
+ {
+ tmpVal |= Output_Val;
+ }
+ else
+ {
+ tmpVal &= ~Output_Val;
+ }
+ btaon_fast_write_safe((addr), tmpVal);
+}
+
+void Pad_OutputEnableValue(uint8_t Pin_Num, uint8_t value)//0xf6
+{
+ uint16_t tmpVal;
+ uint8_t addr = PINADDR_TABLE[Pin_Num];
+
+ tmpVal = btaon_fast_read_safe(addr);
+ if (value)
+ {
+ tmpVal |= Output_En;
+ }
+ else
+ {
+ tmpVal &= ~Output_En;
+ }
+ btaon_fast_write_safe((addr), tmpVal);
+}
+
+void Pad_PullEnableValue(uint8_t Pin_Num, uint8_t value)
+{
+ uint16_t tmpVal;
+ uint8_t addr = PINADDR_TABLE[Pin_Num];
+
+ tmpVal = btaon_fast_read_safe(addr);
+ if (value)
+ {
+ tmpVal |= Pull_En;
+ }
+ else
+ {
+ tmpVal &= ~Pull_En;
+ }
+ btaon_fast_write_safe((addr), tmpVal);
+}
+
+void Pad_PullUpOrDownValue(uint8_t Pin_Num, uint8_t value)
+{
+ uint16_t tmpVal;
+ uint8_t addr = PINADDR_TABLE[Pin_Num];
+
+ tmpVal = btaon_fast_read_safe(addr);
+ if (value)
+ {
+ tmpVal |= Pull_Direction;
+ }
+ else
+ {
+ tmpVal &= ~Pull_Direction;
+ }
+ btaon_fast_write_safe((addr), tmpVal);
+}
+
+void Pad_PullConfigValue(uint8_t Pin_Num, uint8_t value)
+{
+ uint16_t tmpVal;
+ uint8_t addr = PINADDR_TABLE[Pin_Num];
+
+ tmpVal = btaon_fast_read_safe(addr);
+ if (value)
+ {
+ tmpVal |= Pull_Resistance;
+ }
+ else
+ {
+ tmpVal &= ~(Pull_Resistance);
+ }
+ btaon_fast_write_safe(addr, tmpVal);
+}
+
+void Pad_PowerOrShutDownValue(uint8_t Pin_Num, uint8_t value)
+{
+ uint16_t tmpVal;
+ uint8_t addr = PINADDR_TABLE[Pin_Num];
+
+ tmpVal = btaon_fast_read_safe(addr);
+ if (value)
+ {
+ tmpVal |= SHDN;
+ }
+ else
+ {
+ tmpVal &= ~SHDN;
+ }
+ btaon_fast_write_safe((addr), tmpVal);
+}
+
+void Pad_ControlSelectValue(uint8_t Pin_Num, uint8_t value)
+{
+ uint16_t tmpVal;
+ uint8_t addr = PINADDR_TABLE[Pin_Num];
+
+ tmpVal = btaon_fast_read_safe(addr);
+ if (value)
+ {
+ tmpVal |= Pin_Mode;
+ }
+ else
+ {
+ tmpVal &= ~Pin_Mode;
+ }
+ btaon_fast_write_safe((addr), tmpVal);
+}
+
+void Pad_WakeupEnableValue(uint8_t Pin_Num, uint8_t value)
+{
+ uint16_t tmpVal;
+ uint8_t addr = PINADDR_TABLE[Pin_Num];
+
+ tmpVal = btaon_fast_read_safe(addr);
+ if (value)
+ {
+ tmpVal |= WakeUp_En;
+ }
+ else
+ {
+ tmpVal &= ~WakeUp_En;
+ }
+ btaon_fast_write_safe((addr), tmpVal);
+}
+
+void Pad_WakeupPolarityValue(uint8_t Pin_Num, uint8_t value)
+{
+ uint16_t tmpVal;
+ uint8_t addr = PINADDR_TABLE[Pin_Num];
+
+ tmpVal = btaon_fast_read_safe(addr);
+ if (value)
+ {
+ tmpVal |= WKPOL;
+ }
+ else
+ {
+ tmpVal &= ~WKPOL;
+ }
+ btaon_fast_write_safe((addr), tmpVal);
+}
+
+void Pad_WKDebounceConfig(uint8_t Pin_Num, uint8_t value)
+{
+ uint16_t tmpVal;
+ uint8_t addr = PINADDR_TABLE[Pin_Num];
+
+ tmpVal = btaon_fast_read_safe(addr);
+ if (value)
+ {
+ tmpVal |= Pin_Debounce;
+ }
+ else
+ {
+ tmpVal &= ~Pin_Debounce;
+ }
+ btaon_fast_write_safe((addr), tmpVal);
+}
+
+uint8_t Pad_WakeupInterruptValue(uint8_t Pin_Num)
+{
+ uint16_t reg_temp;
+ uint16_t bit_temp;
+ uint16_t temp_value = 0;
+ uint8_t int_value = RESET;
+
+ reg_temp = (WKSTATUS_TABLE[Pin_Num] & ~(0xf000));
+ bit_temp = BIT((WKSTATUS_TABLE[Pin_Num] & (0xf000)) >> 12);
+ temp_value = btaon_fast_read_safe(reg_temp);
+ if (temp_value & bit_temp)
+ {
+ int_value = SET;
+ }
+ return int_value;
+}
+
+uint8_t Pad_DebounceWakeupStatus(void)
+{
+ uint16_t value16 = 0;
+ uint8_t status_value = RESET;
+
+ value16 = btaon_fast_read_safe(0x2a);
+ if (value16 & BIT15)
+ {
+ status_value = SET;
+ }
+ //Write 1 to clear debounceWakeupStatus
+ btaon_fast_write_safe(0x2a, (value16 | BIT15));
+ return status_value;
+}
+
+void Pad_ClearWakeupINTPendingBit(uint8_t Pin_Num)
+{
+ uint16_t reg_temp;
+ uint16_t bit_temp;
+ uint16_t reg_value = 0;
+
+ reg_temp = (WKSTATUS_TABLE[Pin_Num] & ~(0xf000));
+ bit_temp = BIT((WKSTATUS_TABLE[Pin_Num] & (0xf000)) >> 12);
+ reg_value = btaon_fast_read_safe(reg_temp) | bit_temp;
+ btaon_fast_write_safe(reg_temp, reg_value);
+}
+
+/**
+ * @brief Clear all wake up pin interrupt pending bit.
+ * @return None
+ */
+void Pad_ClearAllWakeupINT(void)
+{
+ uint16_t tmpVal;
+
+ tmpVal = btaon_fast_read_safe(0x9a);
+ tmpVal |= 0x1BFF;
+ btaon_fast_write_safe(0x9a, tmpVal);
+
+ tmpVal = btaon_fast_read_safe(0xae);
+ tmpVal |= 0x7F;
+ btaon_fast_write_safe(0xae, tmpVal);
+
+ tmpVal = btaon_fast_read_safe(0xd2);
+ tmpVal |= 0x1FF;
+ btaon_fast_write_safe(0xd2, tmpVal);
+
+ tmpVal = btaon_fast_read_safe(0xf4);
+ tmpVal |= 0x3FF;
+ btaon_fast_write_safe(0xf4, tmpVal);
+}
+
+/**
+ * @brief Spic0 master enable.
+ * @param value: 0:Disable 1:Enable .
+ * @retval None
+ */
+void Spic0_control(uint8_t value)
+{
+ if (value)
+ {
+ HAL_WRITE32(SYSTEM_REG_BASE, REG_TEST_MODE, HAL_READ32(SYSTEM_REG_BASE, REG_TEST_MODE) | BIT(24));
+ }
+ else
+ {
+ HAL_WRITE32(SYSTEM_REG_BASE, REG_TEST_MODE, HAL_READ32(SYSTEM_REG_BASE,
+ REG_TEST_MODE) & (~BIT(24)));
+ }
+}
+/**
+ * @brief Spic1 master enable.
+ * @param value: 0:Disable 1:Enable .
+ * @retval None
+ */
+void Spic1_control(uint8_t value)
+{
+ if (value)
+ {
+ HAL_WRITE32(SYSTEM_REG_BASE, REG_TEST_MODE, HAL_READ32(SYSTEM_REG_BASE, REG_TEST_MODE) | BIT(8));
+ }
+ else
+ {
+ HAL_WRITE32(SYSTEM_REG_BASE, REG_TEST_MODE, HAL_READ32(SYSTEM_REG_BASE, REG_TEST_MODE) & (~BIT(8)));
+ }
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor *****END OF FILE****/
diff --git a/src/mcu/peripheral/rtl876x_qdec.c b/src/mcu/peripheral/rtl876x_qdec.c
new file mode 100644
index 0000000..4b7027f
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_qdec.c
@@ -0,0 +1,315 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_qdec.c
+* @brief This file provides all the QDEC firmware functions.
+* @details
+* @author howie_wang
+* @date 2016-05-10
+* @version v0.1
+*********************************************************************************************************
+*/
+#include "rtl876x_rcc.h"
+#include "rtl876x_qdec.h"
+
+/**
+ * @brief Initializes the Qdecoder peripheral according to the specified
+ * parameters in the QDEC_InitStruct
+ * @param QDECx: selected Qdecoder peripheral.
+ * @param QDEC_InitStruct: pointer to a QDEC_InitStruct structure that
+ * contains the configuration information for the specified Qdecoder peripheral
+ * @retval None
+ */
+void QDEC_Init(QDEC_TypeDef *QDECx, QDEC_InitTypeDef *QDEC_InitStruct)
+{
+ assert_param(IS_QDEC_PERIPH(QDECx));
+
+ QDECx->REG_DIV = (QDEC_InitStruct->scanClockDiv << 4) | (QDEC_InitStruct->debounceClockDiv);
+ if (QDEC_InitStruct->axisConfigX == ENABLE)
+ {
+ QDECx->REG_CR_X = ((QDEC_InitStruct->debounceTimeX << 4) | (QDEC_InitStruct->counterScaleX << 13) |
+ \
+ (QDEC_InitStruct->debounceEnableX << 12) | (QDEC_InitStruct->initPhaseX));
+ }
+ if (QDEC_InitStruct->axisConfigY == ENABLE)
+ {
+ QDECx->REG_CR_Y = ((QDEC_InitStruct->debounceTimeY << 4) | (QDEC_InitStruct->counterScaleY << 13) |
+ \
+ (QDEC_InitStruct->debounceEnableY << 12) | (QDEC_InitStruct->initPhaseY));
+ }
+ if (QDEC_InitStruct->axisConfigZ == ENABLE)
+ {
+ QDECx->REG_CR_Z = ((QDEC_InitStruct->debounceTimeZ << 4) | (QDEC_InitStruct->counterScaleZ << 13) |
+ \
+ (QDEC_InitStruct->debounceEnableZ << 12) | (QDEC_InitStruct->initPhaseZ));
+ }
+ return;
+}
+
+/**
+ * @brief Deinitializes the Qdecoder peripheral registers to their default reset values(turn off Qdecoder clock).
+ * @param QDECx: selected Qdecoder peripheral.
+ * @retval None
+ */
+void QDEC_DeInit(QDEC_TypeDef *QDECx)
+{
+ RCC_PeriphClockCmd(APBPeriph_QDEC, APBPeriph_QDEC_CLOCK, DISABLE);
+}
+
+
+/**
+ * @brief Fills each QDEC_InitStruct member with its default value.
+ * @param QDEC_InitStruct: pointer to a QDEC_InitStruct structure which will be initialized.
+ * @retval None
+ */
+void QDEC_StructInit(QDEC_InitTypeDef *QDEC_InitStruct)
+{
+ QDEC_InitStruct->scanClockDiv = 0x27;/*!< 5M/(scanClockDiv+1) = 125KHz */
+ QDEC_InitStruct->debounceClockDiv = 0x0; /*!< 125KHz/(debounceClockDiv +1) = 125K */
+
+ QDEC_InitStruct->axisConfigX = DISABLE;
+ QDEC_InitStruct->debounceTimeX = 125 * 5; /*!< 5ms */
+ QDEC_InitStruct->counterScaleX = CounterScale_1_Phase;
+ QDEC_InitStruct->debounceEnableX = Debounce_Disable;
+ QDEC_InitStruct->initPhaseX = phaseMode0;
+
+ QDEC_InitStruct->axisConfigY = DISABLE;
+ QDEC_InitStruct->debounceTimeY = 125 * 5; /*!< 5ms */
+ QDEC_InitStruct->counterScaleY = CounterScale_1_Phase;
+ QDEC_InitStruct->debounceEnableY = Debounce_Disable;
+ QDEC_InitStruct->initPhaseY = phaseMode0;
+
+ QDEC_InitStruct->axisConfigZ = DISABLE;
+ QDEC_InitStruct->debounceTimeZ = 125 * 5; /*!< 5ms */
+ QDEC_InitStruct->counterScaleZ = CounterScale_1_Phase;
+ QDEC_InitStruct->debounceEnableZ = Debounce_Disable;
+ QDEC_InitStruct->initPhaseZ = phaseMode0;
+
+ return;
+}
+
+
+/**
+ * @brief Enables or disables the specified Qdecoder interrupts.
+ * @param QDECx: selected Qdecoder peripheral.
+ * @param QDEC_IT: specifies the QDECODER interrupts sources to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * @arg QDEC_X_INT_NEW_DATA:
+ * @arg QDEC_X_INT_ILLEAGE:
+ * @arg QDEC_Y_INT_NEW_DATA:
+ * @arg QDEC_Y_INT_ILLEAGE:
+ * @arg QDEC_Z_INT_NEW_DATA:
+ * @arg QDEC_Z_INT_ILLEAGE:
+ * @param NewState: new state of the specified QDECODER interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void QDEC_INTConfig(QDEC_TypeDef *QDECx, uint32_t QDEC_IT, FunctionalState newState)
+{
+ /* Check the parameters */
+ assert_param(IS_QDEC_PERIPH(QDECx));
+ assert_param(IS_FUNCTIONAL_STATE(newState));
+ assert_param(IS_QDEC_INT_CONFIG(QDEC_IT));
+
+ if (newState == ENABLE)
+ {
+ /* Enable the selected QDECODER interrupts */
+ if (QDEC_IT & QDEC_X_INT_NEW_DATA)
+ {
+ QDECx->REG_CR_X |= BIT15;
+ }
+ if (QDEC_IT & QDEC_Y_INT_NEW_DATA)
+ {
+ QDECx->REG_CR_Y |= BIT15;
+ }
+ if (QDEC_IT & QDEC_Z_INT_NEW_DATA)
+ {
+ QDECx->REG_CR_Z |= BIT15;
+ }
+ if (QDEC_IT & QDEC_X_INT_ILLEAGE)
+ {
+ QDECx->REG_CR_X |= BIT14;
+ }
+ if (QDEC_IT & QDEC_Y_INT_ILLEAGE)
+ {
+ QDECx->REG_CR_Y |= BIT14;
+ }
+ if (QDEC_IT & QDEC_Z_INT_ILLEAGE)
+ {
+ QDECx->REG_CR_Z |= BIT14;
+ }
+ }
+ else
+ {
+ /* Disable the selected QDECODER interrupts */
+ if (QDEC_IT & QDEC_X_INT_NEW_DATA)
+ {
+ QDECx->REG_CR_X &= ~BIT15;
+ }
+ if (QDEC_IT & QDEC_Y_INT_NEW_DATA)
+ {
+ QDECx->REG_CR_Y &= ~BIT15;
+ }
+ if (QDEC_IT & QDEC_Z_INT_NEW_DATA)
+ {
+ QDECx->REG_CR_Z &= ~BIT15;
+ }
+ if (QDEC_IT & QDEC_X_INT_ILLEAGE)
+ {
+ QDECx->REG_CR_X &= ~BIT14;
+ }
+ if (QDEC_IT & QDEC_Y_INT_ILLEAGE)
+ {
+ QDECx->REG_CR_X &= ~BIT14;
+ }
+ if (QDEC_IT & QDEC_Z_INT_ILLEAGE)
+ {
+ QDECx->REG_CR_X &= ~BIT14;
+ }
+ }
+
+ return;
+}
+
+/**
+ * @brief Checks whether the specified Qdecoder flag is set or not.
+ * @param QDECx: selected Qdecoder peripheral.
+ * @param QDEC_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg QDEC_FLAG_ILLEGAL_STATUS_X:
+ * @arg QDEC_FLAG_ILLEGAL_STATUS_Y:
+ * @arg QDEC_FLAG_ILLEGAL_STATUS_Z:
+ * @arg QDEC_FLAG_NEW_STATUS_X:
+ * @arg QDEC_FLAG_NEW_STATUS_Y:
+ * @arg QDEC_FLAG_NEW_STATUS_Z:
+ * @retval The new state of QDEC_FLAG (SET or RESET).
+ */
+FlagStatus QDEC_GetFlagState(QDEC_TypeDef *QDECx, uint32_t QDEC_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_QDEC_PERIPH(QDECx));
+ assert_param(IS_QDEC_CLR_INT_STATUS(QDEC_FLAG));
+
+ if (((QDEC_FLAG & 0x7) | (QDEC_FLAG & (0x7 << 12))))
+ {
+ if (QDECx->INT_SR & QDEC_FLAG)
+ {
+ bitstatus = SET;
+ }
+ }
+ else if (QDEC_FLAG == QDEC_FLAG_OVERFLOW_X)
+ {
+ if (QDECx->REG_SR_X & (BIT18))
+ {
+ bitstatus = SET;
+ }
+ }
+ else if (QDEC_FLAG == QDEC_FLAG_OVERFLOW_Y)
+ {
+ if (QDECx->REG_SR_Y & (BIT18))
+ {
+ bitstatus = SET;
+ }
+ }
+ else if (QDEC_FLAG == QDEC_FLAG_OVERFLOW_Z)
+ {
+ if (QDECx->REG_SR_Z & (BIT18))
+ {
+ bitstatus = SET;
+ }
+ }
+ else if (QDEC_FLAG == QDEC_FLAG_UNDERFLOW_X)
+ {
+ if (QDECx->REG_SR_X & (BIT19))
+ {
+ bitstatus = SET;
+ }
+ }
+ else if (QDEC_FLAG == QDEC_FLAG_UNDERFLOW_Y)
+ {
+ if (QDECx->REG_SR_Y & (BIT19))
+ {
+ bitstatus = SET;
+ }
+ }
+ else if (QDEC_FLAG == QDEC_FLAG_UNDERFLOW_Z)
+ {
+ if (QDECx->REG_SR_Z & (BIT19))
+ {
+ bitstatus = SET;
+ }
+ }
+
+ return bitstatus;
+}
+
+/**
+ * @brief Enables or disables mask the specified Qdecoder axis interrupts.
+ * @param QDECx: selected Qdecoder peripheral.
+ * @param QDEC_AXIS: specifies the Qdecoder axis.
+ * This parameter can be one or logical OR of the following values:
+ * @arg QDEC_X_CT_INT_MASK: The qdecoder X axis.
+ * @arg QDEC_X_ILLEAGE_INT_MASK: The qdecoder Y axis.
+ * @arg QDEC_Y_CT_INT_MASK: The qdecoder Z axis.
+ * @arg QDEC_Y_ILLEAGE_INT_MASK: The qdecoder X axis.
+ * @arg QDEC_Z_CNT_INT_MASK: The qdecoder Y axis.
+ * @arg QDEC_Z_ILLEAGE_INT_MASK: The qdecoder Z axis.
+ * @param NewState: new state of the specified Qdecoder interrupts mask.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void QDEC_INTMask(QDEC_TypeDef *QDECx, uint32_t QDEC_AXIS, FunctionalState newState)
+{
+ /* Check the parameters */
+ assert_param(IS_QDEC_PERIPH(QDECx));
+ assert_param(IS_QDEC_INT_MASK_CONFIG(QDEC_AXIS));
+ assert_param(IS_FUNCTIONAL_STATE(newState));
+
+ if (newState == ENABLE)
+ {
+ /* mask the selected QDEC interrupts */
+ QDECx->INT_MASK |= (QDEC_AXIS);
+ }
+ else
+ {
+ /* unmask the selected QDEC interrupts */
+ QDEC->INT_MASK &= (~(QDEC_AXIS));
+ }
+
+ return;
+}
+
+/**
+ * @brief Get Qdecoder Axis(x/y/z) direction.
+ * @param QDECx: selected Qdecoder peripheral.
+ * @param QDEC_AXIS: specifies the Qdecoder axis.
+ * This parameter can be one of the following values:
+ * @arg QDEC_AXIS_X: The qdecoder X axis.
+ * @arg QDEC_AXIS_Y: The qdecoder Y axis.
+ * @arg QDEC_AXIS_Z: The qdecoder Z axis.
+ * @param newState
+ * This parameter can be one of the following values:
+ * @arg ENABLE: Pause.
+ * @arg DISABLE: Resume.
+ * @retval The count of the axis.
+ */
+void QDEC_Cmd(QDEC_TypeDef *QDECx, uint32_t QDEC_AXIS,
+ FunctionalState newState)
+{
+ /* Check the parameters */
+ assert_param(IS_QDEC_PERIPH(QDECx));
+ assert_param(IS_QDEC_AXIS_DIR(QDEC_AXIS));
+
+ if (newState == ENABLE)
+ {
+ *((volatile uint32_t *)(&QDECx->REG_CR_X) + QDEC_AXIS / 2) |= BIT30 | BIT31;
+ }
+ else
+ {
+ *((volatile uint32_t *)(&QDECx->REG_CR_X) + QDEC_AXIS / 2) &= ~(BIT30 | BIT31);
+ }
+}
+
diff --git a/src/mcu/peripheral/rtl876x_rcc.c b/src/mcu/peripheral/rtl876x_rcc.c
new file mode 100644
index 0000000..befb5b0
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_rcc.c
@@ -0,0 +1,462 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_rcc.c
+* @brief This file provides all the IO clock firmware functions..
+* @details
+* @author tifnan_ge
+* @date 2015-05-16
+* @version v1.0
+*********************************************************************************************************
+*/
+#include "rtl876x.h"
+#include "rtl876x_bitfields.h"
+#include "rtl876x_rcc.h"
+
+/**
+ * @brief Enables or disables the APB peripheral clock.
+ * @param APBPeriph: specifies the APB peripheral to gates its clock.
+ * This parameter can be one of the following values:
+ * @arg APBPeriph_TIMER
+ * @arg APBPeriph_GDMA
+ * @arg APBPeriph_IF8080
+ * @arg APBPeriph_SPI2W
+ * @arg APBPeriph_KEYSCAN
+ * @arg APBPeriph_QDEC
+ * @arg APBPeriph_I2C1
+ * @arg APBPeriph_I2C0
+ * @arg APBPeriph_IR
+ * @arg APBPeriph_SPI1
+ * @arg APBPeriph_SPI0
+ * @arg APBPeriph_UART0
+ * @arg APBPeriph_UART1
+ * @arg APBPeriph_UART2
+ * @arg APBPeriph_GPIO
+ * @arg APBPeriph_ADC
+ * @arg APBPeriph_I2S0
+ * @arg APBPeriph_I2S1
+ * @arg APBPeriph_CODEC
+ * @param APBPeriph_Clock: specifies the APB peripheral clock config.
+ * This parameter can be one of the following values(must be the same with APBPeriph):
+ * @arg APBPeriph_TIMER_CLOCK
+ * @arg APBPeriph_GDMA_CLOCK
+ * @arg APBPeriph_IF8080_CLOCK
+ * @arg APBPeriph_SPI2W_CLOCK
+ * @arg APBPeriph_KEYSCAN_CLOCK
+ * @arg APBPeriph_QDEC_CLOCK
+ * @arg APBPeriph_I2C1_CLOCK
+ * @arg APBPeriph_I2C0_CLOCK
+ * @arg APBPeriph_IR_CLOCK
+ * @arg APBPeriph_SPI1_CLOCK
+ * @arg APBPeriph_SPI0_CLOCK
+ * @arg APBPeriph_UART0_CLOCK
+ * @arg APBPeriph_UART1_CLOCK
+ * @arg APBPeriph_UART2_CLOCK
+ * @arg APBPeriph_GPIO_CLOCK
+ * @arg APBPeriph_ADC_CLOCK
+ * @arg APBPeriph_I2S0_CLOCK
+ * @arg APBPeriph_I2S1_CLOCK
+ * @arg APBPeriph_CODEC_CLOCK
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_PeriphClockCmd(uint32_t APBPeriph, uint32_t APBPeriph_Clock, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_APB_PERIPH(APBPeriph));
+ assert_param(IS_APB_PERIPH_CLOCK(APBPeriph_Clock));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ uint32_t apbRegOff = ((APBPeriph & (0x03 << 26)) >> 26);
+ uint32_t clkRegOff = ((APBPeriph_Clock & (0x03 << 29)) >> 29);
+
+ /*Open clock gating first*/
+ if (NewState == ENABLE)
+ {
+ if (APBPeriph_Clock == APBPeriph_KEYSCAN_CLOCK)
+ {
+ /*Open 5M clock source*/
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26;
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT29;
+ }
+ else if ((APBPeriph_Clock == APBPeriph_ADC_CLOCK) || (APBPeriph_Clock == APBPeriph_CTC_CLOCK))
+ {
+ /*Open 10M clock source*/
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26;
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT22;
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT28;
+ }
+ else if ((APBPeriph_Clock == APBPeriph_QDEC_CLOCK) || (APBPeriph_Clock == APBPeriph_SPI2W_CLOCK))
+ {
+ /*Open 20M clock source*/
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26;
+ SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT27;
+ }
+ else if ((APBPeriph_Clock == APBPeriph_TIMER_CLOCK) ||
+ (APBPeriph_Clock == APBPeriph_ENHTIMER_CLOCK))
+ {
+ /* Enable Timer fixed 40M */
+ CLK_SOURCE_REG_2 |= BIT9;
+ }
+ }
+
+ /* Special register handle */
+ if (NewState == ENABLE)
+ {
+ if ((APBPeriph_Clock == APBPeriph_I2S0_CLOCK) || ((APBPeriph_Clock == APBPeriph_I2S1_CLOCK)) ||
+ (APBPeriph_Clock == APBPeriph_CODEC_CLOCK))
+ {
+ SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN |= APBPeriph | APBPeriph_Clock;
+// SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN |= 0x133;
+ return;
+ }
+ }
+ else
+ {
+ if ((APBPeriph_Clock == APBPeriph_I2S0_CLOCK) || ((APBPeriph_Clock == APBPeriph_I2S1_CLOCK)) ||
+ (APBPeriph_Clock == APBPeriph_CODEC_CLOCK))
+ {
+ SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN &= ~(APBPeriph | APBPeriph_Clock);
+// SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN &= ~(0x13F);
+ return;
+ }
+ }
+
+ /* clear flag */
+ APBPeriph &= (~(0x03 << 26));
+ APBPeriph_Clock &= (~(0x03 << 29));
+
+ if (NewState == ENABLE)
+ {
+ //enable peripheral
+ *((uint32_t *)(&(SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN)) + apbRegOff) |= APBPeriph;
+ //enable peripheral clock
+ *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) |= APBPeriph_Clock;
+ //enable peripheral clock in sleep mode
+ *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) |=
+ (APBPeriph_Clock << 1);
+ }
+ else
+ {
+ //disable peripheral
+ *((uint32_t *)(&(SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN)) + apbRegOff) &= (~APBPeriph);
+ //disable peripheral clock
+ *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) &=
+ (~APBPeriph_Clock);
+ //disable peripheral clock in sleep mode
+ *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) &= (~
+ (APBPeriph_Clock << 1));
+ }
+
+ return;
+}
+
+/**
+ * @brief Enables or disables the APB peripheral clock.
+ * @param APBPeriph: specifies the APB peripheral to gates its clock.
+ * This parameter can be one of the following values:
+ * @arg APBPeriph_TIMER
+ * @arg APBPeriph_GDMA
+ * @arg APBPeriph_IF8080
+ * @arg APBPeriph_SPI2W
+ * @arg APBPeriph_KEYSCAN
+ * @arg APBPeriph_QDEC
+ * @arg APBPeriph_I2C1
+ * @arg APBPeriph_I2C0
+ * @arg APBPeriph_IR
+ * @arg APBPeriph_SPI1
+ * @arg APBPeriph_SPI0
+ * @arg APBPeriph_UART0
+ * @arg APBPeriph_UART1
+ * @arg APBPeriph_UART2
+ * @arg APBPeriph_GPIO
+ * @arg APBPeriph_ADC
+ * @arg APBPeriph_I2S0
+ * @arg APBPeriph_I2S1
+ * @arg APBPeriph_CODEC
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_PeriFunctionConfig(uint32_t APBPeriph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_APB_PERIPH(APBPeriph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ uint32_t apbRegOff = ((APBPeriph & (0x03 << 26)) >> 26);
+
+ /* Special register handle */
+ if (NewState == ENABLE)
+ {
+ if ((APBPeriph == APBPeriph_I2S0) || ((APBPeriph == APBPeriph_I2S1)) ||
+ (APBPeriph == APBPeriph_CODEC))
+ {
+ SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN |= APBPeriph;
+ return;
+ }
+ }
+ else
+ {
+ if ((APBPeriph == APBPeriph_I2S0) || ((APBPeriph == APBPeriph_I2S1)) ||
+ (APBPeriph == APBPeriph_CODEC))
+ {
+ SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN &= ~(APBPeriph);
+ return;
+ }
+ }
+
+ /* clear flag */
+ APBPeriph &= (~(0x03 << 26));
+
+ if (NewState == ENABLE)
+ {
+ //enable peripheral
+ *((uint32_t *)(&(SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN)) + apbRegOff) |= APBPeriph;
+ }
+ else
+ {
+ //disable peripheral
+ *((uint32_t *)(&(SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN)) + apbRegOff) &= (~APBPeriph);
+ }
+
+ return;
+}
+
+/**
+ * @brief Enables or disables the APB peripheral clock.
+ * @param APBPeriph_Clock: specifies the APB peripheral clock config.
+ * This parameter can be one of the following values(must be the same with APBPeriph):
+ * @arg APBPeriph_TIMER_CLOCK
+ * @arg APBPeriph_GDMA_CLOCK
+ * @arg APBPeriph_SPI2W_CLOCK
+ * @arg APBPeriph_KEYSCAN_CLOCK
+ * @arg APBPeriph_QDEC_CLOCK
+ * @arg APBPeriph_I2C1_CLOCK
+ * @arg APBPeriph_I2C0_CLOCK
+ * @arg APBPeriph_IR_CLOCK
+ * @arg APBPeriph_SPI1_CLOCK
+ * @arg APBPeriph_SPI0_CLOCK
+ * @arg APBPeriph_UART0_CLOCK
+ * @arg APBPeriph_UART1_CLOCK
+ * @arg APBPeriph_UART2_CLOCK
+ * @arg APBPeriph_GPIO_CLOCK
+ * @arg APBPeriph_ADC_CLOCK
+ * @arg APBPeriph_I2S0_CLOCK
+ * @arg APBPeriph_I2S1_CLOCK
+ * @arg APBPeriph_CODEC_CLOCK
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_PeriClockConfig(uint32_t APBPeriph_Clock, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_APB_PERIPH_CLOCK(APBPeriph_Clock));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ uint32_t clkRegOff = ((APBPeriph_Clock & (0x03 << 29)) >> 29);
+
+ /* Special register handle */
+ if (NewState == ENABLE)
+ {
+ if ((APBPeriph_Clock == APBPeriph_I2S0_CLOCK) || ((APBPeriph_Clock == APBPeriph_I2S1_CLOCK)) ||
+ (APBPeriph_Clock == APBPeriph_CODEC_CLOCK))
+ {
+ SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN |= APBPeriph_Clock;
+ return;
+ }
+ }
+ else
+ {
+ if ((APBPeriph_Clock == APBPeriph_I2S0_CLOCK) || ((APBPeriph_Clock == APBPeriph_I2S1_CLOCK)) ||
+ (APBPeriph_Clock == APBPeriph_CODEC_CLOCK))
+ {
+ SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN &= ~(APBPeriph_Clock);
+ return;
+ }
+ }
+
+ APBPeriph_Clock &= (~(0x03 << 29));
+
+ if (NewState == ENABLE)
+ {
+ //enable peripheral clock
+ *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) |= APBPeriph_Clock;
+ //enable peripheral clock in sleep mode
+ *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) |=
+ (APBPeriph_Clock << 1);
+ }
+ else
+ {
+ //disable peripheral clock
+ *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) &=
+ (~APBPeriph_Clock);
+ //disable peripheral clock in sleep mode
+ *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) &= (~
+ (APBPeriph_Clock << 1));
+ }
+
+ return;
+}
+
+/**
+ * @brief I2C clock divider config.
+ * @param I2Cx: where x can be 0 or 1 to select the I2C peripheral.
+ * @param ClockDiv: specifies the APB peripheral to gates its clock.
+ * This parameter can be one of the following values:
+ * @arg I2C_CLOCK_DIV_1
+ * @arg I2C_CLOCK_DIV_2
+ * @arg I2C_CLOCK_DIV_4
+ * @arg I2C_CLOCK_DIV_8
+ * @retval None
+ */
+void RCC_I2CClkDivConfig(I2C_TypeDef *I2Cx, uint16_t ClockDiv)
+{
+ assert_param(IS_I2C_DIV(ClockDiv));
+
+ /* Config I2C clock divider */
+ if (I2Cx == I2C0)
+ {
+ /* disable clock first */
+ SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 &= ~SYSBLK_ACTCK_I2C0_EN_Msk;
+ //platform_delay_us(1);
+
+ CLK_SOURCE_REG_1 &= ~(0x03 << 15);
+ CLK_SOURCE_REG_1 |= (ClockDiv << 15);
+
+ //platform_delay_us(1);
+ SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 |= SYSBLK_ACTCK_I2C0_EN_Msk;
+ }
+ else if (I2Cx == I2C1)
+ {
+ SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 &= ~SYSBLK_ACTCK_I2C1_EN_Msk;
+ //platform_delay_us(1);
+
+ CLK_SOURCE_REG_1 &= ~(0x03 << 17);
+ CLK_SOURCE_REG_1 |= (ClockDiv << 17);
+
+ //platform_delay_us(1);
+ SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 |= SYSBLK_ACTCK_I2C1_EN_Msk;
+ }
+
+ return;
+}
+
+/**
+ * @brief SPI clock divider config.
+ * @param SPIx: where x can be 0 or 1 to select the SPI peripheral.
+ * @param ClockDiv: specifies the APB peripheral to gates its clock.
+ * This parameter can be one of the following values:
+ * @arg SPI_CLOCK_DIV_1
+ * @arg SPI_CLOCK_DIV_2
+ * @arg SPI_CLOCK_DIV_4
+ * @arg SPI_CLOCK_DIV_8
+ * @retval None
+ */
+void RCC_SPIClkDivConfig(SPI_TypeDef *SPIx, uint16_t ClockDiv)
+{
+ assert_param(IS_SPI_DIV(ClockDiv));
+
+ /* Config I2C clock divider */
+ if (SPIx == SPI0)
+ {
+ /* disable clock first */
+ SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 &= ~SYSBLK_ACTCK_SPI0_EN_Msk;
+ //platform_delay_us(1);
+
+ CLK_SOURCE_REG_1 &= ~(0x03 << 19);
+ CLK_SOURCE_REG_1 |= (ClockDiv << 19);
+
+ //platform_delay_us(1);
+ SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 |= SYSBLK_ACTCK_SPI0_EN_Msk;
+ }
+ else if (SPIx == SPI1)
+ {
+ SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 &= ~SYSBLK_ACTCK_SPI1_EN_Msk;
+ //platform_delay_us(1);
+
+ CLK_SOURCE_REG_1 &= ~(0x03 << 21);
+ CLK_SOURCE_REG_1 |= (ClockDiv << 21);
+
+ //platform_delay_us(1);
+ SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 |= SYSBLK_ACTCK_SPI1_EN_Msk;
+ }
+ return;
+}
+
+/**
+ * @brief TIMER & ENH-TIMER clock divider config.
+ * @param TIMx: selected TIM number.
+ * @param ClockDiv: specifies the APB peripheral to gates its clock.
+ * This parameter can be one of the following values:
+ * @arg TIM_CLOCK_DIV_1
+ * @arg TIM_CLOCK_DIV_125
+ * @arg TIM_CLOCK_DIV_2
+ * @arg TIM_CLOCK_DIV_4
+ * @arg TIM_CLOCK_DIV_8
+ * @arg TIM_CLOCK_DIV_40
+ * @retval None
+ */
+void RCC_TIMClkDivConfig(E_TIM_NUM TIMx, uint16_t ClockDiv)
+{
+ assert_param(IS_UART_DIV(ClockDiv));
+
+ /* Config TIM clock divider */
+ /* disable clock first */
+ SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL &= ~SYSBLK_ACTCK_TIMER_EN_Msk;
+ //platform_delay_us(1);
+
+ CLK_SOURCE_REG_2 &= ~(0x07 << (13 + (TIMx - 2) * 3));
+ CLK_SOURCE_REG_2 |= (ClockDiv << (13 + (TIMx - 2) * 3));
+
+ //platform_delay_us(1);
+ SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= SYSBLK_ACTCK_TIMER_EN_Msk;
+
+ return;
+}
+
+/**
+ * @brief UART clock divider config.
+ * @param UARTx: selected UART peripheral.
+ * @param ClockDiv: specifies the APB peripheral to gates its clock.
+ * This parameter can be one of the following values:
+ * @arg UART_CLOCK_DIV_1
+ * @arg UART_CLOCK_DIV_2
+ * @arg UART_CLOCK_DIV_4
+ * @arg UART_CLOCK_DIV_16
+ * @retval None
+ */
+void RCC_UARTClkDivConfig(UART_TypeDef *UARTx, uint16_t ClockDiv)
+{
+ assert_param(IS_UART_DIV(ClockDiv));
+
+ /* Config UART clock divider */
+ if (UARTx == UART0)
+ {
+ /* disable clock first */
+ SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 &= ~SYSBLK_ACTCK_UART0DATA_EN_Msk;
+ //platform_delay_us(1);
+
+ CLK_SOURCE_REG_1 &= ~(0x03 << 9);
+ CLK_SOURCE_REG_1 |= (ClockDiv << 9);
+
+ //platform_delay_us(1);
+ SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 |= SYSBLK_ACTCK_UART0DATA_EN_Msk;
+ }
+ else if (UARTx == UART1)
+ {
+ SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL &= ~SYSBLK_ACTCK_LOGUART_EN_Msk;
+ //platform_delay_us(1);
+
+ CLK_SOURCE_REG_1 &= ~(0x03 << 11);
+ CLK_SOURCE_REG_1 |= (ClockDiv << 11);
+
+ //platform_delay_us(1);
+ SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= SYSBLK_ACTCK_LOGUART_EN_Msk;
+ }
+
+ return;
+}
diff --git a/src/mcu/peripheral/rtl876x_rtc.c b/src/mcu/peripheral/rtl876x_rtc.c
new file mode 100644
index 0000000..78252af
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_rtc.c
@@ -0,0 +1,419 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_rtc.c
+* @brief This file provides all the RTC firmware functions.
+* @details
+* @author yuan
+* @date 2020-11-11
+* @version v2.1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_rtc.h"
+
+/* Internal defines ------------------------------------------------------------*/
+#define REG_FAST_WRITE_BASE_ADDR (0x40000100UL)
+#define REG_RTC_FAST_WDATA (0x400001F0UL)
+#define REG_RTC_FAST_ADDR (0x400001F4UL)
+#define REG_RTC_WR_STROBE (0x400001F8UL)
+
+/**
+ * @brief Fast write RTC register.
+ * @param reg_address: the register address.
+ * @param data: data which write to register.
+ * @return None
+ */
+void RTC_WriteReg(uint32_t reg_address, uint32_t data)
+{
+ static bool is_called = false;
+
+ if (is_called == false)
+ {
+ *((volatile uint32_t *)0x40000014) |= BIT(9);//no need run this every time
+ is_called = true;
+ }
+
+ /* Write data */
+ *((volatile uint32_t *)REG_RTC_FAST_WDATA) = data;
+ /* Write RTC register address. Only offset */
+ *((volatile uint32_t *)REG_RTC_FAST_ADDR) = reg_address - REG_FAST_WRITE_BASE_ADDR;
+ *((volatile uint32_t *)REG_RTC_WR_STROBE) = 1;
+}
+
+/**
+ * @brief Reset RTC.
+ * @param None
+ * @return None
+ */
+void RTC_DeInit(void)
+{
+ /* Stop RTC counter */
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 & RTC_START_CLR));
+
+ /* Disable wakeup signal */
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 & RTC_NV_EN_CLR));
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 & RTC_WAKEUP_EN_CLR));
+
+ /* Clear all RTC interrupt & wakeup */
+ RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), RTC_ALL_INT_CLR_SET | RTC_ALL_WAKEUP_CLR_SET);
+ __NOP();
+ __NOP();
+ RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), 0);
+
+ /* Clear prescale register */
+ RTC_WriteReg((uint32_t)(&(RTC->PRESCALER)), 0);
+ /* Clear all comparator register */
+ RTC_WriteReg((uint32_t)(&(RTC->COMP0)), 0);
+ RTC_WriteReg((uint32_t)(&(RTC->COMP1)), 0);
+ RTC_WriteReg((uint32_t)(&(RTC->COMP2)), 0);
+ RTC_WriteReg((uint32_t)(&(RTC->COMP3)), 0);
+ RTC_WriteReg((uint32_t)(&(RTC->COMP0GT)), 0);
+ RTC_WriteReg((uint32_t)(&(RTC->COMP1GT)), 0);
+ RTC_WriteReg((uint32_t)(&(RTC->COMP2GT)), 0);
+ RTC_WriteReg((uint32_t)(&(RTC->COMP3GT)), 0);
+ RTC_WriteReg((uint32_t)(&(RTC->PRE_COMP)), 0);
+
+ /* Reset prescale counter and counter */
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), RTC_PRE_COUNTER_RST_Msk | RTC_COUNTER_RST_Msk);
+ __NOP();
+ __NOP();
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), 0x0);
+}
+
+/**
+ * @brief Set RTC prescaler value.
+ * @param value: the prescaler value to be set.Should be no more than 12 bits!
+ * @return None
+ */
+void RTC_SetPrescaler(uint16_t value)
+{
+ RTC_WriteReg((uint32_t)(&(RTC->PRESCALER)), value & 0xFFF);
+}
+
+/**
+ * @brief Start or stop RTC peripheral.
+ * @param NewState: new state of RTC peripheral.
+ * This parameter can be the following values:
+ * @arg ENABLE: start RTC.
+ * @arg DISABLE: stop RTC.
+ * @return None
+ */
+void RTC_Cmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState == ENABLE)
+ {
+ /* Start RTC */
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), RTC->CR0 | RTC_START_Msk);
+ }
+ else
+ {
+ /* Stop RTC */
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), RTC->CR0 & RTC_START_CLR);
+ }
+}
+
+/**
+ * @brief Enable or disable the specified RTC interrupts.
+ * @param RTC_INT: specifies the RTC interrupt source to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_INT_TICK: tick interrupt
+ * @arg RTC_INT_OVF: counter overflow interrupt
+ * @arg RTC_INT_PRE_CMP: prescale compare interrupt
+ * @arg RTC_INT_PRE_CMP3: prescale & compare 3 interrupt
+ * @arg RTC_INT_CMP0: compare 0 interrupt
+ * @arg RTC_INT_CMP1: compare 1 interrupt
+ * @arg RTC_INT_CMP2: compare 2 interrupt
+ * @arg RTC_INT_CMP3: compare 3 interrupt
+ * @param NewState: new state of the specified RTC interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * @return None.
+ */
+void RTC_INTConfig(E_RTC_INT RTC_INT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_INT(RTC_INT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState == ENABLE)
+ {
+ /* Enable the selected RTC comparator interrupt */
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 | RTC_INT));
+ }
+ else
+ {
+ /* Disable the selected RTC comparator interrupt */
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 & (~RTC_INT)));
+ }
+}
+
+/**
+ * @brief Enable or disable the specified RTC wakeup function.
+ * @param RTC_WK: specifies the RTC wakeup function to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_WK_TICK: tick wakeup function
+ * @arg RTC_WK_OVF: tick wakeup function
+ * @arg RTC_WK_PRE_CMP: prescale compare wakeup function
+ * @arg RTC_WK_PRE_CMP3: prescale & compare 3 wakeup function
+ * @arg RTC_WK_COMP0GT: compare 0 gt wakeup function
+ * @arg RTC_WK_COMP1GT: compare 1 gt wakeup function
+ * @arg RTC_WK_COMP2GT: compare 2 gt wakeup function
+ * @arg RTC_WK_COMP3GT: compare 3 gt wakeup function
+ * @arg RTC_WK_CMP0: compare 0 wakeup function
+ * @arg RTC_WK_CMP1: compare 1 wakeup function
+ * @arg RTC_WK_CMP2: compare 2 wakeup function
+ * @arg RTC_WK_CMP3: compare 3 wakeup function
+ * @param NewState: new state of the specified RTC wakeup function.
+ * This parameter can be: ENABLE or DISABLE.
+ * @return None.
+ */
+void RTC_WKConfig(E_RTC_WK RTC_WK, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_WK(RTC_WK));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState == ENABLE)
+ {
+ /* Enable the selected RTC comparator interrupt */
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 | RTC_WK));
+ }
+ else
+ {
+ /* Disable the selected RTC comparator interrupt */
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 & (~RTC_WK)));
+ }
+}
+
+/**
+ * @brief Enable interrupt signal to CPU NVIC.
+ * @param This parameter can be: ENABLE or DISABLE.
+ * @return None.
+ */
+void RTC_NvCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 | RTC_NV_EN_Msk));
+ }
+ else
+ {
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 & RTC_NV_EN_CLR));
+ }
+}
+
+/**
+ * @brief Enable or disable system wake up of RTC.
+ * @param NewState: new state of the wake up function.
+ * This parameter can be: ENABLE or DISABLE.
+ * @return None
+ */
+void RTC_SystemWakeupConfig(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState == ENABLE)
+ {
+ /* Enable system wake up */
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 | RTC_WAKEUP_EN_Msk));
+ }
+ else
+ {
+ /* Disable system wake up */
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 & RTC_WAKEUP_EN_CLR));
+ }
+}
+
+/**
+ * @brief Reset counter value of RTC.
+ * @param None
+ * @return None
+ */
+void RTC_ResetCounter(void)
+{
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0) | RTC_COUNTER_RST_Msk);
+ __NOP();
+ __NOP();
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0) & RTC_COUNTER_RST_CLR);
+}
+
+/**
+ * @brief Reset prescaler counter value of RTC.
+ * @param None
+ * @return None
+ */
+void RTC_ResetPrescalerCounter(void)
+{
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0) | RTC_PRE_COUNTER_RST_Msk);
+ __NOP();
+ __NOP();
+ RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0) & RTC_PRE_COUNTER_RST_CLR);
+}
+
+/**
+ * @brief Checks whether the specified RTC interrupt is set or not.
+ * @param RTC_INT: specifies the RTC interrupt source to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_INT_TICK: RTC tick interrupt source
+ * @arg RTC_INT_PRE_COMP: prescale compare interrupt source
+ * @arg RTC_INT_PRE_COMP3: prescale & compare 3 interrupt source
+ * @arg RTC_INT_COMP0: compare 0 interrupt source
+ * @arg RTC_INT_COMP1: compare 1 interrupt source
+ * @arg RTC_INT_COMP2: compare 2 interrupt source
+ * @arg RTC_INT_COMP3: compare 3 interrupt source
+ * @return The new state of RTC_INT (SET or RESET).
+ */
+ITStatus RTC_GetINTStatus(E_RTC_INT RTC_INT)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_CONFIG_INT(RTC_INT));
+
+ ITStatus int_status = RESET;
+
+ if ((RTC->INT_SR & ((uint32_t)RTC_INT >> 8)) != (uint32_t)RESET)
+ {
+ int_status = SET;
+ }
+
+ /* Return the RTC_INT status */
+ return int_status;
+}
+
+/**
+ * @brief Clear the interrupt pending bits of RTC.
+ * @param RTC_INT: specifies the RTC interrupt flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_INT_TICK: RTC tick interrupt source
+ * @arg RTC_INT_OVF: RTC counter overflow interrupt source
+ * @arg RTC_INT_PRE_COMP: prescale compare interrupt source
+ * @arg RTC_INT_PRE_COMP3: prescale & compare 3 interrupt source
+ * @arg RTC_INT_COMP0: compare 0 interrupt source
+ * @arg RTC_INT_COMP1: compare 1 interrupt source
+ * @arg RTC_INT_COMP2: compare 2 interrupt source
+ * @arg RTC_INT_COMP3: compare 3 interrupt source
+ * @return None
+ */
+void RTC_ClearINTPendingBit(E_RTC_INT RTC_INT)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_INT(RTC_INT));
+
+ RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), (uint32_t)RTC_INT >> 8);
+ __NOP();
+ __NOP();
+ RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), 0);
+}
+
+/**
+ * @brief Checks whether the specified RTC wakeup state is set or not.
+ * @param RTC_WK: specifies the RTC interrupt source to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_WK_TICK: tick wakeup function
+ * @arg RTC_WK_OVF: tick wakeup function
+ * @arg RTC_WK_PRE_CMP: prescale compare wakeup function
+ * @arg RTC_WK_PRE_CMP3: prescale & compare 3 wakeup function
+ * @arg RTC_WK_COMP0GT: compare 0 gt wakeup function
+ * @arg RTC_WK_COMP1GT: compare 1 gt wakeup function
+ * @arg RTC_WK_COMP2GT: compare 2 gt wakeup function
+ * @arg RTC_WK_COMP3GT: compare 3 gt wakeup function
+ * @arg RTC_WK_CMP0: compare 0 wakeup function
+ * @arg RTC_WK_CMP1: compare 1 wakeup function
+ * @arg RTC_WK_CMP2: compare 2 wakeup function
+ * @arg RTC_WK_CMP3: compare 3 wakeup function
+ * @return The new state of RTC_INT (SET or RESET).
+ */
+ITStatus RTC_GetWakeupStatus(E_RTC_WK RTC_WK)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_CONFIG_INT(RTC_WK));
+
+ ITStatus wakeup_status = RESET;
+
+ if ((RTC->INT_SR & ((uint32_t)RTC_WK >> 8)) != (uint32_t)RESET)
+ {
+ wakeup_status = SET;
+ }
+
+ /* Return the RTC_INT status */
+ return wakeup_status;
+}
+
+/**
+ * @brief Clear the wakeup status bits of RTC.
+ * @param RTC_WK: specifies the RTC wakeup flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_WK_TICK: tick wakeup function
+ * @arg RTC_WK_OVF: tick wakeup function
+ * @arg RTC_WK_PRE_CMP: prescale compare wakeup function
+ * @arg RTC_WK_PRE_CMP3: prescale & compare 3 wakeup function
+ * @arg RTC_WK_COMP0GT: compare 0 gt wakeup function
+ * @arg RTC_WK_COMP1GT: compare 1 gt wakeup function
+ * @arg RTC_WK_COMP2GT: compare 2 gt wakeup function
+ * @arg RTC_WK_COMP3GT: compare 3 gt wakeup function
+ * @arg RTC_WK_CMP0: compare 0 wakeup function
+ * @arg RTC_WK_CMP1: compare 1 wakeup function
+ * @arg RTC_WK_CMP2: compare 2 wakeup function
+ * @arg RTC_WK_CMP3: compare 3 wakeup function
+ * @return None
+ */
+void RTC_ClearWakeupStatusBit(E_RTC_WK RTC_WK)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_WK(RTC_WK));
+
+ RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), (uint32_t)RTC_WK >> 8);
+ __NOP();
+ __NOP();
+ RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), 0);
+}
+
+/**
+ * @brief Clear the interrupt pending bit of the select comparator of RTC.
+ * @param index: the comparator number 0~3.
+ * @return None
+ */
+void RTC_ClearCompINT(E_RTC_COMP_INDEX index)
+{
+ RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), BIT(RTC_COMP0_CLR_Pos + index));
+ __NOP();
+ __NOP();
+ RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), 0);
+}
+
+/**
+ * @brief Clear the overflow interrupt pending bit of RTC.
+ * @param None
+ * @return None
+ */
+void RTC_ClearOverFlowINT(void)
+{
+ RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), RTC_OVERFLOW_CLR_SET);
+ __NOP();
+ __NOP();
+ RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), 0);
+}
+
+/**
+ * @brief Clear the tick interrupt pending bit of RTC.
+ * @param None
+ * @return None
+ */
+void RTC_ClearTickINT(void)
+{
+ RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), RTC_TICK_CLR_SET);
+ __NOP();
+ __NOP();
+ RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), 0);
+}
+
+/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/mcu/peripheral/rtl876x_spi.c b/src/mcu/peripheral/rtl876x_spi.c
new file mode 100644
index 0000000..f831f06
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_spi.c
@@ -0,0 +1,352 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_spi.c
+* @brief This file provides all the Spi firmware functions.
+* @details
+* @author elliot chen
+* @date 2015-05-06
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_spi.h"
+#include "rtl876x_rcc.h"
+
+/**
+ * @brief Deinitializes the SPIx peripheral registers to their default reset values.
+ * @param SPIx: where x can be 0 or 1 to select the SPI peripheral.
+ * @retval None
+ */
+void SPI_DeInit(SPI_TypeDef *SPIx)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ /*Disable SPI clock */
+ if (SPIx == SPI0)
+ {
+ RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, DISABLE);
+ }
+ else
+ {
+ RCC_PeriphClockCmd(APBPeriph_SPI1, APBPeriph_SPI1_CLOCK, DISABLE);
+ }
+}
+
+/**
+ * @brief Initializes the SPIx peripheral according to the specified
+ * parameters in the SPI_InitStruct.
+ * @param SPIx: where x can be 0 or 1 to select the SPI peripheral.
+ * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure that
+ * contains the configuration information for the specified SPI peripheral.
+ * @retval None
+ */
+void SPI_Init(SPI_TypeDef *SPIx, SPI_InitTypeDef *SPI_InitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ /* Check the SPI parameters */
+ assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction));
+ assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));
+ assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize));
+ assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL));
+ assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));
+ assert_param(IS_SPI_FRAME_FORMAT(SPI_InitStruct->SPI_FrameFormat));
+
+ /* Disable SPI device before change configuration */
+ SPIx->SSIENR &= ~0x01;
+
+ /*Set SPI Rx sample delay */
+ SPIx->RX_SAMPLE_DLY = 0x01;
+
+ /* Configure SPI0 mode if select SPI0 */
+ if (SPIx == SPI0)
+ {
+ if (SPI_InitStruct->SPI_Mode == SPI_Mode_Master)
+ {
+ /*Enable SPI0 master mode*/
+ *((volatile uint32_t *)0x40000308) = *((volatile uint32_t *)0x40000308) | BIT(0);
+ /* configure SPI parameters */
+ SPIx->CTRLR0 = (SPI_InitStruct->SPI_DataSize << 16)\
+ | (SPI_InitStruct->SPI_FrameFormat << 4) \
+ | (SPI_InitStruct->SPI_CPHA << 6)\
+ | (SPI_InitStruct->SPI_CPOL << 7) \
+ | (SPI_InitStruct->SPI_Direction << 8) \
+ | (SPI_InitStruct->SPI_ToggleEn << 24);
+ }
+ else
+ {
+ /*Enable SPI0 slave mode*/
+ *((volatile uint32_t *)0x40000308) = *((volatile uint32_t *)0x40000308) & (~(BIT(0)));
+ /* configure SPI parameters */
+ SPIx->CTRLR0 = (SPI_InitStruct->SPI_DataSize)
+ | (SPI_InitStruct->SPI_FrameFormat << 4)
+ | (SPI_InitStruct->SPI_CPHA << 6)
+ | (SPI_InitStruct->SPI_CPOL << 7)
+ | (SPI_InitStruct->SPI_Direction << 8)
+ | (SPI_InitStruct->SPI_SwapTxBitEn << 22)
+ | (SPI_InitStruct->SPI_SwapRxBitEn << 24)
+ | (SPI_InitStruct->SPI_SwapTxByteEn << 21)
+ | (SPI_InitStruct->SPI_SwapRxByteEn << 23)
+ | (SPI_InitStruct->SPI_ToggleEn << 31);
+ }
+
+ }
+ else if (SPIx == SPI1)
+ {
+ /* configure SPI parameters */
+ SPIx->CTRLR0 = (SPI_InitStruct->SPI_DataSize << 16)
+ | (SPI_InitStruct->SPI_FrameFormat << 4)
+ | (SPI_InitStruct->SPI_CPHA << 6)
+ | (SPI_InitStruct->SPI_CPOL << 7)
+ | (SPI_InitStruct->SPI_Direction << 8)
+ | (SPI_InitStruct->SPI_ToggleEn << 24);
+ }
+
+ /* configure SPI clock speed in master mode or enable slave output in slave mode */
+ if (SPI_InitStruct->SPI_Mode == SPI_Mode_Master)
+ {
+ SPIx->BAUDR = (SPI_InitStruct->SPI_BaudRatePrescaler) % 0xFFFF;
+ /* Enable slave Select function in master mode */
+ SPIx->SER |= BIT(0);
+ }
+ else
+ {
+ /* Enable slave output */
+ SPIx->CTRLR0 &= ~(BIT(10));
+ }
+
+ /*set SPI Tx and Rx threshold level ,below this level or equal this level would trigger Tx and Rx FIFO empty interrupt */
+ SPIx->TXFTLR = SPI_InitStruct->SPI_TxThresholdLevel;
+ SPIx->RXFTLR = SPI_InitStruct->SPI_RxThresholdLevel;
+
+ /* mask SPI interrupt in REG_DW_SSI_IMR */
+ SPIx->IMR = 0;
+
+ /* set read length in SPI EEPROM & rx only mode */
+ if ((SPI_InitStruct->SPI_Direction == 0x02) || (SPI_InitStruct->SPI_Direction == 0x03))
+ {
+ SPIx->CTRLR1 = SPI_InitStruct->SPI_NDF;
+ }
+#if 1
+
+ /* Config SPI dma mode */
+ SPIx->DMACR = ((SPI_InitStruct->SPI_RxDmaEn)\
+ | ((SPI_InitStruct->SPI_TxDmaEn) << 1));
+
+ /* Config SPI waterlevel */
+ SPIx->DMARDLR = SPI_InitStruct->SPI_RxWaterlevel;
+ SPIx->DMATDLR = SPI_InitStruct->SPI_TxWaterlevel;
+#endif
+}
+
+/**
+ * @brief Fills each SPI_InitStruct member with its default value.
+ * @param SPI_InitStruct : pointer to a SPI_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void SPI_StructInit(SPI_InitTypeDef *SPI_InitStruct)
+{
+ SPI_InitStruct->SPI_Mode = SPI_Mode_Master;
+ SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b; /* 8-bit serial data transfer */
+ SPI_InitStruct->SPI_FrameFormat = 0; /* 0:FRF_MOTOROLA_SPI; 1,2,3:Reserved */
+ SPI_InitStruct->SPI_Direction =
+ 0; /* 0:TX and RX Mode; 1:TX Only Mode; 2:RX Only Mode;
+ 3:EEPROM Read Mode */
+ SPI_InitStruct->SPI_CPOL =
+ 1; /* 0:inactive state of clock is low; 1:inactive
+ state of clock is high */
+ SPI_InitStruct->SPI_CPHA =
+ 1; /* 1:Serial clock toggles in first of first data bit;
+ 0:Serial clock toggles in middle of first data bit*/
+ SPI_InitStruct->SPI_BaudRatePrescaler =
+ SPI_BaudRatePrescaler_128; /* Speed = SPI Clock source/ SPI_ClkDIV*/
+ SPI_InitStruct->SPI_TxThresholdLevel = 1; /* Transmit FIFO Threshold */
+ SPI_InitStruct->SPI_RxThresholdLevel = 0; /* Receive FIFO Threshold */
+ SPI_InitStruct->SPI_NDF = 1;
+ SPI_InitStruct->SPI_SwapRxBitEn = SPI_SWAP_DISABLE; /* reverse the rx bit or not */
+ SPI_InitStruct->SPI_SwapTxBitEn = SPI_SWAP_DISABLE;
+ SPI_InitStruct->SPI_SwapRxByteEn = SPI_SWAP_DISABLE;
+ SPI_InitStruct->SPI_SwapTxByteEn = SPI_SWAP_DISABLE;
+ SPI_InitStruct->SPI_ToggleEn = DISABLE;
+
+ SPI_InitStruct->SPI_RxDmaEn = DISABLE;
+ SPI_InitStruct->SPI_TxDmaEn = DISABLE;
+ SPI_InitStruct->SPI_RxWaterlevel =
+ 1; /* SPI Rx waterlevel, should be less than fifo threshold, the best value is
+ GDMA Msize */
+ SPI_InitStruct->SPI_TxWaterlevel =
+ 35; /* SPI Tx waterlevel, should be less than fifo threshold, the best value is
+ SPI FIFO Depth minus GDMA Msize */
+}
+
+/**
+ * @brief Enables or disables the specified SPI peripheral.
+ * @param SPIx: where x can be 0 or 1 to select the SPI peripheral.
+ * @param NewState: new state of the SPIx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI_Cmd(SPI_TypeDef *SPIx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SPI peripheral */
+ SPIx->SSIENR |= 0x01;
+ }
+ else
+ {
+ /* Disable the selected SPI peripheral */
+ SPIx->SSIENR &= ~0x01;
+ }
+}
+
+/**
+ * @brief Transmits a number of bytes through the SPIx peripheral.
+ * @param SPIx: where x can be 0 or 1
+ * @param Data : bytes to be transmitted.
+ * @retval None
+ */
+void SPI_SendBuffer(SPI_TypeDef *SPIx, uint8_t *pBuf, uint16_t len)
+{
+ uint16_t i = 0;
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ for (i = 0; i < len; i++)
+ {
+ SPIx->DR[0] = (*pBuf++);
+ /*read TFNF bit status in SR register: SET is Tx FIFO is not full*/
+ while (!(SPIx->SR & BIT(1)));
+ }
+}
+
+/**
+ * @brief Transmits a number of words through the SPIx peripheral.
+ * @param SPIx: where x can be 0 or 1
+ * @param Data : words to be transmitted.
+ * @retval None
+ */
+void SPI_SendWord(SPI_TypeDef *SPIx, uint32_t *pBuf, uint16_t len)
+{
+ uint16_t i = 0;
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ for (i = 0; i < len; i++)
+ {
+ SPIx->DR[0] = (*pBuf++);
+ /*read TFNF bit status in SR register: SET is Tx FIFO is not full*/
+ while (!(SPIx->SR & BIT(1)));
+ }
+}
+
+/**
+ * @brief Transmits a number of halfWords through the SPIx peripheral.
+ * @param SPIx: where x can be 0 or 1
+ * @param Data : Halfwords to be transmitted.
+ * @retval None
+ */
+void SPI_SendHalfWord(SPI_TypeDef *SPIx, uint16_t *pBuf, uint16_t len)
+{
+ uint16_t i = 0;
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ for (i = 0; i < len; i++)
+ {
+ SPIx->DR[0] = (*pBuf++);
+ /*read TFNF bit status in SR register: SET is Tx FIFO is not full*/
+ while (!(SPIx->SR & BIT(1)));
+ }
+}
+
+/**
+ * @brief Enables or disables the specified SPI/I2S interrupts.
+ * @param SPIx: where x can be 0 or 1
+ * @param SPI_IT: specifies the SPI/I2S interrupt source to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * @arg SPI_INT_TXE: Tx buffer empty interrupt mask
+ * @arg SPI_INT_TXO: Tx buffer overflow interrupt mask
+ * @arg SPI_INT_RXU: receive FIFO Underflow Interrupt mask
+ * @arg SPI_INT_RXO: receive FIFO Overflow Interrupt mask
+ * @arg SPI_INT_RXF: receive FIFO Full Interrupt mask which equal RXNE Interrupt!!!
+ * @arg SPI_INT_MST: multi-Master Contention Interrupt mask
+ * @param NewState: new state of the specified SPI interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI_INTConfig(SPI_TypeDef *SPIx, uint8_t SPI_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_SPI_CONFIG_IT(SPI_IT));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SPI interrupt */
+ SPIx->IMR |= SPI_IT;
+ }
+ else
+ {
+ /* Disable the selected SPI interrupt */
+ SPIx->IMR &= (uint16_t)~(SPI_IT);
+ }
+}
+
+/**
+ * @brief Clear the specified SPI interrupt.
+ * @param SPIx: where x can be 0 or 1
+ * @param SPI_IT: specifies the SPI interrupt to clear.
+ * This parameter can be one of the following values:
+ * @arg SPI_INT_MST: Multi-Master Contention Interrupt.
+ * @arg SPI_INT_RXO: Receive FIFO Overflow Interrupt.
+ * @arg SPI_INT_RXU: Receive FIFO Underflow Interrupt.
+ * @arg SPI_INT_TXO: Transmit FIFO Overflow Interrupt .
+ * @retval None.
+ */
+void SPI_ClearINTPendingBit(SPI_TypeDef *SPIx, uint16_t SPI_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_CONFIG_IT(SPI_IT));
+
+ switch (SPI_IT)
+ {
+ case SPI_INT_RXO:
+ SPIx->RXOICR;
+ break;
+ case SPI_INT_RXU:
+ SPIx->RXUICR;
+ break;
+ case SPI_INT_TXO:
+ SPIx->TXOICR;
+ break;
+ case SPI_INT_MST:
+ SPIx->FAEICR;
+ break;
+ case SPI_INT_TUF:
+ SPIx->TXUICR;
+ break;
+ case SPI_INT_RIG:
+ SPIx->SSRICR;
+ break;
+ default:
+ break;
+ }
+
+}
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/mcu/peripheral/rtl876x_tim.c b/src/mcu/peripheral/rtl876x_tim.c
new file mode 100644
index 0000000..f6e8181
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_tim.c
@@ -0,0 +1,320 @@
+/**
+**********************************************************************************************************
+* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_tim.c
+* @brief This file provides all the Timer firmware functions.
+* @details
+* @author Yuan
+* @date 2020.09.29
+* @version v1.0.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_rcc.h"
+#include "rtl876x_tim.h"
+
+/* TIM Private Defines */
+#define TIMER_CLK_SOURCE_REG_35C *((volatile uint32_t *)0x4000035CUL)
+#define TIMER_CLK_SOURCE_REG_360 *((volatile uint32_t *)0x40000360UL)
+
+/**
+ * @brief Deinitializes the TIMx peripheral registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void TIM_DeInit()
+{
+ /*enable timer IP clock and function */
+ RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, DISABLE);
+}
+
+/**
+ * @brief Initializes the TIMx Time Base Unit peripheral according to
+ * the specified parameters in the TIM_TimeBaseInitStruct.
+ * @param TIMx: where x can be 2 to 5 to select the TIM peripheral.
+ * @param TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef
+ * structure that contains the configuration information for the
+ * specified TIM peripheral.
+ * @retval None
+ */
+void TIM_TimeBaseInit(TIM_TypeDef *TIMx, TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct)
+{
+ uint32_t timerid = 0;
+ uint32_t tempreg = 0;
+ volatile uint32_t *count2_address;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_MODE(TIM_TimeBaseInitStruct->TIM_Mode));
+ assert_param(IS_TIM_PWM_DeadZone_En(TIM_TimeBaseInitStruct->PWMDeadZone_En));
+
+ /* Select clock source which can be system clock or 40 MHz or pll*/
+ tempreg = (uint32_t)TIMx;
+ timerid = (tempreg - TIM0_REG_BASE) / 20;
+
+ /*div the clock source,actually it need enable TIM_SOURCE_CLOCK_DIV_EN*/
+ TIMER_CLK_SOURCE_REG_360 |= BIT9;
+
+ if (TIMER_CLK_SOURCE_REG_360 & BIT(10))
+ {
+ TIMER_CLK_SOURCE_REG_360 &= ~(BIT(10));
+ }
+
+ if (timerid < 2)
+ {
+ TIMER_CLK_SOURCE_REG_360 &= ~(0x7 << (timerid * 3));
+ TIMER_CLK_SOURCE_REG_360 |= ((TIM_TimeBaseInitStruct->TIM_SOURCE_DIV) << (timerid * 3));
+ }
+ else if ((timerid >= 2) && (timerid < 6))
+ {
+ TIMER_CLK_SOURCE_REG_360 &= ~(0x7 << (((timerid - 2) * 3) + 13));
+ TIMER_CLK_SOURCE_REG_360 |= ((TIM_TimeBaseInitStruct->TIM_SOURCE_DIV) \
+ << (((timerid - 2) * 3) + 13));
+ }
+
+ if (timerid == 3 || timerid == 5)
+ {
+ if (TIM_TimeBaseInitStruct->ClockDepend == true)
+ {
+ TIMER_CLK_SOURCE_REG_35C |= BIT(((timerid - 1) >> 1) - 1);
+ }
+ else
+ {
+ TIMER_CLK_SOURCE_REG_35C &= ~BIT(((timerid - 1) >> 1) - 1);
+ }
+ }
+
+ /* set timer mode and mask interrupt */
+ if (TIM_TimeBaseInitStruct->TIM_PWM_En == PWM_DISABLE)
+ {
+ TIMx->ControlReg = (TIM_TimeBaseInitStruct->TIM_Mode << 1) | BIT(2);
+ /* set timer period */
+ TIMx->LoadCount = TIM_TimeBaseInitStruct->TIM_Period;
+ }
+ else
+ {
+ TIMx->ControlReg = (TIM_TimeBaseInitStruct->TIM_Mode << 1) | BIT(2) | BIT(3);
+ count2_address = &TIMER0_LOAD_COUNT2;
+ count2_address = count2_address + timerid;
+ *count2_address = TIM_TimeBaseInitStruct->TIM_PWM_High_Count ;
+ /* set timer period */
+ TIMx->LoadCount = TIM_TimeBaseInitStruct->TIM_PWM_Low_Count;
+ }
+
+ /* set pwm deadzone mode, pwm0_pn based on timer2 */
+ if (TIM_TimeBaseInitStruct->PWMDeadZone_En == ENABLE)
+ {
+ if (timerid == 2)
+ {
+ /* set pwm deadzone time */
+ TIMER_PWM2_CR = ((TIM_TimeBaseInitStruct->PWM_Deazone_Size) \
+ | (TIM_TimeBaseInitStruct->PWM_Stop_State_N << 9) \
+ | (TIM_TimeBaseInitStruct->PWM_Stop_State_P << 10) \
+ | BIT12 | BIT17 | BIT18);
+ }
+ }
+ else
+ {
+ if (timerid == 2)
+ {
+ /*disable pwm2 deadzone mode*/
+ TIMER_PWM2_CR &= ~(BIT12 | BIT17 | BIT18);
+ }
+ }
+
+ /* Clear the IT status */
+ TIMx->EOI;
+}
+
+/**
+ * @brief Fills each TIM_InitStruct member with its default value.
+ * @param TIM_InitStruct : pointer to a TIM_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void TIM_StructInit(TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct)
+{
+ TIM_TimeBaseInitStruct->TIM_Mode = TIM_Mode_UserDefine;
+ TIM_TimeBaseInitStruct->TIM_Period = 0xfff;
+ TIM_TimeBaseInitStruct->TIM_SOURCE_DIV = TIM_CLOCK_DIVIDER_1;
+ TIM_TimeBaseInitStruct->ClockDepend = false;
+ TIM_TimeBaseInitStruct->TIM_PWM_En = PWM_DISABLE;
+ TIM_TimeBaseInitStruct->PWM_Stop_State_P = PWM_STOP_AT_LOW;
+ TIM_TimeBaseInitStruct->PWM_Stop_State_N = PWM_STOP_AT_HIGH;
+ TIM_TimeBaseInitStruct->PWMDeadZone_En = DEADZONE_DISABLE;
+}
+
+/**
+ * @brief Enables or disables the specified TIM peripheral.
+ * @param TIMx: where x can be 2 to 5 to select the TIMx peripheral.
+ * @param NewState: new state of the TIMx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_Cmd(TIM_TypeDef *TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the TIM Counter */
+ TIMx->ControlReg |= BIT(0);
+ }
+ else
+ {
+ /* Disable the TIM Counter */
+ TIMx->ControlReg &= ~(BIT(0));
+ }
+}
+
+/**
+ * @brief change TIM period value.
+ * @param TIMx: where x can be 2 to 5 to select the TIMx peripheral.
+ * @retval The new state of success or not (SET or RESET).
+ */
+void TIM_ChangePeriod(TIM_TypeDef *TIMx, uint32_t period)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ TIMx->LoadCount = period;
+
+ return;
+}
+
+/**
+ * @brief Enables or disables the specified TIMx interrupt.
+ * @param TIMx: where x can be 2 to 5 to select the TIMx peripheral.
+ * @param NewState: new state of the TIMx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_INTConfig(TIM_TypeDef *TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the Interrupt sources */
+ TIMx->ControlReg &= ~(BIT(2));
+ }
+ else
+ {
+ /* Disable the Interrupt sources */
+ TIMx->ControlReg |= BIT(2);
+ }
+}
+
+/**
+ * @brief Change PWM freq and duty according high_cnt and low_cnt
+ * @param TIMx: where x can be 2 to 5 to select the TIMx peripheral.
+ * @param high_count:
+ * This parameter can be:
+ * @param low_count:
+ * This parameter can be:
+ * @retval None
+ */
+void TIM_PWMChangeFreqAndDuty(TIM_TypeDef *TIMx, uint32_t high_count, uint32_t low_count)
+{
+ volatile uint32_t *count2_address;
+ uint32_t timerid = 0;
+ uint32_t tempreg = 0;
+ tempreg = (uint32_t)TIMx;
+ timerid = (tempreg - TIM0_REG_BASE) / 20;
+ TIMx->LoadCount = low_count;
+ count2_address = &TIMER0_LOAD_COUNT2;
+ count2_address = count2_address + timerid;
+ *count2_address = high_count;
+
+}
+
+/**
+ * \brief PWM complementary output emergency stop.
+ * PWM_P emergency stop level state is configured by PWM_Stop_State_P,
+ * PWM_N emergency stop level state is configured by PWM_Stop_State_N.
+ * \param[in] PWMx: PWM2.
+ * \param[in] NewState: New state of complementary output.
+ * \ref DISABLE: Resume PWM complementary output.
+ * \ref ENABLE: PWM complementary output emergency stop.
+ * \return None.
+ * \note To use this function, need to configure the corresponding timer.
+ * PWM2 ->> TIM2.
+ */
+void TIM_PWMComplOutputEMCmd(PWM_TypeDef *PWMx, FunctionalState NewState)
+{
+ /* Check the parameters. */
+ assert_param(IS_PWM_ALL_PERIPH(PWMx));
+
+ if (NewState != DISABLE)
+ {
+ /* PWM complementary output emergency stop. */
+ PWMx->CR |= BIT8;
+ }
+ else
+ {
+ /* Resume PWM complementary output. */
+ PWMx->CR &= (~BIT8);
+ }
+}
+
+/**
+ * \brief Enable or disable bypass dead zone function of PWM complementary output.
+ * After enabling, PWM_P = ~PWM_N.
+ * \param[in] PWMx: PWM2.
+ * \param[in] NewState: New state of the PWMx peripheral.
+ * \ref DISABLE: Disable bypass dead zone function.
+ * \ref ENABLE: Enable bypass dead zone function.
+ * \note To use this function, need to configure the corresponding timer.
+ * PWM2 ->> TIM2.
+ * \return None.
+ */
+void TIM_PWMDZBypassCmd(PWM_TypeDef *PWMx, FunctionalState NewState)
+{
+ /* Check the parameters. */
+ assert_param(IS_PWM_ALL_PERIPH(PWMx));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable bypass dead zone function. */
+ PWMx->CR |= BIT13;
+ }
+ else
+ {
+ /* Disable bypass dead zone function. */
+ PWMx->CR &= (~BIT13);
+ }
+}
+
+/**
+ * \brief Change the PWM dead zone clock source.
+ * \param[in] PWMx: PWM2.
+ * \param[in] NewState: New state of the PWMx peripheral.
+ * \ref DISABLE: Use 32k clock source.
+ * \ref ENABLE: Use 5M clock source.
+ * \return None.
+ * \note To use this function, need to configure the corresponding timer.
+ * PWM2 ->> TIM2.
+ */
+void TIM_PWMChangeDZClockSrc(PWM_TypeDef *PWMx, FunctionalState NewState)
+{
+ /* Check the parameters. */
+ assert_param(IS_PWM_ALL_PERIPH(PWMx));
+
+ if (NewState != DISABLE)
+ {
+ /* Use 5M clock source. */
+ PWMx->CR |= BIT16;
+ }
+ else
+ {
+ /* Use 32k clock source. */
+ PWMx->CR &= (~BIT16);
+ }
+}
+
+/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/mcu/peripheral/rtl876x_uart.c b/src/mcu/peripheral/rtl876x_uart.c
new file mode 100644
index 0000000..df6ff62
--- /dev/null
+++ b/src/mcu/peripheral/rtl876x_uart.c
@@ -0,0 +1,425 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rtl876x_uart.c
+* @brief This file provides all the UART firmware functions.
+* @details
+* @author yuan
+* @date 2019-11-14
+* @version v1.0
+*********************************************************************************************************
+*/
+#include "rtl876x_rcc.h"
+#include "rtl876x_uart.h"
+
+#define LCR_DLAB_Set ((uint32_t)(1 << 7))
+#define LCR_DLAB_Reset ((uint32_t)~(1 << 7))
+
+/**
+ * @brief Deinitializes the UART peripheral registers to their default reset values(turn off UART clock).
+ * @param UARTx: selected UART peripheral.
+ * @retval None
+ */
+void UART_DeInit(UART_TypeDef *UARTx)
+{
+ assert_param(IS_UART_PERIPH(UARTx));
+
+ if (UARTx == UART0)
+ {
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, DISABLE);
+ }
+ else if (UARTx == UART1)
+ {
+ RCC_PeriphClockCmd(APBPeriph_UART1, APBPeriph_UART1_CLOCK, DISABLE);
+ }
+// else if (UARTx == UART2)
+// {
+// RCC_PeriphClockCmd(APBPeriph_UART2, APBPeriph_UART2_CLOCK, DISABLE);
+// }
+ return;
+}
+
+/**
+ * @brief Initializes the UART peripheral according to the specified
+ * parameters in the UART_InitStruct
+ * @param UARTx: selected UART peripheral.
+ * @param UART_InitStruct: pointer to a UART_InitTypeDef structure that
+ * contains the configuration information for the specified UART peripheral
+ * @retval None
+ */
+void UART_Init(UART_TypeDef *UARTx, UART_InitTypeDef *UART_InitStruct)
+{
+ assert_param(IS_UART_PERIPH(UARTx));
+ assert_param(IS_UART_WORD_LENGTH(UART_InitStruct->UART_WordLen));
+ assert_param(IS_UART_STOPBITS(UART_InitStruct->UART_StopBits));
+ assert_param(IS_UART_PARITY(UART_InitStruct->UART_Parity));
+ assert_param(IS_UART_RX_FIFO_TRIGGER_LEVEL(UART_InitStruct->UART_RxThdLevel));
+ assert_param(IS_UART_IDLE_TIME(UART_InitStruct->UART_IdleTime));
+ assert_param(IS_UART_DMA_CFG(UART_InitStruct->UART_DmaEn));
+ assert_param(IS_UART_AUTO_FLOW_CTRL(UART_InitStruct->UART_HardwareFlowControl));
+
+ //clear DLAB bit
+ UARTx->LCR &= LCR_DLAB_Reset;
+ //disable all interrupt
+ UARTx->DLH_INTCR = 0x00;
+
+ //read to clear Line Status Reg
+ UARTx->LSR;//cppcheck-suppress [constStatement]
+ //clear FIFO
+ UARTx->INTID_FCR |= (FCR_CLEAR_RX_FIFO_Set | FCR_CLEAR_TX_FIFO_Set);
+
+ //set baudrate, firstly set DLAB bit
+ UARTx->LCR |= LCR_DLAB_Set;
+ //set calibration parameters(OVSR)
+ UARTx->STSR &= ~0xF0;
+ UARTx->STSR |= (UART_InitStruct->UART_Ovsr << 4);
+ //set calibration parameters(OVSR_adj)
+ UARTx->SPR &= (~(0x7ff << 16));
+ UARTx->SPR |= (UART_InitStruct->UART_OvsrAdj << 16);
+ //set DLL and DLH
+ UARTx->DLL = (UART_InitStruct->UART_Div & 0x00FF);
+ UARTx->DLH_INTCR = ((UART_InitStruct->UART_Div & 0xFF00) >> 8);
+ //after set baudrate, clear DLAB bit
+ UARTx->LCR &= LCR_DLAB_Reset;
+
+ //set LCR reg
+ UARTx->LCR = (UART_InitStruct->UART_Parity | UART_InitStruct->UART_StopBits |
+ UART_InitStruct->UART_WordLen);
+ //set FCR reg, FIFO must enable
+ UARTx->INTID_FCR = ((1 << 0) | UART_InitStruct->UART_TxThdLevel << 16 \
+ | UART_InitStruct->UART_RxThdLevel << 8 | UART_InitStruct->UART_DmaEn);
+
+ /* hardware flow control */
+ UARTx->MCR &= (~((1 << 5) | (1 << 1)));
+ UARTx->MCR |= UART_InitStruct->UART_HardwareFlowControl;
+
+ /* set rx idle time */
+ UARTx->RX_IDLE_TOCR = (UART_InitStruct->UART_IdleTime);
+
+ if (UART_InitStruct->UART_DmaEn == UART_DMA_ENABLE)
+ {
+ /* Config UART Tx dma parameter */
+ if (UART_InitStruct->UART_TxDmaEn != DISABLE)
+ {
+ /* Mask uart TX threshold value */
+ UARTx->MISCR &= ~(0x1f << 3);
+ UARTx->MISCR |= ((UART_InitStruct->UART_TxWaterLevel) << 3) | BIT(1);
+ }
+ /* Config UART Rx dma parameter */
+ if (UART_InitStruct->UART_RxDmaEn != DISABLE)
+ {
+ /* Mask uart RX threshold value */
+ UARTx->MISCR &= ~(0x3f << 8);
+ UARTx->MISCR |= (UART_InitStruct->UART_RxWaterLevel << 8) | BIT(2);
+ }
+ }
+
+ return;
+}
+
+/**
+ * @brief Fills each UART_InitStruct member with its default value.
+ * @param UART_InitStruct: pointer to an UART_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void UART_StructInit(UART_InitTypeDef *UART_InitStruct)
+{
+ //115200 default
+ UART_InitStruct->UART_Div = 20;
+ UART_InitStruct->UART_Ovsr = 12;
+ UART_InitStruct->UART_OvsrAdj = 0x252;
+
+ UART_InitStruct->UART_WordLen = UART_WORD_LENGTH_8BIT;
+ UART_InitStruct->UART_StopBits = UART_STOP_BITS_1;
+ UART_InitStruct->UART_Parity = UART_PARITY_NO_PARTY;
+ UART_InitStruct->UART_TxThdLevel = 16; //1~29
+ UART_InitStruct->UART_RxThdLevel = 16; //1~29
+ UART_InitStruct->UART_IdleTime = UART_RX_IDLE_2BYTE; //idle interrupt wait time
+ UART_InitStruct->UART_HardwareFlowControl = UART_HW_FLOW_CTRL_DISABLE;
+ UART_InitStruct->UART_DmaEn = UART_DMA_DISABLE;
+ UART_InitStruct->UART_TxDmaEn = DISABLE;
+ UART_InitStruct->UART_RxDmaEn = DISABLE;
+ UART_InitStruct->UART_TxWaterLevel = 15; //Better to equal TX_FIFO_SIZE(16)- GDMA_MSize
+ UART_InitStruct->UART_RxWaterLevel = 1; //Better to equal GDMA_MSize
+ return;
+}
+
+/**
+ * @brief Mask or unmask the specified UART interrupts.
+ * @param UART_INT: specifies the IR interrupts sources to be mask or unmask.
+ * This parameter can be the following values:
+ * @arg UART_INT_MASK_RD_AVA: mask INTCR(erbi).
+ * @arg UART_INT_MASK_TX_FIFO_EMPTY: mask INTCR(etbei).
+ * @arg UART_INT_MASK_RX_LINE_STS: mask INTCR(elsi).
+ * @arg UART_INT_MASK_MODEM_STS: mask INTCR(edssi).
+ * @arg UART_INT_MASK_RX_BREAK: mask rx break interrupt.
+ * @arg UART_INT_MASK_RX_IDLE: mask rx idle interrupt.
+ * @arg UART_INT_MASK_TX_DONE: mask the interrupt tx done interrupt.
+ * @arg UART_INT_MASK_TX_THD: mask tx fifo threshold interrupt.
+ * @param NewState: new state of the specified UART interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void UART_MaskINTConfig(UART_TypeDef *UARTx, uint32_t UART_INT_MASK, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_PERIPH(UARTx));
+ assert_param(IS_UART_INT_MASK(UART_INT_MASK));
+ assert_param(IS_FUNCTIONAL_STATE(newState));
+
+ if (NewState != DISABLE)
+ {
+ UARTx->INTMASK |= UART_INT_MASK;
+ }
+ else
+ {
+ UARTx->INTMASK &= ~(UART_INT_MASK);
+ }
+}
+
+/**
+ * @brief Enables or disables the specified UART interrupts.
+ * @param UARTx: selected UARTx peripheral.
+ * @param UART_INT: specifies the UART interrupts sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg UART_INT_RD_AVA: Rx data available interrupt source.
+ * @arg UART_INT_TX_FIFO_EMPTY: Tx FIFO empty interrupt source.
+ * @arg UART_INT_RX_LINE_STS: Rx line status interrupt source.
+ * @arg UART_INT_MODEM_STS: modem status interrupt source.
+ * @arg UART_INT_TX_DONE: Tx data done interrupt source.
+ * @arg UART_INT_TX_THD: Tx FIFO data <= thredhold interrupt source.
+ * @arg UART_INT_RX_BREAK: Rx break signal interrupt source.
+ * @arg UART_INT_RX_IDLE: Rx idle interrupt source.
+ * @param NewState: new state of the specified UART interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void UART_INTConfig(UART_TypeDef *UARTx, uint32_t UART_INT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_PERIPH(UARTx));
+ assert_param(IS_UART_INT(UART_INT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (UART_INT & UART_INT_RX_IDLE)
+ {
+ if (NewState == ENABLE)
+ {
+ UARTx->RX_IDLE_INTSR |= BIT0;
+ UARTx->RX_IDLE_INTCR |= BIT0;
+ UARTx->RX_IDLE_TOCR |= BIT31;
+ }
+ else
+ {
+ UARTx->RX_IDLE_TOCR &= (~BIT31);
+ UARTx->RX_IDLE_INTCR &= (~BIT0);
+ }
+ }
+
+ if (UART_INT & UART_INT_RX_BREAK)
+ {
+ if (NewState == ENABLE)
+ {
+ UARTx->SPR |= BIT7;
+ }
+ else
+ {
+ UARTx->SPR &= (~BIT7);
+ }
+ }
+
+ if (UART_INT & 0x3F)
+ {
+ if (NewState == ENABLE)
+ {
+ /* Enable the selected UARTx interrupts */
+ UARTx->DLH_INTCR |= UART_INT;
+ }
+ else
+ {
+ /* Disable the selected UARTx interrupts */
+ UARTx->DLH_INTCR &= (uint32_t)~UART_INT;
+ }
+ }
+ return;
+}
+
+/**
+ * @brief Send data to tx FIFO.
+ * @param UARTx: selected UART peripheral.
+ * @param inBuf: buffer to be written to Tx FIFO.
+ * @param num: number of data to be written.
+ * @retval None
+ */
+void UART_SendData(UART_TypeDef *UARTx, const uint8_t *inBuf, uint16_t num)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_PERIPH(UARTx));
+
+ while (num--)
+ {
+ UARTx->RB_THR = *inBuf++;
+ }
+
+ return;
+}
+
+/**
+ * @brief Receive data from rx FIFO.
+ * @param UARTx: selected UART peripheral.
+ * @param[out] outBuf: buffer to save data read from UART FIFO.
+ * @param count: number of data to be read.
+ * @retval None
+ */
+void UART_ReceiveData(UART_TypeDef *UARTx, uint8_t *outBuf, uint16_t count)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_PERIPH(UARTx));
+
+ while (count--)
+ {
+ *outBuf++ = (uint8_t)UARTx->RB_THR;
+ }
+
+ return;
+}
+
+/**
+ *@brief Change UART baudrate.
+ *@param UARTx: selected UART peripheral.
+ *@param div: parameter of the selected UART baudrate.
+ *@param ovsr: parameter of the selected UART baudrate.
+ *@param ovsr_adj: parameter of the selected UART baudrate.
+ *@retval None.
+ */
+void UART_SetBaudRate(UART_TypeDef *UARTx, uint16_t div, uint16_t ovsr, uint16_t ovsr_adj)
+{
+ //set baudrate, firstly set DLAB bit
+ UARTx->LCR |= LCR_DLAB_Set;
+
+ //set calibration parameters(OVSR)
+ UARTx->STSR &= ~0xF0;
+ UARTx->STSR |= (ovsr << 4);
+ //set calibration parameters(OVSR_adj)
+ UARTx->SPR &= (~(0x7ff << 16));
+ UARTx->SPR |= (ovsr_adj << 16);
+ //set DLL and DLH
+ UARTx->DLL = (div & 0x00FF);
+ UARTx->DLH_INTCR = ((div & 0xFF00) >> 8);
+
+ //after set baudrate, clear DLAB bit
+ UARTx->LCR &= LCR_DLAB_Reset;
+}
+
+/**
+ *@brief Set UART parameters.
+ *@param UARTx: selected UART peripheral.
+ *@param wordLen: data width of selected UART peripheral.
+ *@param parity: parity of selected UART peripheral.
+ *@param stopBits: stop bit of selected UART peripheral.
+ *@retval None
+ */
+void UART_SetParams(UART_TypeDef *UARTx, uint16_t wordLen, uint16_t parity, uint16_t stopBits)
+{
+ //set LCR reg
+ UARTx->LCR = (wordLen | stopBits | parity);
+}
+
+/**
+ *@brief UART loop back mode config.
+ *@param UARTx: selected UART peripheral.
+ *@param NewState: new state of the DMA Channelx.
+ * This parameter can be: ENABLE or DISABLE.
+ *@retval None.
+ */
+void UART_LoopBackCmd(UART_TypeDef *UARTx, FunctionalState NewState)
+{
+ assert_param(IS_UART_PERIPH(UARTx));
+
+ if (NewState == ENABLE)
+ {
+ UARTx->MCR |= BIT4;
+ }
+ else
+ {
+ UARTx->MCR &= ~BIT4;
+ }
+}
+
+/**
+ * @brief Checks whether the specified UART flag is set or not.
+ * @param UARTx: selected UART peripheral.
+ * @param UART_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg UART_FLAG_RX_DATA_RDY: rx data is available.
+ * @arg UART_FLAG_RX_OVERRUN: rx overrun.
+ * @arg UART_FLAG_PARTY_ERR: parity error.
+ * @arg UART_FLAG_FRAME_ERR: UARTx frame error.
+ * @arg UART_FLAG_BREAK_ERR: UARTx break error.
+ * @arg UART_FLAG_THR_EMPTY: tx FIFO is empty.
+ * @arg UART_FLAG_THR_TSR_EMPTY: tx FIFO and tx shift reg are both empty.
+ * @arg UART_FLAG_RX_FIFO_ERR: rx FIFO error.
+ * @arg UART_FLAG_RX_IDLE.
+ * @retval The new state of UART_FLAG (SET or RESET).
+ */
+FlagStatus UART_GetFlagStatus(UART_TypeDef *UARTx, uint32_t UART_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_UART_PERIPH(UARTx));
+ assert_param(IS_UART_GET_FLAG(UART_FLAG));
+
+ if (UART_FLAG == UART_FLAG_TX_THD)
+ {
+ if (UARTx->TX_THR_INTSR & BIT(0))
+ {
+ bitstatus = SET;
+ }
+ }
+ else if (UART_FLAG == UART_FLAG_TX_DONE)
+ {
+ if (UARTx->TX_DONE_INTSR & BIT(0))
+ {
+ bitstatus = SET;
+ }
+ }
+ else if (UART_FLAG == UART_FLAG_RX_IDLE)
+ {
+ if (UARTx->RX_IDLE_INTSR & BIT(0))
+ {
+ bitstatus = SET;
+ }
+ }
+ else
+ {
+ if (UARTx->LSR & UART_FLAG)
+ {
+ bitstatus = SET;
+ }
+ }
+
+ return bitstatus;
+}
+
+///**
+// * @brief Get interrupt identifier.
+// * @param UARTx: selected UART peripheral.
+// * @retval The interrupt identifier value.
+// * This return value can be one of the following values:
+// * @arg UART_INT_ID_LINE_STATUS: interrupt identifier--line status interrupt.
+// * @arg UART_INT_ID_RX_LEVEL_REACH: interrupt identifier--rx trigger level reached interrupt.
+// * @arg UART_INT_ID_RX_TMEOUT: interrupt identifier--line status interrupt.
+// * @arg UART_INT_ID_TX_EMPTY: interrupt identifier--line status interrupt.
+// * @arg UART_INT_ID_MODEM_STATUS: interrupt identifier--line status interrupt.
+// */
+//__STATIC_INLINE uint16_t UART_GetINTStatus(UART_TypeDef *UARTx)
+//{
+// /* Check the parameters */
+// assert_param(IS_UART_PERIPH(UARTx));
+
+// return (uint16_t)(UARTx->INTID_FCR & (0x0000000E));
+//}
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor *****END OF FILE****/
diff --git a/src/mcu/rtl876x/arm/startup_rtl876x.s b/src/mcu/rtl876x/arm/startup_rtl876x.s
new file mode 100644
index 0000000..39b3579
--- /dev/null
+++ b/src/mcu/rtl876x/arm/startup_rtl876x.s
@@ -0,0 +1,280 @@
+
+ EXPORT __initial_sp
+__initial_sp EQU (0x200000 + 14 * 1024)
+
+ PRESERVE8
+ THUMB
+
+; Vector Table Mapped to Address 0 at Reset
+
+ AREA VECTOR, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD System_Handler ;[0] System On interrupt
+ DCD WDG_Handler ;[1] Watch dog global insterrupt
+ DCD BTMAC_Handler ;[2] See Below Table ( an Extension of interrupt )
+ DCD Timer3_Handler ;[3] Timer3 global interrupt
+ DCD Timer2_Handler ;[4] Timer2 global interrupt
+ DCD HardFault_Handler ;[5] Platform interrupt (platform error interrupt)
+ DCD I2S0_TX_Handler ;[6] I2S0 TX interrupt
+ DCD I2S0_RX_Handler ;[7] I2S0 RX interrupt
+ DCD Timer4_5_Handler ;[8] Timer[4:7] global interrupt
+ DCD GPIO4_Handler ;[9] GPIO 4 interrupt
+ DCD GPIO5_Handler ;[10] GPIO 5 interrupt
+ DCD UART1_Handler ;[11] Uart1 interrupt (default for log)
+ DCD UART0_Handler ;[12] Uart0 interrupt
+ DCD RTC_Handler ;[13] Realtime counter interrupt
+ DCD SPI0_Handler ;[14] SPI0 interrupt
+ DCD SPI1_Handler ;[15] SPI1 interrupt
+ DCD I2C0_Handler ;[16] I2C0 interrupt
+ DCD I2C1_Handler ;[17] I2C1 interrupt
+ DCD ADC_Handler ;[18] ADC global interrupt
+ DCD Peripheral_Handler ;[19] See Below Table ( an Extension of interrupt )
+ DCD GDMA0_Channel0_Handler ;[20] RTK-DMA0 channel 0 global interrupt
+ DCD GDMA0_Channel1_Handler ;[21] RTK-DMA0 channel 1 global interrupt
+ DCD GDMA0_Channel2_Handler ;[22] RTK-DMA0 channel 2 global interrupt
+ DCD GDMA0_Channel3_Handler ;[23] RTK-DMA0 channel 3 global interrupt
+ DCD Enhanced_Timer0_Handler ;[24] Enhanced Timer0
+ DCD Enhanced_Timer1_Handler ;[25] Enhanced Timer1
+ DCD GPIO_Group3_Handler ;[26] GPIO(n*4)+3,n={0:7} global interrupt
+ DCD GPIO_Group2_Handler ;[27] GPIO(n*4)+2,n={0:7} global interrupt
+ DCD IR_Handler ;[28] IR module global interrupt
+ DCD GPIO_Group1_Handler ;[29] GPIO(n*4)+1,n={0:7}-{1} global interrupt
+ DCD GPIO_Group0_Handler ;[30] GPIO(n*4)+0,n={0:7}-{1} global interrupt
+ DCD 0 ;[31] Reserved
+
+ ;Timer[4:5] interrupt
+ DCD Timer4_Handler ;8, 0, 48
+ DCD Timer5_Handler ;8, 1, 49
+
+ ;Peripheral Interrupts not special interrupt
+ ;Interrupt name, Interrupt status bit, Offset in vector
+ DCD SPI_Flash_Handler ;19, 0, 50
+ DCD Qdecode_Handler ;19, 1, 51
+ DCD Keyscan_Handler ;19, 2, 52
+ DCD SPI2W_Handler ;19, 3, 53
+ DCD LPCOMP_Handler ;19, 4, 54
+ DCD PTA_Mailbox_Handler ;19, 5, 55
+ DCD CAP_Touch_Handler ;19, 6, 56
+ DCD TRNG_Handler ;19, 9, 57
+__Vectors_End
+
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+ AREA RESET, CODE, READONLY
+
+; Reset Handler
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT SystemInit
+ LDR R0, =SystemInit
+ BX R0
+
+ ENDP ; end of Reset_Handler
+
+
+ AREA |.text|, CODE, READONLY
+Default_Handler PROC
+ EXPORT Default_Handler [WEAK]
+ EXPORT NMI_Handler [WEAK]
+ EXPORT HardFault_Handler [WEAK]
+ EXPORT MemManage_Handler [WEAK]
+ EXPORT BusFault_Handler [WEAK]
+ EXPORT UsageFault_Handler [WEAK]
+ EXPORT SVC_Handler [WEAK]
+ EXPORT PendSV_Handler [WEAK]
+ EXPORT SysTick_Handler [WEAK]
+ EXPORT System_Handler [WEAK]
+ EXPORT WDG_Handler [WEAK]
+ EXPORT BTMAC_Handler [WEAK]
+ EXPORT Timer3_Handler [WEAK]
+ EXPORT Timer2_Handler [WEAK]
+ EXPORT I2S0_TX_Handler [WEAK]
+ EXPORT I2S0_RX_Handler [WEAK]
+ EXPORT Timer4_5_Handler [WEAK]
+ EXPORT GPIO4_Handler [WEAK]
+ EXPORT GPIO5_Handler [WEAK]
+ EXPORT UART1_Handler [WEAK]
+ EXPORT UART0_Handler [WEAK]
+ EXPORT RTC_Handler [WEAK]
+ EXPORT SPI0_Handler [WEAK]
+ EXPORT SPI1_Handler [WEAK]
+ EXPORT I2C0_Handler [WEAK]
+ EXPORT I2C1_Handler [WEAK]
+ EXPORT ADC_Handler [WEAK]
+ EXPORT Peripheral_Handler [WEAK]
+ EXPORT GDMA0_Channel0_Handler [WEAK]
+ EXPORT GDMA0_Channel1_Handler [WEAK]
+ EXPORT GDMA0_Channel2_Handler [WEAK]
+ EXPORT GDMA0_Channel3_Handler [WEAK]
+ EXPORT Enhanced_Timer0_Handler [WEAK]
+ EXPORT Enhanced_Timer1_Handler [WEAK]
+ EXPORT GPIO_Group3_Handler [WEAK]
+ EXPORT GPIO_Group2_Handler [WEAK]
+ EXPORT IR_Handler [WEAK]
+ EXPORT GPIO_Group1_Handler [WEAK]
+ EXPORT GPIO_Group0_Handler [WEAK]
+
+ ;Extension Interrupts
+ EXPORT Timer4_Handler [WEAK]
+ EXPORT Timer5_Handler [WEAK]
+ EXPORT SPI_Flash_Handler [WEAK]
+ EXPORT Qdecode_Handler [WEAK]
+ EXPORT Keyscan_Handler [WEAK]
+ EXPORT SPI2W_Handler [WEAK]
+ EXPORT LPCOMP_Handler [WEAK]
+ EXPORT PTA_Mailbox_Handler [WEAK]
+ EXPORT CAP_Touch_Handler [WEAK]
+ EXPORT TRNG_Handler [WEAK]
+ EXPORT GPIO0_Handler [WEAK]
+ EXPORT GPIO1_Handler [WEAK]
+ EXPORT GPIO2_Handler [WEAK]
+ EXPORT GPIO3_Handler [WEAK]
+ EXPORT GPIO6_Handler [WEAK]
+ EXPORT GPIO7_Handler [WEAK]
+ EXPORT GPIO8_Handler [WEAK]
+ EXPORT GPIO9_Handler [WEAK]
+ EXPORT GPIO10_Handler [WEAK]
+ EXPORT GPIO11_Handler [WEAK]
+ EXPORT GPIO12_Handler [WEAK]
+ EXPORT GPIO13_Handler [WEAK]
+ EXPORT GPIO14_Handler [WEAK]
+ EXPORT GPIO15_Handler [WEAK]
+ EXPORT GPIO16_Handler [WEAK]
+ EXPORT GPIO17_Handler [WEAK]
+ EXPORT GPIO18_Handler [WEAK]
+ EXPORT GPIO19_Handler [WEAK]
+ EXPORT GPIO20_Handler [WEAK]
+ EXPORT GPIO21_Handler [WEAK]
+ EXPORT GPIO22_Handler [WEAK]
+ EXPORT GPIO23_Handler [WEAK]
+ EXPORT GPIO24_Handler [WEAK]
+ EXPORT GPIO25_Handler [WEAK]
+ EXPORT GPIO26_Handler [WEAK]
+ EXPORT GPIO27_Handler [WEAK]
+ EXPORT GPIO28_Handler [WEAK]
+ EXPORT GPIO29_Handler [WEAK]
+ EXPORT GPIO30_Handler [WEAK]
+ EXPORT GPIO31_Handler [WEAK]
+NMI_Handler
+HardFault_Handler
+MemManage_Handler
+BusFault_Handler
+UsageFault_Handler
+SVC_Handler
+PendSV_Handler
+SysTick_Handler
+System_Handler
+WDG_Handler
+BTMAC_Handler
+Timer3_Handler
+Timer2_Handler
+I2S0_TX_Handler
+I2S0_RX_Handler
+Timer4_5_Handler
+GPIO4_Handler
+GPIO5_Handler
+UART1_Handler
+UART0_Handler
+RTC_Handler
+SPI0_Handler
+SPI1_Handler
+I2C0_Handler
+I2C1_Handler
+ADC_Handler
+Peripheral_Handler
+GDMA0_Channel0_Handler
+GDMA0_Channel1_Handler
+GDMA0_Channel2_Handler
+GDMA0_Channel3_Handler
+Enhanced_Timer0_Handler
+Enhanced_Timer1_Handler
+GPIO_Group3_Handler
+GPIO_Group2_Handler
+IR_Handler
+GPIO_Group1_Handler
+GPIO_Group0_Handler
+
+;Extension Interrupts
+Timer4_Handler
+Timer5_Handler
+SPI_Flash_Handler
+Qdecode_Handler
+Keyscan_Handler
+SPI2W_Handler
+LPCOMP_Handler
+PTA_Mailbox_Handler
+CAP_Touch_Handler
+TRNG_Handler
+GPIO0_Handler
+GPIO1_Handler
+GPIO2_Handler
+GPIO3_Handler
+GPIO6_Handler
+GPIO7_Handler
+GPIO8_Handler
+GPIO9_Handler
+GPIO10_Handler
+GPIO11_Handler
+GPIO12_Handler
+GPIO13_Handler
+GPIO14_Handler
+GPIO15_Handler
+GPIO16_Handler
+GPIO17_Handler
+GPIO18_Handler
+GPIO19_Handler
+GPIO20_Handler
+GPIO21_Handler
+GPIO22_Handler
+GPIO23_Handler
+GPIO24_Handler
+GPIO25_Handler
+GPIO26_Handler
+GPIO27_Handler
+GPIO28_Handler
+GPIO29_Handler
+GPIO30_Handler
+GPIO31_Handler
+ IMPORT log_direct
+ LDR R0, =0x20000000
+ LDR R1, =DEFAULT_HANDLER_TXT
+ MRS R2, IPSR
+ LDR R3, =log_direct
+ BLX R3
+ B .
+
+ ENDP
+
+
+; User Initial Stack
+ EXPORT __user_setup_stackheap
+__user_setup_stackheap PROC
+ BX LR
+ ENDP
+
+DEFAULT_HANDLER_TXT
+ DCB "Error! Please implement your ISR Handler for IRQ %d!\n", 0 ; Null terminated string
+ ALIGN
+
+ END
diff --git a/src/mcu/rtl876x/arm/startup_rtl876x_gcc.s b/src/mcu/rtl876x/arm/startup_rtl876x_gcc.s
new file mode 100644
index 0000000..30b254c
--- /dev/null
+++ b/src/mcu/rtl876x/arm/startup_rtl876x_gcc.s
@@ -0,0 +1,371 @@
+;/*****************************************************************************/
+;/* startup_rtl8762c_gcc.s: Startup file for Realtek RTL8762C device series */
+;/*****************************************************************************/
+
+/**
+**===========================================================================
+** Definitions
+**===========================================================================
+*/
+ .syntax unified
+ .cpu cortex-m4
+ .fpu softvfp
+ .thumb
+
+ .global g_pfnVectors
+ .global Default_Handler
+ .type Default_Handler, %function
+
+
+.equ _estack, 0x00203800
+/**
+**===========================================================================
+** Program - Reset_Handler
+** Abstract: This code gets called after a reset event.
+**===========================================================================
+*/
+ .section RESET
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+ LDR R0, = SystemInit
+ BX R0
+
+/**
+**===========================================================================
+** Program - Default_Handler
+** Abstract: This code gets called when the processor receives an
+** unexpected interrupt.
+**===========================================================================
+*/
+ .section .text,"ax",%progbits
+ Default_Handler:
+ b .
+ .size Default_Handler, .-Default_Handler
+/**
+**===========================================================================
+** Reset, Exception, and Interrupt vectors
+**===========================================================================
+*/
+
+ .section VECTOR,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+g_pfnVectors:
+ /* Processor exception vectors */
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word 0
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+
+
+ /* Interrupt Handlers for RTL8762C Peripherals */
+ .word System_Handler /*[0] System On interrupt*/
+ .word WDG_Handler /*[1] Watch dog global insterrupt*/
+ .word BTMAC_Handler /*[2] See Below Table ( an Extension of interrupt )*/
+ .word Timer3_Handler /*[3] Timer3 global interrupt*/
+ .word Timer2_Handler /*[4] Timer2 global interrupt*/
+ .word HardFault_Handler /*[5] Platform interrupt (platform error interrupt)*/
+ .word I2S0_TX_Handler /*[6] I2S0 TX interrupt*/
+ .word I2S0_RX_Handler /*[7] I2S0 RX interrupt*/
+ .word Timer4_5_Handler /*[8] Timer[4:7] global interrupt*/
+ .word GPIO4_Handler /*[9] GPIO 4 interrupt*/
+ .word GPIO5_Handler /*[10] GPIO 5 interrupt*/
+ .word UART1_Handler /*[11] Uart1 interrupt*/
+ .word UART0_Handler /*[12] Uart0 interrupt*/
+ .word RTC_Handler /*[13] Realtime counter interrupt*/
+ .word SPI0_Handler /*[14] SPI0 interrupt*/
+ .word SPI1_Handler /*[15] SPI1 interrupt*/
+ .word I2C0_Handler /*[16] I2C0 interrupt*/
+ .word I2C1_Handler /*[17] I2C1 interrupt*/
+ .word ADC_Handler /*[18] ADC global interrupt*/
+ .word Peripheral_Handler /*[19] See Below Table ( an Extension of interrupt )*/
+ .word GDMA0_Channel0_Handler /*[20] RTK-DMA0 channel 0 global interrupt*/
+ .word GDMA0_Channel1_Handler /*[21] RTK-DMA0 channel 1 global interrupt*/
+ .word GDMA0_Channel2_Handler /*[22] RTK-DMA0 channel 2 global interrupt*/
+ .word GDMA0_Channel3_Handler /*[23] RTK-DMA0 channel 3 global interrupt*/
+ .word Enhanced_Timer0_Handler /*[24] RTK-DMA0 channel 4 global interrupt*/
+ .word Enhanced_Timer1_Handler /*[25] RTK-DMA0 channel 5 global interrupt (default for log)*/
+ .word GPIO_Group3_Handler /*[26] GPIO(n*4)+3,n={0:7} global interrupt*/
+ .word GPIO_Group2_Handler /*[27] GPIO(n*4)+2,n={0:7} global interrupt*/
+ .word IR_Handler /*[28] IR module global interrupt*/
+ .word GPIO_Group1_Handler /*[29] GPIO(n*4)+1,n={0:7}-{1} global interrupt*/
+ .word GPIO_Group0_Handler /*[30] GPIO(n*4)+0,n={0:7}-{1} global interrupt*/
+ .word 0 /*[31] Uart2 interrupt (default for log)*/
+
+ .word Timer4_Handler /* 8, 0, 48 */
+ .word Timer5_Handler /* 8, 1, 49 */
+ .word SPI_Flash_Handler /* 19, 0, 52 */
+ .word Qdecode_Handler /* 9, 1, 53 */
+ .word Keyscan_Handler /* 19, 2, 54 */
+ .word SPI2W_Handler /* 19, 3, 55 */
+ .word LPCOMP_Handler /* 19, 4, 56 */
+ .word PTA_Mailbox_Handler /* 19, 5, 57 */
+ .word CAP_Touch_Handler /* 19, 6, 58 */
+ .word TRNG_Handler /* 19, 7, 59 */
+
+
+
+/**
+**===========================================================================
+** Provide weak aliases for each Exception handler to the Default_Handler.
+**===========================================================================
+*/
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak System_Handler
+ .thumb_set System_Handler,Default_Handler
+
+ .weak WDG_Handler
+ .thumb_set WDG_Handler,Default_Handler
+
+ .weak BTMAC_Handler
+ .thumb_set BTMAC_Handler,Default_Handler
+
+ .weak Timer3_Handler
+ .thumb_set Timer3_Handler,Default_Handler
+
+ .weak Timer2_Handler
+ .thumb_set Timer2_Handler,Default_Handler
+
+ .weak I2S0_TX_Handler
+ .thumb_set I2S0_TX_Handler,Default_Handler
+
+ .weak I2S0_RX_Handler
+ .thumb_set I2S0_RX_Handler,Default_Handler
+
+ .weak Timer4_5_Handler
+ .thumb_set Timer4_5_Handler,Default_Handler
+
+ .weak GPIO4_Handler
+ .thumb_set GPIO4_Handler,Default_Handler
+
+ .weak GPIO5_Handler
+ .thumb_set GPIO5_Handler,Default_Handler
+
+ .weak UART1_Handler
+ .thumb_set UART1_Handler,Default_Handler
+
+ .weak UART0_Handler
+ .thumb_set UART0_Handler,Default_Handler
+
+ .weak RTC_Handler
+ .thumb_set RTC_Handler,Default_Handler
+
+ .weak SPI0_Handler
+ .thumb_set SPI0_Handler,Default_Handler
+
+ .weak SPI1_Handler
+ .thumb_set SPI1_Handler,Default_Handler
+
+ .weak I2C0_Handler
+ .thumb_set I2C0_Handler,Default_Handler
+
+ .weak I2C1_Handler
+ .thumb_set I2C1_Handler,Default_Handler
+
+ .weak ADC_Handler
+ .thumb_set ADC_Handler,Default_Handler
+
+ .weak Peripheral_Handler
+ .thumb_set Peripheral_Handler,Default_Handler
+
+ .weak GDMA0_Channel0_Handler
+ .thumb_set GDMA0_Channel0_Handler,Default_Handler
+
+ .weak GDMA0_Channel1_Handler
+ .thumb_set GDMA0_Channel1_Handler,Default_Handler
+
+ .weak GDMA0_Channel2_Handler
+ .thumb_set GDMA0_Channel2_Handler,Default_Handler
+
+ .weak GDMA0_Channel3_Handler
+ .thumb_set GDMA0_Channel3_Handler,Default_Handler
+
+ .weak Enhanced_Timer0_Handler
+ .thumb_set Enhanced_Timer0_Handler,Default_Handler
+
+ .weak Enhanced_Timer1_Handler
+ .thumb_set Enhanced_Timer1_Handler,Default_Handler
+
+ .weak GPIO_Group3_Handler
+ .thumb_set GPIO_Group3_Handler,Default_Handler
+
+ .weak GPIO_Group2_Handler
+ .thumb_set GPIO_Group2_Handler,Default_Handler
+
+ .weak IR_Handler
+ .thumb_set IR_Handler,Default_Handler
+
+ .weak GPIO_Group1_Handler
+ .thumb_set GPIO_Group1_Handler,Default_Handler
+
+ .weak GPIO_Group0_Handler
+ .thumb_set GPIO_Group0_Handler,Default_Handler
+
+ .weak UART2_Handler
+ .thumb_set UART2_Handler,Default_Handler
+
+ .weak Timer4_Handler
+ .thumb_set Timer4_Handler,Default_Handler
+
+ .weak Timer5_Handler
+ .thumb_set Timer5_Handler,Default_Handler
+
+ .weak Timer6_Handler
+ .thumb_set Timer6_Handler,Default_Handler
+
+ .weak Timer7_Handler
+ .thumb_set Timer7_Handler,Default_Handler
+
+ .weak SPI_Flash_Handler
+ .thumb_set SPI_Flash_Handler,Default_Handler
+
+ .weak Qdecode_Handler
+ .thumb_set Qdecode_Handler,Default_Handler
+
+ .weak Keyscan_Handler
+ .thumb_set Keyscan_Handler,Default_Handler
+
+ .weak SPI2W_Handler
+ .thumb_set SPI2W_Handler,Default_Handler
+
+ .weak LPCOMP_Handler
+ .thumb_set LPCOMP_Handler,Default_Handler
+
+ .weak PTA_Mailbox_Handler
+ .thumb_set PTA_Mailbox_Handler,Default_Handler
+
+ .weak CAP_Touch_Handler
+ .thumb_set CAP_Touch_Handler,Default_Handler
+
+ .weak TRNG_Handler
+ .thumb_set TRNG_Handler,Default_Handler
+
+
+ .weak GPIO0_Handler
+ .thumb_set GPIO0_Handler,Default_Handler
+
+ .weak GPIO1_Handler
+ .thumb_set GPIO1_Handler,Default_Handler
+
+ .weak GPIO2_Handler
+ .thumb_set GPIO2_Handler,Default_Handler
+
+ .weak GPIO3_Handler
+ .thumb_set GPIO3_Handler,Default_Handler
+
+ .weak GPIO6_Handler
+ .thumb_set GPIO6_Handler,Default_Handler
+
+ .weak GPIO7_Handler
+ .thumb_set GPIO7_Handler,Default_Handler
+
+ .weak GPIO8_Handler
+ .thumb_set GPIO8_Handler,Default_Handler
+
+ .weak GPIO9_Handler
+ .thumb_set GPIO9_Handler,Default_Handler
+
+ .weak GPIO10_Handler
+ .thumb_set GPIO10_Handler,Default_Handler
+
+ .weak GPIO11_Handler
+ .thumb_set GPIO11_Handler,Default_Handler
+
+ .weak GPIO12_Handler
+ .thumb_set GPIO12_Handler,Default_Handler
+
+ .weak GPIO13_Handler
+ .thumb_set GPIO13_Handler,Default_Handler
+
+ .weak GPIO14_Handler
+ .thumb_set GPIO14_Handler,Default_Handler
+
+ .weak GPIO15_Handler
+ .thumb_set GPIO15_Handler,Default_Handler
+
+ .weak GPIO16_Handler
+ .thumb_set GPIO16_Handler,Default_Handler
+
+ .weak GPIO17_Handler
+ .thumb_set GPIO17_Handler,Default_Handler
+
+ .weak GPIO18_Handler
+ .thumb_set GPIO18_Handler,Default_Handler
+
+ .weak GPIO19_Handler
+ .thumb_set GPIO19_Handler,Default_Handler
+
+ .weak GPIO20_Handler
+ .thumb_set GPIO20_Handler,Default_Handler
+
+ .weak GPIO21_Handler
+ .thumb_set GPIO21_Handler,Default_Handler
+
+ .weak GPIO22_Handler
+ .thumb_set GPIO22_Handler,Default_Handler
+
+ .weak GPIO23_Handler
+ .thumb_set GPIO23_Handler,Default_Handler
+
+ .weak GPIO24_Handler
+ .thumb_set GPIO24_Handler,Default_Handler
+
+ .weak GPIO25_Handler
+ .thumb_set GPIO25_Handler,Default_Handler
+
+ .weak GPIO26_Handler
+ .thumb_set GPIO26_Handler,Default_Handler
+
+ .weak GPIO27_Handler
+ .thumb_set GPIO27_Handler,Default_Handler
+
+ .weak GPIO28_Handler
+ .thumb_set GPIO28_Handler,Default_Handler
+
+ .weak GPIO29_Handler
+ .thumb_set GPIO29_Handler,Default_Handler
+
+ .weak GPIO30_Handler
+ .thumb_set GPIO30_Handler,Default_Handler
+
+ .weak GPIO31_Handler
+ .thumb_set GPIO31_Handler,Default_Handler
+
+.end
diff --git a/src/mcu/rtl876x/overlay_mgr.c b/src/mcu/rtl876x/overlay_mgr.c
new file mode 100644
index 0000000..f0b131f
--- /dev/null
+++ b/src/mcu/rtl876x/overlay_mgr.c
@@ -0,0 +1,163 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file overlay_mgr.c
+ * @brief overlay manager
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2016 Realtek Semiconductor Corporation</center></h2>
+ * *************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include "overlay_mgr.h"
+
+
+/* linker generates symbols for overlay a section */
+extern uint32_t Load$$OVERLAY_A$$RO$$Base;
+extern uint32_t Load$$OVERLAY_A$$RW$$Base;
+
+extern uint32_t Image$$OVERLAY_A$$RO$$Base;
+extern uint32_t Image$$OVERLAY_A$$RW$$Base;
+extern uint32_t Image$$OVERLAY_A$$ZI$$Base;
+
+extern uint32_t Image$$OVERLAY_A$$RO$$Length;
+extern uint32_t Image$$OVERLAY_A$$RW$$Length;
+extern uint32_t Image$$OVERLAY_A$$ZI$$Length;
+
+/* linker generates symbols for overlay b section */
+extern uint32_t Load$$OVERLAY_B$$RO$$Base;
+extern uint32_t Load$$OVERLAY_B$$RW$$Base;
+
+extern uint32_t Image$$OVERLAY_B$$RO$$Base;
+extern uint32_t Image$$OVERLAY_B$$RW$$Base;
+extern uint32_t Image$$OVERLAY_B$$ZI$$Base;
+
+extern uint32_t Image$$OVERLAY_B$$RO$$Length;
+extern uint32_t Image$$OVERLAY_B$$RW$$Length;
+extern uint32_t Image$$OVERLAY_B$$ZI$$Length;
+
+/* linker generates symbols for overlay c section */
+extern uint32_t Load$$OVERLAY_C$$RO$$Base;
+extern uint32_t Load$$OVERLAY_C$$RW$$Base;
+
+extern uint32_t Image$$OVERLAY_C$$RO$$Base;
+extern uint32_t Image$$OVERLAY_C$$RW$$Base;
+extern uint32_t Image$$OVERLAY_C$$ZI$$Base;
+
+extern uint32_t Image$$OVERLAY_C$$RO$$Length;
+extern uint32_t Image$$OVERLAY_C$$RW$$Length;
+extern uint32_t Image$$OVERLAY_C$$ZI$$Length;
+
+char scenario_name[8];
+
+#if defined ( __CC_ARM )
+#pragma push
+#pragma diag_suppress 1296
+#endif
+static T_OVERLAY_SECTION overlay_sections[OVERLAY_SCENARIO_NUM] =
+{
+ {
+ "BootOnce",
+
+ &Load$$OVERLAY_A$$RO$$Base,
+ &Load$$OVERLAY_A$$RW$$Base,
+
+ &Image$$OVERLAY_A$$RO$$Base,
+ &Image$$OVERLAY_A$$RW$$Base,
+ &Image$$OVERLAY_A$$ZI$$Base,
+
+ /* warning 1296(extended constant initialiser used) */
+ (uint32_t) &Image$$OVERLAY_A$$RO$$Length,
+ (uint32_t) &Image$$OVERLAY_A$$RW$$Length,
+ (uint32_t) &Image$$OVERLAY_A$$ZI$$Length,
+ },
+ {
+ "Scene_B",
+
+ &Load$$OVERLAY_B$$RO$$Base,
+ &Load$$OVERLAY_B$$RW$$Base,
+
+ &Image$$OVERLAY_B$$RO$$Base,
+ &Image$$OVERLAY_B$$RW$$Base,
+ &Image$$OVERLAY_B$$ZI$$Base,
+
+ /* warning 1296(extended constant initialiser used) */
+ (uint32_t) &Image$$OVERLAY_B$$RO$$Length,
+ (uint32_t) &Image$$OVERLAY_B$$RW$$Length,
+ (uint32_t) &Image$$OVERLAY_B$$ZI$$Length,
+ },
+ {
+ "Scene_C",
+
+ &Load$$OVERLAY_C$$RO$$Base,
+ &Load$$OVERLAY_C$$RW$$Base,
+
+ &Image$$OVERLAY_C$$RO$$Base,
+ &Image$$OVERLAY_C$$RW$$Base,
+ &Image$$OVERLAY_C$$ZI$$Base,
+
+ /* warning 1296(extended constant initialiser used) */
+ (uint32_t) &Image$$OVERLAY_C$$RO$$Length,
+ (uint32_t) &Image$$OVERLAY_C$$RW$$Length,
+ (uint32_t) &Image$$OVERLAY_C$$ZI$$Length,
+ }
+};
+#if defined ( __CC_ARM )
+#pragma pop
+#endif
+
+/**
+ * @brief load overlay
+ * @param scenario_idx selected overlay section index
+ * @return none
+ */
+bool load_overlay(T_OVERLAY_SCENARIO_IDX scenario_idx)
+{
+ const T_OVERLAY_SECTION *selected_scenario;
+
+ if (scenario_idx >= OVERLAY_SCENARIO_NUM)
+ {
+ return false;
+ }
+
+ selected_scenario = &overlay_sections[scenario_idx];
+
+ if (memcmp(selected_scenario->signature, scenario_name, 8) == 0)
+ {
+ return true;
+ }
+
+ /* load code */
+ memcpy(selected_scenario->image_ro_base, selected_scenario->load_ro_base,
+ selected_scenario->ro_length);
+ /* load rw data */
+ memcpy(selected_scenario->image_rw_base, selected_scenario->load_rw_base,
+ selected_scenario->rw_length);
+ /* clear zi data */
+ memset(selected_scenario->image_zi_base, 0x0, selected_scenario->zi_length);
+
+ memcpy(scenario_name, selected_scenario->signature, 8);
+
+ return true;
+}
+
+T_OVERLAY_SCENARIO_IDX get_current_scenario_index(void)
+{
+ const T_OVERLAY_SECTION *selected_scenario;
+
+ for (int i = 0; i < (int)OVERLAY_SCENARIO_NUM; ++i)
+ {
+ selected_scenario = &overlay_sections[i];
+ if (memcmp(selected_scenario->signature, scenario_name, 8) == 0)
+ {
+ return (T_OVERLAY_SCENARIO_IDX)i;
+ }
+ }
+
+ return OVERLAY_SCENARIO_NUM; //not found valid scenario
+}
diff --git a/src/mcu/rtl876x/system_rtl876x.c b/src/mcu/rtl876x/system_rtl876x.c
new file mode 100644
index 0000000..b904bed
--- /dev/null
+++ b/src/mcu/rtl876x/system_rtl876x.c
@@ -0,0 +1,1466 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file system_rtl8762c.c
+ * @brief system init file
+ * @author lory xu
+ * @date 2017-11-9
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2016 Realtek Semiconductor Corporation</center></h2>
+ * *************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <locale.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include "version.h"
+#include "rtl876x.h"
+#include "patch_header_check.h"
+#include "app_section.h"
+#include "rom_uuid.h"
+#include "app_define.h"
+#include "core_cmFunc.h"
+#include "mem_config.h"
+#include "otp.h"
+#include "platform_autoconf.h"
+#include "rtl876x_wdg.h"
+#include "overlay_mgr.h"
+#include "flash_device.h"
+#include "os_sched.h"
+#include "os_sync.h"
+#include "otp_config.h"
+#include "test_mode.h"
+#include "platform_utils.h"
+#include "os_mem.h"
+#include "dfu_flash.h"
+#include "rtl876x_wdg.h"
+#include "rtl876x_lib_platform.h"
+#include "board.h"
+#include "dlps.h"
+#include "os_timer.h"
+#include "trace.h"
+#if (SUPPORT_NORMAL_OTA == 1)
+#include "dfu_main.h"
+#endif
+#if (SYSTEM_TRACE_ENABLE == 1)
+#include "system_trace.h"
+#include "trace_config.h"
+#endif
+
+/** @defgroup SYSTEM_INIT System Init
+ * @brief Start up code for user application.
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup SYSTEM_INIT_Exported_Macros System Init Exported Macros
+ * @brief
+ * @{
+ */
+void show_sdk_lib_version(void);
+void SystemInit(void);
+#define SHARE_CACHE_RAM_0K 0x82F70000
+#define SHARE_CACHE_RAM_4K 0x2F2D0002
+#define SHARE_CACHE_RAM_8K 0xA2AA0003
+
+#define SHUTDOWN_DATARAM_4KB (4 * 1024)
+#define SHUTDOWN_DATARAM_8KB (8 * 1024)
+#define SHUTDOWN_DATARAM_24KB (24 * 1024)
+#define SHUTDOWN_DATARAM_56KB (56 * 1024)
+
+#define VTOR_RAM_ADDR 0x00200000 //!< vector table address in RAM.
+#define APP_FAKE_PAYLOAD_LEN 0x100
+
+#define FreeRTOS_portBYTE_ALIGNMENT 8
+
+/** End of SYSTEM_INIT_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup SYSTEM_INIT_Exported_Types System Init Exported Types
+ * @{
+ */
+typedef struct
+{
+ uint8_t ic_type;
+ uint8_t rsvd0[3];
+ uint32_t ram_size;
+ uint32_t check_pattern;
+ T_VERSION_FORMAT git_ver;
+ uint8_t rsvd1[64];
+} T_UPPERSTACK_HEADER;
+
+typedef struct A_BLOCK_LINK
+{
+ struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
+ size_t xBlockSize : 28; /*<< The size of the free block. */
+ size_t xRamType : 3;
+ size_t xAllocateBit : 1;
+} BlockLink_t;
+/** End of SYSTEM_INIT_Exported_Types
+ * @}
+ */
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup SYSTEM_INIT_Exported_Variables System Init Exported Variables
+ * @{
+ */
+extern void GPIO0_Handler(void);
+extern void GPIO1_Handler(void);
+extern void GPIO2_Handler(void);
+extern void GPIO3_Handler(void);
+extern void GPIO4_Handler(void);
+extern void GPIO5_Handler(void);
+extern void GPIO6_Handler(void);
+extern void GPIO7_Handler(void);
+extern void GPIO8_Handler(void);
+extern void GPIO9_Handler(void);
+extern void GPIO10_Handler(void);
+extern void GPIO11_Handler(void);
+extern void GPIO12_Handler(void);
+extern void GPIO13_Handler(void);
+extern void GPIO14_Handler(void);
+extern void GPIO15_Handler(void);
+extern void GPIO16_Handler(void);
+extern void GPIO17_Handler(void);
+extern void GPIO18_Handler(void);
+extern void GPIO19_Handler(void);
+extern void GPIO20_Handler(void);
+extern void GPIO21_Handler(void);
+extern void GPIO22_Handler(void);
+extern void GPIO23_Handler(void);
+extern void GPIO24_Handler(void);
+extern void GPIO25_Handler(void);
+extern void GPIO26_Handler(void);
+extern void GPIO27_Handler(void);
+extern void GPIO28_Handler(void);
+extern void GPIO29_Handler(void);
+extern void GPIO30_Handler(void);
+extern void GPIO31_Handler(void);
+
+#if defined (__CC_ARM)
+extern char Image$$ENCRYPTION_RAM_CODE$$Base[];
+extern char Load$$ENCRYPTION_RAM_CODE$$Base[];
+extern char Load$$ENCRYPTION_RAM_CODE$$Length[];
+
+extern char Image$$FLASH_START_ADDR$$RO$$Base[];
+extern char Load$$FLASH_START_ADDR$$RO$$Base[];
+extern char Load$$FLASH_START_ADDR$$RO$$Length[];
+#elif defined ( __GNUC__ )
+extern uint32_t *__encryption_ram_code_exe_ad__;
+extern uint32_t *__encryption_ram_code_load_ad__;
+extern uint32_t *__encryption_ram_code_length__;
+#endif
+extern uint32_t upperstack_fake_data;
+
+BOOL_WDG_CB user_wdg_cb __attribute__((weak)) = NULL;
+USER_CALL_BACK app_pre_main_cb __attribute__((weak)) = NULL ;
+USER_CALL_BACK os_patch __attribute__((weak)) = NULL ;
+
+#if (LOG_UART_MULTIPLEXING == 1)
+
+#include "log_uart_dma.h"
+typedef enum
+{
+ LOG_UART = 0,
+ DATA_UART
+} UART_STATE;
+
+typedef struct
+{
+ UART_STATE last_flag;
+ UART_STATE current_flag;
+} T_UART_FLAG;
+
+PingpongBuffer MCU_Log_user;
+PingpongBuffer *pMCU_PPB_user = &MCU_Log_user;
+
+T_UART_FLAG uart_flag = {LOG_UART, LOG_UART};
+T_UART_FLAG *uart_flag_p = &uart_flag;
+
+PingpongBuffer *get_tx_buffer_app_cb(void);
+T_UART_FLAG *get_uart_flag_app_cb(void);
+void get_tx_rx_pin_app_cb(uint8_t *p_tx, uint8_t *p_rx);
+
+#endif
+
+#if (LOG_UART_MULTIPLEXING == 1)
+
+//increase APP_CB_NUMBERS when add new app cb
+#define APP_CB_NUMBERS 4
+
+typedef enum
+{
+ APP_CB_ID_WDG_RESET = 0,
+ APP_CB_ID_RX_BUFFER = 1,
+ APP_CB_ID_UART_FLAG = 2,
+ APP_CB_ID_TX_RX_PIN = 3,
+ //add more app cb id here
+} T_APP_CB_ID;
+
+#else
+
+//increase APP_CB_NUMBERS when add new app cb
+#define APP_CB_NUMBERS 1
+
+typedef enum
+{
+ APP_CB_ID_WDG_RESET = 0,
+ //add more app cb id here
+} T_APP_CB_ID;
+
+#endif
+
+typedef struct
+{
+ uint32_t app_cb_signature;
+ uint32_t app_cb_numbers;
+ uint32_t app_cb_addr[APP_CB_NUMBERS];
+} T_APP_CB_TABLE;
+
+const T_APP_CB_TABLE app_cb_table =
+{
+ .app_cb_signature = SIGNATURE_APP_CB,
+ .app_cb_numbers = APP_CB_NUMBERS,
+ .app_cb_addr[0] = (uint32_t)NULL,
+#if (LOG_UART_MULTIPLEXING == 1)
+ .app_cb_addr[1] = (uint32_t)get_tx_buffer_app_cb,
+ .app_cb_addr[2] = (uint32_t)get_uart_flag_app_cb,
+ .app_cb_addr[3] = (uint32_t)get_tx_rx_pin_app_cb,
+#endif
+ //add more cb here
+};
+
+
+#if FEATURE_ENCRYPTION
+#if defined ( __CC_ARM ) || defined ( __GNUC__ )
+#define ENC_ALIGN_SECTION __attribute__((aligned(16), used, section(".enc.dummy.align")));
+const uint8_t enc_dummy_align[16] ENC_ALIGN_SECTION;
+#else
+//#define ENC_ALIGN_SECTION @ ".enc.dummy.align"
+//#pragma data_alignment=16
+//__root const uint8_t enc_dummy_align[16] ENC_ALIGN_SECTION;
+#endif
+#endif
+
+
+#pragma push
+#pragma diag_suppress 1296 /* disable warning 1296(extened constant initialiser used)*/
+
+/**
+* @brief: application header.
+* @note: items in ENCRYPT_RAM_CODE macro is for encryption solution only
+*/
+
+const T_IMG_HEADER_FORMAT img_header APP_FLASH_HEADER =
+{
+ .ctrl_header =
+ {
+ .ic_type = DEFINED_IC_TYPE,
+ .secure_version = 0,
+#if FEATURE_ENCRYPTION
+ .ctrl_flag.flag_value.enc = 1,
+ .ctrl_flag.flag_value.xip = 0,
+ .ctrl_flag.flag_value.load_when_boot = 1,
+ .ctrl_flag.flag_value.enc_key_select = ENC_KEY_OCEK_WITH_OEMCONST,
+#else
+ .ctrl_flag.flag_value.xip = 1,
+ .ctrl_flag.flag_value.enc = 0,
+ .ctrl_flag.flag_value.load_when_boot = 0,
+ .ctrl_flag.flag_value.enc_key_select = NULL,
+#endif
+ .ctrl_flag.flag_value.enc_load = 0,
+ .ctrl_flag.flag_value.not_ready = 0,
+ .ctrl_flag.flag_value.not_obsolete = 1,
+ .ctrl_flag.flag_value.compressed_not_ready = 0,
+ .ctrl_flag.flag_value.compressed_not_obsolete = 1,
+#if (BOOT_INTEGRITY_CHECK_EN == 0)
+ .ctrl_flag.flag_value.integrity_check_en_in_boot = 0,
+#else
+ .ctrl_flag.flag_value.integrity_check_en_in_boot = 1,
+#endif
+ .image_id = AppPatch,
+ .payload_len = APP_FAKE_PAYLOAD_LEN, //Will modify by build tool later
+ },
+ .uuid = DEFINE_rom_uuid,
+
+#if FEATURE_ENCRYPTION
+#if defined ( __ICCARM__ )
+ .exe_base = (uint32_t)__section_begin(".app.encryption.text"),
+ .load_base = (uint32_t)__section_begin(".app.encryption.text_init"),
+ .load_len = (uint32_t)__section_size(".app.encryption.text"),
+#elif defined (__CC_ARM)
+ .load_base = (uint32_t)Load$$ENCRYPTION_RAM_CODE$$Base,
+ .exe_base = (uint32_t)Image$$ENCRYPTION_RAM_CODE$$Base,
+ .load_len = (uint32_t)Load$$ENCRYPTION_RAM_CODE$$Length,
+#else
+ .exe_base = (uint32_t) &__encryption_ram_code_exe_ad__, //(uint32_t)IMAGE_FLASH_START_ADDR,
+ .load_base = (uint32_t) &__encryption_ram_code_load_ad__,
+ .load_len = (uint32_t) &__encryption_ram_code_length__,
+#endif
+#else
+#if defined ( __ICCARM__ )
+ .load_base = 0,
+ .exe_base = (uint32_t)SystemInit,
+#elif defined (__CC_ARM)
+ .load_base = (uint32_t)Load$$FLASH_START_ADDR$$RO$$Base,
+ .exe_base = (uint32_t)Image$$FLASH_START_ADDR$$RO$$Base,
+#else
+ .load_base = 0,
+ .exe_base = (uint32_t) SystemInit,
+#endif
+ .load_len = 0, //0 indicates all XIP
+#endif
+#if (APP_BANK == 0)
+ .image_base = BANK0_APP_ADDR,
+#else
+ .image_base = BANK1_APP_ADDR,
+#endif
+
+ .git_ver =
+ {
+ .ver_info.sub_version._version_major = VERSION_MAJOR,
+ .ver_info.sub_version._version_minor = VERSION_MINOR,
+ .ver_info.sub_version._version_revision = VERSION_REVISION,
+ .ver_info.sub_version._version_reserve = VERSION_BUILDNUM % 32, //only 5 bit
+ ._version_commitid = VERSION_GCID,
+ ._customer_name = {CN_1, CN_2, CN_3, CN_4, CN_5, CN_6, CN_7, CN_8},
+ },
+
+ .app_cb_signature = SIGNATURE_APP_CB,
+ .app_cb_table_base_address = (uint32_t) &app_cb_table
+};
+#if defined ( __ICCARM__ ) || defined ( __CC_ARM )
+const T_AUTH_HEADER_FORMAT auth_header APP_FLASH_HEADER =
+{
+#if defined ( __ICCARM__ )
+ .header_mac = {0xFF},
+ .payload_mac = {0xFF},
+#else
+ .header_mac = {[0 ... 15] = 0xFF},
+ .payload_mac = {[0 ... 15] = 0xFF},
+#endif
+};
+#elif defined ( __GNUC__ )
+const T_AUTH_HEADER_FORMAT auth_header APP_FLASH_HEADER_AUTH =
+{
+ .header_mac = {[0 ... 15] = 0xFF},
+ .payload_mac = {[0 ... 15] = 0xFF},
+};
+#endif
+#if defined ( __CC_ARM )
+#pragma pop
+#endif
+extern void upperstack_loader(void);
+void AppUpdateVectorTable(void);
+void pre_main(void);
+void wdg_system_reset_app_cb(T_WDG_MODE wdg_mode, T_SW_RESET_REASON reset_reason);
+uint32_t random_seed_value;
+
+/** End of SYSTEM_INIT_Exported_Variables
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup SYSTEM_INIT_Exported_Functions System Init Exported Functions
+ * @{
+ */
+void random_seed_init(void)
+{
+ random_seed_value = platform_random(0xFFFFFFFF);
+}
+
+void common_main(void)
+{
+#if (SUPPORT_FTL_IN_APP == 1)
+ extern void ftl_patch_point_init(void);
+ ftl_patch_point_init();
+
+ extern uint32_t ftl_init(uint32_t u32PageStartAddr, uint8_t pagenum);
+ ftl_init(flash_get_bank_addr(FLASH_FTL),
+ flash_get_bank_size(FLASH_FTL) / OTP->PageSize);
+#else
+ extern uint32_t ftl_init(uint32_t u32PageStartAddr, uint8_t pagenum);
+ ftl_init(flash_get_bank_addr(FLASH_FTL),
+ flash_get_bank_size(FLASH_FTL) / OTP->PageSize);
+#endif
+
+ //add common system code here before enter user defined main function
+#if (SUPPORT_NORMAL_OTA == 1)
+ if (dfu_check_ota_mode_flag())
+ {
+ dfu_main();
+ dfu_set_ota_mode_flag(false);
+ goto START_SCHEDULER;
+ }
+#endif
+
+ OTP->run_in_app = 1;
+
+ random_seed_init();
+
+#if (RUN_APP_IN_HCIMODE_ENABLE == 0)
+ if (OTP->stack_en)
+ {
+ DBG_DIRECT("In SoC Mode");
+ }
+ else
+ {
+ DBG_DIRECT("WARNING: In HCI Mode, will not run APP Task");
+ WDG_Disable();
+ goto START_SCHEDULER;
+ }
+#endif
+
+#if (LOG_UART_MULTIPLEXING == 1)
+ PPB_Init(pMCU_PPB_user);
+#endif
+
+ //print sdk lib version
+ show_sdk_lib_version();
+
+#if (SYSTEM_TRACE_ENABLE == 1)
+ extern void system_trace_init(void);
+ system_trace_init();
+#endif
+
+#if defined ( __ICCARM__ )
+ extern void __iar_program_start(const int);
+ __iar_program_start(0);
+#elif defined (__CC_ARM)
+ extern int __main(void);
+ __main();
+#elif defined (__GNUC__)
+ extern int main(void);
+ main();
+#endif
+
+START_SCHEDULER:
+ os_sched_start();
+ return;
+}
+
+
+APP_FLASH_TEXT_SECTION
+void ram_init(void)
+{
+#if defined ( __CC_ARM )
+ //copy data on ro
+ extern char Image$$RAM_DATA_ON$$RO$$Base[];
+ extern char Load$$RAM_DATA_ON$$RO$$Base[];
+ extern unsigned int Image$$RAM_DATA_ON$$RO$$Length;
+
+ memcpy(Image$$RAM_DATA_ON$$RO$$Base,
+ Load$$RAM_DATA_ON$$RO$$Base,
+ (unsigned int)&Image$$RAM_DATA_ON$$RO$$Length);
+
+ //copy data on rw
+ extern char Image$$RAM_DATA_ON$$RW$$Base[];
+ extern char Load$$RAM_DATA_ON$$RW$$Base[];
+ extern unsigned int Image$$RAM_DATA_ON$$RW$$Length;
+
+ memcpy(Image$$RAM_DATA_ON$$RW$$Base,
+ Load$$RAM_DATA_ON$$RW$$Base,
+ (unsigned int)&Image$$RAM_DATA_ON$$RW$$Length);
+
+ //clear data on zi
+ extern char Image$$RAM_DATA_ON$$ZI$$Base[];
+ extern unsigned int Image$$RAM_DATA_ON$$ZI$$Length;
+
+ memset(Image$$RAM_DATA_ON$$ZI$$Base,
+ 0,
+ (unsigned int)&Image$$RAM_DATA_ON$$ZI$$Length);
+#elif defined ( __GNUC__ )
+ //copy data on ro
+ extern uint32_t *__ram_dataon_ro_start__;
+ extern uint32_t *__ram_ro_load_ad__;
+ extern uint32_t *__ram_dataon_ro_length__;
+
+ memcpy(&__ram_dataon_ro_start__,
+ &__ram_ro_load_ad__,
+ (unsigned int)&__ram_dataon_ro_length__);
+ //copy data on rw
+ extern uint32_t *__ram_dataon_rw_start__;
+ extern uint32_t *__ram_rw_load_ad__;
+ extern uint32_t *__ram_dataon_rw_length__;
+
+ memcpy(&__ram_dataon_rw_start__,
+ &__ram_rw_load_ad__,
+ (unsigned int)&__ram_dataon_rw_length__);
+
+ //clear data on zi
+ extern uint32_t *__ram_dataon_zi_start__;
+ extern uint32_t *__ram_dataon_zi_length__;
+
+ memset(&__ram_dataon_zi_start__,
+ 0,
+ (unsigned int)&__ram_dataon_zi_length__);
+#elif defined (__ICCARM__)
+ extern void __iar_data_init2(void);
+ __iar_data_init2();
+#endif
+
+}
+
+APP_FLASH_TEXT_SECTION
+void ram_cache_init(void)
+{
+#if defined ( __CC_ARM )
+ //copy cache ro
+ extern char Image$$CACHE_DATA_ON$$RO$$Base[];
+ extern char Load$$CACHE_DATA_ON$$RO$$Base[];
+ extern unsigned int Image$$CACHE_DATA_ON$$RO$$Length;
+
+ memcpy(Image$$CACHE_DATA_ON$$RO$$Base,
+ Load$$CACHE_DATA_ON$$RO$$Base,
+ (unsigned int)&Image$$CACHE_DATA_ON$$RO$$Length);
+
+ //copy share cache ram rw
+ extern char Image$$CACHE_DATA_ON$$RW$$Base[];
+ extern char Load$$CACHE_DATA_ON$$RW$$Base[];
+ extern unsigned int Image$$CACHE_DATA_ON$$RW$$Length;
+
+ memcpy(Image$$CACHE_DATA_ON$$RW$$Base,
+ Load$$CACHE_DATA_ON$$RW$$Base,
+ (unsigned int)&Image$$CACHE_DATA_ON$$RW$$Length);
+
+ //clear share cache ram zi
+ extern char Image$$CACHE_DATA_ON$$ZI$$Base[];
+ extern unsigned int Image$$CACHE_DATA_ON$$ZI$$Length;
+
+ memset(Image$$CACHE_DATA_ON$$ZI$$Base,
+ 0,
+ (unsigned int)&Image$$CACHE_DATA_ON$$ZI$$Length);
+#elif defined ( __GNUC__ )
+ //copy share cache ram rw
+ extern uint32_t *__cache_dataon_start__;
+ extern uint32_t *__cache_data_load_ad__;
+ extern uint32_t *__cache_dataon_length__;
+
+ memcpy(&__cache_dataon_start__,
+ &__cache_data_load_ad__,
+ (unsigned int)&__cache_dataon_length__);
+#endif
+}
+
+
+APP_FLASH_TEXT_SECTION
+APP_MAIN_FUNC get_image_entry_addr(uint16_t image_id)
+{
+
+ uint32_t active_ota_bank_addr = get_active_ota_bank_addr();
+ if (!check_header_valid(active_ota_bank_addr, OTA))
+ {
+ return NULL;
+ }
+
+ T_OTA_HEADER_FORMAT *ota_header = (T_OTA_HEADER_FORMAT *)active_ota_bank_addr;
+ uint32_t image_size =
+ HAL_READ32((uint32_t)&ota_header->secure_boot_size, (image_id - SecureBoot) * 8);
+
+ if (image_size == 0)
+ {
+ return NULL;
+ }
+
+ uint32_t header_addr = get_header_addr_by_img_id((T_IMG_ID)image_id);
+
+ if (!check_header_valid(header_addr, (T_IMG_ID)image_id))
+ {
+ return NULL;
+ }
+
+ T_IMG_HEADER_FORMAT *header = (T_IMG_HEADER_FORMAT *)header_addr;
+
+ if (header->ctrl_header.image_id != image_id || image_id >= IMAGE_MAX)
+ {
+ return NULL;
+ }
+
+ APP_MAIN_FUNC entry_func = (APP_MAIN_FUNC)(header->exe_base | 1);
+
+ return entry_func;
+}
+
+
+void set_os_clock(OS_TICK os_tick) APP_FLASH_TEXT_SECTION;
+void set_os_clock(OS_TICK os_tick)
+{
+ switch (os_tick)
+ {
+ case OS_TICK_10MS:
+ OTP->os_tick_rate_HZ = 100;
+ break;
+ case OS_TICK_5MS:
+ OTP->os_tick_rate_HZ = 200;
+ break;
+ case OS_TICK_2MS:
+ OTP->os_tick_rate_HZ = 500;
+ break;
+ case OS_TICK_1MS:
+ OTP->os_tick_rate_HZ = 1000;
+ break;
+ default:
+ break;
+ }
+}
+
+#if defined ( __ICCARM__ )
+#if FEATURE_ENCRYPTION
+void SystemInit(void) APP_ENCRYPTION_TEXT_SECTION;
+#else
+void SystemInit(void) APP_FLASH_TEXT_SECTION;
+#endif
+#else
+void SystemInit(void) APP_FLASH_TEXT_SECTION;
+#endif
+
+void SystemInit(void)
+{
+ //hci mode check and bypass app
+ if (check_hci_mode_flag() || (OTP->stack_en == 0))
+ {
+ return;
+ }
+
+ //init pre_main and main functions
+ app_pre_main = (APP_MAIN_FUNC)pre_main;
+ upperstack_entry = get_image_entry_addr(UpperStack);;
+ app_main = (APP_MAIN_FUNC)common_main;
+ app_cb_wdg_reset = (APP_CB_WDG_RESET_TYPE)wdg_system_reset_app_cb;
+
+ /******** update otp here**********/
+ //ram config
+ update_ram_layout(APP_GLOBAL_SIZE, HEAP_DATA_ON_SIZE, SHARE_CACHE_RAM_SIZE);
+
+#ifdef SHUTDOWN_DATARAM_SIZE
+ if (SHUTDOWN_DATARAM_SIZE == 0)
+ {
+ set_dataram_to_shutdown(NO_DATARAM_SHUTDOWN);
+ }
+ else if (SHUTDOWN_DATARAM_SIZE == SHUTDOWN_DATARAM_4KB)
+ {
+ set_dataram_to_shutdown(LAST_4K_DATARAM_SHUTDOWN);
+ }
+ else if (SHUTDOWN_DATARAM_SIZE == SHUTDOWN_DATARAM_8KB)
+ {
+ set_dataram_to_shutdown(LAST_8K_DATARAM_SHUTDOWN);
+ }
+ else if (SHUTDOWN_DATARAM_SIZE == SHUTDOWN_DATARAM_24KB)
+ {
+ set_dataram_to_shutdown(LAST_24K_DATARAM_SHUTDOWN);
+ }
+ else if (SHUTDOWN_DATARAM_SIZE == SHUTDOWN_DATARAM_56KB)
+ {
+ set_dataram_to_shutdown(LAST_56K_DATARAM_SHUTDOWN);
+ }
+ else
+ {
+ DBG_DIRECT("Error! SHUTDOWN_DATARAM_SIZE is not match the size that can be set!");
+ }
+#endif
+
+#ifdef SUPPORT_SINGLE_BANK_OTA_USER_DATA
+ OTP->bkp_data1_addr = USER_DATA_START_ADDR;
+ OTP->bkp_data1_size = USER_DATA_MAX_SIZE;
+#endif
+
+#if (WRITE_HARDFAULT_RECORD_TO_FLASH_ENABLE > 0) && (SYSTEM_TRACE_ENABLE == 1) && (TRACE_HARDFAULT == 1)
+ patch_hardfault_save_to_flash_init();
+#endif
+
+#if ((SYSTEM_TRACE_ENABLE == 1) && ((WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE > 0 && TRACE_WDG_TIMEOUT == 1) || (TRACE_TASK_HANG_USE_WDG_ISR == 1)))
+ patch_wdg_timeout_reason_save_to_flash_init();
+#endif
+
+
+ //sw timer config
+#ifdef TIMER_MAX_NUMBER
+ //define TIMER_MAX_NUMBER in otp_config.h
+ OTP->timerMaxNumber = TIMER_MAX_NUMBER;
+#endif
+
+ //timer task stack size config
+#ifdef TIMER_TASK_STACK_SIZE
+ //define TIMER_TASK_STACK_SIZE in otp_config.h
+ OTP->timer_task_stack_size = TIMER_TASK_STACK_SIZE;
+#endif
+
+ //flash config
+ /*config enable flash block proect depending on flash layout and flash id*/
+#if (FLASH_BLOCK_PROTECT_ENABLE == 1)
+ OTP->bp_enable = 1;
+#else
+ OTP->bp_enable = 0;
+#endif
+ OTP->delay_10us_after_toggle_cs = AFTER_TOGGLE_CS_DELAY;
+
+#if (CHK_IMG_INTEGRITY_USE_AUTO_MODE_ACCESS_FLASH == 1)
+ OTP->image_split_read = 0; //use flash auto mode to check image integrity
+#endif
+
+
+ //os config
+ /*config enable check task stack overflow*/
+#if (CHECK_STACK_OVERFLOW_ENABLE == 1)
+ OTP->checkForStackOverflow = 1;
+#else
+ OTP->checkForStackOverflow = 0;
+#endif
+
+
+ //platform config
+ /*config enable platform assert*/
+#if (PLATFORM_ASSERT_ENABLE == 1)
+ OTP->enableASSERT = 1;
+#else
+ OTP->enableASSERT = 0;
+#endif
+
+ /*Print all log in log buffer before entering DLPS */
+#if (CHECK_LOG_BUFFER_BEFORE_DLPS_ENABLE == 1)
+ OTP->printAllLogBeforeEnterDLPS = 1;
+#else
+ OTP->printAllLogBeforeEnterDLPS = 0;
+#endif
+
+ /*config enable log or not*/
+#if (CONFIG_LOG_FUNCTION_ENABLE == 1)
+ OTP->logDisable = 0;
+#else
+ OTP->logDisable = 1;
+#endif
+
+ /*config log baudrate*/
+#ifdef LOG_BAUD_RATE
+ OTP->logBaudRate = LOG_BAUD_RATE;
+#endif
+
+#if (FTL_REAL_LOGIC_ADDR_SIZE > 0)
+ if (FTL_REAL_LOGIC_ADDR_SIZE <= (((((FMC_PAGE_SIZE / 8) - 1) * ((OTP->ftl_size / FMC_PAGE_SIZE) -
+ 1)) - 1) << 2))
+ {
+ OTP->ftl_real_logic_addr_size = FTL_REAL_LOGIC_ADDR_SIZE;
+ }
+ else
+ {
+ DBG_DIRECT("ERROR! FTL logic addr size is too large!");
+ }
+#endif
+
+#if (FTL_BT_STORAGE_SPACE_SIZE > 0)
+ if (FTL_BT_STORAGE_SPACE_SIZE * 1024 <= OTP->ftl_real_logic_addr_size)
+ {
+ OTP->ftl_app_logical_addr_base = FTL_BT_STORAGE_SPACE_SIZE;
+ }
+ else
+ {
+ DBG_DIRECT("ERROR! FTL BT storage space size is too large!");
+ }
+#endif
+
+ /*if app don't use CTC, can't switch power domain to avoid leakage*/
+#if ( USE_CTC_DLPS == 1)
+ OTP->ldo_311_aux_power_domain = PON_DOMAIN;
+#endif
+
+ /*to fix bug need disable dump callstack info before WDG_SystemReset, default enable */
+#if (DUMP_INFO_BEFORE_RESET_DISABLE == 1)
+ OTP->dump_info_before_reset = 0;
+#endif
+
+ /*Debug: config enable write hardfault record to flash*/
+#if (WRITE_HARDFAULT_RECORD_TO_FLASH_ENABLE > 0)
+ OTP->write_info_to_flash_when_hardfault = WRITE_HARDFAULT_RECORD_TO_FLASH_ENABLE;
+ OTP->HardFault_Record_BegAddr = HARDFAULT_RECORD_BEG_ADDR;
+ OTP->HardFault_Record_EndAddr = HARDFAULT_RECORD_END_ADDR;
+ OTP->HardFault_Record_CFG = HARDFAULT_RECORD_CFG;
+#endif
+
+ /*before wdg system reset, write reset reason to specific flash addr*/
+#if (WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE > 0)
+ OTP->write_info_to_flash_before_reset = WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE;
+ OTP->reboot_record_address = REBOOT_REASON_RECORD_ADDRESS;
+ OTP->reboot_record_item_limit_power_2 = REBOOT_REASON_RECORD_LIMIT_POWERT2;
+#endif
+
+ /*config enable swd pinmux*/
+#if (SWD_PINMUX_ENABLE == 1)
+ OTP->SWD_ENABLE = 1;
+#else
+ OTP->SWD_ENABLE = 0;
+#endif
+
+ /*config enable watch dog in rom*/
+#if (ROM_WATCH_DOG_ENABLE == 1)
+ OTP->wdgEnableInRom = 1;
+#else
+ OTP->wdgEnableInRom = 0;
+#endif
+
+ /*config watch dog mode in rom, default 4s timeout and reset all*/
+#if (ROM_WATCH_DOG_ENABLE == 1)
+ OTP->wdgConfigDivfactor = ROM_WATCH_DOG_CFG_DIV_FACTOR;
+ OTP->wdgConfigCntLimit = ROM_WATCH_DOG_CFG_CNT_LIMIT;
+#if (TRACE_TASK_HANG_USE_WDG_ISR == 1)
+ OTP->wdgMode = INTERRUPT_CPU;
+#else
+ OTP->wdgMode = ROM_WATCH_DOG_MODE;
+#endif
+#endif
+
+ /*config enable write hardfault record to flash*/
+#if (ENABLE_WRITE_HARDFAULT_RECORD_TO_FLASH > 0)
+ OTP->write_info_to_flash_when_hardfault = ENABLE_WRITE_HARDFAULT_RECORD_TO_FLASH;
+ OTP->HardFault_Record_BegAddr = HARDFAULT_RECORD_BEG_ADDR;
+ OTP->HardFault_Record_EndAddr = HARDFAULT_RECORD_END_ADDR;
+ OTP->HardFault_Record_CFG = HARDFAULT_RECORD_CFG;
+#endif
+
+#if (ENABLE_FLASH_READ_TURN_OFF_RF > 0)
+ OTP->read_turn_on_off_rf = ENABLE_FLASH_READ_TURN_OFF_RF;
+#endif
+
+
+ //app config
+ OTP->ota_timeout_total = OTA_TIMEOUT_TOTAL;
+ OTP->ota_timeout_wait4_conn = OTA_TIMEOUT_WAIT4_CONN;
+ OTP->ota_timeout_wait4_image_transfer = OTA_TIMEOUT_WAIT4_IMAGE_TRANS;
+ OTP->ota_timeout_ctittv = OTA_TIMEOUT_CTITTV;
+
+#if ROM_OTA_LINKLOSS_RST
+ OTP->ota_link_loss_reset = 1;
+#endif
+
+#ifdef OS_TICK_TIME
+ set_os_clock(OS_TICK_TIME);
+#endif
+
+ /*config bt stack parameters in rom*/
+#ifdef BT_STACK_CONFIG_ENABLE
+ bt_stack_config_init();
+#endif
+
+//add more otp config here
+
+ ram_init();
+
+ if (os_patch)
+ {
+ os_patch();
+ }
+}
+
+void print_reset_reason(void) APP_FLASH_TEXT_SECTION;
+void print_reset_reason(void)
+{
+ uint32_t wdg_reset_pc = (btaon_fast_read_safe(0x1c2) << 17) | (btaon_fast_read_safe(0x1c0) << 1);
+ uint32_t wdg_reset_lr = (btaon_fast_read_safe(0x1c6) << 16) | (btaon_fast_read_safe(0x1c4));
+ uint32_t wdg_reset_psr = (btaon_fast_read_safe(0x1ca) << 16) | (btaon_fast_read_safe(0x1c8));
+
+ uint32_t aon_wdg_reset_pc = (btaon_fast_read_safe(0x1ce) << 17) | (btaon_fast_read_safe(
+ 0x1cc) << 1);
+ uint32_t aon_wdg_reset_lr = (btaon_fast_read_safe(0x1d2) << 16) | (btaon_fast_read_safe(0x1d0));
+ uint32_t aon_wdg_reset_psr = (btaon_fast_read_safe(0x1d6) << 16) | (btaon_fast_read_safe(0x1d4));
+
+ if (wdg_reset_lr == 0)
+ {
+ BOOT_PRINT_INFO0("[Debug Info]RESET Reason: HW");
+
+ uint32_t wdg_reg_backup = WDG->WDG_CTL;
+
+#if (TRACE_TASK_HANG_USE_WDG_ISR == 1)
+ T_WDG_MODE reset_mode = (T_WDG_MODE)((wdg_reg_backup >> 29) & 0x3);
+ if (INTERRUPT_CPU == reset_mode)
+ {
+ NVIC_DisableIRQ(WDG_IRQn);
+ }
+#endif
+
+ //trigger wdg reset interrupt to update wdg_reset_lr (register is Read-Only, can't write directly)
+ WDG_ClockEnable();
+ WDG_Config(1, 0, INTERRUPT_CPU);
+ WDG_Enable();
+ platform_delay_ms(1); //add delay to make lr as a stable value (0x7bb5 for RTL8762E A-cut)
+
+ WDG_Disable();
+ platform_delay_us(150); //wait for WDG is disabled
+
+#if (TRACE_TASK_HANG_USE_WDG_ISR == 1)
+ if (INTERRUPT_CPU == reset_mode)
+ {
+ NVIC_ClearPendingIRQ(WDG_IRQn);
+ NVIC_EnableIRQ(WDG_IRQn);
+ }
+#endif
+ WDG->WDG_CTL = wdg_reg_backup;
+ }
+ else
+ {
+ T_SW_RESET_REASON sw_reset_type = reset_reason_get();
+
+ //fix reset reason error when watchdog timeout and ROM_WATCH_DOG_MODE is RESET_ALL
+ if (sw_reset_type == RESET_REASON_HW)
+ {
+ sw_reset_type = RESET_REASON_WDG_TIMEOUT;
+ }
+
+ BOOT_PRINT_INFO1("[Debug Info]RESET Reason: SW, TYPE 0x%x", sw_reset_type);
+ BOOT_PRINT_INFO3("[Debug Info]WDG: pc %x, lr %x, psr %x", wdg_reset_pc, wdg_reset_lr,
+ wdg_reset_psr);
+ BOOT_PRINT_INFO3("[Debug Info]AON WDG: pc %x, lr %x, psr %x", aon_wdg_reset_pc, aon_wdg_reset_lr,
+ aon_wdg_reset_psr);
+ }
+}
+
+APP_FLASH_TEXT_SECTION
+void pre_main(void)
+{
+ __disable_irq();
+
+ print_reset_reason();
+
+ ram_cache_init();
+#if defined ( __CC_ARM )
+ load_overlay(OVERLAY_SCENARIO_BOOT_ONCE);
+#endif
+ setlocale(LC_ALL, "C");
+
+
+ BOOT_PRINT_ERROR2("SDK Ver: %s, Build Time: %s",
+ TRACE_STRING(VERSION_BUILD_STR),
+ TRACE_STRING(BUILDING_TIME));
+
+ AppUpdateVectorTable();
+
+
+
+ if (app_pre_main_cb)
+ {
+ app_pre_main_cb();
+ }
+
+ return;
+}
+
+APP_FLASH_TEXT_SECTION
+void wdg_system_reset_app_cb(T_WDG_MODE wdg_mode, T_SW_RESET_REASON reset_reason)
+{
+ //do something necessary before watch dog reset
+ if (user_wdg_cb)
+ {
+ if (user_wdg_cb(wdg_mode, reset_reason))
+ {
+ return;
+ }
+ }
+
+}
+
+__attribute__((weak)) void show_sdk_lib_version(void)
+{
+}
+
+/**
+ * @brief update vector table in app
+ * @param none
+ * @return none
+ */
+OVERLAY_SECTION_BOOT_ONCE
+void AppUpdateVectorTable(void)
+{
+#if defined ( __CC_ARM )
+ extern uint32_t Load$$RAM_VECTOR_TABLE$$RO$$Base;
+ extern uint32_t Image$$RAM_VECTOR_TABLE$$RO$$Length;
+#elif defined ( __GNUC__ )
+ extern uint32_t *__ram_vector_load_ad__;
+ extern uint32_t *__ram_vector_table_length__;
+#endif
+ extern void Default_Handler(void);
+ extern void ROM_Default_Handler(void);
+
+ const char *SysException[] =
+ {
+ "InitialSP", "Reset", "NMI", "HardFault", "MemManage", "BusFault", "UsageFault", "Rsvd",
+ "Rsvd", "Rsvd", "Rsvd", "SVC", "DebugMon", "Rsvd", "PendSV", "SysTick"
+ };
+ const char *ExtIrq[] =
+ {
+ "System", "WDG", "BTMAC", "TIM3", "TIM2", "Platform", "I2S0_TX", "I2S0_RX", "Timer4-5",
+ "GPIO4", "GPIO5", "UART1", "UART0", "RTC", "SPI0", "SPI1", "I2C0", "I2C1", "ADC",
+ "Peripheral", "GDMA0 Channel0", "GDMA0 Channel1", "GDMA0 Channel2", "GDMA0 Channel3",
+ "Enhanced_Timer0", "Enhanced_Timer1", "GPIO_Group3", "GPIO_Group2", "IR", "GPIO_Group1",
+ "GPIO_Group0", "Rsvd", "TIM4", "TIM5", "SPI_Flash", "Qdecode",
+ "Keyscan", "SPI2W", "LPCOMP", "PTA_Mailbox", "CAP_Touch", "TRNG"
+ };
+
+ IRQ_Fun *pRamVector = (IRQ_Fun *)VTOR_RAM_ADDR;
+#if defined ( __ICCARM__ )
+#pragma section = ".intvec"
+ IRQ_Fun *pAppVector = (IRQ_Fun *)__section_begin(".intvec");
+ uint32_t AppVectorSize = (uint32_t)__section_size(".intvec");
+ DBG_DIRECT("pAppVector = 0x%x, AppVectorSize = %d", pAppVector, AppVectorSize);
+#elif defined (__CC_ARM)
+ IRQ_Fun *pAppVector = (IRQ_Fun *)&Load$$RAM_VECTOR_TABLE$$RO$$Base;
+ uint32_t AppVectorSize = (uint32_t)&Image$$RAM_VECTOR_TABLE$$RO$$Length;
+#elif defined (__GNUC__)
+ IRQ_Fun *pAppVector = (IRQ_Fun *)(&__ram_vector_load_ad__);
+ uint32_t AppVectorSize = (uint32_t)&__ram_vector_table_length__;
+#endif
+ uint32_t i = 0;
+
+ if (SCB->VTOR != VTOR_RAM_ADDR)
+ {
+ RamVectorTableInit(VTOR_RAM_ADDR);
+ }
+
+ /* Update APP defined handlers */
+ for (i = 0; i < AppVectorSize / 4; ++i)
+ {
+ if (i == 0 || i == 1) //skip __initial_sp and reset_handler remap
+ {
+ continue;
+ }
+
+ if (((pAppVector[i] != Default_Handler) && (pAppVector[i] != 0)) ||
+ ((pAppVector[i] == Default_Handler) && (pRamVector[i] == (IRQ_Fun)ROM_Default_Handler)))
+ {
+ if (i < System_VECTORn)
+ {
+ OS_PRINT_WARN1("Warning! %s is updated by APP!", TRACE_STRING(SysException[i]));
+ }
+ else
+ {
+ OS_PRINT_WARN1("Warning! ISR %s is updated by APP!",
+ TRACE_STRING(ExtIrq[i - System_VECTORn]));
+ }
+
+ pRamVector[i] = pAppVector[i];
+ }
+ }
+
+ __DMB();
+ __DSB();
+}
+/**
+ * @brief GPIO Group3 Handler
+ * @param none
+ * @return none
+ */
+DATA_RAM_FUNCTION
+void GPIO_Group3_Handler(void)
+{
+ uint32_t GPIOIrqStatus = GPIO->INTSTATUS;
+
+ //Check exact IRQ function
+ if (GPIOIrqStatus & BIT3)
+ {
+ GPIO3_Handler();
+ }
+ if (GPIOIrqStatus & BIT7)
+ {
+ GPIO7_Handler();
+ }
+ if (GPIOIrqStatus & BIT11)
+ {
+ GPIO11_Handler();
+ }
+ if (GPIOIrqStatus & BIT15)
+ {
+ GPIO15_Handler();
+ }
+ if (GPIOIrqStatus & BIT19)
+ {
+ GPIO19_Handler();
+ }
+ if (GPIOIrqStatus & BIT23)
+ {
+ GPIO23_Handler();
+ }
+ if (GPIOIrqStatus & BIT27)
+ {
+ GPIO27_Handler();
+ }
+ if (GPIOIrqStatus & BIT31)
+ {
+ GPIO31_Handler();
+ }
+}
+/**
+ * @brief GPIO Group2 Handler
+ * @param none
+ * @return none
+ */
+DATA_RAM_FUNCTION
+void GPIO_Group2_Handler(void)
+{
+ uint32_t GPIOIrqStatus = GPIO->INTSTATUS;
+
+ //Check exact IRQ function
+ if (GPIOIrqStatus & BIT2)
+ {
+ GPIO2_Handler();
+ }
+ if (GPIOIrqStatus & BIT6)
+ {
+ GPIO6_Handler();
+ }
+ if (GPIOIrqStatus & BIT10)
+ {
+ GPIO10_Handler();
+ }
+ if (GPIOIrqStatus & BIT14)
+ {
+ GPIO14_Handler();
+ }
+ if (GPIOIrqStatus & BIT18)
+ {
+ GPIO18_Handler();
+ }
+ if (GPIOIrqStatus & BIT22)
+ {
+ GPIO22_Handler();
+ }
+ if (GPIOIrqStatus & BIT26)
+ {
+ GPIO26_Handler();
+ }
+ if (GPIOIrqStatus & BIT30)
+ {
+ GPIO30_Handler();
+ }
+}
+/**
+ * @brief GPIO Group1 Handler
+ * @param none
+ * @return none
+ */
+DATA_RAM_FUNCTION
+void GPIO_Group1_Handler(void)
+{
+ uint32_t GPIOIrqStatus = GPIO->INTSTATUS;
+
+ //Check exact IRQ function
+ if (GPIOIrqStatus & BIT1)
+ {
+ GPIO1_Handler();
+ }
+ if (GPIOIrqStatus & BIT9)
+ {
+ GPIO9_Handler();
+ }
+ if (GPIOIrqStatus & BIT13)
+ {
+ GPIO13_Handler();
+ }
+ if (GPIOIrqStatus & BIT17)
+ {
+ GPIO17_Handler();
+ }
+ if (GPIOIrqStatus & BIT21)
+ {
+ GPIO21_Handler();
+ }
+ if (GPIOIrqStatus & BIT25)
+ {
+ GPIO25_Handler();
+ }
+ if (GPIOIrqStatus & BIT29)
+ {
+ GPIO29_Handler();
+ }
+}
+/**
+ * @brief GPIO Group0 Handler
+ * @param none
+ * @return none
+ */
+DATA_RAM_FUNCTION
+void GPIO_Group0_Handler(void)
+{
+ uint32_t GPIOIrqStatus = GPIO->INTSTATUS;
+
+ //Check exact IRQ function
+ if (GPIOIrqStatus & BIT0)
+ {
+ GPIO0_Handler();
+ }
+ if (GPIOIrqStatus & BIT8)
+ {
+ GPIO8_Handler();
+ }
+ if (GPIOIrqStatus & BIT12)
+ {
+ GPIO12_Handler();
+ }
+ if (GPIOIrqStatus & BIT16)
+ {
+ GPIO16_Handler();
+ }
+ if (GPIOIrqStatus & BIT20)
+ {
+ GPIO20_Handler();
+ }
+ if (GPIOIrqStatus & BIT24)
+ {
+ GPIO24_Handler();
+ }
+ if (GPIOIrqStatus & BIT28)
+ {
+ GPIO28_Handler();
+ }
+}
+
+void *malloc(size_t size)
+{
+ return os_mem_alloc(RAM_TYPE_DATA_ON, size);
+}
+
+void *calloc(size_t n, size_t size)
+{
+ return os_mem_zalloc(RAM_TYPE_DATA_ON, n * size);
+}
+
+/*only for FreeRTOS*/
+void *realloc(void *ptr, size_t size)
+{
+ void *new_ptr;
+ BlockLink_t *pxLink;
+ size_t old_size, new_size = 0;
+
+ if (ptr == NULL)
+ {
+ return os_mem_alloc(RAM_TYPE_DATA_ON, size);
+ }
+
+ if (size == 0)
+ {
+ os_mem_free(ptr);
+ ptr = NULL;
+ return NULL;
+ }
+
+ pxLink = (BlockLink_t *)((uint8_t *)ptr - sizeof(BlockLink_t));
+ old_size = pxLink->xBlockSize;
+
+ if ((old_size - sizeof(BlockLink_t)) ==
+ (size + (FreeRTOS_portBYTE_ALIGNMENT - (size & (FreeRTOS_portBYTE_ALIGNMENT - 1)))))
+ {
+ return ptr;
+ }
+
+ os_sched_suspend();
+ os_mem_free(ptr);
+ new_ptr = os_mem_alloc(RAM_TYPE_DATA_ON, size);
+ if (ptr != new_ptr)
+ {
+ pxLink = (BlockLink_t *)((uint8_t *)new_ptr - sizeof(BlockLink_t));
+ new_size = pxLink->xBlockSize;
+ memcpy(new_ptr, ptr, (old_size < new_size) ? (old_size - sizeof(BlockLink_t)) : (new_size - sizeof(
+ BlockLink_t)));
+ }
+ os_sched_resume();
+
+ return new_ptr;
+}
+
+void free(void *ptr)
+{
+ os_mem_free(ptr);
+}
+
+#if (ENABLE_FULL_FEATURED_DIRECT_LOG == 1)
+/*for full featured direct log print*/
+#define LOG_MESSAGE_SYNC_CODE 0x7E
+#define MAX_LOG_MESSAGE_LEN 128
+#define GET_TYPE(info) (uint8_t)((info) >> 24)
+#define GET_SUBTYPE(info) (uint8_t)((info) >> 16)
+
+extern uint8_t log_seq_num;
+extern uint32_t log_timestamp_get(void);
+extern void LogUartTxChar(const uint8_t ch);
+void log_direct_app(uint32_t info, const char *fmt, ...)
+{
+ char l_msg[MAX_LOG_MESSAGE_LEN];
+ uint16_t log_length;
+ int16_t fmt_length;
+ uint32_t timestamp;
+ va_list ap;
+ uint16_t i;
+ uint32_t s;
+
+ /**
+ * Byte: Description
+ * 0: Sync(0x7E)
+ * 1: Length
+ * 2: SeqNum
+ * 3: CheckSum
+ * 4-5: Timestamp
+ * 6: Type
+ * 7: SubType: SUBTYPE_DIRECT
+ * 8: Format String
+ */
+
+ if (!is_log_init || OTP->logDisable == 1)
+ {
+ return;
+ }
+
+ timestamp = log_timestamp_get();
+
+ l_msg[0] = LOG_MESSAGE_SYNC_CODE;
+ l_msg[4] = (uint8_t)timestamp;
+ l_msg[5] = (uint8_t)(timestamp >> 8);
+ l_msg[6] = GET_TYPE(info);
+ l_msg[7] = GET_SUBTYPE(info);
+
+ log_length = 8;
+
+ va_start(ap, fmt);
+#if 1
+ fmt_length = vsnprintf(l_msg + 8, MAX_LOG_MESSAGE_LEN - 8, fmt, ap);
+#else //save ROM code space, 20200907 lory
+ fmt_length = VSnprintf(l_msg + 8, MAX_LOG_MESSAGE_LEN - 8, fmt, ((const int *)&fmt) + 1);
+#endif
+ if (fmt_length < 0) /* error occurred */
+ {
+ fmt_length = 0;
+ }
+ else if (log_length + fmt_length > MAX_LOG_MESSAGE_LEN) /* truncated */
+ {
+ log_length = MAX_LOG_MESSAGE_LEN;
+
+ }
+ else
+ {
+ log_length += fmt_length;
+ }
+ va_end(ap);
+
+ l_msg[1] = log_length;
+
+ s = os_lock();
+ l_msg[2] = log_seq_num++;
+ os_unlock(s);
+
+ l_msg[3] = l_msg[0] ^ l_msg[1] ^ l_msg[2];
+
+#ifdef FOR_SIMULATION
+ for (i = 8; i < log_length; ++ i)
+ {
+ *((volatile uint8_t *)(FAKE_UART_ADDRESS)) = l_msg[i];
+ }
+ *((volatile uint8_t *)(FAKE_UART_ADDRESS)) = '\n';
+#else
+ for (i = 0; i < log_length; ++i)
+ {
+ LogUartTxChar(l_msg[i]);
+ }
+#endif
+}
+#endif
+
+/**
+ * @brief get cpu clock
+ * @param none
+ * @return uint32, for example 40000000 is 40M, 20000000 is 20M.
+ */
+uint32_t get_cpu_clock(void)
+{
+ extern uint32_t SystemCpuClock;
+ return SystemCpuClock;
+}
+
+/**
+ * @brief get ic type
+ * @param none
+ * @return uint8_t, ic type:
+ * #define RTL8762ESF 0x1D
+ * #define RTL8762EGF 0x18
+ * #define RTL8762ERF 0x28
+ * #define RTL8762EJF 0x29
+ * #define RTL8762EMF 0x39
+ * #define RS625MF 0x49
+ * #define RTL8762EKF 0x5A
+ * #define RTL8762EKO 0x6C
+ */
+uint8_t get_ic_type(void)
+{
+ return *(uint8_t *)0x00202cef;
+}
+
+void *active_timer_handle;
+void set_active_timer_callback(void *timer_handle)
+{
+ lps_mode_resume();
+ os_timer_stop(&active_timer_handle);
+ os_timer_delete(&active_timer_handle);
+}
+void set_boot_active_time(uint32_t active_time_ms)
+{
+ lps_mode_pause();
+ bool retval = os_timer_create(&active_timer_handle, "SetActiveTimer", 0, \
+ active_time_ms, false, set_active_timer_callback);
+ if (retval)
+ {
+ os_timer_start(&active_timer_handle);
+ }
+}
+
+#if defined ( __CC_ARM )
+#elif defined ( __GNUC__ )
+extern void *__aeabi_memset(void *s, size_t n, int c);
+void *memset(void *s, int c, size_t n)
+{
+ return __aeabi_memset(s, n, c);
+}
+#endif
+
+#if (LOG_UART_MULTIPLEXING == 1)
+
+APP_FLASH_TEXT_SECTION
+PingpongBuffer *get_tx_buffer_app_cb(void)
+{
+ return pMCU_PPB_user;
+}
+
+APP_FLASH_TEXT_SECTION
+T_UART_FLAG *get_uart_flag_app_cb(void)
+{
+ return uart_flag_p;
+}
+
+APP_FLASH_TEXT_SECTION
+void get_tx_rx_pin_app_cb(uint8_t *p_tx, uint8_t *p_rx)
+{
+ *p_tx = UART_TX_PIN;
+ *p_rx = UART_RX_PIN;
+}
+
+void data_print_buffer(const uint8_t *source, uint16_t size)
+{
+ PPB_Write(pMCU_PPB_user, source, size);
+}
+
+#endif
+
+/** @} */ /* End of group SYSTEM_INIT_Exported_Functions */
+/** @} */ /* End of group SYSTEM_INIT */
+
diff --git a/src/platform/dfu_flash.c b/src/platform/dfu_flash.c
new file mode 100644
index 0000000..f33a423
--- /dev/null
+++ b/src/platform/dfu_flash.c
@@ -0,0 +1,1121 @@
+#include <string.h>
+#include "trace.h"
+#include "flash_device.h"
+#include "patch_header_check.h"
+#include "hw_aes.h"
+#include "rtl876x_hw_aes.h"
+#include "otp.h"
+#include "dfu_api.h"
+#include "rtl876x_wdg.h"
+#include "dfu_flash.h"
+#include "sha256.h"
+#include "crc16btx.h"
+#include "board.h"
+#include "otp_config.h"
+
+#ifdef SUPPORT_SINGLE_BANK_OTA_USER_DATA
+#if ((USER_DATA_START_ADDR & (FMC_BLK_SECTION_LEN - 1)) != 0)
+#error "User data start addr is not 64KB Aligned!!"
+#endif
+#endif
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define BTAON_FAST_REBOOT_SW_INFO0 0x2
+
+#define DECODE_OFFSET (sizeof(T_COMPRESS_IMG_HEADER_FORMAT))
+#define COMPRESS_HEADER_SHA256_OFFSET 36
+
+#define CRC_BUFFER_SIZE 128 //may modify to improve performance
+#define SHA256_BUFFER_SIZE 128
+
+#define SHA256_LENGTH 32
+
+#define DFU_UPDATE_LEN 256
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef union _BTAON_FAST_REBOOT_SW_INFO0_TYPE
+{
+ uint16_t d16;
+ struct
+ {
+ uint16_t rsvd0: 5;
+ uint16_t is_ota: 1; /* bit[5]: enter ota mode after reset */
+ uint16_t rsvd1: 10;
+ } flag;
+} BTAON_FAST_REBOOT_SW_INFO0_TYPE;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+static uint32_t img_total_len = 0;
+static uint32_t total_block_cnt = 0;
+static uint32_t block_cnt = 0;
+uint8_t g_flash_old_bp_lv = 0xff;
+/*============================================================================*
+ * Local Functions
+ *============================================================================*/
+#if (SUPPORT_PUBLIC_DECODE_OTA == 1)
+static bool dfu_check_compressed_image_crc(T_IMG_CTRL_HEADER_FORMAT *p_header)
+{
+ /*
+ Image layout is as below, and CRC will include part 2)
+ 1) Image Compress Header 96 bytes
+ 2) compressed app + header bytes - CRC
+ */
+
+ uint8_t buf[CRC_BUFFER_SIZE];
+ uint16_t calced_crc16;
+
+ uint32_t length = p_header->payload_len;
+ uint8_t *pdata = (uint8_t *) p_header + sizeof(T_COMPRESS_IMG_HEADER_FORMAT);
+ calced_crc16 = dfu_process_crc(BTXFCS_INIT, buf, CRC_BUFFER_SIZE, pdata, length);
+
+ return (p_header->crc16 == calced_crc16);
+}
+
+static bool dfu_check_compressed_image_sha256(T_IMG_CTRL_HEADER_FORMAT *p_header)
+{
+ /*
+ Image layout is as below, and CRC will include part 2)
+ 1) Image Compress Header 96 bytes
+ 2) compressed app + header bytes -sha256
+ */
+
+ SHA256_CTX ctx;
+ uint8_t buf[SHA256_BUFFER_SIZE];
+ uint8_t sha256sum[SHA256_LENGTH];
+ uint8_t sha256img[SHA256_LENGTH];
+
+ SHA256_Init(&ctx);
+
+ uint8_t *pdata = (uint8_t *)p_header + sizeof(T_COMPRESS_IMG_HEADER_FORMAT);
+ dfu_process_sha256(&ctx, buf, SHA256_BUFFER_SIZE, pdata, p_header->payload_len);
+
+ SHA256_Final(&ctx, sha256sum);
+
+ pdata = (uint8_t *)p_header + COMPRESS_HEADER_SHA256_OFFSET;
+ for (int i = 0; i < SHA256_LENGTH; i++)
+ {
+ sha256img[i] = *(pdata++);
+ }
+
+ return (memcmp(sha256img, sha256sum, SHA256_LENGTH) == 0);
+}
+
+/**
+ * @brief calculated checksum(CRC16 or SHA256 determined by image) over the image, and compared
+ * with given checksum value.
+ * @param p_header image header info of the given image.
+ * @return true if image integrity check pass via checksum compare, false otherwise.
+*/
+static bool check_compressed_image_chksum(T_IMG_CTRL_HEADER_FORMAT *p_header)
+{
+ bool ret;
+
+ if (p_header->crc16)
+ {
+ ret = dfu_check_compressed_image_crc(p_header);
+ }
+ else
+ {
+ ret = dfu_check_compressed_image_sha256(p_header);
+ }
+
+ return ret;
+}
+
+#endif
+/**
+ * @brief erase a sector of the flash.
+ * @param addr flash addr in sector to be erase.
+ * @return 0 if erase successfully, fail otherwise
+*/
+static bool flash_erase_sector(uint32_t addr)
+{
+ bool result = false;
+ result = flash_erase_locked(FLASH_ERASE_SECTOR, addr);
+ DFU_PRINT_INFO2("<==dfu flash erase sector: addr=%x, result=%d(1:success)", addr, result);
+ return result;
+}
+
+/**
+ * @brief erase a block of the flash.
+ * @param addr flash addr in sector to be erase.
+ * @return 0 if erase successfully, fail otherwise
+*/
+static bool flash_erase_block(uint32_t addr)
+{
+ bool result = false;
+ result = flash_erase_locked(FLASH_ERASE_BLOCK, addr);
+ DFU_PRINT_INFO2("<==dfu flash erase block: addr=%x, result=%d(1:success)", addr, result);
+ return result;
+}
+
+/**
+* @brief check flash area is blank
+* @param image_id image_id to identify FW.
+* @param offset offset of the image.
+* @param size size to check.
+* @return 0 if blank check successfully, error line number otherwise
+*/
+static uint32_t dfu_flash_check_blank(uint16_t image_id, uint32_t offset, uint16_t size)
+{
+ uint32_t i = 0;
+ uint32_t result = 0;
+ uint32_t start_addr = 0;
+
+ if (size & 0x3)
+ {
+ result = __LINE__;
+ goto L_Return;
+ }
+
+ if ((image_id != IMAGE_USER_DATA) &&
+ (image_id < OTA || image_id >= IMAGE_MAX))
+ {
+ result = __LINE__;
+ goto L_Return;
+ }
+
+ if (image_id == IMAGE_USER_DATA)
+ {
+ start_addr = flash_get_bank_addr(FLASH_BKP_DATA1) + offset;
+ }
+ else
+ {
+ start_addr = get_temp_ota_bank_addr_by_img_id((T_IMG_ID)image_id) + offset;
+ }
+
+ if (start_addr == 0)
+ {
+ result = __LINE__;
+ goto L_Return;
+ }
+
+ for (i = 0; i < size / 4; i++)
+ {
+ uint32_t r_data;
+ if (flash_auto_read_locked(start_addr, &r_data))
+ {
+ if (r_data != FMC_ERASE_PATTERN)
+ {
+ result = __LINE__;
+ goto L_Return;
+ }
+ start_addr += 4;
+ }
+ else
+ {
+ result = __LINE__;
+ goto L_Return;
+ }
+ }
+
+L_Return:
+ DFU_PRINT_INFO4("<==dfu_flash_check_blank: image_id=0x%x, size=%d, addr=%d, result=%d",
+ image_id, size, start_addr, result);
+ return result;
+}
+
+/**
+ * @brief set specified image valid bit..
+ * @param p_header specified image.
+ * @return true if ready bit sets to 0, false otherwise
+*/
+void dfu_set_compressed_ready(T_IMG_CTRL_HEADER_FORMAT *p_header)
+{
+ /* clear not_ready and compressed_not_ready bit */
+ uint32_t data;
+ /*support for 4bit mode silent ota*/
+ flash_auto_read_locked((uint32_t)p_header, &data);
+ data &= ~BIT26;
+ flash_auto_write_locked((uint32_t)p_header, data);
+}
+
+extern void dfu_set_ready(T_IMG_CTRL_HEADER_FORMAT *p_header);
+
+//void dfu_set_ready(T_IMG_CTRL_HEADER_FORMAT *p_header)
+//{
+// /* clear not_ready bit */
+// uint32_t data;
+// /*support for 4bit mode silent ota*/
+// flash_auto_read_locked((uint32_t)p_header, &data);
+// data &= ~BIT23;
+// flash_auto_write_locked((uint32_t)p_header, data);
+//}
+
+/**
+* @brief check ota image size whether exceed flash layout address.
+*/
+static bool check_dfu_update_image_length(uint16_t image_id, uint32_t offset, uint32_t length,
+ void *p_void, uint32_t *ret)
+{
+ uint32_t temp_bank_size = 0;
+ *ret = 0;
+
+ if (p_void == NULL)
+ {
+ *ret = DFU_UPDATE_ERROR_EMPTY_BUFFER;
+ return false;
+ }
+
+ if (IMAGE_USER_DATA == image_id)
+ {
+ temp_bank_size = flash_get_bank_size(FLASH_BKP_DATA1);
+ }
+ else
+ {
+ temp_bank_size = get_temp_ota_bank_size_by_img_id((T_IMG_ID)image_id);
+ }
+
+
+ if (offset == 0)
+ {
+ T_IMG_CTRL_HEADER_FORMAT *p_header = (T_IMG_CTRL_HEADER_FORMAT *) p_void;
+ uint32_t total_length = p_header->payload_len + IMG_HEADER_SIZE;
+
+ if (total_length > temp_bank_size)
+ {
+ DBG_DIRECT("New Image too large! total_length=%d, temp_bank_size=%d", total_length,
+ temp_bank_size);
+ *ret = DFU_UPDATE_ERROR_IMAGE_SIZE_TOO_LARGE;
+ return false;
+ }
+ }
+
+ if (offset + length > temp_bank_size)
+ {
+ DFU_PRINT_ERROR3("New Image single packet too large! offset=%d, length=%d, temp_bank_size=%d",
+ offset, length, temp_bank_size);
+ *ret = DFU_UPDATE_ERROR_PACKET_SIZE_TOO_LARGE;
+ return false;
+ }
+
+ //check pass
+ return true;
+}
+
+static uint32_t dfu_write(uint32_t start_addr, uint32_t length, uint8_t *p_void)
+{
+ uint32_t result = 0;
+ uint16_t loop_cnt = 0;
+ uint16_t remain_size = 0;
+ uint32_t counter = 0;
+ uint8_t s_val[DFU_UPDATE_LEN];
+
+ loop_cnt = length / DFU_UPDATE_LEN;
+ remain_size = length % DFU_UPDATE_LEN;
+ DFU_PRINT_INFO2("dfu_write: start_addr=0x%x, length=%d",
+ start_addr, length);
+
+#if 0 //auto mode access
+ for (int i = 0; i < length; i = i + 4)
+ {
+ uint32_t s_val = 0;
+ flash_auto_write_locked(start_addr + i, *(uint32_t *)p_void);
+ flash_auto_read_locked(start_addr + i | FLASH_OFFSET_TO_NO_CACHE, &s_val);
+ if (s_val != *(uint32_t *)p_void)
+ {
+ DFU_PRINT_ERROR3("<==dfu_update: ERROR! w_data=0x%x, r_data=0x%x, addr=0x%x",
+ *(uint32_t *)p_void, s_val, start_addr + i);
+ result = __LINE__; //write fail
+ goto L_Return;
+ }
+ else
+ {
+ p_void++;
+ }
+ }
+#endif
+
+ for (int i = 0; i < loop_cnt; i++)
+ {
+ if (flash_write_locked(start_addr + i * DFU_UPDATE_LEN, DFU_UPDATE_LEN,
+ p_void + i * DFU_UPDATE_LEN))
+ {
+
+ if (flash_split_read_locked(start_addr + i * DFU_UPDATE_LEN, DFU_UPDATE_LEN,
+ s_val, &counter))
+ {
+ if (0 != memcmp(s_val, p_void + i * DFU_UPDATE_LEN, DFU_UPDATE_LEN))
+ {
+ return DFU_UPDATE_ERROR_FLASH_READBACK_MISMATCH;
+ }
+ }
+ else
+ {
+ return DFU_UPDATE_ERROR_FLASH_READBACK_FAIL;
+ }
+ }
+ else
+ {
+ return DFU_UPDATE_ERROR_FLASH_WRITE_FAIL;
+ }
+ }
+
+ if (remain_size)
+ {
+ if (flash_write_locked(start_addr + loop_cnt * DFU_UPDATE_LEN, remain_size,
+ p_void + loop_cnt * DFU_UPDATE_LEN))
+ {
+ if (flash_split_read_locked(start_addr + loop_cnt * DFU_UPDATE_LEN,
+ remain_size, s_val, &counter))
+ {
+ //ensure p_void is ram addr
+ if (0 != memcmp(s_val, p_void + loop_cnt * DFU_UPDATE_LEN, remain_size))
+ {
+ return DFU_UPDATE_ERROR_FLASH_READBACK_MISMATCH;
+ }
+ }
+ else
+ {
+ return DFU_UPDATE_ERROR_FLASH_READBACK_FAIL;
+ }
+ }
+ else
+ {
+ return DFU_UPDATE_ERROR_FLASH_WRITE_FAIL;
+ }
+ }
+
+ return result;
+}
+
+/*============================================================================*
+ * External Functions
+ *============================================================================*/
+/**
+ * @brief check whether in OTA mode.
+*/
+//bool dfu_check_ota_mode_flag(void)
+//{
+// BTAON_FAST_REBOOT_SW_INFO0_TYPE nFastBoot =
+// (BTAON_FAST_REBOOT_SW_INFO0_TYPE)btaon_fast_read_safe(BTAON_FAST_REBOOT_SW_INFO0);
+// DFU_PRINT_INFO1("dfu_check_ota_mode_flag: ota(%d)", nFastBoot.flag.is_ota);
+
+// return nFastBoot.flag.is_ota ? true : false;
+//}
+
+/**
+ * @brief set aon reg value means whether in OTA mode or not.
+*/
+void dfu_set_ota_mode_flag(bool enable)
+{
+ BTAON_FAST_REBOOT_SW_INFO0_TYPE nFastBoot =
+ (BTAON_FAST_REBOOT_SW_INFO0_TYPE)btaon_fast_read_safe(BTAON_FAST_REBOOT_SW_INFO0);
+ if (enable)
+ {
+ nFastBoot.flag.is_ota = 1;
+ }
+ else
+ {
+ nFastBoot.flag.is_ota = 0;
+ }
+ btaon_fast_write_safe(BTAON_FAST_REBOOT_SW_INFO0, nFastBoot.d16);
+ DFU_PRINT_INFO1("dfu_set_ota_mode_flag ota(%d)", nFastBoot.flag.is_ota);
+}
+
+/**
+ * @brief switch to the OTA mode, if support normal ota app need call it.
+*/
+void dfu_switch_to_ota_mode(void)
+{
+ DFU_PRINT_INFO0("[==>dfu_switch_to_ota_mode");
+ dfu_set_ota_mode_flag(true);
+ WDG_SystemReset(RESET_ALL_EXCEPT_AON, DFU_SWITCH_TO_OTA_MODE);
+}
+
+/**
+ * @brief OTA procedure do wdg system reset.
+ * @param is_active_fw true means dfu success! otherwise fail.
+*/
+void dfu_fw_reboot(bool is_active_fw)
+{
+ DFU_PRINT_TRACE1("==>dfu_fw_reboot: is_active_fw=%d", is_active_fw);
+ if (is_active_fw)
+ {
+ WDG_SystemReset(RESET_ALL, DFU_ACTIVE_RESET);
+ }
+ else
+ {
+ WDG_SystemReset(RESET_ALL, DFU_FAIL_RESET);
+ }
+}
+
+/**
+ * @brief OTA image default ecb mode aes decrypt, last less than 16bytes no encrypted.
+*/
+void dfu_hw_aes_decrypt_image(uint8_t *input, uint8_t *output, uint32_t length)
+{
+ uint32_t offset = 0;
+ hw_aes_init(OTP->aes_key, NULL, AES_MODE_ECB, OTP->ota_with_encryption_use_aes256);
+ do
+ {
+ if ((length - offset) >= 16)
+ {
+ hw_aes_decrypt_16byte(input + offset, output + offset);
+ offset += 16;
+ }
+ else
+ {
+ break;
+ }
+ }
+ while (1);
+}
+
+/**
+ * @brief report specified target ic type.
+ * @param image_id image_id to identify FW.
+ * @param p_ic_type To store ic type.
+ * @return 0 if report ic type info successfully, error line number otherwise
+*/
+uint32_t dfu_report_target_ic_type(uint16_t image_id, uint8_t *p_ic_type)
+{
+ uint32_t result = 0;
+ T_IMG_CTRL_HEADER_FORMAT *p_header;
+
+ if (!p_ic_type)
+ {
+ result = __LINE__;
+ goto L_Return;
+ }
+
+ if (IMAGE_USER_DATA == image_id)
+ {
+ p_header = (T_IMG_CTRL_HEADER_FORMAT *)flash_get_bank_addr(FLASH_BKP_DATA1);
+ }
+ else
+ {
+ p_header = (T_IMG_CTRL_HEADER_FORMAT *)get_header_addr_by_img_id((T_IMG_ID)image_id);
+ }
+
+ if (!p_header)
+ {
+ result = __LINE__;
+ goto L_Return;
+ }
+
+ *p_ic_type = p_header->ic_type;
+
+L_Return:
+ DFU_PRINT_INFO1("<==dfu_report_target_ic_type: result=%d", result);
+ return result;
+}
+
+/**
+ * @brief report specified FW info and current OTA offset.
+ * @param image_id image_id to identify FW.
+ * @param p_origin_fw_version To store current FW version.
+ * @param p_offset To store current file offset.
+ * @return 0 if report FW info successfully, error line number otherwise
+*/
+uint32_t dfu_report_target_fw_info(uint16_t image_id, uint32_t *p_origin_fw_version,
+ uint32_t *p_offset)
+{
+ uint32_t result = 0;
+ T_IMG_HEADER_FORMAT *p_header;
+
+ if (!p_offset)
+ {
+ result = __LINE__;
+ goto L_Return;
+ }
+
+ if (!p_origin_fw_version)
+ {
+ result = __LINE__;
+ goto L_Return;
+ }
+
+ if (IMAGE_USER_DATA == image_id)
+ {
+ p_header = (T_IMG_HEADER_FORMAT *)flash_get_bank_addr(FLASH_BKP_DATA1);
+ }
+ else
+ {
+ p_header = (T_IMG_HEADER_FORMAT *)get_header_addr_by_img_id((T_IMG_ID)image_id);
+ }
+ if (!p_header)
+ {
+ result = __LINE__;
+ goto L_Return;
+ }
+
+ if (image_id == OTA)
+ {
+ T_OTA_HEADER_FORMAT *p_ota_header;
+ p_ota_header = (T_OTA_HEADER_FORMAT *)p_header;
+ *p_origin_fw_version = p_ota_header->ver_val;
+ }
+ else if ((IMAGE_USER_DATA == image_id) ||
+ (image_id >= SecureBoot && image_id < IMAGE_MAX))
+ {
+ *p_origin_fw_version = p_header->git_ver.ver_info.version;
+ }
+ else//image_id don't support
+ {
+ result = __LINE__;
+ goto L_Return;
+ }
+
+ /*bee2 default don't support re-ota*/
+ *p_offset = 0;
+
+L_Return:
+ DFU_PRINT_INFO1("<==dfu_report_target_fw_info: result=%d", result);
+ return result;
+}
+
+
+
+/**
+* @brief calculate checksum of length of buffer in flash.
+* @param buf data.
+* @param length length of data, must align 2bytes.
+* @param crc_val ret crc value point.
+* @return 0 if buffer checksum calcs successfully, error line number otherwise
+*/
+
+uint32_t dfu_check_buf_crc(uint8_t *buf, uint32_t length, uint16_t crc_val)
+{
+ uint16_t checksum16 = 0;
+ uint32_t result = 0;
+ uint32_t i;
+ uint16_t *p16;
+
+ if (length & 0x1)
+ {
+ result = __LINE__;
+ goto L_Return;
+ }
+
+ p16 = (uint16_t *)buf;
+ for (i = 0; i < length / 2; ++i)
+ {
+ checksum16 = checksum16 ^ (*p16);
+ ++p16;
+ }
+
+ checksum16 = ((checksum16 & 0xff) << 8) | ((checksum16 & 0xff00) >> 8);
+
+ if (checksum16 != crc_val)
+ {
+ result = __LINE__;
+ goto L_Return;
+ }
+
+L_Return:
+ DFU_PRINT_INFO4("<==dfu_check_buf_crc: length=%d, checksum16=0x%x, crc_val=0x%x, result:%d",
+ length, checksum16, crc_val, result);
+ return result;
+}
+
+/**
+* @brief: unlock flash is need when erase or write flash.
+*/
+bool unlock_flash_bp_all(void)
+{
+ DFU_PRINT_TRACE0("**********Flash unlock BP***********");
+ if (flash_sw_protect_unlock_by_addr_locked(0x00800000, &g_flash_old_bp_lv))
+ {
+ DFU_PRINT_TRACE1("<==Unlock Total Flash Success! prev_bp_lv=%d", g_flash_old_bp_lv);
+ return true;
+ }
+ return false;
+}
+
+/**
+* @brief: lock flash after erase or write flash.
+*/
+void lock_flash_bp(void)
+{
+ if (g_flash_old_bp_lv != 0xff)
+ {
+ flash_set_block_protect_locked(g_flash_old_bp_lv);
+ }
+}
+
+/**
+ * @brief erase a sector of the flash, will retry three times at most
+ *
+ * @param image_id image_id to identify FW.
+ * @param offset offset of the image.
+ * @return 0 if erase successfully, error line number otherwise,
+*/
+uint32_t dfu_flash_erase_sector_with_retry(uint16_t image_id, uint32_t offset)
+{
+ uint32_t result = 0;
+ uint32_t cnt = 0;
+ uint32_t dfu_base_addr = 0;
+
+ if (image_id == IMAGE_USER_DATA)
+ {
+ dfu_base_addr = flash_get_bank_addr(FLASH_BKP_DATA1);;
+ }
+ else
+ {
+ dfu_base_addr = get_temp_ota_bank_addr_by_img_id((T_IMG_ID)image_id);
+ }
+ if (dfu_base_addr == 0)
+ {
+ result = __LINE__;
+ goto L_Return;
+ }
+
+ do
+ {
+ unlock_flash_bp_all();
+ flash_erase_sector(dfu_base_addr + offset);
+ lock_flash_bp();
+ result = dfu_flash_check_blank(image_id, offset, FMC_SEC_SECTION_LEN);
+
+ if (!result)
+ {
+ //erase ok
+ break;
+ }
+ else
+ {
+ //retry
+ cnt++;
+ }
+ if (cnt >= 3)
+ {
+ /*retry three times all fail*/
+ goto L_Return;
+ }
+ }
+ while (1);
+
+L_Return:
+ DFU_PRINT_INFO2("dfu_flash_erase_with_retry: cnt=%d, result=%d",
+ cnt, result);
+ return result;
+}
+
+
+/**
+ * @brief write specified image data with specified length to flash
+ * @param image_id image_id to identify FW.
+ * @param offset offset of the image.
+ * @param length length of data.
+ * @param p_void pointer to data.
+ * @return 0 if write FW image successfully, error line number otherwise
+*/
+uint32_t dfu_update(uint16_t image_id, uint32_t offset, uint32_t length,
+ uint32_t *p_void, bool is_new_image)
+{
+ uint32_t result = 0;
+ uint32_t dfu_base_addr = 0;
+ uint32_t start_addr = 0;
+ bool erase_rst = true; //default value must be true
+
+ DFU_PRINT_INFO2("==>dfu_update: offset=0x%x, length=%d", offset, length);
+
+ if (length % 4)
+ {
+ result = DFU_UPDATE_ERROR_LEN_NOT_ALIGN;
+ goto L_Return;
+ }
+
+ if (p_void == 0)
+ {
+ result = DFU_UPDATE_ERROR_EMPTY_BUFFER;
+ goto L_Return;
+ }
+
+ if (IMAGE_USER_DATA != image_id)
+ {
+ /*get back up area address*/
+ dfu_base_addr = get_temp_ota_bank_addr_by_img_id((T_IMG_ID)image_id);
+ }
+ else
+ {
+ /*get back up area address*/
+ dfu_base_addr = flash_get_bank_addr(FLASH_BKP_DATA1);
+ }
+
+ if (dfu_base_addr == 0)
+ {
+ result = DFU_UPDATE_ERROR_BASE_ADDR_INVALID;
+ goto L_Return;
+ }
+
+ /* before erase temp image or write image to flash temp, check access length depend flash layout */
+ if (!check_dfu_update_image_length(image_id, offset, length, p_void, &result))
+ {
+ goto L_Return;
+ }
+
+ /*if it's start_packet*/
+// if (offset == 0)
+ if (is_new_image)
+ {
+ T_IMG_CTRL_HEADER_FORMAT *p_header = (T_IMG_CTRL_HEADER_FORMAT *) p_void;
+ /*access ram addr, make sure image is not ready*/
+ p_header->ctrl_flag.flag_value.not_ready = 0x1;
+#if (SUPPORT_PUBLIC_DECODE_OTA == 1)
+ if (IMAGE_COMPRESSED == p_header->ctrl_flag.flag_value.image_type)
+ {
+ /*access ram addr, make sure image is not ready*/
+ p_header->ctrl_flag.flag_value.compressed_not_ready = 0x1;
+ }
+
+#endif
+ if (IMAGE_USER_DATA == image_id)
+ {
+ img_total_len = p_header->payload_len + IMG_HEADER_SIZE;
+
+ if (0 == (dfu_base_addr & (FMC_BLK_SECTION_LEN - 1))) //start addr 64k align
+ {
+ total_block_cnt = img_total_len / FMC_BLK_SECTION_LEN;
+ DFU_PRINT_TRACE2("<==dfu_update: img_total_len=0x%x, total_block_cnt=%d",
+ img_total_len, total_block_cnt);
+ }
+ else
+ {
+ /*improve user data ota performance with the limitation of start addr aligned 64K*/
+ DBG_DIRECT("Error User data start addr not aligned 64K!");
+
+ result = DFU_UPDATE_ERROR_FLASH_ERASE_LEN_NOT_ALIGN;
+ goto L_Return;
+ }
+
+ if (0 != (img_total_len & (FMC_BLK_SECTION_LEN - 1))) //img_total_len is not align 64KB
+ {
+ if (length > FMC_SEC_SECTION_LEN)
+ {
+ /*DFU_TEMP_BUFFER_SIZE can't larger than 4KB if user data size not aligned 64KB,
+ otherwise DFU_TEMP_BUFFER_SIZE can't larger than 64KB when user data size aligned 64KB*/
+ DBG_DIRECT("Error DFU_TEMP_BUFFER_SIZE > 4KB");
+
+ result = __LINE__;
+ goto L_Return;
+
+ }
+ }
+ }
+
+ DFU_PRINT_TRACE3("<==dfu_update: New Image Header=0x%x, image_id=0x%x, dfu_base_addr=0x%x",
+ length, image_id, dfu_base_addr);
+ }
+
+ start_addr = dfu_base_addr + offset;
+
+ unlock_flash_bp_all();
+ if (IMAGE_USER_DATA == image_id)
+ {
+ if (block_cnt < total_block_cnt)
+ {
+ if (0 == (offset & (FMC_BLK_SECTION_LEN - 1))) //new Block starts
+ {
+ erase_rst = flash_erase_block(start_addr);
+ block_cnt ++;
+ }
+ else // only cross two block
+ {
+ if (((offset % FMC_BLK_SECTION_LEN) + length > FMC_BLK_SECTION_LEN)
+ && (length <= FMC_BLK_SECTION_LEN))
+ {
+ erase_rst = flash_erase_block((start_addr + length) & ~(FMC_BLK_SECTION_LEN - 1));
+ block_cnt ++;
+ }
+ }
+ }
+ else
+ {
+ /*img_total_len is not align 64KB, need erase sector*/
+ if (0 != (img_total_len & (FMC_BLK_SECTION_LEN - 1)))
+ {
+ if (0 == (offset & (FMC_SEC_SECTION_LEN - 1))) //new sector starts
+ {
+ erase_rst = flash_erase_sector(start_addr);
+ }
+ else // only cross two sector
+ {
+ if (((offset % FMC_SEC_SECTION_LEN) + length > FMC_SEC_SECTION_LEN)
+ && (length <= FMC_SEC_SECTION_LEN))
+ {
+ erase_rst = flash_erase_sector((start_addr + length) & ~(FMC_SEC_SECTION_LEN - 1));
+ }
+ }
+ }
+ }
+ }
+ else //other images
+ {
+ if (0 == (offset & (FMC_SEC_SECTION_LEN - 1))) //new sector starts
+ {
+ erase_rst = flash_erase_sector(start_addr);
+ }
+ else // only cross two sector
+ {
+ /*write space cross two sector. Note: dfu_base_addr have been 4K align*/
+ /*if buffer size more than 4K, may cross more than two sectors*/
+ if (((offset % FMC_SEC_SECTION_LEN) + length > FMC_SEC_SECTION_LEN)
+ && (length <= FMC_SEC_SECTION_LEN))
+ {
+ erase_rst = flash_erase_sector((start_addr + length) & ~(FMC_SEC_SECTION_LEN - 1));
+ }
+ }
+ }
+ if (!erase_rst)
+ {
+ //erase fail
+ result = DFU_UPDATE_ERROR_FLASH_ERASE_FAIL;
+ goto L_Return;
+ }
+
+ //write data to flash
+ result = dfu_write(start_addr, length, (uint8_t *)p_void);
+ lock_flash_bp();
+
+L_Return:
+ DFU_PRINT_INFO1("<==dfu_update: result=%d", result);
+ return result;
+}
+
+
+/**
+ * @brief calculate checksum of the image and compare with given checksum value.
+ *
+ * @param image_id image id to identify image.
+ * @return true if the image integrity check passes, false otherwise
+*/
+bool dfu_check_checksum(uint16_t image_id, uint32_t offset)
+{
+ uint32_t error_code = DFU_CHECKSUM_SUCCESS;
+ bool check_result = false;
+ uint32_t base_addr = 0;
+ T_IMG_CTRL_HEADER_FORMAT *p_header;
+
+ if (image_id == IMAGE_USER_DATA)
+ {
+ /* because flash_get_bank_addr(FLASH_BKP_DATA1) is not located flash block protect range, needn't unlock bp */
+ base_addr = flash_get_bank_addr(FLASH_BKP_DATA1) | FLASH_OFFSET_TO_NO_CACHE;
+ }
+ else
+ {
+ /* check OTA temp or running bank to see if received image is OK.*/
+ base_addr = get_temp_ota_bank_addr_by_img_id((T_IMG_ID)image_id);
+ }
+ if (base_addr == 0)
+ {
+ error_code = DFU_CHECKSUM_ERROR_BASE_ADDR_INVALID;
+ goto L_Return;
+ }
+
+ if (!is_ota_support_bank_switch())
+ {
+ base_addr += offset;
+ }
+
+ p_header = (T_IMG_CTRL_HEADER_FORMAT *)base_addr;
+#if (SUPPORT_PUBLIC_DECODE_OTA == 1)
+ if (IMAGE_NORMAL == p_header->ctrl_flag.flag_value.image_type)
+ {
+ check_result = check_image_chksum(p_header);
+
+ }
+ else if (IMAGE_COMPRESSED == p_header->ctrl_flag.flag_value.image_type)
+ {
+ check_result = check_compressed_image_chksum(p_header);
+ }
+ else
+ {
+ error_code = DFU_CHECKSUM_ERROR_IMAGE_TYPE_INVALID;
+ goto L_Return;
+ }
+#else
+ check_result = check_image_chksum(p_header);
+#endif
+
+ if (!check_result)
+ {
+ error_code = DFU_CHECKSUM_ERROR_CHECK_FAIL;
+ goto L_Return;
+ }
+
+ /*when disable bank switch, set image ready later*/
+ if (is_ota_support_bank_switch())
+ {
+ dfu_set_image_ready(p_header);
+ }
+
+L_Return:
+ DFU_PRINT_INFO3("<==dfu_check_checksum: check_result:%d, ota_tmp_addr:0x%x, error_code:%d",
+ check_result, base_addr, error_code);
+ return check_result;
+}
+
+void dfu_set_image_ready(T_IMG_CTRL_HEADER_FORMAT *p_header)
+{
+ unlock_flash_bp_all();
+#if (SUPPORT_PUBLIC_DECODE_OTA == 1)
+ /*only set compressed_not_reay to 0, and not_ready still is 1
+ so that bootlader won't copy compressed image*/
+ if (IMAGE_COMPRESSED == p_header->ctrl_flag.flag_value.image_type)
+ {
+ dfu_set_compressed_ready(p_header);
+ }
+ else if (IMAGE_NORMAL == p_header->ctrl_flag.flag_value.image_type)
+ {
+ dfu_set_ready(p_header);
+ }
+ else
+ {
+ return;
+ }
+#else
+ dfu_set_ready(p_header);
+#endif
+ lock_flash_bp();
+}
+
+
+#if (ENABLE_BANK_SWITCH_COPY_APP_DATA == 1)
+extern uint8_t *p_ota_temp_buffer_head;
+/**
+ * @brief copy appdata from active bank to updating bank.
+ *
+ * @param image_id image_id to identify image.
+ * @param dlAddress address the img copy to.
+ * @param dlSize copy size.
+ * @return true if the image copied success, false otherwise
+*/
+bool dfu_copy_img(uint16_t image_id, uint32_t dlAddress, uint32_t dlSize)
+{
+ uint32_t error_code = 0;
+ uint32_t source_base_addr;
+ uint32_t dest_base_addr;
+ int remain_size = dlSize;
+ uint32_t s_val;
+ uint32_t dlOffset, tmp_offset;
+
+ if ((image_id < AppData1) || (image_id > AppData6))
+ {
+ error_code = __LINE__;
+ goto L_Return;
+ }
+ if (dlAddress % 4096)
+ {
+ error_code = __LINE__;
+ goto L_Return;
+ }
+
+ source_base_addr = get_active_ota_bank_addr() & 0xffffff;
+
+ if (flash_get_bank_addr(FLASH_OTA_BANK_0) == get_active_ota_bank_addr())
+ {
+ dest_base_addr = flash_get_bank_addr(FLASH_OTA_BANK_1) & 0xffffff;
+ }
+ else
+ {
+ dest_base_addr = flash_get_bank_addr(FLASH_OTA_BANK_0) & 0xffffff;
+ }
+ if ((source_base_addr % 4096) || (dest_base_addr % 4096))
+ {
+ error_code = __LINE__;
+ goto L_Return;
+ }
+ if (dest_base_addr >= dlAddress)
+ {
+ error_code = __LINE__;
+ goto L_Return;
+ }
+ dlOffset = dlAddress - dest_base_addr;
+ tmp_offset = dlOffset;
+ if (dlOffset % 4096)
+ {
+ error_code = __LINE__;
+ goto L_Return;
+ }
+ T_IMG_HEADER_FORMAT *p_data_header;
+ p_data_header = (T_IMG_HEADER_FORMAT *)(source_base_addr + dlOffset);
+ if (p_data_header->ctrl_header.image_id != image_id)
+ {
+ error_code = __LINE__;
+ goto L_Return;
+ }
+
+ while (remain_size > 0)
+ {
+ if (!((dest_base_addr + tmp_offset) % 4096)) //must 4k align
+ {
+ flash_erase_sector(dest_base_addr + tmp_offset);
+ }
+ if (remain_size > 2048)
+ {
+ memcpy(p_ota_temp_buffer_head, (uint8_t *)(source_base_addr + tmp_offset), 2048);
+ if (remain_size == dlSize)
+ {
+ T_IMG_CTRL_HEADER_FORMAT *p_header = (T_IMG_CTRL_HEADER_FORMAT *) p_ota_temp_buffer_head;
+ p_header->ctrl_flag.flag_value.not_ready = 0x1; /*make sure image is not ready, will use it later*/
+ }
+ for (int i = 0; i < 2048; i = i + 4)
+ {
+ flash_auto_write_locked(dest_base_addr + tmp_offset + i, *(uint32_t *)p_ota_temp_buffer_head);
+
+ flash_auto_read_locked(dest_base_addr + tmp_offset + i | FLASH_OFFSET_TO_NO_CACHE, &s_val);
+ if (s_val != *(uint32_t *)p_ota_temp_buffer_head)
+ {
+ DFU_PRINT_TRACE3("s_val:0x%08x, *p_void:0x%08x, i:0x%08x",
+ s_val, *(uint32_t *)p_ota_temp_buffer_head, i);
+ error_code = __LINE__;
+ goto L_Return;
+ }
+ else
+ {
+ p_ota_temp_buffer_head += 4;
+ }
+ }
+
+
+ remain_size -= 2048;
+ }
+ else
+ {
+ memcpy(p_ota_temp_buffer_head, (uint8_t *)(source_base_addr + tmp_offset), remain_size);
+ for (int i = 0; i < remain_size; i = i + 4)
+ {
+ flash_auto_write_locked(dest_base_addr + tmp_offset + i, *(uint32_t *)p_ota_temp_buffer_head);
+
+ flash_auto_read_locked(dest_base_addr + tmp_offset + i | FLASH_OFFSET_TO_NO_CACHE, &s_val);
+ if (s_val != *(uint32_t *)p_ota_temp_buffer_head)
+ {
+ DFU_PRINT_TRACE3("s_val:0x%08x, *p_void:0x%08x, i:0x%08x",
+ s_val, *(uint32_t *)p_ota_temp_buffer_head, i);
+ error_code = __LINE__;
+ goto L_Return;
+ }
+ else
+ {
+ p_ota_temp_buffer_head += 4;
+ }
+ }
+ remain_size = 0;
+ }
+ tmp_offset += 2048;
+ }
+
+L_Return:
+ DFU_PRINT_INFO1("<====dfu_copy_img error_code:%d", error_code);
+ if (error_code)
+ {
+ return false;
+ }
+ return true;
+}
+#endif //end ENABLE_BANK_SWITCH_COPY_APP_DATA
+
+
+
+
+
+
+
diff --git a/src/platform/psram_platform.c b/src/platform/psram_platform.c
new file mode 100644
index 0000000..d139e02
--- /dev/null
+++ b/src/platform/psram_platform.c
@@ -0,0 +1,513 @@
+#include <stddef.h>
+#include "psram_platform.h"
+#include "rtl876x.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_pinmux.h"
+#include "flash_device.h"
+#include "trace.h"
+
+#define SPIC_FIFO_SIZE 256
+#define PSRAM_MAGIC_PATTERN 0x5A5A12A5
+#define PSRAM_CAL_ADDR 0x6802030 //0x7002030
+#define DELAY_CNT_MAX 32
+#define FMC_MAIN1 0x6800000
+
+/** @defgroup FLASH_DRIVER_Registers_Definitions Flash Driver Registers Definitions
+ * @brief
+ * @{
+ */
+/*****************************************************************************************
+* Registers Definitions --------------------------------------------------------*
+******************** Bits definition for SPIC_CTRLR0 register *******************/
+#define BIT_CK_MTIMES(x) (((x) & 0x0000001F) << 23)
+#define BIT_FAST_RD(x) (((x) & 0x00000001) << 22)
+#define BIT_CMD_CH(x) (((x) & 0x00000003) << 20)
+#define BIT_DATA_CH(x) (((x) & 0x00000003) << 18)
+#define BIT_ADDR_CH(x) (((x) & 0x00000003) << 16)
+#define BIT_TMOD(x) (((x) & 0x00000003) << 8)
+#define BIT_SCPOL (0x00000001 << 7)
+#define BIT_SCPH (0x00000001 << 6)
+
+/******************** Bits definition for SPIC_CTRLR1 register *******************/
+#define BIT_NDF(x) ((x) & 0xfffff)
+
+/******************** Bits definition for SPIC_SSIENR register *******************/
+#define BIT_ATCK_CMD (0x00000001 << 1)
+#define BIT_SPIC_EN (0x00000001)
+
+/******************** Bits definition for SPIC_BAUDR register *******************/
+#define BIT_SCKDV(x) ((x) & 0x0fff)
+
+/******************** Bits definition for SPIC_SR register *******************/
+#define BIT_TXE (0x00000001 << 5)
+#define BIT_RFF (0x00000001 << 4)
+#define BIT_RFNE (0x00000001 << 3)
+#define BIT_TFE (0x00000001 << 2)
+#define BIT_TFNF (0x00000001 << 1)
+#define BIT_BUSY (0x00000001)
+
+/******************** Bits definition for SPIC_IMR register *******************/
+#define BIT_ACSIM (0x00000001 << 11)
+#define BIT_RXSIM (0x00000001 << 10)
+#define BIT_TXSIM (0x00000001 << 9)
+#define BIT_ACEIM (0x00000001 << 8)
+#define BIT_BYEIM (0x00000001 << 7)
+#define BIT_WBEIM (0x00000001 << 6)
+#define BIT_FSEIM (0x00000001 << 5)
+#define BIT_RXFIM (0x00000001 << 4)
+#define BIT_RXOIM (0x00000001 << 3)
+#define BIT_RXUIM (0x00000001 << 2)
+#define BIT_TXOIM (0x00000001 << 1)
+#define BIT_TXEIM (0x00000001)
+
+/******************** Bits definition for SPIC_ISR register *******************/
+#define BIT_ACSIS (0x00000001 << 11)
+#define BIT_RXSIS (0x00000001 << 10)
+#define BIT_TXSIS (0x00000001 << 9)
+#define BIT_ACEIS (0x00000001 << 8)
+#define BIT_BYEIS (0x00000001 << 7)
+#define BIT_WBEIS (0x00000001 << 6)
+#define BIT_FSEIS (0x00000001 << 5)
+#define BIT_RXFIS (0x00000001 << 4)
+#define BIT_RXOIS (0x00000001 << 3)
+#define BIT_RXUIS (0x00000001 << 2)
+#define BIT_TXOIS (0x00000001 << 1)
+#define BIT_TXEIS (0x00000001)
+
+/******************** Bits definition for SPIC_RISR register *******************/
+#define BIT_ACEIR (0x00000001 << 8)
+#define BIT_BYEIR (0x00000001 << 7)
+#define BIT_WBEIR (0x00000001 << 6)
+#define BIT_FSEIR (0x00000001 << 5)
+#define BIT_RXFIR (0x00000001 << 4)
+#define BIT_RXOIR (0x00000001 << 3)
+#define BIT_RXUIR (0x00000001 << 2)
+#define BIT_TXOIR (0x00000001 << 1)
+#define BIT_TXEIR (0x00000001)
+
+/******************** Bits definition for SPIC_CTRLR2 register *******************/
+#define BIT_RX_FIFO_ENTRY(x) (((x) & 0x0000000f) << 8)
+#define BIT_FIFO_ENTRY(x) (((x) & 0x0000000f) << 4)
+#define BIT_SEQ_EN (0x00000001 << 3)
+/* Indicate the WPn input pin of SPI Flash is connected to:
+ 0(default): WP=spi_sout[2], 1:WP=spi_sout[3]. */
+#define BIT_WPN_DNUM (0x00000001 << 2)
+/*write protect function.*/
+#define BIT_WPN_SET (0x00000001 << 1)
+/* SO pin of SPI Flash.0: SO connects to spi_sout[0]. 1(default): SO connects to spi_sout[1].*/
+#define BIT_SO_DUM (0x00000001)
+
+/******************** Bits definition for SPIC_ADDR_LENGTH register *******************/
+#define BIT_ADDR_PHASE_LENGTH(x) ((x) & 0x00000003)
+
+/******************** Bits definition for SPIC_AUTO_LENGTH register *******************/
+#define BIT_CS_H_WR_DUM_LEN(x) (((x) & 0x0000000f) << 28)
+#define BIT_CS_H_RD_DUM_LEN(x) (((x) & 0x00000003) << 26)
+#define BIT_AUTO_DUM_LEN(x) (((x) & 0x000000ff) << 18)
+#define BIT_AUTO_ADDR_LENGTH(x) (((x) & 0x00000003) << 16)
+#define BIT_IN_PHYSICAL_CYC(x) (((x) & 0x0000000f) << 12)
+#define BIT_RD_DUMMY_LENGTH(x) (((x) & 0x00000fff))
+
+/******************** Bits definition for SPIC_VALID_CMD register *******************/
+#define BIT_SEQ_TRANS_EN (0x00000001 << 14)
+#define BIT_CTRLR0_CH (0x00000001 << 12)
+#define BIT_PRM_EN (0x00000001 << 11)
+#define BIT_WR_AUTOCHECKSTATUS (0x00000001 << 10)
+#define BIT_WR_BLOCKING (0x00000001 << 9)
+#define BIT_WR_QUAD_II (0x00000001 << 8)
+#define BIT_WR_QUAD_I (0x00000001 << 7)
+#define BIT_WR_DUAL_II (0x00000001 << 6)
+#define BIT_WR_DUAL_I (0x00000001 << 5)
+#define BIT_RD_QUAD_IO (0x00000001 << 4)
+#define BIT_RD_QUAD_O (0x00000001 << 3)
+#define BIT_RD_DUAL_IO (0x00000001 << 2)
+#define BIT_RD_DUAL_I (0x00000001 << 1)
+#define BIT_FRD_SINGEL (0x00000001)
+
+
+/** End of FLASH_DRIVER_Registers_Definitions
+ * @}
+ */
+
+typedef enum
+{
+ CHANN_SINGLE = 0,
+ CHANN_DUAL = 1,
+ CHANN_QUAD = 2
+} T_CHANN_TYPE;
+
+typedef enum
+{
+ READ_CMD = 0x03,
+ FAST_READ_QUAD_CMD = 0xEB,
+ WRITE_CMD = 0x02,
+ QUAD_WRITE_CMD = 0x38,
+ RDID_CMD = 0x9F,
+ RESET_EN_CMD = 0x66,
+ RESET_CMD = 0x99,
+} PSRAM_CMD;
+
+/**
+ * @brief PSRAM Init structure definition
+ */
+typedef struct
+{
+ uint8_t curr_rd_cmd; /* current used read cmd */
+ uint8_t curr_wr_cmd; /* current used write cmd */
+ uint8_t rd_data_ch; /* read data channel */
+ uint8_t rd_addr_ch; /* read address channel */
+ uint8_t rd_st_dummy_cycle; /* read status dummy cycle */
+ uint8_t bit_mode;
+} T_PSRAM_DEVICE_INFO;
+
+T_PSRAM_DEVICE_INFO psram_device_info =
+{
+ .curr_rd_cmd = READ_CMD,
+ .curr_wr_cmd = WRITE_CMD,
+ .rd_data_ch = CHANN_SINGLE,
+ .rd_addr_ch = CHANN_SINGLE,
+};
+
+extern void spic_enable(SPIC_TypeDef *spic, uint32_t enable);
+extern void spic_set_rd_dummy_length(SPIC_TypeDef *spic, uint8_t dummy_len);
+
+SPIC_TypeDef *spic = NULL;
+
+static uint16_t g_def_dummy_len[3] = {0x0, 0x8, 0xC};/* default dummy length base for each bit mode */
+
+static uint32_t convert_psram_addr_to_offset(uint32_t addr)
+{
+ return (addr - FMC_MAIN1);
+}
+
+/**
+ * @brief set spic enable or disable.
+ *
+ * @param enable DISABLE to disable cache, ENABLE to enable cache.
+ * @return
+ * @note: spic should be disabled before programming any register in user mode
+*/
+void spic_enable(SPIC_TypeDef *spic, uint32_t enable)
+{
+ spic->ssienr = enable;
+}
+
+/**
+ * @brief set dummy_cycle in autolen register[11:0].
+ *
+ * @return
+*/
+
+static void spic_set_rd_dummy_length(SPIC_TypeDef *spic, uint8_t dummy_len)
+{
+ uint32_t data = BIT_RD_DUMMY_LENGTH(dummy_len);
+ HAL_UPDATE32(&spic->auto_length, 0xfff, data);
+}
+
+void psram_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_FLASH1, APBPeriph_FLASH1_CLOCK, (FunctionalState)ENABLE);
+
+ Pinmux_Config(P1_7, IDLE_MODE);
+ Pinmux_Config(P3_6, IDLE_MODE);
+ Pinmux_Config(P3_2, IDLE_MODE);
+ Pinmux_Config(P3_3, IDLE_MODE);
+ Pinmux_Config(P3_4, IDLE_MODE);
+ Pinmux_Config(P3_5, IDLE_MODE);
+
+ Pad_Config(P1_7, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP,
+ PAD_OUT_DISABLE, PAD_OUT_LOW);
+ Pad_Config(P3_6, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE,
+ PAD_OUT_DISABLE, PAD_OUT_LOW);
+ Pad_Config(P3_2, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP,
+ PAD_OUT_DISABLE, PAD_OUT_LOW);
+ Pad_Config(P3_3, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP,
+ PAD_OUT_DISABLE, PAD_OUT_LOW);
+ Pad_Config(P3_4, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP,
+ PAD_OUT_DISABLE, PAD_OUT_LOW);
+ Pad_Config(P3_5, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP,
+ PAD_OUT_DISABLE, PAD_OUT_LOW);
+
+ /* spic1 enable controller */
+ SYSBLKCTRL->u_210.BITS_210.BIT_SOC_FLASH_EN1 = 1;
+
+ /* spic1 master enable */
+ SYSBLKCTRL->u_2A8.BITS_2A8.SPIC1_MASTER_EN = 1;
+
+ /* spic1 & spic2 share clock source enable bit */
+ HAL_WRITE32(PERIPH_REG_BASE, 0x2D0, HAL_READ32(PERIPH_REG_BASE, 0x2D0) | BIT5);
+
+ /* set cs and baudrate */
+ SPIC1->ssienr = 0;
+ SPIC1->ser = BIT0;
+ SPIC1->baudr = 1;
+
+ /* ctrlr2[17:16] = 2'b11 to remove WREN+RDSR (i.e., only PP cmd issue) */
+ SPIC1->ctrlr2 |= (BIT16 | BIT17);
+
+ /* use ctrlr0 CMD_CH/DATA_CH/ADDR_CH in auto mode */
+ //BIT_BAND(SPIC1->valid_cmd, 12) = 1; /* CTRLR0_CH */
+
+ spic = SPIC1;
+}
+
+/*
+What are the differences between 1 bit mode and 4 bit mode?
+only 1 bit and 4 bit supported
+
+address length always 3
+1 bit:
+ 1-1-1
+4 bit:
+ 1-4-4
+
+
+auto mode bit num:
+1 bit:
+ VALID_CMD: no bits or clear 4 bit bits
+
+4 bit:
+ VALID_CMD: BIT_WR_QUAD_II(WR) / RD_QUAD_IO(RD)
+ READ_QUAD_ADDR_DATA[0:7]: 0xEB (PRM_EN disable)
+ WRITE_QUAD_ADDR_DATA: 0x38
+
+user mode bit num:
+ ctrlr0: CMD_CH, DATA_CH, ADDR_CH
+
+*/
+void psram_config(T_FLASH_MODE bit_mode)
+{
+ if (bit_mode == FLASH_MODE_1BIT)
+ {
+ spic->ssienr = 0;
+ spic->ctrlr0 &= ~(BIT_CMD_CH(3) | BIT_ADDR_CH(3) | BIT_DATA_CH(3));
+ spic->ssienr = 1;
+
+ psram_device_info.curr_rd_cmd = READ_CMD;
+ psram_device_info.curr_wr_cmd = WRITE_CMD;
+ psram_device_info.rd_addr_ch = CHANN_SINGLE;
+ psram_device_info.rd_data_ch = CHANN_SINGLE;
+
+ psram_device_info.bit_mode = bit_mode;
+ }
+ else if (bit_mode == FLASH_MODE_4BIT)
+ {
+ spic->ssienr = 0;
+ spic->ctrlr0 &= ~(BIT_CMD_CH(3) | BIT_ADDR_CH(3) | BIT_DATA_CH(3));
+ spic->ctrlr0 |= (BIT_ADDR_CH(bit_mode) | BIT_DATA_CH(bit_mode));
+ spic->valid_cmd |= (BIT4 | BIT8);
+ spic->ssienr = 1;
+
+ psram_device_info.curr_rd_cmd = FAST_READ_QUAD_CMD;
+ psram_device_info.curr_wr_cmd = QUAD_WRITE_CMD;
+ psram_device_info.rd_addr_ch = CHANN_QUAD;
+ psram_device_info.rd_data_ch = CHANN_QUAD;
+
+ psram_device_info.bit_mode = bit_mode;
+ }
+ else
+ {
+ DBG_DIRECT("PSRAM doesn't support %d bit mode.", 1 << bit_mode);
+ while (1);
+ }
+}
+
+void psram_seq_trans_enable(uint8_t enable)
+{
+ spic->ssienr = 0;
+
+ if (enable)
+ {
+ uint8_t bit_mode = psram_device_info.bit_mode;
+ uint16_t rd_dummy_len = BIT_RD_DUMMY_LENGTH(spic->auto_length);
+
+ if (rd_dummy_len >= g_def_dummy_len[bit_mode])
+ {
+ HAL_UPDATE32(&spic->auto_length, (BIT18 | BIT19 | BIT20 | BIT21 | BIT22 | BIT23 | BIT24 | BIT25),
+ BIT_AUTO_DUM_LEN((spic->baudr * 2) * (8 / (1 << bit_mode))));
+ }
+
+ BIT_BAND(spic->valid_cmd, 14) = enable; /* BIT_SEQ_TRANS_EN */
+ }
+ else
+ {
+ HAL_UPDATE32(&spic->auto_length, (BIT18 | BIT19 | BIT20 | BIT21 | BIT22 | BIT23 | BIT24 | BIT25),
+ BIT_AUTO_DUM_LEN(psram_device_info.rd_st_dummy_cycle));
+
+ BIT_BAND(spic->valid_cmd, 14) = enable; /* BIT_SEQ_TRANS_EN */
+ }
+}
+
+bool psram_calibration(T_FLASH_MODE bit_mode)
+{
+ bool ret = false;
+ uint16_t dly_cnt = g_def_dummy_len[bit_mode];
+
+ /* adjust AUTO_LENGTH[RD_DUMMY_LENGTH], make sure read data equals magic pattern. */
+ for (; dly_cnt < DELAY_CNT_MAX; ++dly_cnt)
+ {
+ uint32_t rd_data;
+
+ spic_enable(spic, DISABLE);
+ spic_set_rd_dummy_length(spic, dly_cnt);
+ spic_enable(spic, ENABLE);
+
+ rd_data = HAL_READ32(PSRAM_CAL_ADDR, 0);
+
+ DBG_DIRECT("cnt=%d, [%08X]=%08X", dly_cnt, PSRAM_CAL_ADDR, rd_data);
+
+ if (rd_data == PSRAM_MAGIC_PATTERN)
+ {
+ /* update to AUTO_DUM_LEN when 1 bit mode */
+ if (bit_mode == FLASH_MODE_1BIT)
+ {
+ spic_enable(spic, DISABLE);
+ spic->auto_length &= ~ BIT_AUTO_DUM_LEN(0xFF);
+ spic->auto_length |= BIT_AUTO_DUM_LEN(dly_cnt);
+ spic_enable(spic, ENABLE);
+ psram_device_info.rd_st_dummy_cycle = dly_cnt;
+ }
+
+ /* update IN_PHYSICAL_CYC */
+ if (dly_cnt >= g_def_dummy_len[bit_mode])
+ {
+ spic_enable(spic, DISABLE);
+ spic->auto_length |= BIT_IN_PHYSICAL_CYC(dly_cnt - g_def_dummy_len[bit_mode]);
+ spic_enable(spic, ENABLE);
+ }
+
+ /* get things done, break */
+ break;
+ }
+ }
+
+ return ret;
+}
+
+void psram_try_high_speed(void)
+{
+ /*
+ 1 bit calibration: 1 bit and RDSR rd dummy length
+ use auto write to write a magic pattern before calibration
+ */
+ uint32_t *p_magic_pattern = (uint32_t *)PSRAM_CAL_ADDR;
+
+ *p_magic_pattern = PSRAM_MAGIC_PATTERN;
+
+ /* start 1 bit calibration and get 1 bit rd dummy length */
+ /* do calibration -->
+ get a rd_dummy_len_val
+ set AUTO_LENGTH[RD_DUMMY_LENGTH] and AUTO_LENGTH[AUTO_DUM_LEN] = rd_dummy_len_val
+ set AUTO_LENGTH[IN_PHYSICAL_CYC] = rd_dummy_len_val - g_def_dummy_len
+ */
+ psram_config(FLASH_MODE_1BIT);
+
+ psram_calibration(FLASH_MODE_1BIT);
+
+ DBG_DIRECT("1 bit: [%08X]=%08X", p_magic_pattern, *p_magic_pattern);
+
+ /* start 4 bit calibration and get 4 bit rd dummy length */
+ /* switch to 4 bit mode */
+ /* do calibration */
+ psram_config(FLASH_MODE_4BIT);
+
+ psram_calibration(FLASH_MODE_4BIT);
+
+ DBG_DIRECT("4 bit: [%08X]=%08X", p_magic_pattern, *p_magic_pattern);
+}
+
+bool psram_cmd_rx(uint8_t cmd, uint8_t read_len, uint8_t *read_buf)
+{
+ return true;
+}
+
+bool psram_cmd_tx(uint8_t cmd, uint8_t data_len, uint8_t *data_buf)
+{
+ return true;
+}
+
+bool psram_read(uint32_t addr, uint32_t len, uint8_t *data)
+{
+ return true;
+}
+
+/**
+ * @brief program data to psram via user mode
+ * @param start_addr start address where is going to be written in flash
+ * @param data_len data length to be written
+ * @param data data buffer to be written
+ * @return
+ * @note 1. SPIC only supports SPIC_FIFO_SIZE FIFO, so max SPIC_FIFO_SIZE-4 word allowed to be written.
+ * 2. start address should be 4 byte align
+*/
+static bool psram_write_internal(uint32_t start_addr, uint32_t data_len, uint8_t *data)
+{
+ bool retval = true;
+ uint8_t cmd_pp = psram_device_info.curr_wr_cmd, i;
+ uint32_t wr_addr;
+ uint32_t *data_word = (uint32_t *)data;
+
+ /* the test show that enable spic before push fifo make transfer faster, but we can't push by
+ byte. if we want to push by byte, we should disable spic first. */
+ spic_enable(spic, ENABLE);
+ wr_addr = cmd_pp | __REV(start_addr);
+ spic->dr[0].word = wr_addr;
+
+ for (i = 0; i < data_len / 4; i++)
+ {
+ spic->dr[0].word = data_word[i];
+ }
+
+ while (spic->sr & BIT_BUSY);
+
+ spic_enable(spic, DISABLE);
+ return retval;
+}
+
+/**
+ * @brief program data to flash via user mode
+ * @param start_addr start address where is going to be written in flash
+ * @param data_len data length to be written
+ * @param data data buffer to be written
+ * @return true if success
+ * @note start address should be 4 byte align
+*/
+bool psram_write(uint32_t addr, uint32_t len, uint8_t *data)
+{
+ const uint32_t blksize = SPIC_FIFO_SIZE - 4;
+ uint32_t tmp_addr = convert_psram_addr_to_offset(addr);
+ uint8_t *tmp_data = data;
+ int remain_size = len;
+
+ spic_enable(spic, DISABLE);
+ spic->ctrlr0 &= ~(BIT_TMOD(3)); /* tx mode */
+
+ while (remain_size > 0)
+ {
+ uint32_t write_size = remain_size > blksize ? blksize : remain_size;
+
+ extern bool psram_write_internal(uint32_t start_addr, uint32_t data_len, uint8_t *data);
+ if (!psram_write_internal(tmp_addr, write_size, tmp_data))
+ {
+ return false;
+ }
+
+ tmp_addr += write_size;
+ tmp_data += write_size;
+ remain_size -= write_size;
+ }
+
+ return true;
+}
+
+void psram_deinit(void)
+{
+ /* clock disable */
+ RCC_PeriphClockCmd(APBPeriph_FLASH1, APBPeriph_FLASH1_CLOCK, (FunctionalState)DISABLE);
+
+ /* spic1 enable controller */
+ SYSBLKCTRL->u_210.BITS_210.BIT_SOC_FLASH_EN1 = 0;
+
+ /* spic1 master enable */
+ SYSBLKCTRL->u_2A8.BITS_2A8.SPIC1_MASTER_EN = 0;
+}
diff --git a/src/platform/qspi_lcd_platform.c b/src/platform/qspi_lcd_platform.c
new file mode 100644
index 0000000..24f8e85
--- /dev/null
+++ b/src/platform/qspi_lcd_platform.c
@@ -0,0 +1,46 @@
+#include "qspi_lcd_platform.h"
+#include "rtl876x.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_pinmux.h"
+
+void qspi_lcd_init(void)
+{
+ /* module init */
+ RCC_PeriphClockCmd(APBPeriph_FLASH2, APBPeriph_FLASH2_CLOCK, (FunctionalState)ENABLE);
+
+ Pinmux_Config(P4_3, IDLE_MODE);
+ Pinmux_Config(P4_0, IDLE_MODE);
+ Pinmux_Config(P4_2, IDLE_MODE);
+ Pinmux_Config(P4_1, IDLE_MODE);
+ Pinmux_Config(P0_7, IDLE_MODE);
+ Pinmux_Config(P0_6, IDLE_MODE);
+
+ Pad_Config(P4_3, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP,
+ PAD_OUT_DISABLE, PAD_OUT_LOW);
+ Pad_Config(P4_1, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE,
+ PAD_OUT_DISABLE, PAD_OUT_LOW);
+ Pad_Config(P0_7, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE,
+ PAD_OUT_DISABLE, PAD_OUT_LOW);
+ Pad_Config(P4_2, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE,
+ PAD_OUT_DISABLE, PAD_OUT_LOW);
+ Pad_Config(P4_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE,
+ PAD_OUT_DISABLE, PAD_OUT_LOW);
+ Pad_Config(P0_6, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE,
+ PAD_OUT_DISABLE, PAD_OUT_LOW);
+
+ /* spic2 enable controller */
+ SYSBLKCTRL->u_210.BITS_210.BIT_SOC_FLASH_EN2 = 1;
+ /* spic2 master enable */
+ SYSBLKCTRL->u_2A8.BITS_2A8.SPIC2_MASTER_EN = 1;
+ /* spic2 write enable default (Jimmy) */
+
+ /* spic1 & spic2 share clock source enable bit */
+ HAL_WRITE32(PERIPH_REG_BASE, 0x2D0, HAL_READ32(PERIPH_REG_BASE, 0x2D0) | BIT5);
+
+ /* set cs and baudrate */
+ SPIC2->ssienr = 0;
+ SPIC2->ser = BIT0;
+ SPIC2->baudr = 1;
+}
+
+
diff --git a/src/platform/retarget.c b/src/platform/retarget.c
new file mode 100644
index 0000000..4799e48
--- /dev/null
+++ b/src/platform/retarget.c
@@ -0,0 +1,188 @@
+/******************************************************************************/
+/* RETARGET.C: 'Retarget' layer for target-dependent low level functions */
+/******************************************************************************/
+/* This file is part of the uVision/ARM development tools. */
+/* Copyright (c) 2005 Keil Software. All rights reserved. */
+/* This software may only be used under the terms of a valid, current, */
+/* end user licence from KEIL for a compatible version of KEIL software */
+/* development tools. Nothing else gives you the right to use this software. */
+/******************************************************************************/
+
+/* 0: redefine printf empty function
+ 1: redefine printf and using except log uart to print log
+others: redefine printf just using log uart to print log*/
+#define PRINTF_RETARGET_METHOD 0
+
+
+#if ( PRINTF_RETARGET_METHOD == 0)
+#include <stdio.h>
+struct __FILE
+{
+ int handle;
+ /* Whatever you require here. If the only file you are using is */
+ /* standard output using printf() for debugging, no file handling */
+ /* is required. */
+};
+/* FILE is typedef in stdio.h. */
+FILE __stdout;
+int fputc(int ch, FILE *f)
+{
+ /* Your implementation of fputc(). */
+ return ch;
+}
+int ferror(FILE *f)
+{
+ /* Your implementation of ferror(). */
+ return 0;
+}
+
+#elif (PRINTF_RETARGET_METHOD == 1)
+#include <stdio.h>
+#include "rtl876x_uart.h"
+/*
+#include "rtl876x_nvic.h"
+#include "rtl876x_uart.h"
+#define UART_TX_PIN P4_0
+void board_uart_init(void)
+{
+ Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+ Pinmux_Config(UART_TX_PIN, UART0_TX);
+}
+
+void driver_uart_init(void)
+{
+ UART_DeInit(UART);
+
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ // uart init
+ UART_InitTypeDef UART_InitStruct;
+ UART_StructInit(&UART_InitStruct);
+
+ UART_InitStruct.parity = UART_PARITY_NO_PARTY;
+ UART_InitStruct.stopBits = UART_STOP_BITS_1;
+ UART_InitStruct.wordLen = UART_WROD_LENGTH_8BIT;
+ UART_InitStruct.rxTriggerLevel = 16; //1~29
+ UART_InitStruct.idle_time = UART_RX_IDLE_2BYTE; //idle interrupt wait time
+
+ UART_Init(UART, &UART_InitStruct);
+}
+*/
+
+struct __FILE
+{
+ int handle;
+ /* Whatever you require here. If the only file you are using is */
+ /* standard output using printf() for debugging, no file handling */
+ /* is required. */
+};
+/* FILE is typedef in stdio.h. */
+FILE __stdout;
+int fputc(int ch, FILE *f)
+{
+ /* Your implementation of fputc(). */
+ while (UART_GetFlagState(UART, UART_FLAG_THR_TSR_EMPTY) != SET);
+ UART_SendData(UART, &ch, 1);
+ return ch;
+}
+int ferror(FILE *f)
+{
+ /* Your implementation of ferror(). */
+ return 0;
+}
+
+#else //print log by log_direct
+#include <stdarg.h>
+#include <stdio.h>
+#include "os_sync.h"
+#include "trace.h"
+#include "otp.h"
+
+#define LOG_MESSAGE_SYNC_CODE 0x7E
+#define MAX_LOG_MESSAGE_LEN 128
+#define MAX_LOG_MESSAGE_LEN_FOR_SNOOP 252
+#define MAX_ARGUMENT_SIZE 20
+
+#define GET_TYPE(info) (uint8_t)((info) >> 24)
+#define GET_SUBTYPE(info) (uint8_t)((info) >> 16)
+#define GET_MODULE(info) (uint8_t)((info) >> 8)
+#define GET_LEVEL(info) (uint8_t)((info) >> 0)
+
+extern uint32_t log_timestamp_get(void);
+extern void LogUartTxChar(const uint8_t ch);
+extern uint8_t log_seq_num;
+
+int printf(const char *fmt, ...)
+{
+ char l_msg[MAX_LOG_MESSAGE_LEN];
+ uint16_t log_length;
+ int16_t fmt_length;
+ uint32_t timestamp;
+ va_list ap;
+ uint16_t i;
+ uint32_t s;
+ uint32_t info;
+
+ /**
+ * Byte: Description
+ * 0: Sync(0x7E)
+ * 1: Length
+ * 2: SeqNum
+ * 3: CheckSum
+ * 4-5: Timestamp
+ * 6: Type
+ * 7: SubType: SUBTYPE_DIRECT
+ * 8: Format String
+ */
+
+ if (!is_log_init || OTP->logDisable == 1)
+ {
+ return 0;
+ }
+
+ timestamp = log_timestamp_get();
+ info = COMBINE_TRACE_INFO(TYPE_BEE2, SUBTYPE_DIRECT, 0, 0);
+
+ timestamp = log_timestamp_get();
+
+ l_msg[0] = LOG_MESSAGE_SYNC_CODE;
+ l_msg[4] = (uint8_t)timestamp;
+ l_msg[5] = (uint8_t)(timestamp >> 8);
+ l_msg[6] = GET_TYPE(info);
+ l_msg[7] = GET_SUBTYPE(info);
+
+ log_length = 8;
+
+ va_start(ap, fmt);
+ fmt_length = vsnprintf(l_msg + 8, MAX_LOG_MESSAGE_LEN - 8, fmt, ap);
+ if (fmt_length < 0) /* error occurred */
+ {
+ fmt_length = 0;
+ }
+ else if (log_length + fmt_length > MAX_LOG_MESSAGE_LEN) /* truncated */
+ {
+ log_length = MAX_LOG_MESSAGE_LEN;
+
+ }
+ else
+ {
+ log_length += fmt_length;
+ }
+ va_end(ap);
+
+ l_msg[1] = log_length;
+
+ s = os_lock();
+ l_msg[2] = log_seq_num++;
+ os_unlock(s);
+
+ l_msg[3] = l_msg[0] ^ l_msg[1] ^ l_msg[2];
+
+ for (i = 0; i < log_length; ++i)
+ {
+ LogUartTxChar(l_msg[i]);
+ }
+
+ return log_length;
+}
+#endif
diff --git a/src/platform/system_trace.c b/src/platform/system_trace.c
new file mode 100644
index 0000000..eac69ec
--- /dev/null
+++ b/src/platform/system_trace.c
@@ -0,0 +1,171 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file
+* @brief
+* @details
+* @author
+* @date
+* @version v0.1
+*********************************************************************************************************
+*/
+
+#include "trace_config.h"
+#include "system_trace.h"
+#include "os_timer.h"
+#include "otp.h"
+#include "trace.h"
+
+extern void *xTimerQueue;
+extern void *io_queue_handle;
+extern void *evt_queue_handle;
+
+extern BOOL_PATCH_FUNC patch_vTaskSwitchContext;
+extern void *xTimerQueue;
+
+#if (TRACE_HEAP_EN == 1)
+HEAP_INFO heap_info[TRACE_HEAP_TYPE_NUM];
+
+void print_heap_info(void)
+{
+ for (uint32_t i = 0; i < TRACE_HEAP_TYPE_NUM; ++i)
+ {
+ OS_PRINT_TRACE4("heap type: %i, total size: %d, remain size: %d, minimum ever free size: %d",
+ i, heap_info[i].total_size, heap_info[i].curr_remain_size, heap_info[i].minimum_ever_free_size);
+
+ OS_PRINT_TRACE1("free list: free block %d.", heap_info[i].free_size_list.number);
+ for (uint32_t j = 0; j < heap_info[i].free_size_list.number; ++j)
+ {
+ OS_PRINT_TRACE3("heap type: %i,free block: %d, free size: %d", i,
+ heap_info[i].free_size_list.number, heap_info[i].free_size_list.size[j]);
+ }
+ }
+}
+#endif
+
+#if (TRACE_STACK_EN == 1)
+STACK_INFO stack_info;
+
+void print_stack_info(void)
+{
+ OS_PRINT_TRACE1("task stack: task number %d", stack_info.task_number);
+ for (uint32_t i = 0; i < stack_info.task_number; ++i)
+ {
+ OS_PRINT_TRACE3("task id: %d, name: %s, minimum ever remain size %d bytes",
+ stack_info.task_stack_info[i].task_id, TRACE_STRING(stack_info.task_stack_info[i].task_name),
+ stack_info.task_stack_info[i].minimum_ever_remain_size);
+ }
+ OS_PRINT_TRACE1("main stack: minimum ever remain size %d bytes",
+ stack_info.main_stack_minimum_ever_remain_size);
+}
+#endif
+
+#if (TRACE_TIMER_EN == 1)
+TIMER_INFO timer_info;
+
+void print_timer_info(void)
+{
+ OS_PRINT_TRACE3("timer: total %d, current used %d, minimum ever remain %d",
+ OTP->timerMaxNumber, timer_info.curr_used_num, timer_info.minimum_ever_remain_num);
+}
+#endif
+
+#if (TRACE_QUEUE_EN == 1)
+extern uint32_t queue_handle_num0;
+QUEUE_INFO queue_info[MAX_QUEUE_OBJECTS_NUM];
+void print_queue_info(void)
+{
+ for (uint32_t i = 0; i < queue_handle_num0; i++)
+ {
+ OS_PRINT_TRACE4("queue %d: capacity_num %d, curr_num_in_queue %d, maximum_ever_num_in_queue %d",
+ i, queue_info[i].capacity_num, queue_info[i].curr_num_in_queue,
+ queue_info[i].maximum_ever_num_in_queue);
+ }
+}
+#endif
+
+void trace_timer_callback(void *p_timer)
+{
+#if (TRACE_HEAP_EN == 1)
+ trace_heap();
+ print_heap_info();
+#endif
+
+#if (TRACE_STACK_EN == 1)
+ trace_task_stack();
+ print_stack_info();
+#endif
+
+#if (TRACE_TIMER_EN == 1)
+ trace_timer();
+ print_timer_info();
+#endif
+#if (TRACE_QUEUE_EN == 1)
+ trace_queue();
+ print_queue_info();
+#endif
+}
+
+void system_trace_init(void)
+{
+#if (TRACE_HEAP_EN == 1 || TRACE_STACK_EN == 1 || TRACE_TIMER_EN == 1)
+ void *p_trace_timer = NULL;
+ if (os_timer_create(&p_trace_timer, "trace_timer", 1, \
+ TRACE_PERIOD_TIME, true, trace_timer_callback))
+ {
+ os_timer_start(&p_trace_timer);
+ }
+#endif
+
+#if (TRACE_TIMER_EN == 1)
+ trace_timer_init();
+#endif
+
+#if (DEBUG_DLPS_ERROR_EN == 1)
+ if (!trace_dlps_init(10000, 60000, 0))
+ {
+ OS_PRINT_ERROR0("trace dlps init fail!");
+ }
+#endif
+
+#if (DEBUG_TASK_HANG_EN == 1)
+ trace_task_hang_init(2, &xTimerQueue, 12, &evt_queue_handle, 10);
+#endif
+
+#if (TRACE_QUEUE_EN == 1)
+ trace_queue_init(2, &xTimerQueue, &evt_queue_handle);
+#endif
+
+#if (TRACE_HARDFAULT == 1)
+ /**
+ * extern void *app_task_handle;
+ * TCB_t *pxTimerTCB =(TCB_t *)xTimerTaskHandle;
+ * TCB_t *pxLowerTCB =(TCB_t *)low_task_handle;
+ * TCB_t *pxUpperTCB =(TCB_t *)upperstack_handle;
+ * TCB_t *pxAppTCB =(TCB_t *)app_task_handle;
+ */
+ /**
+ * @brief Initializes trace_hardfault save to flash including critical task stack
+ * @param dump_task_stack_num: number of task
+ * @return if it is successfully initialized , return true
+
+ * For example
+ hardfault_save_to_flash_init(2, &low_task_handle, 1024, &app_task_handle, 1024);
+ @param 2: dump two task stack
+ @param low_task_handle: lowstack task handler value
+ @param 1024: dump task stack size
+ @param app_task_handle: app task handler value
+ @param 1024: dump task stack size
+ @note if need dump app task, must call this api after app task created!!!
+ Upperstack handler address is different when used different upperstack img!
+ */
+ extern void *low_task_handle;
+ extern void *xTimerTaskHandle;
+ extern void *xIdleTaskHandle;
+ extern void *app_task_handle;
+ hardfault_save_to_flash_init(2, &low_task_handle, 1024, &app_task_handle, 1024);
+#endif
+}
+
+
diff --git a/src/sample/ble_audio_ba/app_flags.h b/src/sample/ble_audio_ba/app_flags.h
new file mode 100644
index 0000000..3457a16
--- /dev/null
+++ b/src/sample/ble_audio_ba/app_flags.h
@@ -0,0 +1,36 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup BT5_CENTRAL_Config BT5 Central App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Configure APP LE link number */
+#define APP_MAX_LINKS 1
+
+#define LE_AUDIO_LIB_SUPPORT 1
+#define BT_GATT_CLIENT_SUPPORT 1
+#define LE_AUDIO_BROADCAST_ASSISTANT_ROLE 1
+
+/** @} */ /* End of group BT5_CENTRAL_Config */
+
+#endif
diff --git a/src/sample/ble_audio_ba/app_task.c b/src/sample/ble_audio_ba/app_task.c
new file mode 100644
index 0000000..ad37b38
--- /dev/null
+++ b/src/sample/ble_audio_ba/app_task.c
@@ -0,0 +1,108 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "os_msg.h"
+#include "os_task.h"
+#include "trace.h"
+#include "gap.h"
+#include "gap_le.h"
+#include "data_uart.h"
+#include "user_cmd_parse.h"
+#include "user_cmd.h"
+#include "app_msg.h"
+#include "ble_audio_ba_app.h"
+#include "app_task.h"
+
+/** @defgroup BT5_CENTRAL_APP_TASK BT5 Central App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 8 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_main_task(void *p_param);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE,
+ APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ data_uart_init(evt_queue_handle, io_queue_handle);
+ user_cmd_init(&user_cmd_if, "ble_audio_ba");
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group BT5_CENTRAL_APP_TASK */
+
+
diff --git a/src/sample/ble_audio_ba/app_task.h b/src/sample/ble_audio_ba/app_task.h
new file mode 100644
index 0000000..33186ef
--- /dev/null
+++ b/src/sample/ble_audio_ba/app_task.h
@@ -0,0 +1,30 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.h
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+extern void driver_init(void);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init(void);
+
+extern void *evt_queue_handle;
+extern void *io_queue_handle;
+
+#endif
+
diff --git a/src/sample/ble_audio_ba/ble_audio_ba_app.c b/src/sample/ble_audio_ba/ble_audio_ba_app.c
new file mode 100644
index 0000000..ea5c403
--- /dev/null
+++ b/src/sample/ble_audio_ba/ble_audio_ba_app.c
@@ -0,0 +1,540 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file central_app.c
+ * @brief This file handles BLE BT5 central application routines.
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include "trace.h"
+#include "gap.h"
+#include "gap_bond_le.h"
+#include "gap_msg.h"
+#include "gap_ext_scan.h"
+#include "user_cmd.h"
+#include "user_cmd_parse.h"
+#include "app_msg.h"
+#include "link_mgr.h"
+#include "ble_audio_ba_role.h"
+#if LE_AUDIO_LIB_SUPPORT
+#include "ble_audio.h"
+#endif
+#if BT_GATT_CLIENT_SUPPORT
+#include "bt_gatt_client.h"
+#endif
+
+/** @defgroup BT5_CENTRAL_APP BT5 Central Application
+ * @brief This file handles BLE BT5 central application routines.
+ * @{
+ */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup BT5_CENTRAL_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+ uint8_t rx_char;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+ case IO_MSG_TYPE_UART:
+ /* We handle user command informations from Data UART in this branch. */
+ rx_char = (uint8_t)io_msg.subtype;
+ user_cmd_collect(&user_cmd_if, &rx_char, sizeof(rx_char), user_cmd_table);
+ break;
+#if LE_AUDIO_LIB_SUPPORT
+ case IO_MSG_TYPE_LE_AUDIO:
+ {
+ ble_audio_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, scan state %d, cause 0x%x",
+ new_state.gap_init_state,
+ new_state.gap_scan_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ uint8_t bt_addr[6];
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+ gap_get_param(GAP_PARAM_BD_ADDR, bt_addr);
+ data_uart_print("local bd addr: 0x%2x:%2x:%2x:%2x:%2x:%2x\r\n",
+ bt_addr[5],
+ bt_addr[4],
+ bt_addr[3],
+ bt_addr[2],
+ bt_addr[1],
+ bt_addr[0]);
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ T_BLE_LINK *p_link;
+ if (conn_id >= APP_MAX_LINKS)
+ {
+ return;
+ }
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d, conn_state(%d -> %d), disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ p_link = ble_link_find_by_conn_id(conn_id);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTING:
+ if (p_link != NULL)
+ {
+ p_link->state = GAP_CONN_STATE_DISCONNECTING;
+ }
+ break;
+ case GAP_CONN_STATE_DISCONNECTED:
+ if (p_link != NULL)
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+ ble_link_free(p_link);
+ }
+ data_uart_print("Disconnect conn_id %d, dis_cause 0x%x\r\n", conn_id, disc_cause);
+ break;
+
+ case GAP_CONN_STATE_CONNECTING:
+ if (p_link == NULL)
+ {
+ p_link = ble_link_alloc_by_conn_id(conn_id);
+ if (p_link != NULL)
+ {
+ p_link->state = GAP_CONN_STATE_CONNECTING;
+ le_get_conn_param(GAP_PARAM_CONN_BD_ADDR, p_link->remote_bd, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_BD_ADDR_TYPE, &p_link->remote_bd_type, conn_id);
+ }
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ if (p_link != NULL)
+ {
+ uint8_t tx_phy;
+ uint8_t rx_phy;
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ p_link->state = GAP_CONN_STATE_CONNECTED;
+
+ le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &p_link->mtu_size, conn_id);
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, (uint8_t *)&remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+
+ le_get_conn_param(GAP_PARAM_CONN_TX_PHY_TYPE, &tx_phy, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_RX_PHY_TYPE, &rx_phy, conn_id);
+ data_uart_print("Connected success conn_id %d, tx_phy %d, rx_phy %d\r\n", conn_id, tx_phy, rx_phy);
+ le_get_conn_addr(conn_id, p_link->remote_bd, &p_link->remote_bd_type);
+ le_get_conn_param(GAP_PARAM_CONN_HANDLE, &p_link->conn_handle, conn_id);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+#if BT_GATT_CLIENT_SUPPORT
+ T_BLE_LINK *p_link;
+ p_link = ble_link_find_by_conn_id(conn_id);
+ if (p_link)
+ {
+ if (cause == GAP_SUCCESS)
+ {
+ p_link->auth_cmpl = true;
+ if (p_link->mtu_received)
+ {
+ uint16_t conn_handle;
+ le_get_conn_param(GAP_PARAM_CONN_HANDLE, &conn_handle, conn_id);
+ APP_PRINT_INFO0("app_handle_authen_state_evt: gatt_client_start_discovery_all");
+ gatt_client_start_discovery_all(conn_handle, NULL);
+ }
+ }
+ else
+ {
+ p_link->auth_cmpl = false;
+ }
+ }
+#endif
+ if (cause == GAP_SUCCESS)
+ {
+ data_uart_print("Pair success\r\n");
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ data_uart_print("Pair failed: cause 0x%x\r\n", cause);
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+#if BT_GATT_CLIENT_SUPPORT
+ T_BLE_LINK *p_link;
+ p_link = ble_link_find_by_conn_id(conn_id);
+ if (p_link)
+ {
+ p_link->mtu_received = true;
+ if (p_link->auth_cmpl)
+ {
+ uint16_t conn_handle;
+ le_get_conn_param(GAP_PARAM_CONN_HANDLE, &conn_handle, conn_id);
+ gatt_client_start_discovery_all(conn_handle, NULL);
+ }
+ }
+#endif
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO4("app_handle_conn_param_update_evt update success:conn_id %d, conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_id, conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR2("app_handle_conn_param_update_evt update failed: conn_id %d, cause 0x%x",
+ conn_id, cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO1("app_handle_conn_param_update_evt update pending: conn_id %d", conn_id);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * sub_type of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO2("GAP_MSG_LE_BOND_PASSKEY_DISPLAY: conn_id %d, passkey %d",
+ conn_id, display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ data_uart_print("GAP_MSG_LE_BOND_PASSKEY_DISPLAY: conn_id %d, passkey %d\r\n",
+ conn_id,
+ display_value);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO2("GAP_MSG_LE_BOND_USER_CONFIRMATION: conn_id %d, passkey %d",
+ conn_id, display_value);
+ data_uart_print("GAP_MSG_LE_BOND_USER_CONFIRMATION: conn_id %d, passkey %d\r\n",
+ conn_id,
+ display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ data_uart_print("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d\r\n", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ //uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ //conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ //APP_PRINT_INFO1("GAP_MSG_LE_BOND_OOB_INPUT: conn_id %d", conn_id);
+ //le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ //le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+#if LE_AUDIO_LIB_SUPPORT
+ ble_audio_handle_gap_msg(p_gap_msg->subtype, gap_msg);
+#endif
+}
+/** @} */ /* End of group BT5_CENTRAL_GAP_MSG */
+
+/** @defgroup BT5_CENTRAL_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+#if LE_AUDIO_LIB_SUPPORT
+ ble_audio_handle_gap_cb(cb_type, p_cb_data);
+#endif
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = 0x%x", cb_type);
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_CONN_UPDATE_IND:
+ APP_PRINT_INFO5("GAP_MSG_LE_CONN_UPDATE_IND: conn_id %d, conn_interval_max 0x%x, conn_interval_min 0x%x, conn_latency 0x%x,supervision_timeout 0x%x",
+ p_data->p_le_conn_update_ind->conn_id,
+ p_data->p_le_conn_update_ind->conn_interval_max,
+ p_data->p_le_conn_update_ind->conn_interval_min,
+ p_data->p_le_conn_update_ind->conn_latency,
+ p_data->p_le_conn_update_ind->supervision_timeout);
+ /* if reject the proposed connection parameter from peer device, use APP_RESULT_REJECT. */
+ result = APP_RESULT_ACCEPT;
+ break;
+
+ case GAP_MSG_LE_EXT_ADV_REPORT_INFO:
+#if 0
+ APP_PRINT_INFO6("GAP_MSG_LE_EXT_ADV_REPORT_INFO:connectable %d, scannable %d, direct %d, scan response %d, legacy %d, data status 0x%x",
+ p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_CONNECTABLE_ADV,
+ p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_SCANNABLE_ADV,
+ p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_DIRECTED_ADV,
+ p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_SCAN_RESPONSE,
+ p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_USE_LEGACY_ADV,
+ p_data->p_le_ext_adv_report_info->data_status);
+ APP_PRINT_INFO5("GAP_MSG_LE_EXT_ADV_REPORT_INFO:event_type 0x%x, bd_addr %s, addr_type %d, rssi %d, data_len %d",
+ p_data->p_le_ext_adv_report_info->event_type,
+ TRACE_BDADDR(p_data->p_le_ext_adv_report_info->bd_addr),
+ p_data->p_le_ext_adv_report_info->addr_type,
+ p_data->p_le_ext_adv_report_info->rssi,
+ p_data->p_le_ext_adv_report_info->data_len);
+ APP_PRINT_INFO5("GAP_MSG_LE_EXT_ADV_REPORT_INFO:primary_phy %d, secondary_phy %d, adv_sid %d, tx_power %d, peri_adv_interval %d",
+ p_data->p_le_ext_adv_report_info->primary_phy,
+ p_data->p_le_ext_adv_report_info->secondary_phy,
+ p_data->p_le_ext_adv_report_info->adv_sid,
+ p_data->p_le_ext_adv_report_info->tx_power,
+ p_data->p_le_ext_adv_report_info->peri_adv_interval);
+ APP_PRINT_INFO2("GAP_MSG_LE_EXT_ADV_REPORT_INFO:direct_addr_type 0x%x, direct_addr %s",
+ p_data->p_le_ext_adv_report_info->direct_addr_type,
+ TRACE_BDADDR(p_data->p_le_ext_adv_report_info->direct_addr));
+#endif
+#if LE_AUDIO_BROADCAST_ASSISTANT_ROLE
+ app_ble_audio_handle_adv_report(p_data->p_le_ext_adv_report_info);
+#endif
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group BT5_CENTRAL_GAP_CALLBACK */
+/** @} */ /* End of group BT5_CENTRAL_APP */
diff --git a/src/sample/ble_audio_ba/ble_audio_ba_app.h b/src/sample/ble_audio_ba/ble_audio_ba_app.h
new file mode 100644
index 0000000..290c25c
--- /dev/null
+++ b/src/sample/ble_audio_ba/ble_audio_ba_app.h
@@ -0,0 +1,53 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ble_audio_ba_app.h
+ * @brief This file handles BLE BT5 central application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+#ifndef _BLE_AUDIO_BA_APP_H_
+#define _BLE_AUDIO_BA_APP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "gap_le.h"
+#include "app_msg.h"
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/ble_audio_ba/ble_audio_ba_role.c b/src/sample/ble_audio_ba/ble_audio_ba_role.c
new file mode 100644
index 0000000..e8a003c
--- /dev/null
+++ b/src/sample/ble_audio_ba/ble_audio_ba_role.c
@@ -0,0 +1,610 @@
+#include <string.h>
+#include "trace.h"
+#include "user_cmd.h"
+#include "user_cmd_parse.h"
+#include "link_mgr.h"
+#include "ble_audio_ba_role.h"
+#include "bap.h"
+#include "app_task.h"
+#include "profile_server.h"
+#include "ble_audio_ba_role.h"
+#if LE_AUDIO_LIB_SUPPORT
+#include "ble_audio.h"
+#endif
+#if BT_GATT_CLIENT_SUPPORT
+#include "bt_gatt_client.h"
+#endif
+#include "bass_def.h"
+#include "base_data_parse.h"
+#include "ble_audio_sync.h"
+#include "bass_client.h"
+
+#if LE_AUDIO_BROADCAST_ASSISTANT_ROLE
+typedef struct
+{
+ bool pa_print;
+ bool need_release;
+ T_BLE_AUDIO_SYNC_HANDLE sync_handle;
+ T_GAP_PA_SYNC_STATE source_pa_state;
+} T_APP_BA_CB;
+
+T_APP_BA_CB app_ba_cb;
+
+bool ble_audio_adv_filter_service_data(uint8_t report_data_len, uint8_t *p_report_data,
+ uint16_t uuid, uint8_t **pp_service_data, uint16_t *p_data_len)
+{
+ uint8_t *p_buffer = NULL;
+ uint8_t pos = 0;
+
+ while (pos < report_data_len)
+ {
+ /* Length of the AD structure. */
+ uint16_t length = p_report_data[pos++];
+ uint8_t type;
+
+ if (length < 1)
+ {
+ return false;
+ }
+
+ if ((length > 0x01) && ((pos + length) <= report_data_len))
+ {
+ /* Copy the AD Data to buffer. */
+ p_buffer = p_report_data + pos + 1;
+ /* AD Type, one octet. */
+ type = p_report_data[pos];
+
+ switch (type)
+ {
+ case GAP_ADTYPE_SERVICE_DATA:
+ case GAP_ADTYPE_16BIT_MORE: //just for pts
+ {
+ uint16_t srv_uuid;
+ LE_STREAM_TO_UINT16(srv_uuid, p_buffer);
+ if (srv_uuid == uuid)
+ {
+ if (pp_service_data != NULL)
+ {
+ *pp_service_data = p_buffer;
+ }
+ if (p_data_len != NULL)
+ {
+ *p_data_len = length - 3;
+ }
+ return true;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ pos += length;
+ }
+ return false;
+}
+
+void app_ble_audio_handle_adv_report(T_LE_EXT_ADV_REPORT_INFO *p_report)
+{
+ T_DEV_INFO *p_dev_info = NULL;
+ uint8_t *p_service_data;
+ uint16_t service_data_len;
+
+ if (ble_audio_adv_filter_service_data(p_report->data_len,
+ p_report->p_data,
+ BROADCAST_AUDIO_ANNOUNCEMENT_SRV_UUID, &p_service_data, &service_data_len))
+ {
+ if (service_data_len == BROADCAST_ID_LEN)
+ {
+ link_mgr_add_device(p_report->bd_addr,
+ p_report->addr_type, &p_dev_info);
+ if (p_dev_info)
+ {
+ p_dev_info->uuid16 = BROADCAST_AUDIO_ANNOUNCEMENT_SRV_UUID;
+ memcpy(p_dev_info->broadcast_id, p_service_data, BROADCAST_ID_LEN);
+ p_dev_info->adv_sid = p_report->adv_sid;
+ data_uart_print("Found dev[%d] = [%02x:%02x:%02x:%02x:%02x:%02x], broadcast audio announcement\r\n",
+ p_dev_info->idx,
+ p_dev_info->bd_addr[5], p_dev_info->bd_addr[4],
+ p_dev_info->bd_addr[3], p_dev_info->bd_addr[2],
+ p_dev_info->bd_addr[1], p_dev_info->bd_addr[0]);
+ }
+ }
+
+ }
+ if (ble_audio_adv_filter_service_data(p_report->data_len,
+ p_report->p_data,
+ GATT_UUID_BASS, &p_service_data, &service_data_len))
+ {
+ link_mgr_add_device(p_report->bd_addr,
+ p_report->addr_type, &p_dev_info);
+ if (p_dev_info)
+ {
+ p_dev_info->uuid16 = GATT_UUID_BASS;
+ data_uart_print("Found dev[%d] = [%02x:%02x:%02x:%02x:%02x:%02x], BASS\r\n",
+ p_dev_info->idx,
+ p_dev_info->bd_addr[5], p_dev_info->bd_addr[4],
+ p_dev_info->bd_addr[3], p_dev_info->bd_addr[2],
+ p_dev_info->bd_addr[1], p_dev_info->bd_addr[0]);
+ }
+ }
+}
+
+void app_ba_print_lv2(uint16_t length, uint8_t *p_data)
+{
+ uint16_t idx = 0;
+ uint16_t len;
+ uint8_t type;
+
+ for (; idx < length;)
+ {
+ len = p_data[idx];
+ idx++;
+ type = p_data[idx];
+ data_uart_print(" Length: [%d (0x%02x)]\r\n", len, len);
+ data_uart_print(" Type and Value:\r\n");
+ data_uart_print(" Type: [%d (0x%02x)]\r\n", type, type);
+ data_uart_print(" Value: [0x");
+ for (uint8_t i = 1; i < len; i++)
+ {
+ data_uart_print("%02x", p_data[idx + i]);
+ }
+ data_uart_print("]\r\n");
+ idx += len;
+ }
+}
+void app_ba_print_lv3(uint16_t length, uint8_t *p_data)
+{
+ uint16_t idx = 0;
+ uint16_t len;
+ uint8_t type;
+
+ for (; idx < length;)
+ {
+ len = p_data[idx];
+ idx++;
+ type = p_data[idx];
+ data_uart_print(" Length: [%d (0x%02x)]\r\n", len, len);
+ data_uart_print(" Type and Value:\r\n");
+ data_uart_print(" Type: [%d (0x%02x)]\r\n", type, type);
+ data_uart_print(" Value: [0x");
+ for (uint8_t i = 1; i < len; i++)
+ {
+ data_uart_print("%02x", p_data[idx + i]);
+ }
+ data_uart_print("]\r\n");
+ idx += len;
+ }
+}
+
+
+void app_ba_print_base_info(uint16_t length, uint8_t *p_pa_data)
+{
+ uint8_t codec_id_level2[CODEC_ID_LEN];//
+ uint8_t codec_cfg_len;
+ uint16_t uuid;
+ uint8_t i = 0;
+ uint8_t j = 0;
+ uint8_t num_subgroups;
+ uint32_t presentation_delay;
+
+ data_uart_print("- Set Basic Audio Announcements data:Basic Audio Announcements: \r\n");
+ data_uart_print(" Length: [%d (0x%02x)]\r\n", p_pa_data[0], p_pa_data[0]);
+ data_uart_print(" AD Type: [%d (0x%02x)]\r\n", p_pa_data[1], p_pa_data[1]);
+ STREAM_SKIP_LEN(p_pa_data, 2);
+ LE_STREAM_TO_UINT16(uuid, p_pa_data);
+ if (uuid != BASIC_AUDIO_ANNOUNCEMENT_SRV_UUID)
+ {
+ return;
+ }
+ data_uart_print(" Basic Audio Announcement Service UUID: [%d (0x%04x)] Service UUID\r\n", uuid,
+ uuid);
+ LE_STREAM_TO_UINT24(presentation_delay, p_pa_data);
+ LE_STREAM_TO_UINT8(num_subgroups, p_pa_data);
+ data_uart_print(" Presentation Delay: [%d (0x%06x)]\r\n", presentation_delay, presentation_delay);
+ data_uart_print(" Num Subgroups: [%d (0x%02x)]\r\n", num_subgroups, num_subgroups);
+ data_uart_print(" Codec And Metadata Subgroups: {\r\n");
+
+ for (i = 0; i < num_subgroups; i++)
+ {
+ uint8_t num_bis;//
+ uint8_t metadata_len;
+ LE_STREAM_TO_UINT8(num_bis, p_pa_data);
+ data_uart_print(" Num BIS: [%d (0x%02x)]\r\n", num_bis, num_bis);
+ data_uart_print(" Codec And Metadata Lv2:\r\n");
+ memcpy(codec_id_level2, p_pa_data, CODEC_ID_LEN);
+ STREAM_SKIP_LEN(p_pa_data, CODEC_ID_LEN);
+ data_uart_print(" Codec Configuration:\r\n");
+ data_uart_print(" Codec ID: [0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x]\r\n",
+ codec_id_level2[0], codec_id_level2[1], codec_id_level2[2],
+ codec_id_level2[3], codec_id_level2[4]);
+
+
+ LE_STREAM_TO_UINT8(codec_cfg_len, p_pa_data);
+ data_uart_print(" Codec Specific Configuration Length: [%d (0x%02x)]\r\n", codec_cfg_len,
+ codec_cfg_len);
+ data_uart_print(" LTV Wrapper: {\r\n");
+ if (codec_cfg_len != 0)
+ {
+ app_ba_print_lv2(codec_cfg_len, p_pa_data);
+ }
+ STREAM_SKIP_LEN(p_pa_data, codec_cfg_len);
+
+ LE_STREAM_TO_UINT8(metadata_len, p_pa_data);
+ data_uart_print(" Metadata Length: [%d (0x%02x)]\r\n", metadata_len, metadata_len);
+ data_uart_print(" Metadata:\r\n");
+ data_uart_print(" LTV Wrapper: {\r\n");
+ if (metadata_len != 0)
+ {
+ app_ba_print_lv2(metadata_len, p_pa_data);
+ }
+ STREAM_SKIP_LEN(p_pa_data, metadata_len);
+
+ for (j = 0; j < num_bis; j++)
+ {
+ uint8_t bis_index;
+ data_uart_print(" BIS Codec Subgroup Lv3: {\r\n");
+ LE_STREAM_TO_UINT8(bis_index, p_pa_data);
+ data_uart_print(" BIS index: [%d (0x%02x)]\r\n", bis_index, bis_index);
+ LE_STREAM_TO_UINT8(codec_cfg_len, p_pa_data);
+ data_uart_print(" Codec Specific Configuration Length: [%d (0x%02x)]\r\n", codec_cfg_len,
+ codec_cfg_len);
+ data_uart_print(" Codec Specific Configuration LTV: \r\n");
+ if (codec_cfg_len != 0)
+ {
+ app_ba_print_lv3(codec_cfg_len, p_pa_data);
+ }
+ STREAM_SKIP_LEN(p_pa_data, codec_cfg_len);
+ }
+ }
+}
+
+static void app_ble_audio_pa_sync_cb(T_BLE_AUDIO_SYNC_HANDLE handle, uint8_t cb_type,
+ void *p_cb_data)
+{
+ T_BLE_AUDIO_SYNC_CB_DATA *p_sync_cb = (T_BLE_AUDIO_SYNC_CB_DATA *)p_cb_data;
+ switch (cb_type)
+ {
+ case MSG_BLE_AUDIO_PA_SYNC_STATE:
+ {
+ APP_PRINT_TRACE3("MSG_BLE_AUDIO_PA_SYNC_STATE: sync_state %d, action %d, cause 0x%x\r\n",
+ p_sync_cb->p_pa_sync_state->sync_state,
+ p_sync_cb->p_pa_sync_state->action,
+ p_sync_cb->p_pa_sync_state->cause);
+ app_ba_cb.source_pa_state = p_sync_cb->p_pa_sync_state->sync_state;
+ if (p_sync_cb->p_pa_sync_state->sync_state == GAP_PA_SYNC_STATE_SYNCHRONIZED)
+ {
+ data_uart_print("PA SYNCHRONIZED\r\n");
+ }
+ else if (p_sync_cb->p_pa_sync_state->sync_state == GAP_PA_SYNC_STATE_TERMINATED)
+ {
+ data_uart_print("PA TERMINATED\r\n");
+ if (app_ba_cb.need_release)
+ {
+ if (ble_audio_sync_realese(app_ba_cb.sync_handle))
+ {
+ memset(&app_ba_cb, 0, sizeof(app_ba_cb));
+ }
+ }
+ }
+ }
+ break;
+
+ case MSG_BLE_AUDIO_PA_REPORT_INFO:
+ {
+#if 1
+ if (app_ba_cb.pa_print == false)
+ {
+ app_ba_print_base_info(p_sync_cb->p_le_periodic_adv_report_info->data_len,
+ p_sync_cb->p_le_periodic_adv_report_info->p_data);
+ app_ba_cb.pa_print = true;
+ }
+#endif
+ }
+ break;
+
+ case MSG_BLE_AUDIO_BASE_DATA_MODIFY_INFO:
+ {
+ APP_PRINT_TRACE1("MSG_BLE_AUDIO_BASE_DATA_MODIFY_INFO: p_base_mapping %p\r\n",
+ p_sync_cb->p_base_data_modify_info->p_base_mapping);
+ if (p_sync_cb->p_base_data_modify_info->p_base_mapping)
+ {
+ base_data_print(p_sync_cb->p_base_data_modify_info->p_base_mapping);
+ }
+ }
+ break;
+
+ case MSG_BLE_AUDIO_PA_BIGINFO:
+ {
+ }
+ break;
+ default:
+ break;
+ }
+ return;
+}
+
+bool app_ble_audio_pa_sync(T_DEV_INFO *p_dev_info)
+{
+ uint8_t options = 0;
+ uint8_t sync_cte_type = 0;
+ uint16_t sync_timeout = 1000;
+ uint16_t skip = 0;
+
+ if (app_ba_cb.sync_handle == NULL)
+ {
+ app_ba_cb.sync_handle = ble_audio_sync_create(app_ble_audio_pa_sync_cb,
+ p_dev_info->bd_type,
+ p_dev_info->bd_addr, p_dev_info->adv_sid,
+ p_dev_info->broadcast_id);
+ }
+ if (app_ba_cb.sync_handle == NULL)
+ {
+ goto failed;
+ }
+
+ if (ble_audio_pa_sync_establish(app_ba_cb.sync_handle,
+ options, sync_cte_type, skip, sync_timeout) == false)
+ {
+ goto failed;
+ }
+ return true;
+failed:
+ data_uart_print("bap_ba_ts_pa_sync: failed\r\n");
+ return false;
+}
+
+bool app_ble_audio_stop_pa_sync(bool need_release)
+{
+ if (app_ba_cb.sync_handle != NULL)
+ {
+ app_ba_cb.need_release = need_release;
+ return ble_audio_pa_terminate(app_ba_cb.sync_handle);
+ }
+ return false;
+}
+
+T_APP_RESULT app_handle_bass_client_msg(T_LE_AUDIO_MSG msg, void *buf)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ T_BLE_LINK *p_link = NULL;
+ uint8_t err_idx = 0;
+ switch (msg)
+ {
+ case LE_AUDIO_MSG_BASS_CLIENT_DIS_DONE:
+ {
+ T_BASS_CLIENT_DIS_DONE *p_data = (T_BASS_CLIENT_DIS_DONE *)buf;
+ APP_PRINT_INFO3("LE_AUDIO_MSG_BASS_CLIENT_DIS_DONE: conn_handle 0x%x, is_found %d, brs_char_num %d",
+ p_data->conn_handle,
+ p_data->is_found,
+ p_data->brs_char_num);
+ p_link = ble_link_find_by_conn_handle(p_data->conn_handle);
+ if (p_link == NULL)
+ {
+ err_idx = 0x10;
+ goto failed;
+ }
+ if (p_data->is_found)
+ {
+ if (p_data->load_form_ftl == false)
+ {
+ bass_enable_cccd(p_data->conn_handle);
+ }
+ for (uint8_t i = 0; i < p_data->brs_char_num; i++)
+ {
+ bass_read_brs_value(p_data->conn_handle, i);
+ }
+ p_link->brs_char_num = p_data->brs_char_num;
+ }
+ }
+ break;
+
+ case LE_AUDIO_MSG_BASS_CLIENT_CCCD:
+ {
+ T_BASS_CLIENT_CCCD *p_data = (T_BASS_CLIENT_CCCD *)buf;
+ APP_PRINT_INFO2("LE_AUDIO_MSG_BASS_CLIENT_CCCD: conn_handle 0x%x, cause 0x%x",
+ p_data->conn_handle,
+ p_data->cause);
+ }
+ break;
+ case LE_AUDIO_MSG_BASS_CLIENT_CP_RESULT:
+ {
+ T_BASS_CLIENT_CP_RESULT *p_data = (T_BASS_CLIENT_CP_RESULT *)buf;
+ APP_PRINT_INFO2("LE_AUDIO_MSG_BASS_CLIENT_CP_RESULT: conn_handle 0x%x, cause 0x%x",
+ p_data->conn_handle,
+ p_data->cause);
+ }
+ break;
+
+ case LE_AUDIO_MSG_BASS_CLIENT_SYNC_INFO_REQ:
+ {
+ T_BASS_CLIENT_SYNC_INFO_REQ *p_data = (T_BASS_CLIENT_SYNC_INFO_REQ *)buf;
+ APP_PRINT_INFO2("LE_AUDIO_MSG_BASS_CLIENT_SYNC_INFO_REQ: conn_handle 0x%x, instance_id %d",
+ p_data->conn_handle,
+ p_data->instance_id);
+ p_link = ble_link_find_by_conn_handle(p_data->conn_handle);
+ if (p_link == NULL)
+ {
+ err_idx = 0x10;
+ goto failed;
+ }
+ if (ble_audio_check_remote_features(p_data->conn_handle, LE_SUPPORT_FEATURES_MASK_ARRAY_INDEX3,
+ LE_SUPPORT_FEATURES_PAST_RECIPIENT_MASK_BIT))
+ {
+ T_BASS_PAST_SRV_DATA srv_data;
+ srv_data.adv_a_match_ext_adv = 0;
+ srv_data.adv_a_match_src = 0;
+ srv_data.source_id = p_link->source_id;
+ if (bass_transfer_syncinfo_of_remote_src(app_ba_cb.sync_handle, p_data->conn_handle,
+ srv_data) == false)
+ {
+ err_idx = 1;
+ goto failed;
+ }
+ }
+ }
+ break;
+
+ case LE_AUDIO_MSG_BASS_CLIENT_BRS_DATA:
+ {
+ T_BASS_CLIENT_BRS_DATA *p_data = (T_BASS_CLIENT_BRS_DATA *)buf;
+ APP_PRINT_INFO4("LE_AUDIO_MSG_BASS_CLIENT_BRS_DATA: conn_handle 0x%x, notify %d, read_cause 0x%x, instance_id %d",
+ p_data->conn_handle, p_data->notify, p_data->read_cause, p_data->instance_id);
+ p_link = ble_link_find_by_conn_handle(p_data->conn_handle);
+ if (p_link == NULL)
+ {
+ err_idx = 0x10;
+ goto failed;
+ }
+ if (p_data->p_brs_data && p_data->p_brs_data->brs_is_used)
+ {
+ APP_PRINT_INFO7("LE_AUDIO_MSG_BASS_CLIENT_BRS_DATA: source_id %d, source_address_type 0x%x, source_address %s, source_adv_sid %d, pa_sync_state %d, bis_sync_state 0x%x, big_encryption %d",
+ p_data->p_brs_data->source_id,
+ p_data->p_brs_data->source_address_type,
+ TRACE_BDADDR(p_data->p_brs_data->source_address),
+ p_data->p_brs_data->source_adv_sid,
+ p_data->p_brs_data->pa_sync_state,
+ p_data->p_brs_data->bis_sync_state,
+ p_data->p_brs_data->big_encryption);
+ if (p_data->p_brs_data->num_subgroups)
+ {
+ APP_PRINT_INFO4("LE_AUDIO_MSG_BASS_CLIENT_BRS_DATA: num_subgroups %d, bis_info_size %d, bis_sync 0x%x, metadata_len %d",
+ p_data->p_brs_data->num_subgroups,
+ p_data->p_brs_data->bis_info_size,
+ p_data->p_brs_data->p_cp_bis_info[0].bis_sync,
+ p_data->p_brs_data->p_cp_bis_info[0].metadata_len);
+ }
+
+ p_link->source_id = p_data->p_brs_data->source_id;
+ p_link->pa_sync_state = p_data->p_brs_data->pa_sync_state;
+ p_link->bis_sync_state = p_data->p_brs_data->bis_sync_state;
+ }
+ else
+ {
+ p_link->source_id = 0;
+ p_link->pa_sync_state = PA_SYNC_STATE_NOT_SYNC;
+ p_link->bis_sync_state = 0;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return app_result;
+failed:
+ APP_PRINT_TRACE1("app_handle_bass_client_msg:failed, err_idx %d", err_idx);
+ return app_result;
+}
+
+T_APP_RESULT app_ble_audio_msg_cb(T_LE_AUDIO_MSG msg, void *buf)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ uint16_t msg_group;
+
+ APP_PRINT_TRACE1("app_ble_audio_msg_cb: msg 0x%04x", msg);
+
+ msg_group = msg & 0xff00;
+
+ switch (msg_group)
+ {
+ case LE_AUDIO_MSG_GROUP_BASS_CLIENT:
+ app_result = app_handle_bass_client_msg(msg, buf);
+ break;
+
+ case LE_AUDIO_MSG_GROUP_BAP:
+ break;
+
+ default:
+ break;
+ }
+
+ return app_result;
+}
+
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+bool app_ble_audio_add_source(T_BLE_LINK *p_link, T_BASS_PA_SYNC pa_sync, uint32_t bis_array)
+{
+ if (app_ba_cb.sync_handle != NULL)
+ {
+ if (bass_cp_add_source_by_sync_info(app_ba_cb.sync_handle, p_link->conn_handle, pa_sync,
+ bis_array,
+ false))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool app_ble_audio_modify_source(T_BLE_LINK *p_link, T_BASS_PA_SYNC pa_sync, uint32_t bis_array)
+{
+ if (app_ba_cb.sync_handle != NULL)
+ {
+ if (bass_cp_modify_source_by_sync_info(app_ba_cb.sync_handle, p_link->conn_handle,
+ p_link->source_id, pa_sync, bis_array, false))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool app_ble_audio_profile_init(void)
+{
+ server_register_app_cb(app_profile_callback);
+ client_init(2);
+ T_BAP_ROLE_INFO role_info;
+ T_BLE_AUDIO_PARAMS ble_audio_param;
+ ble_audio_param.p_fun_cb = app_ble_audio_msg_cb;
+ ble_audio_param.evt_queue_handle = evt_queue_handle;
+ ble_audio_param.io_queue_handle = io_queue_handle;
+ if (ble_audio_init(&ble_audio_param) == false)
+ {
+ goto failed;
+ }
+ role_info.role_mask = BAP_BROADCAST_ASSISTANT_ROLE;
+ role_info.isoc_cig_max_num = 0;
+ role_info.isoc_cis_max_num = 0;
+ role_info.pa_adv_num = 0;
+ role_info.isoc_big_broadcaster_num = 0;
+ role_info.isoc_bis_broadcaster_num = 0;
+ role_info.pa_sync_num = 2;
+ role_info.isoc_big_receiver_num = 0;
+ role_info.isoc_bis_receiver_num = 0;
+ role_info.brs_num = 0;
+ role_info.init_gap = true;
+ if (bap_role_init(&role_info) == false)
+ {
+ goto failed;
+ }
+ return true;
+failed:
+ APP_PRINT_ERROR0("app_ble_audio_profile_init: failed");
+ return false;
+}
+#endif
diff --git a/src/sample/ble_audio_ba/ble_audio_ba_role.h b/src/sample/ble_audio_ba/ble_audio_ba_role.h
new file mode 100644
index 0000000..aa18f5e
--- /dev/null
+++ b/src/sample/ble_audio_ba/ble_audio_ba_role.h
@@ -0,0 +1,37 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ble_audio_ba_app.h
+ * @brief This file handles BLE BT5 central application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+#ifndef _BLE_AUDIO_BA_ROLE_H_
+#define _BLE_AUDIO_BA_ROLE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "bass_def.h"
+
+bool app_ble_audio_profile_init(void);
+void app_ble_audio_handle_adv_report(T_LE_EXT_ADV_REPORT_INFO *p_report);
+bool app_ble_audio_pa_sync(T_DEV_INFO *p_dev_info);
+bool app_ble_audio_stop_pa_sync(bool need_release);
+//bass cp
+bool app_ble_audio_add_source(T_BLE_LINK *p_link, T_BASS_PA_SYNC pa_sync, uint32_t bis_array);
+bool app_ble_audio_modify_source(T_BLE_LINK *p_link, T_BASS_PA_SYNC pa_sync, uint32_t bis_array);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/ble_audio_ba/link_mgr.c b/src/sample/ble_audio_ba/link_mgr.c
new file mode 100644
index 0000000..c8f721e
--- /dev/null
+++ b/src/sample/ble_audio_ba/link_mgr.c
@@ -0,0 +1,182 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file link_mgr.c
+ * @brief Link manager functions.
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include "link_mgr.h"
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @} */
+/** @addtogroup BT5_CENTRAL_SCAN_MGR
+ * @{
+ */
+T_DEV_INFO dev_list[APP_MAX_DEVICE_INFO];
+uint8_t dev_list_count = 0;
+T_APP_DB app_db;
+/** @} */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @addtogroup BT5_CENTRAL_SCAN_MGR
+ * @{
+ */
+/**
+ * @brief Add device information to device list.
+ *
+ * @param[in] bd_addr Peer device address.
+ * @param[in] bd_type Peer device address type.
+ * @retval true Success.
+ * @retval false Failed, device list is full.
+ */
+bool link_mgr_add_device(uint8_t *bd_addr, uint8_t bd_type, T_DEV_INFO **pp_dev)
+{
+ *pp_dev = NULL;
+ /* If result count not at max */
+ if (dev_list_count < APP_MAX_DEVICE_INFO)
+ {
+ uint8_t i;
+ /* Check if device is already in device list*/
+ for (i = 0; i < dev_list_count; i++)
+ {
+ if (memcmp(bd_addr, dev_list[i].bd_addr, GAP_BD_ADDR_LEN) == 0)
+ {
+ return true;
+ }
+ }
+ memset(&dev_list[dev_list_count], 0, sizeof(T_DEV_INFO));
+ /*Add addr to device list list*/
+ memcpy(dev_list[dev_list_count].bd_addr, bd_addr, GAP_BD_ADDR_LEN);
+ dev_list[dev_list_count].bd_type = bd_type;
+ dev_list[dev_list_count].idx = dev_list_count;
+ *pp_dev = &dev_list[dev_list_count];
+ /*Increment device list count*/
+ dev_list_count++;
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Clear device list.
+ * @retval void
+ */
+void link_mgr_clear_device_list(void)
+{
+ dev_list_count = 0;
+}
+
+T_BLE_LINK *ble_link_find_by_conn_id(uint8_t conn_id)
+{
+ T_BLE_LINK *p_link = NULL;
+ uint8_t i;
+
+ for (i = 0; i < APP_MAX_LINKS; i++)
+ {
+ if (app_db.le_link[i].used == true &&
+ app_db.le_link[i].conn_id == conn_id)
+ {
+ p_link = &app_db.le_link[i];
+ break;
+ }
+ }
+
+ return p_link;
+}
+
+T_BLE_LINK *ble_link_find_by_conn_handle(uint8_t conn_handle)
+{
+ T_BLE_LINK *p_link = NULL;
+ uint8_t i;
+
+ for (i = 0; i < APP_MAX_LINKS; i++)
+ {
+ if (app_db.le_link[i].used == true &&
+ app_db.le_link[i].conn_handle == conn_handle)
+ {
+ p_link = &app_db.le_link[i];
+ break;
+ }
+ }
+
+ return p_link;
+}
+
+T_BLE_LINK *ble_link_find_by_addr(uint8_t *bd_addr, uint8_t bd_type)
+{
+ T_BLE_LINK *p_link = NULL;
+ uint8_t i;
+
+ for (i = 0; i < APP_MAX_LINKS; i++)
+ {
+ if (app_db.le_link[i].used == true &&
+ app_db.le_link[i].remote_bd_type == bd_type
+ && memcmp(app_db.le_link[i].remote_bd, bd_addr, GAP_BD_ADDR_LEN) == 0)
+ {
+ p_link = &app_db.le_link[i];
+ break;
+ }
+ }
+
+ return p_link;
+}
+
+T_BLE_LINK *ble_link_alloc_by_conn_id(uint8_t conn_id)
+{
+ T_BLE_LINK *p_link = NULL;
+ uint8_t i;
+
+ p_link = ble_link_find_by_conn_id(conn_id);
+ if (p_link != NULL)
+ {
+ return p_link;
+ }
+
+ for (i = 0; i < APP_MAX_LINKS; i++)
+ {
+ if (app_db.le_link[i].used == false)
+ {
+ p_link = &app_db.le_link[i];
+
+ p_link->used = true;
+ p_link->conn_id = conn_id;
+ break;
+ }
+ }
+
+ return p_link;
+}
+
+bool ble_link_free(T_BLE_LINK *p_link)
+{
+ if (p_link != NULL)
+ {
+ if (p_link->used == true)
+ {
+ memset(p_link, 0, sizeof(T_BLE_LINK));
+ p_link->conn_id = 0xFF;
+ return true;
+ }
+ }
+
+ return false;
+}
+/** @} */
diff --git a/src/sample/ble_audio_ba/link_mgr.h b/src/sample/ble_audio_ba/link_mgr.h
new file mode 100644
index 0000000..4a24e07
--- /dev/null
+++ b/src/sample/ble_audio_ba/link_mgr.h
@@ -0,0 +1,115 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file link_mgr.h
+ * @brief Define struct and functions about link.
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _LINK_MANAGER_H_
+#define _LINK_MANAGER_H_
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "gap_conn_le.h"
+#include "app_msg.h"
+#include "ble_audio_def.h"
+#include "bass_def.h"
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Define device list table size. */
+#define APP_MAX_DEVICE_INFO 30
+
+typedef struct
+{
+ bool used;
+ T_GAP_CONN_STATE state;
+#if BT_GATT_CLIENT_SUPPORT
+ bool mtu_received;
+ bool auth_cmpl;
+#endif
+#if LE_AUDIO_BROADCAST_ASSISTANT_ROLE
+ uint8_t source_id;
+ uint8_t brs_char_num;
+ T_PA_SYNC_STATE pa_sync_state;
+ uint32_t bis_sync_state;
+#endif
+ uint8_t conn_id;
+ uint16_t conn_handle;
+ uint16_t mtu_size;
+ uint8_t remote_bd_type;
+ uint8_t remote_bd[GAP_BD_ADDR_LEN]; /* current remote BD */
+} T_BLE_LINK;
+
+typedef struct
+{
+ T_BLE_LINK le_link[APP_MAX_LINKS];
+} T_APP_DB;
+
+/** @addtogroup BT5_CENTRAL_SCAN_MGR
+ * @{
+ */
+/** @brief Extended Scan Mode List.*/
+typedef enum
+{
+ SCAN_UNTIL_DISABLED, /**< If Duration parameter is zero, continue scanning until scanning is disabled. */
+ SCAN_UNTIL_DURATION_EXPIRED, /**< If Duration parameter is non-zero and Period parameter is zero, continue scanning until duration has expired. */
+} T_EXT_SCAN_MODE;
+
+/**
+ * @brief Device list block definition.
+ */
+typedef struct
+{
+ uint8_t bd_addr[GAP_BD_ADDR_LEN]; /**< remote BD */
+ uint8_t bd_type; /**< remote BD type*/
+ uint8_t adv_sid;
+ uint8_t idx;
+ uint16_t uuid16;
+ uint8_t broadcast_id[BROADCAST_ID_LEN];
+} T_DEV_INFO;
+/** @} */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @brief Device list table, used to save discovered device informations. */
+extern T_DEV_INFO dev_list[APP_MAX_DEVICE_INFO];
+/** @brief The number of device informations saved in dev_list. */
+extern uint8_t dev_list_count;
+extern T_APP_DB app_db;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+* @brief Add device information to device list.
+*
+* @param[in] bd_addr Peer device address.
+* @param[in] bd_type Peer device address type.
+* @retval true Success.
+* @retval false Failed, device list is full.
+*/
+bool link_mgr_add_device(uint8_t *bd_addr, uint8_t bd_type, T_DEV_INFO **pp_dev);
+
+/**
+ * @brief Clear device list.
+ * @retval void
+ */
+void link_mgr_clear_device_list(void);
+
+T_BLE_LINK *ble_link_find_by_conn_id(uint8_t conn_id);
+T_BLE_LINK *ble_link_find_by_conn_handle(uint8_t conn_handle);
+T_BLE_LINK *ble_link_alloc_by_conn_id(uint8_t conn_id);
+T_BLE_LINK *ble_link_find_by_addr(uint8_t *bd_addr, uint8_t bd_type);
+bool ble_link_free(T_BLE_LINK *p_link);
+
+#endif
diff --git a/src/sample/ble_audio_ba/main.c b/src/sample/ble_audio_ba/main.c
new file mode 100644
index 0000000..5ae0a48
--- /dev/null
+++ b/src/sample/ble_audio_ba/main.c
@@ -0,0 +1,162 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file main.c
+ * @brief Source file for BLE BT5 central project, mainly used for initialize modules
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include "os_mem.h"
+#include "os_sched.h"
+#include "trace.h"
+#include "gap.h"
+#include "gap_bond_le.h"
+#include "gap_msg.h"
+#include "gap_ext_scan.h"
+#include "app_task.h"
+#include "ble_audio_ba_app.h"
+#include "link_mgr.h"
+#include "ble_audio_ba_role.h"
+#include "otp_config.h"
+#include "gap_config.h"
+
+/** @defgroup BT5_CENTRAL_DEMO_MAIN BT5 Central Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+#ifdef BT_STACK_CONFIG_ENABLE
+#include "app_section.h"
+APP_FLASH_TEXT_SECTION void bt_stack_config_init(void)
+{
+ gap_config_pa_parameter();
+}
+#endif
+/**
+ * @brief Initialize central, gap bond manager and LE Advertising Extensions
+ related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_AUDIO_BA";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+
+ uint16_t max_data_len_tx_oct = 251;
+ uint16_t max_data_len_tx_time = 0x848;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG | GAP_AUTHEN_BIT_SC_FLAG;
+ T_GAP_IO_CAP auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ //uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+ uint8_t auth_sec_req_enable = true;
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG | GAP_AUTHEN_BIT_SC_FLAG;
+
+ /* LE Advertising Extensions parameters */
+ bool use_extended = true;
+
+ le_set_gap_param(GAP_PARAM_DEFAULT_DATA_LEN_MAX_TX_OCTETS, sizeof(max_data_len_tx_oct),
+ &max_data_len_tx_oct);
+ le_set_gap_param(GAP_PARAM_DEFAULT_DATA_LEN_MAX_TX_TIME, sizeof(max_data_len_tx_time),
+ &max_data_len_tx_time);
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ //gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* Use LE Advertising Extensions */
+ le_set_gap_param(GAP_PARAM_USE_EXTENDED_ADV, sizeof(use_extended), &use_extended);
+
+ /* Register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BT5 BLE Central APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_ble_audio_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group BT5_CENTRAL_DEMO_MAIN */
+
+
diff --git a/src/sample/ble_audio_ba/user_cmd.c b/src/sample/ble_audio_ba/user_cmd.c
new file mode 100644
index 0000000..e73ca29
--- /dev/null
+++ b/src/sample/ble_audio_ba/user_cmd.c
@@ -0,0 +1,454 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file user_cmd.c
+ * @brief User defined test commands.
+ * @details User command interfaces.
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "trace.h"
+#include "gap_bond_le.h"
+#include "gap.h"
+#include "gap_conn_le.h"
+#include "gap_ext_scan.h"
+#include "link_mgr.h"
+#include "user_cmd.h"
+#include "ble_audio_ba_role.h"
+#include "bass_def.h"
+
+/** @defgroup BT5_CENTRAL_CMD BT5 Central User Command
+ * @brief This file handles BT5 Central User Command.
+ * @{
+ */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @brief User command interface data, used to parse the commands from Data UART. */
+T_USER_CMD_IF user_cmd_if;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Show all devices connecting status
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "showcon",
+ "showcon\n\r",
+ "Show all devices connecting status\n\r",
+ cmd_showcon
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_showcon(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id;
+ T_GAP_CONN_INFO conn_info;
+ for (conn_id = 0; conn_id < APP_MAX_LINKS; conn_id++)
+ {
+ if (le_get_conn_info(conn_id, &conn_info))
+ {
+ data_uart_print("ShowCon conn_id %d state 0x%x role %d\r\n", conn_id,
+ conn_info.conn_state, conn_info.role);
+ data_uart_print("RemoteBd = [%02x:%02x:%02x:%02x:%02x:%02x] type = %d\r\n",
+ conn_info.remote_bd[5], conn_info.remote_bd[4],
+ conn_info.remote_bd[3], conn_info.remote_bd[2],
+ conn_info.remote_bd[1], conn_info.remote_bd[0],
+ conn_info.remote_bd_type);
+ }
+ }
+ data_uart_print("active link num %d, idle link num %d\r\n",
+ le_get_active_link_num(), le_get_idle_link_num());
+ return (RESULT_SUCCESS);
+}
+
+/**
+ * @brief Disconnect to remote device
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "disc",
+ "disc [conn_id]\n\r",
+ "Disconnect to remote device\n\r",
+ cmd_disc
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_disc(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAP_CAUSE cause;
+ cause = le_disconnect(conn_id);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/************************** Central only *************************************/
+/**
+ * @brief Show scan dev list
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "showdev",
+ "showdev\n\r",
+ "Show scan dev list\n\r",
+ cmd_showdev
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_showdev(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t i;
+ data_uart_print("dev list\r\n");
+ for (i = 0; i < dev_list_count; i++)
+ {
+ data_uart_print("RemoteBd[%d] = [%02x:%02x:%02x:%02x:%02x:%02x]\r\n",
+ i,
+ dev_list[i].bd_addr[5], dev_list[i].bd_addr[4],
+ dev_list[i].bd_addr[3], dev_list[i].bd_addr[2],
+ dev_list[i].bd_addr[1], dev_list[i].bd_addr[0]);
+ }
+
+ return (RESULT_SUCCESS);
+}
+
+/**
+ * @brief Connect to remote device: use showdev to show idx
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "condev",
+ "condev [idx] [init_phys]\n\r",
+ "Connect to remote device: use showdev to show idx\r\n\
+ [idx]: use cmd showdev to show idx before use this cmd\r\n\
+ [init_phys]: bit 0(LE 1M PHY) and bit 2(LE Coded PHY), at least one bit is set to one\r\n\
+ sample: condev 0 0x100\n\r",
+ cmd_condev
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_condev(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t dev_idx = p_parse_value->dw_param[0];
+ if (dev_idx < dev_list_count)
+ {
+ T_GAP_CAUSE cause;
+ T_GAP_LE_CONN_REQ_PARAM conn_req_param;
+ T_GAP_LOCAL_ADDR_TYPE local_addr_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+ uint8_t init_phys = GAP_PHYS_CONN_INIT_2M_BIT | GAP_PHYS_CONN_INIT_1M_BIT;
+ conn_req_param.scan_interval = 0x10;
+ conn_req_param.scan_window = 0x10;
+ conn_req_param.conn_interval_min = 80;
+ conn_req_param.conn_interval_max = 80;
+ conn_req_param.conn_latency = 0;
+ conn_req_param.supv_tout = 1000;
+ conn_req_param.ce_len_min = 2 * (conn_req_param.conn_interval_min - 1);
+ conn_req_param.ce_len_max = 2 * (conn_req_param.conn_interval_max - 1);
+
+ le_set_conn_param(GAP_CONN_PARAM_1M, &conn_req_param);
+ le_set_conn_param(GAP_CONN_PARAM_2M, &conn_req_param);
+
+ cause = le_connect(init_phys, dev_list[dev_idx].bd_addr,
+ (T_GAP_REMOTE_ADDR_TYPE)dev_list[dev_idx].bd_type,
+ local_addr_type,
+ 1000);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ else
+ {
+ return RESULT_ERR;
+ }
+}
+
+
+/**
+ * @brief Start extended scan
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "escan",
+ "escan [scan_mode] [scan_phys]\n\r",
+ "Start extended scan\r\n\
+ [scan_mode]: 0-(continue scanning until scanning is disabled)\r\n\
+ 1-(scan for the duration within a scan period, and scan periods continue until scanning is disabled)\r\n\
+ 2-(continue scanning until duration has expired)\r\n\
+ [scan_phys]: set scan PHYs to 1(LE 1M PHY), 4(LE Coded PHY) or 5(LE 1M PHY and LE Coded PHY)\r\n\
+ sample: escan 0 4\n\r",
+ cmd_escan
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_escan(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ T_GAP_LOCAL_ADDR_TYPE own_address_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+ T_GAP_SCAN_FILTER_POLICY ext_scan_filter_policy = GAP_SCAN_FILTER_ANY;
+ T_GAP_SCAN_FILTER_DUPLICATE ext_scan_filter_duplicate = GAP_SCAN_FILTER_DUPLICATE_ENABLE;
+ uint16_t ext_scan_duration;
+ uint16_t ext_scan_period;
+ uint8_t scan_phys = GAP_EXT_SCAN_PHYS_1M_BIT;
+ T_EXT_SCAN_MODE scan_mode = (T_EXT_SCAN_MODE)p_parse_value->dw_param[0];
+
+ T_GAP_LE_EXT_SCAN_PARAM extended_scan_param[GAP_EXT_SCAN_MAX_PHYS_NUM];
+ extended_scan_param[0].scan_type = GAP_SCAN_MODE_ACTIVE;
+ extended_scan_param[0].scan_interval = 400;
+ extended_scan_param[0].scan_window = 200;
+
+ extended_scan_param[1].scan_type = GAP_SCAN_MODE_ACTIVE;
+ extended_scan_param[1].scan_interval = 440;
+ extended_scan_param[1].scan_window = 220;
+
+ link_mgr_clear_device_list();
+
+ if (scan_mode == SCAN_UNTIL_DISABLED)
+ {
+ ext_scan_duration = 0;
+ ext_scan_period = 0;
+ }
+ else if (scan_mode == SCAN_UNTIL_DURATION_EXPIRED)
+ {
+ ext_scan_duration = 500;
+ ext_scan_period = 0;
+ }
+
+ if (p_parse_value->param_count > 1)
+ {
+ scan_phys = p_parse_value->dw_param[1];
+ }
+
+ /* Initialize extended scan parameters */
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_LOCAL_ADDR_TYPE, sizeof(own_address_type),
+ &own_address_type);
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_PHYS, sizeof(scan_phys),
+ &scan_phys);
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_DURATION, sizeof(ext_scan_duration),
+ &ext_scan_duration);
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_PERIOD, sizeof(ext_scan_period),
+ &ext_scan_period);
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_FILTER_POLICY, sizeof(ext_scan_filter_policy),
+ &ext_scan_filter_policy);
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_FILTER_DUPLICATES, sizeof(ext_scan_filter_duplicate),
+ &ext_scan_filter_duplicate);
+
+ /* Initialize extended scan PHY parameters */
+ le_ext_scan_set_phy_param(LE_SCAN_PHY_LE_1M, &extended_scan_param[0]);
+ le_ext_scan_set_phy_param(LE_SCAN_PHY_LE_CODED, &extended_scan_param[1]);
+
+ /* Enable extended scan */
+ cause = le_ext_scan_start();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Stop extended scan
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "stopescan",
+ "stopescan\n\r",
+ "Stop extended scan\n\r",
+ cmd_stopescan
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_stopescan(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ cause = le_ext_scan_stop();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+static T_USER_CMD_PARSE_RESULT cmd_bondclear(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ le_bond_clear_all_keys();
+ return (RESULT_SUCCESS);
+}
+
+#if LE_AUDIO_BROADCAST_ASSISTANT_ROLE
+static T_USER_CMD_PARSE_RESULT cmd_pasync(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t dev_idx = p_parse_value->dw_param[0];
+ bool ret = false;
+ if (dev_idx < dev_list_count)
+ {
+ if (dev_list[dev_idx].uuid16 == BROADCAST_AUDIO_ANNOUNCEMENT_SRV_UUID)
+ {
+ ret = app_ble_audio_pa_sync(&dev_list[dev_idx]);
+ }
+ }
+ if (ret)
+ {
+ return RESULT_SUCCESS;
+ }
+ else
+ {
+ return RESULT_ERR;
+ }
+}
+
+static T_USER_CMD_PARSE_RESULT cmd_pasyncstop(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ bool ret = false;
+ ret = app_ble_audio_stop_pa_sync(p_parse_value->dw_param[0]);
+ if (ret)
+ {
+ return RESULT_SUCCESS;
+ }
+ else
+ {
+ return RESULT_ERR;
+ }
+}
+
+static T_USER_CMD_PARSE_RESULT cmd_baadd(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ bool ret = false;
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_BASS_PA_SYNC pa_sync = BASS_PA_SYNC_PAST;
+ uint32_t bis_array = 0x00000001; //or 0xFFFFFFFF
+ T_BLE_LINK *p_link;
+ p_link = ble_link_find_by_conn_id(conn_id);
+ if (p_link)
+ {
+ ret = app_ble_audio_add_source(p_link, pa_sync, bis_array);
+ }
+ if (ret)
+ {
+ return RESULT_SUCCESS;
+ }
+ else
+ {
+ return RESULT_ERR;
+ }
+}
+
+static T_USER_CMD_PARSE_RESULT cmd_bamodify(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ bool ret = false;
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_BASS_PA_SYNC pa_sync = (T_BASS_PA_SYNC)p_parse_value->dw_param[1];
+ uint32_t bis_array = p_parse_value->dw_param[2];
+ T_BLE_LINK *p_link;
+ p_link = ble_link_find_by_conn_id(conn_id);
+ if (p_link)
+ {
+ ret = app_ble_audio_modify_source(p_link, pa_sync, bis_array);
+ }
+ if (ret)
+ {
+ return RESULT_SUCCESS;
+ }
+ else
+ {
+ return RESULT_ERR;
+ }
+}
+#endif
+/** @brief User command table */
+const T_USER_CMD_TABLE_ENTRY user_cmd_table[] =
+{
+ /************************** Common cmd *************************************/
+ {
+ "showcon",
+ "showcon\n\r",
+ "Show all devices connecting status\n\r",
+ cmd_showcon
+ },
+ {
+ "disc",
+ "disc [conn_id]\n\r",
+ "Disconnect to remote device\n\r",
+ cmd_disc
+ },
+ /************************** Central only *************************************/
+ {
+ "showdev",
+ "showdev\n\r",
+ "Show scan dev list\n\r",
+ cmd_showdev
+ },
+ {
+ "condev",
+ "condev [idx] [init_phys]\n\r",
+ "Connect to remote device: use showdev to show idx\r\n\
+ [idx]: use cmd showdev to show idx before use this cmd\r\n\
+ [init_phys]: bit 0(LE 1M PHY) and bit 2(LE Coded PHY), at least one bit is set to one\r\n\
+ sample: condev 0 0x100\n\r",
+ cmd_condev
+ },
+ {
+ "escan",
+ "escan [scan_mode] [scan_phys]\n\r",
+ "Start extended scan\r\n\
+ [scan_mode]: 0-(continue scanning until scanning is disabled)\r\n\
+ 1-(scan for the duration within a scan period, and scan periods continue until scanning is disabled)\r\n\
+ 2-(continue scanning until duration has expired)\r\n\
+ [scan_phys]: set scan PHYs to 1(LE 1M PHY), 4(LE Coded PHY) or 5(LE 1M PHY and LE Coded PHY)\r\n\
+ sample: escan 0 4\n\r",
+ cmd_escan
+ },
+ {
+ "stopescan",
+ "stopescan\n\r",
+ "Stop extended scan\n\r",
+ cmd_stopescan
+ },
+ {
+ "bondclear",
+ "bondclear\n\r",
+ "Clear all bonded devices information\n\r",
+ cmd_bondclear
+ },
+#if LE_AUDIO_BROADCAST_ASSISTANT_ROLE
+ {
+ "pasync",
+ "pasync [idx]\n\r",
+ "PA sync\n\r",
+ cmd_pasync
+ },
+ {
+ "pasyncstop",
+ "pasyncstop \n\r",
+ "Stop PA sync\n\r",
+ cmd_pasyncstop
+ },
+ {
+ "baadd",
+ "baadd \n\r",
+ "Add source\n\r",
+ cmd_baadd
+ },
+ {
+ "bamodify",
+ "bamodify \n\r",
+ "Modify source\n\r",
+ cmd_bamodify
+ },
+#endif
+ /* MUST be at the end: */
+ {
+ 0,
+ 0,
+ 0,
+ 0
+ }
+};
+/** @} */ /* End of group BT5_CENTRAL_CMD */
+
+
diff --git a/src/sample/ble_audio_ba/user_cmd.h b/src/sample/ble_audio_ba/user_cmd.h
new file mode 100644
index 0000000..c1615aa
--- /dev/null
+++ b/src/sample/ble_audio_ba/user_cmd.h
@@ -0,0 +1,31 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file user_cmd.h
+* @brief Define user command.
+* @details
+* @author jane
+* @date 2016-02-18
+* @version v0.1
+*********************************************************************************************************
+*/
+#ifndef _USER_CMD_H_
+#define _USER_CMD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <data_uart.h>
+#include <user_cmd_parse.h>
+
+extern const T_USER_CMD_TABLE_ENTRY user_cmd_table[];
+extern T_USER_CMD_IF user_cmd_if;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/src/sample/ble_broadcaster/app_flags.h b/src/sample/ble_broadcaster/app_flags.h
new file mode 100644
index 0000000..739146d
--- /dev/null
+++ b/src/sample/ble_broadcaster/app_flags.h
@@ -0,0 +1,33 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup BROADCASTER_Config Broadcaster App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 1
+
+/** @} */ /* End of group BROADCASTER_Config */
+
+#endif
diff --git a/src/sample/ble_broadcaster/app_task.c b/src/sample/ble_broadcaster/app_task.c
new file mode 100644
index 0000000..69aeb60
--- /dev/null
+++ b/src/sample/ble_broadcaster/app_task.c
@@ -0,0 +1,103 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <os_msg.h>
+#include <os_task.h>
+#include <gap.h>
+#include <gap_le.h>
+#include <app_msg.h>
+#include <app_task.h>
+#include <broadcaster_app.h>
+
+
+
+/** @defgroup BROADCASTER_APP_TASK Broadcaster App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_main_task(void *p_param);
+
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE,
+ APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group BROADCASTER_APP_TASK */
+
+
diff --git a/src/sample/ble_broadcaster/app_task.h b/src/sample/ble_broadcaster/app_task.h
new file mode 100644
index 0000000..8dfcd2a
--- /dev/null
+++ b/src/sample/ble_broadcaster/app_task.h
@@ -0,0 +1,27 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.h
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+extern void driver_init(void);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/ble_broadcaster/broadcaster_app.c b/src/sample/ble_broadcaster/broadcaster_app.c
new file mode 100644
index 0000000..ffed7bd
--- /dev/null
+++ b/src/sample/ble_broadcaster/broadcaster_app.c
@@ -0,0 +1,138 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file broadcaster_app.c
+ * @brief This file handles BLE broadcaster application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <trace.h>
+#include <string.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_msg.h>
+#include <app_msg.h>
+#include <broadcaster_app.h>
+
+
+
+/** @defgroup BROADCASTER_APP Broadcaster Application
+ * @brief This file handles BLE broadcaster application routines.
+ * @{
+ */
+/** @defgroup BROADCASTER_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+ le_adv_start();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group BROADCASTER_GAP_MSG */
+
+/** @} */ /* End of group BROADCASTER_APP */
+
diff --git a/src/sample/ble_broadcaster/broadcaster_app.h b/src/sample/ble_broadcaster/broadcaster_app.h
new file mode 100644
index 0000000..59e3a79
--- /dev/null
+++ b/src/sample/ble_broadcaster/broadcaster_app.h
@@ -0,0 +1,53 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file broadcaster_app.h
+ * @brief This file handles BLE broadcaster application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+#ifndef _BROADCASTER_APP_H__
+#define _BROADCASTER_APP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <app_msg.h>
+#include <gap_le.h>
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/ble_broadcaster/main.c b/src/sample/ble_broadcaster/main.c
new file mode 100644
index 0000000..f6e28d7
--- /dev/null
+++ b/src/sample/ble_broadcaster/main.c
@@ -0,0 +1,178 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file main.c
+ * @brief Source file for BLE broadcaster project, mainly used for initialize modules
+ * @author jane
+ * @date 2017-06-12
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <os_sched.h>
+#include <string.h>
+#include <trace.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <app_task.h>
+#include <gatt.h>
+#if F_BT_DLPS_EN
+#include <dlps.h>
+#include <rtl876x_io_dlps.h>
+#endif
+
+
+
+/** @defgroup BROADCASTER_DEMO_MAIN Broadcaster Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default Maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+
+ /* Local name */
+ 0x10,
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'B', 'R', 'O', 'A', 'D', 'C', 'A', 'S', 'T', 'E', 'R'
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize broadcaster related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_NONCONN_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MIN;
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void io_dlps_enter_cb(void)
+{
+
+}
+
+void io_dlps_exit_cb(void)
+{
+
+}
+
+void pwr_mgr_init(void)
+{
+#if F_BT_DLPS_EN
+ DLPS_IORegUserDlpsEnterCb(io_dlps_enter_cb);
+ DLPS_IORegUserDlpsExitCb(io_dlps_exit_cb);
+ DLPS_IORegister();
+ lps_mode_set(PLATFORM_DLPS_PFM);
+#endif
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Broadcaster APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ board_init();
+ le_gap_init(0);
+ gap_lib_init();
+ app_le_gap_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group BROADCASTER_DEMO_MAIN */
+
+
diff --git a/src/sample/ble_bt5_central/app_flags.h b/src/sample/ble_bt5_central/app_flags.h
new file mode 100644
index 0000000..dc0d267
--- /dev/null
+++ b/src/sample/ble_bt5_central/app_flags.h
@@ -0,0 +1,36 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup BT5_CENTRAL_Config BT5 Central App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Configure coding scheme of LE Coded PHY: 0 - S = 2, 1 - S = 8 */
+#define LE_CODED_PHY_S8 0
+/** @brief Configure APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Configure APP to recombine advertising data: 0 - Disable recombine advertising data feature, 1 - recombine advertising data */
+#define APP_RECOMBINE_ADV_DATA 0
+
+/** @} */ /* End of group BT5_CENTRAL_Config */
+
+#endif
diff --git a/src/sample/ble_bt5_central/app_task.c b/src/sample/ble_bt5_central/app_task.c
new file mode 100644
index 0000000..b7114cc
--- /dev/null
+++ b/src/sample/ble_bt5_central/app_task.c
@@ -0,0 +1,108 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "os_msg.h"
+#include "os_task.h"
+#include "trace.h"
+#include "gap.h"
+#include "gap_le.h"
+#include "data_uart.h"
+#include "user_cmd_parse.h"
+#include "user_cmd.h"
+#include "app_msg.h"
+#include "bt5_central_app.h"
+#include "app_task.h"
+
+/** @defgroup BT5_CENTRAL_APP_TASK BT5 Central App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_main_task(void *p_param);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE,
+ APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ data_uart_init(evt_queue_handle, io_queue_handle);
+ user_cmd_init(&user_cmd_if, "bt5_central");
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group BT5_CENTRAL_APP_TASK */
+
+
diff --git a/src/sample/ble_bt5_central/app_task.h b/src/sample/ble_bt5_central/app_task.h
new file mode 100644
index 0000000..8dfcd2a
--- /dev/null
+++ b/src/sample/ble_bt5_central/app_task.h
@@ -0,0 +1,27 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.h
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+extern void driver_init(void);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/ble_bt5_central/bt5_central_app.c b/src/sample/ble_bt5_central/bt5_central_app.c
new file mode 100644
index 0000000..53049e4
--- /dev/null
+++ b/src/sample/ble_bt5_central/bt5_central_app.c
@@ -0,0 +1,693 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file central_app.c
+ * @brief This file handles BLE BT5 central application routines.
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include "trace.h"
+#include "gap.h"
+#include "gap_bond_le.h"
+#include "gap_msg.h"
+#include "gap_vendor.h"
+#include "gap_ext_scan.h"
+#include "user_cmd.h"
+#include "user_cmd_parse.h"
+#include "app_msg.h"
+#include "link_mgr.h"
+#include "bt5_central_app.h"
+
+/** @defgroup BT5_CENTRAL_APP BT5 Central Application
+ * @brief This file handles BLE BT5 central application routines.
+ * @{
+ */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup BT5_CENTRAL_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+#if APP_RECOMBINE_ADV_DATA
+uint8_t *p_temp_data = NULL; /**< The location to save ext adv data */
+#endif
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+ uint8_t rx_char;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+ case IO_MSG_TYPE_UART:
+ /* We handle user command informations from Data UART in this branch. */
+ rx_char = (uint8_t)io_msg.subtype;
+ user_cmd_collect(&user_cmd_if, &rx_char, sizeof(rx_char), user_cmd_table);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, scan state %d, cause 0x%x",
+ new_state.gap_init_state,
+ new_state.gap_scan_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ uint8_t bt_addr[6];
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+ gap_get_param(GAP_PARAM_BD_ADDR, bt_addr);
+ data_uart_print("local bd addr: 0x%2x:%2x:%2x:%2x:%2x:%2x\r\n",
+ bt_addr[5],
+ bt_addr[4],
+ bt_addr[3],
+ bt_addr[2],
+ bt_addr[1],
+ bt_addr[0]);
+#if LE_CODED_PHY_S8
+ le_ae_coding_scheme(GAP_AE_CODING_SCHEME_S8);
+#endif
+ }
+ }
+
+ if (gap_dev_state.gap_scan_state != new_state.gap_scan_state)
+ {
+ if (new_state.gap_scan_state == GAP_SCAN_STATE_IDLE)
+ {
+ APP_PRINT_INFO0("GAP scan stop");
+ data_uart_print("GAP scan stop\r\n");
+
+ /* Reset flags of recombining advertising data when stop scanning */
+#if APP_RECOMBINE_ADV_DATA
+ ext_adv_data->flag = false;
+ ext_adv_data->data_len = 0;
+ memset(fail_bd_addr, 0, GAP_BD_ADDR_LEN);
+#endif
+ }
+ else if (new_state.gap_scan_state == GAP_SCAN_STATE_SCANNING)
+ {
+ APP_PRINT_INFO0("GAP scan start");
+ data_uart_print("GAP scan start\r\n");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d, conn_state(%d -> %d), disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+ }
+ data_uart_print("Disconnect conn_id %d, dis_cause 0x%x\r\n", conn_id, disc_cause);
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint8_t tx_phy;
+ uint8_t rx_phy;
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, (uint8_t *)&remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+
+ le_get_conn_param(GAP_PARAM_CONN_TX_PHY_TYPE, &tx_phy, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_RX_PHY_TYPE, &rx_phy, conn_id);
+ data_uart_print("Connected success conn_id %d, tx_phy %d, rx_phy %d\r\n", conn_id, tx_phy, rx_phy);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+ data_uart_print("Pair success\r\n");
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ data_uart_print("Pair failed: cause 0x%x\r\n", cause);
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO4("app_handle_conn_param_update_evt update success:conn_id %d, conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_id, conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR2("app_handle_conn_param_update_evt update failed: conn_id %d, cause 0x%x",
+ conn_id, cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO1("app_handle_conn_param_update_evt update pending: conn_id %d", conn_id);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * sub_type of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO2("GAP_MSG_LE_BOND_PASSKEY_DISPLAY: conn_id %d, passkey %d",
+ conn_id, display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ data_uart_print("GAP_MSG_LE_BOND_PASSKEY_DISPLAY: conn_id %d, passkey %d\r\n",
+ conn_id,
+ display_value);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO2("GAP_MSG_LE_BOND_USER_CONFIRMATION: conn_id %d, passkey %d",
+ conn_id, display_value);
+ data_uart_print("GAP_MSG_LE_BOND_USER_CONFIRMATION: conn_id %d, passkey %d\r\n",
+ conn_id,
+ display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ data_uart_print("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d\r\n", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_OOB_INPUT: conn_id %d", conn_id);
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group BT5_CENTRAL_GAP_MSG */
+
+/** @defgroup BT5_CENTRAL_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+#if APP_RECOMBINE_ADV_DATA
+/**
+ * @brief Check the length of received advertising data.
+ * @param[in] data_len Length of received advertising data.
+ * @retval true: length of received advertising data is less than or equal to APP_MAX_EXT_ADV_TOTAL_LEN.
+ false: length of received advertising data is greater than APP_MAX_EXT_ADV_TOTAL_LEN.
+ */
+bool app_check_adv_data_len(void)
+{
+ if (ext_adv_data->data_len > APP_MAX_EXT_ADV_TOTAL_LEN)
+ {
+ APP_PRINT_ERROR2("app_check_adv_data_len: The length of received advertising data is %d, exceeds APP_MAX_EXT_ADV_TOTAL_LEN %d",
+ ext_adv_data->data_len, APP_MAX_EXT_ADV_TOTAL_LEN);
+ /* Update failed recombination parameters for next recombination. */
+ fail_event_type = ext_adv_data->event_type;
+ memcpy(fail_bd_addr, ext_adv_data->bd_addr, GAP_BD_ADDR_LEN);
+ /* Reset recombination parameters. */
+ ext_adv_data->data_len = 0;
+ ext_adv_data->flag = false;
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+/**
+ * @brief Handle callback GAP_MSG_LE_EXT_ADV_REPORT_INFO to recombine advertising data.
+ * @param[in] event_type Advertisement event type.
+ * @param[in] data_status Data status @ref T_GAP_EXT_ADV_EVT_DATA_STATUS.
+ * @param[in] bd_addr Peer device address.
+ * @param[in] data_len Length of data.
+ * @param[in] p_data Advertising data.
+ * @retval void
+ */
+void app_handle_ext_adv_report(uint16_t event_type, T_GAP_EXT_ADV_EVT_DATA_STATUS data_status,
+ uint8_t *bd_addr, uint8_t data_len, uint8_t *p_data)
+{
+ APP_PRINT_INFO2("app_handle_ext_adv_report: Old ext_adv_data->flag is %d, data status is 0x%x",
+ ext_adv_data->flag, data_status);
+
+ /* Recombine advertising data from one device. */
+ switch (data_status)
+ {
+ case GAP_EXT_ADV_EVT_DATA_STATUS_COMPLETE:
+ /* Advertising data is complete. */
+ if (ext_adv_data->flag)
+ {
+ if ((memcmp(ext_adv_data->bd_addr, bd_addr, GAP_BD_ADDR_LEN) == 0) &&
+ (ext_adv_data->event_type == event_type))
+ {
+ /* The advertising report is the expected report. */
+ if ((memcmp(fail_bd_addr, bd_addr, GAP_BD_ADDR_LEN) == 0) && (fail_event_type == event_type))
+ {
+ APP_PRINT_ERROR2("app_handle_ext_adv_report: The advertising data is destroyed by last failed recombination, last failed bd_addr %s, last failed event type 0x%x",
+ TRACE_BDADDR(fail_bd_addr), fail_event_type);
+ }
+ else
+ {
+ /* Update length of advertising data, and check whether the length exceeds APP_MAX_EXT_ADV_TOTAL_LEN. */
+ ext_adv_data->data_len += data_len;
+ if (!(app_check_adv_data_len()))
+ {
+ return;
+ }
+ memcpy(p_temp_data, p_data, data_len);
+ STREAM_SKIP_LEN(p_temp_data, data_len);
+ APP_PRINT_INFO3("app_handle_ext_adv_report: Data from bd_addr %s is complete, event type is 0x%x, total data length is %d",
+ TRACE_BDADDR(ext_adv_data->bd_addr), ext_adv_data->event_type, ext_adv_data->data_len);
+ if (ext_adv_data->data_len > 5)
+ {
+ APP_PRINT_INFO5("app_handle_ext_adv_report: First five datas are 0x%x, 0x%x, 0x%x, 0x%x, 0x%x",
+ ext_adv_data->p_data[0], ext_adv_data->p_data[1], ext_adv_data->p_data[2], ext_adv_data->p_data[3],
+ ext_adv_data->p_data[4]);
+ APP_PRINT_INFO5("app_handle_ext_adv_report: Last five datas are 0x%x, 0x%x, 0x%x, 0x%x, 0x%x",
+ ext_adv_data->p_data[ext_adv_data->data_len - 5], ext_adv_data->p_data[ext_adv_data->data_len - 4],
+ ext_adv_data->p_data[ext_adv_data->data_len - 3],
+ ext_adv_data->p_data[ext_adv_data->data_len - 2], ext_adv_data->p_data[ext_adv_data->data_len - 1]);
+ }
+ }
+ /* Reset recombination parameters. */
+ memset(fail_bd_addr, 0, GAP_BD_ADDR_LEN);
+ ext_adv_data->data_len = 0;
+ ext_adv_data->flag = false;
+ }
+ else
+ {
+ APP_PRINT_INFO2("app_handle_ext_adv_report: New data which is not saved from bd_addr %s is complete, total data length is %d",
+ TRACE_BDADDR(bd_addr), data_len);
+ }
+ }
+ else
+ {
+ if ((memcmp(fail_bd_addr, bd_addr, GAP_BD_ADDR_LEN) == 0) && (fail_event_type == event_type))
+ {
+ APP_PRINT_ERROR2("app_handle_ext_adv_report: The advertising data is destroyed by last failed recombination, last failed bd_addr %s, last failed event type 0x%x",
+ TRACE_BDADDR(fail_bd_addr), fail_event_type);
+ }
+ else
+ {
+ /* Update recombination parameters, and check whether the length exceeds APP_MAX_EXT_ADV_TOTAL_LEN. */
+ ext_adv_data->flag = true;
+ ext_adv_data->data_len = data_len;
+ memcpy(ext_adv_data->bd_addr, bd_addr, GAP_BD_ADDR_LEN);
+ ext_adv_data->event_type = event_type;
+ if (!(app_check_adv_data_len()))
+ {
+ return;
+ }
+ p_temp_data = ext_adv_data->p_data;
+ memcpy(p_temp_data, p_data, data_len);
+ STREAM_SKIP_LEN(p_temp_data, data_len);
+ APP_PRINT_INFO2("app_handle_ext_adv_report: Data from bd_addr %s is complete, total data length is %d",
+ TRACE_BDADDR(ext_adv_data->bd_addr), data_len);
+ ext_adv_data->data_len = 0;
+ ext_adv_data->flag = false;
+ }
+ memset(fail_bd_addr, 0, GAP_BD_ADDR_LEN);
+ }
+ break;
+
+ case GAP_EXT_ADV_EVT_DATA_STATUS_MORE:
+ /* Advertising data is incomplete, more data to come. */
+ if (ext_adv_data->flag)
+ {
+ if ((memcmp(ext_adv_data->bd_addr, bd_addr, GAP_BD_ADDR_LEN) == 0) &&
+ (ext_adv_data->event_type == event_type))
+ {
+ /* The advertising report is the expected report. */
+ ext_adv_data->data_len += data_len;
+ if (!(app_check_adv_data_len()))
+ {
+ return;
+ }
+ memcpy(p_temp_data, p_data, data_len);
+ STREAM_SKIP_LEN(p_temp_data, data_len);
+ APP_PRINT_INFO2("app_handle_ext_adv_report: Continuation data from bd_addr %s is incomplete, data length is %d, and waiting more data",
+ TRACE_BDADDR(ext_adv_data->bd_addr), ext_adv_data->data_len);
+ }
+ else
+ {
+ APP_PRINT_INFO2("app_handle_ext_adv_report: New data which is not saved from bd_addr %s is incomplete, data length is %d",
+ TRACE_BDADDR(bd_addr), data_len);
+ }
+ }
+ else
+ {
+ /* Update recombination parameters for first fragment, and check whether the length exceeds APP_MAX_EXT_ADV_TOTAL_LEN. */
+ ext_adv_data->flag = true;
+ ext_adv_data->data_len = data_len;
+ memcpy(ext_adv_data->bd_addr, bd_addr, GAP_BD_ADDR_LEN);
+ ext_adv_data->event_type = event_type;
+ if (!(app_check_adv_data_len()))
+ {
+ return;
+ }
+ p_temp_data = ext_adv_data->p_data;
+ memcpy(p_temp_data, p_data, data_len);
+ STREAM_SKIP_LEN(p_temp_data, data_len);
+ APP_PRINT_INFO2("app_handle_ext_adv_report:First Data from bd_addr %s, data length is %d, and waiting more data",
+ TRACE_BDADDR(ext_adv_data->bd_addr), ext_adv_data->data_len);
+ }
+ break;
+
+ case GAP_EXT_ADV_EVT_DATA_STATUS_TRUNCATED:
+ /* Advertising data is incomplete, data truncated, no more to come. */
+ if (ext_adv_data->flag && (memcmp(ext_adv_data->bd_addr, bd_addr, GAP_BD_ADDR_LEN) == 0) &&
+ (ext_adv_data->event_type == event_type))
+ {
+ /* If data is truncated, reset recombination parameters. */
+ ext_adv_data->data_len += data_len;
+ if (!(app_check_adv_data_len()))
+ {
+ return;
+ }
+ memcpy(p_temp_data, p_data, data_len);
+ STREAM_SKIP_LEN(p_temp_data, data_len);
+ APP_PRINT_INFO3("app_handle_ext_adv_report: Continuation data from bd_addr %s is truncated, event type is 0x%x, data length is %d, and no more data to come",
+ TRACE_BDADDR(ext_adv_data->bd_addr), ext_adv_data->event_type, ext_adv_data->data_len);
+ memset(fail_bd_addr, 0, GAP_BD_ADDR_LEN);
+ ext_adv_data->data_len = 0;
+ ext_adv_data->flag = false;
+ }
+ break;
+
+ case GAP_EXT_ADV_EVT_DATA_STATUS_RFU:
+ /* Reserved for future use. */
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_ext_adv_report: unhandled data_status 0x%x", data_status);
+ break;
+ }
+ APP_PRINT_INFO1("app_handle_ext_adv_report: New ext_adv_data->flag is %d", ext_adv_data->flag);
+}
+#endif
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = 0x%x", cb_type);
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_CONN_UPDATE_IND:
+ APP_PRINT_INFO5("GAP_MSG_LE_CONN_UPDATE_IND: conn_id %d, conn_interval_max 0x%x, conn_interval_min 0x%x, conn_latency 0x%x,supervision_timeout 0x%x",
+ p_data->p_le_conn_update_ind->conn_id,
+ p_data->p_le_conn_update_ind->conn_interval_max,
+ p_data->p_le_conn_update_ind->conn_interval_min,
+ p_data->p_le_conn_update_ind->conn_latency,
+ p_data->p_le_conn_update_ind->supervision_timeout);
+ /* if reject the proposed connection parameter from peer device, use APP_RESULT_REJECT. */
+ result = APP_RESULT_ACCEPT;
+ break;
+
+ case GAP_MSG_LE_EXT_ADV_REPORT_INFO:
+ APP_PRINT_INFO6("GAP_MSG_LE_EXT_ADV_REPORT_INFO:connectable %d, scannable %d, direct %d, scan response %d, legacy %d, data status 0x%x",
+ p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_CONNECTABLE_ADV,
+ p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_SCANNABLE_ADV,
+ p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_DIRECTED_ADV,
+ p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_SCAN_RESPONSE,
+ p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_USE_LEGACY_ADV,
+ p_data->p_le_ext_adv_report_info->data_status);
+ APP_PRINT_INFO5("GAP_MSG_LE_EXT_ADV_REPORT_INFO:event_type 0x%x, bd_addr %s, addr_type %d, rssi %d, data_len %d",
+ p_data->p_le_ext_adv_report_info->event_type,
+ TRACE_BDADDR(p_data->p_le_ext_adv_report_info->bd_addr),
+ p_data->p_le_ext_adv_report_info->addr_type,
+ p_data->p_le_ext_adv_report_info->rssi,
+ p_data->p_le_ext_adv_report_info->data_len);
+ APP_PRINT_INFO5("GAP_MSG_LE_EXT_ADV_REPORT_INFO:primary_phy %d, secondary_phy %d, adv_sid %d, tx_power %d, peri_adv_interval %d",
+ p_data->p_le_ext_adv_report_info->primary_phy,
+ p_data->p_le_ext_adv_report_info->secondary_phy,
+ p_data->p_le_ext_adv_report_info->adv_sid,
+ p_data->p_le_ext_adv_report_info->tx_power,
+ p_data->p_le_ext_adv_report_info->peri_adv_interval);
+ APP_PRINT_INFO2("GAP_MSG_LE_EXT_ADV_REPORT_INFO:direct_addr_type 0x%x, direct_addr %s",
+ p_data->p_le_ext_adv_report_info->direct_addr_type,
+ TRACE_BDADDR(p_data->p_le_ext_adv_report_info->direct_addr));
+
+ link_mgr_add_device(p_data->p_le_ext_adv_report_info->bd_addr,
+ p_data->p_le_ext_adv_report_info->addr_type);
+
+#if APP_RECOMBINE_ADV_DATA
+ if (!(p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_USE_LEGACY_ADV))
+ {
+ /* If the advertisement uses extended advertising PDUs, recombine advertising data. */
+ app_handle_ext_adv_report(p_data->p_le_ext_adv_report_info->event_type,
+ p_data->p_le_ext_adv_report_info->data_status, p_data->p_le_ext_adv_report_info->bd_addr,
+ p_data->p_le_ext_adv_report_info->data_len, p_data->p_le_ext_adv_report_info->p_data);
+ }
+#endif
+ break;
+
+ case GAP_MSG_LE_AE_CODING_SCHEME:
+ APP_PRINT_INFO1("GAP_MSG_LE_AE_CODING_SCHEME: cause 0x%x",
+ p_data->le_cause.cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group BT5_CENTRAL_GAP_CALLBACK */
+/** @} */ /* End of group BT5_CENTRAL_APP */
diff --git a/src/sample/ble_bt5_central/bt5_central_app.h b/src/sample/ble_bt5_central/bt5_central_app.h
new file mode 100644
index 0000000..1fcdc83
--- /dev/null
+++ b/src/sample/ble_bt5_central/bt5_central_app.h
@@ -0,0 +1,53 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file central_app.h
+ * @brief This file handles BLE BT5 central application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+#ifndef _CENTRAL_APP_H_
+#define _CENTRAL_APP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "gap_le.h"
+#include "app_msg.h"
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/ble_bt5_central/link_mgr.c b/src/sample/ble_bt5_central/link_mgr.c
new file mode 100644
index 0000000..f5c722e
--- /dev/null
+++ b/src/sample/ble_bt5_central/link_mgr.c
@@ -0,0 +1,88 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file link_mgr.c
+ * @brief Link manager functions.
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include "link_mgr.h"
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @} */
+/** @addtogroup BT5_CENTRAL_SCAN_MGR
+ * @{
+ */
+T_DEV_INFO dev_list[APP_MAX_DEVICE_INFO];
+uint8_t dev_list_count = 0;
+#if APP_RECOMBINE_ADV_DATA
+T_EXT_ADV_DATA *ext_adv_data = NULL;
+uint16_t fail_event_type;
+uint8_t fail_bd_addr[GAP_BD_ADDR_LEN] = {0};
+#endif
+/** @} */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @addtogroup BT5_CENTRAL_SCAN_MGR
+ * @{
+ */
+/**
+ * @brief Add device information to device list.
+ *
+ * @param[in] bd_addr Peer device address.
+ * @param[in] bd_type Peer device address type.
+ * @retval true Success.
+ * @retval false Failed, device list is full.
+ */
+bool link_mgr_add_device(uint8_t *bd_addr, uint8_t bd_type)
+{
+ /* If result count not at max */
+ if (dev_list_count < APP_MAX_DEVICE_INFO)
+ {
+ uint8_t i;
+ /* Check if device is already in device list*/
+ for (i = 0; i < dev_list_count; i++)
+ {
+ if (memcmp(bd_addr, dev_list[i].bd_addr, GAP_BD_ADDR_LEN) == 0)
+ {
+ return true;
+ }
+ }
+
+ /*Add addr to device list list*/
+ memcpy(dev_list[dev_list_count].bd_addr, bd_addr, GAP_BD_ADDR_LEN);
+ dev_list[dev_list_count].bd_type = bd_type;
+
+ /*Increment device list count*/
+ dev_list_count++;
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Clear device list.
+ * @retval void
+ */
+void link_mgr_clear_device_list(void)
+{
+ dev_list_count = 0;
+}
+/** @} */
diff --git a/src/sample/ble_bt5_central/link_mgr.h b/src/sample/ble_bt5_central/link_mgr.h
new file mode 100644
index 0000000..d295455
--- /dev/null
+++ b/src/sample/ble_bt5_central/link_mgr.h
@@ -0,0 +1,104 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file link_mgr.h
+ * @brief Define struct and functions about link.
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _LINK_MANAGER_H_
+#define _LINK_MANAGER_H_
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "gap_conn_le.h"
+#include "app_msg.h"
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Define device list table size. */
+#define APP_MAX_DEVICE_INFO 30
+#if APP_RECOMBINE_ADV_DATA
+/** @brief Maximum advertising data size. */
+#define APP_MAX_EXT_ADV_TOTAL_LEN 1024
+#endif
+
+/** @addtogroup BT5_CENTRAL_SCAN_MGR
+ * @{
+ */
+/** @brief Extended Scan Mode List.*/
+typedef enum
+{
+ SCAN_UNTIL_DISABLED, /**< If Duration parameter is zero, continue scanning until scanning is disabled. */
+ PERIOD_SCAN_UNTIL_DISABLED, /**< If Duration and Period parameters are non-zero, scan for the duration within a scan period, and scan periods continue until scanning is disabled. */
+ SCAN_UNTIL_DURATION_EXPIRED, /**< If Duration parameter is non-zero and Period parameter is zero, continue scanning until duration has expired. */
+} T_EXT_SCAN_MODE;
+
+/**
+ * @brief Device list block definition.
+ */
+typedef struct
+{
+ uint8_t bd_addr[GAP_BD_ADDR_LEN]; /**< remote BD */
+ uint8_t bd_type; /**< remote BD type*/
+} T_DEV_INFO;
+
+#if APP_RECOMBINE_ADV_DATA
+/**
+ * @brief Advertising data.
+ */
+typedef struct
+{
+ uint8_t bd_addr[GAP_BD_ADDR_LEN]; /**< remote BD */
+ bool
+ flag; /**< flag of recombining advertising data, true: recombining, false: waiting extended advertising PDUs */
+ uint16_t event_type; /**< advertising event type */
+ uint16_t data_len; /**< length of recombined advertising data */
+ uint8_t p_data[APP_MAX_EXT_ADV_TOTAL_LEN]; /**< recombined advertising data */
+} T_EXT_ADV_DATA;
+#endif
+/** @} */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @brief Device list table, used to save discovered device informations. */
+extern T_DEV_INFO dev_list[APP_MAX_DEVICE_INFO];
+/** @brief The number of device informations saved in dev_list. */
+extern uint8_t dev_list_count;
+#if APP_RECOMBINE_ADV_DATA
+/** @brief Advertising data, used to save advertising data. */
+extern T_EXT_ADV_DATA *ext_adv_data;
+/** @brief Advertising event type of last failed recombination. */
+extern uint16_t fail_event_type;
+/** @brief Bluetooth device address of last failed recombination. */
+extern uint8_t fail_bd_addr[GAP_BD_ADDR_LEN];
+#endif
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+* @brief Add device information to device list.
+*
+* @param[in] bd_addr Peer device address.
+* @param[in] bd_type Peer device address type.
+* @retval true Success.
+* @retval false Failed, device list is full.
+*/
+bool link_mgr_add_device(uint8_t *bd_addr, uint8_t bd_type);
+
+/**
+ * @brief Clear device list.
+ * @retval void
+ */
+void link_mgr_clear_device_list(void);
+
+#endif
diff --git a/src/sample/ble_bt5_central/main.c b/src/sample/ble_bt5_central/main.c
new file mode 100644
index 0000000..4116a9e
--- /dev/null
+++ b/src/sample/ble_bt5_central/main.c
@@ -0,0 +1,163 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file main.c
+ * @brief Source file for BLE BT5 central project, mainly used for initialize modules
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include "os_mem.h"
+#include "os_sched.h"
+#include "trace.h"
+#include "gap.h"
+#include "gap_bond_le.h"
+#include "gap_msg.h"
+#include "gap_ext_scan.h"
+#include "app_task.h"
+#include "bt5_central_app.h"
+#include "link_mgr.h"
+
+/** @defgroup BT5_CENTRAL_DEMO_MAIN BT5 Central Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief Initialize central, gap bond manager and LE Advertising Extensions
+ related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_BT5_Central";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+
+ uint16_t max_data_len_tx_oct = 251;
+#if LE_CODED_PHY_S8
+ uint16_t max_data_len_tx_time = 17040;
+#else
+ uint16_t max_data_len_tx_time = 4542;
+#endif
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG | GAP_AUTHEN_BIT_SC_FLAG;
+ T_GAP_IO_CAP auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+ uint8_t auth_sec_req_enable = false;
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG | GAP_AUTHEN_BIT_SC_FLAG;
+
+ /* LE Advertising Extensions parameters */
+ bool use_extended = true;
+
+ /* Allocate memory for recombining advertising data */
+#if APP_RECOMBINE_ADV_DATA
+ ext_adv_data = os_mem_zalloc(RAM_TYPE_DATA_ON, sizeof(T_EXT_ADV_DATA));
+ ext_adv_data->flag = false;
+#endif
+
+ le_set_gap_param(GAP_PARAM_DEFAULT_DATA_LEN_MAX_TX_OCTETS, sizeof(max_data_len_tx_oct),
+ &max_data_len_tx_oct);
+ le_set_gap_param(GAP_PARAM_DEFAULT_DATA_LEN_MAX_TX_TIME, sizeof(max_data_len_tx_time),
+ &max_data_len_tx_time);
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* Use LE Advertising Extensions */
+ le_set_gap_param(GAP_PARAM_USE_EXTENDED_ADV, sizeof(use_extended), &use_extended);
+
+ /* Register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BT5 BLE Central APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group BT5_CENTRAL_DEMO_MAIN */
+
+
diff --git a/src/sample/ble_bt5_central/user_cmd.c b/src/sample/ble_bt5_central/user_cmd.c
new file mode 100644
index 0000000..662bf14
--- /dev/null
+++ b/src/sample/ble_bt5_central/user_cmd.c
@@ -0,0 +1,430 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file user_cmd.c
+ * @brief User defined test commands.
+ * @details User command interfaces.
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "trace.h"
+#include "gap_bond_le.h"
+#include "gap.h"
+#include "gap_conn_le.h"
+#include "gap_ext_scan.h"
+#include "link_mgr.h"
+#include "user_cmd.h"
+
+
+/** @defgroup BT5_CENTRAL_CMD BT5 Central User Command
+ * @brief This file handles BT5 Central User Command.
+ * @{
+ */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @brief User command interface data, used to parse the commands from Data UART. */
+T_USER_CMD_IF user_cmd_if;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Show all devices connecting status
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "showcon",
+ "showcon\n\r",
+ "Show all devices connecting status\n\r",
+ cmd_showcon
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_showcon(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id;
+ T_GAP_CONN_INFO conn_info;
+ for (conn_id = 0; conn_id < APP_MAX_LINKS; conn_id++)
+ {
+ if (le_get_conn_info(conn_id, &conn_info))
+ {
+ data_uart_print("ShowCon conn_id %d state 0x%x role %d\r\n", conn_id,
+ conn_info.conn_state, conn_info.role);
+ data_uart_print("RemoteBd = [%02x:%02x:%02x:%02x:%02x:%02x] type = %d\r\n",
+ conn_info.remote_bd[5], conn_info.remote_bd[4],
+ conn_info.remote_bd[3], conn_info.remote_bd[2],
+ conn_info.remote_bd[1], conn_info.remote_bd[0],
+ conn_info.remote_bd_type);
+ }
+ }
+ data_uart_print("active link num %d, idle link num %d\r\n",
+ le_get_active_link_num(), le_get_idle_link_num());
+ return (RESULT_SUCCESS);
+}
+
+/**
+ * @brief Disconnect to remote device
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "disc",
+ "disc [conn_id]\n\r",
+ "Disconnect to remote device\n\r",
+ cmd_disc
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_disc(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAP_CAUSE cause;
+ cause = le_disconnect(conn_id);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/************************** Central only *************************************/
+/**
+ * @brief Show scan dev list
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "showdev",
+ "showdev\n\r",
+ "Show scan dev list\n\r",
+ cmd_showdev
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_showdev(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t i;
+ data_uart_print("dev list\r\n");
+ for (i = 0; i < dev_list_count; i++)
+ {
+ data_uart_print("RemoteBd[%d] = [%02x:%02x:%02x:%02x:%02x:%02x]\r\n",
+ i,
+ dev_list[i].bd_addr[5], dev_list[i].bd_addr[4],
+ dev_list[i].bd_addr[3], dev_list[i].bd_addr[2],
+ dev_list[i].bd_addr[1], dev_list[i].bd_addr[0]);
+ }
+
+ return (RESULT_SUCCESS);
+}
+
+/**
+ * @brief Connect to remote device: use showdev to show idx
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "condev",
+ "condev [idx] [init_phys]\n\r",
+ "Connect to remote device: use showdev to show idx\r\n\
+ [idx]: use cmd showdev to show idx before use this cmd\r\n\
+ [init_phys]: bit 0(LE 1M PHY) and bit 2(LE Coded PHY), at least one bit is set to one\r\n\
+ sample: condev 0 0x100\n\r",
+ cmd_condev
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_condev(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t dev_idx = p_parse_value->dw_param[0];
+ if (dev_idx < dev_list_count)
+ {
+ T_GAP_CAUSE cause;
+ T_GAP_LE_CONN_REQ_PARAM conn_req_param;
+ T_GAP_LOCAL_ADDR_TYPE local_addr_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+ uint8_t init_phys = 0;
+ conn_req_param.scan_interval = 0x10;
+ conn_req_param.scan_window = 0x10;
+ conn_req_param.conn_interval_min = 80;
+ conn_req_param.conn_interval_max = 80;
+ conn_req_param.conn_latency = 0;
+ conn_req_param.supv_tout = 1000;
+ conn_req_param.ce_len_min = 2 * (conn_req_param.conn_interval_min - 1);
+ conn_req_param.ce_len_max = 2 * (conn_req_param.conn_interval_max - 1);
+
+ le_set_conn_param(GAP_CONN_PARAM_1M, &conn_req_param);
+ le_set_conn_param(GAP_CONN_PARAM_2M, &conn_req_param);
+ le_set_conn_param(GAP_CONN_PARAM_CODED, &conn_req_param);
+
+ uint32_t input_phys = p_parse_value->dw_param[1];
+
+ switch (input_phys)
+ {
+ case 0x001:
+ init_phys = GAP_PHYS_CONN_INIT_1M_BIT;
+ break;
+ case 0x011:
+ init_phys = GAP_PHYS_CONN_INIT_2M_BIT | GAP_PHYS_CONN_INIT_1M_BIT;
+ break;
+ case 0x100:
+ init_phys = GAP_PHYS_CONN_INIT_CODED_BIT;
+ break;
+ case 0x101:
+ init_phys = GAP_PHYS_CONN_INIT_CODED_BIT | GAP_PHYS_CONN_INIT_1M_BIT;
+ break;
+ case 0x110:
+ init_phys = GAP_PHYS_CONN_INIT_CODED_BIT | GAP_PHYS_CONN_INIT_2M_BIT;
+ break;
+ case 0x111:
+ init_phys = GAP_PHYS_CONN_INIT_CODED_BIT |
+ GAP_PHYS_CONN_INIT_2M_BIT |
+ GAP_PHYS_CONN_INIT_1M_BIT;
+ break;
+
+ default:
+ break;
+ }
+
+ cause = le_connect(init_phys, dev_list[dev_idx].bd_addr,
+ (T_GAP_REMOTE_ADDR_TYPE)dev_list[dev_idx].bd_type,
+ local_addr_type,
+ 1000);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ else
+ {
+ return RESULT_ERR;
+ }
+}
+
+
+/**
+ * @brief Start extended scan
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "escan",
+ "escan [scan_mode] [scan_phys]\n\r",
+ "Start extended scan\r\n\
+ [scan_mode]: 0-(continue scanning until scanning is disabled)\r\n\
+ 1-(scan for the duration within a scan period, and scan periods continue until scanning is disabled)\r\n\
+ 2-(continue scanning until duration has expired)\r\n\
+ [scan_phys]: set scan PHYs to 1(LE 1M PHY), 4(LE Coded PHY) or 5(LE 1M PHY and LE Coded PHY)\r\n\
+ sample: escan 0 4\n\r",
+ cmd_escan
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_escan(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ T_GAP_LOCAL_ADDR_TYPE own_address_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+ T_GAP_SCAN_FILTER_POLICY ext_scan_filter_policy = GAP_SCAN_FILTER_ANY;
+ T_GAP_SCAN_FILTER_DUPLICATE ext_scan_filter_duplicate = GAP_SCAN_FILTER_DUPLICATE_ENABLE;
+ uint16_t ext_scan_duration;
+ uint16_t ext_scan_period;
+ uint8_t scan_phys = GAP_EXT_SCAN_PHYS_1M_BIT | GAP_EXT_SCAN_PHYS_CODED_BIT;
+ T_EXT_SCAN_MODE scan_mode = (T_EXT_SCAN_MODE)p_parse_value->dw_param[0];
+
+ T_GAP_LE_EXT_SCAN_PARAM extended_scan_param[GAP_EXT_SCAN_MAX_PHYS_NUM];
+ extended_scan_param[0].scan_type = GAP_SCAN_MODE_ACTIVE;
+ extended_scan_param[0].scan_interval = 400;
+ extended_scan_param[0].scan_window = 200;
+
+ extended_scan_param[1].scan_type = GAP_SCAN_MODE_ACTIVE;
+ extended_scan_param[1].scan_interval = 440;
+ extended_scan_param[1].scan_window = 220;
+
+ link_mgr_clear_device_list();
+
+ if (scan_mode == SCAN_UNTIL_DISABLED)
+ {
+ ext_scan_duration = 0;
+ ext_scan_period = 0;
+ }
+ else if (scan_mode == PERIOD_SCAN_UNTIL_DISABLED)
+ {
+ ext_scan_duration = 500;
+ ext_scan_period = 8;
+ ext_scan_filter_duplicate = GAP_SCAN_FILTER_DUPLICATE_ENABLED_RESET_FOR_EACH_PERIOD;
+ }
+ else if (scan_mode == SCAN_UNTIL_DURATION_EXPIRED)
+ {
+ ext_scan_duration = 500;
+ ext_scan_period = 0;
+ }
+
+ if (p_parse_value->param_count > 1)
+ {
+ scan_phys = p_parse_value->dw_param[1];
+ }
+
+ /* Initialize extended scan parameters */
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_LOCAL_ADDR_TYPE, sizeof(own_address_type),
+ &own_address_type);
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_PHYS, sizeof(scan_phys),
+ &scan_phys);
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_DURATION, sizeof(ext_scan_duration),
+ &ext_scan_duration);
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_PERIOD, sizeof(ext_scan_period),
+ &ext_scan_period);
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_FILTER_POLICY, sizeof(ext_scan_filter_policy),
+ &ext_scan_filter_policy);
+ le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_FILTER_DUPLICATES, sizeof(ext_scan_filter_duplicate),
+ &ext_scan_filter_duplicate);
+
+ /* Initialize extended scan PHY parameters */
+ le_ext_scan_set_phy_param(LE_SCAN_PHY_LE_1M, &extended_scan_param[0]);
+ le_ext_scan_set_phy_param(LE_SCAN_PHY_LE_CODED, &extended_scan_param[1]);
+
+ /* Enable extended scan */
+ cause = le_ext_scan_start();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Stop extended scan
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "stopescan",
+ "stopescan\n\r",
+ "Stop extended scan\n\r",
+ cmd_stopescan
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_stopescan(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ cause = le_ext_scan_stop();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+#if APP_RECOMBINE_ADV_DATA
+/**
+ * @brief Recombine advertising data
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "radvdata",
+ "radvdata\n\r",
+ "Recombine advertising data from one device\n\r",
+ cmd_radvdata
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_radvdata(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ ext_adv_data->flag = false;
+ ext_adv_data->data_len = 0;
+ memset(fail_bd_addr, 0, GAP_BD_ADDR_LEN);
+ return (RESULT_SUCCESS);
+}
+
+/**
+ * @brief Stop recombine advertising data
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "sadvdata",
+ "sadvdata\n\r",
+ "Stop recombine advertising data\n\r",
+ cmd_sadvdata
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_sadvdata(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ ext_adv_data->flag = true;
+ ext_adv_data->data_len = 0;
+ memset(ext_adv_data->bd_addr, 0, GAP_BD_ADDR_LEN);
+ return (RESULT_SUCCESS);
+}
+#endif
+
+
+/** @brief User command table */
+const T_USER_CMD_TABLE_ENTRY user_cmd_table[] =
+{
+ /************************** Common cmd *************************************/
+ {
+ "showcon",
+ "showcon\n\r",
+ "Show all devices connecting status\n\r",
+ cmd_showcon
+ },
+ {
+ "disc",
+ "disc [conn_id]\n\r",
+ "Disconnect to remote device\n\r",
+ cmd_disc
+ },
+ /************************** Central only *************************************/
+ {
+ "showdev",
+ "showdev\n\r",
+ "Show scan dev list\n\r",
+ cmd_showdev
+ },
+ {
+ "condev",
+ "condev [idx] [init_phys]\n\r",
+ "Connect to remote device: use showdev to show idx\r\n\
+ [idx]: use cmd showdev to show idx before use this cmd\r\n\
+ [init_phys]: bit 0(LE 1M PHY) and bit 2(LE Coded PHY), at least one bit is set to one\r\n\
+ sample: condev 0 0x100\n\r",
+ cmd_condev
+ },
+ {
+ "escan",
+ "escan [scan_mode] [scan_phys]\n\r",
+ "Start extended scan\r\n\
+ [scan_mode]: 0-(continue scanning until scanning is disabled)\r\n\
+ 1-(scan for the duration within a scan period, and scan periods continue until scanning is disabled)\r\n\
+ 2-(continue scanning until duration has expired)\r\n\
+ [scan_phys]: set scan PHYs to 1(LE 1M PHY), 4(LE Coded PHY) or 5(LE 1M PHY and LE Coded PHY)\r\n\
+ sample: escan 0 4\n\r",
+ cmd_escan
+ },
+ {
+ "stopescan",
+ "stopescan\n\r",
+ "Stop extended scan\n\r",
+ cmd_stopescan
+ },
+#if APP_RECOMBINE_ADV_DATA
+ {
+ "radvdata",
+ "radvdata\n\r",
+ "Recombine advertising data from one device\n\r",
+ cmd_radvdata
+ },
+ {
+ "sadvdata",
+ "sadvdata\n\r",
+ "Stop recombine advertising data\n\r",
+ cmd_sadvdata
+ },
+#endif
+ /* MUST be at the end: */
+ {
+ 0,
+ 0,
+ 0,
+ 0
+ }
+};
+/** @} */ /* End of group BT5_CENTRAL_CMD */
+
+
diff --git a/src/sample/ble_bt5_central/user_cmd.h b/src/sample/ble_bt5_central/user_cmd.h
new file mode 100644
index 0000000..c1615aa
--- /dev/null
+++ b/src/sample/ble_bt5_central/user_cmd.h
@@ -0,0 +1,31 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file user_cmd.h
+* @brief Define user command.
+* @details
+* @author jane
+* @date 2016-02-18
+* @version v0.1
+*********************************************************************************************************
+*/
+#ifndef _USER_CMD_H_
+#define _USER_CMD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <data_uart.h>
+#include <user_cmd_parse.h>
+
+extern const T_USER_CMD_TABLE_ENTRY user_cmd_table[];
+extern T_USER_CMD_IF user_cmd_if;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/src/sample/ble_bt5_peripheral/app_flags.h b/src/sample/ble_bt5_peripheral/app_flags.h
new file mode 100644
index 0000000..951d580
--- /dev/null
+++ b/src/sample/ble_bt5_peripheral/app_flags.h
@@ -0,0 +1,37 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup BT5_PERIPH_Config BT5 Peripheral App Configuration
+ * @brief This file is used to configure app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Configure Advertising PHY */
+#define ADVERTISING_PHY APP_PRIMARY_CODED_SECONDARY_CODED
+/** @brief Configure coding scheme of LE Coded PHY: 0 - S = 2, 1 - S = 8 */
+#define LE_CODED_PHY_S8 0
+/** @brief Configure APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Configure DLPS: 0 - Disable DLPS, 1 - Enable DLPS */
+#define F_BT_DLPS_EN 1
+
+/** @} */ /* End of group BT5_PERIPH_Config */
+#endif
diff --git a/src/sample/ble_bt5_peripheral/app_task.c b/src/sample/ble_bt5_peripheral/app_task.c
new file mode 100644
index 0000000..e79796d
--- /dev/null
+++ b/src/sample/ble_bt5_peripheral/app_task.c
@@ -0,0 +1,100 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "os_msg.h"
+#include "os_task.h"
+#include "gap.h"
+#include "gap_le.h"
+#include "app_msg.h"
+#include "bt5_peripheral_app.h"
+#include "app_task.h"
+
+/** @defgroup BT5_PERIPH_APP_TASK BT5 Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_main_task(void *p_param);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE,
+ APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group BT5_PERIPH_APP_TASK */
+
+
diff --git a/src/sample/ble_bt5_peripheral/app_task.h b/src/sample/ble_bt5_peripheral/app_task.h
new file mode 100644
index 0000000..8dfcd2a
--- /dev/null
+++ b/src/sample/ble_bt5_peripheral/app_task.h
@@ -0,0 +1,27 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.h
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+extern void driver_init(void);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/ble_bt5_peripheral/bt5_peripheral_app.c b/src/sample/ble_bt5_peripheral/bt5_peripheral_app.c
new file mode 100644
index 0000000..4831af2
--- /dev/null
+++ b/src/sample/ble_bt5_peripheral/bt5_peripheral_app.c
@@ -0,0 +1,507 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE BT5 peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include "trace.h"
+#include "gap.h"
+#include "gap_conn_le.h"
+#include "gap_bond_le.h"
+#include "gap_msg.h"
+#include "gap_vendor.h"
+#include "gap_ext_adv.h"
+#include "app_msg.h"
+#include "bt5_peripheral_stack_api.h"
+#include "bt5_peripheral_app.h"
+
+/** @defgroup BT5_PERIPH_APP BT5 Peripheral Application
+ * @brief This file handles BLE BT5 peripheral application routines.
+ * @{
+ */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @defgroup BT5_PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /* Stack ready */
+#if LE_CODED_PHY_S8
+ le_ae_coding_scheme(GAP_AE_CODING_SCHEME_S8);
+#endif
+ /* Set extended advertising related parameters */
+ le_ext_adv_start_setting(adv_handle, EXT_ADV_SET_AUTO);
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+ /* Enable one advertising set */
+ le_ext_adv_enable(1, &adv_handle);
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, (uint8_t *)&remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type, conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void app_handle_ext_adv_state_evt(uint8_t adv_handle, T_GAP_EXT_ADV_STATE new_state, uint16_t cause)
+{
+ for (int i = 0; i < APP_MAX_ADV_SET; i++)
+ {
+ if (ext_adv_state[i].adv_handle == adv_handle)
+ {
+ APP_PRINT_INFO2("app_handle_ext_adv_state_evt: adv_handle = %d oldState = %d",
+ ext_adv_state[i].adv_handle, ext_adv_state[i].ext_adv_state);
+ ext_adv_state[i].ext_adv_state = new_state;
+ break;
+ }
+ }
+ APP_PRINT_INFO2("app_handle_ext_adv_state_evt: adv_handle = %d newState = %d",
+ adv_handle, new_state);
+
+ switch (new_state)
+ {
+ /* device is idle */
+ case EXT_ADV_STATE_IDLE:
+ {
+ APP_PRINT_INFO2("EXT_ADV_STATE_IDLE: adv_handle %d, cause 0x%x", adv_handle, cause);
+ }
+ break;
+
+ /* device is advertising */
+ case EXT_ADV_STATE_ADVERTISING:
+ {
+ APP_PRINT_INFO2("EXT_ADV_STATE_ADVERTISING: adv_handle %d, cause 0x%x", adv_handle, cause);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * sub_type of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_EXT_ADV_STATE_CHANGE:
+ {
+ app_handle_ext_adv_state_evt(gap_msg.msg_data.gap_ext_adv_state_change.adv_handle,
+ (T_GAP_EXT_ADV_STATE)gap_msg.msg_data.gap_ext_adv_state_change.new_state,
+ gap_msg.msg_data.gap_ext_adv_state_change.cause);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group BT5_PERIPH_GAP_MSG */
+
+/** @defgroup BT5_PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ APP_PRINT_TRACE1("app_gap_callback: cb_type = 0x%x", cb_type);
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id, p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation, p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ case GAP_MSG_LE_EXT_ADV_START_SETTING:
+ APP_PRINT_INFO3("GAP_MSG_LE_EXT_ADV_START_SETTING:cause 0x%x, flag 0x%x, adv_handle %d",
+ p_data->p_le_ext_adv_start_setting_rsp->cause, p_data->p_le_ext_adv_start_setting_rsp->flag,
+ p_data->p_le_ext_adv_start_setting_rsp->adv_handle);
+
+ if (p_data->p_le_ext_adv_start_setting_rsp->cause == GAP_CAUSE_SUCCESS)
+ {
+ /* Initialize enable parameters */
+ le_init_ext_adv_enable_params(p_data->p_le_ext_adv_start_setting_rsp->adv_handle);
+ /* Enable one advertising set */
+ le_ext_adv_enable(1, &p_data->p_le_ext_adv_start_setting_rsp->adv_handle);
+ }
+ break;
+
+ case GAP_MSG_LE_EXT_ADV_REMOVE_SET:
+ APP_PRINT_INFO2("GAP_MSG_LE_EXT_ADV_REMOVE_SET:cause 0x%x, adv_handle %d",
+ p_data->p_le_ext_adv_remove_set_rsp->cause, p_data->p_le_ext_adv_remove_set_rsp->adv_handle);
+ if (p_data->p_le_ext_adv_remove_set_rsp->cause == GAP_SUCCESS)
+ {
+ for (int i = 0; i < APP_MAX_ADV_SET; i++)
+ {
+ if (ext_adv_state[i].adv_handle == p_data->p_le_ext_adv_remove_set_rsp->adv_handle)
+ {
+ ext_adv_state[i].adv_handle = APP_IDLE_ADV_SET;
+ ext_adv_state[i].ext_adv_state = EXT_ADV_STATE_IDLE;
+ adv_set_num--;
+ break;
+ }
+ }
+ }
+ break;
+
+ case GAP_MSG_LE_EXT_ADV_CLEAR_SET:
+ APP_PRINT_INFO1("GAP_MSG_LE_EXT_ADV_CLEAR_SET:cause 0x%x",
+ p_data->p_le_ext_adv_clear_set_rsp->cause);
+ if (p_data->p_le_ext_adv_clear_set_rsp->cause == GAP_SUCCESS)
+ {
+ for (int i = 0; i < APP_MAX_ADV_SET; i++)
+ {
+ ext_adv_state[i].adv_handle = APP_IDLE_ADV_SET;
+ ext_adv_state[i].ext_adv_state = EXT_ADV_STATE_IDLE;
+ adv_set_num--;
+ }
+ }
+ break;
+
+ case GAP_MSG_LE_EXT_ADV_ENABLE:
+ APP_PRINT_INFO1("GAP_MSG_LE_EXT_ADV_ENABLE:cause 0x%x", p_data->le_cause.cause);
+ break;
+
+ case GAP_MSG_LE_EXT_ADV_DISABLE:
+ APP_PRINT_INFO1("GAP_MSG_LE_EXT_ADV_DISABLE:cause 0x%x", p_data->le_cause.cause);
+ break;
+
+ case GAP_MSG_LE_SCAN_REQ_RECEIVED_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_SCAN_REQ_RECEIVED_INFO:adv_handle %d, scanner_addr_type 0x%x, scanner_addr %s",
+ p_data->p_le_scan_req_received_info->adv_handle,
+ p_data->p_le_scan_req_received_info->scanner_addr_type,
+ TRACE_BDADDR(p_data->p_le_scan_req_received_info->scanner_addr));
+ break;
+
+ case GAP_MSG_LE_AE_CODING_SCHEME:
+ APP_PRINT_INFO1("GAP_MSG_LE_AE_CODING_SCHEME: cause 0x%x",
+ p_data->le_cause.cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+
+/** @} */ /* End of group BT5_PERIPH_GAP_CALLBACK */
+/** @} */ /* End of group BT5_PERIPH_APP */
diff --git a/src/sample/ble_bt5_peripheral/bt5_peripheral_app.h b/src/sample/ble_bt5_peripheral/bt5_peripheral_app.h
new file mode 100644
index 0000000..97bc5dd
--- /dev/null
+++ b/src/sample/ble_bt5_peripheral/bt5_peripheral_app.h
@@ -0,0 +1,54 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.h
+ * @brief This file handles BLE BT5 peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+#ifndef _BT5_PERIPHERAL_APP__
+#define _BT5_PERIPHERAL_APP__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "gap_le.h"
+#include "app_msg.h"
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/ble_bt5_peripheral/bt5_peripheral_stack_api.c b/src/sample/ble_bt5_peripheral/bt5_peripheral_stack_api.c
new file mode 100644
index 0000000..2ef63e3
--- /dev/null
+++ b/src/sample/ble_bt5_peripheral/bt5_peripheral_stack_api.c
@@ -0,0 +1,428 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file bt5_peripheral_stack_api.c
+ * @brief This file handles BLE BT5 peripheral application routines.
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "gap_ext_adv.h"
+#include "bt5_peripheral_stack_api.h"
+
+/** @defgroup BT5_PERIPH_STACK_API BT5 Peripheral Stack API
+ * @brief This file provides APIs about extended advertising parameters.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval (units of 625us, 320=200ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+/** @brief GAP - Advertisement data (best kept short to conserve power) */
+static const uint8_t ext_adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Local name */
+ 0x13, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'B', 'T', '5', '_', 'P', 'e', 'r', 'i', 'p', 'h', 'e', 'r', 'a', 'l',
+ /* Manufacturer Specific Data */
+ 0xdd, /* length */
+ GAP_ADTYPE_MANUFACTURER_SPECIFIC,
+ 0x5d, 0x00,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
+ 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3,
+ 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5,
+ 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
+ 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9,
+ 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb,
+ 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd
+};
+
+/** @brief GAP - Scan response data (best kept short to conserve power) */
+static const uint8_t ext_scan_rsp_data[] =
+{
+ /* Manufacturer Specific Data */
+ 0xfc, /* length */
+ GAP_ADTYPE_MANUFACTURER_SPECIFIC,
+ 0x5d, 0x00,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
+ 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3,
+ 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5,
+ 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
+ 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9,
+ 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb,
+ 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd,
+ 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf
+};
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @brief Identify advertising set */
+uint8_t adv_handle; /**< Advertising handle*/
+/** @brief Extended advertising state */
+T_APP_EXT_ADV_STATE ext_adv_state[APP_MAX_ADV_SET] = {{APP_IDLE_ADV_SET, EXT_ADV_STATE_IDLE}, {APP_IDLE_ADV_SET, EXT_ADV_STATE_IDLE}, {APP_IDLE_ADV_SET, EXT_ADV_STATE_IDLE}, {APP_IDLE_ADV_SET, EXT_ADV_STATE_IDLE}}; /**< Extended advertising state */
+uint8_t adv_set_num = 0; /**< Advertising set number */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize parameters of non-connectable and non-scannable undirected
+ advertising using extended advertising PDUs
+ * @return void
+ */
+void le_init_ext_adv_params_ext(void)
+{
+ T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY adv_event_prop =
+ LE_EXT_ADV_EXTENDED_ADV_NON_SCAN_NON_CONN_UNDIRECTED;
+ uint32_t primary_adv_interval_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint32_t primary_adv_interval_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+ uint8_t primary_adv_channel_map = GAP_ADVCHAN_ALL;
+ T_GAP_LOCAL_ADDR_TYPE own_address_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+ T_GAP_REMOTE_ADDR_TYPE peer_address_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t p_peer_address[6] = {0};
+ T_GAP_ADV_FILTER_POLICY filter_policy = GAP_ADV_FILTER_ANY;
+ /* Host has no preference. */
+ uint8_t tx_power = 127;
+ T_GAP_PHYS_PRIM_ADV_TYPE primary_adv_phy = GAP_PHYS_PRIM_ADV_1M;
+ uint8_t secondary_adv_max_skip = 0;
+ T_GAP_PHYS_TYPE secondary_adv_phy = GAP_PHYS_2M;
+ uint8_t adv_sid = 0;
+ bool scan_req_notification_enable = false;
+
+ /* Initialize extended advertising parameters */
+ adv_handle = le_ext_adv_create_adv_handle();
+ le_ext_adv_set_adv_param(adv_handle,
+ adv_event_prop,
+ primary_adv_interval_min,
+ primary_adv_interval_max,
+ primary_adv_channel_map,
+ own_address_type,
+ peer_address_type,
+ p_peer_address,
+ filter_policy,
+ tx_power,
+ primary_adv_phy,
+ secondary_adv_max_skip,
+ secondary_adv_phy,
+ adv_sid,
+ scan_req_notification_enable);
+
+ /* Initialize extended advertising data(max size when only one advertising set is using = 1024 bytes)*/
+ le_ext_adv_set_adv_data(adv_handle, sizeof(ext_adv_data), (uint8_t *)ext_adv_data);
+}
+
+/**
+ * @brief Initialize parameters of non-connectable and non-scannable directed advertising using
+ extended advertising PDUs
+ * @return void
+ */
+void le_init_ext_adv_params_ext_directed(void)
+{
+ T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY adv_event_prop =
+ LE_EXT_ADV_EXTENDED_ADV_NON_SCAN_NON_CONN_DIRECTED ;
+ uint32_t primary_adv_interval_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint32_t primary_adv_interval_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+ uint8_t primary_adv_channel_map = GAP_ADVCHAN_ALL;
+ T_GAP_LOCAL_ADDR_TYPE own_address_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+ /* peer_address_type and peer_address shall be valid */
+ T_GAP_REMOTE_ADDR_TYPE peer_address_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t p_peer_address[6] = {0x42, 0x44, 0x33, 0x22, 0x11, 0x00};
+ /* filter_policy shall be ignored */
+ T_GAP_ADV_FILTER_POLICY filter_policy = GAP_ADV_FILTER_ANY;
+ /* Host has no preference. */
+ uint8_t tx_power = 127;
+ T_GAP_PHYS_PRIM_ADV_TYPE primary_adv_phy = GAP_PHYS_PRIM_ADV_1M;
+ uint8_t secondary_adv_max_skip = 0;
+ T_GAP_PHYS_TYPE secondary_adv_phy = GAP_PHYS_2M;
+ uint8_t adv_sid = 0;
+ bool scan_req_notification_enable = false;
+
+ /* Initialize extended advertising parameters */
+ adv_handle = le_ext_adv_create_adv_handle();
+ le_ext_adv_set_adv_param(adv_handle,
+ adv_event_prop,
+ primary_adv_interval_min,
+ primary_adv_interval_max,
+ primary_adv_channel_map,
+ own_address_type,
+ peer_address_type,
+ p_peer_address,
+ filter_policy,
+ tx_power,
+ primary_adv_phy,
+ secondary_adv_max_skip,
+ secondary_adv_phy,
+ adv_sid,
+ scan_req_notification_enable);
+
+ /* Initialize extended advertising data(max size when only one advertising set is using = 1024 bytes)*/
+ le_ext_adv_set_adv_data(adv_handle, sizeof(ext_adv_data), (uint8_t *)ext_adv_data);
+}
+
+/**
+ * @brief Initialize parameters of connectable undirected advertising using
+ extended advertising PDUs
+ * @return void
+ */
+void le_init_ext_adv_params_ext_conn(void)
+{
+ T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY adv_event_prop = LE_EXT_ADV_EXTENDED_ADV_CONN_UNDIRECTED;
+ uint32_t primary_adv_interval_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint32_t primary_adv_interval_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+ uint8_t primary_adv_channel_map = GAP_ADVCHAN_ALL;
+ T_GAP_LOCAL_ADDR_TYPE own_address_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+ T_GAP_REMOTE_ADDR_TYPE peer_address_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t p_peer_address[6] = {0};
+ T_GAP_ADV_FILTER_POLICY filter_policy = GAP_ADV_FILTER_ANY;
+ /* Host has no preference. */
+ uint8_t tx_power = 127;
+ T_GAP_PHYS_PRIM_ADV_TYPE primary_adv_phy;
+ uint8_t secondary_adv_max_skip = 0;
+ T_GAP_PHYS_TYPE secondary_adv_phy;
+ uint8_t adv_sid = 0;
+ bool scan_req_notification_enable = false;
+
+ /* Initialize primary advertisement PHY and secondary advertisement PHY */
+ if (ADVERTISING_PHY == APP_PRIMARY_1M_SECONDARY_2M)
+ {
+ primary_adv_phy = GAP_PHYS_PRIM_ADV_1M;
+ secondary_adv_phy = GAP_PHYS_2M;
+ }
+ else if (ADVERTISING_PHY == APP_PRIMARY_CODED_SECONDARY_CODED)
+ {
+ primary_adv_phy = GAP_PHYS_PRIM_ADV_CODED;
+ secondary_adv_phy = GAP_PHYS_CODED;
+ }
+
+ /* Initialize extended advertising parameters */
+ adv_handle = le_ext_adv_create_adv_handle();
+ if (adv_handle == APP_IDLE_ADV_SET)
+ {
+ return;
+ }
+ if (adv_set_num < APP_MAX_ADV_SET)
+ {
+ ext_adv_state[adv_set_num++].adv_handle = adv_handle;
+ }
+
+ le_ext_adv_set_adv_param(adv_handle,
+ adv_event_prop,
+ primary_adv_interval_min,
+ primary_adv_interval_max,
+ primary_adv_channel_map,
+ own_address_type,
+ peer_address_type,
+ p_peer_address,
+ filter_policy,
+ tx_power,
+ primary_adv_phy,
+ secondary_adv_max_skip,
+ secondary_adv_phy,
+ adv_sid,
+ scan_req_notification_enable);
+
+ /* Initialize extended advertising data(max size = 245 bytes)*/
+ le_ext_adv_set_adv_data(adv_handle, sizeof(ext_adv_data), (uint8_t *)ext_adv_data);
+}
+
+
+/**
+ * @brief Initialize parameters of connectable directed advertising using
+ extended advertising PDUs
+ * @return void
+ */
+void le_init_ext_adv_params_ext_conn_directed(void)
+{
+ T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY adv_event_prop = LE_EXT_ADV_EXTENDED_ADV_CONN_DIRECTED ;
+ uint32_t primary_adv_interval_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint32_t primary_adv_interval_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+ uint8_t primary_adv_channel_map = GAP_ADVCHAN_ALL;
+ T_GAP_LOCAL_ADDR_TYPE own_address_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+ /* peer_address_type and peer_address shall be valid */
+ T_GAP_REMOTE_ADDR_TYPE peer_address_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t p_peer_address[6] = {0x42, 0x44, 0x33, 0x22, 0x11, 0x00};
+ /* filter_policy shall be ignored */
+ T_GAP_ADV_FILTER_POLICY filter_policy = GAP_ADV_FILTER_ANY;
+ /* Host has no preference. */
+ uint8_t tx_power = 127;
+ T_GAP_PHYS_PRIM_ADV_TYPE primary_adv_phy = GAP_PHYS_PRIM_ADV_1M;
+ uint8_t secondary_adv_max_skip = 0;
+ T_GAP_PHYS_TYPE secondary_adv_phy = GAP_PHYS_2M;
+ uint8_t adv_sid = 0;
+ bool scan_req_notification_enable = false;
+
+ /* Initialize extended advertising parameters */
+ adv_handle = le_ext_adv_create_adv_handle();
+ le_ext_adv_set_adv_param(adv_handle,
+ adv_event_prop,
+ primary_adv_interval_min,
+ primary_adv_interval_max,
+ primary_adv_channel_map,
+ own_address_type,
+ peer_address_type,
+ p_peer_address,
+ filter_policy,
+ tx_power,
+ primary_adv_phy,
+ secondary_adv_max_skip,
+ secondary_adv_phy,
+ adv_sid,
+ scan_req_notification_enable);
+
+ /* Initialize extended advertising data(max size = 239 bytes)*/
+ le_ext_adv_set_adv_data(adv_handle, sizeof(ext_adv_data), (uint8_t *)ext_adv_data);
+}
+
+/**
+ * @brief Initialize parameters of scannable undirected advertising using
+ extended advertising PDUs
+ * @return void
+ */
+void le_init_ext_adv_params_ext_scan(void)
+{
+ T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY adv_event_prop = LE_EXT_ADV_EXTENDED_ADV_SCAN_UNDIRECTED;
+ uint32_t primary_adv_interval_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint32_t primary_adv_interval_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+ uint8_t primary_adv_channel_map = GAP_ADVCHAN_ALL;
+ T_GAP_LOCAL_ADDR_TYPE own_address_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+ T_GAP_REMOTE_ADDR_TYPE peer_address_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t p_peer_address[6] = {0};
+ T_GAP_ADV_FILTER_POLICY filter_policy = GAP_ADV_FILTER_ANY;
+ /* Host has no preference. */
+ uint8_t tx_power = 127;
+ T_GAP_PHYS_PRIM_ADV_TYPE primary_adv_phy = GAP_PHYS_PRIM_ADV_1M;
+ uint8_t secondary_adv_max_skip = 0;
+ T_GAP_PHYS_TYPE secondary_adv_phy = GAP_PHYS_2M;
+ uint8_t adv_sid = 0;
+ bool scan_req_notification_enable = false;
+
+ /* Initialize extended advertising parameters */
+ adv_handle = le_ext_adv_create_adv_handle();
+ le_ext_adv_set_adv_param(adv_handle,
+ adv_event_prop,
+ primary_adv_interval_min,
+ primary_adv_interval_max,
+ primary_adv_channel_map,
+ own_address_type,
+ peer_address_type,
+ p_peer_address,
+ filter_policy,
+ tx_power,
+ primary_adv_phy,
+ secondary_adv_max_skip,
+ secondary_adv_phy,
+ adv_sid,
+ scan_req_notification_enable);
+
+ le_ext_adv_set_scan_response_data(adv_handle, sizeof(ext_scan_rsp_data),
+ (uint8_t *)ext_scan_rsp_data);
+}
+
+/**
+ * @brief Initialize parameters of scannable directed advertising using
+ extended advertising PDUs
+ * @return void
+ */
+void le_init_ext_adv_params_ext_scan_directed(void)
+{
+ T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY adv_event_prop = LE_EXT_ADV_EXTENDED_ADV_SCAN_DIRECTED;
+ uint32_t primary_adv_interval_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint32_t primary_adv_interval_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+ uint8_t primary_adv_channel_map = GAP_ADVCHAN_ALL;
+ T_GAP_LOCAL_ADDR_TYPE own_address_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+ /* peer_address_type and peer_address shall be valid */
+ T_GAP_REMOTE_ADDR_TYPE peer_address_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t p_peer_address[6] = {0x42, 0x44, 0x33, 0x22, 0x11, 0x00};
+ /* filter_policy shall be ignored */
+ T_GAP_ADV_FILTER_POLICY filter_policy = GAP_ADV_FILTER_ANY;
+ /* Host has no preference. */
+ uint8_t tx_power = 127;
+ T_GAP_PHYS_PRIM_ADV_TYPE primary_adv_phy = GAP_PHYS_PRIM_ADV_1M;
+ uint8_t secondary_adv_max_skip = 0;
+ T_GAP_PHYS_TYPE secondary_adv_phy = GAP_PHYS_2M;
+ uint8_t adv_sid = 0;
+ bool scan_req_notification_enable = false;
+
+ /* Initialize extended advertising parameters */
+ adv_handle = le_ext_adv_create_adv_handle();
+ le_ext_adv_set_adv_param(adv_handle,
+ adv_event_prop,
+ primary_adv_interval_min,
+ primary_adv_interval_max,
+ primary_adv_channel_map,
+ own_address_type,
+ peer_address_type,
+ p_peer_address,
+ filter_policy,
+ tx_power,
+ primary_adv_phy,
+ secondary_adv_max_skip,
+ secondary_adv_phy,
+ adv_sid,
+ scan_req_notification_enable);
+
+ le_ext_adv_set_scan_response_data(adv_handle, sizeof(ext_scan_rsp_data),
+ (uint8_t *)ext_scan_rsp_data);
+}
+
+/**
+ * @brief Continue advertising until advertising is disabled, or a connection is created.
+ * @param[in] adv_handle Identify advertising set
+ * @return void
+ */
+void le_init_ext_adv_enable_params(uint8_t adv_handle)
+{
+ uint16_t duration = 0;
+ uint8_t max_ext_adv_evt = 0;
+
+ le_ext_adv_set_adv_enable_param(adv_handle, duration, max_ext_adv_evt);
+}
+
+/**
+ * @brief Stop advertising when duration expires.
+ * @param[in] adv_handle Identify advertising set
+ * @return void
+ */
+void le_init_ext_adv_enable_params_duration(uint8_t adv_handle)
+{
+ /* Time = 5000 ms */
+ uint16_t duration = 500;
+ uint8_t max_ext_adv_evt = 0;
+
+ le_ext_adv_set_adv_enable_param(adv_handle, duration, max_ext_adv_evt);
+}
+
+/**
+ * @brief Stop advertising when number of extended advertising events transmitted for
+ the advertising set exceeds maximum number of extended advertising events.
+ * @param[in] adv_handle Identify advertising set
+ * @return void
+ */
+void le_init_ext_adv_enable_params_event(uint8_t adv_handle)
+{
+ uint16_t duration = 0;
+ uint8_t max_ext_adv_evt = 100;
+
+ le_ext_adv_set_adv_enable_param(adv_handle, duration, max_ext_adv_evt);
+}
+
+/** @} */ /* End of group BT5_PERIPH_STACK_API */
diff --git a/src/sample/ble_bt5_peripheral/bt5_peripheral_stack_api.h b/src/sample/ble_bt5_peripheral/bt5_peripheral_stack_api.h
new file mode 100644
index 0000000..05fb394
--- /dev/null
+++ b/src/sample/ble_bt5_peripheral/bt5_peripheral_stack_api.h
@@ -0,0 +1,136 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file bt5_peripheral_stack_api.h
+ * @brief This file handles BLE BT5 peripheral application routines.
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+#ifndef _BT5_PERIPHERAL_STACK_API__
+#define _BT5_PERIPHERAL_STACK_API__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "gap_le.h"
+#include "gap_ext_adv.h"
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Idle advertising set */
+#define APP_IDLE_ADV_SET 0xFF
+/** @brief Maximum advertising set */
+#define APP_MAX_ADV_SET 4
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @brief Advertising PHY types */
+typedef enum
+{
+ APP_PRIMARY_1M = 0x10,//!< Using legacy advertising PDUs, primary advertising PHY is LE 1M PHY, and secondary advertising PHY parameter is invalid.
+ APP_PRIMARY_1M_SECONDARY_1M = 0x11,//!< Using extended advertising PDUs, primary advertising PHY is LE 1M PHY, and secondary advertising PHY is LE 1M PHY.
+ APP_PRIMARY_1M_SECONDARY_2M = 0x12,//!< Using extended advertising PDUs, primary advertising PHY is LE 1M PHY, and secondary advertising PHY is LE 2M PHY.
+ APP_PRIMARY_1M_SECONDARY_CODED = 0x13,//!< Using extended advertising PDUs, primary advertising PHY is LE 1M PHY, and secondary advertising PHY is LE Coded PHY.
+ APP_PRIMARY_CODED_SECONDARY_1M = 0x31,//!< Using extended advertising PDUs, primary advertising PHY is LE Coded PHY, and secondary advertising PHY is LE 1M PHY.
+ APP_PRIMARY_CODED_SECONDARY_2M = 0x32,//!< Using extended advertising PDUs, primary advertising PHY is LE Coded PHY, and secondary advertising PHY is LE 2M PHY.
+ APP_PRIMARY_CODED_SECONDARY_CODED = 0x33,//!< Using extended advertising PDUs, primary advertising PHY is LE Coded PHY, and secondary advertising PHY is LE Coded PHY.
+} T_APP_EXT_ADV_PHYS_TYPE;
+
+typedef struct
+{
+ uint8_t adv_handle;
+ T_GAP_EXT_ADV_STATE ext_adv_state;
+} T_APP_EXT_ADV_STATE;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern uint8_t adv_handle; /**< Advertising handle*/
+extern T_APP_EXT_ADV_STATE ext_adv_state[APP_MAX_ADV_SET]; /**< Extended advertising state */
+extern uint8_t adv_set_num; /**< Advertising set number */
+
+/*============================================================================*
+ * Functisons
+ *============================================================================*/
+/**
+ * @brief Initialize parameters of non-connectable and non-scannable undirected
+ advertising using extended advertising PDUs
+ * @return void
+ */
+void le_init_ext_adv_params_ext(void);
+
+/**
+ * @brief Initialize parameters of non-connectable and non-scannable directed advertising using
+ extended advertising PDUs
+ * @return void
+ */
+void le_init_ext_adv_params_ext_directed(void);
+
+/**
+ * @brief Initialize parameters of connectable undirected advertising using
+ extended advertising PDUs
+ * @return void
+ */
+void le_init_ext_adv_params_ext_conn(void);
+
+/**
+ * @brief Initialize parameters of connectable directed advertising using
+ extended advertising PDUs
+ * @return void
+ */
+void le_init_ext_adv_params_ext_conn_directed(void);
+
+/**
+ * @brief Initialize parameters of scannable undirected advertising using
+ extended advertising PDUs
+ * @return void
+ */
+void le_init_ext_adv_params_ext_scan(void);
+
+/**
+ * @brief Initialize parameters of scannable directed advertising using
+ extended advertising PDUs
+ * @return void
+ */
+void le_init_ext_adv_params_ext_scan_directed(void);
+
+/**
+ * @brief Continue advertising until advertising is disabled, or a connection is created.
+ * @param[in] adv_handle Identify advertising set
+ * @return void
+ */
+void le_init_ext_adv_enable_params(uint8_t adv_handle);
+
+/**
+ * @brief Stop advertising when duration expires.
+ * @param[in] adv_handle Identify advertising set
+ * @return void
+ */
+void le_init_ext_adv_enable_params_duration(uint8_t adv_handle);
+
+/**
+ * @brief Stop advertising when number of extended advertising events transmitted for
+ the advertising set exceeds maximum number of extended advertising events.
+ * @param[in] adv_handle Identify advertising set
+ * @return void
+ */
+void le_init_ext_adv_enable_params_event(uint8_t adv_handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/ble_bt5_peripheral/main.c b/src/sample/ble_bt5_peripheral/main.c
new file mode 100644
index 0000000..a344f81
--- /dev/null
+++ b/src/sample/ble_bt5_peripheral/main.c
@@ -0,0 +1,180 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file main.c
+ * @brief Source file for BLE BT5 peripheral project, mainly used for initialize modules
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include "os_sched.h"
+#if F_BT_DLPS_EN
+#include "dlps.h"
+#include "rtl876x_io_dlps.h"
+#endif
+#include "trace.h"
+#include "gap.h"
+#include "gap_bond_le.h"
+#include "gap_ext_adv.h"
+#include "app_task.h"
+#include "bt5_peripheral_app.h"
+#include "bt5_peripheral_stack_api.h"
+
+/** @defgroup BT5_PERIPH_DEMO_MAIN BT5 Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief Initialize peripheral, gap bond manager and LE Advertising Extensions
+ related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_BT5_Peripheral";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+ uint16_t max_data_len_tx_oct = 251;
+#if LE_CODED_PHY_S8
+ uint16_t max_data_len_tx_time = 17040;
+#else
+ uint16_t max_data_len_tx_time = 4542;
+#endif
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG | GAP_AUTHEN_BIT_SC_FLAG;
+ T_GAP_IO_CAP auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+ uint8_t auth_sec_req_enable = false;
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG | GAP_AUTHEN_BIT_SC_FLAG;
+
+ /* LE Advertising Extensions parameters */
+ bool use_extended = true;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ le_set_gap_param(GAP_PARAM_DEFAULT_DATA_LEN_MAX_TX_OCTETS, sizeof(max_data_len_tx_oct),
+ &max_data_len_tx_oct);
+ le_set_gap_param(GAP_PARAM_DEFAULT_DATA_LEN_MAX_TX_TIME, sizeof(max_data_len_tx_time),
+ &max_data_len_tx_time);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* Use LE Advertising Extensions */
+ le_set_gap_param(GAP_PARAM_USE_EXTENDED_ADV, sizeof(use_extended), &use_extended);
+
+ /* Initialize extended advertising related parameters */
+ le_init_ext_adv_params_ext_conn();
+
+ /* Register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void io_dlps_enter_cb(void)
+{
+
+}
+
+void io_dlps_exit_cb(void)
+{
+
+}
+
+void pwr_mgr_init(void)
+{
+#if F_BT_DLPS_EN
+ DLPS_IORegUserDlpsEnterCb(io_dlps_enter_cb);
+ DLPS_IORegUserDlpsExitCb(io_dlps_exit_cb);
+ DLPS_IORegister();
+ lps_mode_set(PLATFORM_DLPS_PFM);
+#endif
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BT5 BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group BT5_PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/ble_central/app_flags.h b/src/sample/ble_central/app_flags.h
new file mode 100644
index 0000000..a1a5956
--- /dev/null
+++ b/src/sample/ble_central/app_flags.h
@@ -0,0 +1,38 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup CENTRAL_Config Central App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 2
+/** @brief Config GATT services storage: 0-Not save, 1-Save to flash
+ *
+ * If configure to 1, the GATT services discovery results will save to the flash.
+ */
+#define F_BT_GATT_SRV_HANDLE_STORAGE 0
+
+/** @} */ /* End of group CENTRAL_Config */
+
+#endif
diff --git a/src/sample/ble_central/app_task.c b/src/sample/ble_central/app_task.c
new file mode 100644
index 0000000..f8330a2
--- /dev/null
+++ b/src/sample/ble_central/app_task.c
@@ -0,0 +1,109 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <os_msg.h>
+#include <os_task.h>
+#include <gap.h>
+#include <gap_le.h>
+#include <trace.h>
+#include <app_task.h>
+#include <app_msg.h>
+#include <app_task.h>
+#include <central_app.h>
+#include <data_uart.h>
+#include <user_cmd_parse.h>
+#include <user_cmd.h>
+
+/** @defgroup CENTRAL_APP_TASK Central App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_main_task(void *p_param);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE,
+ APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ data_uart_init(evt_queue_handle, io_queue_handle);
+ user_cmd_init(&user_cmd_if, "central");
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group CENTRAL_APP_TASK */
+
+
diff --git a/src/sample/ble_central/app_task.h b/src/sample/ble_central/app_task.h
new file mode 100644
index 0000000..8dfcd2a
--- /dev/null
+++ b/src/sample/ble_central/app_task.h
@@ -0,0 +1,27 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.h
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+extern void driver_init(void);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/ble_central/central_app.c b/src/sample/ble_central/central_app.c
new file mode 100644
index 0000000..7304b17
--- /dev/null
+++ b/src/sample/ble_central/central_app.c
@@ -0,0 +1,928 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file central_app.c
+ * @brief This file handles BLE central application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <app_msg.h>
+#include <string.h>
+#include <trace.h>
+#include <gap_scan.h>
+#include <gap.h>
+#include <gap_msg.h>
+#include <gap_bond_le.h>
+#include <central_app.h>
+#include <link_mgr.h>
+#include <user_cmd.h>
+#include <user_cmd_parse.h>
+#include <simple_ble_client.h>
+#include <gaps_client.h>
+#include <bas_client.h>
+
+
+/** @defgroup CENTRAL_APP Central Application
+ * @brief This file handles BLE central application routines.
+ * @{
+ */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup CENTRAL_CLIIENT_CALLBACK
+ * @{
+ */
+T_CLIENT_ID simple_ble_client_id; /**< Simple ble service client id*/
+T_CLIENT_ID gaps_client_id; /**< gap service client id*/
+T_CLIENT_ID bas_client_id; /**< battery service client id*/
+/** @} */ /* End of group CENTRAL_CLIIENT_CALLBACK */
+
+/** @defgroup CENTRAL_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_discov_services(uint8_t conn_id, bool start);
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+ uint8_t rx_char;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+ case IO_MSG_TYPE_UART:
+ /* We handle user command informations from Data UART in this branch. */
+ rx_char = (uint8_t)io_msg.subtype;
+ user_cmd_collect(&user_cmd_if, &rx_char, sizeof(rx_char), user_cmd_table);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, scan state %d, cause 0x%x",
+ new_state.gap_init_state,
+ new_state.gap_scan_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ uint8_t bt_addr[6];
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+ gap_get_param(GAP_PARAM_BD_ADDR, bt_addr);
+ data_uart_print("local bd addr: 0x%2x:%2x:%2x:%2x:%2x:%2x\r\n",
+ bt_addr[5],
+ bt_addr[4],
+ bt_addr[3],
+ bt_addr[2],
+ bt_addr[1],
+ bt_addr[0]);
+ }
+ }
+
+ if (gap_dev_state.gap_scan_state != new_state.gap_scan_state)
+ {
+ if (new_state.gap_scan_state == GAP_SCAN_STATE_IDLE)
+ {
+ APP_PRINT_INFO0("GAP scan stop");
+ data_uart_print("GAP scan stop\r\n");
+ }
+ else if (new_state.gap_scan_state == GAP_SCAN_STATE_SCANNING)
+ {
+ APP_PRINT_INFO0("GAP scan start");
+ data_uart_print("GAP scan start\r\n");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ if (conn_id >= APP_MAX_LINKS)
+ {
+ return;
+ }
+
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d, conn_state(%d -> %d), disc_cause 0x%x",
+ conn_id, app_link_table[conn_id].conn_state, new_state, disc_cause);
+
+ app_link_table[conn_id].conn_state = new_state;
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR2("app_handle_conn_state_evt: connection lost, conn_id %d, cause 0x%x", conn_id,
+ disc_cause);
+ }
+
+ data_uart_print("Disconnect conn_id %d\r\n", conn_id);
+ memset(&app_link_table[conn_id], 0, sizeof(T_APP_LINK));
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ le_get_conn_addr(conn_id, app_link_table[conn_id].bd_addr,
+ &app_link_table[conn_id].bd_type);
+ data_uart_print("Connected success conn_id %d\r\n", conn_id);
+ }
+ break;
+
+ default:
+ break;
+
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+ data_uart_print("Pair success\r\n");
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ data_uart_print("Pair failed: cause 0x%x\r\n", cause);
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+ app_discov_services(conn_id, true);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO4("app_handle_conn_param_update_evt update success:conn_id %d, conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_id, conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR2("app_handle_conn_param_update_evt update failed: conn_id %d, cause 0x%x",
+ conn_id, cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO1("app_handle_conn_param_update_evt update pending: conn_id %d", conn_id);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO2("GAP_MSG_LE_BOND_PASSKEY_DISPLAY: conn_id %d, passkey %d",
+ conn_id, display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ data_uart_print("GAP_MSG_LE_BOND_PASSKEY_DISPLAY: conn_id %d, passkey %d\r\n",
+ conn_id,
+ display_value);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO2("GAP_MSG_LE_BOND_USER_CONFIRMATION: conn_id %d, passkey %d",
+ conn_id, display_value);
+ data_uart_print("GAP_MSG_LE_BOND_USER_CONFIRMATION: conn_id %d, passkey %d\r\n",
+ conn_id,
+ display_value);
+ //le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ //uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ data_uart_print("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d\r\n", conn_id);
+ //le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_OOB_INPUT: conn_id %d", conn_id);
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group CENTRAL_GAP_MSG */
+
+/** @defgroup CENTRAL_SCAN_MGR Scan Information manager
+ * @brief Scan Information manager
+ * @{
+ */
+/**
+ * @brief Use 16 bit uuid to filter scan information
+ * @param[in] uuid 16 bit UUID.
+ * @param[in] scan_info point to scan information data.
+ * @return filter result
+ * @retval true found success
+ * @retval false not found
+ */
+bool filter_scan_info_by_uuid(uint16_t uuid, T_LE_SCAN_INFO *scan_info)
+{
+ uint8_t buffer[32];
+ uint8_t pos = 0;
+
+ while (pos < scan_info->data_len)
+ {
+ /* Length of the AD structure. */
+ uint8_t length = scan_info->data[pos++];
+ uint8_t type;
+
+ if ((length < 1) || (length >= 31))
+ {
+ return false;
+ }
+
+ if ((length > 0x01) && ((pos + length) <= 31))
+ {
+ /* Copy the AD Data to buffer. */
+ memcpy(buffer, scan_info->data + pos + 1, length - 1);
+ /* AD Type, one octet. */
+ type = scan_info->data[pos];
+
+ switch (type)
+ {
+ case GAP_ADTYPE_16BIT_MORE:
+ case GAP_ADTYPE_16BIT_COMPLETE:
+ case GAP_ADTYPE_SERVICES_LIST_16BIT:
+ {
+ uint16_t *p_uuid = (uint16_t *)(buffer);
+ uint8_t i = length - 1;
+
+ while (i >= 2)
+ {
+ APP_PRINT_INFO2(" AD Data: UUID16 List Item %d = 0x%x", i / 2, *p_uuid);
+ if (*p_uuid == uuid)
+ {
+ return true;
+ }
+ p_uuid++;
+ i -= 2;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ pos += length;
+ }
+ return false;
+}
+/** @} */ /* End of group CENTRAL_SCAN_MGR */
+
+/** @defgroup CENTRAL_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_SCAN_INFO:
+ APP_PRINT_INFO5("GAP_MSG_LE_SCAN_INFO:adv_type 0x%x, bd_addr %s, remote_addr_type %d, rssi %d, data_len %d",
+ p_data->p_le_scan_info->adv_type,
+ TRACE_BDADDR(p_data->p_le_scan_info->bd_addr),
+ p_data->p_le_scan_info->remote_addr_type,
+ p_data->p_le_scan_info->rssi,
+ p_data->p_le_scan_info->data_len);
+ /* User can split interested information by using the function as follow. */
+ if (filter_scan_info_by_uuid(GATT_UUID_SIMPLE_PROFILE, p_data->p_le_scan_info))
+ {
+ APP_PRINT_INFO0("Found simple ble service");
+ link_mgr_add_device(p_data->p_le_scan_info->bd_addr, p_data->p_le_scan_info->remote_addr_type);
+ }
+ /* If you want to parse the scan info, please reference function app_parse_scan_info in observer app. */
+ break;
+
+ case GAP_MSG_LE_CONN_UPDATE_IND:
+ APP_PRINT_INFO5("GAP_MSG_LE_CONN_UPDATE_IND: conn_id %d, conn_interval_max 0x%x, conn_interval_min 0x%x, conn_latency 0x%x,supervision_timeout 0x%x",
+ p_data->p_le_conn_update_ind->conn_id,
+ p_data->p_le_conn_update_ind->conn_interval_max,
+ p_data->p_le_conn_update_ind->conn_interval_min,
+ p_data->p_le_conn_update_ind->conn_latency,
+ p_data->p_le_conn_update_ind->supervision_timeout);
+ /* if reject the proposed connection parameter from peer device, use APP_RESULT_REJECT. */
+ result = APP_RESULT_ACCEPT;
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group CENTRAL_GAP_CALLBACK */
+
+/** @defgroup CENTRAL_SRV_DIS GATT Services discovery and storage
+ * @brief GATT Services discovery and storage
+ * @{
+ */
+/**
+ * @brief Discovery GATT services
+ * @param conn_id connection ID.
+ * @param start first call. true - first call this function after conncection, false - not first
+ * @retval None
+ */
+void app_discov_services(uint8_t conn_id, bool start)
+{
+ if (app_link_table[conn_id].conn_state != GAP_CONN_STATE_CONNECTED)
+ {
+ APP_PRINT_ERROR1("app_discov_services: conn_id %d not connected ", conn_id);
+ return;
+ }
+ if (start)
+ {
+#if F_BT_GATT_SRV_HANDLE_STORAGE
+ bool is_disc = true;
+ T_APP_SRVS_HDL_TABLE app_srvs_table;
+ if (app_load_srvs_hdl_table(&app_srvs_table) == 0)
+ {
+ if ((app_srvs_table.srv_found_flags != 0) &&
+ (app_srvs_table.bd_type == app_link_table[conn_id].bd_type) &&
+ (memcmp(app_srvs_table.bd_addr, app_link_table[conn_id].bd_addr, GAP_BD_ADDR_LEN) == 0))
+ {
+ APP_PRINT_INFO1("app_discov_services: load from flash, srv_found_flags 0x%x",
+ app_srvs_table.srv_found_flags);
+ app_link_table[conn_id].srv_found_flags = app_srvs_table.srv_found_flags;
+ if (app_srvs_table.srv_found_flags & APP_DISCOV_GAPS_FLAG)
+ {
+ gaps_set_hdl_cache(conn_id, app_srvs_table.gaps_hdl_cache, sizeof(uint16_t) * HDL_GAPS_CACHE_LEN);
+ }
+ if (app_srvs_table.srv_found_flags & APP_DISCOV_SIMP_FLAG)
+ {
+ simp_ble_client_set_hdl_cache(conn_id, app_srvs_table.simp_hdl_cache,
+ sizeof(uint16_t) * HDL_SIMBLE_CACHE_LEN);
+ }
+ if (app_srvs_table.srv_found_flags & APP_DISCOV_BAS_FLAG)
+ {
+ bas_set_hdl_cache(conn_id, app_srvs_table.bas_hdl_cache, sizeof(uint16_t) * HDL_BAS_CACHE_LEN);
+ }
+ is_disc = false;
+ }
+ }
+ else
+ {
+ APP_PRINT_ERROR0("app_load_srvs_hdl_table: failed");
+ }
+
+ if (is_disc)
+ {
+ if (gaps_start_discovery(conn_id) == false)
+ {
+ APP_PRINT_ERROR1("app_discov_services: discover gaps failed conn_id %d", conn_id);
+ }
+ }
+#else
+ if (gaps_start_discovery(conn_id) == false)
+ {
+ APP_PRINT_ERROR1("app_discov_services: discover gaps failed conn_id %d", conn_id);
+ }
+#endif
+ return;
+ }
+ if ((app_link_table[conn_id].discovered_flags & APP_DISCOV_SIMP_FLAG) == 0)
+ {
+ if (simp_ble_client_start_discovery(conn_id) == false)
+ {
+ APP_PRINT_ERROR1("app_discov_services: discover simp failed conn_id %d", conn_id);
+ }
+ }
+ else if ((app_link_table[conn_id].discovered_flags & APP_DISCOV_BAS_FLAG) == 0)
+ {
+ if (bas_start_discovery(conn_id) == false)
+ {
+ APP_PRINT_ERROR1("app_discov_services: discover bas failed conn_id %d", conn_id);
+ }
+ }
+ else
+ {
+ APP_PRINT_INFO2("app_discov_services: discover complete, conn_id %d, srv_found_flags 0x%x",
+ conn_id, app_link_table[conn_id].srv_found_flags);
+#if F_BT_GATT_SRV_HANDLE_STORAGE
+ if (app_link_table[conn_id].srv_found_flags != 0)
+ {
+ T_APP_SRVS_HDL_TABLE app_srvs_table;
+ memset(&app_srvs_table, 0, sizeof(T_APP_SRVS_HDL_TABLE));
+ app_srvs_table.bd_type = app_link_table[conn_id].bd_type;
+ app_srvs_table.srv_found_flags = app_link_table[conn_id].srv_found_flags;
+ memcpy(app_srvs_table.bd_addr, app_link_table[conn_id].bd_addr, GAP_BD_ADDR_LEN);
+ gaps_get_hdl_cache(conn_id, app_srvs_table.gaps_hdl_cache, sizeof(uint16_t) * HDL_GAPS_CACHE_LEN);
+ simp_ble_client_get_hdl_cache(conn_id, app_srvs_table.simp_hdl_cache,
+ sizeof(uint16_t) * HDL_SIMBLE_CACHE_LEN);
+ bas_get_hdl_cache(conn_id, app_srvs_table.bas_hdl_cache, sizeof(uint16_t) * HDL_BAS_CACHE_LEN);
+ if (app_save_srvs_hdl_table(&app_srvs_table) != 0)
+ {
+ APP_PRINT_ERROR0("app_save_srvs_hdl_table: failed");
+ }
+ }
+#endif
+ }
+
+ return;
+}
+/** @} */ /* End of group CENTRAL_SRV_DIS */
+
+/** @defgroup CENTRAL_CLIIENT_CALLBACK Profile Client Callback Event Handler
+ * @brief Handle profile client callback event
+ * @{
+ */
+
+/**
+ * @brief Callback will be called when data sent from profile client layer.
+ * @param client_id the ID distinguish which module sent the data.
+ * @param conn_id connection ID.
+ * @param p_data pointer to data.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ APP_PRINT_INFO2("app_client_callback: client_id %d, conn_id %d",
+ client_id, conn_id);
+ if (client_id == gaps_client_id)
+ {
+ T_GAPS_CLIENT_CB_DATA *p_gaps_cb_data = (T_GAPS_CLIENT_CB_DATA *)p_data;
+ switch (p_gaps_cb_data->cb_type)
+ {
+ case GAPS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_gaps_cb_data->cb_content.disc_state)
+ {
+ case DISC_GAPS_DONE:
+ app_link_table[conn_id].discovered_flags |= APP_DISCOV_GAPS_FLAG;
+ app_link_table[conn_id].srv_found_flags |= APP_DISCOV_GAPS_FLAG;
+ app_discov_services(conn_id, false);
+ /* Discovery Simple BLE service procedure successfully done. */
+ APP_PRINT_INFO0("app_client_callback: discover gaps procedure done.");
+ break;
+ case DISC_GAPS_FAILED:
+ app_link_table[conn_id].discovered_flags |= APP_DISCOV_GAPS_FLAG;
+ app_discov_services(conn_id, false);
+ /* Discovery Request failed. */
+ APP_PRINT_INFO0("app_client_callback: discover gaps request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+ case GAPS_CLIENT_CB_TYPE_READ_RESULT:
+ switch (p_gaps_cb_data->cb_content.read_result.type)
+ {
+ case GAPS_READ_DEVICE_NAME:
+ if (p_gaps_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO1("GAPS_READ_DEVICE_NAME: device name %s.",
+ TRACE_STRING(p_gaps_cb_data->cb_content.read_result.data.device_name.p_value));
+ }
+ else
+ {
+ APP_PRINT_INFO1("GAPS_READ_DEVICE_NAME: failded cause 0x%x",
+ p_gaps_cb_data->cb_content.read_result.cause);
+ }
+ break;
+ case GAPS_READ_APPEARANCE:
+ if (p_gaps_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO1("GAPS_READ_APPEARANCE: appearance %d",
+ p_gaps_cb_data->cb_content.read_result.data.appearance);
+ }
+ else
+ {
+ APP_PRINT_INFO1("GAPS_READ_APPEARANCE: failded cause 0x%x",
+ p_gaps_cb_data->cb_content.read_result.cause);
+ }
+ break;
+ case GAPS_READ_CENTRAL_ADDR_RESOLUTION:
+ if (p_gaps_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO1("GAPS_READ_CENTRAL_ADDR_RESOLUTION: central_addr_res %d",
+ p_gaps_cb_data->cb_content.read_result.data.central_addr_res);
+ }
+ else
+ {
+ APP_PRINT_INFO1("GAPS_READ_CENTRAL_ADDR_RESOLUTION: failded cause 0x%x",
+ p_gaps_cb_data->cb_content.read_result.cause);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (client_id == simple_ble_client_id)
+ {
+ T_SIMP_CLIENT_CB_DATA *p_simp_client_cb_data = (T_SIMP_CLIENT_CB_DATA *)p_data;
+ uint16_t value_size;
+ uint8_t *p_value;
+ switch (p_simp_client_cb_data->cb_type)
+ {
+ case SIMP_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_simp_client_cb_data->cb_content.disc_state)
+ {
+ case DISC_SIMP_DONE:
+ /* Discovery Simple BLE service procedure successfully done. */
+ app_link_table[conn_id].discovered_flags |= APP_DISCOV_SIMP_FLAG;
+ app_link_table[conn_id].srv_found_flags |= APP_DISCOV_SIMP_FLAG;
+ app_discov_services(conn_id, false);
+ APP_PRINT_INFO0("app_client_callback: discover simp procedure done.");
+ break;
+ case DISC_SIMP_FAILED:
+ /* Discovery Request failed. */
+ app_link_table[conn_id].discovered_flags |= APP_DISCOV_SIMP_FLAG;
+ app_discov_services(conn_id, false);
+ APP_PRINT_INFO0("app_client_callback: discover simp request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+ case SIMP_CLIENT_CB_TYPE_READ_RESULT:
+ switch (p_simp_client_cb_data->cb_content.read_result.type)
+ {
+ case SIMP_READ_V1_READ:
+ if (p_simp_client_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ value_size = p_simp_client_cb_data->cb_content.read_result.data.v1_read.value_size;
+ p_value = p_simp_client_cb_data->cb_content.read_result.data.v1_read.p_value;
+ APP_PRINT_INFO2("SIMP_READ_V1_READ: value_size %d, value %b",
+ value_size, TRACE_BINARY(value_size, p_value));
+ }
+ else
+ {
+ APP_PRINT_ERROR1("SIMP_READ_V1_READ: failed cause 0x%x",
+ p_simp_client_cb_data->cb_content.read_result.cause);
+ }
+ break;
+ case SIMP_READ_V3_NOTIFY_CCCD:
+ if (p_simp_client_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO1("SIMP_READ_V3_NOTIFY_CCCD: notify %d",
+ p_simp_client_cb_data->cb_content.read_result.data.v3_notify_cccd);
+ }
+ else
+ {
+ APP_PRINT_ERROR1("SIMP_READ_V3_NOTIFY_CCCD: failed cause 0x%x",
+ p_simp_client_cb_data->cb_content.read_result.cause);
+ };
+ break;
+ case SIMP_READ_V4_INDICATE_CCCD:
+ if (p_simp_client_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO1("SIMP_READ_V4_INDICATE_CCCD: indicate %d",
+ p_simp_client_cb_data->cb_content.read_result.data.v4_indicate_cccd);
+ }
+ else
+ {
+ APP_PRINT_ERROR1("SIMP_READ_V4_INDICATE_CCCD: failed cause 0x%x",
+ p_simp_client_cb_data->cb_content.read_result.cause);
+ };
+ break;
+
+ default:
+ break;
+ }
+ break;
+ case SIMP_CLIENT_CB_TYPE_WRITE_RESULT:
+ switch (p_simp_client_cb_data->cb_content.write_result.type)
+ {
+ case SIMP_WRITE_V2_WRITE:
+ APP_PRINT_INFO1("SIMP_WRITE_V2_WRITE: write result 0x%x",
+ p_simp_client_cb_data->cb_content.write_result.cause);
+ break;
+ case SIMP_WRITE_V3_NOTIFY_CCCD:
+ APP_PRINT_INFO1("SIMP_WRITE_V3_NOTIFY_CCCD: write result 0x%x",
+ p_simp_client_cb_data->cb_content.write_result.cause);
+ break;
+ case SIMP_WRITE_V4_INDICATE_CCCD:
+ APP_PRINT_INFO1("SIMP_WRITE_V4_INDICATE_CCCD: write result 0x%x",
+ p_simp_client_cb_data->cb_content.write_result.cause);
+ break;
+ default:
+ break;
+ }
+ break;
+ case SIMP_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_simp_client_cb_data->cb_content.notif_ind_data.type)
+ {
+ case SIMP_V3_NOTIFY:
+ value_size = p_simp_client_cb_data->cb_content.notif_ind_data.data.value_size;
+ p_value = p_simp_client_cb_data->cb_content.notif_ind_data.data.p_value;
+ APP_PRINT_INFO2("SIMP_V3_NOTIFY: value_size %d, value %b",
+ value_size, TRACE_BINARY(value_size, p_value));
+ break;
+ case SIMP_V4_INDICATE:
+ value_size = p_simp_client_cb_data->cb_content.notif_ind_data.data.value_size;
+ p_value = p_simp_client_cb_data->cb_content.notif_ind_data.data.p_value;
+ APP_PRINT_INFO2("SIMP_V4_INDICATE: value_size %d, value %b",
+ value_size, TRACE_BINARY(value_size, p_value));
+ break;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (client_id == bas_client_id)
+ {
+ T_BAS_CLIENT_CB_DATA *p_bas_cb_data = (T_BAS_CLIENT_CB_DATA *)p_data;
+ switch (p_bas_cb_data->cb_type)
+ {
+ case BAS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_bas_cb_data->cb_content.disc_state)
+ {
+ case DISC_BAS_DONE:
+ /* Discovery BAS procedure successfully done. */
+ app_link_table[conn_id].discovered_flags |= APP_DISCOV_BAS_FLAG;
+ app_link_table[conn_id].srv_found_flags |= APP_DISCOV_BAS_FLAG;
+ app_discov_services(conn_id, false);
+ APP_PRINT_INFO0("app_client_callback: discover bas procedure done");
+ break;
+ case DISC_BAS_FAILED:
+ /* Discovery Request failed. */
+ app_link_table[conn_id].discovered_flags |= APP_DISCOV_BAS_FLAG;
+ app_discov_services(conn_id, false);
+ APP_PRINT_INFO0("app_client_callback: discover bas procedure failed");
+ break;
+ default:
+ break;
+ }
+ break;
+ case BAS_CLIENT_CB_TYPE_READ_RESULT:
+ switch (p_bas_cb_data->cb_content.read_result.type)
+ {
+ case BAS_READ_BATTERY_LEVEL:
+ if (p_bas_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery level %d",
+ p_bas_cb_data->cb_content.read_result.data.battery_level);
+ }
+ else
+ {
+ APP_PRINT_ERROR1("BAS_READ_BATTERY_LEVEL: failed cause 0x%x",
+ p_bas_cb_data->cb_content.read_result.cause);
+ }
+ break;
+ case BAS_READ_NOTIFY:
+ if (p_bas_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO1("BAS_READ_NOTIFY: notify %d",
+ p_bas_cb_data->cb_content.read_result.data.notify);
+ }
+ else
+ {
+ APP_PRINT_ERROR1("BAS_READ_NOTIFY: failed cause 0x%x",
+ p_bas_cb_data->cb_content.read_result.cause);
+ };
+ break;
+
+ default:
+ break;
+ }
+ break;
+ case BAS_CLIENT_CB_TYPE_WRITE_RESULT:
+ switch (p_bas_cb_data->cb_content.write_result.type)
+ {
+ case BAS_WRITE_NOTIFY_ENABLE:
+ APP_PRINT_INFO1("BAS_WRITE_NOTIFY_ENABLE: write result 0x%x",
+ p_bas_cb_data->cb_content.write_result.cause);
+ break;
+ case BAS_WRITE_NOTIFY_DISABLE:
+ APP_PRINT_INFO1("BAS_WRITE_NOTIFY_DISABLE: write result 0x%x",
+ p_bas_cb_data->cb_content.write_result.cause);
+ break;
+ default:
+ break;
+ }
+ break;
+ case BAS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ APP_PRINT_INFO1("BAS_CLIENT_CB_TYPE_NOTIF_IND_RESULT: battery level %d",
+ p_bas_cb_data->cb_content.notify_data.battery_level);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return result;
+}
+
+/** @} */ /* End of group CENTRAL_CLIENT_CALLBACK */
+/** @} */ /* End of group CENTRAL_APP */
+
diff --git a/src/sample/ble_central/central_app.h b/src/sample/ble_central/central_app.h
new file mode 100644
index 0000000..c7f8779
--- /dev/null
+++ b/src/sample/ble_central/central_app.h
@@ -0,0 +1,69 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file central_app.h
+ * @brief This file handles BLE central application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+#ifndef _CENTRAL_APP_H_
+#define _CENTRAL_APP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_client.h>
+#include <app_msg.h>
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_CLIENT_ID gaps_client_id; /**< Simple ble service client id*/
+extern T_CLIENT_ID simple_ble_client_id; /**< gap service client id*/
+extern T_CLIENT_ID bas_client_id; /**< battery service client id*/
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+/**
+ * @brief Callback will be called when data sent from profile client layer.
+ * @param client_id the ID distinguish which module sent the data.
+ * @param conn_id connection ID.
+ * @param p_data pointer to data.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/ble_central/link_mgr.c b/src/sample/ble_central/link_mgr.c
new file mode 100644
index 0000000..a097eab
--- /dev/null
+++ b/src/sample/ble_central/link_mgr.c
@@ -0,0 +1,139 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file link_mgr.c
+ * @brief Multilink manager functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <link_mgr.h>
+#include <trace.h>
+#include <string.h>
+#include <ftl.h>
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+#if F_BT_GATT_SRV_HANDLE_STORAGE
+/** @addtogroup CENTRAL_SRV_DIS
+ * @{
+ */
+/** @brief Define start offset of the falsh to save GATT Server information. */
+#define APP_SRVS_HDL_TABLE_FLASH_OFFSET 0
+/** @} */ /* End of group CENTRAL_SRV_DIS */
+
+#endif
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup CENTRAL_GAP_MSG
+ * @{
+ */
+T_APP_LINK app_link_table[APP_MAX_LINKS];
+/** @} */
+/** @addtogroup CENTRAL_SCAN_MGR
+ * @{
+ */
+T_DEV_INFO dev_list[APP_MAX_DEVICE_INFO];
+uint8_t dev_list_count = 0;
+/** @} */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @addtogroup CENTRAL_SCAN_MGR
+ * @{
+ */
+/**
+ * @brief Add device information to device list.
+ *
+ * @param[in] bd_addr Peer device address.
+ * @param[in] bd_type Peer device address type.
+ * @retval true Success.
+ * @retval false Failed, device list is full.
+ */
+bool link_mgr_add_device(uint8_t *bd_addr, uint8_t bd_type)
+{
+ /* If result count not at max */
+ if (dev_list_count < APP_MAX_DEVICE_INFO)
+ {
+ uint8_t i;
+ /* Check if device is already in device list*/
+ for (i = 0; i < dev_list_count; i++)
+ {
+ if (memcmp(bd_addr, dev_list[i].bd_addr, GAP_BD_ADDR_LEN) == 0)
+ {
+ return true;
+ }
+ }
+
+ /*Add addr to device list list*/
+ memcpy(dev_list[dev_list_count].bd_addr, bd_addr, GAP_BD_ADDR_LEN);
+ dev_list[dev_list_count].bd_type = bd_type;
+
+ /*Increment device list count*/
+ dev_list_count++;
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Clear device list.
+ * @retval None.
+ */
+void link_mgr_clear_device_list(void)
+{
+ dev_list_count = 0;
+}
+/** @} */
+
+#if F_BT_GATT_SRV_HANDLE_STORAGE
+/** @addtogroup CENTRAL_SRV_DIS
+ * @{
+ */
+/**
+ * @brief Save GATT Services information into flash.
+ * @param[in] p_info the buffer for saving data
+ * @retval 0 Save success.
+ * @retval other Failed.
+ */
+uint32_t app_save_srvs_hdl_table(T_APP_SRVS_HDL_TABLE *p_info)
+{
+ APP_PRINT_INFO0("app_save_srvs_hdl_table");
+ return ftl_save(p_info, APP_SRVS_HDL_TABLE_FLASH_OFFSET, sizeof(T_APP_SRVS_HDL_TABLE));
+}
+
+/**
+ * @brief load GATT Services information from storage
+ * @param[out] p_info the buffer for loading data
+ * @retval 0 Load success.
+ * @retval other Failed.
+ */
+uint32_t app_load_srvs_hdl_table(T_APP_SRVS_HDL_TABLE *p_info)
+{
+ uint32_t result;
+ result = ftl_load(p_info, APP_SRVS_HDL_TABLE_FLASH_OFFSET,
+ sizeof(T_APP_SRVS_HDL_TABLE));
+ APP_PRINT_INFO1("app_load_srvs_hdl_table: result %u", result);
+ if (result)
+ {
+ memset(p_info, 0, sizeof(T_APP_SRVS_HDL_TABLE));
+ }
+ return result;
+}
+/** @} */
+#endif
diff --git a/src/sample/ble_central/link_mgr.h b/src/sample/ble_central/link_mgr.h
new file mode 100644
index 0000000..dbe8717
--- /dev/null
+++ b/src/sample/ble_central/link_mgr.h
@@ -0,0 +1,111 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file link_mgr.h
+ * @brief Define multilink manager struct and functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _LINK_MANAGER_H_
+#define _LINK_MANAGER_H_
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <app_msg.h>
+#include <gap_conn_le.h>
+#include <profile_client.h>
+#include <simple_ble_client.h>
+#include <gaps_client.h>
+#include <bas_client.h>
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Define device list table size. */
+#define APP_MAX_DEVICE_INFO 6
+
+/** @addtogroup CENTRAL_SRV_DIS
+ * @{
+ */
+/** @defgroup APP_DISCOV_BITS Application discover services Bits
+* @{
+ */
+#define APP_DISCOV_GAPS_FLAG 0x01
+#define APP_DISCOV_SIMP_FLAG 0x02
+#define APP_DISCOV_BAS_FLAG 0x04
+/**
+ * @}
+ */
+/** @} */
+/** @addtogroup CENTRAL_GAP_MSG
+ * @{
+ */
+/**
+ * @brief Application Link control block definition.
+ */
+typedef struct
+{
+ T_GAP_CONN_STATE conn_state; /**< Connection state. */
+ uint8_t discovered_flags; /**< discovered flags. */
+ uint8_t srv_found_flags; /**< service founded flogs. */
+ T_GAP_REMOTE_ADDR_TYPE bd_type; /**< remote BD type*/
+ uint8_t bd_addr[GAP_BD_ADDR_LEN]; /**< remote BD */
+} T_APP_LINK;
+/** @} */ /* End of group CENTRAL_GAP_MSG */
+/** @addtogroup CENTRAL_SCAN_MGR
+ * @{
+ */
+/**
+ * @brief Device list block definition.
+ */
+typedef struct
+{
+ uint8_t bd_addr[GAP_BD_ADDR_LEN]; /**< remote BD */
+ uint8_t bd_type; /**< remote BD type*/
+} T_DEV_INFO;
+/** @} */
+#if F_BT_GATT_SRV_HANDLE_STORAGE
+/** @addtogroup CENTRAL_SRV_DIS
+ * @{
+ */
+/** @brief App link table */
+typedef struct
+{
+ uint8_t srv_found_flags;
+ uint8_t bd_type; /**< remote BD type*/
+ uint8_t bd_addr[GAP_BD_ADDR_LEN]; /**< remote BD */
+ uint32_t reserved;
+ uint16_t gaps_hdl_cache[HDL_GAPS_CACHE_LEN];
+ uint16_t simp_hdl_cache[HDL_SIMBLE_CACHE_LEN];
+ uint16_t bas_hdl_cache[HDL_BAS_CACHE_LEN];
+} T_APP_SRVS_HDL_TABLE;
+/** @} */
+#endif
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @brief App link table */
+extern T_APP_LINK app_link_table[APP_MAX_LINKS];
+/** @brief Device list table, used to save discovered device informations. */
+extern T_DEV_INFO dev_list[APP_MAX_DEVICE_INFO];
+/** @brief The number of device informations saved in dev_list. */
+extern uint8_t dev_list_count;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+bool link_mgr_add_device(uint8_t *bd_addr, uint8_t bd_type);
+void link_mgr_clear_device_list(void);
+#if F_BT_GATT_SRV_HANDLE_STORAGE
+uint32_t app_save_srvs_hdl_table(T_APP_SRVS_HDL_TABLE *p_info);
+uint32_t app_load_srvs_hdl_table(T_APP_SRVS_HDL_TABLE *p_info);
+#endif
+
+#endif
diff --git a/src/sample/ble_central/main.c b/src/sample/ble_central/main.c
new file mode 100644
index 0000000..48a1563
--- /dev/null
+++ b/src/sample/ble_central/main.c
@@ -0,0 +1,178 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file main.c
+ * @brief Source file for BLE central project, mainly used for initialize modules
+ * @author jane
+ * @date 2017-06-12
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <os_sched.h>
+#include <string.h>
+#include <app_task.h>
+#include <trace.h>
+#include <gap.h>
+#include <gap_bond_le.h>
+#include <gap_scan.h>
+#include <profile_client.h>
+#include <gap_msg.h>
+#include <central_app.h>
+#include <simple_ble_client.h>
+#include <gaps_client.h>
+#include <bas_client.h>
+#include <link_mgr.h>
+
+/** @defgroup CENTRAL_DEMO_MAIN Central Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default scan interval (units of 0.625ms, 0x10=2.5ms) */
+#define DEFAULT_SCAN_INTERVAL 0x10
+/** @brief Default scan window (units of 0.625ms, 0x10=2.5ms) */
+#define DEFAULT_SCAN_WINDOW 0x10
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize central and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_CENTRAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+
+ /* Scan parameters */
+ uint8_t scan_mode = GAP_SCAN_MODE_ACTIVE;
+ uint16_t scan_interval = DEFAULT_SCAN_INTERVAL;
+ uint16_t scan_window = DEFAULT_SCAN_WINDOW;
+ uint8_t scan_filter_policy = GAP_SCAN_FILTER_ANY;
+ uint8_t scan_filter_duplicate = GAP_SCAN_FILTER_DUPLICATE_ENABLE;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+ uint8_t auth_sec_req_enable = false;
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+
+ /* Set scan parameters */
+ le_scan_set_param(GAP_PARAM_SCAN_MODE, sizeof(scan_mode), &scan_mode);
+ le_scan_set_param(GAP_PARAM_SCAN_INTERVAL, sizeof(scan_interval), &scan_interval);
+ le_scan_set_param(GAP_PARAM_SCAN_WINDOW, sizeof(scan_window), &scan_window);
+ le_scan_set_param(GAP_PARAM_SCAN_FILTER_POLICY, sizeof(scan_filter_policy),
+ &scan_filter_policy);
+ le_scan_set_param(GAP_PARAM_SCAN_FILTER_DUPLICATES, sizeof(scan_filter_duplicate),
+ &scan_filter_duplicate);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT clients and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ client_init(3);
+ gaps_client_id = gaps_add_client(app_client_callback, APP_MAX_LINKS);
+ simple_ble_client_id = simp_ble_add_client(app_client_callback, APP_MAX_LINKS);
+ bas_client_id = bas_add_client(app_client_callback, APP_MAX_LINKS);
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Central APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group CENTRAL_DEMO_MAIN */
+
+
diff --git a/src/sample/ble_central/user_cmd.c b/src/sample/ble_central/user_cmd.c
new file mode 100644
index 0000000..ca26481
--- /dev/null
+++ b/src/sample/ble_central/user_cmd.c
@@ -0,0 +1,1066 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file user_cmd.c
+ * @brief User defined test commands.
+ * @details User command interfaces.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <trace.h>
+#include <profile_client.h>
+#include <gap_bond_le.h>
+#include <gap_scan.h>
+#include <user_cmd.h>
+#include <gap.h>
+#include <gap_conn_le.h>
+#include <link_mgr.h>
+#include <simple_ble_client.h>
+#include <gaps_client.h>
+#include <bas_client.h>
+
+
+/** @defgroup CENTRAL_CMD Central User Command
+ * @brief This file handles Central User Command.
+ * @{
+ */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @brief User command interface data, used to parse the commands from Data UART. */
+T_USER_CMD_IF user_cmd_if;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Show all devices connecting status
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "showcon",
+ "showcon\n\r",
+ "Show all devices connecting status\n\r",
+ cmd_showcon
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_showcon(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id;
+ T_GAP_CONN_INFO conn_info;
+ for (conn_id = 0; conn_id < APP_MAX_LINKS; conn_id++)
+ {
+ if (le_get_conn_info(conn_id, &conn_info))
+ {
+ data_uart_print("ShowCon conn_id %d state 0x%x role %d\r\n", conn_id,
+ conn_info.conn_state, conn_info.role);
+ data_uart_print("RemoteBd = [%02x:%02x:%02x:%02x:%02x:%02x] type = %d\r\n",
+ conn_info.remote_bd[5], conn_info.remote_bd[4],
+ conn_info.remote_bd[3], conn_info.remote_bd[2],
+ conn_info.remote_bd[1], conn_info.remote_bd[0],
+ conn_info.remote_bd_type);
+ }
+ }
+ data_uart_print("active link num %d, idle link num %d\r\n",
+ le_get_active_link_num(), le_get_idle_link_num());
+ return (RESULT_SUCCESS);
+}
+
+/**
+ * @brief LE connection param update request
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "conupdreq",
+ "conupdreq [conn_id] [interval_min] [interval_max] [latency] [supervision_timeout]\n\r",
+ "LE connection param update request\r\n\
+ sample: conupdreq 0 0x30 0x40 0 500\n\r",
+ cmd_conupdreq
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_conupdreq(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t conn_interval_min = p_parse_value->dw_param[1];
+ uint16_t conn_interval_max = p_parse_value->dw_param[2];
+ uint16_t conn_latency = p_parse_value->dw_param[3];
+ uint16_t supervision_timeout = p_parse_value->dw_param[4];
+
+
+ cause = le_update_conn_param(conn_id,
+ conn_interval_min,
+ conn_interval_max,
+ conn_latency,
+ supervision_timeout,
+ 2 * (conn_interval_min - 1),
+ 2 * (conn_interval_max - 1)
+ );
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Disconnect to remote device
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "disc",
+ "disc [conn_id]\n\r",
+ "Disconnect to remote device\n\r",
+ cmd_disc
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_disc(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAP_CAUSE cause;
+ cause = le_disconnect(conn_id);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Config authentication mode
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "authmode",
+ "authmode [auth_flags] [io_cap] [sec_enable] [oob_enable]\n\r",
+ "Config authentication mode\r\n\
+ [auth_flags]:authentication req bit field: bit0-(bonding), bit2-(MITM), bit3-(SC)\r\n\
+ [io_cap]:set io Capabilities: 0-(display only), 1-(display yes/no), 2-(keyboard noly), 3-(no IO), 4-(keyboard display)\r\n\
+ [sec_enable]:Start smp pairing procedure when connected: 0-(disable), 1-(enable)\r\n\
+ [oob_enable]:Enable oob flag: 0-(disable), 1-(enable)\r\n\
+ sample: authmode 0x5 2 1 0\n\r",
+ cmd_authmode
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_authmode(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t oob_enable = false;
+ uint8_t auth_sec_req_enable = false;
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ if (p_parse_value->param_count > 0)
+ {
+ auth_flags = p_parse_value->dw_param[0];
+ auth_sec_req_flags = p_parse_value->dw_param[0];
+ }
+ if (p_parse_value->param_count > 1)
+ {
+ auth_io_cap = p_parse_value->dw_param[1];
+ }
+ if (p_parse_value->param_count > 2)
+ {
+ auth_sec_req_enable = p_parse_value->dw_param[2];
+ }
+ if (p_parse_value->param_count > 3)
+ {
+ oob_enable = p_parse_value->dw_param[3];
+ }
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(uint8_t), &oob_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+ cause = gap_set_pairable_mode();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Send authentication request
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "sauth",
+ "sauth [conn_id]\n\r",
+ "Send authentication request\n\r",
+ cmd_sauth
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_sauth(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAP_CAUSE cause;
+ cause = le_bond_pair(conn_id);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Send user confirmation when show GAP_MSG_LE_BOND_USER_CONFIRMATION
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "userconf",
+ "userconf [conn_id] [conf]\n\r",
+ "Send user confirmation when show GAP_MSG_LE_BOND_USER_CONFIRMATION\r\n\
+ [conf]: 0-(Reject), 1-(Accept)\r\n\
+ sample: userconf 0 1\n\r",
+ cmd_userconf
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_userconf(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAP_CFM_CAUSE confirm = GAP_CFM_CAUSE_ACCEPT;
+ T_GAP_CAUSE cause;
+ if (p_parse_value->dw_param[1] == 0)
+ {
+ confirm = GAP_CFM_CAUSE_REJECT;
+ }
+ cause = le_bond_user_confirm(conn_id, confirm);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Input passkey when show GAP_MSG_LE_BOND_PASSKEY_INPUT
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "authkey",
+ "authkey [conn_id] [passkey]\n\r",
+ "Input passkey when show GAP_MSG_LE_BOND_PASSKEY_INPUT\r\n\
+ [passkey]: 0 - 999999\r\n\
+ sample: authkey 0 123456\n\r",
+ cmd_authkey
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_authkey(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint32_t passcode = p_parse_value->dw_param[1];
+ T_GAP_CAUSE cause;
+ T_GAP_CFM_CAUSE confirm = GAP_CFM_CAUSE_ACCEPT;
+ if (passcode > GAP_PASSCODE_MAX)
+ {
+ confirm = GAP_CFM_CAUSE_REJECT;
+ }
+ cause = le_bond_passkey_input_confirm(conn_id, passcode,
+ confirm);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Clear all bonded devices information
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "bondclear",
+ "bondclear\n\r",
+ "Clear all bonded devices information\n\r",
+ cmd_bondclear
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_bondclear(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ le_bond_clear_all_keys();
+ return (RESULT_SUCCESS);
+}
+
+/**
+ * @brief Get all Bonded devices information
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "bondinfo",
+ "bondinfo\n\r",
+ "Get all Bonded devices information\n\r",
+ cmd_bondinfo
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_bondinfo(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t i;
+ T_LE_KEY_ENTRY *p_entry;
+ uint8_t bond_storage_num = le_get_max_le_paired_device_num();
+ for (i = 0; i < bond_storage_num; i++)
+ {
+ p_entry = le_find_key_entry_by_idx(i);
+ if (p_entry != NULL)
+ {
+ data_uart_print("bond_dev[%d]: bd 0x%02x%02x%02x%02x%02x%02x, addr_type %d, flags 0x%x\r\n",
+ p_entry->idx,
+ p_entry->remote_bd.addr[5],
+ p_entry->remote_bd.addr[4],
+ p_entry->remote_bd.addr[3],
+ p_entry->remote_bd.addr[2],
+ p_entry->remote_bd.addr[1],
+ p_entry->remote_bd.addr[0],
+ p_entry->remote_bd.remote_bd_type,
+ p_entry->flags);
+ }
+ }
+
+ return (RESULT_SUCCESS);
+}
+/************************** Central only *************************************/
+/**
+ * @brief Start scan
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "scan",
+ "scan [filter_policy] [filter_duplicate]\n\r",
+ "Start scan\r\n\
+ [filter_policy]: 0-(any), 1-(whitelist), 2-(any RPA), 3-(whitelist RPA) \r\n\
+ [filter_duplicate]: 0-(disable), 1-(enable) \n\r",
+ cmd_scan
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_scan(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ uint8_t scan_filter_policy = GAP_SCAN_FILTER_ANY;
+ uint8_t scan_filter_duplicate = GAP_SCAN_FILTER_DUPLICATE_ENABLE;
+
+ if (p_parse_value->param_count > 0)
+ {
+ scan_filter_policy = p_parse_value->dw_param[0];
+ }
+ if (p_parse_value->param_count > 1)
+ {
+ scan_filter_duplicate = p_parse_value->dw_param[1];
+ }
+
+ link_mgr_clear_device_list();
+ le_scan_set_param(GAP_PARAM_SCAN_FILTER_POLICY, sizeof(scan_filter_policy),
+ &scan_filter_policy);
+ le_scan_set_param(GAP_PARAM_SCAN_FILTER_DUPLICATES, sizeof(scan_filter_duplicate),
+ &scan_filter_duplicate);
+ cause = le_scan_start();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Stop scan
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "stopscan",
+ "stopscan\n\r",
+ "Stop scan\n\r",
+ cmd_stopscan
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_stopscan(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ cause = le_scan_stop();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Show scan dev list: filter simple ble service
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "showdev",
+ "showdev\n\r",
+ "Show scan dev list: filter simple ble service\n\r",
+ cmd_showdev
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_showdev(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t i;
+ data_uart_print("Advertising and Scan response: filter uuid = 0xA00A dev list\r\n");
+ for (i = 0; i < dev_list_count; i++)
+ {
+ data_uart_print("RemoteBd[%d] = [%02x:%02x:%02x:%02x:%02x:%02x] type = %d\r\n",
+ i,
+ dev_list[i].bd_addr[5], dev_list[i].bd_addr[4],
+ dev_list[i].bd_addr[3], dev_list[i].bd_addr[2],
+ dev_list[i].bd_addr[1], dev_list[i].bd_addr[0],
+ dev_list[i].bd_type);
+ if (dev_list[i].bd_type == GAP_REMOTE_ADDR_LE_RANDOM)
+ {
+ uint8_t addr = dev_list[i].bd_addr[5] & RANDOM_ADDR_MASK;
+ if (addr == RANDOM_ADDR_MASK_STATIC)
+ {
+ data_uart_print("Static Random Addr\r\n");
+ }
+ else if (addr == RANDOM_ADDR_MASK_RESOLVABLE)
+ {
+ data_uart_print("Resolv Random Addr\r\n");
+ }
+ else if (addr == RANDOM_ADDR_MASK_NON_RESOLVABLE)
+ {
+ data_uart_print("Non-resolv Random Addr\r\n");
+ }
+ else
+ {
+ data_uart_print("Unknown Random Addr\r\n");
+ }
+ }
+ }
+
+ return (RESULT_SUCCESS);
+}
+
+/**
+ * @brief Connect to remote device: use address
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "con",
+ "con [BD0] [BD1] [BD2] [BD3] [BD4] [BD5] [addr_type]\n\r",
+ "Connect to remote device: use address\r\n\
+ [BD0] [BD1] [BD2] [BD3] [BD4] [BD5]: remote device address\r\n\
+ [addr_type]: 0-(public), 1-(random)\r\n\
+ sample: con x11 x22 x33 x44 x55 x66 0 \n\r",
+ cmd_con
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_con(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ uint8_t addr[6] = {0};
+ uint8_t addr_len;
+ uint8_t addr_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ T_GAP_LE_CONN_REQ_PARAM conn_req_param;
+
+ conn_req_param.scan_interval = 0x10;
+ conn_req_param.scan_window = 0x10;
+ conn_req_param.conn_interval_min = 80;
+ conn_req_param.conn_interval_max = 80;
+ conn_req_param.conn_latency = 0;
+ conn_req_param.supv_tout = 1000;
+ conn_req_param.ce_len_min = 2 * (conn_req_param.conn_interval_min - 1);
+ conn_req_param.ce_len_max = 2 * (conn_req_param.conn_interval_max - 1);
+ le_set_conn_param(GAP_CONN_PARAM_1M, &conn_req_param);
+
+ for (addr_len = 0; addr_len < GAP_BD_ADDR_LEN; addr_len++)
+ {
+ addr[addr_len] = p_parse_value->dw_param[GAP_BD_ADDR_LEN - addr_len - 1];
+ }
+ if (p_parse_value->param_count >= 7)
+ {
+ addr_type = p_parse_value->dw_param[6];
+ }
+
+ cause = le_connect(GAP_PHYS_CONN_INIT_1M_BIT, addr, (T_GAP_REMOTE_ADDR_TYPE)addr_type,
+ GAP_LOCAL_ADDR_LE_PUBLIC,
+ 1000);
+
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Connect to remote device: use showdev to show idx
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "condev",
+ "condev [idx]\n\r",
+ "Connect to remote device: use showdev to show idx\r\n\
+ [idx]: use cmd showdev to show idx before use this cmd\r\n\
+ sample: condev 0\n\r",
+ cmd_condev
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_condev(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t dev_idx = p_parse_value->dw_param[0];
+ if (dev_idx < dev_list_count)
+ {
+ T_GAP_CAUSE cause;
+ T_GAP_LE_CONN_REQ_PARAM conn_req_param;
+
+ conn_req_param.scan_interval = 0x10;
+ conn_req_param.scan_window = 0x10;
+ conn_req_param.conn_interval_min = 80;
+ conn_req_param.conn_interval_max = 80;
+ conn_req_param.conn_latency = 0;
+ conn_req_param.supv_tout = 1000;
+ conn_req_param.ce_len_min = 2 * (conn_req_param.conn_interval_min - 1);
+ conn_req_param.ce_len_max = 2 * (conn_req_param.conn_interval_max - 1);
+ le_set_conn_param(GAP_CONN_PARAM_1M, &conn_req_param);
+ cause = le_connect(GAP_PHYS_CONN_INIT_1M_BIT,
+ dev_list[dev_idx].bd_addr,
+ (T_GAP_REMOTE_ADDR_TYPE)dev_list[dev_idx].bd_type,
+ GAP_LOCAL_ADDR_LE_PUBLIC,
+ 1000);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ else
+ {
+ return RESULT_ERR;
+ }
+}
+/************************** GATT client *************************************/
+/**
+ * @brief Read GAP service characteristic value
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "gapread",
+ "gapread [conn_id] [type]\n\r",
+ "Read GAP service characteristic value\r\n\
+ [type]: 0-(read device name), 1-(read appearance)\r\n\
+ simple: gapread 0 0\n\r",
+ cmd_gapread
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_gapread(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAPS_READ_TYPE read_type = (T_GAPS_READ_TYPE)p_parse_value->dw_param[1];
+ bool ret = gaps_read(conn_id, read_type);
+ if (ret)
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief List GAP service handle cache
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "gaphdl",
+ "gaphdl [conn_id]\n\r",
+ "List GAP service handle cache\n\r",
+ cmd_gaphdl
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_gaphdl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t hdl_cache[HDL_GAPS_CACHE_LEN];
+ uint8_t hdl_idx;
+ bool ret = gaps_get_hdl_cache(conn_id, hdl_cache,
+ sizeof(uint16_t) * HDL_GAPS_CACHE_LEN);
+
+ if (ret)
+ {
+ for (hdl_idx = HDL_GAPS_SRV_START; hdl_idx < HDL_GAPS_CACHE_LEN; hdl_idx++)
+ {
+ data_uart_print("-->Index %d -- Handle 0x%x\r\n", hdl_idx, hdl_cache[hdl_idx]);
+ }
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief Read simple ble service characteristic and descriptor value
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "simpread",
+ "simpread [conn_id] [type] [pattern]\n\r",
+ "Read simple ble service characteristic and descriptor value\r\n\
+ [type]: 0-(read v1), 1-(v3 cccd), 2-(v4 cccd)\r\n\
+ [pattern]: 0-(read by handle), 1-(read by uuid)\r\n\
+ sample: simpread 0 1 0 \n\r",
+ cmd_simpread
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_simpread(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ /* Indicate which char to be read. */
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret;
+ T_SIMP_READ_TYPE read_type = (T_SIMP_READ_TYPE)p_parse_value->dw_param[1];
+ /* Read by handle or UUID, 1--by UUID, 0--by handle. */
+ uint8_t read_pattern = (uint8_t)p_parse_value->dw_param[2];
+
+ if (read_pattern)
+ {
+ ret = simp_ble_client_read_by_uuid(conn_id, read_type);
+ }
+ else
+ {
+ ret = simp_ble_client_read_by_handle(conn_id, read_type);
+ }
+
+ if (ret)
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief Config simple ble service client characteristic configuration descriptor value
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "simpcccd",
+ "simpcccd [conn_id] [type] [enable]\n\r",
+ "Config simple ble service client characteristic configuration descriptor value\r\n\
+ [type]: 0-(v3 notify), 1-(v4 indication)\r\n\
+ [enable]: 0-(disable), 1-(enable) \r\n\
+ sample: simpcccd 0 1 1\n\r",
+ cmd_simpcccd
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_simpcccd(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ /* Indicate which char CCCD command. */
+ bool ret = false;
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint8_t type = p_parse_value->dw_param[1];
+ /* Enable or disable, 1--enable, 0--disable. */
+ bool cccd_data = (bool)p_parse_value->dw_param[2];
+
+ switch (type)
+ {
+ case 0:/* V3 Notify char notif enable/disable. */
+ ret = simp_ble_client_set_v3_notify(conn_id, cccd_data);
+ break;
+ case 1:/* V4 Indicate char indicate enable/disable. */
+ ret = simp_ble_client_set_v4_ind(conn_id, cccd_data);
+ break;
+ default:
+ break;
+ }
+
+ if (ret)
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief Write simple ble service V2 characteristic value
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "simpwritev2",
+ "simpwritev2 [conn_id] [type] [len]\n\r",
+ "Write simple ble service V2 characteristic value\r\n\
+ [type]: 1-(write request), 2-(write command) \r\n\
+ [len]: type=1 len range:0-270, type=2 len range: 0-(mtu-3)\r\n\
+ sample: simpwritev2 0 1 10\n\r",
+ cmd_simpwritev2
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_simpwritev2(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GATT_WRITE_TYPE write_type = (T_GATT_WRITE_TYPE)p_parse_value->dw_param[1];
+ uint8_t data[270];
+ uint16_t length = 270;
+ uint16_t i;
+ for (i = 0; i < 270; i++)
+ {
+ data[i] = i;
+ }
+ if (write_type > GATT_WRITE_TYPE_CMD)
+ {
+ return (RESULT_ERR);
+ }
+ if (p_parse_value->param_count > 2)
+ {
+ length = p_parse_value->dw_param[2];
+ if (length > 270)
+ {
+ length = 270;
+ }
+ }
+ if (simp_ble_client_write_v2_char(conn_id, length, data, write_type))
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief List simple ble service handle cache
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "simphdl",
+ "simphdl [conn_id]\n\r",
+ "List simple ble service handle cache\n\r",
+ cmd_simphdl
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_simphdl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t hdl_cache[HDL_SIMBLE_CACHE_LEN];
+ uint8_t hdl_idx;
+ bool ret = simp_ble_client_get_hdl_cache(conn_id, hdl_cache,
+ sizeof(uint16_t) * HDL_SIMBLE_CACHE_LEN);
+
+ if (ret)
+ {
+ for (hdl_idx = HDL_SIMBLE_SRV_START; hdl_idx < HDL_SIMBLE_CACHE_LEN; hdl_idx++)
+ {
+ data_uart_print("-->Index %d -- Handle 0x%x\r\n", hdl_idx, hdl_cache[hdl_idx]);
+ }
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief Read battery service characteristic and descriptor value
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "basread",
+ "basread [conn_id] [type]\n\r",
+ "Read battery service characteristic and descriptor value\r\n\
+ [type]: 0-(battery level value), 1-(battery cccd)\r\n\
+ sample: basread 0 1 \n\r",
+ cmd_basread
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_basread(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = false;
+ if (p_parse_value->dw_param[1] == 0)
+ {
+ ret = bas_read_battery_level(conn_id);
+ }
+ else if (p_parse_value->dw_param[1] == 1)
+ {
+ ret = bas_read_notify(conn_id);
+ }
+
+ if (ret)
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief Config battery service client characteristic configuration descriptor value
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "bascccd",
+ "bascccd [conn_id] [notify]\n\r",
+ "Config battery service client characteristic configuration descriptor value\r\n\
+ [notify]: 0-(disable), 1-(enable)\n\r",
+ cmd_bascccd
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_bascccd(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool notify = p_parse_value->dw_param[1];
+ bool ret;
+ ret = bas_set_notify(conn_id, notify);
+
+ if (ret)
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief List battery service handle cache
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "bashdl",
+ "bashdl [conn_id]\n\r",
+ "List battery service handle cache\n\r",
+ cmd_bashdl
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_bashdl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t hdl_cache[HDL_BAS_CACHE_LEN];
+ uint8_t hdl_idx;
+ bool ret = bas_get_hdl_cache(conn_id, hdl_cache,
+ sizeof(uint16_t) * HDL_BAS_CACHE_LEN);
+
+ if (ret)
+ {
+ for (hdl_idx = HDL_BAS_SRV_START; hdl_idx < HDL_BAS_CACHE_LEN; hdl_idx++)
+ {
+ data_uart_print("-->Index %d -- Handle 0x%x\r\n", hdl_idx, hdl_cache[hdl_idx]);
+ }
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/** @brief User command table */
+const T_USER_CMD_TABLE_ENTRY user_cmd_table[] =
+{
+ /************************** Common cmd *************************************/
+ {
+ "conupdreq",
+ "conupdreq [conn_id] [interval_min] [interval_max] [latency] [supervision_timeout]\n\r",
+ "LE connection param update request\r\n\
+ sample: conupdreq 0 0x30 0x40 0 500\n\r",
+ cmd_conupdreq
+ },
+ {
+ "showcon",
+ "showcon\n\r",
+ "Show all devices connecting status\n\r",
+ cmd_showcon
+ },
+ {
+ "disc",
+ "disc [conn_id]\n\r",
+ "Disconnect to remote device\n\r",
+ cmd_disc
+ },
+ {
+ "authmode",
+ "authmode [auth_flags] [io_cap] [sec_enable] [oob_enable]\n\r",
+ "Config authentication mode\r\n\
+ [auth_flags]:authentication req bit field: bit0-(bonding), bit2-(MITM), bit3-(SC)\r\n\
+ [io_cap]:set io Capabilities: 0-(display only), 1-(display yes/no), 2-(keyboard noly), 3-(no IO), 4-(keyboard display)\r\n\
+ [sec_enable]:Start smp pairing procedure when connected: 0-(disable), 1-(enable)\r\n\
+ [oob_enable]:Enable oob flag: 0-(disable), 1-(enable)\r\n\
+ sample: authmode 0x5 2 1 0\n\r",
+ cmd_authmode
+ },
+ {
+ "sauth",
+ "sauth [conn_id]\n\r",
+ "Send authentication request\n\r",
+ cmd_sauth
+ },
+ {
+ "userconf",
+ "userconf [conn_id] [conf]\n\r",
+ "Send user confirmation when show GAP_MSG_LE_BOND_USER_CONFIRMATION\r\n\
+ [conf]: 0-(Reject), 1-(Accept)\r\n\
+ sample: userconf 0 1\n\r",
+ cmd_userconf
+ },
+ {
+ "authkey",
+ "authkey [conn_id] [passkey]\n\r",
+ "Input passkey when show GAP_MSG_LE_BOND_PASSKEY_INPUT\r\n\
+ [passkey]: 0 - 999999\r\n\
+ sample: authkey 0 123456\n\r",
+ cmd_authkey
+ },
+ {
+ "bondinfo",
+ "bondinfo\n\r",
+ "Get all Bonded devices information\n\r",
+ cmd_bondinfo
+ },
+ {
+ "bondclear",
+ "bondclear\n\r",
+ "Clear all bonded devices information\n\r",
+ cmd_bondclear
+ },
+ /************************** Central only *************************************/
+ {
+ "scan",
+ "scan [filter_policy] [filter_duplicate]\n\r",
+ "Start scan\r\n\
+ [filter_policy]: 0-(any), 1-(whitelist), 2-(any RPA), 3-(whitelist RPA) \r\n\
+ [filter_duplicate]: 0-(disable), 1-(enable) \n\r",
+ cmd_scan
+ },
+ {
+ "stopscan",
+ "stopscan\n\r",
+ "Stop scan\n\r",
+ cmd_stopscan
+ },
+ {
+ "showdev",
+ "showdev\n\r",
+ "Show scan dev list: filter simple ble service\n\r",
+ cmd_showdev
+ },
+ {
+ "con",
+ "con [BD0] [BD1] [BD2] [BD3] [BD4] [BD5] [addr_type]\n\r",
+ "Connect to remote device: use address\r\n\
+ [BD0] [BD1] [BD2] [BD3] [BD4] [BD5]: remote device address\r\n\
+ [addr_type]: 0-(public), 1-(random)\r\n\
+ sample: con x11 x22 x33 x44 x55 x66 0 \n\r",
+ cmd_con
+ },
+ {
+ "condev",
+ "condev [idx]\n\r",
+ "Connect to remote device: use showdev to show idx\r\n\
+ [idx]: use cmd showdev to show idx before use this cmd\r\n\
+ sample: condev 0\n\r",
+ cmd_condev
+ },
+ /************************** GATT client *************************************/
+ /*GAPS client*/
+ {
+ "gapread",
+ "gapread [conn_id] [type]\n\r",
+ "Read GAP service characteristic value\r\n\
+ [type]: 0-(read device name), 1-(read appearance)\r\n\
+ simple: gapread 0 0\n\r",
+ cmd_gapread
+ },
+ {
+ "gaphdl",
+ "gaphdl [conn_id]\n\r",
+ "List GAP service handle cache\n\r",
+ cmd_gaphdl
+ },
+ /*Simple ble client*/
+ {
+ "simpread",
+ "simpread [conn_id] [type] [pattern]\n\r",
+ "Read simple ble service characteristic and descriptor value\r\n\
+ [type]: 0-(read v1), 1-(v3 cccd), 2-(v4 cccd)\r\n\
+ [pattern]: 0-(read by handle), 1-(read by uuid)\r\n\
+ sample: simpread 0 1 0 \n\r",
+ cmd_simpread
+ },
+ {
+ "simpcccd",
+ "simpcccd [conn_id] [type] [enable]\n\r",
+ "Config simple ble service client characteristic configuration descriptor value\r\n\
+ [type]: 0-(v3 notify), 1-(v4 indication)\r\n\
+ [enable]: 0-(disable), 1-(enable) \r\n\
+ sample: simpcccd 0 1 1\n\r",
+ cmd_simpcccd
+ },
+ {
+ "simpwritev2",
+ "simpwritev2 [conn_id] [type] [len]\n\r",
+ "Write simple ble service V2 characteristic value\r\n\
+ [type]: 1-(write request), 2-(write command) \r\n\
+ [len]: type=1 len range:0-270, type=2 len range: 0-(mtu-3)\r\n\
+ sample: simpwritev2 0 1 10\n\r",
+ cmd_simpwritev2
+ },
+ {
+ "simphdl",
+ "simphdl [conn_id]\n\r",
+ "List simple ble service handle cache\n\r",
+ cmd_simphdl
+ },
+ /*BAS client*/
+ {
+ "basread",
+ "basread [conn_id] [type]\n\r",
+ "Read battery service characteristic and descriptor value\r\n\
+ [type]: 0-(battery level value), 1-(battery cccd)\r\n\
+ sample: basread 0 1 \n\r",
+ cmd_basread
+ },
+ {
+ "bascccd",
+ "bascccd [conn_id] [notify]\n\r",
+ "Config battery service client characteristic configuration descriptor value\r\n\
+ [notify]: 0-(disable), 1-(enable)\n\r",
+ cmd_bascccd
+ },
+ {
+ "bashdl",
+ "bashdl [conn_id]\n\r",
+ "List battery service handle cache\n\r",
+ cmd_bashdl
+ },
+ /* MUST be at the end: */
+ {
+ 0,
+ 0,
+ 0,
+ 0
+ }
+};
+/** @} */ /* End of group CENTRAL_CMD */
+
+
diff --git a/src/sample/ble_central/user_cmd.h b/src/sample/ble_central/user_cmd.h
new file mode 100644
index 0000000..c1615aa
--- /dev/null
+++ b/src/sample/ble_central/user_cmd.h
@@ -0,0 +1,31 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file user_cmd.h
+* @brief Define user command.
+* @details
+* @author jane
+* @date 2016-02-18
+* @version v0.1
+*********************************************************************************************************
+*/
+#ifndef _USER_CMD_H_
+#define _USER_CMD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <data_uart.h>
+#include <user_cmd_parse.h>
+
+extern const T_USER_CMD_TABLE_ENTRY user_cmd_table[];
+extern T_USER_CMD_IF user_cmd_if;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/src/sample/ble_observer/app_flags.h b/src/sample/ble_observer/app_flags.h
new file mode 100644
index 0000000..f249875
--- /dev/null
+++ b/src/sample/ble_observer/app_flags.h
@@ -0,0 +1,33 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+
+/** @defgroup OB_Config Observer App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 1
+
+/** @} */ /* End of group OB_Config */
+
+#endif
diff --git a/src/sample/ble_observer/app_task.c b/src/sample/ble_observer/app_task.c
new file mode 100644
index 0000000..0306b50
--- /dev/null
+++ b/src/sample/ble_observer/app_task.c
@@ -0,0 +1,102 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <app_task.h>
+#include <app_msg.h>
+#include <gap.h>
+#include <gap_le.h>
+#include <os_msg.h>
+#include <os_task.h>
+#include <observer_app.h>
+
+
+/** @defgroup OB_APP_TASK Observer App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_main_task(void *p_param);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE,
+ APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group OB_APP_TASK */
+
+
diff --git a/src/sample/ble_observer/app_task.h b/src/sample/ble_observer/app_task.h
new file mode 100644
index 0000000..8dfcd2a
--- /dev/null
+++ b/src/sample/ble_observer/app_task.h
@@ -0,0 +1,27 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.h
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+extern void driver_init(void);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/ble_observer/main.c b/src/sample/ble_observer/main.c
new file mode 100644
index 0000000..99fed5c
--- /dev/null
+++ b/src/sample/ble_observer/main.c
@@ -0,0 +1,149 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file main.c
+ * @brief Source file for BLE observer project, mainly used for initialize modules
+ * @author jane
+ * @date 2017-06-12
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <os_sched.h>
+#include <string.h>
+#include <app_task.h>
+#include <trace.h>
+#include <gap_le.h>
+#include <gap_scan.h>
+#include <observer_app.h>
+#if F_BT_DLPS_EN
+#include <dlps.h>
+#include <rtl876x_io_dlps.h>
+#endif
+
+
+/** @defgroup OB_DEMO_MAIN Observer Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Default scan interval (units of 0.625ms, 0x10=2.5ms) */
+#define DEFAULT_SCAN_INTERVAL 0x10
+/** @brief Default scan window (units of 0.625ms, 0x10=2.5ms) */
+#define DEFAULT_SCAN_WINDOW 0x10
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize scan related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Scan parameters */
+ uint8_t scan_mode = GAP_SCAN_MODE_PASSIVE;
+ uint16_t scan_interval = DEFAULT_SCAN_INTERVAL;
+ uint16_t scan_window = DEFAULT_SCAN_WINDOW;
+ uint8_t scan_filter_policy = GAP_SCAN_FILTER_ANY;
+ uint8_t scan_filter_duplicate = GAP_SCAN_FILTER_DUPLICATE_ENABLE;
+
+ /* Set Scan parameters */
+ le_scan_set_param(GAP_PARAM_SCAN_MODE, sizeof(scan_mode), &scan_mode);
+ le_scan_set_param(GAP_PARAM_SCAN_INTERVAL, sizeof(scan_interval), &scan_interval);
+ le_scan_set_param(GAP_PARAM_SCAN_WINDOW, sizeof(scan_window), &scan_window);
+ le_scan_set_param(GAP_PARAM_SCAN_FILTER_POLICY, sizeof(scan_filter_policy),
+ &scan_filter_policy);
+ le_scan_set_param(GAP_PARAM_SCAN_FILTER_DUPLICATES, sizeof(scan_filter_duplicate),
+ &scan_filter_duplicate);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void io_dlps_enter_cb(void)
+{
+
+}
+
+void io_dlps_exit_cb(void)
+{
+
+}
+
+void pwr_mgr_init(void)
+{
+#if F_BT_DLPS_EN
+ DLPS_IORegUserDlpsEnterCb(io_dlps_enter_cb);
+ DLPS_IORegUserDlpsExitCb(io_dlps_exit_cb);
+ DLPS_IORegister();
+ lps_mode_set(PLATFORM_DLPS_PFM);
+#endif
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Observer APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ board_init();
+ le_gap_init(0);
+ gap_lib_init();
+ app_le_gap_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group OB_DEMO_MAIN */
+
+
diff --git a/src/sample/ble_observer/observer_app.c b/src/sample/ble_observer/observer_app.c
new file mode 100644
index 0000000..d9018bd
--- /dev/null
+++ b/src/sample/ble_observer/observer_app.c
@@ -0,0 +1,315 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file observer_app.c
+ * @brief This file handles BLE observer application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <trace.h>
+#include <gap_scan.h>
+#include <gap.h>
+#include <gap_msg.h>
+#include <observer_app.h>
+#include <string.h>
+
+
+/** @defgroup OB_APP Observer Application
+ * @brief This file handles BLE observer application routines.
+ * @{
+ */
+
+/** @defgroup OB_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, scan state %d, cause 0x%x",
+ new_state.gap_init_state,
+ new_state.gap_scan_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+ le_scan_start();
+ }
+ }
+
+ if (gap_dev_state.gap_scan_state != new_state.gap_scan_state)
+ {
+ if (new_state.gap_scan_state == GAP_SCAN_STATE_IDLE)
+ {
+ APP_PRINT_INFO0("GAP scan stop");
+ }
+ else if (new_state.gap_scan_state == GAP_SCAN_STATE_SCANNING)
+ {
+ APP_PRINT_INFO0("GAP scan start");
+ }
+ }
+ gap_dev_state = new_state;
+}
+
+
+
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group OB_GAP_MSG */
+
+/** @defgroup OB_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+/**
+ * @brief Used to parse advertising data and scan response data
+ * @param[in] scan_info point to scan information data.
+ * @retval void
+ */
+void app_parse_scan_info(T_LE_SCAN_INFO *scan_info)
+{
+ uint8_t buffer[32];
+ uint8_t pos = 0;
+
+ while (pos < scan_info->data_len)
+ {
+ /* Length of the AD structure. */
+ uint8_t length = scan_info->data[pos++];
+ uint8_t type;
+
+ if ((length < 1) || (length >= 31))
+ {
+ return;
+ }
+
+ if ((length > 0x01) && ((pos + length) <= 31))
+ {
+ /* Copy the AD Data to buffer. */
+ memcpy(buffer, scan_info->data + pos + 1, length - 1);
+ /* AD Type, one octet. */
+ type = scan_info->data[pos];
+
+ APP_PRINT_TRACE2("app_parse_scan_info: AD Structure Info: AD type 0x%x, AD Data Length %d", type,
+ length - 1);
+
+ switch (type)
+ {
+ case GAP_ADTYPE_FLAGS:
+ {
+ /* (flags & 0x01) -- LE Limited Discoverable Mode */
+ /* (flags & 0x02) -- LE General Discoverable Mode */
+ /* (flags & 0x04) -- BR/EDR Not Supported */
+ /* (flags & 0x08) -- Simultaneous LE and BR/EDR to Same Device Capable (Controller) */
+ /* (flags & 0x10) -- Simultaneous LE and BR/EDR to Same Device Capable (Host) */
+ uint8_t flags = scan_info->data[pos + 1];
+ APP_PRINT_INFO1("GAP_ADTYPE_FLAGS: 0x%x", flags);
+ }
+ break;
+
+ case GAP_ADTYPE_16BIT_MORE:
+ case GAP_ADTYPE_16BIT_COMPLETE:
+ case GAP_ADTYPE_SERVICES_LIST_16BIT:
+ {
+ uint16_t *p_uuid = (uint16_t *)(buffer);
+ uint8_t i = length - 1;
+
+ while (i >= 2)
+ {
+ APP_PRINT_INFO1("GAP_ADTYPE_16BIT_XXX: 0x%x", *p_uuid++);
+ i -= 2;
+ }
+ }
+ break;
+
+ case GAP_ADTYPE_32BIT_MORE:
+ case GAP_ADTYPE_32BIT_COMPLETE:
+ {
+ uint32_t *p_uuid = (uint32_t *)(buffer);
+ uint8_t i = length - 1;
+
+ while (i >= 4)
+ {
+ APP_PRINT_INFO1("GAP_ADTYPE_32BIT_XXX: 0x%x", *p_uuid++);
+ i -= 4;
+ }
+ }
+ break;
+
+ case GAP_ADTYPE_128BIT_MORE:
+ case GAP_ADTYPE_128BIT_COMPLETE:
+ case GAP_ADTYPE_SERVICES_LIST_128BIT:
+ {
+ uint32_t *p_uuid = (uint32_t *)(buffer);
+ APP_PRINT_INFO4("GAP_ADTYPE_128BIT_XXX: 0x%8.8x%8.8x%8.8x%8.8x",
+ p_uuid[3], p_uuid[2], p_uuid[1], p_uuid[0]);
+ }
+ break;
+
+ case GAP_ADTYPE_LOCAL_NAME_SHORT:
+ case GAP_ADTYPE_LOCAL_NAME_COMPLETE:
+ {
+ buffer[length - 1] = '\0';
+ APP_PRINT_INFO1("GAP_ADTYPE_LOCAL_NAME_XXX: %s", TRACE_STRING(buffer));
+ }
+ break;
+
+ case GAP_ADTYPE_POWER_LEVEL:
+ {
+ APP_PRINT_INFO1("GAP_ADTYPE_POWER_LEVEL: 0x%x", scan_info->data[pos + 1]);
+ }
+ break;
+
+ case GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE:
+ {
+ uint16_t *p_min = (uint16_t *)(buffer);
+ uint16_t *p_max = p_min + 1;
+ APP_PRINT_INFO2("GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE: 0x%x - 0x%x", *p_min,
+ *p_max);
+ }
+ break;
+
+ case GAP_ADTYPE_SERVICE_DATA:
+ {
+ uint16_t *p_uuid = (uint16_t *)(buffer);
+ uint8_t data_len = length - 3;
+
+ APP_PRINT_INFO3("GAP_ADTYPE_SERVICE_DATA: UUID 0x%x, len %d, data %b", *p_uuid,
+ data_len, TRACE_BINARY(data_len, &buffer[2]));
+ }
+ break;
+ case GAP_ADTYPE_APPEARANCE:
+ {
+ uint16_t *p_appearance = (uint16_t *)(buffer);
+ APP_PRINT_INFO1("GAP_ADTYPE_APPEARANCE: %d", *p_appearance);
+ }
+ break;
+
+ case GAP_ADTYPE_MANUFACTURER_SPECIFIC:
+ {
+ uint8_t data_len = length - 3;
+ uint16_t *p_company_id = (uint16_t *)(buffer);
+ APP_PRINT_INFO3("GAP_ADTYPE_MANUFACTURER_SPECIFIC: company_id 0x%x, len %d, data %b",
+ *p_company_id, data_len, TRACE_BINARY(data_len, &buffer[2]));
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ pos += length;
+ }
+}
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_SCAN_INFO:
+ APP_PRINT_TRACE5("GAP_MSG_LE_SCAN_INFO: bd_addr %s, bdtype %d, event 0x%x, rssi %d, len %d",
+ TRACE_BDADDR(p_data->p_le_scan_info->bd_addr),
+ p_data->p_le_scan_info->remote_addr_type,
+ p_data->p_le_scan_info->adv_type,
+ p_data->p_le_scan_info->rssi,
+ p_data->p_le_scan_info->data_len);
+ /* User can split interested information by using the function as follow. */
+ app_parse_scan_info(p_data->p_le_scan_info);
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group OB_GAP_CALLBACK */
+
+/** @} */ /* End of group OB_APP */
+
diff --git a/src/sample/ble_observer/observer_app.h b/src/sample/ble_observer/observer_app.h
new file mode 100644
index 0000000..ef63910
--- /dev/null
+++ b/src/sample/ble_observer/observer_app.h
@@ -0,0 +1,54 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file observer_app.h
+ * @brief This file handles BLE observer application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+#ifndef _OBSERVER_APP_H_
+#define _OBSERVER_APP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <app_msg.h>
+#include <gap_le.h>
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/ble_peripheral/ancs.c b/src/sample/ble_peripheral/ancs.c
new file mode 100644
index 0000000..774cbc1
--- /dev/null
+++ b/src/sample/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id %d os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/ble_peripheral/ancs.h b/src/sample/ble_peripheral/ancs.h
new file mode 100644
index 0000000..27a5d9e
--- /dev/null
+++ b/src/sample/ble_peripheral/ancs.h
@@ -0,0 +1,262 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+#include <app_msg.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Peripheral ANCS
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/ble_peripheral/app_flags.h b/src/sample/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..eefa164
--- /dev/null
+++ b/src/sample/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 1
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/ble_peripheral/app_task.c b/src/sample/ble_peripheral/app_task.c
new file mode 100644
index 0000000..ee8f56d
--- /dev/null
+++ b/src/sample/ble_peripheral/app_task.c
@@ -0,0 +1,103 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <os_msg.h>
+#include <os_task.h>
+#include <gap.h>
+#include <gap_le.h>
+#include <app_task.h>
+#include <app_msg.h>
+#include <app_task.h>
+#include <peripheral_app.h>
+
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_main_task(void *p_param);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE,
+ APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/ble_peripheral/app_task.h b/src/sample/ble_peripheral/app_task.h
new file mode 100644
index 0000000..e03ffca
--- /dev/null
+++ b/src/sample/ble_peripheral/app_task.h
@@ -0,0 +1,39 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.h
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief Peripheral App Task
+ * @{
+ */
+
+extern void driver_init(void);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init(void);
+
+
+/** End of PERIPH_APP_TASK
+* @}
+*/
+
+
+#endif
+
diff --git a/src/sample/ble_peripheral/main.c b/src/sample/ble_peripheral/main.c
new file mode 100644
index 0000000..33f3e4b
--- /dev/null
+++ b/src/sample/ble_peripheral/main.c
@@ -0,0 +1,248 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file main.c
+ * @brief Source file for BLE peripheral project, mainly used for initialize modules
+ * @author jane
+ * @date 2017-06-12
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <os_sched.h>
+#include <string.h>
+#include <trace.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <profile_server.h>
+#include <gap_msg.h>
+#include <simple_ble_service.h>
+#include <bas.h>
+#include <app_task.h>
+#include <peripheral_app.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include <ancs.h>
+#endif
+#if F_BT_DLPS_EN
+#include <dlps.h>
+#include <rtl876x_io_dlps.h>
+#endif
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void io_dlps_enter_cb(void)
+{
+
+}
+
+void io_dlps_exit_cb(void)
+{
+
+}
+
+void pwr_mgr_init(void)
+{
+#if F_BT_DLPS_EN
+ DLPS_IORegUserDlpsEnterCb(io_dlps_enter_cb);
+ DLPS_IORegUserDlpsExitCb(io_dlps_exit_cb);
+ DLPS_IORegister();
+ lps_mode_set(PLATFORM_DLPS_PFM);
+#endif
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/ble_peripheral/peripheral_app.c b/src/sample/ble_peripheral/peripheral_app.c
new file mode 100644
index 0000000..7b819ae
--- /dev/null
+++ b/src/sample/ble_peripheral/peripheral_app.c
@@ -0,0 +1,594 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <trace.h>
+#include <string.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <profile_server.h>
+#include <gap_msg.h>
+#include <simple_ble_service.h>
+#include <bas.h>
+#include <app_msg.h>
+#include <peripheral_app.h>
+#include <gap_conn_le.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include <ancs.h>
+#endif
+
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+ le_adv_start();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/ble_peripheral/peripheral_app.h b/src/sample/ble_peripheral/peripheral_app.h
new file mode 100644
index 0000000..62c07e9
--- /dev/null
+++ b/src/sample/ble_peripheral/peripheral_app.h
@@ -0,0 +1,85 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.h
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+#ifndef _PERIPHERAL_APP__
+#define _PERIPHERAL_APP__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <app_msg.h>
+#include <gap_le.h>
+#include <profile_server.h>
+
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief Peripheral Application
+ * @{
+ */
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id.
+ * @param[in] service_id Profile service ID
+ * @param[in] p_data Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+
+/** End of PERIPH_APP
+* @}
+*/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/ble_peripheral_privacy/app_flags.h b/src/sample/ble_peripheral_privacy/app_flags.h
new file mode 100644
index 0000000..886967e
--- /dev/null
+++ b/src/sample/ble_peripheral_privacy/app_flags.h
@@ -0,0 +1,42 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PRIVA_PERIPH_Config Peripheral Privacy App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Configure APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief User command: 0-Close user command, 1-Open user command */
+#define USER_CMD_EN 1
+
+/** @brief Configure Privacy1.2 feature: 0-Closed, 1-Open */
+#define APP_PRIVACY_EN 1
+
+#if APP_PRIVACY_EN
+/** @brief Configure the authentication requirement of simple_ble_service.c */
+#define SIMP_SRV_AUTHEN_EN 1
+#endif
+
+/** @} */ /* End of group PRIVA_PERIPH_Config */
+#endif
diff --git a/src/sample/ble_peripheral_privacy/app_task.c b/src/sample/ble_peripheral_privacy/app_task.c
new file mode 100644
index 0000000..bc8a2b1
--- /dev/null
+++ b/src/sample/ble_peripheral_privacy/app_task.c
@@ -0,0 +1,110 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <os_msg.h>
+#include <os_task.h>
+#include <gap.h>
+#include <gap_le.h>
+#include <app_task.h>
+#include <app_msg.h>
+#include <app_task.h>
+#include <peripheral_privacy_app.h>
+#if USER_CMD_EN
+#include <data_uart.h>
+#include <user_cmd_parse.h>
+#include <user_cmd.h>
+#endif
+
+/** @defgroup PRIVA_PERIPH_APP_TASK Peripheral Privacy App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 8 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_main_task(void *p_param);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE,
+ APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+#if USER_CMD_EN
+ data_uart_init(evt_queue_handle, io_queue_handle);
+ user_cmd_init(&user_cmd_if, "periph privacy app");
+#endif
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PRIVA_PERIPH_APP_TASK */
+
+
diff --git a/src/sample/ble_peripheral_privacy/app_task.h b/src/sample/ble_peripheral_privacy/app_task.h
new file mode 100644
index 0000000..8dfcd2a
--- /dev/null
+++ b/src/sample/ble_peripheral_privacy/app_task.h
@@ -0,0 +1,27 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.h
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+extern void driver_init(void);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/ble_peripheral_privacy/main.c b/src/sample/ble_peripheral_privacy/main.c
new file mode 100644
index 0000000..c277b36
--- /dev/null
+++ b/src/sample/ble_peripheral_privacy/main.c
@@ -0,0 +1,220 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file main.c
+ * @brief Source file for BLE peripheral privacy project, mainly used for initialize modules
+ * @author jane
+ * @date 2017-06-12
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <os_sched.h>
+#include <string.h>
+#include <trace.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <profile_server.h>
+#include <simple_ble_service.h>
+#include <bas.h>
+#include <app_task.h>
+#include <peripheral_privacy_app.h>
+#include <privacy_mgnt.h>
+
+
+/** @defgroup PRIVA_PERIPH_DEMO_MAIN Peripheral Privacy Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0C, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'R', 'I', 'V', 'A', 'C', 'Y',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PRIVACY";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG | GAP_AUTHEN_BIT_SC_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+ uint8_t auth_sec_req_enable = false;
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG | GAP_AUTHEN_BIT_SC_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+#if APP_PRIVACY_EN
+ privacy_init(app_privacy_callback, true);
+#endif
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral Privacy APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PRIVA_PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/ble_peripheral_privacy/peripheral_privacy_app.c b/src/sample/ble_peripheral_privacy/peripheral_privacy_app.c
new file mode 100644
index 0000000..a1188bc
--- /dev/null
+++ b/src/sample/ble_peripheral_privacy/peripheral_privacy_app.c
@@ -0,0 +1,710 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_privacy_app.c
+ * @brief This file handles BLE peripheral privacy application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <trace.h>
+#include <string.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <profile_server.h>
+#include <gap_msg.h>
+#include <simple_ble_service.h>
+#include <bas.h>
+#include <app_msg.h>
+#include <peripheral_privacy_app.h>
+#include <gap_conn_le.h>
+#if APP_PRIVACY_EN
+#include <privacy_mgnt.h>
+#endif
+#if USER_CMD_EN
+#include <user_cmd.h>
+#include <user_cmd_parse.h>
+#endif
+/** @defgroup PRIVA_PERIPH_APP Peripheral Privacy Application
+ * @brief This file handles BLE peripheral privacy application routines.
+ * @{
+ */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PRIVA_PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PRIVA_PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PRIVA_PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+#if APP_PRIVACY_EN
+T_PRIVACY_STATE app_privacy_state = PRIVACY_STATE_INIT;
+T_PRIVACY_ADDR_RESOLUTION_STATE app_privacy_resolution_state = PRIVACY_ADDR_RESOLUTION_DISABLED;
+T_APP_WORK_MODE app_work_mode = APP_PAIRABLE_MODE;
+#endif
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+
+#if USER_CMD_EN
+ case IO_MSG_TYPE_UART:
+ /* We handle user command informations from Data UART in this branch. */
+ {
+ uint8_t rx_char;
+ rx_char = (uint8_t)io_msg.subtype;
+ user_cmd_collect(&user_cmd_if, &rx_char, sizeof(rx_char), user_cmd_table);
+ }
+ break;
+#endif
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Start advertising
+ *
+ * @return void
+ */
+void app_adv_start(void)
+{
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+#if APP_PRIVACY_EN
+ T_LE_KEY_ENTRY *p_entry;
+ p_entry = le_get_high_priority_bond();
+
+ if (p_entry == NULL)
+ {
+ /* No bonded device, send connectable undirected advertisement without using whitelist*/
+ app_work_mode = APP_PAIRABLE_MODE;
+ adv_filter_policy = GAP_ADV_FILTER_ANY;
+ if (app_privacy_resolution_state == PRIVACY_ADDR_RESOLUTION_ENABLED)
+ {
+ privacy_set_addr_resolution(false);
+ }
+ }
+ else
+ {
+ app_work_mode = APP_RECONNECTION_MODE;
+ adv_filter_policy = GAP_ADV_FILTER_WHITE_LIST_ALL;
+ if (app_privacy_resolution_state == PRIVACY_ADDR_RESOLUTION_DISABLED)
+ {
+ privacy_set_addr_resolution(true);
+ }
+ }
+#endif
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_start();
+}
+
+#if APP_PRIVACY_EN
+/**
+ * @brief Application changes to pairable mode.
+ * @retval void
+ */
+void app_change_to_pair_mode(void)
+{
+ APP_PRINT_INFO0("app_change_to_pair_mode");
+ if (app_work_mode == APP_RECONNECTION_MODE)
+ {
+ if (gap_dev_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ le_adv_stop();
+ }
+ else if (gap_conn_state == GAP_CONN_STATE_CONNECTED)
+ {
+ le_disconnect(0);
+ }
+ }
+ app_work_mode = APP_PAIRABLE_MODE;
+}
+
+/**
+ * @brief Callback for BLE privacy management module to notify app
+ * @param[in] type callback msy type @ref T_PRIVACY_CB_TYPE.
+ * @param[in] cb_data callback data.
+ * @retval void
+ */
+void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data)
+{
+ APP_PRINT_INFO1("app_privacy_callback: type %d", type);
+ switch (type)
+ {
+ case PRIVACY_STATE_MSGTYPE:
+ app_privacy_state = cb_data.privacy_state;
+ APP_PRINT_INFO1("PRIVACY_STATE_MSGTYPE: status %d", app_privacy_state);
+ break;
+
+ case PRIVACY_RESOLUTION_STATUS_MSGTYPE:
+ app_privacy_resolution_state = cb_data.resolution_state;
+ APP_PRINT_INFO1("PRIVACY_RESOLUTION_STATUS_MSGTYPE: status %d", app_privacy_resolution_state);
+ break;
+
+ default:
+ break;
+ }
+}
+#endif
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+#if APP_PRIVACY_EN
+ if ((new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ && (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ && (new_state.gap_conn_state == GAP_CONN_DEV_STATE_IDLE))
+ {
+ privacy_handle_resolv_list();
+ }
+#endif
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+ app_adv_start();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ app_adv_start();
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ app_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ if (cause == (SM_ERR | SM_ERR_LINK_KEY_MISSING))
+ {
+ le_bond_pair(conn_id);
+ }
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PRIVA_PERIPH_GAP_MSG */
+
+/** @defgroup PRIVA_PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+#if APP_PRIVACY_EN
+ case GAP_MSG_LE_BOND_MODIFY_INFO:
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x",
+ p_data->p_le_bond_modify_info->type);
+ privacy_handle_bond_modify_msg(p_data->p_le_bond_modify_info->type,
+ p_data->p_le_bond_modify_info->p_entry, true);
+ break;
+#endif
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PRIVA_PERIPH_GAP_CALLBACK */
+
+/** @defgroup PRIVA_PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PRIVA_PERIPH_SEVER_CALLBACK */
+/** @} */ /* End of group PRIVA_PERIPH_APP */
diff --git a/src/sample/ble_peripheral_privacy/peripheral_privacy_app.h b/src/sample/ble_peripheral_privacy/peripheral_privacy_app.h
new file mode 100644
index 0000000..a627f2a
--- /dev/null
+++ b/src/sample/ble_peripheral_privacy/peripheral_privacy_app.h
@@ -0,0 +1,97 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_privacy_app.h
+ * @brief This file handles BLE peripheral privacy application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+#ifndef _PERIPHERAL_PRIVACY_APP__
+#define _PERIPHERAL_PRIVACY_APP__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <app_msg.h>
+#include <gap_le.h>
+#include <profile_server.h>
+#if APP_PRIVACY_EN
+#include <privacy_mgnt.h>
+#endif
+
+typedef enum
+{
+ APP_PAIRABLE_MODE, /**< Pairable mode. */
+ APP_RECONNECTION_MODE, /**< Reconnection mode. */
+} T_APP_WORK_MODE;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id.
+ * @param[in] service_id Profile service ID
+ * @param[in] p_data Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#if APP_PRIVACY_EN
+/**
+ * @brief Callback for BLE privacy management module to notify app
+ * @param[in] type callback msy type @ref T_PRIVACY_CB_TYPE.
+ * @param[in] cb_data callback data.
+ * @retval void
+ */
+void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data);
+
+/**
+ * @brief Application changes to pairable mode.
+ * @retval void
+ */
+void app_change_to_pair_mode(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/ble_peripheral_privacy/user_cmd.c b/src/sample/ble_peripheral_privacy/user_cmd.c
new file mode 100644
index 0000000..4a6cf97
--- /dev/null
+++ b/src/sample/ble_peripheral_privacy/user_cmd.c
@@ -0,0 +1,110 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file user_cmd.c
+ * @brief User defined test commands.
+ * @details User command interfaces.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if USER_CMD_EN
+#include <gap_bond_le.h>
+#include <user_cmd.h>
+#include <gap_conn_le.h>
+#include <peripheral_privacy_app.h>
+
+/** @defgroup PRIVA_PERIPH_CMD Peripheral Privacy User Command
+ * @brief This file handles Peripheral Privacy User Command.
+ * @{
+ */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @brief User command interface data, used to parse the commands from Data UART. */
+T_USER_CMD_IF user_cmd_if;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief Disconnect to remote device
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "disc",
+ "disc [conn_id]\n\r",
+ "Disconnect to remote device\n\r",
+ cmd_disc
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_disc(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAP_CAUSE cause;
+ cause = le_disconnect(conn_id);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Clear all bonded devices information
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "bondclear",
+ "bondclear\n\r",
+ "Clear all bonded devices information\n\r",
+ cmd_bondclear
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_bondclear(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+#if APP_PRIVACY_EN
+ app_change_to_pair_mode();
+#endif
+ le_bond_clear_all_keys();
+ return (RESULT_SUCCESS);
+}
+
+/*----------------------------------------------------
+ * command table
+ * --------------------------------------------------*/
+const T_USER_CMD_TABLE_ENTRY user_cmd_table[] =
+{
+ /************************** Common cmd *************************************/
+ {
+ "disc",
+ "disc [conn_id]\n\r",
+ "Disconnect to remote device\n\r",
+ cmd_disc
+ },
+ {
+ "bondclear",
+ "bondclear\n\r",
+ "Clear all bonded devices information\n\r",
+ cmd_bondclear
+ },
+ /* MUST be at the end: */
+ {
+ 0,
+ 0,
+ 0,
+ 0
+ }
+};
+/** @} */ /* End of group PRIVA_PERIPH_CMD */
+#endif
+
diff --git a/src/sample/ble_peripheral_privacy/user_cmd.h b/src/sample/ble_peripheral_privacy/user_cmd.h
new file mode 100644
index 0000000..c1615aa
--- /dev/null
+++ b/src/sample/ble_peripheral_privacy/user_cmd.h
@@ -0,0 +1,31 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file user_cmd.h
+* @brief Define user command.
+* @details
+* @author jane
+* @date 2016-02-18
+* @version v0.1
+*********************************************************************************************************
+*/
+#ifndef _USER_CMD_H_
+#define _USER_CMD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <data_uart.h>
+#include <user_cmd_parse.h>
+
+extern const T_USER_CMD_TABLE_ENTRY user_cmd_table[];
+extern T_USER_CMD_IF user_cmd_if;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/src/sample/ble_scatternet/app_flags.h b/src/sample/ble_scatternet/app_flags.h
new file mode 100644
index 0000000..efc5b06
--- /dev/null
+++ b/src/sample/ble_scatternet/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup SCATTERNET_Config Scatternet App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 2
+/** @brief Config airplane mode support: 0-Not built in, 1-built in, use user command to set*/
+#define F_BT_AIRPLANE_MODE_SUPPORT 0
+/** @brief Config device name characteristic and appearance characteristic property: 0-Not writeable, 1-writeable, save to flash*/
+#define F_BT_GAPS_CHAR_WRITEABLE 0
+/** @brief Config set physical: 0-Not built in, 1-built in, use user command to set*/
+#define F_BT_LE_5_0_SET_PHY_SUPPORT 0
+/** @brief Config local address type: 0-pulic address, 1-static random address */
+#define F_BT_LE_USE_STATIC_RANDOM_ADDR 0
+
+/** @} */ /* End of group SCATTERNET_Config */
+#endif
diff --git a/src/sample/ble_scatternet/app_task.c b/src/sample/ble_scatternet/app_task.c
new file mode 100644
index 0000000..b4614be
--- /dev/null
+++ b/src/sample/ble_scatternet/app_task.c
@@ -0,0 +1,111 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <os_msg.h>
+#include <os_task.h>
+#include <gap.h>
+#include <gap_le.h>
+#include <trace.h>
+#include <app_task.h>
+#include <app_msg.h>
+#include <app_task.h>
+#include <scatternet_app.h>
+#include <data_uart.h>
+#include <user_cmd_parse.h>
+#include <user_cmd.h>
+
+
+/** @defgroup SCATTERNET_APP_TASK Scatternet App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 6 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_main_task(void *p_param);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE,
+ APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ data_uart_init(evt_queue_handle, io_queue_handle);
+ user_cmd_init(&user_cmd_if, "scatternet");
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group SCATTERNET_APP_TASK */
+
+
diff --git a/src/sample/ble_scatternet/app_task.h b/src/sample/ble_scatternet/app_task.h
new file mode 100644
index 0000000..8dfcd2a
--- /dev/null
+++ b/src/sample/ble_scatternet/app_task.h
@@ -0,0 +1,27 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.h
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+extern void driver_init(void);
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/ble_scatternet/link_mgr.c b/src/sample/ble_scatternet/link_mgr.c
new file mode 100644
index 0000000..ee57041
--- /dev/null
+++ b/src/sample/ble_scatternet/link_mgr.c
@@ -0,0 +1,137 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file link_mgr.c
+ * @brief Multilink manager functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <link_mgr.h>
+#include <trace.h>
+#include <string.h>
+#include <ftl.h>
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+#if F_BT_LE_USE_STATIC_RANDOM_ADDR
+/** @brief Define start offset of the flash to save static random address. */
+#define APP_STATIC_RANDOM_ADDR_OFFSET 0
+#endif
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup SCATTERNET_GAP_MSG
+ * @{
+ */
+T_APP_LINK app_link_table[APP_MAX_LINKS];
+/** @} */
+/** @addtogroup SCATTERNET_SCAN_MGR
+ * @{
+ */
+T_DEV_INFO dev_list[APP_MAX_DEVICE_INFO];
+uint8_t dev_list_count = 0;
+/** @} */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @addtogroup CENTRAL_SCAN_MGR
+ * @{
+ */
+/**
+ * @brief Add device information to device list.
+ *
+ * @param[in] bd_addr Peer device address.
+ * @param[in] bd_type Peer device address type.
+ * @retval true Success.
+ * @retval false Failed, device list is full.
+ */
+bool link_mgr_add_device(uint8_t *bd_addr, uint8_t bd_type)
+{
+ /* If result count not at max */
+ if (dev_list_count < APP_MAX_DEVICE_INFO)
+ {
+ uint8_t i;
+ /* Check if device is already in device list*/
+ for (i = 0; i < dev_list_count; i++)
+ {
+ if (memcmp(bd_addr, dev_list[i].bd_addr, GAP_BD_ADDR_LEN) == 0)
+ {
+ return true;
+ }
+ }
+
+ /*Add addr to device list list*/
+ memcpy(dev_list[dev_list_count].bd_addr, bd_addr, GAP_BD_ADDR_LEN);
+ dev_list[dev_list_count].bd_type = bd_type;
+
+ /*Increment device list count*/
+ dev_list_count++;
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Clear device list.
+ * @retval None.
+ */
+void link_mgr_clear_device_list(void)
+{
+ dev_list_count = 0;
+}
+/** @} */
+/** @addtogroup SCATTERNET_APP
+ * @{
+ */
+/** @defgroup SCATTERNET_RANDOM Static Random Address Storage
+ * @brief Use @ref F_BT_LE_USE_STATIC_RANDOM_ADDR to open
+ * @{
+ */
+#if F_BT_LE_USE_STATIC_RANDOM_ADDR
+/**
+ * @brief Save static random address information into flash.
+ * @param[in] p_addr Pointer to the buffer for saving data.
+ * @retval 0 Save success.
+ * @retval other Failed.
+ */
+uint32_t app_save_static_random_address(T_APP_STATIC_RANDOM_ADDR *p_addr)
+{
+ APP_PRINT_INFO0("app_save_static_random_address");
+ return ftl_save(p_addr, APP_STATIC_RANDOM_ADDR_OFFSET, sizeof(T_APP_STATIC_RANDOM_ADDR));
+}
+/**
+ * @brief Load static random address information from storage.
+ * @param[out] p_addr Pointer to the buffer for loading data.
+ * @retval 0 Load success.
+ * @retval other Failed.
+ */
+uint32_t app_load_static_random_address(T_APP_STATIC_RANDOM_ADDR *p_addr)
+{
+ uint32_t result;
+ result = ftl_load(p_addr, APP_STATIC_RANDOM_ADDR_OFFSET,
+ sizeof(T_APP_STATIC_RANDOM_ADDR));
+ APP_PRINT_INFO1("app_load_static_random_address: result 0x%x", result);
+ if (result)
+ {
+ memset(p_addr, 0, sizeof(T_APP_STATIC_RANDOM_ADDR));
+ }
+ return result;
+}
+#endif
+/** @} */
+/** @} */
diff --git a/src/sample/ble_scatternet/link_mgr.h b/src/sample/ble_scatternet/link_mgr.h
new file mode 100644
index 0000000..dd8ac7a
--- /dev/null
+++ b/src/sample/ble_scatternet/link_mgr.h
@@ -0,0 +1,87 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file link_mgr.h
+ * @brief Define multilink manager struct and functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _LINK_MANAGER_H_
+#define _LINK_MANAGER_H_
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <app_msg.h>
+#include <gap_conn_le.h>
+#include <profile_client.h>
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Define device list table size. */
+#define APP_MAX_DEVICE_INFO 6
+
+/** @addtogroup SCATTERNET_GAP_MSG
+ * @{
+ */
+/**
+ * @brief Application Link control block definition.
+ */
+typedef struct
+{
+ T_GAP_CONN_STATE conn_state; /**< Connection state. */
+ T_GAP_REMOTE_ADDR_TYPE bd_type; /**< remote BD type*/
+ uint8_t bd_addr[GAP_BD_ADDR_LEN]; /**< remote BD */
+} T_APP_LINK;
+/** @} */ /* End of group SCATTERNET_GAP_MSG */
+/** @addtogroup SCATTERNET_SCAN_MGR
+ * @{
+ */
+/**
+ * @brief Device list block definition.
+ */
+typedef struct
+{
+ uint8_t bd_addr[GAP_BD_ADDR_LEN]; /**< remote BD */
+ uint8_t bd_type; /**< remote BD type*/
+} T_DEV_INFO;
+/** @} */
+/** @addtogroup SCATTERNET_RANDOM
+ * @{
+ */
+#if F_BT_LE_USE_STATIC_RANDOM_ADDR
+typedef struct
+{
+ uint8_t is_exist;
+ uint8_t reserved; /**< remote BD type*/
+ uint8_t bd_addr[GAP_BD_ADDR_LEN]; /**< remote BD */
+} T_APP_STATIC_RANDOM_ADDR;
+#endif
+/** @} */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @brief App link table */
+extern T_APP_LINK app_link_table[APP_MAX_LINKS];
+/** @brief Device list table, used to save discovered device informations. */
+extern T_DEV_INFO dev_list[APP_MAX_DEVICE_INFO];
+/** @brief The number of device informations saved in dev_list. */
+extern uint8_t dev_list_count;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+bool link_mgr_add_device(uint8_t *bd_addr, uint8_t bd_type);
+void link_mgr_clear_device_list(void);
+
+#if F_BT_LE_USE_STATIC_RANDOM_ADDR
+uint32_t app_save_static_random_address(T_APP_STATIC_RANDOM_ADDR *p_addr);
+uint32_t app_load_static_random_address(T_APP_STATIC_RANDOM_ADDR *p_addr);
+#endif
+#endif
diff --git a/src/sample/ble_scatternet/main.c b/src/sample/ble_scatternet/main.c
new file mode 100644
index 0000000..e121ae4
--- /dev/null
+++ b/src/sample/ble_scatternet/main.c
@@ -0,0 +1,297 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file main.c
+ * @brief Source file for BLE scatternet project, mainly used for initialize modules
+ * @author jane
+ * @date 2017-06-12
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <os_sched.h>
+#include <string.h>
+#include <app_task.h>
+#include <trace.h>
+#include <gap.h>
+#include <gap_bond_le.h>
+#include <gap_scan.h>
+#include <gap_msg.h>
+#include <profile_client.h>
+#include <simple_ble_client.h>
+#include <gaps_client.h>
+#include <bas_client.h>
+#include <link_mgr.h>
+#include <scatternet_app.h>
+#include <gap_adv.h>
+#include <profile_server.h>
+#include <simple_ble_service.h>
+#include <bas.h>
+#include <gatt_builtin_services.h>
+
+
+/** @defgroup SCATTERNET_DEMO_MAIN Scatternet Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default scan interval (units of 0.625ms, 0x10=2.5ms) */
+#define DEFAULT_SCAN_INTERVAL 0x20
+/** @brief Default scan window (units of 0.625ms, 0x10=2.5ms) */
+#define DEFAULT_SCAN_WINDOW 0x10
+
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default Maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03,
+ GAP_ADTYPE_APPEARANCE,
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ 0x02,
+ GAP_ADTYPE_FLAGS,
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+
+ 0x03,
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+
+ 0x0F,
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'S', 'C', 'A', 'T', 'T', 'E', 'R', 'N', 'E', 'T',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize gap related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_SCATTERNET";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+
+ /* Scan parameters */
+ uint8_t scan_mode = GAP_SCAN_MODE_ACTIVE;
+ uint16_t scan_interval = DEFAULT_SCAN_INTERVAL;
+ uint16_t scan_window = DEFAULT_SCAN_WINDOW;
+ uint8_t scan_filter_policy = GAP_SCAN_FILTER_ANY;
+ uint8_t scan_filter_duplicate = GAP_SCAN_FILTER_DUPLICATE_ENABLE;
+
+ /* advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MIN;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+ uint8_t auth_sec_req_enable = false;
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+
+ /* Set scan parameters */
+ le_scan_set_param(GAP_PARAM_SCAN_MODE, sizeof(scan_mode), &scan_mode);
+ le_scan_set_param(GAP_PARAM_SCAN_INTERVAL, sizeof(scan_interval), &scan_interval);
+ le_scan_set_param(GAP_PARAM_SCAN_WINDOW, sizeof(scan_window), &scan_window);
+ le_scan_set_param(GAP_PARAM_SCAN_FILTER_POLICY, sizeof(scan_filter_policy),
+ &scan_filter_policy);
+ le_scan_set_param(GAP_PARAM_SCAN_FILTER_DUPLICATES, sizeof(scan_filter_duplicate),
+ &scan_filter_duplicate);
+
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+#if F_BT_LE_USE_STATIC_RANDOM_ADDR
+ T_APP_STATIC_RANDOM_ADDR random_addr;
+ bool gen_addr = true;
+ uint8_t local_bd_type = GAP_LOCAL_ADDR_LE_RANDOM;
+ if (app_load_static_random_address(&random_addr) == 0)
+ {
+ if (random_addr.is_exist == true)
+ {
+ gen_addr = false;
+ }
+ }
+ if (gen_addr)
+ {
+ if (le_gen_rand_addr(GAP_RAND_ADDR_STATIC, random_addr.bd_addr) == GAP_CAUSE_SUCCESS)
+ {
+ random_addr.is_exist = true;
+ app_save_static_random_address(&random_addr);
+ }
+ }
+ le_cfg_local_identity_address(random_addr.bd_addr, GAP_IDENT_ADDR_RAND);
+ le_set_gap_param(GAP_PARAM_RANDOM_ADDR, 6, random_addr.bd_addr);
+ //only for peripheral,broadcaster
+ le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type);
+ //only for central,observer
+ le_scan_set_param(GAP_PARAM_SCAN_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type);
+#endif
+#if F_BT_AIRPLANE_MODE_SUPPORT
+ gap_register_app_cb(app_gap_common_callback);
+#endif
+#if F_BT_GAPS_CHAR_WRITEABLE
+ uint8_t appearance_prop = GAPS_PROPERTY_WRITE_ENABLE;
+ uint8_t device_name_prop = GAPS_PROPERTY_WRITE_ENABLE;
+ T_LOCAL_APPEARANCE appearance_local;
+ T_LOCAL_NAME local_device_name;
+ if (flash_load_local_appearance(&appearance_local) == 0)
+ {
+ gaps_set_parameter(GAPS_PARAM_APPEARANCE, sizeof(uint16_t), &appearance_local.local_appearance);
+ }
+
+ if (flash_load_local_name(&local_device_name) == 0)
+ {
+ gaps_set_parameter(GAPS_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, local_device_name.local_name);
+ }
+ gaps_set_parameter(GAPS_PARAM_APPEARANCE_PROPERTY, sizeof(appearance_prop), &appearance_prop);
+ gaps_set_parameter(GAPS_PARAM_DEVICE_NAME_PROPERTY, sizeof(device_name_prop), &device_name_prop);
+ gatt_register_callback(gap_service_callback);
+#endif
+#if F_BT_LE_5_0_SET_PHY_SUPPORT
+ uint8_t phys_prefer = GAP_PHYS_PREFER_ALL;
+ uint8_t tx_phys_prefer = GAP_PHYS_PREFER_1M_BIT | GAP_PHYS_PREFER_2M_BIT |
+ GAP_PHYS_PREFER_CODED_BIT;
+ uint8_t rx_phys_prefer = GAP_PHYS_PREFER_1M_BIT | GAP_PHYS_PREFER_2M_BIT |
+ GAP_PHYS_PREFER_CODED_BIT;
+ le_set_gap_param(GAP_PARAM_DEFAULT_PHYS_PREFER, sizeof(phys_prefer), &phys_prefer);
+ le_set_gap_param(GAP_PARAM_DEFAULT_TX_PHYS_PREFER, sizeof(tx_phys_prefer), &tx_phys_prefer);
+ le_set_gap_param(GAP_PARAM_DEFAULT_RX_PHYS_PREFER, sizeof(rx_phys_prefer), &rx_phys_prefer);
+#endif
+}
+
+/**
+ * @brief Add GATT services, clients and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+
+ client_init(3);
+ gaps_client_id = gaps_add_client(app_client_callback, APP_MAX_LINKS);
+ simple_ble_client_id = simp_ble_add_client(app_client_callback, APP_MAX_LINKS);
+ bas_client_id = bas_add_client(app_client_callback, APP_MAX_LINKS);
+ client_register_general_client_cb(app_client_callback);
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Scatternet APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group SCATTERNET_DEMO_MAIN */
+
diff --git a/src/sample/ble_scatternet/scatternet_app.c b/src/sample/ble_scatternet/scatternet_app.c
new file mode 100644
index 0000000..ce3c481
--- /dev/null
+++ b/src/sample/ble_scatternet/scatternet_app.c
@@ -0,0 +1,1205 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file scatternet_app.c
+ * @brief This file handles BLE scatternet application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+
+#include <string.h>
+#include <app_msg.h>
+#include <trace.h>
+#include <gap_scan.h>
+#include <gap.h>
+#include <gap_msg.h>
+#include <gap_bond_le.h>
+#include <scatternet_app.h>
+#include <link_mgr.h>
+#include <user_cmd.h>
+#include <user_cmd_parse.h>
+#include <simple_ble_client.h>
+#include <gaps_client.h>
+#include <bas_client.h>
+#include <profile_server.h>
+#include <simple_ble_service.h>
+#include <bas.h>
+#include <gatt_builtin_services.h>
+
+
+/** @defgroup SCATTERNET_APP Scatternet Application
+ * @brief This file handles BLE scatternet application routines.
+ * @{
+ */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup SCATTERNET_CLIIENT_CALLBACK
+ * @{
+ */
+T_CLIENT_ID simple_ble_client_id; /**< Simple ble service client id*/
+T_CLIENT_ID gaps_client_id; /**< gap service client id*/
+T_CLIENT_ID bas_client_id; /**< battery service client id*/
+/** @} */ /* End of group SCATTERNET_CLIIENT_CALLBACK */
+
+/** @addtogroup SCATTERNET_SEVER_CALLBACK
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group SCATTERNET_SEVER_CALLBACK */
+
+/** @defgroup SCATTERNET_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+ uint8_t rx_char;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+ case IO_MSG_TYPE_UART:
+ /* We handle user command informations from Data UART in this branch. */
+ rx_char = (uint8_t)io_msg.subtype;
+ user_cmd_collect(&user_cmd_if, &rx_char, sizeof(rx_char), user_cmd_table);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO4("app_handle_dev_state_evt: init state %d, adv state %d, scan state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state,
+ new_state.gap_scan_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ uint8_t bt_addr[6];
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+ gap_get_param(GAP_PARAM_BD_ADDR, bt_addr);
+ data_uart_print("local bd addr: 0x%2x:%2x:%2x:%2x:%2x:%2x\r\n",
+ bt_addr[5], bt_addr[4], bt_addr[3],
+ bt_addr[2], bt_addr[1], bt_addr[0]);
+ }
+ }
+
+ if (gap_dev_state.gap_scan_state != new_state.gap_scan_state)
+ {
+ if (new_state.gap_scan_state == GAP_SCAN_STATE_IDLE)
+ {
+ APP_PRINT_INFO0("GAP scan stop");
+ data_uart_print("GAP scan stop\r\n");
+ }
+ else if (new_state.gap_scan_state == GAP_SCAN_STATE_SCANNING)
+ {
+ APP_PRINT_INFO0("GAP scan start");
+ data_uart_print("GAP scan start\r\n");
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ data_uart_print("GAP adv stoped\r\n");
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ data_uart_print("GAP adv start\r\n");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ if (conn_id >= APP_MAX_LINKS)
+ {
+ return;
+ }
+
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d, conn_state(%d -> %d), disc_cause 0x%x",
+ conn_id, app_link_table[conn_id].conn_state, new_state, disc_cause);
+
+ app_link_table[conn_id].conn_state = new_state;
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR2("app_handle_conn_state_evt: connection lost, conn_id %d, cause 0x%x", conn_id,
+ disc_cause);
+ }
+
+ data_uart_print("Disconnect conn_id %d\r\n", conn_id);
+ memset(&app_link_table[conn_id], 0, sizeof(T_APP_LINK));
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, app_link_table[conn_id].bd_addr,
+ &app_link_table[conn_id].bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(app_link_table[conn_id].bd_addr), app_link_table[conn_id].bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ data_uart_print("Connected success conn_id %d\r\n", conn_id);
+#if F_BT_LE_5_0_SET_PHY_SUPPORT
+ {
+ uint8_t tx_phy;
+ uint8_t rx_phy;
+ le_get_conn_param(GAP_PARAM_CONN_RX_PHY_TYPE, &rx_phy, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TX_PHY_TYPE, &tx_phy, conn_id);
+ APP_PRINT_INFO2("GAP_CONN_STATE_CONNECTED: tx_phy %d, rx_phy %d", tx_phy, rx_phy);
+ }
+#endif
+ }
+ break;
+
+ default:
+ break;
+
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+ data_uart_print("Pair success\r\n");
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ data_uart_print("Pair failed: cause 0x%x\r\n", cause);
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO4("app_handle_conn_param_update_evt update success:conn_id %d, conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_id, conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR2("app_handle_conn_param_update_evt update failed: conn_id %d, cause 0x%x",
+ conn_id, cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO1("app_handle_conn_param_update_evt update pending: conn_id %d", conn_id);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO2("GAP_MSG_LE_BOND_PASSKEY_DISPLAY: conn_id %d, passkey %d",
+ conn_id, display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ data_uart_print("GAP_MSG_LE_BOND_PASSKEY_DISPLAY: conn_id %d, passkey %d\r\n",
+ conn_id,
+ display_value);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO2("GAP_MSG_LE_BOND_USER_CONFIRMATION: conn_id %d, passkey %d",
+ conn_id, display_value);
+ data_uart_print("GAP_MSG_LE_BOND_USER_CONFIRMATION: conn_id %d, passkey %d\r\n",
+ conn_id,
+ display_value);
+ //le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ //uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO2("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d, key_press %d",
+ conn_id, gap_msg.msg_data.gap_bond_passkey_input.key_press);
+ data_uart_print("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d\r\n", conn_id);
+ //le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_OOB_INPUT: conn_id %d", conn_id);
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group SCATTERNET_GAP_MSG */
+
+/** @defgroup SCATTERNET_SCAN_MGR Scan Information manager
+ * @brief Scan Information manager
+ * @{
+ */
+/**
+ * @brief Use 16 bit uuid to filter scan information
+ * @param[in] uuid 16 bit UUID.
+ * @param[in] scan_info point to scan information data.
+ * @return filter result
+ * @retval true found success
+ * @retval false not found
+ */
+bool filter_scan_info_by_uuid(uint16_t uuid, T_LE_SCAN_INFO *scan_info)
+{
+ uint8_t buffer[32];
+ uint8_t pos = 0;
+
+ while (pos < scan_info->data_len)
+ {
+ /* Length of the AD structure. */
+ uint8_t length = scan_info->data[pos++];
+ uint8_t type;
+
+ if ((length < 1) || (length >= 31))
+ {
+ return false;
+ }
+
+ if ((length > 0x01) && ((pos + length) <= 31))
+ {
+ /* Copy the AD Data to buffer. */
+ memcpy(buffer, scan_info->data + pos + 1, length - 1);
+ /* AD Type, one octet. */
+ type = scan_info->data[pos];
+
+ switch (type)
+ {
+ case GAP_ADTYPE_16BIT_MORE:
+ case GAP_ADTYPE_16BIT_COMPLETE:
+ case GAP_ADTYPE_SERVICES_LIST_16BIT:
+ {
+ uint16_t *p_uuid = (uint16_t *)(buffer);
+ uint8_t i = length - 1;
+
+ while (i >= 2)
+ {
+ APP_PRINT_INFO2(" AD Data: UUID16 List Item %d = 0x%x", i / 2, *p_uuid);
+ if (*p_uuid == uuid)
+ {
+ return true;
+ }
+ p_uuid++;
+ i -= 2;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ pos += length;
+ }
+ return false;
+}
+/** @} */ /* End of group SCATTERNET_SCAN_MGR */
+
+/** @defgroup SCATTERNET_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ /* common msg*/
+ case GAP_MSG_LE_READ_RSSI:
+ APP_PRINT_INFO3("GAP_MSG_LE_READ_RSSI:conn_id %d cause 0x%x rssi %d",
+ p_data->p_le_read_rssi_rsp->conn_id,
+ p_data->p_le_read_rssi_rsp->cause,
+ p_data->p_le_read_rssi_rsp->rssi);
+ break;
+
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_BOND_MODIFY_INFO:
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x",
+ p_data->p_le_bond_modify_info->type);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+ /* central reference msg*/
+ case GAP_MSG_LE_SCAN_INFO:
+ APP_PRINT_INFO5("GAP_MSG_LE_SCAN_INFO:adv_type 0x%x, bd_addr %s, remote_addr_type %d, rssi %d, data_len %d",
+ p_data->p_le_scan_info->adv_type,
+ TRACE_BDADDR(p_data->p_le_scan_info->bd_addr),
+ p_data->p_le_scan_info->remote_addr_type,
+ p_data->p_le_scan_info->rssi,
+ p_data->p_le_scan_info->data_len);
+
+ /* User can split interested information by using the function as follow. */
+ if (filter_scan_info_by_uuid(GATT_UUID_SIMPLE_PROFILE, p_data->p_le_scan_info))
+ {
+ APP_PRINT_INFO0("Found simple ble service");
+ link_mgr_add_device(p_data->p_le_scan_info->bd_addr, p_data->p_le_scan_info->remote_addr_type);
+ }
+ /* If you want to parse the scan info, please reference function app_parse_scan_info in observer app. */
+ break;
+
+ case GAP_MSG_LE_CONN_UPDATE_IND:
+ APP_PRINT_INFO5("GAP_MSG_LE_CONN_UPDATE_IND: conn_id %d, conn_interval_max 0x%x, conn_interval_min 0x%x, conn_latency 0x%x,supervision_timeout 0x%x",
+ p_data->p_le_conn_update_ind->conn_id,
+ p_data->p_le_conn_update_ind->conn_interval_max,
+ p_data->p_le_conn_update_ind->conn_interval_min,
+ p_data->p_le_conn_update_ind->conn_latency,
+ p_data->p_le_conn_update_ind->supervision_timeout);
+ /* if reject the proposed connection parameter from peer device, use APP_RESULT_REJECT. */
+ result = APP_RESULT_ACCEPT;
+ break;
+
+ case GAP_MSG_LE_SET_HOST_CHANN_CLASSIF:
+ APP_PRINT_INFO1("GAP_MSG_LE_SET_HOST_CHANN_CLASSIF: cause 0x%x",
+ p_data->p_le_set_host_chann_classif_rsp->cause);
+ break;
+ /* peripheral reference msg*/
+ case GAP_MSG_LE_ADV_UPDATE_PARAM:
+ APP_PRINT_INFO1("GAP_MSG_LE_ADV_UPDATE_PARAM: cause 0x%x",
+ p_data->p_le_adv_update_param_rsp->cause);
+ break;
+
+ case GAP_MSG_LE_DISABLE_SLAVE_LATENCY:
+ APP_PRINT_INFO1("GAP_MSG_LE_DISABLE_SLAVE_LATENCY: cause 0x%x",
+ p_data->p_le_disable_slave_latency_rsp->cause);
+ break;
+
+ case GAP_MSG_LE_UPDATE_PASSED_CHANN_MAP:
+ APP_PRINT_INFO1("GAP_MSG_LE_UPDATE_PASSED_CHANN_MAP:cause 0x%x",
+ p_data->p_le_update_passed_chann_map_rsp->cause);
+ break;
+#if F_BT_LE_5_0_SET_PHY_SUPPORT
+ case GAP_MSG_LE_PHY_UPDATE_INFO:
+ APP_PRINT_INFO4("GAP_MSG_LE_PHY_UPDATE_INFO:conn_id %d, cause 0x%x, rx_phy %d, tx_phy %d",
+ p_data->p_le_phy_update_info->conn_id,
+ p_data->p_le_phy_update_info->cause,
+ p_data->p_le_phy_update_info->rx_phy,
+ p_data->p_le_phy_update_info->tx_phy);
+ break;
+
+ case GAP_MSG_LE_REMOTE_FEATS_INFO:
+ {
+ uint8_t remote_feats[8];
+ APP_PRINT_INFO3("GAP_MSG_LE_REMOTE_FEATS_INFO: conn id %d, cause 0x%x, remote_feats %b",
+ p_data->p_le_remote_feats_info->conn_id,
+ p_data->p_le_remote_feats_info->cause,
+ TRACE_BINARY(8, p_data->p_le_remote_feats_info->remote_feats));
+ if (p_data->p_le_remote_feats_info->cause == GAP_SUCCESS)
+ {
+ memcpy(remote_feats, p_data->p_le_remote_feats_info->remote_feats, 8);
+ if (remote_feats[LE_SUPPORT_FEATURES_MASK_ARRAY_INDEX1] & LE_SUPPORT_FEATURES_LE_2M_MASK_BIT)
+ {
+ APP_PRINT_INFO0("GAP_MSG_LE_REMOTE_FEATS_INFO: support 2M");
+ }
+ if (remote_feats[LE_SUPPORT_FEATURES_MASK_ARRAY_INDEX1] & LE_SUPPORT_FEATURES_LE_CODED_PHY_MASK_BIT)
+ {
+ APP_PRINT_INFO0("GAP_MSG_LE_REMOTE_FEATS_INFO: support CODED");
+ }
+ }
+ }
+ break;
+#endif
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group SCATTERNET_GAP_CALLBACK */
+
+#if F_BT_AIRPLANE_MODE_SUPPORT
+/** @defgroup SCATTERNET_AIRPLANE Airplane Mode Handler
+ * @brief Use @ref F_BT_AIRPLANE_MODE_SUPPORT to open
+ * @{
+ */
+/**
+ * @brief Callback for gap common module to notify app
+ * @param[in] cb_type callback msy type @ref GAP_COMMON_MSG_TYPE.
+ * @param[in] p_cb_data point to callback data @ref T_GAP_CB_DATA.
+ * @retval void
+ */
+void app_gap_common_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_GAP_CB_DATA cb_data;
+ memcpy(&cb_data, p_cb_data, sizeof(T_GAP_CB_DATA));
+ APP_PRINT_INFO1("app_gap_common_callback: cb_type = %d", cb_type);
+ switch (cb_type)
+ {
+ case GAP_MSG_WRITE_AIRPLAN_MODE:
+ APP_PRINT_INFO1("GAP_MSG_WRITE_AIRPLAN_MODE: cause 0x%x",
+ cb_data.p_gap_write_airplan_mode_rsp->cause);
+ break;
+ case GAP_MSG_READ_AIRPLAN_MODE:
+ APP_PRINT_INFO2("GAP_MSG_READ_AIRPLAN_MODE: cause 0x%x, mode %d",
+ cb_data.p_gap_read_airplan_mode_rsp->cause,
+ cb_data.p_gap_read_airplan_mode_rsp->mode);
+ break;
+ default:
+ break;
+ }
+ return;
+}
+/** @} */
+#endif
+
+#if F_BT_GAPS_CHAR_WRITEABLE
+/** @defgroup SCATTERNET_GAPS_WRITE GAP Service Callback Handler
+ * @brief Use @ref F_BT_GAPS_CHAR_WRITEABLE to open
+ * @{
+ */
+/**
+ * @brief All the BT GAP service callback events are handled in this function
+ * @param[in] service_id Profile service ID
+ * @param[in] p_para Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT gap_service_callback(T_SERVER_ID service_id, void *p_para)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_GAPS_CALLBACK_DATA *p_gap_data = (T_GAPS_CALLBACK_DATA *)p_para;
+ APP_PRINT_INFO2("gap_service_callback conn_id = %d msg_type = %d\n", p_gap_data->conn_id,
+ p_gap_data->msg_type);
+ if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE)
+ {
+ switch (p_gap_data->msg_data.opcode)
+ {
+ case GAPS_WRITE_DEVICE_NAME:
+ {
+ T_LOCAL_NAME device_name;
+ memcpy(device_name.local_name, p_gap_data->msg_data.p_value, p_gap_data->msg_data.len);
+ device_name.local_name[p_gap_data->msg_data.len] = 0;
+ flash_save_local_name(&device_name);
+ }
+ break;
+
+ case GAPS_WRITE_APPEARANCE:
+ {
+ uint16_t appearance_val;
+ T_LOCAL_APPEARANCE appearance;
+
+ LE_ARRAY_TO_UINT16(appearance_val, p_gap_data->msg_data.p_value);
+ appearance.local_appearance = appearance_val;
+ flash_save_local_appearance(&appearance);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return result;
+}
+/** @} */
+#endif
+
+/** @defgroup SCATTERNET_CLIIENT_CALLBACK Profile Client Callback Event Handler
+ * @brief Handle profile client callback event
+ * @{
+ */
+
+/**
+ * @brief Callback will be called when data sent from profile client layer.
+ * @param client_id the ID distinguish which module sent the data.
+ * @param conn_id connection ID.
+ * @param p_data pointer to data.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ APP_PRINT_INFO2("app_client_callback: client_id %d, conn_id %d",
+ client_id, conn_id);
+ if (client_id == CLIENT_PROFILE_GENERAL_ID)
+ {
+ T_CLIENT_APP_CB_DATA *p_client_app_cb_data = (T_CLIENT_APP_CB_DATA *)p_data;
+ switch (p_client_app_cb_data->cb_type)
+ {
+ case CLIENT_APP_CB_TYPE_DISC_STATE:
+ if (p_client_app_cb_data->cb_content.disc_state_data.disc_state == DISC_STATE_SRV_DONE)
+ {
+ APP_PRINT_INFO0("Discovery All Service Procedure Done.");
+ }
+ else
+ {
+ APP_PRINT_INFO0("Discovery state send to application directly.");
+ }
+ break;
+ case CLIENT_APP_CB_TYPE_DISC_RESULT:
+ if (p_client_app_cb_data->cb_content.disc_result_data.result_type == DISC_RESULT_ALL_SRV_UUID16)
+ {
+ APP_PRINT_INFO3("Discovery All Primary Service: UUID16 0x%x, start handle 0x%x, end handle 0x%x.",
+ p_client_app_cb_data->cb_content.disc_result_data.result_data.p_srv_uuid16_disc_data->uuid16,
+ p_client_app_cb_data->cb_content.disc_result_data.result_data.p_srv_uuid16_disc_data->att_handle,
+ p_client_app_cb_data->cb_content.disc_result_data.result_data.p_srv_uuid16_disc_data->end_group_handle);
+ }
+ else
+ {
+ APP_PRINT_INFO0("Discovery result send to application directly.");
+ }
+ break;
+ default:
+ break;
+ }
+
+ }
+ else if (client_id == gaps_client_id)
+ {
+ T_GAPS_CLIENT_CB_DATA *p_gaps_cb_data = (T_GAPS_CLIENT_CB_DATA *)p_data;
+ switch (p_gaps_cb_data->cb_type)
+ {
+ case GAPS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_gaps_cb_data->cb_content.disc_state)
+ {
+ case DISC_GAPS_DONE:
+ /* Discovery Simple BLE service procedure successfully done. */
+ APP_PRINT_INFO0("app_client_callback: discover gaps procedure done.");
+ break;
+ case DISC_GAPS_FAILED:
+ /* Discovery Request failed. */
+ APP_PRINT_INFO0("app_client_callback: discover gaps request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+ case GAPS_CLIENT_CB_TYPE_READ_RESULT:
+ switch (p_gaps_cb_data->cb_content.read_result.type)
+ {
+ case GAPS_READ_DEVICE_NAME:
+ if (p_gaps_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO1("GAPS_READ_DEVICE_NAME: device name %s.",
+ TRACE_STRING(p_gaps_cb_data->cb_content.read_result.data.device_name.p_value));
+ }
+ else
+ {
+ APP_PRINT_INFO1("GAPS_READ_DEVICE_NAME: failded cause 0x%x",
+ p_gaps_cb_data->cb_content.read_result.cause);
+ }
+ break;
+ case GAPS_READ_APPEARANCE:
+ if (p_gaps_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO1("GAPS_READ_APPEARANCE: appearance %d",
+ p_gaps_cb_data->cb_content.read_result.data.appearance);
+ }
+ else
+ {
+ APP_PRINT_INFO1("GAPS_READ_APPEARANCE: failded cause 0x%x",
+ p_gaps_cb_data->cb_content.read_result.cause);
+ }
+ break;
+ case GAPS_READ_CENTRAL_ADDR_RESOLUTION:
+ if (p_gaps_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO1("GAPS_READ_CENTRAL_ADDR_RESOLUTION: central_addr_res %d",
+ p_gaps_cb_data->cb_content.read_result.data.central_addr_res);
+ }
+ else
+ {
+ APP_PRINT_INFO1("GAPS_READ_CENTRAL_ADDR_RESOLUTION: failded cause 0x%x",
+ p_gaps_cb_data->cb_content.read_result.cause);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (client_id == simple_ble_client_id)
+ {
+ T_SIMP_CLIENT_CB_DATA *p_simp_client_cb_data = (T_SIMP_CLIENT_CB_DATA *)p_data;
+ uint16_t value_size;
+ uint8_t *p_value;
+ switch (p_simp_client_cb_data->cb_type)
+ {
+ case SIMP_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_simp_client_cb_data->cb_content.disc_state)
+ {
+ case DISC_SIMP_DONE:
+ APP_PRINT_INFO0("app_client_callback: discover simp procedure done.");
+ break;
+ case DISC_SIMP_FAILED:
+ /* Discovery Request failed. */
+ APP_PRINT_INFO0("app_client_callback: discover simp request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+ case SIMP_CLIENT_CB_TYPE_READ_RESULT:
+ switch (p_simp_client_cb_data->cb_content.read_result.type)
+ {
+ case SIMP_READ_V1_READ:
+ if (p_simp_client_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ value_size = p_simp_client_cb_data->cb_content.read_result.data.v1_read.value_size;
+ p_value = p_simp_client_cb_data->cb_content.read_result.data.v1_read.p_value;
+ APP_PRINT_INFO2("SIMP_READ_V1_READ: value_size %d, value %b",
+ value_size, TRACE_BINARY(value_size, p_value));
+ }
+ else
+ {
+ APP_PRINT_ERROR1("SIMP_READ_V1_READ: failed cause 0x%x",
+ p_simp_client_cb_data->cb_content.read_result.cause);
+ }
+ break;
+ case SIMP_READ_V3_NOTIFY_CCCD:
+ if (p_simp_client_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO1("SIMP_READ_V3_NOTIFY_CCCD: notify %d",
+ p_simp_client_cb_data->cb_content.read_result.data.v3_notify_cccd);
+ }
+ else
+ {
+ APP_PRINT_ERROR1("SIMP_READ_V3_NOTIFY_CCCD: failed cause 0x%x",
+ p_simp_client_cb_data->cb_content.read_result.cause);
+ };
+ break;
+ case SIMP_READ_V4_INDICATE_CCCD:
+ if (p_simp_client_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO1("SIMP_READ_V4_INDICATE_CCCD: indicate %d",
+ p_simp_client_cb_data->cb_content.read_result.data.v4_indicate_cccd);
+ }
+ else
+ {
+ APP_PRINT_ERROR1("SIMP_READ_V4_INDICATE_CCCD: failed cause 0x%x",
+ p_simp_client_cb_data->cb_content.read_result.cause);
+ };
+ break;
+
+ default:
+ break;
+ }
+ break;
+ case SIMP_CLIENT_CB_TYPE_WRITE_RESULT:
+ switch (p_simp_client_cb_data->cb_content.write_result.type)
+ {
+ case SIMP_WRITE_V2_WRITE:
+ APP_PRINT_INFO1("SIMP_WRITE_V2_WRITE: write result 0x%x",
+ p_simp_client_cb_data->cb_content.write_result.cause);
+ break;
+ case SIMP_WRITE_V3_NOTIFY_CCCD:
+ APP_PRINT_INFO1("SIMP_WRITE_V3_NOTIFY_CCCD: write result 0x%x",
+ p_simp_client_cb_data->cb_content.write_result.cause);
+ break;
+ case SIMP_WRITE_V4_INDICATE_CCCD:
+ APP_PRINT_INFO1("SIMP_WRITE_V4_INDICATE_CCCD: write result 0x%x",
+ p_simp_client_cb_data->cb_content.write_result.cause);
+ break;
+ default:
+ break;
+ }
+ break;
+ case SIMP_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_simp_client_cb_data->cb_content.notif_ind_data.type)
+ {
+ case SIMP_V3_NOTIFY:
+ value_size = p_simp_client_cb_data->cb_content.notif_ind_data.data.value_size;
+ p_value = p_simp_client_cb_data->cb_content.notif_ind_data.data.p_value;
+ APP_PRINT_INFO2("SIMP_V3_NOTIFY: value_size %d, value %b",
+ value_size, TRACE_BINARY(value_size, p_value));
+ break;
+ case SIMP_V4_INDICATE:
+ value_size = p_simp_client_cb_data->cb_content.notif_ind_data.data.value_size;
+ p_value = p_simp_client_cb_data->cb_content.notif_ind_data.data.p_value;
+ APP_PRINT_INFO2("SIMP_V4_INDICATE: value_size %d, value %b",
+ value_size, TRACE_BINARY(value_size, p_value));
+ break;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ if (client_id == bas_client_id)
+ {
+ T_BAS_CLIENT_CB_DATA *p_bas_cb_data = (T_BAS_CLIENT_CB_DATA *)p_data;
+ switch (p_bas_cb_data->cb_type)
+ {
+ case BAS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_bas_cb_data->cb_content.disc_state)
+ {
+ case DISC_BAS_DONE:
+ /* Discovery BAS procedure successfully done. */
+ APP_PRINT_INFO0("app_client_callback: discover bas procedure done");
+ break;
+ case DISC_BAS_FAILED:
+ /* Discovery Request failed. */
+ APP_PRINT_INFO0("app_client_callback: discover bas procedure failed");
+ break;
+ default:
+ break;
+ }
+ break;
+ case BAS_CLIENT_CB_TYPE_READ_RESULT:
+ switch (p_bas_cb_data->cb_content.read_result.type)
+ {
+ case BAS_READ_BATTERY_LEVEL:
+ if (p_bas_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery level %d",
+ p_bas_cb_data->cb_content.read_result.data.battery_level);
+ }
+ else
+ {
+ APP_PRINT_ERROR1("BAS_READ_BATTERY_LEVEL: failed cause 0x%x",
+ p_bas_cb_data->cb_content.read_result.cause);
+ }
+ break;
+ case BAS_READ_NOTIFY:
+ if (p_bas_cb_data->cb_content.read_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO1("BAS_READ_NOTIFY: notify %d",
+ p_bas_cb_data->cb_content.read_result.data.notify);
+ }
+ else
+ {
+ APP_PRINT_ERROR1("BAS_READ_NOTIFY: failed cause 0x%x",
+ p_bas_cb_data->cb_content.read_result.cause);
+ };
+ break;
+
+ default:
+ break;
+ }
+ break;
+ case BAS_CLIENT_CB_TYPE_WRITE_RESULT:
+ switch (p_bas_cb_data->cb_content.write_result.type)
+ {
+ case BAS_WRITE_NOTIFY_ENABLE:
+ APP_PRINT_INFO1("BAS_WRITE_NOTIFY_ENABLE: write result 0x%x",
+ p_bas_cb_data->cb_content.write_result.cause);
+ break;
+ case BAS_WRITE_NOTIFY_DISABLE:
+ APP_PRINT_INFO1("BAS_WRITE_NOTIFY_DISABLE: write result 0x%x",
+ p_bas_cb_data->cb_content.write_result.cause);
+ break;
+ default:
+ break;
+ }
+ break;
+ case BAS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ APP_PRINT_INFO1("BAS_CLIENT_CB_TYPE_NOTIF_IND_RESULT: battery level %d",
+ p_bas_cb_data->cb_content.notify_data.battery_level);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return result;
+}
+/** @} */ /* End of group SCATTERNET_CLIENT_CALLBACK */
+/** @defgroup SCATTERNET_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+/** @} */ /* End of group SCATTERNET_SEVER_CALLBACK */
+/** @} */ /* End of group SCATTERNET_APP */
+
diff --git a/src/sample/ble_scatternet/scatternet_app.h b/src/sample/ble_scatternet/scatternet_app.h
new file mode 100644
index 0000000..b40363d
--- /dev/null
+++ b/src/sample/ble_scatternet/scatternet_app.h
@@ -0,0 +1,77 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file scatternet_app.h
+ * @brief This file handles BLE scatternet application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+#ifndef _SCATTERNET_APP_H_
+#define _SCATTERNET_APP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_client.h>
+#include <profile_server.h>
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_CLIENT_ID gaps_client_id; /**< Simple ble service client id*/
+extern T_CLIENT_ID simple_ble_client_id; /**< gap service client id*/
+extern T_CLIENT_ID bas_client_id; /**< battery service client id*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+/**
+ * @brief Callback will be called when data sent from profile client layer.
+ * @param client_id the ID distinguish which module sent the data.
+ * @param conn_id connection ID.
+ * @param p_data pointer to data.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data);
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+#if F_BT_AIRPLANE_MODE_SUPPORT
+void app_gap_common_callback(uint8_t cb_type, void *p_cb_data);
+#endif
+#if F_BT_GAPS_CHAR_WRITEABLE
+T_APP_RESULT gap_service_callback(T_SERVER_ID service_id, void *p_para);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/ble_scatternet/user_cmd.c b/src/sample/ble_scatternet/user_cmd.c
new file mode 100644
index 0000000..72fbb81
--- /dev/null
+++ b/src/sample/ble_scatternet/user_cmd.c
@@ -0,0 +1,1968 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file user_cmd.c
+ * @brief User defined test commands.
+ * @details User command interfaces.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <trace.h>
+#include <profile_client.h>
+#include <gap_bond_le.h>
+#include <gap_scan.h>
+#include <user_cmd.h>
+#include <gap.h>
+#include <gap_conn_le.h>
+#include <link_mgr.h>
+#include <simple_ble_client.h>
+#include <gaps_client.h>
+#include <bas_client.h>
+#include <gap_adv.h>
+#include <scatternet_app.h>
+#include <simple_ble_service.h>
+#include <bas.h>
+#include <gatt_builtin_services.h>
+
+
+/** @defgroup SCATTERNET_CMD Scatternet User Command
+ * @brief This file handles Scatternet User Command.
+ * @{
+ */
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @brief User command interface data, used to parse the commands from Data UART. */
+T_USER_CMD_IF user_cmd_if;
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Read the RSSI value
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "rssiread",
+ "rssiread [conn_id]\n\r",
+ "Read the RSSI value\n\r",
+ cmd_rssiread
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_rssiread(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAP_CAUSE cause;
+ cause = le_read_rssi(conn_id);
+
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Show all devices connecting status
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "showcon",
+ "showcon\n\r",
+ "Show all devices connecting status\n\r",
+ cmd_showcon
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_showcon(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id;
+ T_GAP_CONN_INFO conn_info;
+ for (conn_id = 0; conn_id < APP_MAX_LINKS; conn_id++)
+ {
+ if (le_get_conn_info(conn_id, &conn_info))
+ {
+ data_uart_print("ShowCon conn_id %d state 0x%x role %d\r\n", conn_id,
+ conn_info.conn_state, conn_info.role);
+ data_uart_print("RemoteBd = [%02x:%02x:%02x:%02x:%02x:%02x] type = %d\r\n",
+ conn_info.remote_bd[5], conn_info.remote_bd[4],
+ conn_info.remote_bd[3], conn_info.remote_bd[2],
+ conn_info.remote_bd[1], conn_info.remote_bd[0],
+ conn_info.remote_bd_type);
+ }
+ }
+ data_uart_print("active link num %d, idle link num %d\r\n",
+ le_get_active_link_num(), le_get_idle_link_num());
+ return (RESULT_SUCCESS);
+}
+
+/**
+ * @brief LE connection param update request
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "conupdreq",
+ "conupdreq [conn_id] [interval_min] [interval_max] [latency] [supervision_timeout]\n\r",
+ "LE connection param update request\r\n\
+ sample: conupdreq 0 0x30 0x40 0 500\n\r",
+ cmd_conupdreq
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_conupdreq(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t conn_interval_min = p_parse_value->dw_param[1];
+ uint16_t conn_interval_max = p_parse_value->dw_param[2];
+ uint16_t conn_latency = p_parse_value->dw_param[3];
+ uint16_t supervision_timeout = p_parse_value->dw_param[4];
+
+
+ cause = le_update_conn_param(conn_id,
+ conn_interval_min,
+ conn_interval_max,
+ conn_latency,
+ supervision_timeout,
+ 2 * (conn_interval_min - 1),
+ 2 * (conn_interval_max - 1)
+ );
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Disconnect to remote device
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "disc",
+ "disc [conn_id]\n\r",
+ "Disconnect to remote device\n\r",
+ cmd_disc
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_disc(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAP_CAUSE cause;
+ cause = le_disconnect(conn_id);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Using connected device address to modify whitelist
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "wl",
+ "wl [op] [conn_id]\n\r",
+ "Using connected device address to modify whitelist \r\n\
+ [op]: 0-(clear), 1-(add), 2-(remove)\r\n\
+ sample: wl 0 1\n\r",
+ cmd_wl
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_wl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ T_GAP_WHITE_LIST_OP op = (T_GAP_WHITE_LIST_OP)p_parse_value->dw_param[0];
+ uint8_t conn_id = p_parse_value->dw_param[1];
+ T_GAP_CONN_INFO conn_info;
+
+ if (op == GAP_WHITE_LIST_OP_CLEAR)
+ {
+ cause = le_modify_white_list(GAP_WHITE_LIST_OP_CLEAR, NULL, GAP_REMOTE_ADDR_LE_PUBLIC);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+
+ if (le_get_conn_info(conn_id, &conn_info))
+ {
+ cause = le_modify_white_list(op, conn_info.remote_bd,
+ (T_GAP_REMOTE_ADDR_TYPE)conn_info.remote_bd_type);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ else
+ {
+ return RESULT_CMD_ERR_PARAM;
+ }
+}
+/**
+ * @brief Config authentication mode
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "authmode",
+ "authmode [auth_flags] [io_cap] [sec_enable] [oob_enable]\n\r",
+ "Config authentication mode\r\n\
+ [auth_flags]:authentication req bit field: bit0-(bonding), bit2-(MITM), bit3-(SC)\r\n\
+ [io_cap]:set io Capabilities: 0-(display only), 1-(display yes/no), 2-(keyboard noly), 3-(no IO), 4-(keyboard display)\r\n\
+ [sec_enable]:Start smp pairing procedure when connected: 0-(disable), 1-(enable)\r\n\
+ [oob_enable]:Enable oob flag: 0-(disable), 1-(enable)\r\n\
+ sample: authmode 0x5 2 1 0\n\r",
+ cmd_authmode
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_authmode(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t oob_enable = false;
+ uint8_t auth_sec_req_enable = false;
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ if (p_parse_value->param_count > 0)
+ {
+ auth_flags = p_parse_value->dw_param[0];
+ auth_sec_req_flags = p_parse_value->dw_param[0];
+ }
+ if (p_parse_value->param_count > 1)
+ {
+ auth_io_cap = p_parse_value->dw_param[1];
+ }
+ if (p_parse_value->param_count > 2)
+ {
+ auth_sec_req_enable = p_parse_value->dw_param[2];
+ }
+ if (p_parse_value->param_count > 3)
+ {
+ oob_enable = p_parse_value->dw_param[3];
+ }
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(uint8_t), &oob_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+ cause = gap_set_pairable_mode();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Send authentication request
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "sauth",
+ "sauth [conn_id]\n\r",
+ "Send authentication request\n\r",
+ cmd_sauth
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_sauth(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAP_CAUSE cause;
+ cause = le_bond_pair(conn_id);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Send user confirmation when show GAP_MSG_LE_BOND_USER_CONFIRMATION
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "userconf",
+ "userconf [conn_id] [conf]\n\r",
+ "Send user confirmation when show GAP_MSG_LE_BOND_USER_CONFIRMATION\r\n\
+ [conf]: 0-(Reject), 1-(Accept)\r\n\
+ sample: userconf 0 1\n\r",
+ cmd_userconf
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_userconf(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAP_CFM_CAUSE confirm = GAP_CFM_CAUSE_ACCEPT;
+ T_GAP_CAUSE cause;
+ if (p_parse_value->dw_param[1] == 0)
+ {
+ confirm = GAP_CFM_CAUSE_REJECT;
+ }
+ cause = le_bond_user_confirm(conn_id, confirm);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Input passkey when show GAP_MSG_LE_BOND_PASSKEY_INPUT
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "authkey",
+ "authkey [conn_id] [passkey]\n\r",
+ "Input passkey when show GAP_MSG_LE_BOND_PASSKEY_INPUT\r\n\
+ [passkey]: 0 - 999999\r\n\
+ sample: authkey 0 123456\n\r",
+ cmd_authkey
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_authkey(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint32_t passcode = p_parse_value->dw_param[1];
+ T_GAP_CAUSE cause;
+ T_GAP_CFM_CAUSE confirm = GAP_CFM_CAUSE_ACCEPT;
+ if (passcode > GAP_PASSCODE_MAX)
+ {
+ confirm = GAP_CFM_CAUSE_REJECT;
+ }
+ cause = le_bond_passkey_input_confirm(conn_id, passcode,
+ confirm);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Clear all bonded devices information
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "bondclear",
+ "bondclear\n\r",
+ "Clear all bonded devices information\n\r",
+ cmd_bondclear
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_bondclear(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ le_bond_clear_all_keys();
+ return (RESULT_SUCCESS);
+}
+
+/**
+ * @brief Get all Bonded devices information
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "bondinfo",
+ "bondinfo\n\r",
+ "Get all Bonded devices information\n\r",
+ cmd_bondinfo
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_bondinfo(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t i;
+ T_LE_KEY_ENTRY *p_entry;
+ uint8_t bond_storage_num = le_get_max_le_paired_device_num();
+ for (i = 0; i < bond_storage_num; i++)
+ {
+ p_entry = le_find_key_entry_by_idx(i);
+ if (p_entry != NULL)
+ {
+ data_uart_print("bond_dev[%d]: bd 0x%02x%02x%02x%02x%02x%02x, addr_type %d, flags 0x%x\r\n",
+ p_entry->idx,
+ p_entry->remote_bd.addr[5],
+ p_entry->remote_bd.addr[4],
+ p_entry->remote_bd.addr[3],
+ p_entry->remote_bd.addr[2],
+ p_entry->remote_bd.addr[1],
+ p_entry->remote_bd.addr[0],
+ p_entry->remote_bd.remote_bd_type,
+ p_entry->flags);
+ }
+ }
+
+ return (RESULT_SUCCESS);
+}
+
+#if F_BT_AIRPLANE_MODE_SUPPORT
+/**
+ * @brief Write airplane mode
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "wairplane",
+ "wairplane [mode]\n\r",
+ "Write airplane mode\r\n\
+ [mode]: 0-(normal), 1-(airplane)\n\r",
+ cmd_wairplane
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_wairplane(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ uint8_t mode = p_parse_value->dw_param[0];
+ cause = gap_write_airplan_mode(mode);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Read airplane mode
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "rairplane",
+ "rairplane\n\r",
+ "Read airplane mode\n\r",
+ cmd_rairplane
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_rairplane(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ cause = gap_read_airplan_mode();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+#endif
+/************************** Central only *************************************/
+/**
+ * @brief Start scan
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "scan",
+ "scan [filter_policy] [filter_duplicate]\n\r",
+ "Start scan\r\n\
+ [filter_policy]: 0-(any), 1-(whitelist), 2-(any RPA), 3-(whitelist RPA) \r\n\
+ [filter_duplicate]: 0-(disable), 1-(enable) \n\r",
+ cmd_scan
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_scan(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ uint8_t scan_filter_policy = GAP_SCAN_FILTER_ANY;
+ uint8_t scan_filter_duplicate = GAP_SCAN_FILTER_DUPLICATE_ENABLE;
+
+ if (p_parse_value->param_count > 0)
+ {
+ scan_filter_policy = p_parse_value->dw_param[0];
+ }
+ if (p_parse_value->param_count > 1)
+ {
+ scan_filter_duplicate = p_parse_value->dw_param[1];
+ }
+
+ link_mgr_clear_device_list();
+ le_scan_set_param(GAP_PARAM_SCAN_FILTER_POLICY, sizeof(scan_filter_policy),
+ &scan_filter_policy);
+ le_scan_set_param(GAP_PARAM_SCAN_FILTER_DUPLICATES, sizeof(scan_filter_duplicate),
+ &scan_filter_duplicate);
+ cause = le_scan_start();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Stop scan
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "stopscan",
+ "stopscan\n\r",
+ "Stop scan\n\r",
+ cmd_stopscan
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_stopscan(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ cause = le_scan_stop();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Show scan dev list: filter simple ble service
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "showdev",
+ "showdev\n\r",
+ "Show scan dev list: filter simple ble service\n\r",
+ cmd_showdev
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_showdev(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t i;
+ data_uart_print("Advertising and Scan response: filter uuid = 0xA00A dev list\r\n");
+ for (i = 0; i < dev_list_count; i++)
+ {
+ data_uart_print("RemoteBd[%d] = [%02x:%02x:%02x:%02x:%02x:%02x] type = %d\r\n",
+ i,
+ dev_list[i].bd_addr[5], dev_list[i].bd_addr[4],
+ dev_list[i].bd_addr[3], dev_list[i].bd_addr[2],
+ dev_list[i].bd_addr[1], dev_list[i].bd_addr[0],
+ dev_list[i].bd_type);
+ if (dev_list[i].bd_type == GAP_REMOTE_ADDR_LE_RANDOM)
+ {
+ uint8_t addr = dev_list[i].bd_addr[5] & RANDOM_ADDR_MASK;
+ if (addr == RANDOM_ADDR_MASK_STATIC)
+ {
+ data_uart_print("Static Random Addr\r\n");
+ }
+ else if (addr == RANDOM_ADDR_MASK_RESOLVABLE)
+ {
+ data_uart_print("Resolv Random Addr\r\n");
+ }
+ else if (addr == RANDOM_ADDR_MASK_NON_RESOLVABLE)
+ {
+ data_uart_print("Non-resolv Random Addr\r\n");
+ }
+ else
+ {
+ data_uart_print("Unknown Random Addr\r\n");
+ }
+ }
+ }
+
+ return (RESULT_SUCCESS);
+}
+
+/**
+ * @brief Connect to remote device: use address
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "con",
+ "con [BD0] [BD1] [BD2] [BD3] [BD4] [BD5] [addr_type]\n\r",
+ "Connect to remote device: use address\r\n\
+ [BD0] [BD1] [BD2] [BD3] [BD4] [BD5]: remote device address\r\n\
+ [addr_type]: 0-(public), 1-(random)\r\n\
+ sample: con x11 x22 x33 x44 x55 x66 0 \n\r",
+ cmd_con
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_con(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ uint8_t addr[6] = {0};
+ uint8_t addr_len;
+ uint8_t addr_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ T_GAP_LE_CONN_REQ_PARAM conn_req_param;
+#if F_BT_LE_USE_STATIC_RANDOM_ADDR
+ T_GAP_LOCAL_ADDR_TYPE local_addr_type = GAP_LOCAL_ADDR_LE_RANDOM;
+#else
+ T_GAP_LOCAL_ADDR_TYPE local_addr_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+#endif
+ conn_req_param.scan_interval = 0x10;
+ conn_req_param.scan_window = 0x10;
+ conn_req_param.conn_interval_min = 80;
+ conn_req_param.conn_interval_max = 80;
+ conn_req_param.conn_latency = 0;
+ conn_req_param.supv_tout = 1000;
+ conn_req_param.ce_len_min = 2 * (conn_req_param.conn_interval_min - 1);
+ conn_req_param.ce_len_max = 2 * (conn_req_param.conn_interval_max - 1);
+ le_set_conn_param(GAP_CONN_PARAM_1M, &conn_req_param);
+
+ for (addr_len = 0; addr_len < GAP_BD_ADDR_LEN; addr_len++)
+ {
+ addr[addr_len] = p_parse_value->dw_param[GAP_BD_ADDR_LEN - addr_len - 1];
+ }
+ if (p_parse_value->param_count >= 7)
+ {
+ addr_type = p_parse_value->dw_param[6];
+ }
+
+ cause = le_connect(GAP_PHYS_CONN_INIT_1M_BIT, addr, (T_GAP_REMOTE_ADDR_TYPE)addr_type,
+ local_addr_type,
+ 1000);
+
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Connect to remote device: use showdev to show idx
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "condev",
+ "condev [idx]\n\r",
+ "Connect to remote device: use showdev to show idx\r\n\
+ [idx]: use cmd showdev to show idx before use this cmd\r\n\
+ sample: condev 0\n\r",
+ cmd_condev
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_condev(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t dev_idx = p_parse_value->dw_param[0];
+ if (dev_idx < dev_list_count)
+ {
+ T_GAP_CAUSE cause;
+ T_GAP_LE_CONN_REQ_PARAM conn_req_param;
+#if F_BT_LE_USE_STATIC_RANDOM_ADDR
+ T_GAP_LOCAL_ADDR_TYPE local_addr_type = GAP_LOCAL_ADDR_LE_RANDOM;
+#else
+ T_GAP_LOCAL_ADDR_TYPE local_addr_type = GAP_LOCAL_ADDR_LE_PUBLIC;
+#endif
+
+ conn_req_param.scan_interval = 0x10;
+ conn_req_param.scan_window = 0x10;
+ conn_req_param.conn_interval_min = 80;
+ conn_req_param.conn_interval_max = 80;
+ conn_req_param.conn_latency = 0;
+ conn_req_param.supv_tout = 1000;
+ conn_req_param.ce_len_min = 2 * (conn_req_param.conn_interval_min - 1);
+ conn_req_param.ce_len_max = 2 * (conn_req_param.conn_interval_max - 1);
+ le_set_conn_param(GAP_CONN_PARAM_1M, &conn_req_param);
+ cause = le_connect(GAP_PHYS_CONN_INIT_1M_BIT,
+ dev_list[dev_idx].bd_addr,
+ (T_GAP_REMOTE_ADDR_TYPE)dev_list[dev_idx].bd_type,
+ local_addr_type,
+ 1000);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+ }
+ else
+ {
+ return RESULT_ERR;
+ }
+}
+
+/**
+ * @brief Set Host Channel Classification
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "chanclassset",
+ "chanclassset [idx0] [idx1] [idx2] [idx3] [idx4]\n\r",
+ "Set Host Channel Classification\r\n\
+ [idx0] [idx1] [idx2] [idx3] [idx4]: channel bit map\r\n\
+ sample: chanclassset xff xff x3f xff x00\n\r",
+ cmd_chanclassset
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_chanclassset(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ uint8_t chan_map[5] = {0};
+ uint8_t i;
+ for (i = 0; i < 5; i++)
+ {
+ chan_map[i] = (uint8_t)p_parse_value->dw_param[i];
+ }
+
+ chan_map[4] = chan_map[4] & 0x1F;
+
+ cause = le_set_host_chann_classif(chan_map);
+
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+/************************** GATT client *************************************/
+/**
+ * @brief Service discovery, discover all primary services
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "srvdis",
+ "srvdis [conn_id]\n\r",
+ "Service discovery, discover all primary services\n\r",
+ cmd_srvdis
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_srvdis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAP_CAUSE cause;
+
+ cause = client_all_primary_srv_discovery(conn_id, CLIENT_PROFILE_GENERAL_ID);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief Start discovery gap service
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "gapdis",
+ "gapdis [conn_id]\n\r",
+ "Start discovery gap service\n\r",
+ cmd_gapdis
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_gapdis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = gaps_start_discovery(conn_id);
+ if (ret)
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+/**
+ * @brief Read GAP service characteristic value
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "gapread",
+ "gapread [conn_id] [type]\n\r",
+ "Read GAP service characteristic value\r\n\
+ [type]: 0-(read device name), 1-(read appearance)\r\n\
+ simple: gapread 0 0\n\r",
+ cmd_gapread
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_gapread(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GAPS_READ_TYPE read_type = (T_GAPS_READ_TYPE)p_parse_value->dw_param[1];
+ bool ret = gaps_read(conn_id, read_type);
+ if (ret)
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief List GAP service handle cache
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "gaphdl",
+ "gaphdl [conn_id]\n\r",
+ "List GAP service handle cache\n\r",
+ cmd_gaphdl
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_gaphdl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t hdl_cache[HDL_GAPS_CACHE_LEN];
+ uint8_t hdl_idx;
+ bool ret = gaps_get_hdl_cache(conn_id, hdl_cache,
+ sizeof(uint16_t) * HDL_GAPS_CACHE_LEN);
+
+ if (ret)
+ {
+ for (hdl_idx = HDL_GAPS_SRV_START; hdl_idx < HDL_GAPS_CACHE_LEN; hdl_idx++)
+ {
+ data_uart_print("-->Index %d -- Handle 0x%x\r\n", hdl_idx, hdl_cache[hdl_idx]);
+ }
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief Start discovery simple ble service
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "simpdis",
+ "simpdis [conn_id]\n\r",
+ "Start discovery simple ble service\n\r",
+ cmd_simpdis
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_simpdis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = simp_ble_client_start_discovery(conn_id);
+ if (ret)
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+/**
+ * @brief Read simple ble service characteristic and descriptor value
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "simpread",
+ "simpread [conn_id] [type] [pattern]\n\r",
+ "Read simple ble service characteristic and descriptor value\r\n\
+ [type]: 0-(read v1), 1-(v3 cccd), 2-(v4 cccd)\r\n\
+ [pattern]: 0-(read by handle), 1-(read by uuid)\r\n\
+ sample: simpread 0 1 0 \n\r",
+ cmd_simpread
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_simpread(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ /* Indicate which char to be read. */
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret;
+ T_SIMP_READ_TYPE read_type = (T_SIMP_READ_TYPE)p_parse_value->dw_param[1];
+ /* Read by handle or UUID, 1--by UUID, 0--by handle. */
+ uint8_t read_pattern = (uint8_t)p_parse_value->dw_param[2];
+
+ if (read_pattern)
+ {
+ ret = simp_ble_client_read_by_uuid(conn_id, read_type);
+ }
+ else
+ {
+ ret = simp_ble_client_read_by_handle(conn_id, read_type);
+ }
+
+ if (ret)
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief Config simple ble service client characteristic configuration descriptor value
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "simpcccd",
+ "simpcccd [conn_id] [type] [enable]\n\r",
+ "Config simple ble service client characteristic configuration descriptor value\r\n\
+ [type]: 0-(v3 notify), 1-(v4 indication)\r\n\
+ [enable]: 0-(disable), 1-(enable) \r\n\
+ sample: simpcccd 0 1 1\n\r",
+ cmd_simpcccd
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_simpcccd(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ /* Indicate which char CCCD command. */
+ bool ret = false;
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint8_t type = p_parse_value->dw_param[1];
+ /* Enable or disable, 1--enable, 0--disable. */
+ bool cccd_data = (bool)p_parse_value->dw_param[2];
+
+ switch (type)
+ {
+ case 0:/* V3 Notify char notif enable/disable. */
+ ret = simp_ble_client_set_v3_notify(conn_id, cccd_data);
+ break;
+ case 1:/* V4 Indicate char indicate enable/disable. */
+ ret = simp_ble_client_set_v4_ind(conn_id, cccd_data);
+ break;
+ default:
+ break;
+ }
+
+ if (ret)
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief Write simple ble service V2 characteristic value
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "simpwritev2",
+ "simpwritev2 [conn_id] [type] [len]\n\r",
+ "Write simple ble service V2 characteristic value\r\n\
+ [type]: 1-(write request), 2-(write command) \r\n\
+ [len]: type=1 len range:0-270, type=2 len range: 0-(mtu-3)\r\n\
+ sample: simpwritev2 0 1 10\n\r",
+ cmd_simpwritev2
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_simpwritev2(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ T_GATT_WRITE_TYPE write_type = (T_GATT_WRITE_TYPE)p_parse_value->dw_param[1];
+ uint8_t data[270];
+ uint16_t length = 270;
+ uint16_t i;
+ for (i = 0; i < 270; i++)
+ {
+ data[i] = i;
+ }
+ if (write_type > GATT_WRITE_TYPE_CMD)
+ {
+ return (RESULT_ERR);
+ }
+ if (p_parse_value->param_count > 2)
+ {
+ length = p_parse_value->dw_param[2];
+ if (length > 270)
+ {
+ length = 270;
+ }
+ }
+ if (simp_ble_client_write_v2_char(conn_id, length, data, write_type))
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief List simple ble service handle cache
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "simphdl",
+ "simphdl [conn_id]\n\r",
+ "List simple ble service handle cache\n\r",
+ cmd_simphdl
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_simphdl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t hdl_cache[HDL_SIMBLE_CACHE_LEN];
+ uint8_t hdl_idx;
+ bool ret = simp_ble_client_get_hdl_cache(conn_id, hdl_cache,
+ sizeof(uint16_t) * HDL_SIMBLE_CACHE_LEN);
+
+ if (ret)
+ {
+ for (hdl_idx = HDL_SIMBLE_SRV_START; hdl_idx < HDL_SIMBLE_CACHE_LEN; hdl_idx++)
+ {
+ data_uart_print("-->Index %d -- Handle 0x%x\r\n", hdl_idx, hdl_cache[hdl_idx]);
+ }
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+/**
+ * @brief Start discovery battery service
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "basdis",
+ "basdis [conn_id]\n\r",
+ "Start discovery battery service\n\r",
+ cmd_basdis
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_basdis(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = bas_start_discovery(conn_id);
+ if (ret)
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+/**
+ * @brief Read battery service characteristic and descriptor value
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "basread",
+ "basread [conn_id] [type]\n\r",
+ "Read battery service characteristic and descriptor value\r\n\
+ [type]: 0-(battery level value), 1-(battery cccd)\r\n\
+ sample: basread 0 1 \n\r",
+ cmd_basread
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_basread(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool ret = false;
+ if (p_parse_value->dw_param[1] == 0)
+ {
+ ret = bas_read_battery_level(conn_id);
+ }
+ else if (p_parse_value->dw_param[1] == 1)
+ {
+ ret = bas_read_notify(conn_id);
+ }
+
+ if (ret)
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief Config battery service client characteristic configuration descriptor value
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "bascccd",
+ "bascccd [conn_id] [notify]\n\r",
+ "Config battery service client characteristic configuration descriptor value\r\n\
+ [notify]: 0-(disable), 1-(enable)\n\r",
+ cmd_bascccd
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_bascccd(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool notify = p_parse_value->dw_param[1];
+ bool ret;
+ ret = bas_set_notify(conn_id, notify);
+
+ if (ret)
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief List battery service handle cache
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "bashdl",
+ "bashdl [conn_id]\n\r",
+ "List battery service handle cache\n\r",
+ cmd_bashdl
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_bashdl(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint16_t hdl_cache[HDL_BAS_CACHE_LEN];
+ uint8_t hdl_idx;
+ bool ret = bas_get_hdl_cache(conn_id, hdl_cache,
+ sizeof(uint16_t) * HDL_BAS_CACHE_LEN);
+
+ if (ret)
+ {
+ for (hdl_idx = HDL_BAS_SRV_START; hdl_idx < HDL_BAS_CACHE_LEN; hdl_idx++)
+ {
+ data_uart_print("-->Index %d -- Handle 0x%x\r\n", hdl_idx, hdl_cache[hdl_idx]);
+ }
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/************************** Peripheral Only *************************************/
+/**
+ * @brief Start advertising without setting advertising parameters
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "startadv",
+ "startadv\n\r",
+ "start advertising without setting advertising parameters\n\r",
+ cmd_startadv
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_startadv(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ //advertising parameters
+ T_GAP_CAUSE cause;
+ cause = le_adv_start();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+/**
+ * @brief Stop advertising
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "stopadv",
+ "stopadv\n\r",
+ "Stop advertising\n\r",
+ cmd_stopadv
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_stopadv(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ cause = le_adv_stop();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+/**
+ * @brief Start Undirected advertising
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "adv",
+ "adv [adv_interval] [filter_policy]\n\r",
+ "Start Undirected advertising\r\n\
+ [adv_interval]: 0x0020 - 0x4000 (20ms - 10240ms, 0.625ms/step)\r\n\
+ [filter_policy]: 0-(all), 1-(whitelist scan), 2-(whitelist conn), 3-(whitelist all)\r\n\
+ sample: adv x40 0 \n\r",
+ cmd_adv
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_adv(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = 80;
+ uint16_t adv_int_max = 80;
+
+ if (p_parse_value->param_count > 0)
+ {
+ adv_int_min = p_parse_value->dw_param[0];
+ adv_int_max = p_parse_value->dw_param[0];
+ }
+ if (p_parse_value->param_count > 1)
+ {
+ adv_filter_policy = p_parse_value->dw_param[1];
+ }
+
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+
+ cause = le_adv_start();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+/**
+ * @brief Start lower duty directed advertising
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "advld",
+ "advld [BD0] [BD1] [BD2] [BD3] [BD4] [BD5]\n\r",
+ "Start lower duty directed advertising\r\n\
+ [BD0] [BD1] [BD2] [BD3] [BD4] [BD5]: peer address\r\n\
+ sample: advld x11 x22 x33 x44 x55 x66\n\r",
+ cmd_advld
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_advld(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_LDC_DIRECT_IND;
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint16_t adv_int_min = 300;
+ uint16_t adv_int_max = 320;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t addr_len;
+
+ for (addr_len = 0; addr_len < GAP_BD_ADDR_LEN; addr_len++)
+ {
+ adv_direct_addr[addr_len] = p_parse_value->dw_param[GAP_BD_ADDR_LEN - addr_len - 1];
+ }
+
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+
+ cause = le_adv_start();
+
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+/**
+ * @brief Start high duty directed advertising
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "advhd",
+ "advhd [BD0] [BD1] [BD2] [BD3] [BD4] [BD5]\n\r",
+ "Start high duty directed advertising\r\n\
+ [BD0] [BD1] [BD2] [BD3] [BD4] [BD5]: peer address\r\n\
+ sample: advhd x11 x22 x33 x44 x55 x66\n\r",
+ cmd_advhd
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_advhd(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_HDC_DIRECT_IND;
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t addr_len;
+
+ for (addr_len = 0; addr_len < GAP_BD_ADDR_LEN; addr_len++)
+ {
+ adv_direct_addr[addr_len] = p_parse_value->dw_param[GAP_BD_ADDR_LEN - addr_len - 1];
+ }
+
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+
+ cause = le_adv_start();
+
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+/**
+ * @brief Start scannable undirected advertising
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "advscan",
+ "advscan\n\r",
+ "Start scannable undirected advertising\n\r",
+ cmd_advscan
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_advscan(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_SCAN_IND;
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = 300;
+ uint16_t adv_int_max = 320;
+
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+
+ cause = le_adv_start();
+
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+/**
+ * @brief Start non_connectable undirected advertising
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "advnonconn",
+ "advnonconn\n\r",
+ "Start non_connectable undirected advertising\n\r",
+ cmd_advnonconn
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_advnonconn(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ T_GAP_CAUSE cause;
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_NONCONN_IND;
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = 300;
+ uint16_t adv_int_max = 320;
+
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+
+ cause = le_adv_start();
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/**
+ * @brief On off slave latency
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "latency",
+ "latency [conn_id] [on_off]\n\r",
+ "On off slave latency\r\n\
+ [on_off]: 0-(turn on the latency), 1-(turn off the latency)\r\n\
+ sample: latency 0 1\n\r",
+ cmd_latency
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_latency(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ bool disable = p_parse_value->dw_param[1];
+ T_GAP_CAUSE cause;
+
+ cause = le_disable_slave_latency(conn_id, disable);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+/**
+ * @brief Update instant passed channel map
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "epassed",
+ "epassed [enable]\n\r",
+ "Update instant passed channel map\r\n\
+ [enable]: 0 - (disable), 1-(enable)\r\n\
+ sample: epassed 1\n\r",
+ cmd_epassed
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_epassed(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ /* Indicate which char to be written. */
+ bool enable = p_parse_value->dw_param[0];
+ T_GAP_CAUSE cause;
+
+ cause = le_update_passed_chann_map(enable);
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+
+/************************** GATT services *************************************/
+/**
+ * @brief Set GAP service Peripheral Preferred Connection Parameters Char value
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "gapprefconn",
+ "gapprefconn [conn_interval_min] [conn_interval_max] [latency] [supervision_timeout]\n\r",
+ "Set GAP service Peripheral Preferred Connection Parameters Char value\r\n\
+ [conn_interval_min]: 0x0006 to 0x0C80(1.25ms/step)\r\n\
+ [conn_interval_max]: 0x0006 to 0x0C80(1.25ms/step)\r\n\
+ [latency]: 0x0000 to 0x01F3\r\n\
+ [supervision_timeout]: 0x000A to 0x0C80(10ms/step)\r\n\
+ sample: gapprefconn x80 x90 0 500 \n\r",
+ cmd_gapprefconn
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_gapprefconn(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint16_t conn_interval_min = p_parse_value->dw_param[0];
+ uint16_t conn_interval_max = p_parse_value->dw_param[1];
+ uint16_t slave_latency = p_parse_value->dw_param[2];
+ uint16_t supervision_timeout = p_parse_value->dw_param[3];
+ gaps_set_peripheral_preferred_conn_param(conn_interval_min, conn_interval_max,
+ slave_latency, supervision_timeout);
+ return (RESULT_SUCCESS);
+}
+/**
+ * @brief Send V3 notification
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "simpv3notify",
+ "simpv3notify [conn_id] [len] \n\r",
+ "Send V3 notification\r\n\
+ [len]: 0 - (mtu-3)\n\r",
+ cmd_simpv3notify
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_simpv3notify(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint8_t notif_val[244];
+ uint16_t length = p_parse_value->dw_param[1];
+ uint16_t i;
+
+ if (length > 244)
+ {
+ return RESULT_ERR;
+ }
+ for (i = 0; i < length; i++)
+ {
+ notif_val[i] = i;
+ }
+
+ if (simp_ble_service_send_v3_notify(conn_id, simp_srv_id,
+ &notif_val,
+ length))
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+/**
+ * @brief Send V4 indication
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "simpv4ind",
+ "simpv4ind [conn_id] [len]\n\r",
+ "Send V4 indication\r\n\
+ [len]: 0 - (mtu-3)\n\r",
+ cmd_simpv4ind
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_simpv4ind(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint8_t ind_val[244];
+ uint16_t length = p_parse_value->dw_param[1];
+ uint16_t i;
+
+ if (length > 244)
+ {
+ return RESULT_ERR;
+ }
+ for (i = 0; i < length; i++)
+ {
+ ind_val[i] = i;
+ }
+
+ if (simp_ble_service_send_v4_indicate(conn_id, simp_srv_id,
+ &ind_val,
+ length))
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+
+/**
+ * @brief Send battery level notification
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "basnotify",
+ "basnotify [conn_id] [battery_level] \n\r",
+ "Send battery level notification\r\n\
+ [battery_level]: 0 - 100\r\n\
+ sample: basnotify 0 80\n\r",
+ cmd_basnotify
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_basnotify(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint8_t battery_level = p_parse_value->dw_param[1];
+
+ if (bas_battery_level_value_notify(conn_id, bas_srv_id, battery_level))
+ {
+ return (RESULT_SUCCESS);
+ }
+ else
+ {
+ return (RESULT_ERR);
+ }
+}
+#if F_BT_LE_5_0_SET_PHY_SUPPORT
+/**
+ * @brief Set the PHY preferences for the connection
+ *
+ * <b>Command table define</b>
+ * \code{.c}
+ {
+ "setphy",
+ "setphy [conn_id] [type]\n\r",
+ "Set the PHY preferences for the connection\r\n\
+ [type]: 0-(1M), 1-(2M), 2-(CODED-S8), 3-(CODED-S2), 4-(tx 2M, rx 1M) \n\r",
+ cmd_setphy
+ },
+ * \endcode
+ */
+static T_USER_CMD_PARSE_RESULT cmd_setphy(T_USER_CMD_PARSED_VALUE *p_parse_value)
+{
+ uint8_t conn_id = p_parse_value->dw_param[0];
+ uint8_t all_phys;
+ uint8_t tx_phys;
+ uint8_t rx_phys;
+ T_GAP_PHYS_OPTIONS phy_options = GAP_PHYS_OPTIONS_CODED_PREFER_S8;
+ T_GAP_CAUSE cause;
+
+ if (p_parse_value->dw_param[1] == 0)
+ {
+ all_phys = GAP_PHYS_PREFER_ALL;
+ tx_phys = GAP_PHYS_PREFER_1M_BIT;
+ rx_phys = GAP_PHYS_PREFER_1M_BIT;
+ }
+ else if (p_parse_value->dw_param[1] == 1)
+ {
+ all_phys = GAP_PHYS_PREFER_ALL;
+ tx_phys = GAP_PHYS_PREFER_2M_BIT;
+ rx_phys = GAP_PHYS_PREFER_2M_BIT;
+ }
+ else if (p_parse_value->dw_param[1] == 2)
+ {
+ all_phys = GAP_PHYS_PREFER_ALL;
+ tx_phys = GAP_PHYS_PREFER_CODED_BIT;
+ rx_phys = GAP_PHYS_PREFER_CODED_BIT;
+ phy_options = GAP_PHYS_OPTIONS_CODED_PREFER_S8;
+ }
+ else if (p_parse_value->dw_param[1] == 3)
+ {
+ all_phys = GAP_PHYS_PREFER_ALL;
+ tx_phys = GAP_PHYS_PREFER_CODED_BIT;
+ rx_phys = GAP_PHYS_PREFER_CODED_BIT;
+ phy_options = GAP_PHYS_OPTIONS_CODED_PREFER_S2;
+ }
+ else
+ {
+ all_phys = GAP_PHYS_NO_PREFER_TX_BIT;
+ tx_phys = GAP_PHYS_PREFER_2M_BIT;
+ rx_phys = GAP_PHYS_PREFER_1M_BIT;
+ }
+ cause = le_set_phy(conn_id, all_phys, tx_phys, rx_phys, phy_options);
+
+ return (T_USER_CMD_PARSE_RESULT)cause;
+}
+#endif
+
+/*----------------------------------------------------
+ * command table
+ * --------------------------------------------------*/
+const T_USER_CMD_TABLE_ENTRY user_cmd_table[] =
+{
+ /************************** Common cmd *************************************/
+ {
+ "rssiread",
+ "rssiread [conn_id]\n\r",
+ "Read the RSSI value\n\r",
+ cmd_rssiread
+ },
+ {
+ "conupdreq",
+ "conupdreq [conn_id] [interval_min] [interval_max] [latency] [supervision_timeout]\n\r",
+ "LE connection param update request\r\n\
+ sample: conupdreq 0 0x30 0x40 0 500\n\r",
+ cmd_conupdreq
+ },
+ {
+ "showcon",
+ "showcon\n\r",
+ "Show all devices connecting status\n\r",
+ cmd_showcon
+ },
+ {
+ "disc",
+ "disc [conn_id]\n\r",
+ "Disconnect to remote device\n\r",
+ cmd_disc
+ },
+ {
+ "wl",
+ "wl [op] [conn_id]\n\r",
+ "Using connected device address to modify whitelist \r\n\
+ [op]: 0-(clear), 1-(add), 2-(remove)\r\n\
+ sample: wl 0 1\n\r",
+ cmd_wl
+ },
+ {
+ "authmode",
+ "authmode [auth_flags] [io_cap] [sec_enable] [oob_enable]\n\r",
+ "Config authentication mode\r\n\
+ [auth_flags]:authentication req bit field: bit0-(bonding), bit2-(MITM), bit3-(SC)\r\n\
+ [io_cap]:set io Capabilities: 0-(display only), 1-(display yes/no), 2-(keyboard noly), 3-(no IO), 4-(keyboard display)\r\n\
+ [sec_enable]:Start smp pairing procedure when connected: 0-(disable), 1-(enable)\r\n\
+ [oob_enable]:Enable oob flag: 0-(disable), 1-(enable)\r\n\
+ sample: authmode 0x5 2 1 0\n\r",
+ cmd_authmode
+ },
+ {
+ "sauth",
+ "sauth [conn_id]\n\r",
+ "Send authentication request\n\r",
+ cmd_sauth
+ },
+ {
+ "userconf",
+ "userconf [conn_id] [conf]\n\r",
+ "Send user confirmation when show GAP_MSG_LE_BOND_USER_CONFIRMATION\r\n\
+ [conf]: 0-(Reject), 1-(Accept)\r\n\
+ sample: userconf 0 1\n\r",
+ cmd_userconf
+ },
+ {
+ "authkey",
+ "authkey [conn_id] [passkey]\n\r",
+ "Input passkey when show GAP_MSG_LE_BOND_PASSKEY_INPUT\r\n\
+ [passkey]: 0 - 999999\r\n\
+ sample: authkey 0 123456\n\r",
+ cmd_authkey
+ },
+ {
+ "bondinfo",
+ "bondinfo\n\r",
+ "Get all Bonded devices information\n\r",
+ cmd_bondinfo
+ },
+ {
+ "bondclear",
+ "bondclear\n\r",
+ "Clear all bonded devices information\n\r",
+ cmd_bondclear
+ },
+#if F_BT_AIRPLANE_MODE_SUPPORT
+ {
+ "wairplane",
+ "wairplane [mode]\n\r",
+ "Write airplane mode\r\n\
+ [mode]: 0-(normal), 1-(airplane)\n\r",
+ cmd_wairplane
+ },
+ {
+ "rairplane",
+ "rairplane\n\r",
+ "Read airplane mode\n\r",
+ cmd_rairplane
+ },
+#endif
+ /************************** Central only *************************************/
+ {
+ "scan",
+ "scan [filter_policy] [filter_duplicate]\n\r",
+ "Start scan\r\n\
+ [filter_policy]: 0-(any), 1-(whitelist), 2-(any RPA), 3-(whitelist RPA) \r\n\
+ [filter_duplicate]: 0-(disable), 1-(enable) \n\r",
+ cmd_scan
+ },
+ {
+ "stopscan",
+ "stopscan\n\r",
+ "Stop scan\n\r",
+ cmd_stopscan
+ },
+ {
+ "showdev",
+ "showdev\n\r",
+ "Show scan dev list: filter simple ble service\n\r",
+ cmd_showdev
+ },
+ {
+ "con",
+ "con [BD0] [BD1] [BD2] [BD3] [BD4] [BD5] [addr_type]\n\r",
+ "Connect to remote device: use address\r\n\
+ [BD0] [BD1] [BD2] [BD3] [BD4] [BD5]: remote device address\r\n\
+ [addr_type]: 0-(public), 1-(random)\r\n\
+ sample: con x11 x22 x33 x44 x55 x66 0 \n\r",
+ cmd_con
+ },
+ {
+ "condev",
+ "condev [idx]\n\r",
+ "Connect to remote device: use showdev to show idx\r\n\
+ [idx]: use cmd showdev to show idx before use this cmd\r\n\
+ sample: condev 0\n\r",
+ cmd_condev
+ },
+ {
+ "chanclassset",
+ "chanclassset [idx0] [idx1] [idx2] [idx3] [idx4]\n\r",
+ "Set Host Channel Classification\r\n\
+ [idx0] [idx1] [idx2] [idx3] [idx4]: channel bit map\r\n\
+ sample: chanclassset xff xff x3f xff x00\n\r",
+ cmd_chanclassset
+ },
+ /************************** GATT client *************************************/
+ {
+ "srvdis",
+ "srvdis [conn_id]\n\r",
+ "Service discovery, discover all primary services\n\r",
+ cmd_srvdis
+ },
+ /*GAPS client*/
+ {
+ "gapdis",
+ "gapdis [conn_id]\n\r",
+ "Start discovery gap service\n\r",
+ cmd_gapdis
+ },
+ {
+ "gapread",
+ "gapread [conn_id] [type]\n\r",
+ "Read GAP service characteristic value\r\n\
+ [type]: 0-(read device name), 1-(read appearance)\r\n\
+ simple: gapread 0 0\n\r",
+ cmd_gapread
+ },
+ {
+ "gaphdl",
+ "gaphdl [conn_id]\n\r",
+ "List GAP service handle cache\n\r",
+ cmd_gaphdl
+ },
+ /*Simple ble client*/
+ {
+ "simpdis",
+ "simpdis [conn_id]\n\r",
+ "Start discovery simple ble service\n\r",
+ cmd_simpdis
+ },
+ {
+ "simpread",
+ "simpread [conn_id] [type] [pattern]\n\r",
+ "Read simple ble service characteristic and descriptor value\r\n\
+ [type]: 0-(read v1), 1-(v3 cccd), 2-(v4 cccd)\r\n\
+ [pattern]: 0-(read by handle), 1-(read by uuid)\r\n\
+ sample: simpread 0 1 0 \n\r",
+ cmd_simpread
+ },
+ {
+ "simpcccd",
+ "simpcccd [conn_id] [type] [enable]\n\r",
+ "Config simple ble service client characteristic configuration descriptor value\r\n\
+ [type]: 0-(v3 notify), 1-(v4 indication)\r\n\
+ [enable]: 0-(disable), 1-(enable) \r\n\
+ sample: simpcccd 0 1 1\n\r",
+ cmd_simpcccd
+ },
+ {
+ "simpwritev2",
+ "simpwritev2 [conn_id] [type] [len]\n\r",
+ "Write simple ble service V2 characteristic value\r\n\
+ [type]: 1-(write request), 2-(write command) \r\n\
+ [len]: type=1 len range:0-270, type=2 len range: 0-(mtu-3)\r\n\
+ sample: simpwritev2 0 1 10\n\r",
+ cmd_simpwritev2
+ },
+ {
+ "simphdl",
+ "simphdl [conn_id]\n\r",
+ "List simple ble service handle cache\n\r",
+ cmd_simphdl
+ },
+ /*BAS client*/
+ {
+ "basdis",
+ "basdis [conn_id]\n\r",
+ "Start discovery battery service\n\r",
+ cmd_basdis
+ },
+ {
+ "basread",
+ "basread [conn_id] [type]\n\r",
+ "Read battery service characteristic and descriptor value\r\n\
+ [type]: 0-(battery level value), 1-(battery cccd)\r\n\
+ sample: basread 0 1 \n\r",
+ cmd_basread
+ },
+ {
+ "bascccd",
+ "bascccd [conn_id] [notify]\n\r",
+ "Config battery service client characteristic configuration descriptor value\r\n\
+ [notify]: 0-(disable), 1-(enable)\n\r",
+ cmd_bascccd
+ },
+ {
+ "bashdl",
+ "bashdl [conn_id]\n\r",
+ "List battery service handle cache\n\r",
+ cmd_bashdl
+ },
+ /************************** Peripheral Only *************************************/
+ {
+ "startadv",
+ "startadv\n\r",
+ "start advertising without setting advertising parameters\n\r",
+ cmd_startadv
+ },
+ {
+ "stopadv",
+ "stopadv\n\r",
+ "Stop advertising\n\r",
+ cmd_stopadv
+ },
+ {
+ "adv",
+ "adv [adv_interval] [filter_policy]\n\r",
+ "Start Undirected advertising\r\n\
+ [adv_interval]: 0x0020 - 0x4000 (20ms - 10240ms, 0.625ms/step)\r\n\
+ [filter_policy]: 0-(all), 1-(whitelist scan), 2-(whitelist conn), 3-(whitelist all)\r\n\
+ sample: adv x40 0 \n\r",
+ cmd_adv
+ },
+ {
+ "advld",
+ "advld [BD0] [BD1] [BD2] [BD3] [BD4] [BD5]\n\r",
+ "Start lower duty directed advertising\r\n\
+ [BD0] [BD1] [BD2] [BD3] [BD4] [BD5]: peer address\r\n\
+ sample: advld x11 x22 x33 x44 x55 x66\n\r",
+ cmd_advld
+ },
+ {
+ "advhd",
+ "advhd [BD0] [BD1] [BD2] [BD3] [BD4] [BD5]\n\r",
+ "Start high duty directed advertising\r\n\
+ [BD0] [BD1] [BD2] [BD3] [BD4] [BD5]: peer address\r\n\
+ sample: advhd x11 x22 x33 x44 x55 x66\n\r",
+ cmd_advhd
+ },
+ {
+ "advscan",
+ "advscan\n\r",
+ "Start scannable undirected advertising\n\r",
+ cmd_advscan
+ },
+ {
+ "advnonconn",
+ "advnonconn\n\r",
+ "Start non_connectable undirected advertising\n\r",
+ cmd_advnonconn
+ },
+ {
+ "latency",
+ "latency [conn_id] [on_off]\n\r",
+ "On off slave latency\r\n\
+ [on_off]: 0-(turn on the latency), 1-(turn off the latency)\r\n\
+ sample: latency 0 1\n\r",
+ cmd_latency
+ },
+ {
+ "epassed",
+ "epassed [enable]\n\r",
+ "Update instant passed channel map\r\n\
+ [enable]: 0 - (disable), 1-(enable)\r\n\
+ sample: epassed 1\n\r",
+ cmd_epassed
+ },
+ /************************** GATT services *************************************/
+ {
+ "gapprefconn",
+ "gapprefconn [conn_interval_min] [conn_interval_max] [latency] [supervision_timeout]\n\r",
+ "Set GAP service Peripheral Preferred Connection Parameters Char value\r\n\
+ [conn_interval_min]: 0x0006 to 0x0C80(1.25ms/step)\r\n\
+ [conn_interval_max]: 0x0006 to 0x0C80(1.25ms/step)\r\n\
+ [latency]: 0x0000 to 0x01F3\r\n\
+ [supervision_timeout]: 0x000A to 0x0C80(10ms/step)\r\n\
+ sample: gapprefconn x80 x90 0 500 \n\r",
+ cmd_gapprefconn
+ },
+ {
+ "simpv3notify",
+ "simpv3notify [conn_id] [len] \n\r",
+ "Send V3 notification\r\n\
+ [len]: 0 - (mtu-3)\n\r",
+ cmd_simpv3notify
+ },
+ {
+ "simpv4ind",
+ "simpv4ind [conn_id] [len]\n\r",
+ "Send V4 indication\r\n\
+ [len]: 0 - (mtu-3)\n\r",
+ cmd_simpv4ind
+ },
+ {
+ "basnotify",
+ "basnotify [conn_id] [battery_level] \n\r",
+ "Send battery level notification\r\n\
+ [battery_level]: 0 - 100\r\n\
+ sample: basnotify 0 80\n\r",
+ cmd_basnotify
+ },
+#if F_BT_LE_5_0_SET_PHY_SUPPORT
+ {
+ "setphy",
+ "setphy [conn_id] [type]\n\r",
+ "Set the PHY preferences for the connection\r\n\
+ [type]: 0-(1M), 1-(2M), 2-(CODED-S8), 3-(CODED-S2), 4-(tx 2M, rx 1M) \n\r",
+ cmd_setphy
+ },
+#endif
+ /* MUST be at the end: */
+ {
+ 0,
+ 0,
+ 0,
+ 0
+ }
+};
+/** @} */ /* End of group SCATTERNET_CMD */
+
+
diff --git a/src/sample/ble_scatternet/user_cmd.h b/src/sample/ble_scatternet/user_cmd.h
new file mode 100644
index 0000000..c1615aa
--- /dev/null
+++ b/src/sample/ble_scatternet/user_cmd.h
@@ -0,0 +1,31 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file user_cmd.h
+* @brief Define user command.
+* @details
+* @author jane
+* @date 2016-02-18
+* @version v0.1
+*********************************************************************************************************
+*/
+#ifndef _USER_CMD_H_
+#define _USER_CMD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <data_uart.h>
+#include <user_cmd_parse.h>
+
+extern const T_USER_CMD_TABLE_ENTRY user_cmd_table[];
+extern T_USER_CMD_IF user_cmd_if;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/src/sample/dtm/app_flags.h b/src/sample/dtm/app_flags.h
new file mode 100644
index 0000000..4f8d86a
--- /dev/null
+++ b/src/sample/dtm/app_flags.h
@@ -0,0 +1,31 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author berni
+ * @date 2018-04-27
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup DTM_Config DTM App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Macro definition
+ *============================================================================*/
+
+
+/** @} */ /* End of group DTM_Config */
+
+#endif
diff --git a/src/sample/dtm/app_task.c b/src/sample/dtm/app_task.c
new file mode 100644
index 0000000..d61579a
--- /dev/null
+++ b/src/sample/dtm/app_task.c
@@ -0,0 +1,96 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file app_task.c
+* @brief direct test mode task.
+* @details
+* @author jeff
+* @date 2016-12-01
+* @version v1.0
+*
+*/
+
+#include <os_task.h>
+#include <os_msg.h>
+#include <gap.h>
+#include "dtm_app.h"
+#include <app_msg.h>
+
+/** @defgroup DTM_APP_TASK Direct Test Demo App Task
+ * @brief This file create message queue and application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+void dtm_task(void *pvParameters);
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void application_task_init()
+{
+ os_task_create(&app_task_handle, "dtm_task", dtm_task, 0, 512 * 4, 1);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param Parameters sending to the task
+ * @return void
+ */
+void dtm_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ dtm_uart_init();
+
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xffffffff) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ //dtm need not to handle io message
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group DTM_APP_TASK */
+
diff --git a/src/sample/dtm/app_task.h b/src/sample/dtm/app_task.h
new file mode 100644
index 0000000..cd5c2af
--- /dev/null
+++ b/src/sample/dtm/app_task.h
@@ -0,0 +1,27 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file app_task.h
+* @brief
+* @details
+* @author jeff
+* @date 2016-12-01
+* @version v1.0
+*
+*/
+
+#ifndef _APPLICATION_H_
+#define _APPLICATION_H_
+
+#include <stdint.h>
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void application_task_init(void);
+
+
+#endif
+
diff --git a/src/sample/dtm/dtm_app.c b/src/sample/dtm/dtm_app.c
new file mode 100644
index 0000000..810e200
--- /dev/null
+++ b/src/sample/dtm/dtm_app.c
@@ -0,0 +1,377 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file dtm_app.c
+* @brief direct test mode implementation.
+* @details
+* @author jeff
+* @date 2016-12-01
+* @version v1.0
+*
+*/
+
+#include "rtl876x_nvic.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_uart.h"
+#include "gap_dtm.h"
+#include "trace.h"
+#include "board.h"
+
+/** @defgroup DTM_APP Direct Test Mode Application
+ * @brief This file handles commands from 8852B and return with events.
+ * @{
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief Uart initialization
+ * @return void
+ */
+void dtm_uart_init(void)
+{
+ Pinmux_Config(DATA_UART_TX_PIN, UART0_TX);
+ Pinmux_Config(DATA_UART_RX_PIN, UART0_RX);
+
+ Pad_Config(DATA_UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(DATA_UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ UART_InitTypeDef uartInitStruct;
+ UART_StructInit(&uartInitStruct);
+
+ uartInitStruct.rxTriggerLevel = 14;
+ UART_Init(UART0, &uartInitStruct);
+
+ UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+
+ NVIC_InitTypeDef nvic_init_struct;
+ nvic_init_struct.NVIC_IRQChannel = UART0_IRQn;
+ nvic_init_struct.NVIC_IRQChannelCmd = ENABLE;
+ nvic_init_struct.NVIC_IRQChannelPriority = 5;
+ NVIC_Init(&nvic_init_struct);
+
+ return;
+}
+
+/**
+ * @brief Send event to 8852B
+ * @param event events to send
+ * @return void
+ */
+void dtm_uart_send_bytes(uint16_t event)
+{
+ uint8_t uartdata[2] = {0};
+ uartdata[0] = (event & 0xff00) >> 8;
+ uartdata[1] = event & 0xff;
+ uint8_t *p_ch = uartdata;
+
+ uint8_t i = 0;
+ for (i = 0; i < 2; i++)
+ {
+ while (UART_GetFlagState(UART0, UART_FLAG_THR_EMPTY) != SET)
+ {
+ ;
+ }
+ UART_SendData(UART0, p_ch++, 1);
+ }
+}
+
+/**
+ * @brief handle test command from 8852B, then invoke gap api to start test procedure.
+ * @param[in] command commands from 8852B.
+ * @return void
+ */
+void dtm_test_req(uint16_t command)
+{
+ uint8_t contrl = 0;
+ uint8_t param = 0;
+ uint8_t tx_chann = 0;
+ uint8_t rx_chann = 0;
+ uint8_t data_len = 0;
+ uint8_t pkt_pl = 0;
+ uint8_t cmd = (command & 0xc000) >> 14;
+ uint16_t event = 0;
+
+ //the upper 2 bits of the data length for any Transmitter or Receiver commands following
+ static uint8_t up_2_bits = 0;
+ //physical to use
+ static uint8_t phy = 1;
+ //modulation index to use
+ static uint8_t mod_idx = 0;
+ //local supported features
+ static uint8_t lcl_feats[GAP_LE_SUPPORTED_FEATURES_LEN] = {0};
+
+ switch (cmd)
+ {
+ case 0:
+ contrl = (command & 0x3f00) >> 8;
+ param = (command & 0xfc) >> 2;
+
+ switch (contrl)
+ {
+ case 0:
+ if (param == 0)
+ {
+ up_2_bits = 0;
+ phy = 1;
+ mod_idx = 0;
+ }
+ else
+ {
+ event |= 1;
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ case 1:
+ if (param <= 3)
+ {
+ up_2_bits = param;
+ }
+ else
+ {
+ event |= 1;
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ case 2:
+ if (param >= 1 && param <= 4)
+ {
+ phy = (param == 4) ? 3 : param;
+ }
+ else
+ {
+ event |= 1;
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ case 3:
+ if (param == 0 || param == 1)
+ {
+ mod_idx = param;
+ }
+ else
+ {
+ event |= 1;
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ case 4:
+ if (param == 0)
+ {
+ le_get_gap_param(GAP_PARAM_LOCAL_FEATURES, lcl_feats);
+ if (lcl_feats[0] & 0x20)
+ {
+ event |= 0x0002;
+ }
+ if (lcl_feats[1] & 0x01)
+ {
+ event |= 0x0004;
+ }
+ if (lcl_feats[1] & 0x02)
+ {
+ event |= 0x0008;
+ }
+ APP_PRINT_INFO1("dtm_test_req: lcl_feats 0x%x", event);
+ }
+ else
+ {
+ event |= 1;
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ case 5:
+ /*
+ 8852B do not send these commands
+ 0x00 Read supportedMaxTxOctets
+ 0x01 Read supportedMaxTxTime
+ 0x02 Read supportedMaxRxOctets
+ 0x03 Read supportedMaxRxTime
+ */
+ break;
+ default:
+ break;
+ }
+ APP_PRINT_INFO3("dtm_test_req: up_2_bits 0x%x, phy 0x%x, mod_idx 0x%x", up_2_bits, phy, mod_idx);
+ break;
+
+ case 1:
+ rx_chann = (command & 0x3f00) >> 8;
+ APP_PRINT_INFO3("dtm_test_req: rx_channel 0x%x, phy 0x%x, mod_idx 0x%x", rx_chann, phy, mod_idx);
+#if F_BT_LE_5_0_DTM_SUPPORT
+ if (le_dtm_enhanced_receiver_test(rx_chann, phy, mod_idx) != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR0("dtm_test_req: le_dtm_enhanced_receiver_test fail");
+ }
+#else
+ if (le_dtm_receiver_test(rx_chann) != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR0("dtm_test_req: le_dtm_receiver_test fail");
+ }
+#endif
+ break;
+
+ case 2:
+ tx_chann = (command & 0x3f00) >> 8;
+ data_len = up_2_bits << 6 | (command & 0xfc) >> 2;
+ pkt_pl = command & 0x03;
+ if (pkt_pl == 3)
+ {
+ pkt_pl = 4;
+ }
+ APP_PRINT_INFO4("dtm_test_req: tx_channel 0x%x, data_len 0x%x, pkt_pl 0x%x, phy 0x%x", tx_chann,
+ data_len, pkt_pl, phy);
+#if F_BT_LE_5_0_DTM_SUPPORT
+ if (le_dtm_enhanced_transmitter_test(tx_chann, data_len, pkt_pl, phy) != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR0("dtm_test_req: le_dtm_enhanced_transmitter_test fail");
+ }
+#else
+ if (le_dtm_transmitter_test(tx_chann, data_len, pkt_pl) != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR0("dtm_test_req: le_dtm_transmitter_test fail");
+ }
+#endif
+ break;
+
+ case 3:
+ contrl = (command & 0x3f00) >> 8;
+ param = (command & 0xfc) >> 2;
+ if (contrl == 0 && param == 0)
+ {
+ APP_PRINT_INFO0("dtm_test_req: le test end");
+ if (le_dtm_test_end() != GAP_CAUSE_SUCCESS)
+ {
+ APP_PRINT_ERROR0("dtm_test_req: le_test_end fail");
+ }
+ }
+ break;
+ }
+}
+
+
+/**
+ * @brief Receive command from 8852B
+ * @return void
+ */
+void UART0_Handler(void)
+{
+ uint8_t uartdata[2] = {0, 0};
+ uint8_t *p = uartdata;
+ uint16_t command = 0;
+ uint32_t int_status = 0;
+ int_status = UART_GetIID(UART0);
+
+ UART_INTConfig(UART0, UART_INT_RD_AVA | UART_INT_LINE_STS, DISABLE);
+
+ switch (int_status)
+ {
+ case UART_INT_ID_TX_EMPTY:
+ break;
+
+ case UART_INT_ID_RX_LEVEL_REACH:
+
+ case UART_INT_ID_RX_TMEOUT:
+ while (UART_GetFlagState(UART0, UART_FLAG_RX_DATA_RDY) == SET)
+ {
+ UART_ReceiveData(UART0, p++, 1);
+ if (p - uartdata > 2)
+ {
+ break;
+ }
+ }
+ command = (uartdata[0] << 8) | uartdata[1];
+ APP_PRINT_INFO1("FORM 8852B: 0x%x", command);
+ dtm_test_req(command);
+ break;
+
+ case UART_INT_ID_LINE_STATUS:
+ break;
+
+ default:
+ break;
+ }
+
+ UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+ return;
+}
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type
+ * @param[in] p_cb_data point to callback data
+ * @retval result
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+ uint16_t status = 0;
+ uint16_t event = 0;
+ APP_PRINT_INFO1("app_gap_callback: cb_type %d", cb_type);
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DTM_RECEIVER_TEST:
+#if F_BT_LE_5_0_DTM_SUPPORT
+ case GAP_MSG_LE_DTM_ENHANCED_RECEIVER_TEST:
+#endif
+ status = p_data->le_cause.cause;
+ if (status == 0)
+ {
+ APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+
+ case GAP_MSG_LE_DTM_TRANSMITTER_TEST:
+#if F_BT_LE_5_0_DTM_SUPPORT
+ case GAP_MSG_LE_DTM_ENHANCED_TRANSMITTER_TEST:
+#endif
+ status = p_data->le_cause.cause;
+ if (status == 0)
+ {
+ APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+
+ case GAP_MSG_LE_DTM_TEST_END:
+ status = p_data->p_le_dtm_test_end_rsp->cause;
+ if (status == 0)
+ {
+ event |= 1 << 15;
+ event |= p_data->p_le_dtm_test_end_rsp->num_pkts;
+ APP_PRINT_INFO2("app_gap_callback: event 0x%x, packet count 0x%x", (event & 0x8000) >> 15,
+ event & 0x7fff);
+ }
+ else
+ {
+ event |= 1;
+ APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1);
+ }
+ dtm_uart_send_bytes(event);
+ break;
+ }
+
+ return result;
+}
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/dtm/dtm_app.h b/src/sample/dtm/dtm_app.h
new file mode 100644
index 0000000..8467231
--- /dev/null
+++ b/src/sample/dtm/dtm_app.h
@@ -0,0 +1,44 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file dtm_app.h
+* @brief
+* @details
+* @author jeff
+* @date 2016-12-01
+* @version v1.0
+*
+*/
+
+#ifndef _DTM_H_
+#define _DTM_H_
+
+#include <stdint.h>
+#include <gap_le.h>
+#include <gap_msg.h>
+
+/**
+ * @brief Uart initialization
+ * @param void
+ * @return void
+ */
+void dtm_uart_init(void);
+
+/**
+ * @brief handle test command from 8852B, then invoke gap api to start test procedure.
+ * @param[in] command commands from 8852B.
+ * @return void
+ */
+void dtm_test_req(uint16_t command);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type
+ * @param[in] p_cb_data point to callback data
+ * @retval result
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#endif
+
diff --git a/src/sample/dtm/main.c b/src/sample/dtm/main.c
new file mode 100644
index 0000000..54d5f40
--- /dev/null
+++ b/src/sample/dtm/main.c
@@ -0,0 +1,54 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file main.c
+* @brief Entry of application
+* @details
+* @author jeff
+* @date 2016-12-01
+* @version v1.0
+*
+*/
+
+#include "app_section.h"
+#include "flash_device.h"
+#include "gap_le.h"
+#include "os_sched.h"
+#include "app_task.h"
+#include "dtm_app.h"
+
+/** @defgroup DTM_MAIN Direct Test Mode Main
+ * @brief Main file to initialize parameters and register application message callback.
+ * @{
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief register gap message callback
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ le_gap_init(0);
+ gap_lib_init();
+ app_le_gap_init();
+ application_task_init();
+ os_sched_start();
+
+ return 0;
+}
+
+/** @} */ /* End of group DTM_MAIN */
diff --git a/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/ancs.c b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/ancs.h b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app.c b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app.c
new file mode 100644
index 0000000..bb0beb9
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app.c
@@ -0,0 +1,613 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file peripheral_app.c
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+
+#include "app.h"
+#include "io_adc.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_ADC:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: adc msg.");
+ io_handle_adc_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ case IO_MSG_TYPE_GDMA:
+ {
+ APP_PRINT_INFO0("[app]app_handle_io_msg: gdma msg.");
+ io_handle_gdma_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ io_adc_sample_start();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app.h b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app_flags.h b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app_task.c b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app_task.c
new file mode 100644
index 0000000..39fe610
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app_task.c
@@ -0,0 +1,124 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+#include "io_adc.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app_task.h b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/main.c b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/main.c
new file mode 100644
index 0000000..3b04eac
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode+GDMA/ble_peripheral/main.c
@@ -0,0 +1,242 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdlib.h>
+#include <string.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+#include "io_adc.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+ global_data_adc_init();
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_adc_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_adc_init();
+ driver_gdma_adc_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+// global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/ADC/ContinuousMode+GDMA/io_adc.c b/src/sample/io_sample/ADC/ContinuousMode+GDMA/io_adc.c
new file mode 100644
index 0000000..284aa13
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode+GDMA/io_adc.c
@@ -0,0 +1,358 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_adc.c
+* @brief This file provides demo code of adc continuous sample and read by gdma.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_adc.h"
+#include "app_task.h"
+
+/* Globals ------------------------------------------------------------------*/
+uint16_t ADC_Recv_Buffer[GDMA_TRANSFER_SIZE];
+
+/**
+ * @brief Initialization adc global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_adc_init(void)
+{
+ /* Initialize adc k value! */
+ APP_PRINT_INFO0("[io_adc]global_data_adc_init");
+ bool adc_k_status = false;
+ adc_k_status = ADC_CalibrationInit();
+ if (false == adc_k_status)
+ {
+ APP_PRINT_ERROR0("[io_adc]global_data_adc_init: ADC_CalibrationInit fail!");
+ }
+ memset(&ADC_Recv_Buffer, 0, sizeof(ADC_Recv_Buffer));
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_adc_init(void)
+{
+ Pad_Config(ADC_SAMPLE_PIN_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+ Pad_Config(ADC_SAMPLE_PIN_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+ Pad_Config(ADC_SAMPLE_PIN_2, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+ Pad_Config(ADC_SAMPLE_PIN_3, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+}
+
+/**
+ * @brief Initialize ADC peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_adc_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+
+ ADC_InitTypeDef ADC_InitStruct;
+ ADC_StructInit(&ADC_InitStruct);
+
+ ADC_InitStruct.ADC_WaterLevel = 4;
+ /* Configure the ADC sampling schedule, a schedule represents an ADC channel data,
+ up to 16, i.e. schIndex[0] ~ schIndex[15] */
+ ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(ADC_SAMPLE_CHANNEL_0);
+ ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(ADC_SAMPLE_CHANNEL_1);
+ ADC_InitStruct.ADC_SchIndex[2] = EXT_SINGLE_ENDED(ADC_SAMPLE_CHANNEL_2);
+ ADC_InitStruct.ADC_SchIndex[3] = EXT_SINGLE_ENDED(ADC_SAMPLE_CHANNEL_3);
+ /* Set the bitmap corresponding to schedule, 16 bits, LSB,
+ schIndex[0-15] corresponding to 16 bits of bitmap bit0-bit15.
+ For example, if config schIndex[0] and schIndex [1], then bitmap is 0000 0000 0011 (that is, 0x0003);
+ if config schIndex [0] and schIndex [2], then bitmap is 0000 0000 0101 (that is, 0x0005).
+ */
+ ADC_InitStruct.ADC_Bitmap = 0x0F;
+ /* Configuration of ADC continuous sampling cycle. */
+ ADC_InitStruct.ADC_SampleTime = ADC_CONTINUOUS_SAMPLE_PERIOD;
+
+ ADC_InitStruct.ADC_PowerAlwaysOnEn = ADC_POWER_ALWAYS_ON_ENABLE;
+
+ ADC_Init(ADC, &ADC_InitStruct);
+
+#if (ADC_MODE_DIVIDE_OR_BYPASS == ADC_BYPASS_MODE)
+ /* High bypass resistance mode config, please notice that the input voltage of
+ adc channel using high bypass mode should not be over 0.9V */
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_0, ENABLE);
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_1, ENABLE);
+ APP_PRINT_INFO0("[io_adc]driver_adc_init: ADC sample mode is bypass mode !");
+#else
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_0, DISABLE);
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_1, DISABLE);
+#endif
+
+ ADC_INTConfig(ADC, ADC_INT_FIFO_RD_ERR, ENABLE);
+ ADC_INTConfig(ADC, ADC_INT_FIFO_OVERFLOW, ENABLE);
+
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = ADC_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+ /* When ADC is enabled, sampling will be done quickly and interruption will occur.
+ After initialization, ADC can be enabled when sampling is needed.*/
+// ADC_Cmd(ADC, ADC_Continuous_Mode, ENABLE);
+}
+
+/**
+ * @brief Initialize gdma peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_gdma_adc_init(void)
+{
+ uint32_t i = 0;
+
+ /* Initialize data buffer which for storing data from adc */
+ for (i = 0; i < GDMA_TRANSFER_SIZE; i++)
+ {
+ ADC_Recv_Buffer[i] = 0;
+ }
+
+ /* GDMA init */
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+
+ GDMA_InitStruct.GDMA_ChannelNum = ADC_GDMA_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToMemory;
+ GDMA_InitStruct.GDMA_BufferSize = GDMA_TRANSFER_SIZE;//Determine total transfer size
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Inc;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_HalfWord;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_HalfWord;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)(&(ADC->FIFO));
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)ADC_Recv_Buffer;
+ GDMA_InitStruct.GDMA_SourceHandshake = GDMA_Handshake_ADC;
+
+ GDMA_Init(ADC_GDMA_Channel, &GDMA_InitStruct);
+
+ GDMA_INTConfig(ADC_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+
+ /* GDMA irq init */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = ADC_GDMA_Channel_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+// /* Start to receive data */
+// GDMA_Cmd(ADC_GDMA_CHANNEL_NUM, ENABLE);
+// /* Enable adc */
+// ADC_Cmd(ADC, ADC_Continuous_Mode, ENABLE);
+
+}
+
+/**
+ * @brief Calculate adc sample voltage.
+ * @param No parameter.
+ * @return void
+ */
+static void io_adc_voltage_calculate(T_IO_MSG *io_adc_msg)
+{
+ uint16_t *p_buf = io_adc_msg->u.buf;
+
+ for (uint32_t i = 0; i < GDMA_TRANSFER_SIZE; i++)
+ {
+ uint16_t sample_data = p_buf[i];
+ float sample_voltage = 0;
+ ADC_ErrorStatus error_status = NO_ERROR;
+
+#if (ADC_MODE_DIVIDE_OR_BYPASS == ADC_BYPASS_MODE)
+ sample_voltage = ADC_GetVoltage(BYPASS_SINGLE_MODE, (int32_t)sample_data, &error_status);
+#else
+ sample_voltage = ADC_GetVoltage(DIVIDE_SINGLE_MODE, (int32_t)sample_data, &error_status);
+#endif
+ if (error_status < 0)
+ {
+ APP_PRINT_INFO2("[io_adc]io_adc_voltage_calculate: ADC parameter or efuse data error! i = %d, error_status = %d",
+ i, error_status);
+ }
+ else
+ {
+ APP_PRINT_INFO4("[io_adc]io_adc_voltage_calculate: ADC rawdata_%-4d = %d, voltage_%-4d = %dmV ", i,
+ sample_data, i, (uint32_t)sample_voltage);
+ }
+ }
+
+ platform_delay_ms(1000);
+ /* Restart dma and adc */
+ GDMA_SetSourceAddress(ADC_GDMA_Channel, (uint32_t)(&(ADC->FIFO)));
+ GDMA_SetDestinationAddress(ADC_GDMA_Channel, (uint32_t)(ADC_Recv_Buffer));
+ GDMA_SetBufferSize(ADC_GDMA_Channel, GDMA_TRANSFER_SIZE);
+ GDMA_ClearINTPendingBit(ADC_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+ GDMA_Cmd(ADC_GDMA_CHANNEL_NUM, ENABLE);
+ ADC_ClearFIFO(ADC);
+ ADC_Cmd(ADC, ADC_CONTINUOUS_MODE, ENABLE);
+}
+
+/**
+ * @brief Handle adc error function.
+ * @param No parameter.
+ * @return void
+ */
+static void io_handle_adc_error(T_IO_MSG *io_adc_msg)
+{
+ uint16_t adc_msg_subtype = io_adc_msg->subtype;
+
+ switch (adc_msg_subtype)
+ {
+ case IO_MSG_ADC_FIFO_READ_ERR:
+ {
+ APP_PRINT_ERROR0("[io_adc]io_handle_adc_error: IO_MSG_ADC_FIFO_READ_ERR!");
+ //Add user code here!
+ }
+ break;
+ case IO_MSG_ADC_FIFO_OVERFLOW:
+ {
+ APP_PRINT_ERROR0("[io_adc]io_handle_adc_error: IO_MSG_ADC_FIFO_OVERFLOW!");
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle adc msg function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_adc_msg(T_IO_MSG *io_adc_msg)
+{
+ io_handle_adc_error(io_adc_msg);
+}
+
+/**
+ * @brief Handle gdma msg function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_gdma_msg(T_IO_MSG *io_gdma_msg)
+{
+ io_adc_voltage_calculate(io_gdma_msg);
+}
+
+/**
+ * @brief ADC sample start.
+ * @param No parameter.
+ * @return void
+ */
+void io_adc_sample_start(void)
+{
+ /* Start to receive data */
+ GDMA_Cmd(ADC_GDMA_CHANNEL_NUM, ENABLE);
+
+ /* Clear adc fifo */
+ ADC_ClearFIFO(ADC);
+ /* Enable adc */
+ ADC_Cmd(ADC, ADC_CONTINUOUS_MODE, ENABLE);
+}
+
+/**
+ * @brief ADC sample stop.
+ * @param No parameter.
+ * @return void
+ */
+void io_adc_sample_stop(void)
+{
+ /* Stop dma */
+ GDMA_SuspendCmd(ADC_GDMA_Channel, ENABLE);
+ while (!(GDMA_GetSuspendChannelStatus(ADC_GDMA_Channel)));
+ GDMA_Cmd(ADC_GDMA_CHANNEL_NUM, DISABLE);
+
+ /* Clear adc fifo */
+ ADC_ClearFIFO(ADC);
+ /* Disable adc */
+ ADC_Cmd(ADC, ADC_CONTINUOUS_MODE, DISABLE);
+}
+
+/**
+ * @brief ADC interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void ADC_Handler(void)
+{
+ if (ADC_GetINTStatus(ADC, ADC_INT_FIFO_RD_ERR) == SET)
+ {
+ T_IO_MSG int_adc_msg;
+
+ int_adc_msg.type = IO_MSG_TYPE_ADC;
+ int_adc_msg.subtype = IO_MSG_ADC_FIFO_READ_ERR;
+ if (false == app_send_msg_to_apptask(&int_adc_msg))
+ {
+ APP_PRINT_ERROR0("[io_adc]ADC_Handler: 1111Send int_adc_msg failed!");
+ //Add user code here!
+ io_adc_sample_stop();
+// ADC_Cmd(ADC, ADC_CONTINUOUS_MODE, DISABLE);
+// ADC_ClearFifo(ADC);
+ ADC_ClearINTPendingBit(ADC, ADC_INT_FIFO_RD_ERR);
+ return;
+ }
+ ADC_ClearINTPendingBit(ADC, ADC_INT_FIFO_RD_ERR);
+ }
+ if (ADC_GetINTStatus(ADC, ADC_INT_FIFO_OVERFLOW) == SET)
+ {
+ ADC_WriteFIFOCmd(ADC, DISABLE);
+ DBG_DIRECT("ADC_INT_FIFO_OVERFLOW");
+
+ T_IO_MSG int_adc_msg;
+
+ int_adc_msg.type = IO_MSG_TYPE_ADC;
+ int_adc_msg.subtype = IO_MSG_ADC_FIFO_OVERFLOW;
+ if (false == app_send_msg_to_apptask(&int_adc_msg))
+ {
+ APP_PRINT_ERROR0("[io_adc]ADC_Handler: Send int_adc_msg failed!");
+ io_adc_sample_stop();
+// ADC_ClearFifo(ADC);
+ ADC_ClearINTPendingBit(ADC, ADC_INT_FIFO_OVERFLOW);
+ return;
+ }
+ ADC_ClearFIFO(ADC);
+ ADC_WriteFIFOCmd(ADC, ENABLE);
+ ADC_ClearINTPendingBit(ADC, ADC_INT_FIFO_OVERFLOW);
+ }
+}
+
+/**
+ * @brief GDMA channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void ADC_GDMA_Channel_Handler(void)
+{
+ ADC_Cmd(ADC, ADC_CONTINUOUS_MODE, DISABLE);
+
+ T_IO_MSG int_gdma_msg;
+
+ int_gdma_msg.type = IO_MSG_TYPE_GDMA;
+ int_gdma_msg.subtype = 0;
+ int_gdma_msg.u.buf = (void *)(ADC_Recv_Buffer);
+ if (false == app_send_msg_to_apptask(&int_gdma_msg))
+ {
+ APP_PRINT_ERROR0("[io_adc]ADC_GDMA_Channel_Handler: Send int_gdma_msg failed!");
+ io_adc_sample_stop();
+// ADC_ClearFifo(ADC);
+ GDMA_ClearINTPendingBit(ADC_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+ return;
+ }
+ GDMA_ClearINTPendingBit(ADC_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+}
diff --git a/src/sample/io_sample/ADC/ContinuousMode+GDMA/io_adc.h b/src/sample/io_sample/ADC/ContinuousMode+GDMA/io_adc.h
new file mode 100644
index 0000000..90dd436
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode+GDMA/io_adc.h
@@ -0,0 +1,78 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_adc.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_ADC_H
+#define __IO_ADC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_adc.h"
+#include "rtl876x_gdma.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+
+#include "app_msg.h"
+#include "board.h"
+
+/* Defines ------------------------------------------------------------------*/
+/** ADC sample channel config.
+ * ADC sample channel config:P2_2,P2_3,P2_6,P2_7 and VBAT
+ * ADC sample channel index select: #define ADC_Channel_Index_0 0
+ * #define ADC_Channel_Index_1 1
+ * #define ADC_Channel_Index_2 2
+ * #define ADC_Channel_Index_3 3
+
+ * If ADC_SAMPLE_PIN = P2_2, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_0;
+ * If ADC_SAMPLE_PIN = P2_3, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_1;
+ * If ADC_SAMPLE_PIN = P2_6, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_2;
+ * If ADC_SAMPLE_PIN = P2_7, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_3;
+ */
+#define ADC_SAMPLE_CHANNEL_0 ADC_Channel_Index_0
+#define ADC_SAMPLE_CHANNEL_1 ADC_Channel_Index_1
+#define ADC_SAMPLE_CHANNEL_2 ADC_Channel_Index_2
+#define ADC_SAMPLE_CHANNEL_3 ADC_Channel_Index_3
+
+/** ADC mode config.
+ * ADC pin hardware mode: bypass mode
+ * divide mode
+ */
+#define ADC_DIVIDE_MODE 0
+#define ADC_BYPASS_MODE 1
+#define ADC_MODE_DIVIDE_OR_BYPASS ADC_DIVIDE_MODE
+
+#define ADC_CONTINUOUS_SAMPLE_PERIOD (20-1)//2us
+
+#define GDMA_TRANSFER_SIZE 4000
+
+
+extern uint16_t ADC_Recv_Buffer[GDMA_TRANSFER_SIZE];
+
+void global_data_adc_init(void);
+void board_adc_init(void);
+void driver_adc_init(void);
+void driver_gdma_adc_init(void);
+void io_handle_adc_msg(T_IO_MSG *io_adc_msg);
+void io_handle_gdma_msg(T_IO_MSG *io_gdma_msg);
+void io_adc_sample_start(void);
+void io_adc_sample_stop(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/ancs.c b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/ancs.h b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app.c b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app.c
new file mode 100644
index 0000000..cbc9143
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app.c
@@ -0,0 +1,608 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_adc.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_ADC:
+ {
+// APP_PRINT_INFO0("[app] app_handle_io_msg: adc msg.");
+ io_handle_adc_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app.h b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app_flags.h b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..d3e92fe
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_flags.h
+* @brief This file is used to config app functions.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app_task.c b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app_task.c
new file mode 100644
index 0000000..635c4c3
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app_task.h b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/main.c b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/main.c
new file mode 100644
index 0000000..831ba68
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode/ble_peripheral/main.c
@@ -0,0 +1,241 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdlib.h>
+#include <string.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+#include "io_adc.h"
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+ global_data_adc_init();
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_adc_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_adc_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/ADC/ContinuousMode/io_adc.c b/src/sample/io_sample/ADC/ContinuousMode/io_adc.c
new file mode 100644
index 0000000..49e1c61
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode/io_adc.c
@@ -0,0 +1,200 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_adc.c
+* @brief This file provides demo code of adc continuous mode.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_adc.h"
+
+#include "app_task.h"
+
+/* Globals ------------------------------------------------------------------*/
+ADC_Data_TypeDef ADC_Global_Data;
+
+/**
+ * @brief Initialization adc global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_adc_init(void)
+{
+ /* Initialize adc k value! */
+ APP_PRINT_INFO0("[io_adc] global_data_adc_init");
+ bool adc_k_status = false;
+ adc_k_status = ADC_CalibrationInit();
+ if (false == adc_k_status)
+ {
+ APP_PRINT_ERROR0("[io_adc] global_data_adc_init: ADC_CalibrationInit fail!");
+ }
+ memset(&ADC_Global_Data, 0, sizeof(ADC_Global_Data));
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_adc_init(void)
+{
+ Pad_Config(ADC_SAMPLE_PIN_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+ Pad_Config(ADC_SAMPLE_PIN_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+}
+
+/**
+ * @brief Initialize ADC peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_adc_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+
+ ADC_InitTypeDef ADC_InitStruct;
+ ADC_StructInit(&ADC_InitStruct);
+ /* Configure the ADC sampling schedule, a schedule represents an ADC channel data,
+ up to 16, i.e. schIndex[0] ~ schIndex[15] */
+ ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(ADC_SAMPLE_CHANNEL_0);
+ ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(ADC_SAMPLE_CHANNEL_1);
+ /* Set the bitmap corresponding to schedule, 15 bits, LSB,
+ schIndex[0-15] corresponding to 16 bits of bitmap bit0-bit15.
+ For example, if config schIndex[0] and schIndex [1], then bitmap is 0000 0000 0011 (that is, 0x0003);
+ if config schIndex [0] and schIndex [2], then bitmap is 0000 0000 0101 (that is, 0x0005).
+ */
+ ADC_InitStruct.ADC_Bitmap = 0x03;
+ ADC_InitStruct.ADC_SampleTime = ADC_CONTINUOUS_SAMPLE_PERIOD;
+ /* Configure the interrupt of ADC_INT_FIFO_TH threshold value. */
+ ADC_InitStruct.ADC_FifoThdLevel = 16;
+ ADC_Init(ADC, &ADC_InitStruct);
+
+#if (ADC_MODE_DIVIDE_OR_BYPASS == ADC_BYPASS_MODE)
+ /* High bypass resistance mode config, please notice that the input voltage of
+ adc channel using high bypass mode should not be over 0.9V */
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_0, ENABLE);
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_1, ENABLE);
+ APP_PRINT_INFO0("[ADC] ADC sample mode is bypass mode !");
+#else
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_0, DISABLE);
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_1, DISABLE);
+ APP_PRINT_INFO0("[ADC] ADC sample mode is divide mode !");
+#endif
+
+ ADC_INTConfig(ADC, ADC_INT_FIFO_THD, ENABLE);
+
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = ADC_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+ /* When ADC is enabled, sampling will be done quickly and interruption will occur.
+ After initialization, ADC can be enabled when sampling is needed.*/
+ ADC_Cmd(ADC, ADC_CONTINUOUS_MODE, ENABLE);
+}
+
+/**
+ * @brief Calculate adc sample voltage.
+ * @param No parameter.
+ * @return void
+ */
+static void io_adc_voltage_calculate(T_IO_MSG *io_adc_msg)
+{
+ uint8_t sample_data_len = 0;
+ uint16_t sample_data[ADC_FIFO_MAX] = {0};
+ float sample_voltage[ADC_FIFO_MAX] = {0};
+ ADC_ErrorStatus error_status = NO_ERROR;
+
+ uint16_t *p_buf = io_adc_msg->u.buf;
+
+ sample_data_len = p_buf[0];
+ for (uint8_t i = 0; i < sample_data_len; i++)
+ {
+ sample_data[i] = p_buf[i + 1];
+ }
+ for (uint8_t i = 0; i < sample_data_len; i++)
+ {
+#if (ADC_MODE_DIVIDE_OR_BYPASS == ADC_BYPASS_MODE)
+ sample_voltage[i] = ADC_GetVoltage(BYPASS_SINGLE_MODE, (int32_t)sample_data[i], &error_status);
+#else
+ sample_voltage[i] = ADC_GetVoltage(DIVIDE_SINGLE_MODE, (int32_t)sample_data[i], &error_status);
+#endif
+ if (error_status < 0)
+ {
+ APP_PRINT_INFO2("[io_adc] io_adc_voltage_calculate: ADC parameter or efuse data error! i = %d, error_status = %d",
+ i, error_status);
+ }
+ else
+ {
+ APP_PRINT_INFO4("[io_adc] io_adc_voltage_calculate: ADC rawdata_%-4d = %d, voltage_%-4d = %dmV ", i,
+ sample_data[i], i, (uint32_t)sample_voltage[i]);
+
+ }
+ }
+ memset(&ADC_Global_Data, 0, sizeof(ADC_Global_Data));
+ for (uint32_t i = 0; i < 1000000; i++);
+ ADC_Cmd(ADC, ADC_CONTINUOUS_MODE, ENABLE);
+}
+
+/**
+ * @brief Handle adc data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_adc_msg(T_IO_MSG *io_adc_msg)
+{
+ io_adc_voltage_calculate(io_adc_msg);
+}
+
+/**
+ * @brief ADC interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void ADC_Handler(void)
+{
+ uint8_t data_len = 0;
+ uint16_t sample_data[ADC_FIFO_MAX] = {0};
+
+ if (ADC_GetINTStatus(ADC, ADC_INT_FIFO_THD) == SET)
+ {
+ ADC_Cmd(ADC, ADC_CONTINUOUS_MODE, DISABLE);
+
+ data_len = ADC_GetFIFODataLen(ADC);
+ /* ADC continuous sampling mode, read data from FIFO.
+ In multi-channel sampling,
+ the data order in FIFO corresponds to the channel order set by schedule index.
+ */
+ ADC_ReadFIFOData(ADC, sample_data, data_len);
+
+ ADC_ClearFIFO(ADC);
+ ADC_ClearINTPendingBit(ADC, ADC_INT_FIFO_THD);
+
+ T_IO_MSG int_adc_msg;
+
+ int_adc_msg.type = IO_MSG_TYPE_ADC;
+ int_adc_msg.subtype = 0;
+ ADC_Global_Data.RawData[0] = data_len;
+ for (uint8_t i = 0; i < data_len; i++)
+ {
+ ADC_Global_Data.RawData[i + 1] = sample_data[i];
+ }
+ int_adc_msg.u.buf = (void *)(ADC_Global_Data.RawData);
+ if (false == app_send_msg_to_apptask(&int_adc_msg))
+ {
+ APP_PRINT_ERROR0("[io_adc] ADC_Handler: Send int_adc_msg failed!");
+ //Add user code here!
+ ADC_ClearFIFO(ADC);
+ ADC_ClearINTPendingBit(ADC, ADC_INT_FIFO_THD);
+ return;
+ }
+ }
+}
+
diff --git a/src/sample/io_sample/ADC/ContinuousMode/io_adc.h b/src/sample/io_sample/ADC/ContinuousMode/io_adc.h
new file mode 100644
index 0000000..bf908d0
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode/io_adc.h
@@ -0,0 +1,77 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_adc.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_ADC_H
+#define __IO_ADC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_adc.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "app_msg.h"
+#include "board.h"
+
+/* Defines ------------------------------------------------------------------*/
+/** ADC sample channel config.
+ * ADC sample channel config:P2_2,P2_3,P2_6,P2_7 and VBAT
+ * ADC sample channel index select: #define ADC_Channel_Index_0 0
+ * #define ADC_Channel_Index_1 1
+ * #define ADC_Channel_Index_2 2
+ * #define ADC_Channel_Index_3 3
+
+ * If ADC_SAMPLE_PIN = P2_2, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_0;
+ * If ADC_SAMPLE_PIN = P2_3, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_1;
+ * If ADC_SAMPLE_PIN = P2_6, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_2;
+ * If ADC_SAMPLE_PIN = P2_7, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_3;
+ */
+#define ADC_SAMPLE_CHANNEL_0 ADC_Channel_Index_0
+#define ADC_SAMPLE_CHANNEL_1 ADC_Channel_Index_1
+
+/** ADC mode config.
+ * ADC pin hardware mode: bypass mode
+ * divide mode
+ */
+#define ADC_DIVIDE_MODE 0
+#define ADC_BYPASS_MODE 1
+#define ADC_MODE_DIVIDE_OR_BYPASS ADC_DIVIDE_MODE
+
+#define ADC_CONTINUOUS_SAMPLE_PERIOD (200-1)//20us
+
+#define ADC_FIFO_MAX (32)
+
+/* ADC global data struct*/
+typedef struct
+{
+ uint16_t RawData[ADC_FIFO_MAX + 1];
+// float voltage[ADC_FIFO_THD];
+} ADC_Data_TypeDef;
+
+extern ADC_Data_TypeDef ADC_Global_Data;
+
+void global_data_adc_init(void);
+void board_adc_init(void);
+void driver_adc_init(void);
+void io_handle_adc_msg(T_IO_MSG *io_adc_msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/DLPS/ble_peripheral/ancs.c b/src/sample/io_sample/ADC/DLPS/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/ADC/DLPS/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/ADC/DLPS/ble_peripheral/ancs.h b/src/sample/io_sample/ADC/DLPS/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/ADC/DLPS/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/DLPS/ble_peripheral/app.c b/src/sample/io_sample/ADC/DLPS/ble_peripheral/app.c
new file mode 100644
index 0000000..242570a
--- /dev/null
+++ b/src/sample/io_sample/ADC/DLPS/ble_peripheral/app.c
@@ -0,0 +1,613 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "app.h"
+#include "io_adc.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_ADC:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: ADC data msg.");
+ io_handle_adc_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ case IO_MSG_TYPE_GPIO:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: gpio msg.");
+ io_adc_sample_start();
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ io_adc_sample_start();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/ADC/DLPS/ble_peripheral/app.h b/src/sample/io_sample/ADC/DLPS/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/ADC/DLPS/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/DLPS/ble_peripheral/app_flags.h b/src/sample/io_sample/ADC/DLPS/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..0b1c430
--- /dev/null
+++ b/src/sample/io_sample/ADC/DLPS/ble_peripheral/app_flags.h
@@ -0,0 +1,39 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/ADC/DLPS/ble_peripheral/app_task.c b/src/sample/io_sample/ADC/DLPS/ble_peripheral/app_task.c
new file mode 100644
index 0000000..0580a66
--- /dev/null
+++ b/src/sample/io_sample/ADC/DLPS/ble_peripheral/app_task.c
@@ -0,0 +1,124 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+#include "app.h"
+#include "app_task.h"
+#include "io_adc.h"
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+//uint8_t String_Buf[100];
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/ADC/DLPS/ble_peripheral/app_task.h b/src/sample/io_sample/ADC/DLPS/ble_peripheral/app_task.h
new file mode 100644
index 0000000..bd16830
--- /dev/null
+++ b/src/sample/io_sample/ADC/DLPS/ble_peripheral/app_task.h
@@ -0,0 +1,46 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/DLPS/ble_peripheral/main.c b/src/sample/io_sample/ADC/DLPS/ble_peripheral/main.c
new file mode 100644
index 0000000..968e5d5
--- /dev/null
+++ b/src/sample/io_sample/ADC/DLPS/ble_peripheral/main.c
@@ -0,0 +1,308 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author yuan
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+#include "dlps.h"
+#include "io_adc.h"
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+void global_data_init(void)
+{
+ global_data_adc_init();
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_adc_init();
+ board_gpio_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_adc_init();
+ driver_gpio_init();
+}
+
+#if DLPS_EN
+/**
+ * @brief this function will be called before enter DLPS
+ *
+ * set PAD and wakeup pin config for enterring DLPS
+ *
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_enter_dlps_config(void)
+{
+ io_adc_dlps_enter();
+}
+
+/**
+ * @brief this function will be called after exit DLPS
+ *
+ * set PAD and wakeup pin config for enterring DLPS
+ *
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_exit_dlps_config(void)
+{
+ io_adc_dlps_exit();
+}
+
+/**
+ * @brief Contains the setting about app dlps callback.
+ */
+bool app_dlps_check_cb(void)
+{
+ return (io_adc_dlps_check());
+}
+#endif /* DLPS_EN */
+
+/**
+ * @brief The setting about power mode.
+ * @param No parameter.
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+#if DLPS_EN
+ if (false == dlps_check_cb_reg(app_dlps_check_cb))
+ {
+ APP_PRINT_ERROR0("Error: dlps_check_cb_reg(app_dlps_check_cb) failed!");
+ }
+ DLPS_IORegUserDlpsEnterCb(app_enter_dlps_config);
+ DLPS_IORegUserDlpsExitCb(app_exit_dlps_config);
+ DLPS_IORegister();
+ lps_mode_set(PLATFORM_DLPS_PFM);
+
+ /* Config WakeUp pin */
+ System_WakeUpPinEnable(ADC_DLPS_WAKEUP_PIN, PAD_WAKEUP_POL_LOW, 0);
+#else
+ lps_mode_set(LPM_ACTIVE_MODE);
+#endif
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+/**
+ * @brief System interrupt handler function, for wakeup pin.
+ * @param No parameter.
+ * @return void
+*/
+void System_Handler(void)
+{
+ if (System_WakeUpInterruptValue(ADC_DLPS_WAKEUP_PIN) == SET)
+ {
+ APP_PRINT_INFO0("System_Handler");
+ Pad_ClearWakeupINTPendingBit(ADC_DLPS_WAKEUP_PIN);
+ System_WakeUpPinDisable(ADC_DLPS_WAKEUP_PIN);
+ IO_ADC_DLPS_Enter_Allowed = false;
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/ADC/DLPS/io_adc.c b/src/sample/io_sample/ADC/DLPS/io_adc.c
new file mode 100644
index 0000000..be49b1f
--- /dev/null
+++ b/src/sample/io_sample/ADC/DLPS/io_adc.c
@@ -0,0 +1,269 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file io_uart.c
+* @brief uart interrupt demo
+* @details
+* @author yuan
+* @date 2018-06-28
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_adc.h"
+#include <string.h>
+#include "app_task.h"
+
+/* Globals ------------------------------------------------------------------*/
+uint16_t ADC_DATA_Buffer[32];
+uint8_t ADC_DATA_Length = 0;
+
+bool IO_ADC_DLPS_Enter_Allowed = false;
+
+/**
+ * @brief Initialize uart global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_adc_init(void)
+{
+ IO_ADC_DLPS_Enter_Allowed = true;
+ ADC_DATA_Length = 0;
+ memset(ADC_DATA_Buffer, 0, sizeof(ADC_DATA_Buffer));
+}
+
+void board_adc_init(void)
+{
+ Pad_Config(ADC_SAMPLE_PIN_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+
+ Pad_Config(ADC_SAMPLE_PIN_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+}
+
+/**
+ * @brief Initialize adc peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_adc_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+
+ ADC_InitTypeDef ADC_InitStruct;
+ ADC_StructInit(&ADC_InitStruct);
+
+ ADC_InitStruct.ADC_SampleTime = 255; /* (n + 1) cycle of 10MHz,n = 0~255 or n = 2048~14591 */
+
+ ADC_InitStruct.ADC_SchIndex[0] = INTERNAL_VBAT_MODE;
+ ADC_InitStruct.ADC_Bitmap = 0x01;
+
+ ADC_InitStruct.ADC_PowerAlwaysOnEn = ADC_POWER_ALWAYS_ON_ENABLE;
+ ADC_Init(ADC, &ADC_InitStruct);
+
+#if (ADC_MODE_DIVIDE_OR_BYPASS == ADC_BYPASS_MODE)
+ /* High bypass resistance mode config, please notice that the input voltage of
+ adc channel using high bypass mode should not be over 0.9V */
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_0, ENABLE);
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_1, ENABLE);
+#endif
+
+ ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE);
+
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = ADC_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_gpio_init(void)
+{
+ Pad_Config(ADC_DLPS_WAKEUP_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(ADC_DLPS_WAKEUP_PIN, DWGPIO);
+}
+
+/**
+ * @brief Initialize GPIO peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_gpio_init(void)
+{
+ /* Initialize GPIO peripheral */
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+ GPIO_StructInit(&GPIO_InitStruct);
+ GPIO_InitStruct.GPIO_Pin = GPIO_PIN_INPUT;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
+ GPIO_InitStruct.GPIO_ITCmd = ENABLE;
+ GPIO_InitStruct.GPIO_ITTrigger = GPIO_INT_Trigger_EDGE;
+ GPIO_InitStruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW;
+ GPIO_InitStruct.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_ENABLE;
+ GPIO_InitStruct.GPIO_DebounceTime = 64;/* unit:ms , can be 1~64 ms */
+ GPIO_Init(&GPIO_InitStruct);
+
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = GPIO_PIN_INPUT_IRQN;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ GPIO_MaskINTConfig(GPIO_PIN_INPUT, DISABLE);
+ GPIO_INTConfig(GPIO_PIN_INPUT, ENABLE);
+}
+
+/**
+ * @brief IO enter dlps call back function.
+ * @param No parameter.
+ * @return void
+ */
+void io_adc_dlps_enter(void)
+{
+ uint8_t reg_value = 0;
+ reg_value = btaon_fast_read_safe(0x113);
+ btaon_fast_write(0x113, reg_value | 0x04);
+ /* Switch pad to Software mode */
+ Pad_ControlSelectValue(ADC_DLPS_WAKEUP_PIN, PAD_SW_MODE);
+ System_WakeUpPinEnable(ADC_DLPS_WAKEUP_PIN, PAD_WAKEUP_POL_LOW, 0);
+ DBG_DIRECT("io_adc_dlps_enter");
+}
+
+/**
+ * @brief IO exit dlps call back function.
+ * @param No parameter.
+ * @return void
+ */
+void io_adc_dlps_exit(void)
+{
+ uint8_t reg_value = 0;
+ reg_value = btaon_fast_read_safe(0x113);
+ btaon_fast_write(0x113, reg_value & (~0x04));
+ /* Switch pad to Pinmux mode */
+ Pad_ControlSelectValue(ADC_DLPS_WAKEUP_PIN, PAD_PINMUX_MODE);
+ DBG_DIRECT("io_adc_dlps_exit");
+}
+
+/**
+ * @brief IO enter dlps check function.
+ * @param No parameter.
+ * @return void
+ */
+bool io_adc_dlps_check(void)
+{
+ return IO_ADC_DLPS_Enter_Allowed;
+}
+
+/**
+ * @brief Handle uart data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_adc_handle_msg(T_IO_MSG *io_adc_msg)
+{
+ uint16_t *p_buf = io_adc_msg->u.buf;
+ uint16_t type = io_adc_msg->type;
+
+ if (IO_MSG_TYPE_ADC == type)
+ {
+ DBG_DIRECT("io_adc_handle_msg: len = %d", ADC_DATA_Length);
+ for (uint8_t i = 0; i < ADC_DATA_Length; i++)
+ {
+ DBG_DIRECT("adc raw data = 0x%X", p_buf[i]);
+ }
+ platform_delay_ms(1000);
+ IO_ADC_DLPS_Enter_Allowed = true;
+ }
+}
+
+/**
+ * @brief Handle uart msg function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_adc_msg(T_IO_MSG *io_adc_msg)
+{
+ io_adc_handle_msg(io_adc_msg);
+}
+
+/**
+ * @brief IO enter dlps check function.
+ * @param No parameter.
+ * @return void
+ */
+void io_adc_sample_start(void)
+{
+ ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE);
+}
+
+/**
+ * @brief ADC interrupt handler function.
+ * @param No parameter.
+ * @return void
+*/
+void ADC_Handler(void)
+{
+ uint16_t sample_data[32];
+
+ if (ADC_GetINTStatus(ADC, ADC_INT_ONE_SHOT_DONE) == SET)
+ {
+ ADC_ClearINTPendingBit(ADC, ADC_INT_ONE_SHOT_DONE);
+
+ /* Send msg to app task */
+ ADC_DATA_Length = 1;
+ sample_data[0] = ADC_ReadRawData(ADC, ADC_Schedule_Index_0);
+
+ ADC_DATA_Buffer[0] = sample_data[0];
+ T_IO_MSG int_adc_msg;
+
+ int_adc_msg.type = IO_MSG_TYPE_ADC;
+ int_adc_msg.u.buf = (void *)(&ADC_DATA_Buffer);
+ if (false == app_send_msg_to_apptask(&int_adc_msg))
+ {
+ APP_PRINT_ERROR0("[io_adc] ADC_Handler: Send int_adc_msg failed!");
+ //Add user code here!
+ return;
+ }
+ }
+}
+
+/**
+ * @brief GPIO interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void GPIO_Input_Handler(void)
+{
+ DBG_DIRECT("GPIO_Input_Handler");
+ GPIO_INTConfig(GPIO_PIN_INPUT, DISABLE);
+ GPIO_MaskINTConfig(GPIO_PIN_INPUT, ENABLE);
+
+ T_IO_MSG int_gpio_msg;
+
+ int_gpio_msg.type = IO_MSG_TYPE_GPIO;
+ int_gpio_msg.subtype = 0;
+ if (false == app_send_msg_to_apptask(&int_gpio_msg))
+ {
+ APP_PRINT_ERROR0("[io_gpio] GPIO_Input_Handler: Send int_gpio_msg failed!");
+ //Add user code here!
+ GPIO_ClearINTPendingBit(GPIO_PIN_INPUT);
+ return;
+ }
+
+ GPIO_ClearINTPendingBit(GPIO_PIN_INPUT);
+ GPIO_MaskINTConfig(GPIO_PIN_INPUT, DISABLE);
+ GPIO_INTConfig(GPIO_PIN_INPUT, ENABLE);
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/ADC/DLPS/io_adc.h b/src/sample/io_sample/ADC/DLPS/io_adc.h
new file mode 100644
index 0000000..71582fb
--- /dev/null
+++ b/src/sample/io_sample/ADC/DLPS/io_adc.h
@@ -0,0 +1,78 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_adc.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_ADC_H
+#define __IO_ADC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_adc.h"
+#include "rtl876x_gpio.h"
+#include "rtl876x_io_dlps.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_tim.h"
+
+#include "app_msg.h"
+#include "board.h"
+
+/* Defines --------------------------------------------------------------*/
+/** ADC sample channel config.
+ * ADC sample channel config:P2_2,P2_3,P2_6,P2_7 and VBAT
+ * ADC sample channel index select: #define ADC_Channel_Index_0 0
+ * #define ADC_Channel_Index_1 1
+ * #define ADC_Channel_Index_2 2
+ * #define ADC_Channel_Index_3 3
+
+ * If ADC_SAMPLE_PIN = P2_2, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_0;
+ * If ADC_SAMPLE_PIN = P2_3, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_1;
+ * If ADC_SAMPLE_PIN = P2_6, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_2;
+ * If ADC_SAMPLE_PIN = P2_7, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_3;
+ */
+#define ADC_SAMPLE_CHANNEL_0 ADC_Channel_Index_0
+#define ADC_SAMPLE_CHANNEL_1 ADC_Channel_Index_1
+
+/* Config ADC channel and mode --------------------------------------------------------------*/
+/* ADC bypass mode or divide mode */
+#define ADC_DIVIDE_MODE 0
+#define ADC_BYPASS_MODE 1
+#define ADC_MODE_DIVIDE_OR_BYPASS ADC_DIVIDE_MODE
+
+#define TIMER_ADC_ONE_SHOT_SAMPLE_PERIOD (100-1)//10us
+
+/* Globals ------------------------------------------------------------------*/
+extern bool IO_ADC_DLPS_Enter_Allowed;
+
+void global_data_adc_init(void);
+void board_adc_init(void);
+void driver_adc_init(void);
+void board_gpio_init(void);
+void driver_gpio_init(void);
+void io_adc_dlps_enter(void);
+void io_adc_dlps_exit(void);
+bool io_adc_dlps_check(void);
+void io_handle_adc_msg(T_IO_MSG *io_adc_msg);
+void io_adc_sample_start(void);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/OneShotMode+GDMA/main.c b/src/sample/io_sample/ADC/OneShotMode+GDMA/main.c
new file mode 100644
index 0000000..0550279
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode+GDMA/main.c
@@ -0,0 +1,300 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief
+* @details
+* @author yuan
+* @date 2021-06-09
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_adc.h"
+#include "rtl876x_gdma.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_tim.h"
+#include "trace.h"
+
+/* Defines --------------------------------------------------------------*/
+#define ADC_Channel_Index_0 0
+#define ADC_Channel_Index_1 1
+#define ADC_Channel_Index_2 2
+#define ADC_Channel_Index_3 3
+
+
+#define ADC_Schedule_Index_0 0
+#define ADC_Schedule_Index_1 1
+#define ADC_Schedule_Index_2 2
+#define ADC_Schedule_Index_3 3
+#define ADC_Schedule_Index_4 4
+#define ADC_Schedule_Index_5 5
+#define ADC_Schedule_Index_6 6
+#define ADC_Schedule_Index_7 7
+#define ADC_Schedule_Index_8 8
+#define ADC_Schedule_Index_9 9
+#define ADC_Schedule_Index_10 10
+#define ADC_Schedule_Index_11 11
+#define ADC_Schedule_Index_12 12
+#define ADC_Schedule_Index_13 13
+#define ADC_Schedule_Index_14 14
+#define ADC_Schedule_Index_15 15
+
+
+/* Config ADC channel and mode --------------------------------------------------------------*/
+//ADC bypass mode or divide mode
+#define ADC_DIVIDE_MODE 0
+#define ADC_BYPASS_MODE 1
+#define ADC_MODE_DIVIDE_OR_BYPASS ADC_DIVIDE_MODE
+
+/** ADC sample channel config.
+ * ADC sample channel config:P2_2,P2_3,P2_6,P2_7 and VBAT
+ * ADC sample channel index select: #define ADC_Channel_Index_0 0
+ * #define ADC_Channel_Index_1 1
+ * #define ADC_Channel_Index_2 2
+ * #define ADC_Channel_Index_3 3
+
+ * If ADC_SAMPLE_PIN = P2_2, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_0;
+ * If ADC_SAMPLE_PIN = P2_3, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_1;
+ * If ADC_SAMPLE_PIN = P2_6, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_2;
+ * If ADC_SAMPLE_PIN = P2_7, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_3;
+ */
+#define ADC_SAMPLE_PIN_0 P2_2
+#define ADC_SAMPLE_PIN_1 P2_3
+#define ADC_SAMPLE_CHANNEL_0 ADC_Channel_Index_0
+#define ADC_SAMPLE_CHANNEL_1 ADC_Channel_Index_1
+
+#define ADC_GDMA_CHANNEL_NUM 2
+#define ADC_GDMA_Channel GDMA_Channel2
+#define ADC_GDMA_Channel_IRQn GDMA0_Channel2_IRQn
+#define ADC_GDMA_Channel_Handler GDMA0_Channel2_Handler
+#define GDMA_TRANSFER_SIZE 2
+
+#define TIMER_ADC_ONE_SHOT_SAMPLE_PERIOD (100)//100us
+
+
+/* Globals --------------------------------------------------------------*/
+uint16_t ADC_Recv_Data_Buffer[GDMA_TRANSFER_SIZE];
+
+/* Functions --------------------------------------------------------------*/
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_adc_init(void)
+{
+ Pad_Config(ADC_SAMPLE_PIN_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+
+ Pad_Config(ADC_SAMPLE_PIN_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+}
+
+/**
+ * @brief Initialize adc peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_adc_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+
+ ADC_InitTypeDef ADC_InitStruct;
+ ADC_StructInit(&ADC_InitStruct);
+
+ ADC_InitStruct.ADC_DataWriteToFifo = ADC_DATA_WRITE_TO_FIFO_ENABLE;
+ ADC_InitStruct.ADC_WaterLevel = 0x4;
+ ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(ADC_SAMPLE_CHANNEL_0);
+ ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(ADC_SAMPLE_CHANNEL_1);
+ ADC_InitStruct.ADC_Bitmap = 0x03;
+ ADC_InitStruct.ADC_TimerTriggerEn = ADC_TIMER_TRIGGER_ENABLE;
+ ADC_InitStruct.ADC_PowerAlwaysOnEn = ADC_POWER_ALWAYS_ON_ENABLE;
+ ADC_InitStruct.ADC_SampleTime = 20 -
+ 1; /* (n + 1) cycle of 10MHz,n = 0~255 or n = 2048~14591 */
+
+ ADC_Init(ADC, &ADC_InitStruct);
+
+#if (ADC_MODE_DIVIDE_OR_BYPASS == ADC_BYPASS_MODE)
+ /* High bypass resistance mode config, please notice that the input voltage of
+ adc channel using high bypass mode should not be over 0.9V */
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_0, ENABLE);
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_1, ENABLE);
+#endif
+
+ ADC_INTConfig(ADC, ADC_INT_FIFO_RD_ERR, ENABLE);
+ ADC_INTConfig(ADC, ADC_INT_FIFO_OVERFLOW, ENABLE);
+
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = ADC_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/**
+ * @brief Initialize timer peripheral for adc one shot mode.
+ * @param No parameter.
+ * @return void
+*/
+void driver_adc_timer_init(void)
+{
+ /* TIM7 for timing voltage acqusition(fix) */
+ RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+
+ TIM_TimeBaseInitTypeDef TIM_InitStruct;
+
+ TIM_StructInit(&TIM_InitStruct);
+
+ TIM_InitStruct.TIM_PWM_En = PWM_DISABLE;
+ TIM_InitStruct.TIM_Period = TIMER_ADC_ONE_SHOT_SAMPLE_PERIOD - 1 ; //sampling once 1 second
+ TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ TIM_InitStruct.TIM_SOURCE_DIV = TIM_CLOCK_DIVIDER_40;
+ TIM_TimeBaseInit(TIM2, &TIM_InitStruct);
+
+ TIM_ClearINT(TIM2);
+ TIM_Cmd(TIM2, ENABLE);
+}
+
+/**
+ * @brief Initialize gdma peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_adc_gdma_init(void)
+{
+ /* Initialize data buffer which for storing data from adc */
+ for (uint32_t i = 0; i < GDMA_TRANSFER_SIZE; i++)
+ {
+ ADC_Recv_Data_Buffer[i] = 0;
+ }
+
+ /* GDMA init */
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+
+ GDMA_InitStruct.GDMA_ChannelNum = ADC_GDMA_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToMemory;
+ GDMA_InitStruct.GDMA_BufferSize = GDMA_TRANSFER_SIZE;//Determine total transfer size
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Inc;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_HalfWord;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_HalfWord;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)(&(ADC->FIFO));
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)ADC_Recv_Data_Buffer;
+ GDMA_InitStruct.GDMA_SourceHandshake = GDMA_Handshake_ADC;
+
+ GDMA_Init(ADC_GDMA_Channel, &GDMA_InitStruct);
+
+ GDMA_INTConfig(ADC_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+
+ /* GDMA irq init */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = ADC_GDMA_Channel_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ /* Start to receive data */
+ GDMA_Cmd(ADC_GDMA_CHANNEL_NUM, ENABLE);
+}
+
+/**
+ * @brief Demo code of operation about adc.
+ * @param No parameter.
+ * @return void
+*/
+void adc_demo(void)
+{
+// ADC_CalibrationInit();
+ /* Configure pad and pinmux firstly! */
+ board_adc_init();
+ /* Initialize adc peripheral */
+ driver_adc_init();
+ /* Initialize timer peripheral */
+ driver_adc_timer_init();
+ /* Initialize dma peripheral */
+ driver_adc_gdma_init();
+
+ ADC_ClearFIFO(ADC);
+ ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE);
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ __enable_irq();
+ adc_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ }
+}
+
+
+/**
+ * @brief ADC interrupt handler function.
+ * @param No parameter.
+ * @return void
+*/
+void ADC_Handler(void)
+{
+ DBG_DIRECT("ADC_Handler!");
+ if (ADC_GetINTStatus(ADC, ADC_INT_FIFO_RD_ERR) == SET)
+ {
+ DBG_DIRECT("ADC_INT_FIFO_RD_ERR");
+ ADC_ClearINTPendingBit(ADC, ADC_INT_FIFO_RD_ERR);
+ // Add user code here!
+ }
+ if (ADC_GetINTStatus(ADC, ADC_INT_FIFO_OVERFLOW) == SET)
+ {
+ DBG_DIRECT("ADC_INT_FIFO_OVERFLOW");
+ ADC_ClearINTPendingBit(ADC, ADC_INT_FIFO_OVERFLOW);
+ // Add user code here!
+ }
+}
+
+/**
+ * @brief GDMA channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+*/
+void ADC_GDMA_Channel_Handler(void)
+{
+ TIM_Cmd(TIM2, DISABLE);
+ DBG_DIRECT("ADC_GDMA_Channel_Handler!");
+ for (uint32_t i = 0; i < GDMA_TRANSFER_SIZE; i++)
+ {
+ DBG_DIRECT("ADC_GDMA_Channel_Handler: data[%d] = %d", i, ADC_Recv_Data_Buffer[i]);
+ }
+// ADC_ErrorStatus error_status = NO_ERROR;
+// for (uint32_t i = 0; i < GDMA_TRANSFER_SIZE; i++)
+// {
+// DBG_DIRECT("ADC sample data[%d] = %10d %10.2f", i, ADC_Recv_Data_Buffer[i],
+// ADC_GetVoltage(DIVIDE_SINGLE_MODE, ADC_Recv_Data_Buffer[i],
+// &error_status));
+// }
+ GDMA_SetSourceAddress(ADC_GDMA_Channel, (uint32_t)(&(ADC->FIFO)));
+ GDMA_SetDestinationAddress(ADC_GDMA_Channel, (uint32_t)(ADC_Recv_Data_Buffer));
+ GDMA_SetBufferSize(ADC_GDMA_Channel, GDMA_TRANSFER_SIZE);
+ GDMA_ClearINTPendingBit(ADC_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+ GDMA_Cmd(ADC_GDMA_CHANNEL_NUM, ENABLE);
+ ADC_ClearFIFO(ADC);
+ TIM_Cmd(TIM2, ENABLE);
+}
+
diff --git a/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/ancs.c b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/ancs.h b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app.c b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app.c
new file mode 100644
index 0000000..92e753c
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app.c
@@ -0,0 +1,609 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_adc.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_ADC:
+ {
+// APP_PRINT_INFO0("[app] app_handle_io_msg: adc msg.");
+ io_handle_adc_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ adc_sample_start();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app.h b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app_flags.h b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app_task.c b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app_task.c
new file mode 100644
index 0000000..635c4c3
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app_task.h b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/main.c b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/main.c
new file mode 100644
index 0000000..0d3fa3b
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode/ble_peripheral/main.c
@@ -0,0 +1,248 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+//#include "app_timer.h"
+
+#include "io_adc.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+ global_data_adc_init();
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_adc_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ adc_demo_driver_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+// sw_timer_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/ADC/OneShotMode/io_adc.c b/src/sample/io_sample/ADC/OneShotMode/io_adc.c
new file mode 100644
index 0000000..092d4c0
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode/io_adc.c
@@ -0,0 +1,248 @@
+
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_adc.c
+* @brief This file provides demo code of adc continuous mode.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_adc.h"
+
+#include "app_task.h"
+
+/* Globals ------------------------------------------------------------------*/
+ADC_Data_TypeDef ADC_Global_Data;
+
+/**
+ * @brief Initialization adc global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_adc_init(void)
+{
+ /* Initialize adc k value! */
+ APP_PRINT_INFO0("[io_adc] global_data_adc_init");
+ bool adc_k_status = false;
+ adc_k_status = ADC_CalibrationInit();
+ if (false == adc_k_status)
+ {
+ APP_PRINT_ERROR0("[io_adc] global_data_adc_init: ADC_CalibrationInit fail!");
+ }
+ memset(&ADC_Global_Data, 0, sizeof(ADC_Global_Data));
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_adc_init(void)
+{
+ Pad_Config(ADC_SAMPLE_PIN_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+}
+
+/**
+ * @brief Initialize ADC peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_adc_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+
+ ADC_InitTypeDef ADC_InitStruct;
+ ADC_StructInit(&ADC_InitStruct);
+
+ /* Configure the ADC sampling schedule0 */
+ ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(ADC_SAMPLE_CHANNEL_0);
+ /* Set the bitmap corresponding to schedule0*/
+ ADC_InitStruct.ADC_Bitmap = 0x01;
+
+#if (ADC_DATA_HW_AVERAGE && ADC_DATA_OUTPUT_TO_FIFO)
+ APP_PRINT_ERROR0("[io_adc] driver_adc_init: ADC config error !");
+#elif (ADC_DATA_HW_AVERAGE )
+ ADC_InitStruct.ADC_DataAvgEn = ADC_DATA_AVERAGE_ENABLE;
+ ADC_InitStruct.ADC_DataAvgSel = ADC_DATA_AVERAGE_OF_4;
+#elif (ADC_DATA_OUTPUT_TO_FIFO)
+ ADC_InitStruct.ADC_DataWriteToFifo = ADC_DATA_WRITE_TO_FIFO_ENABLE;
+ ADC_InitStruct.ADC_FifoThdLevel = 0x0A;
+#endif
+
+ ADC_InitStruct.ADC_PowerAlwaysOnEn = ADC_POWER_ALWAYS_ON_ENABLE;
+ /* Fixed 255 in OneShot mode. */
+ ADC_InitStruct.ADC_SampleTime = 255;
+
+ ADC_Init(ADC, &ADC_InitStruct);
+
+#if (ADC_MODE_DIVIDE_OR_BYPASS == ADC_BYPASS_MODE)
+ /* High bypass resistance mode config, please notice that the input voltage of
+ adc channel using high bypass mode should not be over 0.9V */
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_0, ENABLE);
+ APP_PRINT_INFO0("[io_adc] driver_adc_init: ADC sample mode is bypass mode !");
+#else
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_0, DISABLE);
+ APP_PRINT_INFO0("[io_adc] driver_adc_init: ADC sample mode is divide mode !");
+#endif
+
+#if (!ADC_DATA_OUTPUT_TO_FIFO)
+ ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE);
+#else
+ ADC_INTConfig(ADC, ADC_INT_FIFO_THD, ENABLE);
+#endif
+
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = ADC_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+ /* When ADC is enabled, sampling will be done quickly and interruption will occur.
+ After initialization, ADC can be enabled when sampling is needed.*/
+// ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE);
+}
+
+/**
+ * @brief Calculate adc sample voltage.
+ * @param No parameter.
+ * @return void
+ */
+static void io_adc_voltage_calculate(T_IO_MSG *io_adc_msg)
+{
+ ADC_Data_TypeDef *p_buf = io_adc_msg->u.buf;
+ uint8_t sample_data_len = 0;
+ uint16_t sample_data = 0;
+
+ sample_data_len = p_buf->RawDataLen;
+ for (uint8_t i = 0; i < sample_data_len; i++)
+ {
+ sample_data = p_buf->RawData[i];
+ DBG_DIRECT("io_adc_voltage_calculate: raw_data = 0x%X", sample_data);
+#if (ADC_DATA_HW_AVERAGE )
+ sample_data = (p_buf->RawData[i] & 0x3FFC) >> 2;
+ uint16_t sample_data_decimal = (p_buf->RawData[i] & 0x3);
+
+ float cacl_result = sample_data;
+ float cacl_result_dec = 0;
+ cacl_result_dec = (float)(sample_data_decimal & 0x1) / 2 + (float)((sample_data_decimal >> 1) & 0x1)
+ / 2;
+ cacl_result += cacl_result_dec;
+ DBG_DIRECT("io_adc_voltage_calculate: sample_data = %d, cacl_result = %d\r\n",
+ sample_data, (uint32_t)cacl_result);
+
+#endif
+ float sample_voltage = 0;
+ ADC_ErrorStatus error_status = NO_ERROR;
+#if (ADC_MODE_DIVIDE_OR_BYPASS == ADC_BYPASS_MODE)
+ sample_voltage = ADC_GetVoltage(BYPASS_SINGLE_MODE, (int32_t)sample_data, &error_status);
+#else
+ sample_voltage = ADC_GetVoltage(DIVIDE_SINGLE_MODE, (int32_t)sample_data, &error_status);
+#endif
+ if (error_status < 0)
+ {
+ APP_PRINT_INFO1("[io_adc] io_adc_voltage_calculate: ADC parameter or efuse data error! error_status = %d",
+ error_status);
+ }
+ else
+ {
+ APP_PRINT_INFO2("[io_adc] io_adc_voltage_calculate: ADC rawdata = %d, voltage = %dmV ",
+ sample_data, (uint32_t)sample_voltage);
+ }
+ }
+ memset(&ADC_Global_Data, 0, sizeof(ADC_Global_Data));
+}
+
+void adc_demo_driver_init(void)
+{
+ driver_adc_init();
+}
+
+void adc_sample_start(void)
+{
+#if (ADC_DATA_OUTPUT_TO_FIFO)
+ ADC_ClearFifo(ADC);
+#endif
+ /* Enable adc sample */
+ ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE);
+
+}
+
+/**
+ * @brief Handle adc data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_adc_msg(T_IO_MSG *io_adc_msg)
+{
+ io_adc_voltage_calculate(io_adc_msg);
+}
+
+/**
+ * @brief ADC interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void ADC_Handler(void)
+{
+#if (!ADC_DATA_OUTPUT_TO_FIFO)
+ if (ADC_GetINTStatus(ADC, ADC_INT_ONE_SHOT_DONE) == SET)
+ {
+ ADC_ClearINTPendingBit(ADC, ADC_INT_ONE_SHOT_DONE);
+
+ uint16_t sample_data = 0;
+ sample_data = ADC_ReadRawData(ADC, ADC_Schedule_Index_0);
+
+ T_IO_MSG int_adc_msg;
+ int_adc_msg.type = IO_MSG_TYPE_ADC;
+ int_adc_msg.subtype = 0;
+ ADC_Global_Data.RawDataLen = 1;
+ ADC_Global_Data.RawData[0] = sample_data;
+ int_adc_msg.u.buf = (void *)(&ADC_Global_Data);
+ if (false == app_send_msg_to_apptask(&int_adc_msg))
+ {
+ APP_PRINT_ERROR0("[io_adc] ADC_Handler: Send int_adc_msg failed!");
+ //Add user code here!
+ ADC_ClearINTPendingBit(ADC, ADC_INT_ONE_SHOT_DONE);
+ return;
+ }
+ }
+#else
+ if (ADC_GetIntFlagStatus(ADC, ADC_INT_FIFO_THD) == SET)
+ {
+// uint16_t sample_data[32] = {0};
+// /* stop write fifo */
+// ADC_ClearINTPendingBit(ADC, ADC_INT_FIFO_THD);
+ ADC_Global_Data.RawDataLen = ADC_GetFifoLen(ADC);
+ ADC_GetFifoData(ADC, ADC_Global_Data.RawData, ADC_Global_Data.RawDataLen);
+
+ DBG_DIRECT("ADC_INT_FIFO_THD: len = %d", ADC_Global_Data.RawDataLen);
+ for (uint8_t i = 0; i < ADC_Global_Data.RawDataLen; i++)
+ {
+ DBG_DIRECT("ADC_INT_FIFO_THD: data[%d] = %d", i, ADC_Global_Data.RawData[i]);
+ }
+ /* Send msg to app task */
+ T_IO_MSG int_adc_msg;
+ int_adc_msg.type = IO_MSG_TYPE_ADC;
+ int_adc_msg.u.buf = (void *)(&ADC_Global_Data);
+ if (false == app_send_msg_to_apptask(&int_adc_msg))
+ {
+ APP_PRINT_ERROR0("[io_adc] ADC_Handler: Send int_adc_msg failed!");
+ //Add user code here!
+ TIM_Cmd(TIM7, DISABLE);
+ ADC_ClearFifo(ADC);
+ ADC_ClearINTPendingBit(ADC, ADC_INT_FIFO_THD);
+ return;
+ }
+ ADC_ClearINTPendingBit(ADC, ADC_INT_FIFO_THD);
+ ADC_ClearFifo(ADC);
+ TIM_Cmd(TIM7, ENABLE);
+ }
+#endif
+}
+
diff --git a/src/sample/io_sample/ADC/OneShotMode/io_adc.h b/src/sample/io_sample/ADC/OneShotMode/io_adc.h
new file mode 100644
index 0000000..c628a5f
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode/io_adc.h
@@ -0,0 +1,121 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_adc.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_ADC_H
+#define __IO_ADC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_adc.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+
+#include "app_msg.h"
+#include "board.h"
+
+/* Defines ------------------------------------------------------------------*/
+/** ADC sample channel config.
+ * ADC sample channel config:P2_2,P2_3,P2_6,P2_7 and VBAT
+ * ADC sample channel index select: #define ADC_Channel_Index_0 0
+ * #define ADC_Channel_Index_1 1
+ * #define ADC_Channel_Index_2 2
+ * #define ADC_Channel_Index_3 3
+
+ * If ADC_SAMPLE_PIN = P2_2, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_0;
+ * If ADC_SAMPLE_PIN = P2_3, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_1;
+ * If ADC_SAMPLE_PIN = P2_6, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_4;
+ * If ADC_SAMPLE_PIN = P2_7, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_5;
+ */
+#define ADC_SAMPLE_CHANNEL_0 ADC_Channel_Index_0
+#define ADC_SAMPLE_CHANNEL_1 ADC_Channel_Index_1
+#define ADC_SAMPLE_CHANNEL_2 ADC_Channel_Index_2
+#define ADC_SAMPLE_CHANNEL_3 ADC_Channel_Index_3
+
+/* Define schedule index. */
+#define ADC_Schedule_Index_0 0
+#define ADC_Schedule_Index_1 1
+#define ADC_Schedule_Index_2 2
+#define ADC_Schedule_Index_3 3
+#define ADC_Schedule_Index_4 4
+#define ADC_Schedule_Index_5 5
+#define ADC_Schedule_Index_6 6
+#define ADC_Schedule_Index_7 7
+#define ADC_Schedule_Index_8 8
+#define ADC_Schedule_Index_9 9
+#define ADC_Schedule_Index_10 10
+#define ADC_Schedule_Index_11 11
+#define ADC_Schedule_Index_12 12
+#define ADC_Schedule_Index_13 13
+#define ADC_Schedule_Index_14 14
+#define ADC_Schedule_Index_15 15
+
+/** Define that how many schedules to use, max 16.
+ */
+#define ADC_SCHEDULE_NUM (2)
+
+/** ADC mode config.
+ * ADC pin hardware mode: bypass mode
+ * divide mode
+ */
+#define ADC_DIVIDE_MODE 0
+#define ADC_BYPASS_MODE 1
+#define ADC_MODE_DIVIDE_OR_BYPASS ADC_DIVIDE_MODE
+
+/** ADC data hardware average config,
+ * only sample one channel data and onle read data from ADC_Schedule_Index_0.
+ * Mode: 0: ADC data hardware average disable
+ * 1: ADC data hardware average enable
+ */
+#define ADC_DATA_HW_AVERAGE 1
+
+/** ADC data output mode config.
+ * Mode: 0: ADC data output to schedule table
+ * 1: ADC data output to fifo
+ */
+#define ADC_DATA_OUTPUT_TO_FIFO 0
+
+/** ADC ADC multiple fixed interval sampling config.
+ * Mode: 0: ADC sample once and stop
+ * 1: ADC timing sampling
+ */
+#define ADC_MULTI_SAMPLE 1
+
+#define ADC_ONE_SHOT_SAMPLE_PERIOD (1000000-1)//100ms
+
+/* ADC global data struct*/
+typedef struct
+{
+ uint16_t RawData[32];
+ uint8_t RawDataLen;
+} ADC_Data_TypeDef;
+
+extern ADC_Data_TypeDef ADC_Global_Data;
+
+void global_data_adc_init(void);
+void board_adc_init(void);
+void adc_demo_driver_init(void);
+void adc_sample_start(void);
+
+void io_handle_adc_msg(T_IO_MSG *io_adc_msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/ancs.c b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/ancs.h b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app.c b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app.c
new file mode 100644
index 0000000..cbc9143
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app.c
@@ -0,0 +1,608 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_adc.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_ADC:
+ {
+// APP_PRINT_INFO0("[app] app_handle_io_msg: adc msg.");
+ io_handle_adc_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app.h b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app_flags.h b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app_task.c b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app_task.c
new file mode 100644
index 0000000..635c4c3
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app_task.h b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/main.c b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/main.c
new file mode 100644
index 0000000..5b0e091
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/ble_peripheral/main.c
@@ -0,0 +1,249 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdlib.h>
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+//#include "app_timer.h"
+
+#include "io_adc.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+ global_data_adc_init();
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_adc_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_adc_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+// sw_timer_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/io_adc.c b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/io_adc.c
new file mode 100644
index 0000000..44e5d27
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/io_adc.c
@@ -0,0 +1,216 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_adc.c
+* @brief This file provides demo code of adc continuous mode.
+* @details
+* @author echo
+* @date 2021-06-29
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_adc.h"
+
+#include "app_task.h"
+
+/* Globals ------------------------------------------------------------------*/
+ADC_Data_TypeDef ADC_Global_Data;
+
+/**
+ * @brief Initialization adc global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_adc_init(void)
+{
+ /* Initialize adc k value! */
+ APP_PRINT_INFO0("[io_adc] global_data_adc_init");
+ bool adc_k_status = false;
+ adc_k_status = ADC_CalibrationInit();
+ if (false == adc_k_status)
+ {
+ APP_PRINT_ERROR0("[io_adc] global_data_adc_init: ADC_CalibrationInit fail!");
+ }
+ memset(&ADC_Global_Data, 0, sizeof(ADC_Global_Data));
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_adc_init(void)
+{
+ Pad_Config(ADC_SAMPLE_PIN_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+ Pad_Config(ADC_SAMPLE_PIN_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+}
+
+/**
+ * @brief Initialize ADC peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_adc_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+
+ ADC_InitTypeDef ADC_InitStruct;
+ ADC_StructInit(&ADC_InitStruct);
+ /** Configure the ADC sampling schedule, a schedule represents an ADC channel data,
+ * up to 16, i.e. schIndex[0] ~ schIndex[15].
+ * If one of the differential channel pairs uses P2_x, x = 2/6, then the other differential channel must be 1/2;
+ * If one of the differential channel pairs uses P2_x, x = 3/7, then the other differential channel must be 1/2.
+ * In differential mode, read the sample value of any channel of the differential channel pairs,
+ * and the absolute value of the two channels is approximately equal.
+ */
+ ADC_InitStruct.ADC_SchIndex[0] = EXT_DIFFERENTIAL(ADC_SAMPLE_CHANNEL_0);
+ ADC_InitStruct.ADC_SchIndex[1] = EXT_DIFFERENTIAL(ADC_SAMPLE_CHANNEL_1);
+ /** Set the bitmap corresponding to schedule, 16 bits, LSB,
+ * schIndex[0-15] corresponding to 16 bits of bitmap bit0-bit15.
+ * For example, if config schIndex[0] and schIndex [1], then bitmap is 0000 0000 0011 (that is, 0x0003);
+ * if config schIndex [0] and schIndex [2], then bitmap is 0000 0000 0101 (that is, 0x0005).
+ */
+ ADC_InitStruct.ADC_Bitmap = 0x03;
+ /* Fixed 255 in OneShot mode. */
+ ADC_InitStruct.ADC_SampleTime = 255;
+ ADC_Init(ADC, &ADC_InitStruct);
+
+#if (ADC_MODE_DIVIDE_OR_BYPASS == ADC_BYPASS_MODE)
+ /** High bypass resistance mode config, please notice that the input voltage of
+ * adc channel using high bypass mode should not be over 0.9V.
+ */
+ APP_PRINT_INFO0("[io_adc]driver_adc_init: ADC sample mode is bypass mode !");
+ uint8_t temp = ADC_SAMPLE_CHANNEL_0 & 0x02;
+ switch (temp)
+ {
+ case 0x0:
+ ADC_BypassCmd(0, ENABLE);
+ ADC_BypassCmd(1, ENABLE);
+ break;
+ case 0x02:
+ ADC_BypassCmd(2, ENABLE);
+ ADC_BypassCmd(3, ENABLE);
+ break;
+ default:
+ break;
+ }
+ temp += 0x01;
+#else
+ ADC_BypassCmd(0, DISABLE);
+ ADC_BypassCmd(1, DISABLE);
+ ADC_BypassCmd(2, DISABLE);
+ ADC_BypassCmd(3, DISABLE);
+ APP_PRINT_INFO0("[io_adc]driver_adc_init: ADC sample mode is divide mode !");
+#endif
+
+ ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE);
+
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = ADC_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+ /** When ADC is enabled, sampling will be done quickly and interruption will occur.
+ * After initialization, ADC can be enabled when sampling is needed.
+ */
+ ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE);
+}
+
+/**
+ * @brief Calculate adc sample voltage.
+ * @param No parameter.
+ * @return void
+ */
+static void io_adc_voltage_calculate(T_IO_MSG *io_adc_msg)
+{
+ uint8_t sample_data_len = 0;
+ uint16_t sample_data[ADC_SCHEDULE_NUM] = {0};
+ float sample_voltage[ADC_SCHEDULE_NUM] = {0};
+ ADC_ErrorStatus error_status = NO_ERROR;
+
+ uint16_t *p_buf = io_adc_msg->u.buf;
+
+ sample_data_len = p_buf[0];
+ for (uint8_t i = 0; i < sample_data_len; i++)
+ {
+ sample_data[i] = p_buf[i + 1];
+ }
+ for (uint8_t i = 0; i < sample_data_len; i++)
+ {
+
+#if (ADC_MODE_DIVIDE_OR_BYPASS == ADC_BYPASS_MODE)
+ sample_voltage[i] = ADC_GetVoltage(BYPASS_DIFFERENTIAL_MODE, (int32_t)sample_data[i],
+ &error_status);
+#else
+ sample_voltage[i] = ADC_GetVoltage(DIVIDE_DIFFERENTIAL_MODE, (int32_t)sample_data[i],
+ &error_status);
+#endif
+ if (error_status < 0)
+ {
+ APP_PRINT_INFO2("[io_adc]io_adc_voltage_calculate: ADC parameter or efuse data error! i = %d, error_status = %d",
+ i, error_status);
+ }
+ else
+ {
+ APP_PRINT_INFO4("[io_adc]io_adc_voltage_calculate: ADC rawdata_%-4d = %d, voltage_%-4d = %dmV ", i,
+ sample_data[i], i, (int32_t)sample_voltage[i]);
+ }
+ }
+ memset(&ADC_Global_Data, 0, sizeof(ADC_Global_Data));
+}
+
+/**
+ * @brief Handle adc data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_adc_msg(T_IO_MSG *io_adc_msg)
+{
+ io_adc_voltage_calculate(io_adc_msg);
+}
+
+/**
+ * @brief ADC interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void ADC_Handler(void)
+{
+ uint16_t sample_data[ADC_SCHEDULE_NUM] = {0};
+
+ if (ADC_GetINTStatus(ADC, ADC_INT_ONE_SHOT_DONE) == SET)
+ {
+ ADC_ClearINTPendingBit(ADC, ADC_INT_ONE_SHOT_DONE);
+ /* ADC one shot sampling mode, read data from schedule table.
+ The schedule index is which config in adc init function.
+ The value is ADC_Schedule_Index_0 ~ ADC_Schedule_Index_15
+ */
+
+ sample_data[0] = ADC_ReadRawData(ADC, ADC_Schedule_Index_0);
+ sample_data[1] = ADC_ReadRawData(ADC, ADC_Schedule_Index_1);
+
+ T_IO_MSG int_adc_msg;
+
+ int_adc_msg.type = IO_MSG_TYPE_ADC;
+ int_adc_msg.subtype = 0;
+ ADC_Global_Data.RawData[0] = 2;
+ for (uint8_t i = 0; i < ADC_SCHEDULE_NUM; i++)
+ {
+ ADC_Global_Data.RawData[i + 1] = sample_data[i];
+ }
+ int_adc_msg.u.buf = (void *)(ADC_Global_Data.RawData);
+ if (false == app_send_msg_to_apptask(&int_adc_msg))
+ {
+ APP_PRINT_ERROR0("[io_adc] ADC_Handler: Send int_adc_msg failed!");
+ //Add user code here!
+ ADC_ClearINTPendingBit(ADC, ADC_INT_ONE_SHOT_DONE);
+ return;
+ }
+ }
+}
+
diff --git a/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/io_adc.h b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/io_adc.h
new file mode 100644
index 0000000..9bf25da
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode_DifferentialMode/io_adc.h
@@ -0,0 +1,100 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_adc.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_ADC_H
+#define __IO_ADC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_adc.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+
+#include "app_msg.h"
+#include "board.h"
+
+/* Defines ------------------------------------------------------------------*/
+/** ADC sample channel config.
+ * ADC sample channel config:P2_2,P2_3,P2_6,P2_7 and VBAT
+ * ADC sample channel index select: #define ADC_Channel_Index_0 0
+ * #define ADC_Channel_Index_1 1
+ * #define ADC_Channel_Index_2 2
+ * #define ADC_Channel_Index_3 3
+
+ * If ADC_SAMPLE_PIN = P2_2, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_0;
+ * If ADC_SAMPLE_PIN = P2_3, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_1;
+ * If ADC_SAMPLE_PIN = P2_6, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_2;
+ * If ADC_SAMPLE_PIN = P2_7, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_3;
+ */
+#define ADC_SAMPLE_CHANNEL_0 ADC_Channel_Index_0
+#define ADC_SAMPLE_CHANNEL_1 ADC_Channel_Index_1
+
+/* Define schedule index. */
+#define ADC_Schedule_Index_0 0
+#define ADC_Schedule_Index_1 1
+#define ADC_Schedule_Index_2 2
+#define ADC_Schedule_Index_3 3
+#define ADC_Schedule_Index_4 4
+#define ADC_Schedule_Index_5 5
+#define ADC_Schedule_Index_6 6
+#define ADC_Schedule_Index_7 7
+#define ADC_Schedule_Index_8 8
+#define ADC_Schedule_Index_9 9
+#define ADC_Schedule_Index_10 10
+#define ADC_Schedule_Index_11 11
+#define ADC_Schedule_Index_12 12
+#define ADC_Schedule_Index_13 13
+#define ADC_Schedule_Index_14 14
+#define ADC_Schedule_Index_15 15
+
+/** Define that how many schedules to use, max 16.
+ */
+#define ADC_SCHEDULE_NUM (2)
+
+
+/** ADC mode config.
+ * ADC pin hardware mode: bypass mode
+ * divide mode
+ */
+#define ADC_DIVIDE_MODE 0
+#define ADC_BYPASS_MODE 1
+#define ADC_MODE_DIVIDE_OR_BYPASS ADC_DIVIDE_MODE
+
+#define ADC_ONE_SHOT_SAMPLE_PERIOD (1000000-1)//100ms
+
+
+/* ADC global data struct*/
+typedef struct
+{
+ uint16_t RawData[ADC_SCHEDULE_NUM + 1];
+} ADC_Data_TypeDef;
+
+extern ADC_Data_TypeDef ADC_Global_Data;
+
+void global_data_adc_init(void);
+void board_adc_init(void);
+void driver_adc_init(void);
+void driver_adc_timer_init(void);
+void io_handle_adc_msg(T_IO_MSG *io_adc_msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/ADC/OneShotMode_Polling/main.c b/src/sample/io_sample/ADC/OneShotMode_Polling/main.c
new file mode 100644
index 0000000..3b4129a
--- /dev/null
+++ b/src/sample/io_sample/ADC/OneShotMode_Polling/main.c
@@ -0,0 +1,209 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief Uses adc one shot sampling mode. Polling reads adc sampling data.
+* @details
+* @author yuan_feng
+* @date 2018-12-03
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes --------------------------------------------------------------*/
+#include <stdlib.h>
+#include "rtl876x_adc.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+
+#include "trace.h"
+
+/* Defines --------------------------------------------------------------*/
+#define ADC_Channel_Index_0 0
+#define ADC_Channel_Index_1 1
+#define ADC_Channel_Index_2 2
+#define ADC_Channel_Index_3 3
+
+
+#define ADC_Schedule_Index_0 0
+#define ADC_Schedule_Index_1 1
+#define ADC_Schedule_Index_2 2
+#define ADC_Schedule_Index_3 3
+#define ADC_Schedule_Index_4 4
+#define ADC_Schedule_Index_5 5
+#define ADC_Schedule_Index_6 6
+#define ADC_Schedule_Index_7 7
+#define ADC_Schedule_Index_8 8
+#define ADC_Schedule_Index_9 9
+#define ADC_Schedule_Index_10 10
+#define ADC_Schedule_Index_11 11
+#define ADC_Schedule_Index_12 12
+#define ADC_Schedule_Index_13 13
+#define ADC_Schedule_Index_14 14
+#define ADC_Schedule_Index_15 15
+
+/* Config ADC channel and mode --------------------------------------------------------------*/
+/* ADC bypass mode or divide mode */
+#define ADC_DIVIDE_MODE 0
+#define ADC_BYPASS_MODE 1
+/* Change the ADC sampling mode here! */
+#define ADC_MODE_DIVIDE_OR_BYPASS ADC_DIVIDE_MODE
+
+
+/* Change the ADC sampling pin here! */
+/** ADC sample channel config.
+ * ADC sample channel config:P2_2,P2_3,P2_6,P2_7 and VBAT
+ * ADC sample channel index select: #define ADC_Channel_Index_0 0
+ * #define ADC_Channel_Index_1 1
+ * #define ADC_Channel_Index_2 2
+ * #define ADC_Channel_Index_3 3
+
+ * If ADC_SAMPLE_PIN = P2_2, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_0;
+ * If ADC_SAMPLE_PIN = P2_3, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_1;
+ * If ADC_SAMPLE_PIN = P2_6, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_2;
+ * If ADC_SAMPLE_PIN = P2_7, then ADC_SAMPLE_CHANNEL = ADC_Channel_Index_3;
+ */
+#define ADC_SAMPLE_PIN_0 P2_2
+#define ADC_SAMPLE_CHANNEL_0 ADC_Channel_Index_0
+
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_adc_init(void)
+{
+ Pad_Config(ADC_SAMPLE_PIN_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+}
+
+/**
+ * @brief Initialize adc peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_adc_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+
+ ADC_InitTypeDef ADC_InitStruct;
+ ADC_StructInit(&ADC_InitStruct);
+ ADC_InitStruct.ADC_SampleTime = 255;
+ for (uint8_t i = 0; i < 16; i++)
+ {
+#ifdef INTERNAL_VBAT_TEST
+ ADC_InitStruct.schIndex[i] = INTERNAL_VBAT_MODE;
+#else
+ ADC_InitStruct.ADC_SchIndex[i] = EXT_SINGLE_ENDED(ADC_SAMPLE_CHANNEL_0);
+#endif
+ }
+ ADC_InitStruct.ADC_Bitmap = 0xFFFF;
+ ADC_InitStruct.ADC_PowerAlwaysOnEn = ADC_POWER_ALWAYS_ON_ENABLE;
+ ADC_Init(ADC, &ADC_InitStruct);
+
+#if (ADC_MODE_DIVIDE_OR_BYPASS == ADC_BYPASS_MODE)
+ /* High bypass resistance mode config, please notice that the input voltage of
+ adc channel using high bypass mode should not be over 0.9V */
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_0, ENABLE);
+ DBG_DIRECT("[ADC]ADC sample mode is bypass mode !");
+#else
+ DBG_DIRECT("[ADC]ADC sample mode is divide mode !");
+#endif
+ ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE);
+}
+
+/**
+ * @brief Demo code of operation about adc.
+ * @param No parameter.
+ * @return void
+ */
+void adc_demo(void)
+{
+ /* Initialize adc k value! */
+ bool adc_k_status;
+ adc_k_status = ADC_CalibrationInit();
+ if (false == adc_k_status)
+ {
+ APP_PRINT_ERROR0("[ADC]ADC_CalibrationInit fail!");
+ }
+ /* Configure pad and pinmux firstly! */
+ board_adc_init();
+
+ /* Initialize adc peripheral */
+ driver_adc_init();
+
+ /* Enable adc */
+ ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE);
+}
+
+/**
+ * @brief ADC polling sample demo code.
+ * @param No parameter.
+ * @return void
+ */
+void adc_sample_demo(void)
+{
+ uint16_t sample_data[16] = {0};
+ float sample_voltage[16] = {0};
+ ADC_ErrorStatus error_status = NO_ERROR;
+
+ while (ADC_GetINTStatus(ADC, ADC_INT_ONE_SHOT_DONE) == RESET);
+ ADC_ClearINTPendingBit(ADC, ADC_INT_ONE_SHOT_DONE);
+ for (uint8_t i = 0; i < 16; i++)
+ {
+ sample_data[i] = ADC_ReadRawData(ADC, ADC_Schedule_Index_0 + i);
+ }
+
+ for (uint8_t i = 0; i < 16; i++)
+ {
+#if (ADC_MODE_DIVIDE_OR_BYPASS == ADC_BYPASS_MODE)
+ sample_voltage[i] = ADC_GetVoltage(BYPASS_SINGLE_MODE, (int32_t)sample_data[i], &error_status);
+#else
+ sample_voltage[i] = ADC_GetVoltage(DIVIDE_SINGLE_MODE, (int32_t)sample_data[i], &error_status);
+#endif
+ if (error_status < 0)
+ {
+ /* Notes: DBG_DIRECT is only used for debug demo, do not use in app!
+ In app project, the APP_PRINT_INFO can be used.
+ */
+ DBG_DIRECT("[ADC]adc_sample_demo: ADC parameter or efuse data error! i = %d, error_status = %d", i,
+ error_status);
+// APP_PRINT_INFO2("[ADC] adc_sample_demo: ADC parameter or efuse data error! i = %d, error_status = %d", i, error_status);
+ }
+ else
+ {
+ /* Notes: DBG_DIRECT is only used for debug demo, do not use in app!
+ In app project, the APP_PRINT_INFO can be used.
+ */
+ DBG_DIRECT("[ADC] adc_sample_demo: ADC one shot mode sample data_%d = %d, voltage_%d = %dmV ", i,
+ sample_data[i], i, (uint32_t)sample_voltage[i]);
+// APP_PRINT_INFO4("[ADC] adc_sample_demo: ADC one shot mode sample data_%-4d = %d, voltage_%-4d = %dmV ", i, sample_data[i], i, (uint32_t)sample_voltage[i]);
+ }
+ }
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ adc_demo();
+
+ while (1)
+ {
+ /* Notes: DBG_DIRECT is only used for debug demo, do not use in app!
+ In app project, the APP_PRINT_INFO can be used.
+ */
+ DBG_DIRECT("[ADC]Polling reads adc sample data !");
+ adc_sample_demo();
+ for (uint32_t i = 500000; i > 0; i--);
+ ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE);
+ }
+}
+
+
diff --git a/src/sample/io_sample/CAPTOUCH/Touch/main.c b/src/sample/io_sample/CAPTOUCH/Touch/main.c
new file mode 100644
index 0000000..96d9845
--- /dev/null
+++ b/src/sample/io_sample/CAPTOUCH/Touch/main.c
@@ -0,0 +1,199 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2021, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file
+* @brief
+* @author
+* @date 2021-07-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2021 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "board.h"
+#include "rtl876x_adc.h"
+#include "rtl876x_captouch.h"
+#include "rtl876x_nvic.h"
+#include "trace.h"
+
+/* Globals -------------------------------------------------------------------*/
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_ctc_init(void)
+{
+
+}
+
+/**
+ * @brief Initialize tim peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_ctc_init(void)
+{
+// RCC_PeriphClockCmd(APBPeriph_CTC, APBPeriph_CTC_CLOCK, ENABLE);
+
+ CTC_RCCConfig(CTC_CLOCK_SOURCE_1M);
+
+ CTC_InitTypeDef CTC_InitStruct;
+ CTC_StructInit(&CTC_InitStruct);
+ CTC_InitStruct.CTC_ETCEn = ENABLE;
+ CTC_Init(CTC, &CTC_InitStruct);
+
+// AUXADC_PowerOn(ENABLE);
+
+ CTC_ChannelInitTypeDef CTC_ChannelInitStruct;
+ CTC_ChannelStructInit(&CTC_ChannelInitStruct);
+ CTC_ChannelInitStruct.CTC_DifferenceTouchThd = 0x00;
+ CTC_ChannelInitStruct.CTC_MBias = CTC_MBIAS_0p25uA;
+ CTC_ChannelInitStruct.CTC_ChannelEn = ENABLE;
+ CTC_ChannelInit(CTC_Channel0, &CTC_ChannelInitStruct);
+ CTC_ChannelInit(CTC_Channel1, &CTC_ChannelInitStruct);
+
+ /* Enable IRQ */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = CAP_TOUCH_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ CTC_INTConfig(CTC_INT_FALSE_TOUCH_CH0 | CTC_INT_TOUCH_RELEASE_CH0 | CTC_INT_TOUCH_PRESS_CH0,
+ ENABLE);
+ CTC_INTConfig(CTC_INT_FALSE_TOUCH_CH1 | CTC_INT_TOUCH_RELEASE_CH1 | CTC_INT_TOUCH_PRESS_CH1,
+ ENABLE);
+}
+
+/**
+ * @brief Demo code of Cap Touch.
+ * @param No parameter.
+ * @return void
+*/
+void ctc_demo(void)
+{
+ /* Initialize Cap Touch peripheral */
+ driver_ctc_init();
+
+ /* Set scan interval */
+ if (!CTC_SetScanInterval(0x3C, CTC_SLOW_MODE))
+ {
+ APP_PRINT_ERROR0(" Slow mode scan interval overange!\r\n");
+ }
+ if (!CTC_SetScanInterval(0x10, CTC_FAST_MODE))
+ {
+ APP_PRINT_ERROR0("Fast mode scan interval overange!\r\n");
+ }
+
+ /* Cap Touch start */
+ CTC_Cmd(CTC, ENABLE);
+ while (CTC_GetBaselineInistatus());
+ APP_PRINT_INFO0("Cap Touch Baseline init done!\r\n");
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ __enable_irq();
+
+ ctc_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ }
+}
+
+/**
+ * @brief CTC Interrupt Handler.
+ * @retval None
+ */
+void CAP_Touch_Handler(void)
+{
+ /*Printed information is only used for debugging, and removed in actual applications.*/
+ APP_PRINT_INFO3("ch0: [%4d, %5d, %4d]\r\n",
+ CTC_GetChannelAveData(CTC_Channel0),
+ CTC_GetChannelAveData(CTC_Channel0) - CTC_GetChannelBaseline(CTC_Channel0),
+ CTC_GetChannelTouchCount(CTC_CH0));
+ APP_PRINT_INFO3("ch1: [%4d, %5d, %4d]\r\n",
+ CTC_GetChannelAveData(CTC_Channel1),
+ CTC_GetChannelAveData(CTC_Channel1) - CTC_GetChannelBaseline(CTC_Channel1),
+ CTC_GetChannelTouchCount(CTC_CH1));
+ APP_PRINT_INFO3("fs:%d, touch0_status:%d, touch1_status:%d\r\n",
+ CTC_IsFastMode(),
+ CTC_GetChannelTouchStatus(CTC_CH0),
+ CTC_GetChannelTouchStatus(CTC_CH1));
+
+ /* Add corresponding interrupt processing according to application needs.*/
+ if (CTC_GetINTStatus(CTC, CTC_INT_FALSE_TOUCH_CH1))
+ {
+ CTC_ClearINTPendingBit(CTC, CTC_INT_FALSE_TOUCH_CH1);
+ APP_PRINT_INFO0("CTC_INT_FALSE_TOUCH_CH1\r\n");
+ }
+ if (CTC_GetINTStatus(CTC, CTC_INT_FALSE_TOUCH_CH0))
+ {
+ //Add user code here.
+ CTC_ClearINTPendingBit(CTC, CTC_INT_FALSE_TOUCH_CH0);
+ APP_PRINT_INFO0("CTC_INT_FALSE_TOUCH_CH0\r\n");
+ }
+ if (CTC_GetINTStatus(CTC, CTC_INT_TOUCH_RELEASE_CH1))
+ {
+ //Add user code here.
+ CTC_ClearINTPendingBit(CTC, CTC_INT_TOUCH_RELEASE_CH1);
+ APP_PRINT_INFO0("CTC_INT_TOUCH_RELEASE_CH1\r\n");
+ }
+ if (CTC_GetINTStatus(CTC, CTC_INT_TOUCH_RELEASE_CH0))
+ {
+ //Add user code here.
+ CTC_ClearINTPendingBit(CTC, CTC_INT_TOUCH_RELEASE_CH0);
+ APP_PRINT_INFO0("CTC_INT_TOUCH_RELEASE_CH0\r\n");
+ }
+ if (CTC_GetINTStatus(CTC, CTC_INT_TOUCH_PRESS_CH1))
+ {
+ //Add user code here.
+ CTC_ClearINTPendingBit(CTC, CTC_INT_TOUCH_PRESS_CH1);
+ APP_PRINT_INFO0("CTC_INT_TOUCH_PRESS_CH1\r\n");
+ }
+ if (CTC_GetINTStatus(CTC, CTC_INT_TOUCH_PRESS_CH0))
+ {
+ //Add user code here.
+ CTC_ClearINTPendingBit(CTC, CTC_INT_TOUCH_PRESS_CH0);
+ APP_PRINT_INFO0("CTC_INT_TOUCH_PRESS_CH0\r\n");
+ }
+ if (CTC_GetINTStatus(CTC, CTC_INT_N_NOISE_THD))
+ {
+ //Add user code here.
+ CTC_ClearINTPendingBit(CTC, CTC_INT_N_NOISE_THD);
+ APP_PRINT_INFO0("CTC_INT_N_NOISE_THD\r\n");
+ }
+ if (CTC_GetINTStatus(CTC, CTC_INT_P_NOISE_THD))
+ {
+ //Add user code here.
+ CTC_Cmd(CTC, DISABLE);
+ CTC_Cmd(CTC, ENABLE);
+ CTC_ClearINTPendingBit(CTC, CTC_INT_P_NOISE_THD);
+ APP_PRINT_INFO0("CTC_INT_P_NOISE_THD\r\n");
+ }
+ if (CTC_GetINTStatus(CTC, CTC_INT_FIFO_OVERFLOW))
+ {
+ //Add user code here.
+ CTC_ClearINTPendingBit(CTC, CTC_INT_FIFO_OVERFLOW);
+ APP_PRINT_INFO0("CTC_INT_FIFO_OVERFLOW\r\n");
+ }
+}
diff --git a/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/ancs.c b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/ancs.h b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app.c b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app.c
new file mode 100644
index 0000000..6cd10e5
--- /dev/null
+++ b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app.c
@@ -0,0 +1,608 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_cap_touch.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_UART:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: UART data msg.");
+ io_handle_uart_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app.h b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app_flags.h b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app_task.c b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app_task.c
new file mode 100644
index 0000000..8d0f4f9
--- /dev/null
+++ b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app_task.c
@@ -0,0 +1,133 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+#include "io_cap_touch.h"
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+uint8_t String_Buf[100];
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+
+ /* Send demo string */
+ uint8_t demo_str_len = 0;
+ char *demo_str = "### Welcome to use UART demo ###\r\n";
+ demo_str_len = strlen(demo_str);
+ memcpy(String_Buf, demo_str, demo_str_len);
+ uart_senddata_continuous(UART0, String_Buf, demo_str_len);
+
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app_task.h b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app_task.h
new file mode 100644
index 0000000..bd16830
--- /dev/null
+++ b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/app_task.h
@@ -0,0 +1,46 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/main.c b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/main.c
new file mode 100644
index 0000000..615eaf0
--- /dev/null
+++ b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/ble_peripheral/main.c
@@ -0,0 +1,332 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author echo
+* @date 2021-10-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+
+#include "dlps.h"
+#include "rtl876x_io_dlps.h"
+
+#include "io_cap_touch.h"
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+void global_data_init(void)
+{
+ global_data_cap_touch_init();
+ global_data_uart_init();
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_uart_init();
+
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_uart_init();
+}
+
+#if DLPS_EN
+/**
+ * @brief this function will be called before enter DLPS
+ *
+ * set PAD and wakeup pin config for enterring DLPS
+ *
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_enter_dlps_config(void)
+{
+ io_uart_dlps_enter();
+}
+
+/**
+ * @brief this function will be called after exit DLPS
+ *
+ * set PAD and wakeup pin config for enterring DLPS
+ *
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_exit_dlps_config(void)
+{
+ io_uart_dlps_exit();
+}
+
+/**
+ * @brief Contains the setting about app dlps callback.
+ */
+bool app_dlps_check_cb(void)
+{
+ return (io_uart_dlps_check());
+}
+#endif /* DLPS_EN */
+
+/**
+ * @brief The setting about power mode.
+ * @param No parameter.
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+#if DLPS_EN
+ if (false == dlps_check_cb_reg(app_dlps_check_cb))
+ {
+ APP_PRINT_ERROR0("Error: dlps_check_cb_reg(app_dlps_check_cb) failed!");
+ }
+ DLPS_IORegUserDlpsEnterCb(app_enter_dlps_config);
+ DLPS_IORegUserDlpsExitCb(app_exit_dlps_config);
+ DLPS_IORegister();
+ lps_mode_set(PLATFORM_DLPS_PFM);
+
+ /* Config WakeUp pin */
+ System_WakeUpPinEnable(UART_RX_PIN, PAD_WAKEUP_POL_LOW, 0);
+
+
+
+ if (false == dlps_check_cb_reg(app_dlps_check_cb))
+ {
+ APP_PRINT_ERROR0("Error: dlps_check_cb_reg(app_dlps_check_cb) failed!");
+ }
+ DLPS_IORegUserDlpsEnterCb(app_enter_dlps_config);
+ DLPS_IORegUserDlpsExitCb(app_exit_dlps_config);
+ DLPS_IORegister();
+ lps_mode_set(PLATFORM_DLPS_PFM);
+
+ /* Config WakeUp pin */
+ System_WakeUpPinEnable(UART_RX_PIN, PAD_WAKEUP_POL_LOW, 0);
+
+#else
+ lps_mode_set(LPM_ACTIVE_MODE);
+#endif
+}
+
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+/**
+ * @brief System interrupt handler function, for wakeup pin.
+ * @param No parameter.
+ * @return void
+*/
+void System_Handler(void)
+{
+ APP_PRINT_INFO0("[main] System_Handler");
+ if (System_WakeUpInterruptValue(UART_RX_PIN) == SET)
+ {
+ Pad_ClearWakeupINTPendingBit(UART_RX_PIN);
+ System_WakeUpPinDisable(UART_RX_PIN);
+ IO_UART_DLPS_Enter_Allowed = false;
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/CAPTOUCH/Touch_DLPS/io_cap_touch.h b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/io_cap_touch.h
new file mode 100644
index 0000000..0f4d553
--- /dev/null
+++ b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/io_cap_touch.h
@@ -0,0 +1,53 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_uart.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_UART_H
+#define __IO_UART_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_uart.h"
+
+#include "board.h"
+
+#include "app_msg.h"
+
+#define UART UART0
+
+/* Globals ------------------------------------------------------------------*/
+extern bool IO_UART_DLPS_Enter_Allowed;
+extern bool IO_CAP_TOUCH_DLPS_Enter_Allowed;
+
+void global_data_uart_init(void);
+void global_data_cap_touch_init(void);
+void board_uart_init(void);
+void driver_uart_init(void);
+void io_uart_dlps_enter(void);
+void io_uart_dlps_exit(void);
+bool io_uart_dlps_check(void);
+void io_handle_uart_msg(T_IO_MSG *io_uart_msg);
+void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/CAPTOUCH/Touch_DLPS/io_cap_tpuch.c b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/io_cap_tpuch.c
new file mode 100644
index 0000000..a290f71
--- /dev/null
+++ b/src/sample/io_sample/CAPTOUCH/Touch_DLPS/io_cap_tpuch.c
@@ -0,0 +1,249 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file io_uart.c
+* @brief uart interrupt demo
+* @details
+* @author yuan
+* @date 2018-06-28
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_cap_touch.h"
+
+#include <string.h>
+
+#include "app_task.h"
+
+#include "trace.h"
+
+
+/* Globals ------------------------------------------------------------------*/
+uint8_t UART_RX_Buffer[256];
+uint8_t UART_RX_Count = 0;
+
+bool IO_UART_DLPS_Enter_Allowed = false;
+bool IO_CAP_TOUCH_DLPS_Enter_Allowed = false;
+
+/**
+ * @brief Initialize uart global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_uart_init(void)
+{
+ IO_UART_DLPS_Enter_Allowed = true;
+ UART_RX_Count = 0;
+ memset(UART_RX_Buffer, 0, sizeof(UART_RX_Buffer));
+}
+
+/**
+ * @brief Initialize uart global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_cap_touch_init(void)
+{
+ IO_CAP_TOUCH_DLPS_Enter_Allowed = true;
+}
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_uart_init(void)
+{
+ Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+ Pad_Config(UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+
+ Pinmux_Config(UART_TX_PIN, UART0_TX);
+ Pinmux_Config(UART_RX_PIN, UART0_RX);
+}
+
+/**
+ * @brief Initialize uart peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_uart_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ /* uart init */
+ UART_InitTypeDef UART_InitStruct;
+ UART_StructInit(&UART_InitStruct);
+
+ UART_Init(UART0, &UART_InitStruct);
+
+ //enable rx interrupt and line status interrupt
+ UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+ UART_INTConfig(UART0, UART_INT_RX_IDLE, ENABLE);
+
+ /* Enable UART IRQ */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = UART0_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/**
+ * @brief IO enter dlps call back function.
+ * @param No parameter.
+ * @return void
+ */
+void io_uart_dlps_enter(void)
+{
+ /* Switch pad to Software mode */
+ Pad_ControlSelectValue(UART_TX_PIN, PAD_SW_MODE);
+ Pad_ControlSelectValue(UART_RX_PIN, PAD_SW_MODE);
+
+ System_WakeUpPinEnable(UART_RX_PIN, PAD_WAKEUP_POL_LOW, 0);
+}
+
+/**
+ * @brief IO exit dlps call back function.
+ * @param No parameter.
+ * @return void
+ */
+void io_uart_dlps_exit(void)
+{
+ /* Switch pad to Pinmux mode */
+ Pad_ControlSelectValue(UART_TX_PIN, PAD_PINMUX_MODE);
+ Pad_ControlSelectValue(UART_RX_PIN, PAD_PINMUX_MODE);
+
+}
+
+/**
+ * @brief IO enter dlps check function.
+ * @param No parameter.
+ * @return void
+ */
+bool io_uart_dlps_check(void)
+{
+ return IO_UART_DLPS_Enter_Allowed;
+}
+
+/**
+ * @brief UARt send data continuous.
+ * @param No parameter.
+ * @return void
+ */
+void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount)
+{
+ uint8_t count;
+
+ while (vCount / UART_TX_FIFO_SIZE > 0)
+ {
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ for (count = UART_TX_FIFO_SIZE; count > 0; count--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+ vCount -= UART_TX_FIFO_SIZE;
+ }
+
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ while (vCount--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+}
+
+/**
+ * @brief Handle uart data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_uart_handle_msg(T_IO_MSG *io_uart_msg)
+{
+// uint8_t *p_buf = io_uart_msg.u.buf;
+ uint16_t subtype = io_uart_msg->subtype;
+
+ if (IO_MSG_UART_RX == subtype)
+ {
+ uart_senddata_continuous(UART0, UART_RX_Buffer, UART_RX_Count);
+ global_data_uart_init();
+ while (UART_GetFlagStatus(UART0, UART_FLAG_TX_FIFO_EMPTY) == 0) { IO_UART_DLPS_Enter_Allowed = true; }
+ }
+}
+
+/**
+ * @brief Handle uart msg function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_uart_msg(T_IO_MSG *io_uart_msg)
+{
+ io_uart_handle_msg(io_uart_msg);
+}
+
+void UART0_Handler()
+{
+ uint16_t rx_len = 0;
+
+ /* Read interrupt id */
+ uint32_t int_status = UART_GetIID(UART0);
+
+ /* Disable interrupt */
+ UART_INTConfig(UART0, UART_INT_RD_AVA | UART_INT_RX_LINE_STS, DISABLE);
+
+ if (UART_GetFlagStatus(UART0, UART_FLAG_RX_IDLE) == SET)
+ {
+ /* Clear flag */
+ UART_INTConfig(UART0, UART_INT_RX_IDLE, DISABLE);
+
+ /* Send msg to app task */
+ T_IO_MSG int_uart_msg;
+
+ int_uart_msg.type = IO_MSG_TYPE_UART;
+ int_uart_msg.subtype = IO_MSG_UART_RX;
+ UART_RX_Buffer[UART_RX_Count] = UART_RX_Count;
+ int_uart_msg.u.buf = (void *)(&UART_RX_Buffer);
+ if (false == app_send_msg_to_apptask(&int_uart_msg))
+ {
+ APP_PRINT_ERROR0("[io_uart] UART0_Handler: Send int_uart_msg failed!");
+ //Add user code here!
+ return;
+ }
+// IO_UART_DLPS_Enter_Allowed = true;
+ UART_ClearRxFIFO(UART0);
+ UART_INTConfig(UART0, UART_INT_RX_IDLE, ENABLE);
+ }
+
+ switch (int_status & 0x0E)
+ {
+ /* Rx time out(0x0C). */
+ case UART_INT_ID_RX_DATA_TIMEOUT:
+ rx_len = UART_GetRxFIFODataLen(UART0);
+ UART_ReceiveData(UART0, &UART_RX_Buffer[UART_RX_Count], rx_len);
+ UART_RX_Count += rx_len;
+ break;
+
+ /* Receive line status interrupt(0x06). */
+ case UART_INT_ID_LINE_STATUS:
+ break;
+
+ /* Rx data valiable(0x04). */
+ case UART_INT_ID_RX_LEVEL_REACH:
+ rx_len = UART_GetRxFIFODataLen(UART0);
+ UART_ReceiveData(UART0, &UART_RX_Buffer[UART_RX_Count], rx_len);
+ UART_RX_Count += rx_len;
+ break;
+
+ /* Tx fifo empty(0x02), not enable. */
+ case UART_INT_ID_TX_EMPTY:
+ /* Do nothing */
+ break;
+ default:
+ break;
+ }
+
+ /* enable interrupt again */
+ UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/CODEC/AMIC/main.c b/src/sample/io_sample/CODEC/AMIC/main.c
new file mode 100644
index 0000000..fc3f8c1
--- /dev/null
+++ b/src/sample/io_sample/CODEC/AMIC/main.c
@@ -0,0 +1,235 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief AMIC demo code
+* @details
+* @author yuan
+* @date 2018-05-29
+* @version 0.1
+*********************************************************************************************************
+*/
+
+/* Includes -----------------------------------------------------------------*/
+#include <stdlib.h>
+#include "rtl876x_codec.h"
+#include "rtl876x_gdma.h"
+#include "rtl876x_i2s.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_uart.h"
+#include "trace.h"
+
+/* Defines ------------------------------------------------------------------*/
+/* Pin define of Data UART peripheral */
+#define UART_TX_PIN P2_4
+#define UART_RX_PIN P2_5
+
+/* Audio operation ---------------------------------------------*/
+#define AUDIO_FRAME_SIZE 4000
+
+/* GDMA RX defines */
+#define GDMA_Channel_AMIC_NUM 0
+#define GDMA_Channel_AMIC GDMA_Channel0
+#define GDMA_Channel_AMIC_IRQn GDMA0_Channel0_IRQn
+#define GDMA_Channel_AMIC_Handler GDMA0_Channel0_Handler
+
+#define GDMA_TX_BURST_SIZE ((uint32_t)1)
+#define GDMA_RX_BURST_SIZE ((uint32_t)1)
+
+/**
+ * @brief Initialization of codec pad settings.
+ * @param No parameter.
+ * @return Void
+ */
+void board_codec_init(void)
+{
+ Pad_Config(H_0, PAD_SW_MODE, PAD_NOT_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(P2_6, PAD_SW_MODE, PAD_NOT_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+ Pad_Config(P2_7, PAD_SW_MODE, PAD_NOT_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW);
+}
+
+/**
+ * @brief Initialization of uart pinmux settings and uart pad settings.
+ * @param No parameter.
+ * @return Void
+ */
+void board_uart_init(void)
+{
+ Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
+
+ Pinmux_Config(UART_TX_PIN, UART0_TX);
+ Pinmux_Config(UART_RX_PIN, UART0_RX);
+}
+
+/**
+ * @brief Initialize codec peripheral.
+ * @param No parameter.
+ * @return Void
+ */
+void driver_codec_init(void)
+{
+ /*switch to pwm mode*/
+ SystemCall(3, 1);
+ CODEC_AnalogCircuitInit();
+ RCC_PeriphClockCmd(APBPeriph_CODEC, APBPeriph_CODEC_CLOCK, ENABLE);
+
+ CODEC_InitTypeDef CODEC_InitStruct;
+ CODEC_StructInit(&CODEC_InitStruct);
+
+ CODEC_InitStruct.CODEC_Ch0MicType = CODEC_CH0_AMIC;
+ CODEC_InitStruct.CODEC_MicBstMode = MICBST_Mode_Differential;
+ CODEC_InitStruct.CODEC_SampleRate = SAMPLE_RATE_16KHz;
+ CODEC_InitStruct.CODEC_I2SFormat = CODEC_I2S_DataFormat_I2S;
+ CODEC_InitStruct.CODEC_I2SDataWidth = CODEC_I2S_DataWidth_16Bits;
+ CODEC_Init(CODEC, &CODEC_InitStruct);
+
+ CODEC_Init(CODEC, &CODEC_InitStruct);
+}
+
+/**
+ * @brief Initialize i2s peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_i2s_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_I2S0, APBPeriph_I2S0_CLOCK, ENABLE);
+
+ I2S_InitTypeDef I2S_InitStruct;
+ I2S_StructInit(&I2S_InitStruct);
+ I2S_InitStruct.I2S_ClockSource = I2S_CLK_40M;
+ I2S_InitStruct.I2S_DataFormat = I2S_Mode;
+ I2S_InitStruct.I2S_ChannelType = I2S_Channel_Mono;
+ I2S_InitStruct.I2S_DeviceMode = I2S_DeviceMode_Master;
+ I2S_InitStruct.I2S_RxWaterlevel = 0x4;
+ /* BCLK = 40MHz*(I2S_BClockNi/I2S_BClockMi) = Sample Rate * 64BCLK/sample */
+ I2S_InitStruct.I2S_BClockMi = 0x186A;
+ I2S_InitStruct.I2S_BClockNi = 0xA0;
+
+ I2S_Init(I2S0, &I2S_InitStruct);
+}
+
+/**
+ * @brief Initialize uart peripheral.
+ * @param No parameter.
+ * @return Void
+ */
+void driver_uart_init(void)
+{
+ /* Enable clock */
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ /* UART init */
+ UART_InitTypeDef UART_InitStruct;
+
+ UART_StructInit(&UART_InitStruct);
+ /* change to 3M baudrate */
+ UART_InitStruct.UART_Div = 1;
+ UART_InitStruct.UART_Ovsr = 8;
+ UART_InitStruct.UART_OvsrAdj = 0x492;
+ UART_InitStruct.UART_TxWaterLevel = 12;
+ UART_InitStruct.UART_TxDmaEn = ENABLE;
+ UART_InitStruct.UART_DmaEn = UART_DMA_ENABLE;
+ UART_Init(UART0, &UART_InitStruct);
+}
+
+/**
+ * @brief Initialize gdma peripheral.
+ * @param No parameter.
+ * @return Void
+ */
+void driver_gdma_init(void)
+{
+ /* Enable GDMA clock */
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+
+ /* Initialize GDMA peripheral */
+ GDMA_InitTypeDef GDMA_InitStruct;
+
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = GDMA_Channel_AMIC_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToPeripheral;
+ GDMA_InitStruct.GDMA_BufferSize = AUDIO_FRAME_SIZE / 4;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)(&(I2S0->RX_DR));
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(UART0->RB_THR));
+ GDMA_InitStruct.GDMA_SourceHandshake = GDMA_Handshake_I2S0_RX;
+ GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_UART0_TX;
+ GDMA_Init(GDMA_Channel_AMIC, &GDMA_InitStruct);
+ GDMA_INTConfig(GDMA_Channel_AMIC_NUM, GDMA_INT_Transfer, ENABLE);
+
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = GDMA_Channel_AMIC_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 1;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/**
+ * @brief Demo code of codec amic.
+ * @param No parameter.
+ * @return Void
+ */
+void codec_demo(void)
+{
+ board_codec_init();
+ board_uart_init();
+ driver_i2s_init();
+ driver_uart_init();
+ driver_gdma_init();
+ driver_codec_init();
+ I2S_Cmd(I2S0, I2S_MODE_TX | I2S_MODE_RX, ENABLE);
+ GDMA_Cmd(GDMA_Channel_AMIC_NUM, ENABLE);
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+
+ codec_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+
+ }
+}
+
+/**
+ * @brief GDMA interrupt handler function.
+ * @param No parameter.
+ * @return Void
+ */
+void GDMA_Channel_AMIC_Handler(void)
+{
+ GDMA_SetSourceAddress(GDMA_Channel_AMIC, (uint32_t)(&(I2S0->RX_DR)));
+ GDMA_SetDestinationAddress(GDMA_Channel_AMIC, (uint32_t)(&(UART0->RB_THR)));
+
+ GDMA_SetBufferSize(GDMA_Channel_AMIC, AUDIO_FRAME_SIZE / 4);
+
+ GDMA_ClearINTPendingBit(GDMA_Channel_AMIC_NUM, GDMA_INT_Transfer);
+ GDMA_Cmd(GDMA_Channel_AMIC_NUM, ENABLE);
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/CODEC/DMIC/main.c b/src/sample/io_sample/CODEC/DMIC/main.c
new file mode 100644
index 0000000..04a2ed0
--- /dev/null
+++ b/src/sample/io_sample/CODEC/DMIC/main.c
@@ -0,0 +1,248 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief DMIC demo code
+* @details
+* @author yuan
+* @date 2018-05-29
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes -----------------------------------------------------------------*/
+#include <stdlib.h>
+#include "rtl876x_codec.h"
+#include "rtl876x_gdma.h"
+#include "rtl876x_i2s.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_uart.h"
+#include "trace.h"
+
+/* Defines ------------------------------------------------------------------*/
+/* Pin define of DMIC peripheral */
+#define DMIC_MSBC_CLK_PIN P3_2
+#define DMIC_MSBC_DAT_PIN P3_3
+
+/* Pin define of Data UART peripheral */
+#define UART UART0
+#define UART_TX_PIN P2_4
+#define UART_RX_PIN P2_5
+
+#define GDMA_TX_BURST_SIZE ((uint32_t)1)
+#define GDMA_RX_BURST_SIZE ((uint32_t)1)
+
+/* Audio operation ---------------------------------------------*/
+#define AUDIO_FRAME_SIZE 4000
+
+/* GDMA RX defines */
+#define GDMA_Channel_DMIC_NUM 0
+#define GDMA_Channel_DMIC GDMA_Channel0
+#define GDMA_Channel_DMIC_IRQn GDMA0_Channel0_IRQn
+#define GDMA_Channel_DMIC_Handler GDMA0_Channel0_Handler
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return Void
+ */
+void board_codec_init(void)
+{
+ Pad_Config(DMIC_MSBC_CLK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+ Pad_Config(DMIC_MSBC_DAT_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+
+ Pinmux_Config(DMIC_MSBC_CLK_PIN, DMIC1_CLK);
+ Pinmux_Config(DMIC_MSBC_DAT_PIN, DMIC1_DAT);
+}
+
+/**
+ * @brief Initialization of uart pinmux settings and uart pad settings.
+ * @param No parameter.
+ * @return Void
+ */
+void board_uart_init(void)
+{
+ Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
+
+ Pinmux_Config(UART_TX_PIN, UART0_TX);
+ Pinmux_Config(UART_RX_PIN, UART0_RX);
+}
+
+/**
+ * @brief Initialize codec peripheral.
+ * @param No parameter.
+ * @return Void
+ */
+void driver_codec_init(void)
+{
+ /*switch to pwm mode*/
+ SystemCall(3, 1);
+
+ CODEC_AnalogCircuitInit();
+
+ RCC_PeriphClockCmd(APBPeriph_CODEC, APBPeriph_CODEC_CLOCK, ENABLE);
+
+ CODEC_InitTypeDef CODEC_InitStruct;
+
+ CODEC_StructInit(&CODEC_InitStruct);
+ CODEC_InitStruct.CODEC_Ch0MicType = CODEC_CH0_DMIC;
+ CODEC_InitStruct.CODEC_DmicClock = DMIC_Clock_2500KHz;
+ CODEC_InitStruct.CODEC_Ch0DmicDataLatch = DMIC_Ch0_Rising_Latch;
+ CODEC_InitStruct.CODEC_SampleRate = SAMPLE_RATE_16KHz;
+ CODEC_InitStruct.CODEC_I2SFormat = CODEC_I2S_DataFormat_I2S;
+ CODEC_InitStruct.CODEC_I2SDataWidth = CODEC_I2S_DataWidth_16Bits;
+ CODEC_Init(CODEC, &CODEC_InitStruct);
+ DBG_DIRECT("Use dmic test!");
+}
+
+/**
+ * @brief Initialize i2s peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_i2s_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_I2S0, APBPeriph_I2S0_CLOCK, ENABLE);
+
+ I2S_InitTypeDef I2S_InitStruct;
+
+ I2S_StructInit(&I2S_InitStruct);
+ I2S_InitStruct.I2S_ClockSource = I2S_CLK_40M;
+ I2S_InitStruct.I2S_BClockMi = 0x271;/* <!BCLK = 16K */
+ I2S_InitStruct.I2S_BClockNi = 0x10;
+ I2S_InitStruct.I2S_DeviceMode = I2S_DeviceMode_Master;
+ I2S_InitStruct.I2S_ChannelType = I2S_Channel_Mono;
+ I2S_InitStruct.I2S_DataFormat = I2S_Mode;
+ I2S_Init(I2S0, &I2S_InitStruct);
+}
+
+/**
+ * @brief Initialize uart peripheral.
+ * @param No parameter.
+ * @return Void
+ */
+void driver_uart_init(void)
+{
+ /* Enable clock */
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ /* UART init */
+ UART_InitTypeDef UART_InitStruct;
+
+ UART_StructInit(&UART_InitStruct);
+ /* change to 3M baudrate */
+ UART_InitStruct.UART_Div = 1;
+ UART_InitStruct.UART_Ovsr = 8;
+ UART_InitStruct.UART_OvsrAdj = 0x492;
+ UART_InitStruct.UART_TxWaterLevel = 12;
+
+ UART_InitStruct.UART_TxDmaEn = ENABLE;
+ UART_InitStruct.UART_DmaEn = UART_DMA_ENABLE;
+ UART_Init(UART0, &UART_InitStruct);
+
+}
+
+/**
+ * @brief Initialize gdma peripheral.
+ * @param No parameter.
+ * @return Void
+ */
+void driver_gdma_init(void)
+{
+ /* Enable GDMA clock */
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+
+ /* Initialize GDMA peripheral */
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = GDMA_Channel_DMIC_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToPeripheral;
+ GDMA_InitStruct.GDMA_BufferSize = AUDIO_FRAME_SIZE / 4;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)(&(I2S0->RX_DR));
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(UART0->RB_THR));
+ GDMA_InitStruct.GDMA_SourceHandshake = GDMA_Handshake_I2S0_RX;
+ GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_UART0_TX;
+ GDMA_Init(GDMA_Channel_DMIC, &GDMA_InitStruct);
+ GDMA_INTConfig(GDMA_Channel_DMIC_NUM, GDMA_INT_Transfer, ENABLE);
+
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = GDMA_Channel_DMIC_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 1;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/**
+ * @brief Demo code of codec dmic.
+ * @param No parameter.
+ * @return Void
+*/
+void codec_demo(void)
+{
+ board_codec_init();
+ board_uart_init();
+
+ driver_i2s_init();
+ driver_uart_init();
+ driver_gdma_init();
+ driver_codec_init();
+
+ I2S_Cmd(I2S0, I2S_MODE_TX | I2S_MODE_RX, ENABLE);
+ GDMA_Cmd(GDMA_Channel_DMIC_NUM, ENABLE);
+}
+
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+
+ codec_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+
+ }
+}
+
+/**
+ * @brief GDMA interrupt handler function.
+ * @param No parameter.
+ * @return Void
+*/
+void GDMA_Channel_DMIC_Handler(void)
+{
+ GDMA_SetSourceAddress(GDMA_Channel_DMIC, (uint32_t)(&(I2S0->RX_DR)));
+ GDMA_SetDestinationAddress(GDMA_Channel_DMIC, (uint32_t)(&(UART0->RB_THR)));
+
+ GDMA_SetBufferSize(GDMA_Channel_DMIC, AUDIO_FRAME_SIZE / 4);
+
+ GDMA_ClearINTPendingBit(GDMA_Channel_DMIC_NUM, GDMA_INT_Transfer);
+ GDMA_Cmd(GDMA_Channel_DMIC_NUM, ENABLE);
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/ancs.c b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/ancs.h b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app.c b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app.c
new file mode 100644
index 0000000..6db6d59
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app.c
@@ -0,0 +1,610 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_gdma.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_GDMA:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: GDMA interrupt msg.");
+ io_handle_gdma_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ /* Enable GDMA transmission when the GAP stack is ready. */
+ GDMA_Cmd(GDMA_CHANNEL_NUM, ENABLE);
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app.h b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app_flags.h b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app_task.c b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app_task.c
new file mode 100644
index 0000000..cd427fc
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app_task.h b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/main.c b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/main.c
new file mode 100644
index 0000000..396449e
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/ble_peripheral/main.c
@@ -0,0 +1,234 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+
+#include "io_gdma.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_gdma_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_multi_block/io_gdma.c b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/io_gdma.c
new file mode 100644
index 0000000..757dc1e
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/io_gdma.c
@@ -0,0 +1,230 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file io_gdma.c
+* @brief This file provides demo code of meomory to memory transfer by gdma.
+* @details
+* @author yuan
+* @date 2019-01-11
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_gdma.h"
+
+#include "app_task.h"
+
+/* Globals ------------------------------------------------------------------*/
+//uint32_t GDMA_Send_Buf[GDMA_TRANSFER_SIZE];
+//uint32_t GDMA_Recv_Buf[GDMA_TRANSFER_SIZE];
+uint8_t GDMA_Send_Buffer[GDMA_MULTIBLOCK_SIZE][GDMA_TRANSFER_SIZE];
+uint8_t GDMA_Recv_Buffer[GDMA_MULTIBLOCK_SIZE][GDMA_TRANSFER_SIZE];
+GDMA_LLIDef GDMA_LLIStruct[GDMA_MULTIBLOCK_SIZE];
+
+/**
+ * @brief Initialize gdma peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_gdma_init(void)
+{
+ uint32_t i, j = 0;
+
+ /*--------------Initialize test buffer---------------------*/
+ for (i = 0; i < GDMA_TRANSFER_SIZE; i++)
+ {
+ for (j = 0; j < GDMA_MULTIBLOCK_SIZE; j++)
+ {
+ GDMA_Send_Buffer[j][i] = (i + j) & 0xff;
+ GDMA_Recv_Buffer[j][i] = 0;
+ }
+ }
+
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+
+ GDMA_InitStruct.GDMA_ChannelNum = GDMA_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToMemory;
+ GDMA_InitStruct.GDMA_BufferSize = GDMA_TRANSFER_SIZE;//determine total transfer size
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Inc;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_Send_Buffer;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)GDMA_Recv_Buffer;
+ GDMA_InitStruct.GDMA_Multi_Block_Mode = GDMA_MULTIBLOCK_MODE;//LLI_TRANSFER;
+ GDMA_InitStruct.GDMA_Multi_Block_En = 1;
+ GDMA_InitStruct.GDMA_Multi_Block_Struct = (uint32_t)GDMA_LLIStruct;
+
+ for (uint32_t i = 0; i < GDMA_MULTIBLOCK_SIZE; i++)
+ {
+ if (i == GDMA_MULTIBLOCK_SIZE - 1)
+ {
+ //GDMA_LLIStruct[i].LLP=0;
+ GDMA_LLIStruct[i].SAR = (uint32_t)GDMA_Send_Buffer[i];
+ GDMA_LLIStruct[i].DAR = (uint32_t)GDMA_Recv_Buffer[i];
+ GDMA_LLIStruct[i].LLP = 0;
+ /* Configure low 32 bit of CTL register */
+ GDMA_LLIStruct[i].CTL_LOW = BIT(0)
+ | (GDMA_InitStruct.GDMA_DestinationDataSize << 1)
+ | (GDMA_InitStruct.GDMA_SourceDataSize << 4)
+ | (GDMA_InitStruct.GDMA_DestinationInc << 7)
+ | (GDMA_InitStruct.GDMA_SourceInc << 9)
+ | (GDMA_InitStruct.GDMA_DestinationMsize << 11)
+ | (GDMA_InitStruct.GDMA_SourceMsize << 14)
+ | (GDMA_InitStruct.GDMA_DIR << 20);
+ /* Configure high 32 bit of CTL register */
+ GDMA_LLIStruct[i].CTL_HIGH = GDMA_InitStruct.GDMA_BufferSize;
+ }
+ else
+ {
+ GDMA_LLIStruct[i].SAR = (uint32_t)GDMA_Send_Buffer[i];
+ GDMA_LLIStruct[i].DAR = (uint32_t)GDMA_Recv_Buffer[i];
+ GDMA_LLIStruct[i].LLP = (uint32_t)&GDMA_LLIStruct[i + 1];
+ /* Configure low 32 bit of CTL register */
+ GDMA_LLIStruct[i].CTL_LOW = BIT(0)
+ | (GDMA_InitStruct.GDMA_DestinationDataSize << 1)
+ | (GDMA_InitStruct.GDMA_SourceDataSize << 4)
+ | (GDMA_InitStruct.GDMA_DestinationInc << 7)
+ | (GDMA_InitStruct.GDMA_SourceInc << 9)
+ | (GDMA_InitStruct.GDMA_DestinationMsize << 11)
+ | (GDMA_InitStruct.GDMA_SourceMsize << 14)
+ | (GDMA_InitStruct.GDMA_DIR << 20)
+ | (GDMA_InitStruct.GDMA_Multi_Block_Mode & LLP_SELECTED_BIT);
+ /* Configure high 32 bit of CTL register */
+ GDMA_LLIStruct[i].CTL_HIGH = GDMA_InitStruct.GDMA_BufferSize;
+ }
+ }
+ GDMA_Init(GDMA_Channel, &GDMA_InitStruct);
+
+ /* GDMA irq config */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = GDMA_Channel_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&NVIC_InitStruct);
+
+ /** Either single block transmission completion interruption or transmission completion interruption can be choose.
+ * Synchronized modifications are also required in GDMA_Channel_Handler if a single block transmission interrupt is used.
+ */
+#if (GDMA_INTERRUPT_MODE == INT_TRANSFER)
+ GDMA_INTConfig(GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+#elif (GDMA_INTERRUPT_MODE == INT_BLOCK)
+ GDMA_INTConfig(GDMA_CHANNEL_NUM, GDMA_INT_Block, ENABLE);
+#endif
+ /** To debug, enable GDMA transmission when the GAP stack is ready.
+ * In app.c->app_handle_dev_state_evt()
+ */
+// GDMA_Cmd(GDMA_CHANNEL_NUM, ENABLE);
+}
+
+#if (GDMA_INTERRUPT_MODE == INT_TRANSFER)
+/**
+ * @brief Handle gdma data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_gdma_msg(T_IO_MSG *io_gdma_msg)
+{
+ APP_PRINT_INFO0("[io_gdma] io_handle_gdma_msg: GDMA transfer data completion!");
+
+ for (uint32_t i = 0; i < GDMA_MULTIBLOCK_SIZE; i++)
+ {
+ for (uint32_t j = 0; j < GDMA_TRANSFER_SIZE; j++)
+ {
+ if (GDMA_Send_Buffer[i][j] != GDMA_Recv_Buffer[i][j])
+ {
+ APP_PRINT_INFO2("[io_gdma]io_handle_gdma_msg: Data transmission error! GDMA_Send_Buffer = %d, GDMA_Recv_Buffer = %d",
+ GDMA_Send_Buffer[i][j], GDMA_Recv_Buffer[i][j]);
+ }
+ GDMA_Recv_Buffer[i][j] = 0;
+ }
+ }
+}
+
+/**
+ * @brief GDMA channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void GDMA_Channel_Handler(void)
+{
+ GDMA_INTConfig(GDMA_CHANNEL_NUM, GDMA_INT_Transfer, DISABLE);
+
+ T_IO_MSG int_gdma_msg;
+
+ int_gdma_msg.type = IO_MSG_TYPE_GDMA;
+ int_gdma_msg.subtype = 0;
+ if (false == app_send_msg_to_apptask(&int_gdma_msg))
+ {
+ APP_PRINT_ERROR0("[io_gdma] GDMA_Channel_Handler: Send int_gdma_msg failed!");
+ //Add user code here!
+ GDMA_ClearINTPendingBit(GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+ return;
+ }
+
+ GDMA_ClearINTPendingBit(GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+}
+
+#elif (GDMA_INTERRUPT_MODE == INT_BLOCK)
+static uint8_t GDMA_INT_Block_Counter = 0;
+/**
+ * @brief Handle gdma data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_gdma_msg(T_IO_MSG *io_gdma_msg)
+{
+ uint8_t *p_buf = io_gdma_msg->u.buf;
+
+ APP_PRINT_INFO1("[io_gdma] io_handle_gdma_msg: GDMA block%d transfer data completion!", *p_buf);
+ for (uint32_t j = 0; j < GDMA_TRANSFER_SIZE; j++)
+ {
+ if (GDMA_Send_Buffer[*p_buf][j] != GDMA_Recv_Buffer[*p_buf][j])
+ {
+ APP_PRINT_INFO2("[io_gdma]io_handle_gdma_msg: Data transmission error! GDMA_Send_Buffer = %d, GDMA_Recv_Buffer = %d",
+ GDMA_Send_Buffer[*p_buf][j], GDMA_Recv_Buffer[*p_buf][j]);
+ }
+ GDMA_Recv_Buffer[*p_buf][j] = 0;
+ }
+ GDMA_INT_Block_Counter++;
+ if (GDMA_INT_Block_Counter < GDMA_MULTIBLOCK_SIZE)
+ {
+ GDMA_INTConfig(GDMA_CHANNEL_NUM, GDMA_INT_Block, ENABLE);
+ }
+ else
+ {
+ GDMA_INT_Block_Counter = 0;
+ }
+
+}
+/**
+ * @brief GDMA channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void GDMA_Channel_Handler(void)
+{
+ GDMA_INTConfig(GDMA_CHANNEL_NUM, GDMA_INT_Block, DISABLE);
+
+ T_IO_MSG int_gdma_msg;
+
+ int_gdma_msg.type = IO_MSG_TYPE_GDMA;
+ int_gdma_msg.subtype = 0;
+ int_gdma_msg.u.buf = (void *)&GDMA_INT_Block_Counter;
+ if (false == app_send_msg_to_apptask(&int_gdma_msg))
+ {
+ APP_PRINT_ERROR0("[io_gdma]GDMA_Channel_Handler: Send int_gdma_msg failed!");
+ //Add user code here!
+ GDMA_ClearINTPendingBit(GDMA_CHANNEL_NUM, GDMA_INT_Block);
+ return;
+ }
+}
+
+#endif
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_multi_block/io_gdma.h b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/io_gdma.h
new file mode 100644
index 0000000..9e7469a
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_multi_block/io_gdma.h
@@ -0,0 +1,70 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_gdma.h
+* @brief
+* @details
+* @author yuan
+* @date 2019-01-11
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_GDMA_H
+#define __IO_GDMA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include "rtl876x_gdma.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "trace.h"
+
+#include "board.h"
+
+#include "app_task.h"
+
+/* Defines ------------------------------------------------------------------*/
+/* Channel 0 ~ channel 1 have multiple block mode. */
+#define GDMA_CHANNEL_NUM 1
+#define GDMA_Channel GDMA_Channel1
+#define GDMA_Channel_IRQn GDMA0_Channel1_IRQn
+#define GDMA_Channel_Handler GDMA0_Channel1_Handler
+
+/* The maximum number of GDMA single block is 65535. */
+#define GDMA_TRANSFER_SIZE 200
+
+#define GDMA_MULTIBLOCK_SIZE 12
+
+/** GDMA multi block mode.
+ * AUTO_RELOAD_WITH_CONTIGUOUS_SAR
+ * AUTO_RELOAD_WITH_CONTIGUOUS_DAR
+ * AUTO_RELOAD_TRANSFER
+ * LLI_WITH_CONTIGUOUS_SAR
+ * LLI_WITH_AUTO_RELOAD_SAR
+ * LLI_WITH_CONTIGUOUS_DAR
+ * LLI_WITH_AUTO_RELOAD_DAR
+ * LLI_TRANSFER
+ */
+#define GDMA_MULTIBLOCK_MODE LLI_TRANSFER
+
+#define INT_TRANSFER 1
+#define INT_BLOCK 0
+#define GDMA_INTERRUPT_MODE INT_TRANSFER
+
+void driver_gdma_init(void);
+void io_handle_gdma_msg(T_IO_MSG *io_gdma_msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/ancs.c b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/ancs.h b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app.c b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app.c
new file mode 100644
index 0000000..3df95ce
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app.c
@@ -0,0 +1,610 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_gdma.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_GDMA:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: GDMA input msg.");
+ io_handle_gdma_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ /* Enable GDMA transmission when the GAP stack is ready. */
+ GDMA_Cmd(GDMA_CHANNEL_NUM, ENABLE);
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app.h b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app_flags.h b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app_task.c b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app_task.c
new file mode 100644
index 0000000..f5914b1
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app_task.h b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/main.c b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/main.c
new file mode 100644
index 0000000..396449e
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_single_block/ble_peripheral/main.c
@@ -0,0 +1,234 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+
+#include "io_gdma.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_gdma_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_single_block/io_gdma.c b/src/sample/io_sample/GDMA/Mem2Mem_single_block/io_gdma.c
new file mode 100644
index 0000000..4fff321
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_single_block/io_gdma.c
@@ -0,0 +1,116 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file io_gdma.c
+* @brief This file provides demo code of meomory to memory transfer by gdma.
+* @details
+* @author yuan
+* @date 2019-01-11
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_gdma.h"
+
+#include "app_task.h"
+
+/* Globals ------------------------------------------------------------------*/
+uint32_t GDMA_Send_Buf[GDMA_TRANSFER_SIZE];
+uint32_t GDMA_Recv_Buf[GDMA_TRANSFER_SIZE];
+
+/**
+ * @brief Initialize gdma peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_gdma_init(void)
+{
+ uint32_t i = 0;
+
+ /* Test data buffer */
+ for (i = 0; i < GDMA_TRANSFER_SIZE; i++)
+ {
+ GDMA_Send_Buf[i] = i + 1;
+ GDMA_Recv_Buf[i] = 0;
+ }
+
+ /* Turn on gdma clock */
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+ /* GDMA initial*/
+ GDMA_InitStruct.GDMA_ChannelNum = GDMA_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToMemory;
+ GDMA_InitStruct.GDMA_BufferSize = GDMA_TRANSFER_SIZE;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Inc;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_8;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_8;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_Send_Buf;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)GDMA_Recv_Buf;
+
+ GDMA_Init(GDMA_Channel, &GDMA_InitStruct);
+
+ GDMA_INTConfig(GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+
+ /* GDMA irq init */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = GDMA_Channel_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&NVIC_InitStruct);
+
+ /** To debug, enable GDMA transmission when the GAP stack is ready.
+ * In app.c->app_handle_dev_state_evt()
+ */
+// GDMA_Cmd(GDMA_CHANNEL_NUM, ENABLE);
+}
+
+/**
+ * @brief Handle gdma data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_gdma_msg(T_IO_MSG *io_gdma_msg)
+{
+ APP_PRINT_INFO0("[io_gdma] io_handle_gdma_msg: GDMA transfer data completion!");
+ for (uint32_t i = 0; i < GDMA_TRANSFER_SIZE; i++)
+ {
+ if (GDMA_Send_Buf[i] != GDMA_Recv_Buf[i])
+ {
+ APP_PRINT_INFO2("[io_gdma] io_handle_gdma_msg: Data transmission error! GDMA_Send_Buf = %d, GDMA_Recv_Buf = %d",
+ GDMA_Send_Buf[i], GDMA_Recv_Buf[i]);
+ }
+ }
+}
+
+/**
+ * @brief GDMA channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void GDMA_Channel_Handler(void)
+{
+ GDMA_INTConfig(GDMA_CHANNEL_NUM, GDMA_INT_Transfer, DISABLE);
+
+ T_IO_MSG int_gdma_msg;
+
+ int_gdma_msg.type = IO_MSG_TYPE_GDMA;
+ int_gdma_msg.subtype = 0;
+ if (false == app_send_msg_to_apptask(&int_gdma_msg))
+ {
+ APP_PRINT_ERROR0("[io_gdma] GDMA_Channel_Handler: Send int_gdma_msg failed!");
+ //Add user code here!
+ GDMA_ClearINTPendingBit(GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+ return;
+ }
+
+ GDMA_ClearINTPendingBit(GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+}
+
+
diff --git a/src/sample/io_sample/GDMA/Mem2Mem_single_block/io_gdma.h b/src/sample/io_sample/GDMA/Mem2Mem_single_block/io_gdma.h
new file mode 100644
index 0000000..3e6a0c8
--- /dev/null
+++ b/src/sample/io_sample/GDMA/Mem2Mem_single_block/io_gdma.h
@@ -0,0 +1,51 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_gdma.h
+* @brief
+* @details
+* @author yuan
+* @date 2019-01-11
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_GDMA_H
+#define __IO_GDMA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include "rtl876x_gdma.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "trace.h"
+
+#include "board.h"
+
+#include "app_task.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define GDMA_CHANNEL_NUM 2
+#define GDMA_Channel GDMA_Channel2
+#define GDMA_Channel_IRQn GDMA0_Channel2_IRQn
+#define GDMA_Channel_Handler GDMA0_Channel2_Handler
+
+/* The maximum number of GDMA single block is 65535. */
+#define GDMA_TRANSFER_SIZE 200
+
+void driver_gdma_init(void);
+void io_handle_gdma_msg(T_IO_MSG *io_gdma_msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/GPIO/Input_key/ble_peripheral/ancs.c b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/GPIO/Input_key/ble_peripheral/ancs.h b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/GPIO/Input_key/ble_peripheral/app.c b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/app.c
new file mode 100644
index 0000000..a5b3e02
--- /dev/null
+++ b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/app.c
@@ -0,0 +1,607 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_gpio.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_GPIO:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: GPIO input msg.");
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/GPIO/Input_key/ble_peripheral/app.h b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/GPIO/Input_key/ble_peripheral/app_flags.h b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/GPIO/Input_key/ble_peripheral/app_task.c b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/app_task.c
new file mode 100644
index 0000000..f5914b1
--- /dev/null
+++ b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/GPIO/Input_key/ble_peripheral/app_task.h b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/GPIO/Input_key/ble_peripheral/main.c b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/main.c
new file mode 100644
index 0000000..72b1766
--- /dev/null
+++ b/src/sample/io_sample/GPIO/Input_key/ble_peripheral/main.c
@@ -0,0 +1,235 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+
+#include "io_gpio.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_gpio_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_gpio_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/GPIO/Input_key/io_gpio.c b/src/sample/io_sample/GPIO/Input_key/io_gpio.c
new file mode 100644
index 0000000..762fd0e
--- /dev/null
+++ b/src/sample/io_sample/GPIO/Input_key/io_gpio.c
@@ -0,0 +1,91 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_gpio.c
+* @brief This file provides demo code of gpio input mode.
+ Get key value.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_gpio.h"
+
+#include "app_task.h"
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_gpio_init(void)
+{
+ Pad_Config(GPIO_INPUT_PIN_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(GPIO_INPUT_PIN_0, DWGPIO);
+}
+
+/**
+ * @brief Initialize GPIO peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_gpio_init(void)
+{
+ /* Initialize GPIO peripheral */
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+ GPIO_StructInit(&GPIO_InitStruct);
+ GPIO_InitStruct.GPIO_Pin = GPIO_PIN_INPUT;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
+ GPIO_InitStruct.GPIO_ITCmd = ENABLE;
+ GPIO_InitStruct.GPIO_ITTrigger = GPIO_INT_Trigger_EDGE;
+ GPIO_InitStruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW;
+ GPIO_InitStruct.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_ENABLE;
+ GPIO_InitStruct.GPIO_DebounceTime = 10;/* unit:ms , can be 1~64 ms */
+ GPIO_Init(&GPIO_InitStruct);
+
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = GPIO_PIN_INPUT_IRQN;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ GPIO_MaskINTConfig(GPIO_PIN_INPUT, DISABLE);
+ GPIO_INTConfig(GPIO_PIN_INPUT, ENABLE);
+}
+
+/**
+ * @brief GPIO interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void GPIO_Input_Handler(void)
+{
+ GPIO_INTConfig(GPIO_PIN_INPUT, DISABLE);
+ GPIO_MaskINTConfig(GPIO_PIN_INPUT, ENABLE);
+
+ T_IO_MSG int_gpio_msg;
+
+ int_gpio_msg.type = IO_MSG_TYPE_GPIO;
+ int_gpio_msg.subtype = 0;
+ if (false == app_send_msg_to_apptask(&int_gpio_msg))
+ {
+ APP_PRINT_ERROR0("[io_gpio] GPIO_Input_Handler: Send int_gpio_msg failed!");
+ //Add user code here!
+ GPIO_ClearINTPendingBit(GPIO_PIN_INPUT);
+ return;
+ }
+
+ GPIO_ClearINTPendingBit(GPIO_PIN_INPUT);
+ GPIO_MaskINTConfig(GPIO_PIN_INPUT, DISABLE);
+ GPIO_INTConfig(GPIO_PIN_INPUT, ENABLE);
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/GPIO/Input_key/io_gpio.h b/src/sample/io_sample/GPIO/Input_key/io_gpio.h
new file mode 100644
index 0000000..4731c6a
--- /dev/null
+++ b/src/sample/io_sample/GPIO/Input_key/io_gpio.h
@@ -0,0 +1,39 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_gpio.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_GPIO_H
+#define __IO_GPIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_gpio.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+
+#include "board.h"
+
+
+void board_gpio_init(void);
+void driver_gpio_init(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/GPIO/Input_polling/main.c b/src/sample/io_sample/GPIO/Input_polling/main.c
new file mode 100644
index 0000000..5c8e50b
--- /dev/null
+++ b/src/sample/io_sample/GPIO/Input_polling/main.c
@@ -0,0 +1,94 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code of gpio input mode.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include "rtl876x_gpio.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "trace.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define GPIO_INPUT_PIN_0 P2_3
+#define GPIO_PIN_INPUT GPIO_GetPin(GPIO_INPUT_PIN_0)
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_gpio_init(void)
+{
+ Pad_Config(GPIO_INPUT_PIN_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(GPIO_INPUT_PIN_0, DWGPIO);
+}
+
+/**
+ * @brief Initialize GPIO peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_gpio_init(void)
+{
+ /* Initialize GPIO peripheral */
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+ GPIO_StructInit(&GPIO_InitStruct);
+ GPIO_InitStruct.GPIO_Pin = GPIO_PIN_INPUT;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
+ GPIO_InitStruct.GPIO_ITCmd = DISABLE;
+ GPIO_Init(&GPIO_InitStruct);
+}
+
+/**
+ * @brief Demo code of operation about gpio.
+ * @param No parameter.
+ * @return void
+ */
+void gpio_demo(void)
+{
+ /* Configure pad and pinmux firstly! */
+ board_gpio_init();
+
+ /* Initialize gpio peripheral */
+ driver_gpio_init();
+
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ gpio_demo();
+
+ while (1)
+ {
+ /* Read GPIO input value: gpio_input_data */
+ uint8_t gpio_input_data = GPIO_ReadInputDataBit(GPIO_PIN_INPUT);
+
+ /** User code here.
+ * for example: print the value of gpio_input_data;
+ */
+// DBG_DIRECT ("gpio_input_data = %d", gpio_input_data);
+// for(uint32_t i = 0 ; i <10000; i++);
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/GPIO/Output_led/main.c b/src/sample/io_sample/GPIO/Output_led/main.c
new file mode 100644
index 0000000..504f98f
--- /dev/null
+++ b/src/sample/io_sample/GPIO/Output_led/main.c
@@ -0,0 +1,93 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code of gpio output mode.
+ Control LED flashing.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include "rtl876x_gpio.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+
+/* Defines ------------------------------------------------------------------*/
+/* P0_1 is connected to LED0 on EVB board */
+#define GPIO_OUTPUT_PIN_0 P0_1
+#define GPIO_PIN_OUTPUT GPIO_GetPin(GPIO_OUTPUT_PIN_0)
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_gpio_init(void)
+{
+ Pad_Config(GPIO_OUTPUT_PIN_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(GPIO_OUTPUT_PIN_0, DWGPIO);
+}
+
+/**
+ * @brief Initialize GPIO peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_gpio_init(void)
+{
+ /* Initialize GPIO peripheral */
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+ GPIO_StructInit(&GPIO_InitStruct);
+ GPIO_InitStruct.GPIO_Pin = GPIO_PIN_OUTPUT;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_InitStruct.GPIO_ITCmd = DISABLE;
+ GPIO_Init(&GPIO_InitStruct);
+}
+
+/**
+ * @brief Demo code of operation about gpio.
+ * @param No parameter.
+ * @return void
+ */
+void gpio_demo(void)
+{
+ /* Configure pad and pinmux firstly! */
+ board_gpio_init();
+
+ /* Initialize gpio peripheral */
+ driver_gpio_init();
+
+}
+
+/**
+ * @brief Entry of app code
+ * @return int(To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ gpio_demo();
+
+ while (1)
+ {
+ /* Light up LED0 */
+ GPIO_WriteBit(GPIO_PIN_OUTPUT, (BitAction)(1));
+ for (uint32_t i = 0; i < 1000000; i++);
+ /* Lights out LED0 */
+ GPIO_WriteBit(GPIO_PIN_OUTPUT, (BitAction)(0));
+ for (uint32_t i = 0; i < 1000000; i++);
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/GPIO/Output_led/xiaomi_gpio_test.c b/src/sample/io_sample/GPIO/Output_led/xiaomi_gpio_test.c
new file mode 100644
index 0000000..09a4f04
--- /dev/null
+++ b/src/sample/io_sample/GPIO/Output_led/xiaomi_gpio_test.c
@@ -0,0 +1,322 @@
+/* Includes ------------------------------------------------------------------*/
+#include "xiaomi_gpio_mp_test.h"
+
+#include <string.h>
+
+
+uint8_t GPIO_PIN_NUM[12][2] =
+{
+ {0, 3}, //P0_0 0, P0_3 3
+ {6, 0}, //P0_6 6, P0_7 7
+ {1, 2}, //P0_1 1, P0_2 2
+ {4, 36}, //P0_4 4, H_0 36
+ {8, 9}, //P1_0 8, P1_1 9
+ {18, 19}, //P2_2 18,P2_3 19
+ {20, 21}, //P2_4 20,P2_5 21
+ {22, 23}, //P2_6 22,P2_7 23
+ {26, 27}, //P3_2 26,P3_3 27
+
+ {32, 33}, //P4_0 32,P4_1 33
+ {34, 35}, //P4_2 34,P4_3 35
+ {37, 38}, //H_1 37,H_2 38
+// {20,21},//P2_4 20,P2_5 21
+// {22,23},//P2_6 22,P2_7 23
+// {26,27},//P3_2 26,P3_3 27
+};
+
+uint8_t GPIO_Test_Result[12] = {0};
+
+uint8_t *mp_test_gpio_forward(void)
+{
+ DBG_DIRECT("mp_test_gpio_forward");
+
+ uint32_t pin_input = 0;
+ uint32_t pin_output = 0;
+ uint8_t gpio_input_data[12];
+
+ GPIO_DeInit();
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+ GPIO_StructInit(&GPIO_InitStruct);
+ for (uint8_t i = 1; i < 9; i++)
+ {
+ /* GPIO pin input */
+ Pad_Config(GPIO_PIN_NUM[i][0], PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(GPIO_PIN_NUM[i][0], DWGPIO);
+ pin_input |= GPIO_GetPin(GPIO_PIN_NUM[i][0]);
+
+ /* GPIO pin output */
+ Pad_Config(GPIO_PIN_NUM[i][1], PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(GPIO_PIN_NUM[i][1], DWGPIO);
+ pin_output |= GPIO_GetPin(GPIO_PIN_NUM[i][1]);
+ }
+ GPIO_InitStruct.GPIO_Pin = pin_input;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
+ GPIO_InitStruct.GPIO_ITCmd = DISABLE;
+ GPIO_Init(&GPIO_InitStruct);
+
+ GPIO_InitStruct.GPIO_Pin = pin_output;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_InitStruct.GPIO_ITCmd = DISABLE;
+ GPIO_Init(&GPIO_InitStruct);
+
+ /* output low */
+ DBG_DIRECT("mp_test_gpio: output low");
+ GPIO_Write(~pin_output);
+// for (uint32_t i = 0; i < 1000; i++);
+ for (uint8_t i = 1; i < 9; i++)
+ {
+ gpio_input_data[i] = GPIO_ReadInputDataBit(GPIO_GetPin(GPIO_PIN_NUM[i][0]));
+ if (0 != gpio_input_data[i]) { GPIO_Test_Result[i]++; }
+ DBG_DIRECT("mp_test_gpio: gpio_input_data_%d = %d", GPIO_PIN_NUM[i][0], gpio_input_data[i]);
+ }
+ memset(gpio_input_data, 0, sizeof(gpio_input_data));
+
+ /* output high */
+ DBG_DIRECT("mp_test_gpio: output high");
+ GPIO_Write(pin_output);
+// for (uint32_t i = 0; i < 1000; i++);
+ for (uint8_t i = 1; i < 9; i++)
+ {
+ gpio_input_data[i] = GPIO_ReadInputDataBit(GPIO_GetPin(GPIO_PIN_NUM[i][0]));
+ if (1 != gpio_input_data[i]) { GPIO_Test_Result[i]++; }
+ DBG_DIRECT("mp_test_gpio: gpio_input_data_%d = %d", GPIO_PIN_NUM[i][0], gpio_input_data[i]);
+ }
+ memset(gpio_input_data, 0, sizeof(gpio_input_data));
+
+ DBG_DIRECT("mp_test_gpio: output low");
+ GPIO_Write(~pin_output);
+// for (uint32_t i = 0; i < 1000; i++);
+ for (uint8_t i = 1; i < 9; i++)
+ {
+ gpio_input_data[i] = GPIO_ReadInputDataBit(GPIO_GetPin(GPIO_PIN_NUM[i][0]));
+ if (0 != gpio_input_data[i]) { GPIO_Test_Result[i]++; }
+ DBG_DIRECT("mp_test_gpio: gpio_input_data_%d = %d", GPIO_PIN_NUM[i][0], gpio_input_data[i]);
+ }
+ memset(gpio_input_data, 0, sizeof(gpio_input_data));
+
+ GPIO_DeInit();
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+ GPIO_StructInit(&GPIO_InitStruct);
+ pin_input = 0;
+ pin_output = 0;
+ for (uint8_t i = 1; i < 9; i++)
+ {
+ Pinmux_Config(GPIO_PIN_NUM[i][0], IDLE_MODE);
+ Pinmux_Config(GPIO_PIN_NUM[i][1], IDLE_MODE);
+ }
+
+ for (uint8_t i = 9; i < 12; i++)
+ {
+ /* GPIO pin input */
+ Pad_Config(GPIO_PIN_NUM[i][0], PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(GPIO_PIN_NUM[i][0], DWGPIO);
+ pin_input |= GPIO_GetPin(GPIO_PIN_NUM[i][0]);
+
+ /* GPIO pin output */
+ Pad_Config(GPIO_PIN_NUM[i][1], PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(GPIO_PIN_NUM[i][1], DWGPIO);
+ pin_output |= GPIO_GetPin(GPIO_PIN_NUM[i][1]);
+ }
+ GPIO_InitStruct.GPIO_Pin = pin_input;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
+ GPIO_InitStruct.GPIO_ITCmd = DISABLE;
+ GPIO_Init(&GPIO_InitStruct);
+
+ GPIO_InitStruct.GPIO_Pin = pin_output;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_InitStruct.GPIO_ITCmd = DISABLE;
+ GPIO_Init(&GPIO_InitStruct);
+
+ /* output low */
+ DBG_DIRECT("mp_test_gpio: output low");
+ GPIO_Write(~pin_output);
+// for (uint32_t i = 0; i < 1000; i++);
+ for (uint8_t i = 9; i < 12; i++)
+ {
+ gpio_input_data[i] = GPIO_ReadInputDataBit(GPIO_GetPin(GPIO_PIN_NUM[i][0]));
+ if (0 != gpio_input_data[i]) { GPIO_Test_Result[i]++; }
+ DBG_DIRECT("mp_test_gpio: gpio_input_data_%d = %d", GPIO_PIN_NUM[i][0], gpio_input_data[i]);
+ }
+ memset(gpio_input_data, 0, sizeof(gpio_input_data));
+
+ /* output high */
+ DBG_DIRECT("mp_test_gpio: output high");
+ GPIO_Write(pin_output);
+// for (uint32_t i = 0; i < 1000; i++);
+ for (uint8_t i = 9; i < 12; i++)
+ {
+ gpio_input_data[i] = GPIO_ReadInputDataBit(GPIO_GetPin(GPIO_PIN_NUM[i][0]));
+ if (1 != gpio_input_data[i]) { GPIO_Test_Result[i]++; }
+ DBG_DIRECT("mp_test_gpio: gpio_input_data_%d = %d", GPIO_PIN_NUM[i][0], gpio_input_data[i]);
+ }
+ memset(gpio_input_data, 0, sizeof(gpio_input_data));
+
+ /* output low */
+ DBG_DIRECT("mp_test_gpio: output low");
+ GPIO_Write(~pin_output);
+// for (uint32_t i = 0; i < 100000; i++);
+ for (uint8_t i = 9; i < 12; i++)
+ {
+ gpio_input_data[i] = GPIO_ReadInputDataBit(GPIO_GetPin(GPIO_PIN_NUM[i][0]));
+ if (0 != gpio_input_data[i]) { GPIO_Test_Result[i]++; }
+ DBG_DIRECT("mp_test_gpio: gpio_input_data_%d = %d", GPIO_PIN_NUM[i][0], gpio_input_data[i]);
+ }
+ memset(gpio_input_data, 0, sizeof(gpio_input_data));
+ APP_PRINT_INFO1("GPIO_Test_Result %b", TRACE_BINARY(12, GPIO_Test_Result));
+ return GPIO_Test_Result;//right 0; error ~0
+}
+
+uint8_t *mp_test_gpio_backward(void)
+{
+ DBG_DIRECT("mp_test_gpio_backward");
+
+ uint32_t pin_input = 0;
+ uint32_t pin_output = 0;
+ uint8_t gpio_input_data[12];
+
+ GPIO_DeInit();
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+ GPIO_StructInit(&GPIO_InitStruct);
+ for (uint8_t i = 1; i < 9; i++)
+ {
+ /* GPIO pin input */
+ Pad_Config(GPIO_PIN_NUM[i][1], PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(GPIO_PIN_NUM[i][1], DWGPIO);
+ pin_input |= GPIO_GetPin(GPIO_PIN_NUM[i][1]);
+
+ /* GPIO pin output */
+ Pad_Config(GPIO_PIN_NUM[i][0], PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(GPIO_PIN_NUM[i][0], DWGPIO);
+ pin_output |= GPIO_GetPin(GPIO_PIN_NUM[i][0]);
+ }
+ GPIO_InitStruct.GPIO_Pin = pin_input;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
+ GPIO_InitStruct.GPIO_ITCmd = DISABLE;
+ GPIO_Init(&GPIO_InitStruct);
+
+ GPIO_InitStruct.GPIO_Pin = pin_output;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_InitStruct.GPIO_ITCmd = DISABLE;
+ GPIO_Init(&GPIO_InitStruct);
+
+ /* output low */
+ DBG_DIRECT("mp_test_gpio: output low");
+ GPIO_Write(~pin_output);
+ for (uint32_t i = 0; i < 1000; i++);
+ for (uint8_t i = 1; i < 9; i++)
+ {
+ gpio_input_data[i] = GPIO_ReadInputDataBit(GPIO_GetPin(GPIO_PIN_NUM[i][1]));
+ if (0 != gpio_input_data[i]) { GPIO_Test_Result[i]++; }
+ DBG_DIRECT("mp_test_gpio: gpio_input_data_%d = %d", GPIO_PIN_NUM[i][1], gpio_input_data[i]);
+ }
+ memset(gpio_input_data, 0, sizeof(gpio_input_data));
+
+ /* output high */
+ DBG_DIRECT("mp_test_gpio: output high");
+ GPIO_Write(pin_output);
+ for (uint32_t i = 0; i < 1000; i++);
+ for (uint8_t i = 1; i < 9; i++)
+ {
+ gpio_input_data[i] = GPIO_ReadInputDataBit(GPIO_GetPin(GPIO_PIN_NUM[i][1]));
+ if (1 != gpio_input_data[i]) { GPIO_Test_Result[i]++; }
+ DBG_DIRECT("mp_test_gpio: gpio_input_data_%d = %d", GPIO_PIN_NUM[i][1], gpio_input_data[i]);
+ }
+ memset(gpio_input_data, 0, sizeof(gpio_input_data));
+
+ /* output low */
+ DBG_DIRECT("mp_test_gpio: output low");
+ GPIO_Write(~pin_output);
+ for (uint32_t i = 0; i < 1000; i++);
+ for (uint8_t i = 1; i < 9; i++)
+ {
+ gpio_input_data[i] = GPIO_ReadInputDataBit(GPIO_GetPin(GPIO_PIN_NUM[i][1]));
+ if (0 != gpio_input_data[i]) { GPIO_Test_Result[i]++; }
+ DBG_DIRECT("mp_test_gpio: gpio_input_data_%d = %d", GPIO_PIN_NUM[i][1], gpio_input_data[i]);
+ }
+ memset(gpio_input_data, 0, sizeof(gpio_input_data));
+
+ GPIO_DeInit();
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+ GPIO_StructInit(&GPIO_InitStruct);
+ pin_input = 0;
+ pin_output = 0;
+ for (uint8_t i = 1; i < 9; i++)
+ {
+ Pinmux_Config(GPIO_PIN_NUM[i][0], IDLE_MODE);
+ Pinmux_Config(GPIO_PIN_NUM[i][1], IDLE_MODE);
+ }
+
+ for (uint8_t i = 9; i < 12; i++)
+ {
+ /* GPIO pin input */
+ Pad_Config(GPIO_PIN_NUM[i][1], PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(GPIO_PIN_NUM[i][1], DWGPIO);
+ pin_input |= GPIO_GetPin(GPIO_PIN_NUM[i][1]);
+
+ /* GPIO pin output */
+ Pad_Config(GPIO_PIN_NUM[i][0], PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(GPIO_PIN_NUM[i][0], DWGPIO);
+ pin_output |= GPIO_GetPin(GPIO_PIN_NUM[i][0]);
+ }
+ GPIO_InitStruct.GPIO_Pin = pin_input;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
+ GPIO_InitStruct.GPIO_ITCmd = DISABLE;
+ GPIO_Init(&GPIO_InitStruct);
+
+ GPIO_InitStruct.GPIO_Pin = pin_output;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_InitStruct.GPIO_ITCmd = DISABLE;
+ GPIO_Init(&GPIO_InitStruct);
+
+ /* output low */
+ DBG_DIRECT("mp_test_gpio: output low");
+ GPIO_Write(~pin_output);
+ for (uint32_t i = 0; i < 1000; i++);
+ for (uint8_t i = 9; i < 12; i++)
+ {
+ gpio_input_data[i] = GPIO_ReadInputDataBit(GPIO_GetPin(GPIO_PIN_NUM[i][1]));
+ if (0 != gpio_input_data[i]) { GPIO_Test_Result[i]++; }
+ DBG_DIRECT("mp_test_gpio: gpio_input_data_%d = %d", GPIO_PIN_NUM[i][1], gpio_input_data[i]);
+ }
+ memset(gpio_input_data, 0, sizeof(gpio_input_data));
+
+ /* output high */
+ DBG_DIRECT("mp_test_gpio: output high");
+ GPIO_Write(pin_output);
+ for (uint32_t i = 0; i < 1000; i++);
+ for (uint8_t i = 9; i < 12; i++)
+ {
+ gpio_input_data[i] = GPIO_ReadInputDataBit(GPIO_GetPin(GPIO_PIN_NUM[i][1]));
+ if (1 != gpio_input_data[i]) { GPIO_Test_Result[i]++; }
+ DBG_DIRECT("mp_test_gpio: gpio_input_data_%d = %d", GPIO_PIN_NUM[i][1], gpio_input_data[i]);
+ }
+ memset(gpio_input_data, 0, sizeof(gpio_input_data));
+
+ /* output low */
+ DBG_DIRECT("mp_test_gpio: output low");
+ GPIO_Write(~pin_output);
+ for (uint32_t i = 0; i < 1000; i++);
+ for (uint8_t i = 9; i < 12; i++)
+ {
+ gpio_input_data[i] = GPIO_ReadInputDataBit(GPIO_GetPin(GPIO_PIN_NUM[i][1]));
+ if (0 != gpio_input_data[i]) { GPIO_Test_Result[i]++; }
+ DBG_DIRECT("mp_test_gpio: gpio_input_data_%d = %d", GPIO_PIN_NUM[i][1], gpio_input_data[i]);
+ }
+ memset(gpio_input_data, 0, sizeof(gpio_input_data));
+
+ APP_PRINT_INFO1("GPIO_Test_Result %b", TRACE_BINARY(12, GPIO_Test_Result));
+ return GPIO_Test_Result;//right 0; error ~0
+}
+
diff --git a/src/sample/io_sample/GPIO/Output_led/xiaomi_gpio_test.h b/src/sample/io_sample/GPIO/Output_led/xiaomi_gpio_test.h
new file mode 100644
index 0000000..b675485
--- /dev/null
+++ b/src/sample/io_sample/GPIO/Output_led/xiaomi_gpio_test.h
@@ -0,0 +1,38 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file gpio_mp_test.h
+* @brief
+* @details
+* @author yuan
+* @date 2019-04-18
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __GPIO_MP_TEST_H
+#define __GPIO_MP_TEST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_gpio.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "trace.h"
+
+
+/* Globals ------------------------------------------------------------------*/
+extern uint8_t GPIO_Test_Result[12];
+
+uint8_t *mp_test_gpio_forward(void);
+uint8_t *mp_test_gpio_backward(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/sample/io_sample/I2C/GDMA_Master_Rx_Slave_Tx/main.c b/src/sample/io_sample/I2C/GDMA_Master_Rx_Slave_Tx/main.c
new file mode 100644
index 0000000..7be4cdf
--- /dev/null
+++ b/src/sample/io_sample/I2C/GDMA_Master_Rx_Slave_Tx/main.c
@@ -0,0 +1,418 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief IIC demo GDMA master tx slave rx.
+* @details
+* @author echo
+* @date 2021-05-27
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include <string.h>
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_gdma.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_i2c.h"
+#include "trace.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/* I2C pin define*/
+
+#define I2C_MASTER_SCL_PIN I2C0_SCL_PIN
+#define I2C_MASTER_SDA_PIN I2C0_SDA_PIN
+
+#define I2C_SLAVER_SCL_PIN I2C1_SCL_PIN
+#define I2C_SLAVE_SDA_PIN I2C1_SDA_PIN
+
+#define I2C0_SCL_PIN P4_0
+#define I2C0_SDA_PIN P4_1
+
+#define I2C1_SCL_PIN P4_2
+#define I2C1_SDA_PIN P4_3
+
+#define I2C0_GDMA_CHANNEL_NUM 0
+#define I2C0_GDMA_Channel GDMA_Channel0
+#define I2C0_GDMA_Channel_IRQn GDMA0_Channel0_IRQn
+#define I2C0_GDMA_Channel_Handler GDMA0_Channel0_Handler
+#define I2C1_GDMA_CHANNEL_NUM 1
+#define I2C1_GDMA_Channel GDMA_Channel1
+#define I2C1_GDMA_Channel_IRQn GDMA0_Channel1_IRQn
+#define I2C1_GDMA_Channel_Handler GDMA0_Channel1_Handler
+
+#define I2C0_READ_CMD_GDMA_CHANNEL_NUM 2
+#define I2C0_READ_CMD_GDMA_Channel GDMA_Channel2
+#define I2C0_READ_CMD_GDMA_Channel_IRQn GDMA0_Channel2_IRQn
+#define I2C0_READ_CMD_GDMA_Channel_Handler GDMA0_Channel2_Handler
+
+#define GDMA_TRANSFER_SIZE 200
+
+
+/* Globals ------------------------------------------------------------------*/
+uint16_t GDMA_I2C_Send_Buf[GDMA_TRANSFER_SIZE];
+uint8_t GDMA_I2C_Recv_Buf[GDMA_TRANSFER_SIZE];
+uint32_t GDMA_I2C_Tx_Read_Buf[GDMA_TRANSFER_SIZE];
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_i2c_master_init(void)
+{
+
+ Pad_Config(I2C_MASTER_SCL_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(I2C_MASTER_SDA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(I2C_MASTER_SCL_PIN, I2C0_CLK);
+ Pinmux_Config(I2C_MASTER_SDA_PIN, I2C0_DAT);
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_i2c_slave_init(void)
+{
+ Pad_Config(I2C_SLAVER_SCL_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(I2C_SLAVE_SDA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(I2C_SLAVER_SCL_PIN, I2C1_CLK);
+ Pinmux_Config(I2C_SLAVE_SDA_PIN, I2C1_DAT);
+}
+
+/**
+ * @brief Initialize I2C Master peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_i2c_master_init(void)
+{
+ /* Initialize I2C peripheral */
+ RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, ENABLE);
+
+ I2C_InitTypeDef I2C_InitStruct;
+ I2C_StructInit(&I2C_InitStruct);
+
+ I2C_InitStruct.I2C_ClockSpeed = 100000;
+ I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Master;
+ I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT;
+ I2C_InitStruct.I2C_SlaveAddress = 0x50;
+ I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
+ I2C_InitStruct.I2C_RxDmaEn = ENABLE;
+ I2C_InitStruct.I2C_TxDmaEn = ENABLE;
+ I2C_InitStruct.I2C_RxWaterlevel = 3;
+ I2C_InitStruct.I2C_TxWaterlevel = 22;
+ I2C_Init(I2C0, &I2C_InitStruct);
+
+ I2C_Cmd(I2C0, ENABLE);
+}
+
+/**
+ * @brief Initialize I2C Slave peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_i2c_slave_init(void)
+{
+ /* Initialize I2C peripheral */
+ RCC_PeriphClockCmd(APBPeriph_I2C1, APBPeriph_I2C1_CLOCK, ENABLE);
+
+ I2C_InitTypeDef I2C_InitStruct;
+ I2C_StructInit(&I2C_InitStruct);
+
+ I2C_InitStruct.I2C_ClockSpeed = 100000;
+ I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Slave;
+ I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT;
+ I2C_InitStruct.I2C_SlaveAddress = 0x50;
+ I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
+ I2C_InitStruct.I2C_TxDmaEn = ENABLE;
+ I2C_InitStruct.I2C_TxWaterlevel = 16;
+ I2C_Init(I2C1, &I2C_InitStruct);
+
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = I2C1_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&NVIC_InitStruct);
+
+ /* Configure interrupt type, please reference to i2c document about all interrupt type description */
+ I2C_INTConfig(I2C1, I2C_INT_RD_REQ, ENABLE);
+
+ I2C_Cmd(I2C1, ENABLE);
+}
+
+/**
+ * @brief Initialize gdma peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void gdma_i2c_slave_tx_init(void)
+{
+ /* Initialize data buffer */
+ for (uint32_t i = 0; i < GDMA_TRANSFER_SIZE; i++)
+ {
+ GDMA_I2C_Send_Buf[i] = i;
+ }
+
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+
+ /* GDMA init */
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+
+ GDMA_InitStruct.GDMA_ChannelNum = I2C1_GDMA_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral;
+ GDMA_InitStruct.GDMA_BufferSize = GDMA_TRANSFER_SIZE;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_HalfWord;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_HalfWord;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_I2C_Send_Buf;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(I2C1->IC_DATA_CMD));
+ GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_I2C1_TX;
+
+ GDMA_Init(I2C1_GDMA_Channel, &GDMA_InitStruct);
+
+ /* GDMA irq config */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = I2C1_GDMA_Channel_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&NVIC_InitStruct);
+
+ GDMA_INTConfig(I2C1_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+}
+
+/**
+ * @brief Initialize gdma peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void gdma_i2c_master_rx_init(void)
+{
+ /* Initialize data buffer */
+ for (uint32_t i = 0; i < GDMA_TRANSFER_SIZE; i++)
+ {
+ GDMA_I2C_Recv_Buf[i] = 0;
+ }
+
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+
+ /* GDMA init */
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+
+ GDMA_InitStruct.GDMA_ChannelNum = I2C0_GDMA_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToMemory;
+ GDMA_InitStruct.GDMA_BufferSize = GDMA_TRANSFER_SIZE;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Inc;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)(&(I2C0->IC_DATA_CMD));
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(GDMA_I2C_Recv_Buf);
+ GDMA_InitStruct.GDMA_SourceHandshake = GDMA_Handshake_I2C0_RX;
+
+ GDMA_Init(I2C0_GDMA_Channel, &GDMA_InitStruct);
+
+ /* GDMA irq config */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = I2C0_GDMA_Channel_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&NVIC_InitStruct);
+
+ GDMA_INTConfig(I2C0_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+
+ /* Start to receive data */
+ GDMA_Cmd(I2C0_GDMA_CHANNEL_NUM, ENABLE);
+}
+
+/**
+ * @brief Initialize gdma peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void i2c_master_send_read_cmd(void)
+{
+ /* Initialize data buffer */
+ for (uint32_t i = 0; i < (GDMA_TRANSFER_SIZE - 1); i++)
+ {
+ GDMA_I2C_Tx_Read_Buf[i] = (0x01 << 8);
+ }
+ GDMA_I2C_Tx_Read_Buf[GDMA_TRANSFER_SIZE - 1] = (0x03 << 8);
+
+ /* GDMA init */
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+
+ GDMA_InitStruct.GDMA_ChannelNum = I2C0_READ_CMD_GDMA_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral;
+ GDMA_InitStruct.GDMA_BufferSize = GDMA_TRANSFER_SIZE;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_I2C_Tx_Read_Buf;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(I2C0->IC_DATA_CMD));
+ GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_I2C0_TX;
+
+ GDMA_Init(I2C0_READ_CMD_GDMA_Channel, &GDMA_InitStruct);
+
+ /* GDMA irq config */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = I2C0_READ_CMD_GDMA_Channel_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&NVIC_InitStruct);
+
+ GDMA_INTConfig(I2C0_READ_CMD_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+
+ GDMA_Cmd(I2C0_READ_CMD_GDMA_CHANNEL_NUM, ENABLE);
+}
+
+/**
+ * @brief Demo code of i2c.
+ * @param No parameter.
+ * @return void
+*/
+void i2c_demo(void)
+{
+ /* Configure pad and pinmux firstly! */
+ board_i2c_master_init();
+ board_i2c_slave_init();
+
+ /* Initialize i2c peripheral */
+ driver_i2c_master_init();
+ driver_i2c_slave_init();
+
+ /* Initialize gdma peripheral */
+ gdma_i2c_slave_tx_init();
+ gdma_i2c_master_rx_init();
+
+ i2c_master_send_read_cmd();
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+ i2c_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ }
+}
+
+/**
+ * @brief I2C1 interrupt handler function.
+ * @param No parameter.
+ * @return void
+*/
+void I2C1_Handler(void)
+{
+ /* Notes: DBG_DIRECT is only used for debug demo, do not use in app!
+ In app project, the APP_PRINT_INFO can be used.
+ */
+// DBG_DIRECT("I2C1_Handler!");
+ if (I2C_GetINTStatus(I2C1, I2C_INT_RD_REQ) == SET)
+ {
+// DBG_DIRECT("I2C1_Handler I2C_INT_RD_REQ!");
+ GDMA_Cmd(I2C1_GDMA_CHANNEL_NUM, ENABLE);
+ //Add user code here
+ /* Clear interrupt */
+ I2C_ClearINTPendingBit(I2C1, I2C_INT_RD_REQ);
+ I2C_INTConfig(I2C1, I2C_INT_RD_REQ, DISABLE);
+ }
+}
+
+/**
+ * @brief GDMA channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+*/
+void I2C1_GDMA_Channel_Handler(void)
+{
+ GDMA_INTConfig(I2C1_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, DISABLE);
+ /* Notes: DBG_DIRECT is only used for debug demo, do not use in app!
+ In app project, the APP_PRINT_INFO can be used.
+ */
+ DBG_DIRECT("In I2C1_GDMA_Channel_Handler! I2C slave send data by GDMA successfully");
+ //Add user code here
+ GDMA_ClearINTPendingBit(I2C1_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+}
+
+/**
+ * @brief GDMA channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+*/
+void I2C0_GDMA_Channel_Handler(void)
+{
+ GDMA_INTConfig(I2C0_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, DISABLE);
+ /* Notes: DBG_DIRECT is only used for debug demo, do not use in app!
+ In app project, the APP_PRINT_INFO can be used.
+ */
+ DBG_DIRECT("I2C0_GDMA_Channel_Handler!I2C master read data by GDMA successfully");
+ //Add user code here
+ GDMA_ClearINTPendingBit(I2C0_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+
+ for (uint32_t i = 0; i < GDMA_TRANSFER_SIZE; i++)
+ {
+ if (GDMA_I2C_Send_Buf[i] != GDMA_I2C_Recv_Buf[i])
+ {
+ DBG_DIRECT(" Data transmission error! GDMA_Send_Buf = %d, GDMA_Recv_Buf = %d",
+ GDMA_I2C_Send_Buf[i], GDMA_I2C_Recv_Buf[i]);
+ }
+ GDMA_I2C_Recv_Buf[i] = 0;
+ }
+
+}
+
+/**
+ * @brief GDMA channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+*/
+void I2C0_READ_CMD_GDMA_Channel_Handler(void)
+{
+ GDMA_INTConfig(I2C0_READ_CMD_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, DISABLE);
+ /* Notes: DBG_DIRECT is only used for debug demo, do not use in app!
+ In app project, the APP_PRINT_INFO can be used.
+ */
+ DBG_DIRECT("I2C0_READ_CMD_GDMA2_Channel_Handler!");
+ //Add user code here
+ GDMA_ClearINTPendingBit(I2C0_READ_CMD_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+}
+
+
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/I2C/GDMA_Master_Tx_Slave_Rx/main.c b/src/sample/io_sample/I2C/GDMA_Master_Tx_Slave_Rx/main.c
new file mode 100644
index 0000000..ff0de79
--- /dev/null
+++ b/src/sample/io_sample/I2C/GDMA_Master_Tx_Slave_Rx/main.c
@@ -0,0 +1,314 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief IIC demo GDMA master tx slave rx.
+* @details
+* @author echo
+* @date 2021-05-27
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include <string.h>
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_gdma.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_i2c.h"
+#include "trace.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/* I2C pin define*/
+
+#define I2C_MASTER_SCL_PIN I2C0_SCL_PIN
+#define I2C_MASTER_SDA_PIN I2C0_SDA_PIN
+
+#define I2C_SLAVER_SCL_PIN I2C1_SCL_PIN
+#define I2C_SLAVE_SDA_PIN I2C1_SDA_PIN
+
+#define I2C0_SCL_PIN P4_0
+#define I2C0_SDA_PIN P4_1
+
+#define I2C1_SCL_PIN P4_2
+#define I2C1_SDA_PIN P4_3
+
+#define I2C0_GDMA_CHANNEL_NUM 0
+#define I2C0_GDMA_Channel GDMA_Channel0
+#define I2C0_GDMA_Channel_IRQn GDMA0_Channel0_IRQn
+#define I2C0_GDMA_Channel_Handler GDMA0_Channel0_Handler
+#define I2C1_GDMA_CHANNEL_NUM 1
+#define I2C1_GDMA_Channel GDMA_Channel1
+#define I2C1_GDMA_Channel_IRQn GDMA0_Channel1_IRQn
+#define I2C1_GDMA_Channel_Handler GDMA0_Channel1_Handler
+
+#define GDMA_TRANSFER_SIZE 200
+
+
+/* Globals ------------------------------------------------------------------*/
+uint16_t GDMA_I2C_Send_Buf[GDMA_TRANSFER_SIZE];
+uint8_t GDMA_I2C_Recv_Buf[GDMA_TRANSFER_SIZE];
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_i2c_master_init(void)
+{
+
+ Pad_Config(I2C_MASTER_SCL_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(I2C_MASTER_SDA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(I2C_MASTER_SCL_PIN, I2C0_CLK);
+ Pinmux_Config(I2C_MASTER_SDA_PIN, I2C0_DAT);
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_i2c_slave_init(void)
+{
+ Pad_Config(I2C_SLAVER_SCL_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(I2C_SLAVE_SDA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(I2C_SLAVER_SCL_PIN, I2C1_CLK);
+ Pinmux_Config(I2C_SLAVE_SDA_PIN, I2C1_DAT);
+}
+
+/**
+ * @brief Initialize I2C Master peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_i2c_master_init(void)
+{
+ /* Initialize I2C peripheral */
+ RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, ENABLE);
+
+ I2C_InitTypeDef I2C_InitStruct;
+ I2C_StructInit(&I2C_InitStruct);
+
+ I2C_InitStruct.I2C_ClockSpeed = 100000;
+ I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Master;
+ I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT;
+ I2C_InitStruct.I2C_SlaveAddress = 0x50;
+ I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
+ I2C_InitStruct.I2C_RxDmaEn = ENABLE;
+ I2C_InitStruct.I2C_TxDmaEn = ENABLE;
+ I2C_InitStruct.I2C_RxWaterlevel = 3;
+ I2C_InitStruct.I2C_TxWaterlevel = 22;
+ I2C_Init(I2C0, &I2C_InitStruct);
+
+ I2C_Cmd(I2C0, ENABLE);
+
+}
+
+/**
+ * @brief Initialize I2C Slave peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_i2c_slave_init(void)
+{
+ /* Initialize I2C peripheral */
+ RCC_PeriphClockCmd(APBPeriph_I2C1, APBPeriph_I2C1_CLOCK, ENABLE);
+
+ I2C_InitTypeDef I2C_InitStruct;
+ I2C_StructInit(&I2C_InitStruct);
+ I2C_InitStruct.I2C_ClockSpeed = 100000;
+ I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Slave;
+ I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT;
+ I2C_InitStruct.I2C_SlaveAddress = 0x50;
+ I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
+ I2C_InitStruct.I2C_RxDmaEn = ENABLE;
+ I2C_InitStruct.I2C_RxWaterlevel = 3;
+ I2C_Init(I2C1, &I2C_InitStruct);
+
+ I2C_Cmd(I2C1, ENABLE);
+}
+
+/**
+ * @brief Initialize gdma peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void gdma_i2c_slave_rx_init(void)
+{
+ /* Initialize data buffer */
+ for (uint32_t i = 0; i < GDMA_TRANSFER_SIZE; i++)
+ {
+ GDMA_I2C_Recv_Buf[i] = 0;
+ }
+
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+ /* GDMA init */
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+
+ GDMA_InitStruct.GDMA_ChannelNum = I2C1_GDMA_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToMemory;
+ GDMA_InitStruct.GDMA_BufferSize = GDMA_TRANSFER_SIZE;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Inc;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)(&(I2C1->IC_DATA_CMD));
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(GDMA_I2C_Recv_Buf);
+ GDMA_InitStruct.GDMA_SourceHandshake = GDMA_Handshake_I2C1_RX;
+
+ GDMA_Init(I2C1_GDMA_Channel, &GDMA_InitStruct);
+
+ /* GDMA irq config */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = I2C1_GDMA_Channel_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&NVIC_InitStruct);
+
+ GDMA_INTConfig(I2C1_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+
+ /* Start to receive data */
+ GDMA_Cmd(I2C1_GDMA_CHANNEL_NUM, ENABLE);
+}
+
+/**
+ * @brief Initialize gdma peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void gdma_i2c_master_tx_init(void)
+{
+
+ /* Initialize data buffer */
+ for (uint32_t i = 0; i < (GDMA_TRANSFER_SIZE); i++)
+ {
+ GDMA_I2C_Send_Buf[i] = i | (0x0000 << 8);
+ }
+ GDMA_I2C_Send_Buf[GDMA_TRANSFER_SIZE - 1] = (GDMA_I2C_Send_Buf[GDMA_TRANSFER_SIZE - 1] |
+ (0x00001 << 9));
+
+ /* GDMA init */
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+
+ GDMA_InitStruct.GDMA_ChannelNum = I2C0_GDMA_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral;
+ GDMA_InitStruct.GDMA_BufferSize = GDMA_TRANSFER_SIZE;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_HalfWord;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_HalfWord;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_I2C_Send_Buf;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(I2C0->IC_DATA_CMD));
+ GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_I2C0_TX;
+
+ GDMA_Init(I2C0_GDMA_Channel, &GDMA_InitStruct);
+
+ /* GDMA irq config */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = GDMA0_Channel0_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&NVIC_InitStruct);
+
+ GDMA_INTConfig(I2C0_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+
+ GDMA_Cmd(I2C0_GDMA_CHANNEL_NUM, ENABLE);
+}
+
+/**
+ * @brief Demo code of i2c.
+ * @param No parameter.
+ * @return void
+*/
+void i2c_demo(void)
+{
+ /* Configure pad and pinmux firstly! */
+ board_i2c_master_init();
+ board_i2c_slave_init();
+
+ /* Initialize i2c peripheral */
+ driver_i2c_master_init();
+ driver_i2c_slave_init();
+
+ /* Initialize gdma peripheral */
+ gdma_i2c_master_tx_init();
+ gdma_i2c_slave_rx_init();
+}
+
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+ i2c_demo();
+
+
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ }
+}
+
+/**
+ * @brief GDMA channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+*/
+void I2C0_GDMA_Channel_Handler(void)
+{
+ GDMA_INTConfig(I2C0_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, DISABLE);
+ DBG_DIRECT("I2C0_GDMA_Channel_Handler! I2C master send data by GDMA successfully");
+ //Add user code here
+ GDMA_ClearINTPendingBit(I2C0_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+
+}
+
+/**
+ * @brief GDMA channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+*/
+void I2C1_GDMA_Channel_Handler(void)
+{
+ GDMA_INTConfig(I2C1_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, DISABLE);
+ DBG_DIRECT("In I2C1_GDMA_Channel_Handler! I2C slave receive data by GDMA successfully");
+ //Add user code here
+ GDMA_ClearINTPendingBit(I2C1_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+ for (uint32_t i = 0; i < GDMA_TRANSFER_SIZE; i++)
+ {
+ if ((uint8_t)GDMA_I2C_Send_Buf[i] != GDMA_I2C_Recv_Buf[i])
+ {
+ DBG_DIRECT(" Data transmission error! GDMA_Send_Buf = %d, GDMA_Recv_Buf = %d",
+ GDMA_I2C_Send_Buf[i], GDMA_I2C_Recv_Buf[i]);
+ }
+ GDMA_I2C_Recv_Buf[i] = 0;
+ }
+}
+
+///******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/I2C/I2C_EEPROM/main.c b/src/sample/io_sample/I2C/I2C_EEPROM/main.c
new file mode 100644
index 0000000..87066e9
--- /dev/null
+++ b/src/sample/io_sample/I2C/I2C_EEPROM/main.c
@@ -0,0 +1,165 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief IIC EEPROM demo .
+ This file provides demo code of i2c master.
+ AT24C02 is slave.
+* @details
+* @author echo
+* @date 2021-05-27
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include <string.h>
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_i2c.h"
+#include "trace.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define I2C0_SCL_PIN P4_0
+#define I2C0_SDA_PIN P4_1
+
+/* Globals ------------------------------------------------------------------*/
+#define TransferLength 10
+uint8_t I2C_Rev_Data[255];
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_i2c_master_init(void)
+{
+ Pad_Config(I2C0_SCL_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(I2C0_SDA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(I2C0_SCL_PIN, I2C0_CLK);
+ Pinmux_Config(I2C0_SDA_PIN, I2C0_DAT);
+}
+
+/**
+ * @brief Initialize I2C Master peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_i2c_master_init(void)
+{
+ /* Initialize I2C peripheral */
+ RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, ENABLE);
+
+ I2C_InitTypeDef I2C_InitStruct;
+ I2C_StructInit(&I2C_InitStruct);
+
+ I2C_InitStruct.I2C_ClockSpeed = 100000;
+ I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Master;
+ I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT;
+ /* The address of AT24C02 is 0X50 */
+ I2C_InitStruct.I2C_SlaveAddress = 0x50;
+ I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
+
+ I2C_Init(I2C0, &I2C_InitStruct);
+ I2C_Cmd(I2C0, ENABLE);
+}
+
+
+void i2c_mem_write(I2C_TypeDef *I2Cx, uint8_t mem_addr, uint16_t mem_addr_size,
+ const uint8_t *data, uint16_t data_size)
+{
+ uint16_t write_data_len = mem_addr_size + data_size;
+ uint8_t pWriteBuf[write_data_len];
+
+ if (mem_addr_size == 1)
+ {
+ pWriteBuf[0] = mem_addr;
+ uint32_t i = 1;
+ while (data_size--)
+ {
+ pWriteBuf[i] = *data++;
+ i++;
+ }
+ }
+ else if (mem_addr_size == 2)
+ {
+ pWriteBuf[0] = mem_addr << 8;
+ pWriteBuf[1] = (uint8_t)mem_addr & 0xFF;
+ uint32_t i = 2;
+ while (data_size--)
+ {
+ pWriteBuf[i] = *data++;
+ i++;
+ }
+ }
+ I2C_MasterWrite(I2Cx, pWriteBuf, write_data_len);
+}
+
+
+/**
+ * @brief Demo code of i2c.
+ * @param No parameter.
+ * @return void
+*/
+void i2c_demo(void)
+{
+ /* Configure pad and pinmux firstly! */
+ board_i2c_master_init();
+
+ /* Initialize i2c peripheral */
+ driver_i2c_master_init();
+
+ /* I2C master write */
+ uint8_t write_data[TransferLength] ;
+
+ for (uint8_t i = 0; i < TransferLength; i++)
+ {
+ write_data[i] = i;
+ }
+
+ uint8_t mem_address = 0x20;
+
+ i2c_mem_write(I2C0, mem_address, 1, write_data, 10);
+
+ for (uint32_t i = 0; i < 100000; i++);
+
+ uint8_t read_data[TransferLength] = {0};
+
+ I2C_RepeatRead(I2C0, (uint8_t *)&mem_address, 1, read_data, 10);
+
+// /* Only for Debug */
+// for (uint32_t i = 0; i < 50 ; i++)
+// {
+// DBG_DIRECT("Master Read data = %d\n", read_data[i]);
+// }
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+ i2c_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/I2C/STK8321/ble_peripheral/ancs.c b/src/sample/io_sample/I2C/STK8321/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/I2C/STK8321/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/I2C/STK8321/ble_peripheral/ancs.h b/src/sample/io_sample/I2C/STK8321/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/I2C/STK8321/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/I2C/STK8321/ble_peripheral/app.c b/src/sample/io_sample/I2C/STK8321/ble_peripheral/app.c
new file mode 100644
index 0000000..0bdd1cd
--- /dev/null
+++ b/src/sample/io_sample/I2C/STK8321/ble_peripheral/app.c
@@ -0,0 +1,609 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_i2c.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_I2C:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: i2c msg.");
+ io_handle_i2c_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ i2c_demo();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/I2C/STK8321/ble_peripheral/app.h b/src/sample/io_sample/I2C/STK8321/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/I2C/STK8321/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/I2C/STK8321/ble_peripheral/app_flags.h b/src/sample/io_sample/I2C/STK8321/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/I2C/STK8321/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/I2C/STK8321/ble_peripheral/app_task.c b/src/sample/io_sample/I2C/STK8321/ble_peripheral/app_task.c
new file mode 100644
index 0000000..635c4c3
--- /dev/null
+++ b/src/sample/io_sample/I2C/STK8321/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/I2C/STK8321/ble_peripheral/app_task.h b/src/sample/io_sample/I2C/STK8321/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/I2C/STK8321/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/I2C/STK8321/ble_peripheral/main.c b/src/sample/io_sample/I2C/STK8321/ble_peripheral/main.c
new file mode 100644
index 0000000..9226cbe
--- /dev/null
+++ b/src/sample/io_sample/I2C/STK8321/ble_peripheral/main.c
@@ -0,0 +1,245 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+
+#include "io_i2c.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_i2c_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_i2c_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/I2C/STK8321/io_i2c.c b/src/sample/io_sample/I2C/STK8321/io_i2c.c
new file mode 100644
index 0000000..85c8259
--- /dev/null
+++ b/src/sample/io_sample/I2C/STK8321/io_i2c.c
@@ -0,0 +1,151 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_i2c.c
+* @brief This file provides demo code of i2c master.
+ STK8321 is slave.
+ Read the chip id of STK8321 and Gsensor outdata.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_i2c.h"
+
+#include "stk8321.h"
+
+#include "app_task.h"
+
+/* Globals ------------------------------------------------------------------*/
+
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_i2c_init(void)
+{
+ Pad_Config(I2C0_SCL_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(I2C0_SDA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+
+ Pinmux_Config(I2C0_SCL_PIN, I2C0_CLK);
+ Pinmux_Config(I2C0_SDA_PIN, I2C0_DAT);
+}
+
+/**
+ * @brief Initialize i2c peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_i2c_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, ENABLE);
+
+ I2C_InitTypeDef I2C_InitStruct;
+ I2C_StructInit(&I2C_InitStruct);
+
+ I2C_InitStruct.I2C_ClockSpeed = 100000;
+ I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Master;
+ I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT;
+ I2C_InitStruct.I2C_SlaveAddress = STK8321_ADDRESS;
+ I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
+
+ I2C_Init(I2C0, &I2C_InitStruct);
+ I2C_Cmd(I2C0, ENABLE);
+
+}
+
+/**
+ * @brief Config i2c nvic.
+ * @param No parameter.
+ * @return void
+ */
+void nvic_i2c_config(void)
+{
+ /* Detect stop signal */
+ I2C_ClearINTPendingBit(I2C0, I2C_INT_STOP_DET);
+ I2C_INTConfig(I2C0, I2C_INT_STOP_DET, ENABLE);
+
+ /* Config I2C interrupt */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = I2C0_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/**
+ * @brief Demo code of operation about i2c.
+ * @param No parameter.
+ * @return void
+*/
+void i2c_demo(void)
+{
+ if (0x23 == stk8321_id_get())
+ {
+ APP_PRINT_INFO0("[io_i2c] i2c_demo: Get stk8321 chip id OK. ");
+ nvic_i2c_config();
+ stk8321_outdata_get();
+ }
+}
+
+/**
+ * @brief Handle i2c data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_i2c_handle_msg(T_IO_MSG *io_i2c_msg)
+{
+ uint8_t *p_buf = io_i2c_msg->u.buf;
+
+ GSensor_Data.XData = p_buf[0] & 0xFF;
+ GSensor_Data.XData = (GSensor_Data.XData + ((uint16_t)p_buf[1] << 8)) >> 4;
+ GSensor_Data.YData = p_buf[2] & 0xFF;
+ GSensor_Data.YData = (GSensor_Data.YData + ((uint16_t)p_buf[3] << 8)) >> 4;
+ GSensor_Data.ZData = p_buf[4] & 0xFF;
+ GSensor_Data.ZData = (GSensor_Data.ZData + ((uint16_t)p_buf[5] << 8)) >> 4;
+ APP_PRINT_INFO3("[io_i2c]io_i2c_handle_msg: GSensor x_axic_data = %d, y_axic_data = %d, z_axic_data = %d,",
+ GSensor_Data.XData, GSensor_Data.YData, GSensor_Data.ZData);
+}
+
+/**
+ * @brief Handle i2c data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_i2c_msg(T_IO_MSG *io_i2c_msg)
+{
+ io_i2c_handle_msg(io_i2c_msg);
+}
+
+/**
+ * @brief I2C0 interrupt handle function.
+ * @param None.
+ * @return None.
+*/
+void I2C0_Handler(void)
+{
+ if (I2C_GetINTStatus(I2C0, I2C_INT_STOP_DET) == SET)
+ {
+ T_IO_MSG int_i2c_msg;
+
+ int_i2c_msg.type = IO_MSG_TYPE_I2C;
+ int_i2c_msg.subtype = 0;
+ int_i2c_msg.u.buf = (void *)(GSensor_Data.OutData);
+ if (false == app_send_msg_to_apptask(&int_i2c_msg))
+ {
+ APP_PRINT_ERROR0("[io_i2c] I2C0_Handler: Send int_i2c_msg failed!");
+ I2C_ClearINTPendingBit(I2C0, I2C_INT_STOP_DET);
+ //Add user code here!
+ return;
+ }
+ I2C_ClearINTPendingBit(I2C0, I2C_INT_STOP_DET);
+// stk8321_outdata_get();
+ }
+}
+
diff --git a/src/sample/io_sample/I2C/STK8321/io_i2c.h b/src/sample/io_sample/I2C/STK8321/io_i2c.h
new file mode 100644
index 0000000..6c85197
--- /dev/null
+++ b/src/sample/io_sample/I2C/STK8321/io_i2c.h
@@ -0,0 +1,43 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_i2c.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_I2C_H
+#define __IO_I2C_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_i2c.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+
+#include "board.h"
+
+#include "app_msg.h"
+
+
+void board_i2c_init(void);
+void driver_i2c_init(void);
+void i2c_demo(void);
+void io_handle_i2c_msg(T_IO_MSG *io_i2c_msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/I2C/STK8321/stk8321.c b/src/sample/io_sample/I2C/STK8321/stk8321.c
new file mode 100644
index 0000000..84e5963
--- /dev/null
+++ b/src/sample/io_sample/I2C/STK8321/stk8321.c
@@ -0,0 +1,33 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_adc.c
+* @brief This file provides demo code of adc continuous mode.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "stk8321.h"
+
+
+/* Globals ------------------------------------------------------------------*/
+GSensor_Data_TypeDef GSensor_Data;
+
+uint8_t stk8321_id_get(void)
+{
+ uint8_t stk8321_chip_id = 0;
+ uint8_t reg_addr = STK8321_REG_CHIP_ID;
+ I2C_RepeatRead(I2C0, &reg_addr, 1, &stk8321_chip_id, 1);
+ return stk8321_chip_id;
+}
+
+void stk8321_outdata_get(void)
+{
+ uint8_t reg_addr = STK8321_REG_X_OUT_LOW;
+ I2C_RepeatRead(I2C0, &reg_addr, 1, GSensor_Data.OutData, 6);
+}
diff --git a/src/sample/io_sample/I2C/STK8321/stk8321.h b/src/sample/io_sample/I2C/STK8321/stk8321.h
new file mode 100644
index 0000000..b609442
--- /dev/null
+++ b/src/sample/io_sample/I2C/STK8321/stk8321.h
@@ -0,0 +1,58 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_adc.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __STK8321_H
+#define __STK8321_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_i2c.h"
+
+
+
+/* Defines ------------------------------------------------------------------*/
+#define STK8321_ADDRESS 0x0F
+#define STK8321_REG_CHIP_ID 0x00
+#define STK8321_REG_X_OUT_LOW 0x02
+#define STK8321_REG_X_OUT_HIGH 0x03
+#define STK8321_REG_Y_OUT_LOW 0x04
+#define STK8321_REG_Y_OUT_HIGH 0x05
+#define STK8321_REG_Z_OUT_LOW 0x06
+#define STK8321_REG_Z_OUT_HIGH 0x07
+
+typedef struct
+{
+// uint8_t XOut[2];
+// uint8_t YOut[2];
+// uint8_t ZOut[2];
+ uint8_t RegAddr;
+ uint8_t OutData[6];
+ uint16_t XData;
+ uint16_t YData;
+ uint16_t ZData;
+} GSensor_Data_TypeDef;
+
+extern GSensor_Data_TypeDef GSensor_Data;
+
+uint8_t stk8321_id_get(void);
+void stk8321_outdata_get(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/I2C/Self_Test/main.c b/src/sample/io_sample/I2C/Self_Test/main.c
new file mode 100644
index 0000000..7d46d50
--- /dev/null
+++ b/src/sample/io_sample/I2C/Self_Test/main.c
@@ -0,0 +1,351 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief IIC demo self test.
+* @details
+* @author echo
+* @date 2021-05-27
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include <string.h>
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_i2c.h"
+#include "trace.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/* I2C pin define*/
+#define I2C_MASTER_SCL_PIN I2C0_SCL_PIN
+#define I2C_MASTER_SDA_PIN I2C0_SDA_PIN
+
+#define I2C_SLAVER_SCL_PIN I2C1_SCL_PIN
+#define I2C_SLAVE_SDA_PIN I2C1_SDA_PIN
+
+#define I2C0_SCL_PIN P4_0
+#define I2C0_SDA_PIN P4_1
+
+#define I2C1_SCL_PIN P4_2
+#define I2C1_SDA_PIN P4_3
+
+#define I2C_MASTER_SEND_SLAVE_RECEIVE 1
+#define I2C_MASTER_RECEIVE_SLAVE_SEND 0
+#define I2C_MASTER_REPEAT_READ 0
+
+/* Globals ------------------------------------------------------------------*/
+#define I2C_TX_FIFO_SIZE 24
+#define TransferLength 24
+
+uint8_t I2C_Rev_Data[255];
+uint8_t I2C_Rev_Index;
+uint8_t I2C_Send_Index = 0;
+volatile uint8_t I2C_Rev_Data_Length;
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_i2c_master_init(void)
+{
+ Pad_Config(I2C_MASTER_SCL_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(I2C_MASTER_SDA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(I2C_MASTER_SCL_PIN, I2C0_CLK);
+ Pinmux_Config(I2C_MASTER_SDA_PIN, I2C0_DAT);
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_i2c_slave_init(void)
+{
+ Pad_Config(I2C_SLAVER_SCL_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(I2C_SLAVE_SDA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(I2C_SLAVER_SCL_PIN, I2C1_CLK);
+ Pinmux_Config(I2C_SLAVE_SDA_PIN, I2C1_DAT);
+}
+
+/**
+ * @brief Initialize I2C Master peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_i2c_master_init(void)
+{
+ /* Initialize I2C peripheral */
+ RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, ENABLE);
+
+ I2C_InitTypeDef I2C_InitStruct;
+ I2C_StructInit(&I2C_InitStruct);
+
+ I2C_InitStruct.I2C_ClockSpeed = 100000;
+ I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Master;
+ I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT;
+ I2C_InitStruct.I2C_SlaveAddress = 0x50;
+ I2C_InitStruct.I2C_RxThresholdLevel = 8;
+ I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
+
+ I2C_Init(I2C0, &I2C_InitStruct);
+ I2C_Cmd(I2C0, ENABLE);
+}
+
+/**
+ * @brief Initialize I2C Slave peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_i2c_slave_init(void)
+{
+ /* Initialize I2C peripheral */
+ RCC_PeriphClockCmd(APBPeriph_I2C1, APBPeriph_I2C1_CLOCK, ENABLE);
+
+ I2C_InitTypeDef I2C_InitStruct;
+ I2C_StructInit(&I2C_InitStruct);
+
+ I2C_InitStruct.I2C_ClockSpeed = 100000;
+ I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Slave;
+ I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT;
+ I2C_InitStruct.I2C_SlaveAddress = 0x50;
+ I2C_InitStruct.I2C_RxThresholdLevel = 8;
+ I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
+
+ I2C_Init(I2C1, &I2C_InitStruct);
+ I2C_Cmd(I2C1, ENABLE);
+}
+
+/**
+ * @brief Config i2c nvic.
+ * @param No parameter.
+ * @return void
+ */
+void nvic_i2c_config(void)
+{
+ /* Detect stop signal */
+ I2C_ClearINTPendingBit(I2C0, I2C_INT_STOP_DET);
+ I2C_ClearINTPendingBit(I2C1, I2C_INT_STOP_DET);
+ /* Detect read require signal */
+ I2C_ClearINTPendingBit(I2C1, I2C_INT_RD_REQ);
+ /* Detect rx fifo full signal */
+ I2C_ClearINTPendingBit(I2C1, I2C_INT_RX_FULL);
+ /* Detect rx transmission finished signal */
+ I2C_ClearINTPendingBit(I2C1, I2C_INT_RX_DONE);
+
+#if I2C_MASTER_SEND_SLAVE_RECEIVE
+ I2C_INTConfig(I2C0, I2C_INT_STOP_DET, ENABLE);
+ I2C_INTConfig(I2C1, I2C_INT_RX_FULL, ENABLE);
+ I2C_INTConfig(I2C1, I2C_INT_STOP_DET, ENABLE);
+ I2C_INTConfig(I2C1, I2C_INT_RX_DONE, ENABLE);
+#endif
+
+#if I2C_MASTER_RECEIVE_SLAVE_SEND
+ I2C_INTConfig(I2C1, I2C_INT_RD_REQ, ENABLE);
+#endif
+
+#if I2C_MASTER_REPEAT_READ
+ I2C_INTConfig(I2C0, I2C_INT_STOP_DET, ENABLE);
+ I2C_INTConfig(I2C1, I2C_INT_RX_FULL, ENABLE);
+ I2C_INTConfig(I2C1, I2C_INT_STOP_DET, ENABLE);
+ I2C_INTConfig(I2C1, I2C_INT_RX_DONE, ENABLE);
+ I2C_INTConfig(I2C1, I2C_INT_RD_REQ, ENABLE);
+#endif
+
+ /* Config I2C interrupt */
+ NVIC_InitTypeDef NVIC_InitStruct;
+
+ NVIC_InitStruct.NVIC_IRQChannel = I2C0_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ NVIC_InitStruct.NVIC_IRQChannel = I2C1_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+}
+/**
+ * @brief Demo code of i2c.
+ * @param No parameter.
+ * @return void
+*/
+void i2c_demo(void)
+{
+ /* Configure pad and pinmux firstly! */
+ board_i2c_master_init();
+ board_i2c_slave_init();
+
+ /* Initialize i2c peripheral */
+ driver_i2c_master_init();
+ driver_i2c_slave_init();
+
+ /* Config i2c nvic */
+ nvic_i2c_config();
+
+ /* I2C master write */
+ uint8_t write_data[TransferLength] ;
+
+ for (uint8_t i = 0; i < TransferLength; i++)
+ {
+ write_data[i] = i;
+ }
+
+#if I2C_MASTER_SEND_SLAVE_RECEIVE
+ I2C_MasterWrite(I2C0, write_data, TransferLength);
+#endif
+
+#if I2C_MASTER_RECEIVE_SLAVE_SEND
+ /* I2C master read */
+ uint8_t data[TransferLength] = {0};
+ I2C_MasterRead(I2C0, data, TransferLength);
+
+ for (uint32_t i = 0; i < TransferLength ; i++)
+ {
+ DBG_DIRECT("Master Read data = %d\n", data[i]);
+ }
+#endif
+
+#if I2C_MASTER_REPEAT_READ
+ /* I2C master repeat read */
+ uint8_t tx_data[10] = {01, 02, 03, 04};
+ uint8_t rx_data[TransferLength] = {0};
+ I2C_RepeatRead(I2C0, tx_data, 4, rx_data, TransferLength);
+
+ for (uint32_t i = 0; i < TransferLength ; i++)
+ {
+ DBG_DIRECT("Master Repeat Read data = %d\n", rx_data[i]);
+ }
+#endif
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+ i2c_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ }
+}
+
+void I2C0_Handler(void)
+{
+ if (I2C_GetINTStatus(I2C0, I2C_INT_STOP_DET) == SET)
+ {
+ /* Notes: DBG_DIRECT is only used for debug demo, do not use in app!
+ In app project, the APP_PRINT_INFO can be used.
+ */
+ DBG_DIRECT("I2C0 Stop signal detected");
+ I2C_ClearINTPendingBit(I2C0, I2C_INT_STOP_DET);
+ }
+}
+
+/**
+ * @brief I2C1 interrupt handle function.
+ * @param None.
+ * @return None.
+*/
+void I2C1_Handler(void)
+{
+ uint16_t length;
+
+ uint8_t send_data_buffer[100];
+ for (uint32_t i = 0; i < TransferLength; i++)
+ {
+ send_data_buffer[i] = i + 10;
+ }
+ if (I2C_GetINTStatus(I2C1, I2C_INT_RD_REQ) == SET)
+ {
+ /* Notes: DBG_DIRECT is only used for debug demo, do not use in app!
+ In app project, the APP_PRINT_INFO can be used.
+ */
+ DBG_DIRECT("Enter I2C1 interrupt I2C1_INT_RD_REQ!");
+
+ for (uint32_t i = 0; i < TransferLength; i++)
+ {
+ I2C_SendCmd(I2C1, I2C_WRITE_CMD, send_data_buffer[i], I2C_STOP_DISABLE);
+ }
+
+ I2C_ClearINTPendingBit(I2C1, I2C_INT_RD_REQ);
+
+ }
+
+ if (I2C_GetINTStatus(I2C1, I2C_INT_STOP_DET) == SET)
+ {
+ /* Notes: DBG_DIRECT is only used for debug demo, do not use in app!
+ In app project, the APP_PRINT_INFO can be used.
+ */
+ DBG_DIRECT("I2C1 Stop signal detected");
+
+ /*read I2C receive data*/
+ length = I2C_GetRxFIFOLen(I2C1);
+ for (uint32_t i = 0; i < length; i++)
+ {
+
+ I2C_Rev_Data[I2C_Rev_Index++] = I2C_ReceiveData(I2C1);
+ }
+ I2C_Rev_Data_Length += length;
+ I2C_ClearINTPendingBit(I2C1, I2C_INT_STOP_DET);
+
+ DBG_DIRECT("Slave Recv Date length = %d", I2C_Rev_Data_Length);
+
+ for (uint32_t i = 0; i < I2C_Rev_Data_Length; i++)
+ {
+ DBG_DIRECT("I2C1_Slave_ReceiveData=%d\n", I2C_Rev_Data[i]);
+ }
+
+ }
+ if (I2C_GetINTStatus(I2C1, I2C_INT_RX_DONE) == SET)
+ {
+ /* Notes: DBG_DIRECT is only used for debug demo, do not use in app!
+ In app project, the APP_PRINT_INFO can be used.
+ */
+ DBG_DIRECT("I2C1 RX_DONE detected");
+ I2C_ClearINTPendingBit(I2C1, I2C_INT_RX_DONE);
+
+ }
+ if (I2C_GetINTStatus(I2C1, I2C_INT_RX_FULL) == SET)
+ {
+ /* Notes: DBG_DIRECT is only used for debug demo, do not use in app!
+ In app project, the APP_PRINT_INFO can be used.
+ */
+ DBG_DIRECT("I2C1 Rx Full detected");
+ length = I2C_GetRxFIFOLen(I2C1);
+
+ /*read I2C data*/
+ for (uint32_t i = 0; i < length; i++)
+ {
+ I2C_Rev_Data[I2C_Rev_Index++] = I2C_ReceiveData(I2C1);
+ }
+ I2C_Rev_Data_Length += length;
+
+ I2C_ClearINTPendingBit(I2C1, I2C_INT_RX_FULL);
+ }
+
+}
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/I2S/I2S_Slave_Recv/main.c b/src/sample/io_sample/I2S/I2S_Slave_Recv/main.c
new file mode 100644
index 0000000..aafe4dd
--- /dev/null
+++ b/src/sample/io_sample/I2S/I2S_Slave_Recv/main.c
@@ -0,0 +1,140 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code of i2s send data.
+* @details
+* @author yuan
+* @date 2021-06-29
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_i2s.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "trace.h"
+
+/* Defines -------------------------------------------------------------------*/
+#define I2S_LRCK_PIN P3_2
+#define I2S_BCLK_PIN P3_3
+#define I2S_DATA_RX_PIN P4_0
+
+#define I2S_NUM I2S0
+#define I2S_LRCK_PINMUX LRC_SPORT0
+#define I2S_BCLK_PINMUX BCLK_SPORT0
+#define I2S_DATA_RX_PINMUX ADCDAT_SPORT0
+
+#define APB_I2S APBPeriph_I2S0
+#define APB_I2S_CLOCK APBPeriph_I2S0_CLOCK
+
+#define I2S_CLK_SOURCE_REG_224 *((volatile uint32_t *)0x40000224UL)
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return Void
+ */
+void board_i2s_init(void)
+{
+ Pad_Config(I2S_BCLK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
+ Pad_Config(I2S_LRCK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
+ Pad_Config(I2S_DATA_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_LOW);
+
+ Pinmux_Config(I2S_BCLK_PIN, I2S_BCLK_PINMUX);
+ Pinmux_Config(I2S_LRCK_PIN, I2S_LRCK_PINMUX);
+ Pinmux_Config(I2S_DATA_RX_PIN, I2S_DATA_RX_PINMUX);
+}
+
+/**
+ * @brief Initialize I2S peripheral.
+ * @param No parameter.
+ * @return Void
+ */
+void driver_i2s_init(void)
+{
+ RCC_PeriphClockCmd(APB_I2S, APB_I2S_CLOCK, ENABLE);
+
+ I2S_InitTypeDef I2S_InitStruct;
+ I2S_StructInit(&I2S_InitStruct);
+ I2S_InitStruct.I2S_ClockSource = I2S_CLK_40M;
+ /* BCLK = 40MHz*(ni/mi), LRCK = BCLK/64 */
+ I2S_InitStruct.I2S_BClockMi = 0x271; /* <!LRCK = 16K */
+ I2S_InitStruct.I2S_BClockNi = 0x10; /* <!BCLK = 1024K */
+ I2S_InitStruct.I2S_DeviceMode = I2S_DeviceMode_Slave;
+ I2S_InitStruct.I2S_ChannelType = I2S_Channel_stereo;
+ I2S_InitStruct.I2S_DataWidth = I2S_Width_16Bits;
+ I2S_InitStruct.I2S_DataFormat = I2S_Mode;
+ I2S_InitStruct.I2S_DMACmd = I2S_DMA_DISABLE;
+ I2S_Init(I2S_NUM, &I2S_InitStruct);
+ /* Change the I2S transmission into external codec .*/
+ I2S_CLK_SOURCE_REG_224 |= BIT(3);
+// DBG_DIRECT("I2S_CLK_SOURCE_REG_224 = 0x%X",I2S_CLK_SOURCE_REG_224);
+ I2S_Cmd(I2S_NUM, I2S_MODE_RX, ENABLE);
+ I2S_INTConfig(I2S_NUM, I2S_INT_RX_READY, ENABLE);
+
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = I2S0_RX_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/**
+ * @brief Demo code of I2S communication.
+ * @param No parameter.
+ * @return Void
+*/
+void i2s_demo(void)
+{
+ board_i2s_init();
+ driver_i2s_init();
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ __enable_irq();
+ i2s_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+
+ }
+}
+
+/**
+ * @brief I2S0 interrupt handle function.
+ * @param None.
+ * @return None.
+*/
+void I2S0_RX_Handler(void)
+{
+ /* Notes: DBG_DIRECT is only used in debug demo, do not use in app project.*/
+ DBG_DIRECT("I2S0_RX_Handler");
+ if (I2S_GetINTStatus(I2S_NUM, I2S_INT_RX_READY))
+ {
+ uint8_t len = I2S_GetRxFIFOLen(I2S_NUM);
+ DBG_DIRECT("length = %d", len);
+ for (uint8_t i = 0; i < len; i++)
+ {
+ DBG_DIRECT("data[%d] = 0x%X", i, I2S_ReceiveData(I2S_NUM));
+ }
+ I2S_ClearINTPendingBit(I2S_NUM, I2S_INT_RX_READY);
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/I2S/I2S_Slave_Recv_GDMA/main.c b/src/sample/io_sample/I2S/I2S_Slave_Recv_GDMA/main.c
new file mode 100644
index 0000000..a871bdb
--- /dev/null
+++ b/src/sample/io_sample/I2S/I2S_Slave_Recv_GDMA/main.c
@@ -0,0 +1,229 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code of i2s send data.
+* @details
+* @author echo
+* @date 2021-07-21
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_i2s.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_uart.h"
+#include "rtl876x_gdma.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "trace.h"
+
+/* Defines -------------------------------------------------------------------*/
+#define I2S_LRCK_PIN P3_2
+#define I2S_BCLK_PIN P3_3
+#define I2S_DATA_TX_PIN P2_0
+
+#define I2S_NUM I2S0
+#define I2S_LRCK_PINMUX LRC_SPORT0
+#define I2S_BCLK_PINMUX BCLK_SPORT0
+#define I2S_DATA_RX_PINMUX ADCDAT_SPORT0
+
+#define APB_I2S APBPeriph_I2S0
+#define APB_I2S_CLOCK APBPeriph_I2S0_CLOCK
+
+#define I2S_CLK_SOURCE_REG_224 *((volatile uint32_t *)0x40000224UL)
+
+/* GDMA RX defines */
+#define GDMA_Channel_NUM 0
+#define GDMA_Channel GDMA_Channel0
+#define GDMA_Channel_IRQn GDMA0_Channel0_IRQn
+#define GDMA_Channel_Handler GDMA0_Channel0_Handler
+
+
+#define UART_TX_PIN P2_4
+#define UART_RX_PIN P2_5
+
+void board_uart_init(void)
+{
+ Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
+
+ Pinmux_Config(UART_TX_PIN, UART0_TX);
+ Pinmux_Config(UART_RX_PIN, UART0_RX);
+}
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return Void
+ */
+void board_i2s_init(void)
+{
+ Pad_Config(I2S_BCLK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
+ Pad_Config(I2S_LRCK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
+ Pad_Config(I2S_DATA_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_LOW);
+
+ Pinmux_Config(I2S_BCLK_PIN, I2S_BCLK_PINMUX);
+ Pinmux_Config(I2S_LRCK_PIN, I2S_LRCK_PINMUX);
+ Pinmux_Config(I2S_DATA_TX_PIN, I2S_DATA_RX_PINMUX);
+}
+
+/**
+ * @brief Initialize I2S peripheral.
+ * @param No parameter.
+ * @return Void
+ */
+void driver_i2s_init(void)
+{
+ RCC_PeriphClockCmd(APB_I2S, APB_I2S_CLOCK, ENABLE);
+
+ I2S_InitTypeDef I2S_InitStruct;
+
+ I2S_StructInit(&I2S_InitStruct);
+ I2S_InitStruct.I2S_ClockSource = I2S_CLK_40M;
+ /* BCLK = 40MHz*(ni/mi), LRCK = BCLK/64 */
+ I2S_InitStruct.I2S_BClockMi = 0x271; /* <!LRCK = 16K */
+ I2S_InitStruct.I2S_BClockNi = 0x30; /* <!BCLK = 1024K */
+ I2S_InitStruct.I2S_DeviceMode = I2S_DeviceMode_Slave;
+ I2S_InitStruct.I2S_ChannelType = I2S_Channel_stereo;
+ I2S_InitStruct.I2S_DataWidth = I2S_Width_16Bits;
+ I2S_InitStruct.I2S_DataFormat = I2S_Mode;
+ I2S_InitStruct.I2S_DMACmd = I2S_DMA_ENABLE;
+ I2S_Init(I2S_NUM, &I2S_InitStruct);
+
+ /* Set SPORT0 with external codec */
+ I2S_CLK_SOURCE_REG_224 |= BIT(3);
+
+ I2S_Cmd(I2S_NUM, I2S_MODE_RX, ENABLE);
+}
+
+void driver_uart_init(void)
+{
+ /* Enable clock */
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ /* UART init */
+ UART_InitTypeDef UART_InitStruct;
+
+ UART_StructInit(&UART_InitStruct);
+ /* change to 3M baudrate */
+ UART_InitStruct.div = 1;
+ UART_InitStruct.ovsr = 8;
+ UART_InitStruct.ovsr_adj = 0x492;
+ UART_InitStruct.TxWaterlevel = 12;
+
+ UART_InitStruct.TxDmaEn = ENABLE;
+ UART_InitStruct.dmaEn = UART_DMA_ENABLE;
+ UART_Init(UART0, &UART_InitStruct);
+
+}
+
+void driver_gdma_init(void)
+{
+ /* Enable GDMA clock */
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+
+ /* Initialize GDMA peripheral */
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = GDMA_Channel_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToPeripheral;
+ GDMA_InitStruct.GDMA_BufferSize = 1000 / 4;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)(&(I2S0->RX_DR));
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(UART0->RB_THR));
+ GDMA_InitStruct.GDMA_SourceHandshake = GDMA_Handshake_I2S0_RX;
+ GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_UART0_TX;
+ GDMA_Init(GDMA_Channel, &GDMA_InitStruct);
+ GDMA_INTConfig(GDMA_Channel_NUM, GDMA_INT_Transfer, ENABLE);
+
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = GDMA_Channel_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 1;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+ GDMA_Cmd(GDMA_Channel_NUM, ENABLE);
+}
+
+/**
+ * @brief Demo code of I2S communication.
+ * @param No parameter.
+ * @return Void
+*/
+void i2s_demo(void)
+{
+ board_i2s_init();
+
+ board_uart_init();
+
+ driver_gdma_init();
+
+ driver_i2s_init();
+
+ driver_uart_init();
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ __enable_irq();
+ i2s_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ }
+}
+
+/**
+ * @brief I2S0_RX_Handler.
+ * @param No parameter.
+ * @return void
+*/
+void I2S0_RX_Handler(void)
+{
+// DBG_DIRECT("In I2S0_RX_Handler");
+
+ if (I2S_GetINTStatus(I2S_NUM, I2S_INT_RX_READY))
+ {
+ uint8_t len = I2S_GetRxFIFOLen(I2S_NUM);
+// DBG_DIRECT("length = %d", len);
+// for (uint8_t i = 0; i < len; i++)
+// {
+// DBG_DIRECT("data[%d] = 0x%X", i, I2S_ReceiveData(I2S_NUM));
+// }
+ I2S_ClearINTPendingBit(I2S_NUM, I2S_INT_RX_READY);
+ }
+}
+
+
+void GDMA_Channel_Handler(void)
+{
+// DBG_DIRECT("in gdma handler");
+ GDMA_SetSourceAddress(GDMA_Channel, (uint32_t)(&(I2S0->RX_DR)));
+ GDMA_SetDestinationAddress(GDMA_Channel, (uint32_t)(&(UART0->RB_THR)));
+
+ GDMA_SetBufferSize(GDMA_Channel, 1000 / 4);
+
+ GDMA_ClearINTPendingBit(GDMA_Channel_NUM, GDMA_INT_Transfer);
+ GDMA_Cmd(GDMA_Channel_NUM, ENABLE);
+}
+
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/I2S/Tx_polling/main.c b/src/sample/io_sample/I2S/Tx_polling/main.c
new file mode 100644
index 0000000..0a2bd1f
--- /dev/null
+++ b/src/sample/io_sample/I2S/Tx_polling/main.c
@@ -0,0 +1,130 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code of i2s send data.
+* @details
+* @author yuan
+* @date 2018-05-29
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include "rtl876x_i2s.h"
+//#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+
+/* Defines -------------------------------------------------------------------*/
+#define I2S_LRCK_PIN P3_2
+#define I2S_BCLK_PIN P3_3
+#define I2S_DATA_TX_PIN P4_0
+
+#define I2S_NUM I2S0
+#define I2S_LRCK_PINMUX LRC_SPORT0
+#define I2S_BCLK_PINMUX BCLK_SPORT0
+#define I2S_DATA_TX_PINMUX DACDAT_SPORT0
+
+#define APB_I2S APBPeriph_I2S0
+#define APB_I2S_CLOCK APBPeriph_I2S0_CLOCK
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return Void
+ */
+void board_i2s_init(void)
+{
+ Pad_Config(I2S_BCLK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
+ Pad_Config(I2S_LRCK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
+ Pad_Config(I2S_DATA_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_LOW);
+
+ Pinmux_Config(I2S_BCLK_PIN, I2S_BCLK_PINMUX);
+ Pinmux_Config(I2S_LRCK_PIN, I2S_LRCK_PINMUX);
+ Pinmux_Config(I2S_DATA_TX_PIN, I2S_DATA_TX_PINMUX);
+}
+
+/**
+ * @brief Initialize I2S peripheral.
+ * @param No parameter.
+ * @return Void
+ */
+void driver_i2s_init(void)
+{
+ RCC_PeriphClockCmd(APB_I2S, APB_I2S_CLOCK, ENABLE);
+
+ I2S_InitTypeDef I2S_InitStruct;
+
+ I2S_StructInit(&I2S_InitStruct);
+ I2S_InitStruct.I2S_ClockSource = I2S_CLK_40M;
+ /* BCLK = 40MHz*(ni/mi), LRCK = BCLK/64 */
+ I2S_InitStruct.I2S_BClockMi = 0x271; /* <!LRCK = 16K */
+ I2S_InitStruct.I2S_BClockNi = 0x10; /* <!BCLK = 1024K */
+ I2S_InitStruct.I2S_DeviceMode = I2S_DeviceMode_Master;
+ I2S_InitStruct.I2S_ChannelType = I2S_Channel_stereo;
+ I2S_InitStruct.I2S_DataWidth = I2S_Width_16Bits;
+ I2S_InitStruct.I2S_DataFormat = I2S_Mode;
+ I2S_InitStruct.I2S_DMACmd = I2S_DMA_DISABLE;
+ I2S_Init(I2S_NUM, &I2S_InitStruct);
+ I2S_Cmd(I2S_NUM, I2S_MODE_TX, ENABLE);
+}
+
+/**
+ * @brief Demo code of sending data continuously.
+ * @param No parameter.
+ * @return Void
+ */
+void i2s_senddata(void)
+{
+ uint32_t i = 0x12348800;
+
+ while (1)
+ {
+ if (I2S_GetTxFIFOFreeLen(I2S_NUM))
+ {
+ /* 16bit format, lower half word send first! */
+ I2S_SendData(I2S_NUM, i++);
+ }
+ }
+}
+
+/**
+ * @brief Demo code of I2S communication.
+ * @param No parameter.
+ * @return Void
+*/
+void i2s_demo(void)
+{
+ board_i2s_init();
+ driver_i2s_init();
+ i2s_senddata();
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ i2s_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/Learn/ble_peripheral/ancs.c b/src/sample/io_sample/IR/Learn/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/IR/Learn/ble_peripheral/ancs.h b/src/sample/io_sample/IR/Learn/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/IR/Learn/ble_peripheral/app.c b/src/sample/io_sample/IR/Learn/ble_peripheral/app.c
new file mode 100644
index 0000000..af0eaa1
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/ble_peripheral/app.c
@@ -0,0 +1,619 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "ir_learn_app.h"
+#include "ir_learn.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+#if (IR_FUN_EN)
+ case IO_MSG_TYPE_IR:
+ {
+#if (IR_FUN_LEARN_EN)
+ if (ir_learn_handle_msg(&io_msg))
+ {
+ /* IR learn finish */
+#if (LED_IR_FUN_EN)
+ extern void led_ir_learn_swap(void);
+ led_ir_learn_swap();
+#endif
+ }
+ //Add user code here!
+#endif
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/IR/Learn/ble_peripheral/app.h b/src/sample/io_sample/IR/Learn/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/IR/Learn/ble_peripheral/app_flags.h b/src/sample/io_sample/IR/Learn/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/IR/Learn/ble_peripheral/app_task.c b/src/sample/io_sample/IR/Learn/ble_peripheral/app_task.c
new file mode 100644
index 0000000..0d2bbb9
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/ble_peripheral/app_task.c
@@ -0,0 +1,124 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/IR/Learn/ble_peripheral/app_task.h b/src/sample/io_sample/IR/Learn/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/IR/Learn/ble_peripheral/main.c b/src/sample/io_sample/IR/Learn/ble_peripheral/main.c
new file mode 100644
index 0000000..65575cb
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/ble_peripheral/main.c
@@ -0,0 +1,261 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdlib.h>
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+//#include "app_timer.h"
+
+#include "ir_learn_app.h"
+#include "ir_learn.h"
+#include "ir_led.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+#if (IR_FUN_EN && LED_IR_FUN_EN)
+ board_ir_led_init();
+#endif
+#if (IR_FUN_EN && IR_FUN_LEARN_EN)
+ board_ir_learn_init();
+#endif
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+#if (IR_FUN_EN && LED_IR_FUN_EN)
+ driver_ir_led_init();
+#endif
+#if (IR_FUN_EN && IR_FUN_LEARN_EN)
+ ir_learn_timer_init();
+ ir_learn_module_init();
+#endif
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+// sw_timer_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/IR/Learn/ir_learn.c b/src/sample/io_sample/IR/Learn/ir_learn.c
new file mode 100644
index 0000000..efb68e5
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/ir_learn.c
@@ -0,0 +1,340 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_learn.c
+* @brief This file provides ir learn driver.
+* @details
+* @author elliot chen
+* @date 2017-11-16
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes --------------------------------------------------------------------*/
+#include "ir_learn.h"
+
+#if (IR_FUN_EN && IR_FUN_LEARN_EN)
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_ir_learn_init(void)
+{
+ board_ir_rx_init();
+}
+
+/**
+ * @brief Close the IR learn function.
+ * @param none.
+ * @retval None
+ */
+void ir_learn_deinit(void)
+{
+ ir_trans_rx_deinit();
+}
+
+/**
+ * @brief Initializes some peripherals which used to learn waveform.
+ * @param none.
+ * @retval None
+ */
+void ir_learn_init(void)
+{
+ ir_trans_rx_init();
+}
+
+#ifdef IR_LEARN_DUTY_CYCLE_SUPPORT
+/**
+ * @brief Learn a specific IR waveform duty cycle.
+ * @param pIR_Packet: point to IR packet struct.
+ * @retval The decoded status.
+ */
+static IR_Learn_Status ir_learn_dutycycle(IR_Learn_TypeDef *pIR_Packet)
+{
+ uint16_t i = 0;
+ uint32_t buf[IR_LEARN_DUTY_CYCLE_SAMPLE_SIZE_MAX] = {0};
+ uint32_t carrier_high_time = 0;
+ uint32_t carrier_low_time = 0;
+
+ /* Replicate data used to calculate duty cycle from the IR receiving data queue. */
+ if (ir_trans_rx_get_data_len() >= IR_LEARN_DUTY_CYCLE_SAMPLE_SIZE_MAX)
+ {
+ ir_trans_rx_copy_data(buf, IR_LEARN_DUTY_CYCLE_SAMPLE_SIZE_MAX);
+ }
+ else
+ {
+ return IR_LEARN_DUTY_CYCLE_ERR_NO_SAMPLE;
+ }
+
+ for (i = 0; i < (IR_LEARN_DUTY_CYCLE_SAMPLE_SIZE_MAX - 1); i++)
+ {
+ if (((buf[i] & IR_DATA_MSK) < TIME_HIGHEST_VALUE) &&
+ ((buf[i + 1] & IR_DATA_MSK) < TIME_HIGHEST_VALUE))
+ {
+ /* Check if there is a carrier waveform. */
+ if (buf[i] & IR_CARRIER_DATA_TYPE)
+ {
+ carrier_high_time = buf[i] & IR_DATA_MSK;
+ carrier_low_time = buf[i + 1] & IR_DATA_MSK;
+ }
+ else
+ {
+ carrier_high_time = buf[i + 1] & IR_DATA_MSK;
+ carrier_low_time = buf[i] & IR_DATA_MSK;
+ }
+ break;
+ }
+ }
+
+ if (carrier_high_time && carrier_low_time)
+ {
+ pIR_Packet->carrier_time = carrier_high_time + carrier_low_time;
+ pIR_Packet->duty_cycle = (float)carrier_high_time / ((float)carrier_high_time +
+ (float)carrier_low_time);
+ return IR_LEARN_OK;
+ }
+
+ return IR_LEARN_DUTY_CYCLE_ERR_NO_VALID_DATA;
+}
+
+/**
+ * @brief IR data compensation.
+ * @param pIR_Packet: point to ir packet struct.
+ * @retval void
+ */
+void ir_learn_data_compensation(IR_Learn_TypeDef *pIR_Packet)
+{
+ uint16_t i = 0;
+
+ if ((pIR_Packet->freq == 0) || (pIR_Packet->duty_cycle == 0))
+ {
+ return ;
+ }
+
+ for (i = 0; i <= pIR_Packet->buf_index; i++)
+ {
+ pIR_Packet->ir_buf[i] += pIR_Packet->carrier_time;
+ }
+}
+
+#endif
+
+
+/**
+ * @brief Learn a specific ir waveform freqency.
+ * @param pIR_Packet: point to ir packet struct.
+ * @retval The decoded status.
+ */
+IR_Learn_Status ir_learn_freq(IR_Learn_TypeDef *pIR_Packet)
+{
+ uint16_t i = 0;
+ uint16_t j = 0;
+ float freq_sum = 0;
+#if IR_LEARN_FREQ_FILTER_EN
+ float max_freq = 0;
+ float min_freq = 1000.0;
+ float temp = 0;
+#endif
+
+ for (i = 0, j = 0; (i <= pIR_Packet->buf_index) && (j <= pIR_Packet->carrier_info_idx); i++)
+ {
+ if (pIR_Packet->ir_buf[i] & IR_CARRIER_DATA_TYPE)
+ {
+ temp = (pIR_Packet->carrier_info_buf[j++] * (IR_LEARN_FREQ * 0.5)) / \
+ (pIR_Packet->ir_buf[i] & IR_DATA_MSK);
+
+ freq_sum += temp;
+
+#if IR_LEARN_FREQ_FILTER_EN
+ if (max_freq < temp)
+ {
+ max_freq = temp;
+ }
+ if (min_freq > temp)
+ {
+ min_freq = temp;
+ }
+#endif
+ }
+ }
+
+#if IR_LEARN_FREQ_FILTER_EN
+ if (j > 2)
+ {
+ freq_sum -= (max_freq + min_freq);
+ j -= 2;
+ }
+#endif
+
+ if (j)
+ {
+ pIR_Packet->freq = freq_sum / j;
+ }
+
+ return IR_LEARN_OK;
+}
+
+
+/**
+ * @brief Convert ir learned waveform data to actual ir data which can be sent.
+ * @param pIR_Packet: point to ir packet struct.
+ * @retval void
+ */
+void ir_learn_data_convert(IR_Learn_TypeDef *pIR_Packet)
+{
+ uint16_t i = 0;
+
+#ifdef IR_LEARN_DUTY_CYCLE_SUPPORT
+ if ((pIR_Packet->freq == 0) || (pIR_Packet->duty_cycle == 0))
+ {
+ return ;
+ }
+#else
+ if (pIR_Packet->freq == 0)
+ {
+ return ;
+ }
+#endif
+
+ for (i = 0; i <= pIR_Packet->buf_index; i++)
+ {
+ if (pIR_Packet->ir_buf[i] & IR_CARRIER_DATA_TYPE)
+ {
+ pIR_Packet->ir_buf[i] = (pIR_Packet->ir_buf[i] & IR_DATA_MSK) * pIR_Packet->freq / IR_LEARN_FREQ;
+ pIR_Packet->ir_buf[i] |= IR_CARRIER_DATA_TYPE;
+ }
+ else
+ {
+ pIR_Packet->ir_buf[i] = (pIR_Packet->ir_buf[i] & IR_DATA_MSK) * pIR_Packet->freq / IR_LEARN_FREQ;
+ }
+
+#if IR_LEARN_SOFTWARE_ADJUST_EN
+ if ((pIR_Packet->ir_buf[i] & IR_DATA_MSK) > 0)
+ {
+ pIR_Packet->ir_buf[i] -= 1;
+ }
+#endif
+ }
+}
+
+/**
+ * @brief IR learn data decode
+ * @param pIR_Packet: point to IR packet struct.
+ * @retval The decoded status.
+ */
+IR_Learn_Status ir_learn_decode(IR_Learn_TypeDef *pIR_Packet)
+{
+ uint32_t time_interval = 0;
+ IR_Learn_Status status = IR_LEARN_OK;
+
+#ifdef IR_LEARN_DUTY_CYCLE_SUPPORT
+ if (!pIR_Packet->duty_cycle)
+ {
+ status = ir_learn_dutycycle(pIR_Packet);
+ }
+#endif
+
+ while (ir_trans_rx_get_data_len())
+ {
+ /* Extract data */
+ ir_trans_rx_read_data(&time_interval, 1);
+ time_interval &= IR_DATA_MSK;
+
+ /* Record total time of carrier wave */
+ if (time_interval < TIME_HIGHEST_VALUE)
+ {
+ /* Record carrier waveform time */
+ pIR_Packet->ir_buf[pIR_Packet->buf_index] += time_interval;
+
+ /* Record carrier number */
+ pIR_Packet->carrier_info_buf[pIR_Packet->carrier_info_idx]++;
+
+ /* Record data type */
+ pIR_Packet->is_carrier = true;
+#ifdef IR_LEARN_DUTY_CYCLE_SUPPORT
+ pIR_Packet->last_handle_data = time_interval;
+#endif
+ }
+ else
+ {
+ if (pIR_Packet->is_carrier == true)
+ {
+#ifdef IR_LEARN_DUTY_CYCLE_SUPPORT
+ if (pIR_Packet->duty_cycle)
+ {
+ if (pIR_Packet->last_handle_data < TIME_HIGHEST_VALUE)
+ {
+ pIR_Packet->ir_buf[pIR_Packet->buf_index] += pIR_Packet->carrier_time -
+ pIR_Packet->last_handle_data;
+ }
+ }
+ else
+ {
+ IR_RX_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "Warning: IR carrier data compensation handle error!",
+ 0);
+ status = IR_LEARN_CARRIRE_DATA_HANDLE_ERR;
+ }
+#endif
+ /* Restore data type */
+ pIR_Packet->ir_buf[pIR_Packet->buf_index] |= IR_CARRIER_DATA_TYPE;
+ /* pointer to next buffer to store data */
+ pIR_Packet->buf_index++;
+#ifdef IR_LEARN_DUTY_CYCLE_SUPPORT
+ if (pIR_Packet->duty_cycle)
+ {
+ /* Store value of low waveform */
+ pIR_Packet->ir_buf[pIR_Packet->buf_index++] = time_interval + pIR_Packet->last_handle_data - \
+ pIR_Packet->carrier_time;
+ }
+ else
+ {
+ /* Store value of low waveform */
+ pIR_Packet->ir_buf[pIR_Packet->buf_index++] = time_interval;
+ IR_RX_DBG_BUFFER(MODULE_APP, LEVEL_INFO,
+ "Warning: IR no carrier data compensation handle error!", 0);
+ status = IR_LEARN_NO_CARRIRE_DATA_HANDLE_ERR;
+ }
+#else
+ /* Store value of low waveform */
+ pIR_Packet->ir_buf[pIR_Packet->buf_index++] = time_interval;
+#endif
+ /* Record new carrier waveform information */
+ pIR_Packet->carrier_info_idx++;
+ /* Record data type */
+ pIR_Packet->is_carrier = false;
+ }
+ else
+ {
+ /* Store value of low waveform */
+ //pIR_Packet->ir_buf[pIR_Packet->buf_index] += time_interval;
+ IR_RX_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "Warning: exceed maximum stop signal value!", 0);
+ status = IR_LEARN_WAVEFORM_ERR;
+ break;
+ }
+ }
+
+ /* Check the maximum number of learning data */
+ if (pIR_Packet->buf_index >= IR_LEARN_WAVEFORM_SIZE_MAX)
+ {
+ status = IR_LEARN_EXCEED_SIZE;
+ break;
+ }
+
+ /* Check IR end signal */
+ if (time_interval >= IR_LEARN_STOP_TIME)
+ {
+ status = IR_LEARN_EXIT;
+ break;
+ }
+ }
+
+ return status;
+}
+
+#endif /* (IR_FUN_EN && IR_FUN_LEARN_EN) */
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/Learn/ir_learn.h b/src/sample/io_sample/IR/Learn/ir_learn.h
new file mode 100644
index 0000000..a88df33
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/ir_learn.h
@@ -0,0 +1,99 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ir_learn.h
+* @brief
+* @details
+* @author yuan
+* @date 2019-01-24
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __IR_LEARN_H
+#define __IR_LEARN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "board.h"
+
+
+#if (IR_FUN_EN && IR_FUN_LEARN_EN)
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_trans_rx.h"
+#include "ir_learn_config.h"
+
+/* Defines -------------------------------------------------------------*/
+/* Filter threshold value. If time interval< 200us(10KHz), treat it as a part of a carrier time. */
+/* IR learn carrier freqency between 10KHz and 2.5MHz */
+#define TIME_HIGHEST_VALUE (200*(IR_LEARN_FREQ/1000000))
+
+/* IR data mask */
+#define IR_DATA_MSK ((uint32_t)0x7FFFFFFFUL)
+/* Carrier waveform data type select */
+#define IR_CARRIER_DATA_TYPE ((uint32_t)0x80000000UL)
+
+/** @defgroup IR_LEARN_Exported_Types IR Learn Exported Types
+ * @{
+ */
+typedef enum
+{
+ IR_LEARN_OK, /**< IR learn ok: learning */
+ IR_LEARN_EXIT, /**< IR learn exit: complete IR learn */
+ IR_LEARN_WAVEFORM_ERR, /**< IR learn waveform error */
+ IR_LEARN_CARRIRE_DATA_HANDLE_ERR, /**< IR learn carrier data compensation error */
+ IR_LEARN_NO_CARRIRE_DATA_HANDLE_ERR, /**< IR learn carrier data compensation error */
+ IR_LEARN_EXCEED_SIZE, /**< IR learn exceed maximum size */
+ IR_LEARN_DUTY_CYCLE_ERR_NO_SAMPLE, /**< IR learn duty cycle error: samples were not collceted */
+ IR_LEARN_DUTY_CYCLE_ERR_NO_VALID_DATA, /**< IR learn duty cycle error: have no valid data */
+ //IR_LEARN_DUTY_CYCLE_ERR_NO_Carrier_TIME,/**< IR learn duty cycle error: have no valid carrier high time */
+} IR_Learn_Status;
+
+/**
+ * @brief IR learn data structure
+ */
+typedef struct
+{
+ uint32_t ir_buf[IR_LEARN_WAVEFORM_SIZE_MAX];
+#ifdef IR_LEARN_DUTY_CYCLE_SUPPORT
+ uint32_t last_handle_data;
+#endif
+ uint16_t buf_index;
+ uint16_t carrier_info_buf[IR_LEARN_WAVEFORM_SIZE_MAX / 2 + 2];
+ uint16_t carrier_info_idx;
+ uint8_t is_carrier;
+
+#ifdef IR_LEARN_DUTY_CYCLE_SUPPORT
+ uint32_t carrier_time;
+ float duty_cycle;
+#endif
+ float freq;
+} IR_Learn_TypeDef;
+
+/** End of IR_LEARN_Exported_Types
+ * @}
+ */
+
+void board_ir_learn_init(void);
+void ir_learn_deinit(void);
+void ir_learn_init(void);
+IR_Learn_Status ir_learn_freq(IR_Learn_TypeDef *pIR_Packet);
+void ir_learn_data_convert(IR_Learn_TypeDef *pIR_Packet);
+IR_Learn_Status ir_learn_decode(IR_Learn_TypeDef *pIR_Packet);
+
+#endif /* (IR_FUN_EN && IR_FUN_LEARN_EN) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __IR_LEARN_H */
+
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/Learn/ir_learn_app.c b/src/sample/io_sample/IR/Learn/ir_learn_app.c
new file mode 100644
index 0000000..44d1784
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/ir_learn_app.c
@@ -0,0 +1,199 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_learn_app.c
+* @brief This file provides application layer application code for how to use IR learin driver.
+* @details
+* @author elliot chen
+* @date 2018-7-24
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_learn_app.h"
+
+
+#if (IR_FUN_EN && IR_FUN_LEARN_EN)
+#include "os_timer.h"
+
+/* Globals -------------------------------------------------------------------*/
+typedef void *TimerHandle_t;
+
+TimerHandle_t IR_Learn_Timer = 0;
+
+IR_Learn_TypeDef IR_Learn_Packet;
+
+extern bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+#define ir_send_msg_to_apptask app_send_msg_to_apptask
+
+/**
+ * @brief ir learn msg handle from ir learn driver isr.
+ * @param vIsEnd:0 FALSE, 1 TRUE
+ * @return void
+ */
+static void ir_learn_send_msg_from_isr(uint8_t vIsEnd)
+{
+ //Add applcation code here which send msg from IR ISR to application layer to notify handling data
+ T_IO_MSG bee_io_msg;
+ bee_io_msg.type = IO_MSG_TYPE_IR;
+
+ if (vIsEnd)
+ {
+ /* send ir learn data message to app */
+ bee_io_msg.subtype = IO_MSG_TYPE_IR_LEARN_STOP;
+ }
+ else
+ {
+ /* send ir learn data message to app */
+ bee_io_msg.subtype = IO_MSG_TYPE_IR_LEARN_DATA;
+ }
+ ir_send_msg_to_apptask(&bee_io_msg);
+}
+
+/**
+ * @brief Stop ir learn function.
+ * @param None
+ * @return void
+ */
+static void ir_learn_exit(void)
+{
+ APP_PRINT_INFO0("[ir_learn_app]ir_learn_exit");
+
+ /* Close IR learn */
+ ir_learn_deinit();
+}
+
+/**
+ * @brief IR learn timer callback.
+ * @param TimerHandle_t pxTimer.
+ * @return void.
+ * @note None.
+ */
+static void ir_learn_timer_callback(TimerHandle_t pxTimer)
+{
+ APP_PRINT_INFO0("[ir_learn_app]ir_learn_timer_callback: ir learn time out");
+ ir_learn_exit();
+
+ //Add application code here!!!
+}
+
+/**
+ * @brief ir learn timer init.
+ *@param void.
+ * @return void.
+ * @note none.
+**/
+void ir_learn_timer_init(void)
+{
+ APP_PRINT_INFO0("[ir_learn_app]ir_learn_timer_init");
+ /* IR_Learn_Timer is used for ir learn */
+ if (false == os_timer_create(&IR_Learn_Timer, "ir_learn_timer", 1, \
+ IR_LEARN_TIMEOUT, false, ir_learn_timer_callback))
+ {
+ APP_PRINT_ERROR0("[ir_learn_app]ir_learn_timer_init: creat IR_Learn_Timer fail!");
+ }
+}
+
+/**
+* @brief Application code for IR learn module init.
+* @param No parameter.
+* @return void
+*/
+void ir_learn_module_init(void)
+{
+ APP_PRINT_INFO0("[ir_learn_app]ir_learn_module_init");
+ if (true == os_timer_start(&IR_Learn_Timer))
+ {
+ APP_PRINT_INFO0("[ir_learn_app]ir_learn_module_init: IR_Learn_Timer start success!");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("[ir_learn_app]ir_learn_module_init: IR_Learn_Timer start failed!");
+ }
+
+ board_ir_learn_init();
+ /* Initialize IR learn data structure */
+ memset(&IR_Learn_Packet, 0, sizeof(IR_Learn_TypeDef));
+ ir_trans_rx_handler_cb(ir_learn_send_msg_from_isr);
+ ir_learn_init();
+}
+
+/**
+ * @brief Check if ir learn allow enter dlps.
+ * @param None
+ * @return bool: true working;
+ * false idle;
+ */
+bool ir_learn_check_dlps(void)
+{
+ return true;
+}
+
+/**
+ * @brief Application code for IR learn data process.
+ * @param IR sub type msg.
+ * @return bool.
+ * true: specific msg can be handle;
+ * false: ir msg can not be handled.
+ */
+bool ir_learn_handle_msg(T_IO_MSG *io_ir_msg)
+{
+ bool ret = false;
+ uint16_t sub_type = io_ir_msg->subtype;
+
+ if (sub_type == IO_MSG_TYPE_IR_LEARN_DATA)
+ {
+ IR_Learn_Status status = IR_LEARN_OK;
+ status = ir_learn_decode(&IR_Learn_Packet);
+
+ if (status == IR_LEARN_EXCEED_SIZE)
+ {
+ APP_PRINT_WARN0("[ir_learn_app]ir_learn_handle_msg: IR learn exceed size!");
+ /* Close IR learn */
+ ir_learn_deinit();
+ ret = false;
+ }
+ else if (status == IR_LEARN_EXIT)
+ {
+ APP_PRINT_WARN0("[ir_learn_app]ir_learn_handle_msg: IR learn stop time error!");
+ /* Close IR learn */
+ ir_learn_deinit();
+ ret = false;
+ }
+ }
+ else if (sub_type == IO_MSG_TYPE_IR_LEARN_STOP)
+ {
+ /* Pick up the last ir data*/
+ ir_learn_decode(&IR_Learn_Packet);
+ /* Decode IR carrier freqency */
+ ir_learn_freq(&IR_Learn_Packet);
+ /* Data reduction */
+ ir_learn_data_convert(&IR_Learn_Packet);
+ /* Print decode result */
+#ifdef IR_LEARN_DUTY_CYCLE_SUPPORT
+ APP_PRINT_INFO1("[ir_learn_app]ir_learn_handle_msg:IO_MSG_TYPE_IR_LEARN_STOP, duty_cycle: %d/1000.",
+ (uint32_t)(IR_Learn_Packet.duty_cycle * 1000));
+#endif
+ APP_PRINT_INFO1("[ir_learn_app]ir_learn_handle_msg:IO_MSG_TYPE_IR_LEARN_STOP, frequence: %d.",
+ (uint32_t)(IR_Learn_Packet.freq * 1000));
+ APP_PRINT_INFO1("[ir_learn_app]ir_learn_handle_msg:IO_MSG_TYPE_IR_LEARN_STOP, learn data length: %d.",
+ IR_Learn_Packet.buf_index);
+ for (uint32_t i = 0; i < IR_Learn_Packet.buf_index; i++)
+ {
+ APP_PRINT_INFO2("[ir_learn_app]ir_learn_handle_msg:IO_MSG_TYPE_IR_LEARN_STOP,learn data%d: 0x%x.",
+ i, IR_Learn_Packet.ir_buf[i]);
+ }
+ ir_learn_exit();
+ ret = true;
+
+ // Add application code here!!!
+ ir_learn_module_init();
+ }
+ return ret;
+}
+
+#endif /* IR_FUN_EN && IR_FUN_LEARN_EN */
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/IR/Learn/ir_learn_app.h b/src/sample/io_sample/IR/Learn/ir_learn_app.h
new file mode 100644
index 0000000..c5212e4
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/ir_learn_app.h
@@ -0,0 +1,38 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ir_learn_app.h
+* @brief
+* @details
+* @author elliot chen
+* @date 2018-7-24
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __IR_LEARN_APP_H_
+#define __IR_LEARN_APP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "app_msg.h"
+
+#include "ir_learn.h"
+#include "ir_learn_config.h"
+
+void ir_learn_timer_init(void);
+void ir_learn_module_init(void);
+bool ir_learn_handle_msg(T_IO_MSG *io_ir_msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__IR_LEARN_APP_H_*/
+
+/******************* (C) COPYRIGHT 2018Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/Learn/ir_learn_config.h b/src/sample/io_sample/IR/Learn/ir_learn_config.h
new file mode 100644
index 0000000..4adc05c
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/ir_learn_config.h
@@ -0,0 +1,54 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_learn_config.h
+* @brief ir learn configuration header file
+* @details
+* @author elliot chen
+* @date 2017-11-16
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IR_LEARN_CONFIG_H
+#define __IR_LEARN_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Defines ------------------------------------------------------------------*/
+
+/**
+ * @brief No carrier waveform maximum time is 6ms
+ */
+#define IR_LEARN_NO_WAVEFORM_TIME_MAX ((uint32_t)IR_LEARN_FREQ*6)
+#define IR_LEARN_STOP_TIME (IR_LEARN_NO_WAVEFORM_TIME_MAX*0.95)
+
+/**
+ * @brief Enable IR duty cycle learning or not
+ */
+#define IR_LEARN_DUTY_CYCLE_SUPPORT
+#define IR_LEARN_DUTY_CYCLE_SAMPLE_SIZE_MAX 6
+
+/**
+ * @brief Enable filter IR freqency or not
+ */
+#define IR_LEARN_FREQ_FILTER_EN 1
+/**
+ * @brief Software adjustment for sending IR learn data
+ */
+#define IR_LEARN_SOFTWARE_ADJUST_EN 1
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined (__IR_LEARN_CONFIG_H) */
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/Learn/led/ir_led.c b/src/sample/io_sample/IR/Learn/led/ir_led.c
new file mode 100644
index 0000000..d04166f
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/led/ir_led.c
@@ -0,0 +1,78 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_led.c
+* @brief This file provides led display for ir application code.
+* @details
+* @author yuan
+* @date 2019-01-24
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_led.h"
+
+#if (IR_FUN_EN && LED_IR_FUN_EN)
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_ir_led_init(void)
+{
+ Pad_Config(LED_IR_SEND_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(LED_IR_SEND_PIN, DWGPIO);
+#if (IR_FUN_LEARN_EN)
+ Pad_Config(LED_IR_LEARN_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(LED_IR_LEARN_PIN, DWGPIO);
+#endif
+}
+
+/**
+ * @brief Initialize gpio peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_ir_led_init(void)
+{
+ /* Enable GPIO clock */
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+
+ /* Initialize GPIO */
+ GPIO_InitTypeDef GPIO_InitStruct;
+ GPIO_StructInit(&GPIO_InitStruct);
+#if (IR_FUN_LEARN_EN)
+ GPIO_InitStruct.GPIO_Pin = LED_IR_SEND_OUT_PIN | LED_IR_LEARN_OUT_PIN;
+#else
+ GPIO_InitStruct.GPIO_Pin = LED_IR_SEND_OUT_PIN;
+#endif
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_Init(&GPIO_InitStruct);
+
+ GPIO_ResetBits(LED_IR_SEND_OUT_PIN);
+#if (IR_FUN_LEARN_EN)
+ GPIO_ResetBits(LED_IR_LEARN_OUT_PIN);
+#endif
+}
+
+void led_ir_send_swap(void)
+{
+ GPIO_WriteBit(LED_IR_SEND_OUT_PIN, (BitAction)(1 - GPIO_ReadOutputDataBit(LED_IR_SEND_OUT_PIN)));
+}
+
+#if (IR_FUN_LEARN_EN)
+void led_ir_learn_swap(void)
+{
+ GPIO_WriteBit(LED_IR_LEARN_OUT_PIN, (BitAction)(1 - GPIO_ReadOutputDataBit(LED_IR_LEARN_OUT_PIN)));
+}
+#endif /* IR_FUN_LEARN_EN */
+
+#endif /* (IR_FUN_EN && LED_IR_FUN_EN) */
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/Learn/led/ir_led.h b/src/sample/io_sample/IR/Learn/led/ir_led.h
new file mode 100644
index 0000000..8755201
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/led/ir_led.h
@@ -0,0 +1,51 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ir_led.h
+* @brief
+* @details
+* @author yuan
+* @date 2019-01-24
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __IR_LED_H
+#define __IR_LED_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "board.h"
+
+#if (IR_FUN_EN && LED_IR_FUN_EN)
+#include "rtl876x_gpio.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define LED_IR_SEND_OUT_PIN GPIO_GetPin(LED_IR_SEND_PIN)
+#if (IR_FUN_LEARN_EN)
+#define LED_IR_LEARN_OUT_PIN GPIO_GetPin(LED_IR_LEARN_PIN)
+#endif
+
+/* Function declaration --------------------------------------------------------*/
+void board_ir_led_init(void);
+void driver_ir_led_init(void);
+void led_ir_send_swap(void);
+void led_ir_learn_swap(void);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__IR_LED_H*/
+
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/Learn/trans/ir_driver_rx.c b/src/sample/io_sample/IR/Learn/trans/ir_driver_rx.c
new file mode 100644
index 0000000..0c13a65
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/trans/ir_driver_rx.c
@@ -0,0 +1,166 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ir_driver_rx.c
+* @brief This file provides demo code of ir.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_driver_rx.h"
+
+#include "ir_rx_loop_queue.h"
+
+#if (IR_FUN_EN && IR_FUN_LEARN_EN)
+
+/* Globals ------------------------------------------------------------------*/
+/* Function pointer used to send event to application from IR learn interrupt handler. */
+pFn_IR_RX_Handler_CB_t pFn_IR_RX_Handler_CB = NULL;
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_ir_rx_init(void)
+{
+ Pad_Config(IR_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
+
+ Pinmux_Config(IR_RX_PIN, IRDA_RX);
+}
+
+
+/**
+ * @brief Initialize ir peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_ir_rx_init(void)
+{
+ /* Enable IR clock */
+ RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, DISABLE);
+ RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, ENABLE);
+
+ /* Initialize IR */
+ IR_InitTypeDef IR_InitStruct;
+ IR_StructInit(&IR_InitStruct);
+ /* IR carrier freqency is 38KHz */
+ IR_InitStruct.IR_Freq = IR_LEARN_FREQ;
+ /* Duty ratio = 1/IR_DutyCycle */
+ IR_InitStruct.IR_DutyCycle = 2;
+ /* IR receiveing mode */
+ IR_InitStruct.IR_Mode = IR_MODE_RX;
+ IR_InitStruct.IR_RxStartMode = IR_RX_AUTO_MODE;
+ /* Configure RX FIFO threshold level to trigger IR_INT_RF_LEVEL interrupt */
+ IR_InitStruct.IR_RxFIFOThrLevel = IR_RX_FIFO_THR_LEVEL;
+ /* Discard the latest received dta if RX FIFO is full */
+ IR_InitStruct.IR_RxFIFOFullCtrl = IR_RX_FIFO_FULL_DISCARD_NEWEST;
+ /* Configure trigger type */
+ IR_InitStruct.IR_RxTriggerMode = IR_RX_FALL_EDGE;
+ /* If high to low or low to high transition time <= 50ns,Filter out it. */
+ IR_InitStruct.IR_RxFilterTime = IR_RX_FILTER_TIME_200ns;
+ /* IR_RX_Count_Low_Level is counting low level */
+ IR_InitStruct.IR_RxCntThrType = IR_RX_Count_High_Level;
+ /* Configure RX counter threshold.You can use it to decide to stop receiving IR data */
+ IR_InitStruct.IR_RxCntThr = IR_LEARN_NO_WAVEFORM_TIME_MAX;
+ IR_Init(&IR_InitStruct);
+
+ IR_Cmd(IR_MODE_RX, ENABLE);
+ IR_ClearRxFIFO();
+
+ IR_INTConfig(IR_INT_RF_LEVEL | IR_INT_RX_CNT_THR, ENABLE);
+ IR_MaskINTConfig(IR_INT_RF_LEVEL | IR_INT_RX_CNT_THR, DISABLE);
+
+ /* Configure NVIC */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = IR_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 2;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/**
+ * @brief Enables or disables the specified interrupt.
+ * @param NewState: new state of the specified interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None.
+ */
+void int_ir_rx_config(FunctionalState state)
+{
+ if (state != DISABLE)
+ {
+ /* Enable interrupt */
+ IR_INTConfig(IR_INT_RF_LEVEL | IR_INT_RX_CNT_THR, ENABLE);
+ }
+ else
+ {
+ /* Disable interrupt */
+ IR_INTConfig(IR_INT_RF_LEVEL | IR_INT_RX_CNT_THR, DISABLE);
+ }
+}
+
+/**
+ * @brief Register callback function to send events from IR learn interrupt handle to application layer.
+ * @param pFunc: callback function.
+ * @return void
+ */
+void ir_rx_handler_cb(pFn_IR_RX_Handler_CB_t pFunc)
+{
+ pFn_IR_RX_Handler_CB = pFunc;
+}
+
+/**
+ * @brief IR interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void IR_RX_Handler(void)
+{
+ uint16_t data_len = 0;
+ uint8_t ir_learn_end_flag = false;
+ ITStatus int_status_rfl = IR_GetINTStatus(IR_INT_RF_LEVEL);
+ ITStatus int_status_rxcnt = IR_GetINTStatus(IR_INT_RX_CNT_THR);
+
+ /* Mask IR all interrupt */
+ IR_MaskINTConfig(IR_INT_RF_LEVEL | IR_INT_RX_CNT_THR, ENABLE);
+
+ /* Received interrupt */
+ if (int_status_rfl == SET)
+ {
+ data_len = IR_GetRxDataLen();
+ ir_loop_queue_data_in(&IR_RX_Queue, data_len);
+ IR_ClearINTPendingBit(IR_INT_RF_LEVEL_CLR);
+ }
+
+ /* Stop to receive IR data */
+ if (int_status_rxcnt == SET)
+ {
+ /* Read remaining data */
+ data_len = IR_GetRxDataLen();
+ ir_loop_queue_data_in(&IR_RX_Queue, data_len);
+ IR_ClearINTPendingBit(IR_INT_RX_CNT_THR_CLR);
+
+ /* Send ir learn end signal. */
+ //Add application code here
+ ir_learn_end_flag = true;
+ }
+
+ if (pFn_IR_RX_Handler_CB)
+ {
+ pFn_IR_RX_Handler_CB(ir_learn_end_flag);
+ }
+
+ /* Unmask IR all interrupt */
+ IR_MaskINTConfig(IR_INT_RF_LEVEL | IR_INT_RX_CNT_THR, DISABLE);
+
+}
+
+#endif
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/Learn/trans/ir_driver_rx.h b/src/sample/io_sample/IR/Learn/trans/ir_driver_rx.h
new file mode 100644
index 0000000..edb9610
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/trans/ir_driver_rx.h
@@ -0,0 +1,64 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ir_driver_rx.h
+* @brief
+* @details
+* @author yuan
+* @date 2019-01-23
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __IR_DRIVER_RX_H
+#define __IR_DRIVER_RX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+
+#include "rtl876x_ir.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+
+#include "board.h"
+
+#include "trace.h"
+
+#include "app_msg.h"
+
+#include "ir_learn_config.h"
+
+
+/** @defgroup pFn_IR_RX_Handler_CB
+ * @brief Function pointer type used by IR learn interrupt handle to general callback and send events to application.
+ * @{
+ */
+typedef void (*pFn_IR_RX_Handler_CB_t)(uint8_t vFlag);
+/**
+ * @} End of pFn_IR_RX_Handler_CB
+ */
+extern pFn_IR_RX_Handler_CB_t pFn_IR_RX_Handler_CB;
+
+
+void board_ir_rx_init(void);
+void driver_ir_rx_init(void);
+void int_ir_rx_config(FunctionalState state);
+void ir_rx_handler_cb(pFn_IR_RX_Handler_CB_t pFunc);
+void IR_Handler(void);
+void IR_RX_Handler(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__IR_DRIVER_RX_H*/
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/Learn/trans/ir_rx_loop_queue.c b/src/sample/io_sample/IR/Learn/trans/ir_rx_loop_queue.c
new file mode 100644
index 0000000..6a06677
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/trans/ir_rx_loop_queue.c
@@ -0,0 +1,234 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_rx_loop_queue.c
+* @brief
+* @details
+* @author yuan
+* @date 2019-01-23
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_rx_loop_queue.h"
+
+#if (IR_FUN_EN && IR_FUN_LEARN_EN)
+
+/* Globals ------------------------------------------------------------------ */
+/* Loop queue management data structure */
+IR_LoopQueue_TypeDef IR_RX_Queue;
+
+
+/* Functions ------------------------------------------------------------------*/
+
+/**
+ * @brief Initializes loop queue to their default reset values.
+ * @param pPacket: point to loop queue data structure.
+ * @retval None
+ */
+void ir_loop_queue_init(IR_LoopQueue_TypeDef *pLoopQueue)
+{
+ memset(pLoopQueue, 0, sizeof(IR_LoopQueue_TypeDef));
+}
+
+/**
+ * @brief check loop queue if will full or not.
+ * @param pLoopQueue: point to loop queue dta struct.
+ * @retval The new state of loop queue (full:TRUE, not full:FALSE).
+ */
+bool ir_loop_queue_is_full(IR_LoopQueue_TypeDef *pLoopQueue, uint16_t vLength)
+{
+ /* Check loop queue status */
+ if (pLoopQueue->InQueueIndex >= pLoopQueue->OutQueueIndex)
+ {
+ if ((pLoopQueue->InQueueIndex + vLength) >= (LOOP_QUEUE_BUF_SIZE_MAX + pLoopQueue->OutQueueIndex))
+ {
+ IR_RX_DBG_BUFFER(MODULE_APP, LEVEL_ERROR,
+ "[ir_trans_rx]loop_queue_is_full: Loop Queue is overflow!", 0);
+ pLoopQueue->IsOverFlow = true;
+ return true;
+ }
+ }
+ else
+ {
+ if ((pLoopQueue->InQueueIndex + vLength) >= pLoopQueue->OutQueueIndex)
+ {
+ IR_RX_DBG_BUFFER(MODULE_APP, LEVEL_ERROR,
+ "[ir_trans_rx]loop_queue_is_full: Loop Queue is overflow!", 0);
+ pLoopQueue->IsOverFlow = true;
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * @brief Check loop queue if empty or not.
+ * @param pLoopQueue: point to IR packet struct.
+ * @retval The new state of loop queue (empty:true, not empty:false).
+ */
+bool ir_loop_queue_is_empty(IR_LoopQueue_TypeDef *pLoopQueue)
+{
+ return ((pLoopQueue->InQueueIndex) == pLoopQueue->OutQueueIndex);
+}
+
+/**
+ * @brief Get valid data length.
+ * @param pLoopQueue:
+ * @retval valid data length
+ */
+uint16_t ir_loop_queue_get_data_len(IR_LoopQueue_TypeDef *pLoopQueue)
+{
+ return ((LOOP_QUEUE_BUF_SIZE_MAX + pLoopQueue->InQueueIndex - pLoopQueue->OutQueueIndex) &
+ LOOP_QUEUE_CAPABILITY);
+}
+
+/**
+ * @brief Write buffer data to loop queue.
+ * @param None.
+ * @retval None.
+ */
+void ir_loop_queue_data_in(IR_LoopQueue_TypeDef *pLoopQueue, uint8_t vLen)
+{
+ uint8_t tail_data_len = 0;
+
+ if (!ir_loop_queue_is_full(pLoopQueue, vLen))
+ {
+ if (pLoopQueue->InQueueIndex + vLen <= LOOP_QUEUE_BUF_SIZE_MAX)
+ {
+ IR_ReceiveBuf(&(pLoopQueue->LoopQueueBuf[pLoopQueue->InQueueIndex]), vLen);
+ pLoopQueue->InQueueIndex += vLen;
+ }
+ else
+ {
+ tail_data_len = LOOP_QUEUE_BUF_SIZE_MAX - pLoopQueue->InQueueIndex;
+ IR_ReceiveBuf(&(pLoopQueue->LoopQueueBuf[pLoopQueue->InQueueIndex]), tail_data_len);
+ pLoopQueue->InQueueIndex = 0;
+ IR_ReceiveBuf(&(pLoopQueue->LoopQueueBuf[pLoopQueue->InQueueIndex]), vLen - tail_data_len);
+ pLoopQueue->InQueueIndex += (vLen - tail_data_len);
+ }
+ pLoopQueue->InQueueIndex &= LOOP_QUEUE_CAPABILITY;
+ }
+ else
+ {
+ /* Discard data. Actually IR maximum rx FIFO is 32, vLen <= 32. */
+ uint8_t discard_data_len = 0;
+ uint32_t discard_buf[32];
+ while (vLen)
+ {
+ discard_data_len = (vLen > 32) ? 32 : vLen;
+ IR_ReceiveBuf(discard_buf, discard_data_len);
+ vLen -= discard_data_len;
+ }
+ IR_RX_DBG_BUFFER(MODULE_APP, LEVEL_INFO, "[ir_trans_rx]loop_queue_data_in: Discard bytes = %d!",
+ 1, vLen);
+ }
+}
+
+/**
+ * @brief Read data from loop queue.
+ * @param None.
+ * @retval None.
+ */
+void ir_loop_queue_data_out(IR_LoopQueue_TypeDef *pLoopQueue, uint32_t *pBuf, uint16_t vLen)
+{
+ uint16_t remain_data_len = 0;
+ uint16_t temp = 0;
+
+ /* Check parameters */
+ if ((vLen == 0) || (pBuf == NULL))
+ {
+ return;
+ }
+
+ if (pLoopQueue->InQueueIndex + vLen <= LOOP_QUEUE_BUF_SIZE_MAX)
+ {
+#ifdef LOOP_QUEUE_USE_MEMCPY_FUNCTION
+ memcpy(pBuf, &(pLoopQueue->LoopQueueBuf[pLoopQueue->OutQueueIndex]), vLen * sizeof(uint32_t));
+ pLoopQueue->OutQueueIndex += vLen;
+#else
+ while (vLen--)
+ {
+ *pBuf++ = pLoopQueue->LoopQueueBuf[pLoopQueue->OutQueueIndex++];
+ }
+#endif
+ }
+ else
+ {
+#ifdef LOOP_QUEUE_USE_MEMCPY_FUNCTION
+ remain_data_len = LOOP_QUEUE_BUF_SIZE_MAX - pLoopQueue->OutQueueIndex;
+ memcpy(pBuf, &(pLoopQueue->LoopQueueBuf[pLoopQueue->OutQueueIndex]),
+ remain_data_len * sizeof(uint32_t));
+ pLoopQueue->OutQueueIndex = 0;
+ memcpy(pBuf + remain_data_len, &(pLoopQueue->LoopQueueBuf[pLoopQueue->OutQueueIndex]),
+ (vLen - remain_data_len)*sizeof(uint32_t));
+#else
+ remain_data_len = LOOP_QUEUE_BUF_SIZE_MAX - pLoopQueue->OutQueueIndex;
+ temp = remain_data_len;
+ while (temp--)
+ {
+ *pBuf++ = pLoopQueue->LoopQueueBuf[pLoopQueue->OutQueueIndex++];
+ }
+ pLoopQueue->OutQueueIndex = 0;
+ temp = vLen - remain_data_len;
+ while (temp--)
+ {
+ *pBuf++ = pLoopQueue->LoopQueueBuf[pLoopQueue->OutQueueIndex++];
+ }
+
+#endif
+ }
+ temp += 0;
+ pLoopQueue->OutQueueIndex &= LOOP_QUEUE_CAPABILITY;
+}
+
+/**
+ * @brief Copy data from loop queue.
+ * @param None.
+ * @retval None.
+ */
+void ir_loop_queue_data_copy(IR_LoopQueue_TypeDef *pLoopQueue, uint32_t *pBuf, uint16_t vLen)
+{
+ uint16_t remain_data_len = 0;
+ uint16_t index = 0;
+
+ /* Check parameters */
+ if ((vLen == 0) || (pBuf == NULL))
+ {
+ return;
+ }
+
+ if (pLoopQueue->OutQueueIndex + vLen <= LOOP_QUEUE_BUF_SIZE_MAX)
+ {
+ index = 0;
+ while (vLen--)
+ {
+ *pBuf++ = pLoopQueue->LoopQueueBuf[pLoopQueue->OutQueueIndex + index];
+ index++;
+ }
+ }
+ else
+ {
+ remain_data_len = LOOP_QUEUE_BUF_SIZE_MAX - pLoopQueue->OutQueueIndex;
+ uint16_t i = remain_data_len;
+ index = 0;
+ while (i--)
+ {
+ *pBuf++ = pLoopQueue->LoopQueueBuf[pLoopQueue->OutQueueIndex + index];
+ index++;
+ }
+
+ i = vLen - remain_data_len;
+ index = 0;
+ while (i--)
+ {
+ *pBuf++ = pLoopQueue->LoopQueueBuf[index++];
+ }
+ }
+}
+
+#endif
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/IR/Learn/trans/ir_rx_loop_queue.h b/src/sample/io_sample/IR/Learn/trans/ir_rx_loop_queue.h
new file mode 100644
index 0000000..f4050e5
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/trans/ir_rx_loop_queue.h
@@ -0,0 +1,76 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ir_rx_loop_queue.h
+* @brief ir rx data loop queue
+* @details
+* @author yuan
+* @date 2019-01-23
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __IR_RX_LOOP_QUEUE_H
+#define __IR_RX_LOOP_QUEUE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "board.h"
+
+
+#if (IR_FUN_EN && IR_FUN_LEARN_EN)
+#include <string.h>
+
+#include "rtl876x_ir.h"
+
+#include "trace.h"
+
+/* Defines ------------------------------------------------------------------*/
+#ifdef IR_RX_PRINT_LOG
+#define IR_RX_DBG_BUFFER(module, level, fmt, param_num,...) \
+ DBG_BUFFER_##level(TYPE_BUMBLEBEE3, SUBTYPE_FORMAT, module, fmt, param_num, ##__VA_ARGS__)
+#else
+#define IR_RX_DBG_BUFFER(MODULE, LEVEL, pFormat, para_num,...) ((void)0)
+#endif
+
+/**
+ * @brief IR loop queue parameters
+ */
+#define LOOP_QUEUE_USE_MEMCPY_FUNCTION 0
+
+#define LOOP_QUEUE_BUF_SIZE_MAX (1024)
+#define LOOP_QUEUE_CAPABILITY (LOOP_QUEUE_BUF_SIZE_MAX-1)
+
+typedef struct
+{
+ volatile uint16_t InQueueIndex; /* index of in queue */
+ volatile uint16_t OutQueueIndex; /* index of out queue */
+ uint32_t LoopQueueBuf[LOOP_QUEUE_BUF_SIZE_MAX];
+ bool IsOverFlow;
+} IR_LoopQueue_TypeDef;
+
+extern IR_LoopQueue_TypeDef IR_RX_Queue;
+
+void ir_loop_queue_init(IR_LoopQueue_TypeDef *pLoopQueue);
+bool ir_loop_queue_is_full(IR_LoopQueue_TypeDef *pLoopQueue, uint16_t vLength);
+bool ir_loop_queue_is_empty(IR_LoopQueue_TypeDef *pLoopQueue);
+uint16_t ir_loop_queue_get_data_len(IR_LoopQueue_TypeDef *pLoopQueue);
+void ir_loop_queue_data_in(IR_LoopQueue_TypeDef *pLoopQueue, uint8_t vLen);
+void ir_loop_queue_data_out(IR_LoopQueue_TypeDef *pLoopQueue, uint32_t *pBuf, uint16_t vLen);
+void ir_loop_queue_data_copy(IR_LoopQueue_TypeDef *pLoopQueue, uint32_t *pBuf, uint16_t vLen);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __IR_RX_LOOP_QUEUE_H */
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/Learn/trans/ir_trans_rx.c b/src/sample/io_sample/IR/Learn/trans/ir_trans_rx.c
new file mode 100644
index 0000000..4f90a2b
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/trans/ir_trans_rx.c
@@ -0,0 +1,153 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_trans_rx.c
+* @brief
+* @details
+* @author yuan
+* @date 2019-01-23
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_trans_rx.h"
+
+#if (IR_FUN_EN && IR_FUN_LEARN_EN)
+
+/**
+ * @brief Deinitializes data transmission layer.
+ * @param None.
+ * @retval None
+ */
+void ir_trans_rx_deinit(void)
+{
+ /* Initialize loop queue */
+ ir_loop_queue_init(&IR_RX_Queue);
+
+ /* Close IR peripheral */
+ IR_Cmd(IR_MODE_RX, DISABLE);
+
+ /* Modify IR interrupt handle */
+ RamVectorTableUpdate(IR_VECTORn, IR_Handler);
+}
+
+/**
+ * @brief Initializes data transmission layer.
+ * @param None.
+ * @retval None
+ */
+void ir_trans_rx_init(void)
+{
+ /* Initialize loop queue */
+ ir_loop_queue_init(&IR_RX_Queue);
+
+ /* Modify IR interrupt handle */
+ RamVectorTableUpdate(IR_VECTORn, IR_RX_Handler);
+
+ /* Initialize IR peripheral */
+ driver_ir_rx_init();
+}
+
+/**
+ * @brief Initializes loop queue.
+ * @param None
+ * @retval None
+ */
+void ir_trans_rx_queue_init(void)
+{
+ ir_loop_queue_init(&IR_RX_Queue);
+}
+
+/**
+ * @brief Check loop queue is empty or not.
+ * @param None.
+ * @retval status of loop queue.:
+ TRUE: loop queue is empty.
+ FALSE: loop queue is not empty.
+ */
+bool ir_trans_rx_queue_is_empty(void)
+{
+ return ir_loop_queue_is_empty(&IR_RX_Queue);
+}
+
+/**
+ * @brief Get valid data length.
+ * @param None.
+ * @retval loop queue length
+ */
+uint16_t ir_trans_rx_get_data_len(void)
+{
+ return ir_loop_queue_get_data_len(&IR_RX_Queue);
+}
+
+/**
+ * @brief Read data from loop queue.
+ * @param pBuf: point to address of buffer.
+ * @param vLen: data length.
+ * @retval None.
+ */
+void ir_trans_rx_read_data(uint32_t *pBuf, uint16_t vLen)
+{
+ ir_loop_queue_data_out(&IR_RX_Queue, pBuf, vLen);
+}
+
+/**
+ * @brief copy data from loop queue.
+ * @param pBuf: point to address of buffer.
+ * @param vLen: data length.
+ * @retval None.
+ */
+void ir_trans_rx_copy_data(uint32_t *pBuf, uint16_t vLen)
+{
+ ir_loop_queue_data_copy(&IR_RX_Queue, pBuf, vLen);
+}
+
+/**
+ * @brief Find special data in loop queue.
+ * @param vData: Find data.
+ * @param vLen: data length in loop queue.
+ * @retval actual data position in loop queue.
+ */
+uint16_t ir_trans_rx_find_data_pos(uint32_t vData, uint16_t vLen)
+{
+ uint16_t pos = IR_RX_Queue.OutQueueIndex;
+
+ while (vLen--)
+ {
+ pos &= LOOP_QUEUE_CAPABILITY;
+
+ if (vData == IR_RX_Queue.LoopQueueBuf[pos++])
+ {
+ return (pos + LOOP_QUEUE_BUF_SIZE_MAX - IR_RX_Queue.OutQueueIndex) & LOOP_QUEUE_CAPABILITY;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Enables or disables the specified interrupt.
+ * @param NewState: new state of the specified interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None.
+ */
+void ir_trans_rx_int_config(FunctionalState state)
+{
+ int_ir_rx_config(state);
+}
+
+/**
+ * @brief Register callback function to send events from IR learn interrupt handle to application layer.
+ * @param pFunc: callback function.
+ * @return void
+*/
+void ir_trans_rx_handler_cb(pFn_IR_RX_Handler_CB_t pFunc)
+{
+ ir_rx_handler_cb(pFunc);
+}
+
+#endif
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/IR/Learn/trans/ir_trans_rx.h b/src/sample/io_sample/IR/Learn/trans/ir_trans_rx.h
new file mode 100644
index 0000000..cdb54a0
--- /dev/null
+++ b/src/sample/io_sample/IR/Learn/trans/ir_trans_rx.h
@@ -0,0 +1,43 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ir_trans_rx.h
+* @brief data transmission layer driver
+* @details
+* @author yuan
+* @date 2019-01-23
+* @version v1.0
+* *********************************************************************************************************
+*/
+#ifndef __IR_TRANS_RX_H
+#define __IR_TRANS_RX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_driver_rx.h"
+#include "ir_rx_loop_queue.h"
+
+
+void ir_trans_rx_deinit(void);
+void ir_trans_rx_init(void);
+void ir_trans_rx_queue_init(void);
+bool ir_trans_rx_queue_is_empty(void);
+uint16_t ir_trans_rx_get_data_len(void);
+void ir_trans_rx_read_data(uint32_t *pBuf, uint16_t vLen);
+void ir_trans_rx_copy_data(uint32_t *pBuf, uint16_t vLen);
+uint16_t ir_trans_rx_find_data_pos(uint32_t vData, uint16_t vLen);
+void ir_trans_rx_int_config(FunctionalState state);
+void ir_trans_rx_handler_cb(pFn_IR_RX_Handler_CB_t pFunc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__IR_TRANS_RX_H*/
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/Rx+GDMA/main.c b/src/sample/io_sample/IR/Rx+GDMA/main.c
new file mode 100644
index 0000000..e6dc229
--- /dev/null
+++ b/src/sample/io_sample/IR/Rx+GDMA/main.c
@@ -0,0 +1,233 @@
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include <stdlib.h>
+#include "rtl876x_gdma.h"
+#include "rtl876x_ir.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_tim.h"
+#include "trace.h"
+
+
+
+#define IR_RX_PIN P2_5
+#define IR_RX_FIFO_THR_LEVEL 30
+#define IR_DATA_SIZE_MAX 80
+#define IO_TEST_GDMA_TRANSFER_SIZE IR_DATA_SIZE_MAX
+
+#define PWM_OUT_PIN P2_6//Used for IR sampling output, for debug
+#define PWM_OUT_PINMUX TIM_PWM5
+#define PWM_TIMER_NUM TIM5
+#define PWM_HIGH_COUNT (20000 - 1)
+#define PWM_LOW_COUNT (20000 - 1)
+
+#define IO_TEST_GDMA_CHANNEL_MUM 1
+
+#if (IO_TEST_GDMA_CHANNEL_MUM == 0)
+#define IO_TEST_GDMA_Channel GDMA_Channel0
+#define IO_TEST_GDMA_Channel_IRQn GDMA0_Channel0_IRQn
+#define IO_TEST_GDMA_Channel_Handler GDMA0_Channel0_Handler
+#elif IO_TEST_GDMA_CHANNEL_MUM == 1
+#define IO_TEST_GDMA_Channel GDMA_Channel1
+#define IO_TEST_GDMA_Channel_IRQn GDMA0_Channel1_IRQn
+#define IO_TEST_GDMA_Channel_Handler GDMA0_Channel1_Handler
+#elif IO_TEST_GDMA_CHANNEL_MUM == 2
+#define IO_TEST_GDMA_Channel GDMA_Channel2
+#define IO_TEST_GDMA_Channel_IRQn GDMA0_Channel2_IRQn
+#define IO_TEST_GDMA_Channel_Handler GDMA0_Channel2_Handler
+#elif IO_TEST_GDMA_CHANNEL_MUM == 3
+#define IO_TEST_GDMA_Channel GDMA_Channel3
+#define IO_TEST_GDMA_Channel_IRQn GDMA0_Channel3_IRQn
+#define IO_TEST_GDMA_Channel_Handler GDMA0_Channel3_Handler
+#elif IO_TEST_GDMA_CHANNEL_MUM == 4
+#endif
+
+/* Globals ------------------------------------------------------------------*/
+uint32_t GDMA_Recv_Buf[4095];
+uint16_t IR_GDMA_Rev_Data_Len = 0;
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_pwm_init(void)
+{
+ Pad_Config(PWM_OUT_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ /* Normal mode */
+ Pinmux_Config(PWM_OUT_PIN, PWM_OUT_PINMUX);
+}
+
+/**
+ * @brief Initialize tim peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_pwm_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+
+ TIM_TimeBaseInitTypeDef TIM_InitStruct;
+ TIM_StructInit(&TIM_InitStruct);
+
+ TIM_InitStruct.TIM_PWM_En = PWM_ENABLE;
+ TIM_InitStruct.TIM_PWM_High_Count = PWM_HIGH_COUNT;
+ TIM_InitStruct.TIM_PWM_Low_Count = PWM_LOW_COUNT;
+ TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ TIM_TimeBaseInit(PWM_TIMER_NUM, &TIM_InitStruct);
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_ir_init(void)
+{
+ Pad_Config(IR_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
+ Pad_PullConfigValue(IR_RX_PIN, PAD_STRONG_PULL);
+
+ Pinmux_Config(IR_RX_PIN, IRDA_RX);
+}
+
+/**
+ * @brief Initialize ir peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_ir_init(void)
+{
+ /* Enable IR clock */
+ RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, ENABLE);
+// RCC_IRClockConfig(ENABLE);
+
+ /* Initialize IR */
+ IR_InitTypeDef IR_InitStruct;
+ IR_StructInit(&IR_InitStruct);
+
+ IR_InitStruct.IR_Clock = IR_CLOCK_40M;
+ IR_InitStruct.IR_Freq = 40000000;
+ IR_InitStruct.IR_Mode = IR_MODE_RX;
+ IR_InitStruct.IR_RxStartMode = IR_RX_AUTO_MODE;
+ IR_InitStruct.IR_RxFIFOThrLevel = IR_RX_FIFO_THR_LEVEL;
+ IR_InitStruct.IR_RxFIFOFullCtrl = IR_RX_FIFO_FULL_DISCARD_NEWEST;
+ IR_InitStruct.IR_RxFilterTime = IR_RX_FILTER_TIME_50ns;
+ IR_InitStruct.IR_RxTriggerMode = IR_RX_FALL_EDGE;
+ IR_InitStruct.IR_RxCntThrType = IR_RX_Count_High_Level;
+ IR_InitStruct.IR_RxCntThr = 0x0ED8;
+ IR_InitStruct.IR_RxDmaEn = ENABLE;
+ IR_InitStruct.IR_RxWaterLevel = 4;
+
+ IR_Init(&IR_InitStruct);
+ IR_Cmd(IR_MODE_RX, ENABLE);
+ IR_ClearRxFIFO();
+}
+
+/**
+ * @brief Initialize GDMA peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_ir_gdma_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+ GDMA_InitTypeDef GDMA_InitStruct;
+
+ memset(GDMA_Recv_Buf, 0, sizeof(GDMA_Recv_Buf));
+
+ /*--------------GDMA init-----------------------------*/
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = IO_TEST_GDMA_CHANNEL_MUM;
+ GDMA_InitStruct.GDMA_BufferSize = IO_TEST_GDMA_TRANSFER_SIZE;//determine total transfer size
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToMemory;//GDMA_DIR_PeripheralToMemory
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Inc;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)(&IR->RX_FIFO);
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(GDMA_Recv_Buf);
+ GDMA_InitStruct.GDMA_SourceHandshake = GDMA_Handshake_IR_RX;
+ GDMA_Init(IO_TEST_GDMA_Channel, &GDMA_InitStruct);
+
+ GDMA_INTConfig(IO_TEST_GDMA_CHANNEL_MUM, GDMA_INT_Transfer, ENABLE);
+
+ /*-----------------GDMA IRQ init-------------------*/
+ NVIC_InitTypeDef nvic_init_struct;
+ nvic_init_struct.NVIC_IRQChannel = IO_TEST_GDMA_Channel_IRQn;
+ nvic_init_struct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ nvic_init_struct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&nvic_init_struct);
+
+ GDMA_Cmd(IO_TEST_GDMA_CHANNEL_MUM, ENABLE);
+}
+
+/**
+ * @brief Handle gdma data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_gdma_msg(void)
+{
+ DBG_DIRECT("io_handle_gdma_msg: IR_GDMA_Rev_Data_Len = %d \r\n", IR_GDMA_Rev_Data_Len);
+ for (uint32_t i = 0; i < IR_GDMA_Rev_Data_Len; i++)
+ {
+ DBG_DIRECT("io_handle_gdma_msg: GDMA_Recv_Buf[%d] = 0x%x \r\n", i, GDMA_Recv_Buf[i]);
+ }
+}
+
+/**
+ * @brief Demo code of ir send data.
+ * @param No parameter.
+ * @return Void
+*/
+void ir_demo(void)
+{
+ board_pwm_init();
+ driver_pwm_init();
+ TIM_Cmd(PWM_TIMER_NUM, ENABLE);
+ board_ir_init();
+ driver_ir_init();
+ driver_ir_gdma_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+*/
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+
+ ir_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+
+ }
+}
+
+/**
+ * @brief GDMA channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void IO_TEST_GDMA_Channel_Handler(void)
+{
+ GDMA_INTConfig(IO_TEST_GDMA_CHANNEL_MUM, GDMA_INT_Transfer, DISABLE);
+ GDMA_Cmd(IO_TEST_GDMA_CHANNEL_MUM, DISABLE);
+ IR_GDMA_Rev_Data_Len = IO_TEST_GDMA_TRANSFER_SIZE;
+ io_handle_gdma_msg();
+ GDMA_ClearINTPendingBit(IO_TEST_GDMA_CHANNEL_MUM, GDMA_INT_Transfer);
+}
diff --git a/src/sample/io_sample/IR/Rx/ble_peripheral/ancs.c b/src/sample/io_sample/IR/Rx/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/IR/Rx/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/IR/Rx/ble_peripheral/ancs.h b/src/sample/io_sample/IR/Rx/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/IR/Rx/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/IR/Rx/ble_peripheral/app.c b/src/sample/io_sample/IR/Rx/ble_peripheral/app.c
new file mode 100644
index 0000000..63ce766
--- /dev/null
+++ b/src/sample/io_sample/IR/Rx/ble_peripheral/app.c
@@ -0,0 +1,610 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_ir.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_IR:
+ {
+ APP_PRINT_INFO0("[app]app_handle_io_msg: ir msg.");
+ io_handle_ir_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ ir_demo();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/IR/Rx/ble_peripheral/app.h b/src/sample/io_sample/IR/Rx/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/IR/Rx/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/IR/Rx/ble_peripheral/app_flags.h b/src/sample/io_sample/IR/Rx/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..4cfe1d8
--- /dev/null
+++ b/src/sample/io_sample/IR/Rx/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/IR/Rx/ble_peripheral/app_task.c b/src/sample/io_sample/IR/Rx/ble_peripheral/app_task.c
new file mode 100644
index 0000000..0d2bbb9
--- /dev/null
+++ b/src/sample/io_sample/IR/Rx/ble_peripheral/app_task.c
@@ -0,0 +1,124 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/IR/Rx/ble_peripheral/app_task.h b/src/sample/io_sample/IR/Rx/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/IR/Rx/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/IR/Rx/ble_peripheral/main.c b/src/sample/io_sample/IR/Rx/ble_peripheral/main.c
new file mode 100644
index 0000000..fa449d0
--- /dev/null
+++ b/src/sample/io_sample/IR/Rx/ble_peripheral/main.c
@@ -0,0 +1,248 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdlib.h>
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+//#include "app_timer.h"
+
+#include "io_ir.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+ global_data_ir_init();
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_ir_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_ir_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+// sw_timer_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/IR/Rx/ble_peripheral/maincc.c b/src/sample/io_sample/IR/Rx/ble_peripheral/maincc.c
new file mode 100644
index 0000000..e652f57
--- /dev/null
+++ b/src/sample/io_sample/IR/Rx/ble_peripheral/maincc.c
@@ -0,0 +1,249 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdlib.h>
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+//#include "app_timer.h"
+#include "app_flags.h"
+
+#include "io_ir.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+// global_data_adc_init();
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_ir_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_ir_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+// sw_timer_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/IR/Rx/io_ir.c b/src/sample/io_sample/IR/Rx/io_ir.c
new file mode 100644
index 0000000..43f69c6
--- /dev/null
+++ b/src/sample/io_sample/IR/Rx/io_ir.c
@@ -0,0 +1,167 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_ir.c
+* @brief This file provides demo code of ir.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_ir.h"
+
+#include "app_task.h"
+
+
+/* Globals ------------------------------------------------------------------*/
+IR_Data_TypeDef IR_Rx_Data;
+/* Number of data which has been sent */
+uint16_t IR_RX_Count = 0;
+
+/**
+ * @brief Initialization ir global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_ir_init(void)
+{
+ /* Initialize adc k value! */
+ APP_PRINT_INFO0("[io_ir]global_data_ir_init");
+ memset(&IR_Rx_Data, 0, sizeof(IR_Rx_Data));
+ IR_RX_Count = 0;
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_ir_init(void)
+{
+ Pad_Config(IR_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW);
+
+ Pinmux_Config(IR_RX_PIN, IRDA_RX);
+}
+
+
+/**
+ * @brief Initialize ir peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_ir_init(void)
+{
+ /* Enable IR clock */
+ RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, ENABLE);
+
+ /* Initialize IR */
+ IR_InitTypeDef IR_InitStruct;
+ IR_StructInit(&IR_InitStruct);
+
+ IR_InitStruct.IR_Freq = 38000;/* IR carrier freqency is 38KHz */
+ IR_InitStruct.IR_Mode = IR_MODE_RX;/* IR receiveing mode */
+ IR_InitStruct.IR_RxStartMode = IR_RX_AUTO_MODE;
+ IR_InitStruct.IR_RxFIFOThrLevel =
+ IR_RX_FIFO_THR_LEVEL; /* Configure RX FIFO threshold level to trigger IR_INT_RF_LEVEL interrupt */
+ IR_InitStruct.IR_RxFIFOFullCtrl =
+ IR_RX_FIFO_FULL_DISCARD_NEWEST;/* Discard the latest received dta if RX FIFO is full */
+ IR_InitStruct.IR_RxFilterTime =
+ IR_RX_FILTER_TIME_50ns;/* If high to low or low to high transition time <= 50ns,Filter out it. */
+ IR_InitStruct.IR_RxTriggerMode = IR_RX_FALL_EDGE;/* Configure trigger type */
+ IR_InitStruct.IR_RxCntThrType =
+ IR_RX_Count_High_Level;/* IR_RX_Count_High_Level is counting high level */
+ IR_InitStruct.IR_RxCntThr =
+ 0x1F40;/* Configure RX counter threshold.You can use it to decide to stop receiving IR data */
+ IR_Init(&IR_InitStruct);
+ IR_Cmd(IR_MODE_RX, ENABLE);
+ IR_ClearRxFIFO();
+
+ /* Configure NVIC */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = IR_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+}
+
+/**
+ * @brief Demo code of ir send data.
+ * @param No parameter.
+ * @return Void
+*/
+void ir_demo(void)
+{
+ /* Enable IR threshold interrupt. when RX FIFO offset >= threshold value, trigger interrupt*/
+ /* Enable IR counter threshold interrupt to stop receiving data */
+ IR_INTConfig(IR_INT_RF_LEVEL | IR_INT_RX_CNT_THR, ENABLE);
+ IR_MaskINTConfig(IR_INT_RF_LEVEL | IR_INT_RX_CNT_THR, DISABLE);
+}
+
+void io_handle_ir_msg(T_IO_MSG *io_ir_msg)
+{
+ IR_Data_TypeDef *p_buf = io_ir_msg->u.buf;
+ for (uint16_t i = 0; i < p_buf->DataLen; i++)
+ {
+ APP_PRINT_INFO2("[io_ir]io_handle_ir_msg: IR RX data[%d] = 0x%x", i, p_buf->DataBuf[i]);
+ }
+ memset(&IR_Rx_Data, 0, sizeof(IR_Rx_Data));
+ IR_RX_Count = 0;
+}
+
+/**
+ * @brief IR interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void IR_Handler(void)
+{
+ uint16_t len = 0;
+ ITStatus int_status_rfl = IR_GetINTStatus(IR_INT_RF_LEVEL);
+ ITStatus int_status_rxcnt = IR_GetINTStatus(IR_INT_RX_CNT_THR);
+
+ /* Mask IR all interrupt */
+ IR_MaskINTConfig(IR_INT_RF_LEVEL | IR_INT_RX_CNT_THR, ENABLE);
+
+ /* Receive by interrupt */
+ if (int_status_rfl == SET)
+ {
+ len = IR_GetRxDataLen();
+ IR_ReceiveBuf(IR_Rx_Data.DataBuf + IR_RX_Count, len);
+ IR_Rx_Data.DataLen += len;
+ IR_RX_Count += len;
+
+ IR_ClearINTPendingBit(IR_INT_RF_LEVEL_CLR);
+ }
+
+ /* Stop to receive IR data */
+ if (int_status_rxcnt == SET)
+ {
+ /* Read remaining data */
+ len = IR_GetRxDataLen();
+ IR_ReceiveBuf(IR_Rx_Data.DataBuf + IR_RX_Count, len);
+ IR_Rx_Data.DataLen += len;
+ IR_RX_Count += len;
+
+ T_IO_MSG int_ir_msg;
+ int_ir_msg.type = IO_MSG_TYPE_IR;
+ int_ir_msg.subtype = 0;
+ int_ir_msg.u.buf = (void *)(&IR_Rx_Data);
+ if (false == app_send_msg_to_apptask(&int_ir_msg))
+ {
+ APP_PRINT_ERROR0("[io_ir]IR_INT_RX_CNT_THR: Send int_ir_msg failed!");
+ //Add user code here!
+ IR_ClearINTPendingBit(IR_INT_RX_CNT_THR_CLR);
+ return;
+ }
+ IR_ClearINTPendingBit(IR_INT_RX_CNT_THR_CLR);
+ }
+
+ /* Unmask IR all interrupt */
+ IR_MaskINTConfig(IR_INT_RF_LEVEL | IR_INT_RX_CNT_THR, DISABLE);
+}
+
diff --git a/src/sample/io_sample/IR/Rx/io_ir.h b/src/sample/io_sample/IR/Rx/io_ir.h
new file mode 100644
index 0000000..5bd5faa
--- /dev/null
+++ b/src/sample/io_sample/IR/Rx/io_ir.h
@@ -0,0 +1,67 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_ir.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_IR_H
+#define __IO_IR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_ir.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+
+#include "board.h"
+
+#include "app_msg.h"
+
+
+/* Defines ------------------------------------------------------------------*/
+#define IR_DATA_SIZE_MAX 100
+
+#define IR_RX_FIFO_THR_LEVEL 30
+
+///** @brief IO subtype definitions for @ref IO_MSG_TYPE_IR type */
+//typedef enum
+//{
+// IO_MSG_IR_RX_RF_LEVEL,
+// IO_MSG_IR_RX_CNT_THR,
+//} T_IO_MSG_TYPE_IR;
+
+/**
+ * @brief IR data structure definition
+ */
+typedef struct
+{
+ /* Unit of carrierFreq is KHz */
+ uint8_t CarrierFreq;
+ uint32_t DataBuf[IR_DATA_SIZE_MAX];
+ uint16_t DataLen;
+} IR_Data_TypeDef;
+
+void global_data_ir_init(void);
+void board_ir_init(void);
+void driver_ir_init(void);
+void ir_demo(void);
+void io_handle_ir_msg(T_IO_MSG *io_ir_msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/IR/SendCode/ble_peripheral/ancs.c b/src/sample/io_sample/IR/SendCode/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/IR/SendCode/ble_peripheral/ancs.h b/src/sample/io_sample/IR/SendCode/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/IR/SendCode/ble_peripheral/app.c b/src/sample/io_sample/IR/SendCode/ble_peripheral/app.c
new file mode 100644
index 0000000..5482bf3
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/ble_peripheral/app.c
@@ -0,0 +1,633 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "ir_app.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+uint32_t ir_raw_data_buf[] =
+{
+ 9040, 4500,
+ 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560,
+ 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690,
+ 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560,
+ 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief IR app send msg process.
+ * @param uint16_t msg_sub_type.
+ * @return bool
+ */
+void ir_send_msg_proc(void)
+{
+ NEC_SendCode();
+ //Add application code here
+}
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_IR:
+ {
+// APP_PRINT_INFO0("[app]app_handle_io_msg: ir msg.");
+ if (io_msg.subtype == IO_MSG_TYPE_IR_SEND_COMPLETE)
+ {
+ ir_send_msg_proc();
+ }
+// io_handle_ir_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ IR_Raw_Packet_Send(ir_raw_data_buf, sizeof(ir_raw_data_buf) / sizeof(ir_raw_data_buf[0]));
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/IR/SendCode/ble_peripheral/app.h b/src/sample/io_sample/IR/SendCode/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/IR/SendCode/ble_peripheral/app_flags.h b/src/sample/io_sample/IR/SendCode/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..4cfe1d8
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/IR/SendCode/ble_peripheral/app_task.c b/src/sample/io_sample/IR/SendCode/ble_peripheral/app_task.c
new file mode 100644
index 0000000..013ac7b
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/ble_peripheral/app_task.c
@@ -0,0 +1,126 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+#include "ir_app.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ IR_Send_Init();
+
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/IR/SendCode/ble_peripheral/app_task.h b/src/sample/io_sample/IR/SendCode/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/IR/SendCode/ble_peripheral/main.c b/src/sample/io_sample/IR/SendCode/ble_peripheral/main.c
new file mode 100644
index 0000000..61e3012
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/ble_peripheral/main.c
@@ -0,0 +1,249 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdlib.h>
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+//#include "app_timer.h"
+
+#include "ir_app.h"
+#include "ir_led.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ Board_All_LED_Init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ Driver_All_LED_Init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+// sw_timer_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/IR/SendCode/config/ir_protocol_config.h b/src/sample/io_sample/IR/SendCode/config/ir_protocol_config.h
new file mode 100644
index 0000000..f8be215
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/config/ir_protocol_config.h
@@ -0,0 +1,205 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_protocol_config.h
+* @brief ir protocol configuration header file.
+* @details
+* @author elliot chen
+* @date 2017-08-15
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IR_PROTOCOL_CONFIG_H
+#define __IR_PROTOCOL_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stdint.h"
+#include "stdbool.h"
+
+/**
+ * @brief Configure protocol type which to be used
+ */
+#define RAW_PACK_PROT
+#define NEC_PROT
+#define RC5_PROT
+#define SONY6124_PROT
+#define LC7464M_PROT
+#define TC9012_PROT
+#define MITC8D8_PROT
+#define PIONEER_PROT
+#define VICTORC8D8_PROT
+#define DVB_PROT
+#define SHARP_PROT
+#define KONICA_PROT
+#define RAW_IR_PROT
+#define RC6_32B_PROT
+#define DVB_40BIT_PROT
+
+/**
+ * @brief Enable send two group data in one frame situation or not
+ */
+#define IR_ONE_FRAME_SEND_TWICE
+
+/**
+ * @brief IR send pin definition
+ */
+
+#define IR_SEND_PIN P2_5
+
+/**
+ * @brief IR_DataType definition
+ */
+
+typedef uint32_t IR_DataType;
+
+/**
+ * @brief Carrier waveform data type bit select
+ */
+
+//#define IR_PACK_TYPE ((uint32_t)15)
+
+/**
+ * @brief IR data mask
+ */
+
+#define IR_DATA_MSK (0x7fffffffUL)
+
+/**
+ * @brief Carrier waveform data type select
+ */
+
+#define IR_PULSE_HIGH ((uint32_t)0x80000000)
+
+
+/**
+ * @brief No carrier waveform data type select
+ */
+
+#define IR_PULSE_LOW (0x0)
+
+/**
+ * @brief Configure maximum length of user code and data code
+ */
+
+#define IR_MAX_CODE_SIZE 8
+
+/**
+ * @brief Configure maximum length of data sent by IR peripheral
+ */
+
+#define IR_MAX_BUF_SIZE 500
+
+
+/**
+ * @brief Configure maximum length of customer code
+ */
+
+#define MAX_CUSTOM_CODE_LEN 4
+
+#define MAX_CUSTOM_CODE_BIT_LEN (MAX_CUSTOM_CODE_LEN*8)
+
+/**
+ * @brief Configure maximum length of key code
+ */
+
+#define MAX_KEY_CODE_LEN 4
+
+#define MAX_KEY_CODE_BIT_LEN (MAX_KEY_CODE_LEN*8)
+
+
+/**
+ * @brief IR peripheral parameter definition
+ */
+
+//#define IR_TX_MAX_LEN (IR_TX_FIFO_SIZE - 1)
+#define IR_TX_FIFO_THR_LEVEL 2
+
+/**
+ * @brief TIM peripheral parameter definition
+ */
+
+#define IR_TIM TIM5
+#define IR_TIM_IRQ TIMER5_IRQ
+#define IR_TIMIntrHandler Timer5_Handler//Timer5IntrHandler
+
+/* brief: Configure maximum length of repeat code of IR protocol.
+ * note: MAX_REPEAT_CODE_LEN >= RepeatCodeLen!!!
+ * User can modify this define to adjust this driver to various application.
+ */
+#define IR_REPEAT_CODE_MAX_LEN 8
+
+/* brief Software avoidance.
+ */
+
+#define SOFTWARE_AVOIDANCE 1
+
+/* brief Hadware avoidance.
+ */
+
+#define HARDWARE_AVOIDANCE 1
+
+/* brief IR waveform interval time control.
+ */
+
+#define IR_WAVEFORM_INTERVAL_CTRL
+
+/**
+ * @brief IR return type of encoding function
+ */
+
+typedef enum
+{
+ IR_SUCCEED = 0,
+ IR_FREQENCY_ERROR = 1,
+ IR_HEARDE_TYPE_ERROR = 2,
+ IR_HEADER_DATA_ERROR = 3,
+ IR_DATA_TYPE_ERROR = 4,
+ IR_DATA_ERROR = 5
+} IR_Return_Type;
+
+/**
+ * @brief IR data structure definition
+ */
+
+typedef struct
+{
+ uint16_t carrierFreq;
+ uint8_t code[IR_MAX_CODE_SIZE];
+ uint8_t custom_bit_len;
+ uint8_t key_bit_len;
+ IR_DataType irBuf[IR_MAX_BUF_SIZE];
+ uint16_t bufLen;
+ volatile bool isSendRepeatcode;
+ bool isRepeatcodeEncoded;
+#ifdef IR_WAVEFORM_INTERVAL_CTRL
+ volatile bool intervalCtrl;
+ volatile bool isTimerOccurred;
+#endif
+} IR_DataTypeDef, *pIR_DataTypeDef;
+
+typedef IR_Return_Type(*IRProtocolEncodeFnCB)(pIR_DataTypeDef);
+
+typedef struct
+{
+ IRProtocolEncodeFnCB IREncodeFunCb;
+ IRProtocolEncodeFnCB IRRepeatCodeEncodeFunCb;
+ uint32_t carrierFreq;
+ uint32_t repeat_interval;
+} IR_ProtocolEncodeLib_t;
+
+#define ABS_TIME(a,b) ((a>b) ? (a-b):(b-a))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined (__IR_PROTOCOL_CONFIG_H) */
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/encode/ir_encode.c b/src/sample/io_sample/IR/SendCode/encode/ir_encode.c
new file mode 100644
index 0000000..e49f64b
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/encode/ir_encode.c
@@ -0,0 +1,226 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_encode.c
+* @brief This file provides driver of IR protocol encoding.
+* @details
+* @author elliot_chen
+* @date 2017-09-19
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_encode.h"
+
+
+/* Internal defines -------------------------------------------------------------------*/
+
+#define IR_ENCODE_BIT_LEN_TO_BYTE_LEN 7
+#define IR_ENCODE_BYTE_LEN 8
+#define IR_ENCODE_LOGICAL_1 (0x01)
+
+/**
+ * @brief unit convert.
+ * @param time: time of waveform.
+ * @param carrier_cycle: cycle of carrier.
+ * @retval vaule of data whose unit is cycle of carrier.
+ */
+IR_DataType ConvertToCarrierCycle(uint32_t time, uint32_t freq, IR_DATA_TYPE data_type)
+{
+ if (data_type == TIME_UNIT)
+ {
+#if HARDWARE_AVOIDANCE
+ return ((time & IR_PULSE_HIGH) | ((time & IR_DATA_MSK) * freq / 1000 - 1));
+#else
+ return ((time & IR_PULSE_HIGH) | ((time & IR_DATA_MSK) * freq / 1000));
+#endif
+ }
+ else
+ {
+#if HARDWARE_AVOIDANCE
+ return ((time & IR_PULSE_HIGH) | ((time & IR_DATA_MSK) - 1));
+#else
+ return time;
+#endif
+ }
+}
+
+/**
+ * @brief check specify bit value of data.
+ * @param a: data which want to check.
+ * @param bit_pos: position of bit which want to check
+ * @retval
+ */
+static uint8_t CheckBitStatus(uint32_t a, uint32_t bit_pos)
+{
+ return ((a >> bit_pos) & 0x1);
+}
+
+/**
+ * @brief Encode data to packet.
+ * @param IR_DataStruct: pointer to struct which store IR data code.
+ * @param IR_Protocol: pointer to specify IR protocol structure.
+ * @retval None
+ */
+IR_Return_Type IR_EncodeCode(IR_DataTypeDef *IR_DataStruct, IR_ProtocolTypeDef *IR_Protocol,
+ uint8_t index, uint8_t bitLen, uint8_t *pBufLen)
+{
+ uint8_t codeWidth = 0;
+ uint16_t i = 0;
+ uint16_t bitPos = 0;
+ IR_DataType Log1[IR_MAX_LOG_WAVFORM_SIZE];
+ IR_DataType Log0[IR_MAX_LOG_WAVFORM_SIZE];
+
+ for (i = 0; i < IR_MAX_LOG_WAVFORM_SIZE; i++)
+ {
+ Log1[i] = ConvertToCarrierCycle(IR_Protocol->log1Buf[i], IR_DataStruct->carrierFreq,
+ IR_Protocol->unit);
+ Log0[i] = ConvertToCarrierCycle(IR_Protocol->log0Buf[i], IR_DataStruct->carrierFreq,
+ IR_Protocol->unit);
+ }
+
+ for (; bitLen > 0; index++)
+ {
+ if (bitLen > IR_ENCODE_BYTE_LEN)
+ {
+ bitLen -= IR_ENCODE_BYTE_LEN;
+ codeWidth = IR_ENCODE_BYTE_LEN;
+ }
+ else
+ {
+ codeWidth = bitLen;
+ bitLen = 0;
+ }
+
+ if (IR_Protocol->coding_order == IR_CODING_LSB_FIRST)
+ {
+ for (bitPos = 0; bitPos < codeWidth; bitPos++)
+ {
+ if (CheckBitStatus(IR_DataStruct->code[index], bitPos) == IR_ENCODE_LOGICAL_1)
+ {
+ IR_DataStruct->irBuf[*pBufLen] = Log1[0];
+ IR_DataStruct->irBuf[*pBufLen + 1] = Log1[1];
+ }
+ else
+ {
+ IR_DataStruct->irBuf[*pBufLen] = Log0[0];
+ IR_DataStruct->irBuf[*pBufLen + 1] = Log0[1];
+ }
+ *pBufLen += IR_MAX_LOG_WAVFORM_SIZE;
+ }
+ }
+ else
+ {
+ for (bitPos = codeWidth; bitPos > 0; bitPos--)
+ {
+ if (CheckBitStatus(IR_DataStruct->code[index], bitPos - 1) == IR_ENCODE_LOGICAL_1)
+ {
+ IR_DataStruct->irBuf[*pBufLen] = Log1[0];
+ IR_DataStruct->irBuf[*pBufLen + 1] = Log1[1];
+ }
+ else
+ {
+ IR_DataStruct->irBuf[*pBufLen] = Log0[0];
+ IR_DataStruct->irBuf[*pBufLen + 1] = Log0[1];
+ }
+ *pBufLen += IR_MAX_LOG_WAVFORM_SIZE;
+ }
+ }
+ }
+ return IR_SUCCEED;
+}
+
+/**
+ * @brief Encode data to packet.
+ * @param IR_DataStruct: pointer to struct which store IR data code.
+ * @param IR_Protocol: pointer to specify IR protocol structure.
+ * @param in_order: encoding order
+ * @retval None
+ */
+IR_Return_Type IR_Encode(IR_DataTypeDef *IR_DataStruct, IR_ProtocolTypeDef *IR_Protocol,
+ bool in_order)
+{
+ uint8_t custom_code_len = 0;
+ uint16_t index = 0;
+ uint8_t bufLen = IR_Protocol->headerLen;
+
+ /* Check parameters */
+ if (IR_DataStruct->carrierFreq != IR_Protocol->carrierFreq)
+ {
+ return IR_FREQENCY_ERROR;
+ }
+
+ /* Encoding header */
+ for (index = 0; index < IR_Protocol->headerLen; index++)
+ {
+ IR_DataStruct->irBuf[index] = ConvertToCarrierCycle(IR_Protocol->headerBuf[index], \
+ IR_DataStruct->carrierFreq, IR_Protocol->unit);
+ }
+
+ custom_code_len = (IR_DataStruct->custom_bit_len + IR_ENCODE_BIT_LEN_TO_BYTE_LEN) /
+ IR_ENCODE_BYTE_LEN;
+ if (in_order == true)
+ {
+ IR_EncodeCode(IR_DataStruct, IR_Protocol, 0, IR_DataStruct->custom_bit_len, &bufLen);
+ IR_EncodeCode(IR_DataStruct, IR_Protocol, custom_code_len, IR_DataStruct->key_bit_len, &bufLen);
+ }
+ else
+ {
+ IR_EncodeCode(IR_DataStruct, IR_Protocol, custom_code_len, IR_DataStruct->key_bit_len, &bufLen);
+ IR_EncodeCode(IR_DataStruct, IR_Protocol, 0, IR_DataStruct->custom_bit_len, &bufLen);
+ }
+
+ /* Encode stop code */
+ if (IR_Protocol->stopBuf != 0)
+ {
+ IR_DataStruct->irBuf[bufLen++] = ConvertToCarrierCycle(IR_Protocol->stopBuf, \
+ IR_DataStruct->carrierFreq, IR_Protocol->unit);
+ }
+
+#if SOFTWARE_AVOIDANCE
+ IR_DataStruct->irBuf[bufLen++] = 0;
+#endif
+
+ IR_DataStruct->bufLen = bufLen;
+
+ return IR_SUCCEED;
+}
+
+/**
+ * @brief Encode repeat code to packet.
+ * @param IR_DataStruct: pointer to struct which store repeat code data.
+ * @param IR_Protocol: pointer to specify IR protocol structure.
+ * @retval None
+ */
+IR_Return_Type IR_RepeatCodeEncode(IR_DataTypeDef *IR_DataStruct, IR_RepeatCodeTypeDef *IR_Protocol)
+{
+ uint16_t index = 0;
+
+ /* Error handle */
+ if (IR_DataStruct->carrierFreq == 0)
+ {
+ return IR_FREQENCY_ERROR;
+ }
+
+ /* Encode repeat code */
+ for (index = 0; index < IR_Protocol->RepeatCodeLen; index++)
+ {
+ IR_DataStruct->irBuf[index] = ConvertToCarrierCycle(IR_Protocol->RepeatCodeBuf[index],
+ IR_DataStruct->carrierFreq, IR_Protocol->unit);
+ }
+
+ IR_DataStruct->bufLen = IR_Protocol->RepeatCodeLen;
+
+#if SOFTWARE_AVOIDANCE
+ IR_DataStruct->irBuf[index] = 0;
+ IR_DataStruct->bufLen++;
+#endif
+
+ return IR_SUCCEED;
+}
+
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/encode/ir_encode.h b/src/sample/io_sample/IR/SendCode/encode/ir_encode.h
new file mode 100644
index 0000000..8da1f1e
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/encode/ir_encode.h
@@ -0,0 +1,98 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ir_encode.h
+* @brief This file provides driver of IR protocol encoding.
+* @details
+* @author elliot chen
+* @date 2017-09-19
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __IR_ENCODE_H
+#define __IR_ENCODE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_protocol_config.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/**
+ * @brief Configure maximum length of header of IR protocol
+ */
+
+#define IR_MAX_HEADDER_LEN 6
+
+/**
+ * @brief Configure maximum data length of logical 0 and logical 1
+ */
+
+#define IR_MAX_LOG_WAVFORM_SIZE 2
+
+/**
+ * @brief IR coding order type definition.
+ */
+
+typedef enum
+{
+ IR_CODING_LSB_FIRST,
+ IR_CODING_MSB_FIRST
+} IR_CODING_ORDER;
+
+/**
+ * @brief IR coding order type definition.
+ */
+
+typedef enum
+{
+ CARRIER_UNIT,
+ TIME_UNIT
+} IR_DATA_TYPE;
+
+/**
+ * @brief IR protocol structure definition
+ */
+typedef struct
+{
+ uint16_t carrierFreq;
+ IR_CODING_ORDER coding_order;
+ IR_DATA_TYPE unit;
+ uint8_t headerLen;
+ IR_DataType headerBuf[IR_MAX_HEADDER_LEN];
+ IR_DataType log0Buf[IR_MAX_LOG_WAVFORM_SIZE];
+ IR_DataType log1Buf[IR_MAX_LOG_WAVFORM_SIZE];
+ IR_DataType stopBuf;
+} IR_ProtocolTypeDef;
+
+/**
+ * @brief IR protocol structure definition which store IR repeat code.
+ */
+
+typedef struct
+{
+ IR_DATA_TYPE unit;
+ uint8_t RepeatCodeLen;
+ IR_DataType RepeatCodeBuf[IR_REPEAT_CODE_MAX_LEN];
+} IR_RepeatCodeTypeDef;
+
+/* Exported functions --------------------------------------------------------*/
+IR_Return_Type IR_Encode(IR_DataTypeDef *IR_DataStruct, IR_ProtocolTypeDef *IR_Protocol,
+ bool in_order);
+IR_Return_Type IR_RepeatCodeEncode(IR_DataTypeDef *IR_DataStruct,
+ IR_RepeatCodeTypeDef *IR_Protocol);
+IR_DataType ConvertToCarrierCycle(uint32_t time, uint32_t freq, IR_DATA_TYPE data_type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__IR_ENCODE_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/ir_app.c b/src/sample/io_sample/IR/SendCode/ir_app.c
new file mode 100644
index 0000000..6a9fa7e
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/ir_app.c
@@ -0,0 +1,782 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_send_app.c
+* @brief This file provides IR transmission application code.
+* @details
+* @author elliot chen
+* @date 2018-3-20
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_app.h"
+#include "ir_led.h"
+#include "platform_utils.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/* Globals -------------------------------------------------------------------*/
+UIR_PARAM_INFO uir_param_info;
+extern bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Callback function which send message from IR interrupt handle to app task.
+ * @param void.
+ * @return void.
+ */
+void sendMsgToAppTaskFromISR(void)
+{
+ T_IO_MSG bee_io_msg;
+ bee_io_msg.type = IO_MSG_TYPE_IR;
+
+ /*send ir learn data message to app*/
+ bee_io_msg.subtype = IO_MSG_TYPE_IR_SEND_COMPLETE;
+ app_send_msg_to_apptask(&bee_io_msg);
+}
+
+/**
+ * @brief IR send initialization.
+ * @param void.
+ * @return void.
+ */
+void IR_Send_Init(void)
+{
+ /* Initialize IR send module */
+ UIR_TransInit();
+
+ /* Register IR interrupt handle callback function */
+ UIR_RegisterIRIntrHandlerCB(sendMsgToAppTaskFromISR);
+}
+
+/**
+ * @brief Raw Packet send demo.
+ * @param void.
+ * @return void.
+ */
+void IR_Raw_Packet_Send(uint32_t *pBuf, uint32_t len)
+{
+ UIR_STATUS status;
+
+ memset(&uir_param_info, 0, sizeof(uir_param_info));
+ uir_param_info.uir_protocol_index = UIR_CODESET_TYPE_RAW_Pack;
+ uir_param_info.pRawPackAddr = pBuf;
+ uir_param_info.raw_pack_len = len;
+
+ status = UIR_OneFrameTransmitting(&uir_param_info, DISABLE);
+ if (UIR_STATUS_NO_ERROR == status)
+ {
+ LED_IR_Send_Swap();
+ }
+}
+
+/**
+ * @brief NEC send demo.
+ * @param void.
+ * @return void.
+ */
+void NEC_SendCode(void)
+{
+ UIR_STATUS status;
+
+ memset(&uir_param_info, 0, sizeof(uir_param_info));
+ uir_param_info.uir_protocol_index = UIR_CODESET_TYPE_NEC;
+ uir_param_info.custom_code_value[0] = 0x55;
+ uir_param_info.custom_code_value[1] = (uint8_t)(~(0x55));
+ uir_param_info.custom_code_length = 16;
+ uir_param_info.key_code_value[0] = 0xAA;
+ uir_param_info.key_code_value[1] = (uint8_t)(~(0xAA));
+ uir_param_info.key_code_length = 16;
+
+ UIR_OneFrameTransmitting(&uir_param_info, DISABLE);
+
+ platform_delay_ms(2000);
+
+ status = UIR_StartContinuouslyTransmitting(&uir_param_info);
+
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // Start IR send successfully
+ }
+ else
+ {
+ if (status == UIR_STATUS_INVALID_CODESET_TYPE)
+ {
+ // Invalid IR protocol type!
+ }
+ }
+
+ platform_delay_ms(2000);
+
+ status = UIR_StopContinuouslyTransmitting();
+
+ if (status == UIR_STATUS_ALREADY_IN_TRANSMITTING)
+ {
+ // IR is sending data, waiting for IR tx empty interrupt
+ // Add application code here
+ }
+ else
+ {
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // IR has stopped sending data
+ // Add application code here
+ }
+ }
+
+ platform_delay_ms(1000);
+}
+
+/**
+ * @brief RC5 send demo.
+ * @param void.
+ * @return void.
+ */
+void RC5_SendCode(void)
+{
+ UIR_STATUS status;
+
+ memset(&uir_param_info, 0, sizeof(uir_param_info));
+ uir_param_info.uir_protocol_index = UIR_CODESET_TYPE_RC5;
+ uir_param_info.custom_code_value[0] = 0x0A;
+ uir_param_info.custom_code_length = 5;
+ uir_param_info.key_code_value[0] = 0x3A | (0 << 6);
+ uir_param_info.key_code_length = 6;
+
+ status = UIR_StartContinuouslyTransmitting(&uir_param_info);
+
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // Start IR send successfully
+ }
+ else
+ {
+ if (status == UIR_STATUS_INVALID_CODESET_TYPE)
+ {
+ // Invalid IR protocol type!
+ }
+ }
+
+ platform_delay_ms(1000);
+
+ status = UIR_StopContinuouslyTransmitting();
+
+ if (status == UIR_STATUS_ALREADY_IN_TRANSMITTING)
+ {
+ // IR is sending data, waiting for IR tx empty interrupt
+ // Add application code here
+ }
+ else
+ {
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // IR has stopped sending data
+ // Add application code here
+ }
+ }
+
+ platform_delay_ms(1000);
+}
+
+/**
+ * @brief RC5 send demo.
+ * @param void.
+ * @return void.
+ */
+void RC6_SendCode(void)
+{
+ UIR_STATUS status;
+
+ memset(&uir_param_info, 0, sizeof(uir_param_info));
+ uir_param_info.uir_protocol_index = UIR_CODESET_TYPE_RC6_32B;
+ uir_param_info.custom_code_value[0] = 0x80;
+ uir_param_info.custom_code_value[1] = 0x10;
+ uir_param_info.custom_code_length = 16;
+ uir_param_info.key_code_value[0] = 0x26 | (0 << 7);
+ uir_param_info.key_code_value[1] = 0x0C;
+ uir_param_info.key_code_length = 16;
+
+ status = UIR_StartContinuouslyTransmitting(&uir_param_info);
+
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // Start IR send successfully
+ }
+ else
+ {
+ if (status == UIR_STATUS_INVALID_CODESET_TYPE)
+ {
+ // Invalid IR protocol type!
+ }
+ }
+
+ platform_delay_ms(1000);
+
+ status = UIR_StopContinuouslyTransmitting();
+
+ if (status == UIR_STATUS_ALREADY_IN_TRANSMITTING)
+ {
+ // IR is sending data, waiting for IR tx empty interrupt
+ // Add application code here
+ }
+ else
+ {
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // IR has stopped sending data
+ // Add application code here
+ }
+ }
+
+ platform_delay_ms(1000);
+}
+
+/**
+ * @brief SONY6124 send demo.
+ * @param void.
+ * @return void.
+ */
+void SONY6124_SendCode(void)
+{
+ UIR_STATUS status;
+
+ memset(&uir_param_info, 0, sizeof(uir_param_info));
+ uir_param_info.uir_protocol_index = UIR_CODESET_TYPE_6124;
+ uir_param_info.custom_code_value[0] = 0x2A;
+ uir_param_info.custom_code_length = 8;
+ uir_param_info.key_code_value[0] = 0x1A;
+ uir_param_info.key_code_length = 8;
+
+ status = UIR_StartContinuouslyTransmitting(&uir_param_info);
+
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // Start IR send successfully
+ }
+ else
+ {
+ if (status == UIR_STATUS_INVALID_CODESET_TYPE)
+ {
+ // Invalid IR protocol type!
+ }
+ }
+
+ platform_delay_ms(1000);
+
+ status = UIR_StopContinuouslyTransmitting();
+
+ if (status == UIR_STATUS_ALREADY_IN_TRANSMITTING)
+ {
+ // IR is sending data, waiting for IR tx empty interrupt
+ // Add application code here
+ }
+ else
+ {
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // IR has stopped sending data
+ // Add application code here
+ }
+ }
+
+ platform_delay_ms(1000);
+}
+
+/**
+ * @brief LC7464M send demo.
+ * @param void.
+ * @return void.
+ */
+void LC7464M_SendCode(void)
+{
+ UIR_STATUS status;
+
+ memset(&uir_param_info, 0, sizeof(uir_param_info));
+ uir_param_info.uir_protocol_index = UIR_CODESET_TYPE_LC7464M;
+ uir_param_info.custom_code_value[0] = 0x55;
+ uir_param_info.custom_code_length = 8;
+ uir_param_info.key_code_value[0] = 0xAA;
+ uir_param_info.key_code_length = 8;
+
+ status = UIR_StartContinuouslyTransmitting(&uir_param_info);
+
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // Start IR send successfully
+ }
+ else
+ {
+ if (status == UIR_STATUS_INVALID_CODESET_TYPE)
+ {
+ // Invalid IR protocol type!
+ }
+ }
+
+ platform_delay_ms(1000);
+
+ status = UIR_StopContinuouslyTransmitting();
+
+ if (status == UIR_STATUS_ALREADY_IN_TRANSMITTING)
+ {
+ // IR is sending data, waiting for IR tx empty interrupt
+ // Add application code here
+ }
+ else
+ {
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // IR has stopped sending data
+ // Add application code here
+ }
+ }
+
+ platform_delay_ms(1000);
+}
+
+/**
+ * @brief TC9012 send demo.
+ * @param void.
+ * @return void.
+ */
+void TC9012_SendCode(void)
+{
+ UIR_STATUS status;
+
+ memset(&uir_param_info, 0, sizeof(uir_param_info));
+ uir_param_info.uir_protocol_index = UIR_CODESET_TYPE_TC9012;
+ uir_param_info.custom_code_value[0] = 0x55;
+ uir_param_info.custom_code_value[1] = (uint8_t)~(0x55);
+ uir_param_info.custom_code_length = 16;
+ uir_param_info.key_code_value[0] = 0xAA;
+ uir_param_info.key_code_value[1] = (uint8_t)~(0xAA);
+ uir_param_info.key_code_length = 16;
+
+ status = UIR_StartContinuouslyTransmitting(&uir_param_info);
+
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // Start IR send successfully
+ }
+ else
+ {
+ if (status == UIR_STATUS_INVALID_CODESET_TYPE)
+ {
+ // Invalid IR protocol type!
+ }
+ }
+
+ platform_delay_ms(1000);
+
+ status = UIR_StopContinuouslyTransmitting();
+
+ if (status == UIR_STATUS_ALREADY_IN_TRANSMITTING)
+ {
+ // IR is sending data, waiting for IR tx empty interrupt
+ // Add application code here
+ }
+ else
+ {
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // IR has stopped sending data
+ // Add application code here
+ }
+ }
+
+ platform_delay_ms(1000);
+}
+
+/**
+ * @brief MITC8D8 send demo.
+ * @param void.
+ * @return void.
+ */
+void MITC8D8_SendCode(void)
+{
+ UIR_STATUS status;
+
+ memset(&uir_param_info, 0, sizeof(uir_param_info));
+ uir_param_info.uir_protocol_index = UIR_CODESET_TYPE_MIT_C8D8;
+ uir_param_info.custom_code_value[0] = 0x55;
+ uir_param_info.custom_code_length = 8;
+ uir_param_info.key_code_value[0] = 0xAA;
+ uir_param_info.key_code_length = 8;
+
+ status = UIR_StartContinuouslyTransmitting(&uir_param_info);
+
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // Start IR send successfully
+ }
+ else
+ {
+ if (status == UIR_STATUS_INVALID_CODESET_TYPE)
+ {
+ // Invalid IR protocol type!
+ }
+ }
+
+ platform_delay_ms(1000);
+
+ status = UIR_StopContinuouslyTransmitting();
+
+ if (status == UIR_STATUS_ALREADY_IN_TRANSMITTING)
+ {
+ // IR is sending data, waiting for IR tx empty interrupt
+ // Add application code here
+ }
+ else
+ {
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // IR has stopped sending data
+ // Add application code here
+ }
+ }
+
+ platform_delay_ms(1000);
+}
+
+/**
+ * @brief PIONEER send demo.
+ * @param void.
+ * @return void.
+ */
+void PIONEER_SendCode(void)
+{
+ UIR_STATUS status;
+
+ uint16_t custom = 0x55AA;
+ uint16_t data = 0xAA55;
+
+ memset(&uir_param_info, 0, sizeof(uir_param_info));
+ uir_param_info.uir_protocol_index = UIR_CODESET_TYPE_Pioneer;
+ uir_param_info.custom_code_value[0] = custom & 0xFF;
+ uir_param_info.custom_code_value[1] = (custom >> 8) & 0xFF;
+ uir_param_info.custom_code_length = 16;
+ uir_param_info.key_code_value[0] = data & 0xFF;
+ uir_param_info.key_code_value[1] = (data >> 8) & 0xFF;
+ uir_param_info.key_code_length = 16;
+ uir_param_info.is_second_code_valid = 1;
+ uir_param_info.second_custom_code_value[0] = data & 0xFF;
+ uir_param_info.second_custom_code_value[1] = (data >> 8) & 0xFF;
+ uir_param_info.second_custom_code_length = 16;
+ uir_param_info.second_key_code_value[0] = custom & 0xFF;
+ uir_param_info.second_key_code_value[1] = (custom >> 8) & 0xFF;
+ uir_param_info.second_key_code_length = 16;
+
+ status = UIR_StartContinuouslyTransmitting(&uir_param_info);
+
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // Start IR send successfully
+ }
+ else
+ {
+ if (status == UIR_STATUS_INVALID_CODESET_TYPE)
+ {
+ // Invalid IR protocol type!
+ }
+ }
+
+ platform_delay_ms(1000);
+
+ status = UIR_StopContinuouslyTransmitting();
+
+ if (status == UIR_STATUS_ALREADY_IN_TRANSMITTING)
+ {
+ // IR is sending data, waiting for IR tx empty interrupt
+ // Add application code here
+ }
+ else
+ {
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // IR has stopped sending data
+ // Add application code here
+ }
+ }
+
+ platform_delay_ms(1000);
+}
+
+/**
+ * @brief VICTORC8D8 send demo.
+ * @param void.
+ * @return void.
+ */
+void VICTORC8D8_SendCode(void)
+{
+ UIR_STATUS status;
+
+ uint8_t custom = 0x55;
+ uint8_t data = 0xAA;
+
+ memset(&uir_param_info, 0, sizeof(uir_param_info));
+ uir_param_info.uir_protocol_index = UIR_CODESET_TYPE_Victor_C8D8;
+ uir_param_info.custom_code_value[0] = custom;
+ uir_param_info.custom_code_length = 8;
+ uir_param_info.key_code_value[0] = data;
+ uir_param_info.key_code_length = 8;
+
+ status = UIR_StartContinuouslyTransmitting(&uir_param_info);
+
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // Start IR send successfully
+ }
+ else
+ {
+ if (status == UIR_STATUS_INVALID_CODESET_TYPE)
+ {
+ // Invalid IR protocol type!
+ }
+ }
+
+ platform_delay_ms(1000);
+
+ status = UIR_StopContinuouslyTransmitting();
+
+ if (status == UIR_STATUS_ALREADY_IN_TRANSMITTING)
+ {
+ // IR is sending data, waiting for IR tx empty interrupt
+ // Add application code here
+ }
+ else
+ {
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // IR has stopped sending data
+ // Add application code here
+ }
+ }
+
+ platform_delay_ms(1000);
+}
+
+/**
+ * @brief DVB send demo.
+ * @param void.
+ * @return void.
+ */
+void DVB_SendCode(void)
+{
+ UIR_STATUS status;
+
+ uint32_t custom = 0x12345678;
+ uint16_t data = 0x55AA;
+
+ memset(&uir_param_info, 0, sizeof(uir_param_info));
+ uir_param_info.uir_protocol_index = UIR_CODESET_TYPE_DVB;
+ uir_param_info.custom_code_value[0] = custom & 0xFF;
+ uir_param_info.custom_code_value[1] = (custom >> 8) & 0xFF;
+ uir_param_info.custom_code_value[2] = (custom >> 16) & 0xFF;
+ uir_param_info.custom_code_value[3] = (custom >> 24) & 0xFF;
+ uir_param_info.custom_code_length = 32;
+ uir_param_info.key_code_value[0] = data & 0xFF;
+ uir_param_info.key_code_value[1] = (data >> 8) & 0xFF;
+ uir_param_info.key_code_length = 16;
+
+ status = UIR_StartContinuouslyTransmitting(&uir_param_info);
+
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // Start IR send successfully
+ }
+ else
+ {
+ if (status == UIR_STATUS_INVALID_CODESET_TYPE)
+ {
+ // Invalid IR protocol type!
+ }
+ }
+
+ platform_delay_ms(1000);
+
+ status = UIR_StopContinuouslyTransmitting();
+
+ if (status == UIR_STATUS_ALREADY_IN_TRANSMITTING)
+ {
+ // IR is sending data, waiting for IR tx empty interrupt
+ // Add application code here
+ }
+ else
+ {
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // IR has stopped sending data
+ // Add application code here
+ }
+ }
+
+ platform_delay_ms(1000);
+}
+
+/**
+ * @brief SHARP send demo.
+ * @param void.
+ * @return void.
+ */
+void SHARP_SendCode(void)
+{
+ UIR_STATUS status;
+
+ uint16_t data = 0x35A;
+
+ memset(&uir_param_info, 0, sizeof(uir_param_info));
+ uir_param_info.uir_protocol_index = UIR_CODESET_TYPE_SHARP;
+ uir_param_info.key_code_value[0] = data & 0xFF;
+ uir_param_info.key_code_value[0] = (data >> 8) & 0xFF;
+ uir_param_info.key_code_length = 16;
+
+ status = UIR_StartContinuouslyTransmitting(&uir_param_info);
+
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // Start IR send successfully
+ }
+ else
+ {
+ if (status == UIR_STATUS_INVALID_CODESET_TYPE)
+ {
+ // Invalid IR protocol type!
+ }
+ }
+
+ platform_delay_ms(1000);
+
+ status = UIR_StopContinuouslyTransmitting();
+
+ if (status == UIR_STATUS_ALREADY_IN_TRANSMITTING)
+ {
+ // IR is sending data, waiting for IR tx empty interrupt
+ // Add application code here
+ }
+ else
+ {
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // IR has stopped sending data
+ // Add application code here
+ }
+ }
+
+ platform_delay_ms(1000);
+}
+
+/**
+ * @brief KONICA send demo.
+ * @param void.
+ * @return void.
+ */
+void KONICA_SendCode(void)
+{
+ UIR_STATUS status;
+
+ memset(&uir_param_info, 0, sizeof(uir_param_info));
+ uir_param_info.uir_protocol_index = UIR_CODESET_TYPE_KONICA;
+ uir_param_info.custom_code_value[0] = 0x55;
+ uir_param_info.custom_code_value[1] = (uint8_t)(~(0x55));
+ uir_param_info.custom_code_length = 16;
+ uir_param_info.key_code_value[0] = 0xAA;
+ uir_param_info.key_code_value[1] = (uint8_t)(~(0xAA));
+ uir_param_info.key_code_length = 16;
+
+ //UIR_OneFrameTransmitting(&uir_param_info);
+ status = UIR_StartContinuouslyTransmitting(&uir_param_info);
+
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // Start IR send successfully
+ }
+ else
+ {
+ if (status == UIR_STATUS_INVALID_CODESET_TYPE)
+ {
+ // Invalid IR protocol type!
+ }
+ }
+
+ platform_delay_ms(1000);
+
+ status = UIR_StopContinuouslyTransmitting();
+
+ if (status == UIR_STATUS_ALREADY_IN_TRANSMITTING)
+ {
+ // IR is sending data, waiting for IR tx empty interrupt
+ // Add application code here
+ }
+ else
+ {
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // IR has stopped sending data
+ // Add application code here
+ }
+ }
+
+ platform_delay_ms(1000);
+}
+
+/**
+ * @brief NEC send demo.
+ * @param void.
+ * @return void.
+ */
+void DVB_40BIT_SendCode(void)
+{
+ UIR_STATUS status;
+
+ memset(&uir_param_info, 0, sizeof(uir_param_info));
+ uir_param_info.uir_protocol_index = UIR_CODESET_TYPE_DVB_40BIT;
+ uir_param_info.custom_code_value[0] = 0x4F;
+ uir_param_info.custom_code_value[1] = 0x43;
+ uir_param_info.custom_code_value[2] = 0x4E;
+ uir_param_info.custom_code_length = 24;
+ uir_param_info.key_code_value[0] = 0x2C;
+ uir_param_info.key_code_value[1] = 0xD3;
+ uir_param_info.key_code_length = 16;
+
+ UIR_OneFrameTransmitting(&uir_param_info, DISABLE);
+
+ platform_delay_ms(1000);
+
+ status = UIR_StartContinuouslyTransmitting(&uir_param_info);
+
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // Start IR send successfully
+ }
+ else
+ {
+ if (status == UIR_STATUS_INVALID_CODESET_TYPE)
+ {
+ // Invalid IR protocol type!
+ }
+ }
+
+ platform_delay_ms(1000);
+
+ status = UIR_StopContinuouslyTransmitting();
+
+ if (status == UIR_STATUS_ALREADY_IN_TRANSMITTING)
+ {
+ // IR is sending data, waiting for IR tx empty interrupt
+ // Add application code here
+ }
+ else
+ {
+ if (status == UIR_STATUS_NO_ERROR)
+ {
+ // IR has stopped sending data
+ // Add application code here
+ }
+ }
+
+ platform_delay_ms(1000);
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/ir_app.h b/src/sample/io_sample/IR/SendCode/ir_app.h
new file mode 100644
index 0000000..c524fb1
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/ir_app.h
@@ -0,0 +1,41 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ir_send_app.h
+* @brief
+* @details
+* @author elliot chen
+* @date 2018-07-23
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __IR_SEND_APP_H
+#define __IR_SEND_APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_trans.h"
+#include "string.h"
+#include "app_msg.h"
+#include "trace.h"
+
+void Board_LED_Init(void);
+void Driver_LED_Init(void);
+void IR_Send_Init(void);
+void IR_Raw_Packet_Send(uint32_t *pBuf, uint32_t len);
+void NEC_SendCode(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__IR_SEND_APP_H*/
+
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/led/ir_led.c b/src/sample/io_sample/IR/SendCode/led/ir_led.c
new file mode 100644
index 0000000..0e1240b
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/led/ir_led.c
@@ -0,0 +1,74 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_led.c
+* @brief This file provides led display for ir application code.
+* @details
+* @author elliot chen
+* @date 2018-7-23
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_led.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define LED_IR_SEND_PIN P0_1
+#define LED_IR_LEARN_PIN P0_2
+
+#define LED_IR_SEND_GPIO_INDEX GPIO_GetPin(LED_IR_SEND_PIN)
+#define LED_IR_LEARN_GPIO_INDEX GPIO_GetPin(LED_IR_LEARN_PIN)
+
+/* Globals -------------------------------------------------------------------*/
+
+/**
+ * @brief initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void Board_All_LED_Init(void)
+{
+ Pad_Config(LED_IR_SEND_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(LED_IR_LEARN_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(LED_IR_SEND_PIN, DWGPIO);
+ Pinmux_Config(LED_IR_LEARN_PIN, DWGPIO);
+}
+
+/**
+ * @brief Initialize GPIO peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void Driver_All_LED_Init(void)
+{
+ /* Enable GPIO clock */
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+
+ /* Initialize GPIO */
+ GPIO_InitTypeDef GPIO_InitStruct;
+ GPIO_StructInit(&GPIO_InitStruct);
+ GPIO_InitStruct.GPIO_Pin = LED_IR_SEND_GPIO_INDEX | LED_IR_LEARN_GPIO_INDEX;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_Init(&GPIO_InitStruct);
+ GPIO_ResetBits(LED_IR_SEND_GPIO_INDEX);
+ GPIO_ResetBits(LED_IR_LEARN_GPIO_INDEX);
+}
+
+void LED_IR_Send_Swap(void)
+{
+ GPIO_WriteBit(LED_IR_SEND_GPIO_INDEX,
+ (BitAction)(1 - GPIO_ReadOutputDataBit(LED_IR_SEND_GPIO_INDEX)));
+}
+
+void LED_IR_Learn_Swap(void)
+{
+ GPIO_WriteBit(LED_IR_LEARN_GPIO_INDEX,
+ (BitAction)(1 - GPIO_ReadOutputDataBit(LED_IR_LEARN_GPIO_INDEX)));
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/led/ir_led.h b/src/sample/io_sample/IR/SendCode/led/ir_led.h
new file mode 100644
index 0000000..aa7ca80
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/led/ir_led.h
@@ -0,0 +1,40 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ir_led.h
+* @brief
+* @details
+* @author elliot chen
+* @date 2018-07-23
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __IR_LED_H
+#define __IR_LED_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_rcc.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_gpio.h"
+
+/* Function declaration --------------------------------------------------------*/
+void Board_All_LED_Init(void);
+void Driver_All_LED_Init(void);
+void LED_IR_Send_Swap(void);
+void LED_IR_Learn_Swap(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__IR_LED_H*/
+
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/dvb_40bit_prot.c b/src/sample/io_sample/IR/SendCode/protocol/dvb_40bit_prot.c
new file mode 100644
index 0000000..7454152
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/dvb_40bit_prot.c
@@ -0,0 +1,96 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file dvb_40bit_prot.c
+* @brief This file provides driver of dvb protocol encoding.
+* @details
+* @author elliot_chen
+* @date 2019-083-19
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "dvb_40bit_prot.h"
+
+
+#define DVB_40BIT_SEPAR_FIRST_PERIOD (IR_PULSE_HIGH | (3690))
+#define DVB_40BIT_SEPAR_SECOND_PERIOD (IR_PULSE_LOW | (1770))
+
+/*!
+* @ brief: DVB_40BIT_Encode protocol structure.
+* @ note: Store parameters of DVB protocol.
+* @ Carrier frequency = 38kHz
+* @ duty factor = 1/3
+* @ first pulse : 3.5ms 1.75ms
+* @ Custom (32 bits) is sent first
+* @ Data (32 bits) follows
+* @ LSB is sent first !
+*/
+const IR_ProtocolTypeDef DVB_40BIT_PROTOCOL =
+{
+ 38, /* Carrier freqency */
+ IR_CODING_LSB_FIRST, /* LSB first */
+ TIME_UNIT, /* unit is us */
+ 2, /* headerLen */
+ {
+ IR_PULSE_HIGH | (3720), IR_PULSE_LOW | (1775), /* headerBuf */
+ 0, 0,
+ 0, 0
+ },
+ {IR_PULSE_HIGH | 605, IR_PULSE_LOW | 524}, /* log0Buf */
+ {IR_PULSE_HIGH | 605, IR_PULSE_LOW | 1096}, /* log1Buf */
+ IR_PULSE_HIGH | 605 /* stopBuf */
+};
+
+/*!
+* @ User can modify this data structure to send user-defined repeat code!!!
+* @ brief: IR repeat code protocol structure.
+* @ note: Store parameters of repeat code protocol.
+*/
+const IR_RepeatCodeTypeDef DVB_40BIT_REPEAT_CODE_PROTOCOL =
+{
+ TIME_UNIT, /* unit is us */
+ 3, /* length of repeat code */
+ {IR_PULSE_HIGH | 3710, IR_PULSE_LOW | 3580, IR_PULSE_HIGH | 630} /* Buffer of repeat code */
+};
+
+/**
+ * @brief Encode data of DVB protocol.
+ * @param IR_DataStruct: pointer to struct which store DVB code.
+ * @retval None
+ */
+IR_Return_Type DVB_40BIT_Encode(IR_DataTypeDef *IR_DataStruct)
+{
+ IR_Return_Type ret = IR_SUCCEED;
+ uint32_t key_code_idx = (IR_DataStruct->custom_bit_len << 1) + DVB_40BIT_PROTOCOL.headerLen;
+
+ ret = IR_Encode(IR_DataStruct, (IR_ProtocolTypeDef *)(&DVB_40BIT_PROTOCOL), true);
+
+ memmove(&IR_DataStruct->irBuf[key_code_idx + 2], \
+ &IR_DataStruct->irBuf[key_code_idx], \
+ (IR_DataStruct->bufLen - key_code_idx) * 4);
+
+ IR_DataStruct->irBuf[key_code_idx] = ConvertToCarrierCycle(DVB_40BIT_SEPAR_FIRST_PERIOD, \
+ DVB_40BIT_PROTOCOL.carrierFreq, DVB_40BIT_PROTOCOL.unit);
+ IR_DataStruct->irBuf[key_code_idx + 1] = ConvertToCarrierCycle(DVB_40BIT_SEPAR_SECOND_PERIOD, \
+ DVB_40BIT_PROTOCOL.carrierFreq, DVB_40BIT_PROTOCOL.unit);
+ IR_DataStruct->bufLen += 2;
+ return ret;
+}
+
+/**
+ * @brief Encode data of repeat code protocol.
+ * @param frequency: carrier frequency whose uinit is KHz.
+ * @param IR_DataStruct: pointer to struct which store repeat code data.
+ * @retval None
+ */
+IR_Return_Type DVB_40BIT_RepeatCodeEncode(IR_DataTypeDef *IR_DataStruct)
+{
+ return IR_RepeatCodeEncode(IR_DataStruct,
+ (IR_RepeatCodeTypeDef *)(&DVB_40BIT_REPEAT_CODE_PROTOCOL));
+}
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/dvb_40bit_prot.h b/src/sample/io_sample/IR/SendCode/protocol/dvb_40bit_prot.h
new file mode 100644
index 0000000..399320b
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/dvb_40bit_prot.h
@@ -0,0 +1,46 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file dvb_40bit_prot.h
+* @brief This file provides driver of dvb protocol encoding.
+* @details
+* @author elliot chen
+* @date 2019-03-19
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __DVB_40BIT_PROT_H
+#define __DVB_40BIT_PROT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include "ir_protocol_config.h"
+#include "ir_encode.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/**
+ * @brief Configure DVB_4BIT protocol repeat code transmission interval
+ */
+
+#define DVB_40BIT_TRANSMISION_INTERVAL ((uint32_t)((538*1000 - 1)))
+#define DVB_40BIT_TRANSMISION_RE_INTERVAL ((uint32_t)((101*10000 - 1)))
+
+/* Exported functions --------------------------------------------------------*/
+IR_Return_Type DVB_40BIT_Encode(IR_DataTypeDef *IR_DataStruct);
+IR_Return_Type DVB_40BIT_RepeatCodeEncode(IR_DataTypeDef *IR_DataStruct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__DVB_40BIT_PROT_H*/
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/dvb_prot.c b/src/sample/io_sample/IR/SendCode/protocol/dvb_prot.c
new file mode 100644
index 0000000..d97a3a3
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/dvb_prot.c
@@ -0,0 +1,56 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file dvb_prot.c
+* @brief This file provides driver of dvb protocol encoding.
+* @details
+* @author elliot_chen
+* @date 2017-08-21
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "dvb_prot.h"
+
+
+/*!
+* @ brief: DVB protocol structure.
+* @ note: Store parameters of DVB protocol.
+* @ Carrier frequency = 38kHz
+* @ duty factor = 1/3
+* @ first pulse : 3.5ms 1.75ms
+* @ Custom (32 bits) is sent first
+* @ Data (32 bits) follows
+* @ LSB is sent first !
+*/
+const IR_ProtocolTypeDef DVB_PROTOCOL =
+{
+ 38, /* Carrier freqency */
+ IR_CODING_LSB_FIRST, /* LSB first */
+ TIME_UNIT, /* unit is us */
+ 2, /* headerLen */
+ {
+ IR_PULSE_HIGH | (3500), IR_PULSE_LOW | (1750), /* headerBuf */
+ 0, 0,
+ 0, 0
+ },
+ {IR_PULSE_HIGH | 421, IR_PULSE_LOW | 421}, /* log0Buf */
+ {IR_PULSE_HIGH | 421, IR_PULSE_LOW | 1263}, /* log1Buf */
+ IR_PULSE_HIGH | 421 /* stopBuf */
+};
+
+/**
+ * @brief Encode data of DVB protocol.
+ * @param IR_DataStruct: pointer to struct which store DVB code.
+ * @retval None
+ */
+IR_Return_Type DVB_Encode(IR_DataTypeDef *IR_DataStruct)
+{
+ return IR_Encode(IR_DataStruct, (IR_ProtocolTypeDef *)(&DVB_PROTOCOL), true);
+}
+
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/dvb_prot.h b/src/sample/io_sample/IR/SendCode/protocol/dvb_prot.h
new file mode 100644
index 0000000..631f6fe
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/dvb_prot.h
@@ -0,0 +1,43 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file dvb_prot.h
+* @brief This file provides driver of dvb protocol encoding.
+* @details
+* @author elliot chen
+* @date 2017-08-21
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __DVB_PROT_H
+#define __DVB_PROT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_protocol_config.h"
+#include "ir_encode.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/**
+ * @brief Configure PIONEER protocol repeat code transmission interval
+ */
+
+#define DVB_TRANSMISION_INTERVAL ((uint32_t)((50*10000 - 1)))
+
+/* Exported functions --------------------------------------------------------*/
+IR_Return_Type DVB_Encode(IR_DataTypeDef *IR_DataStruct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__DVB_PROT_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/konica_prot.c b/src/sample/io_sample/IR/SendCode/protocol/konica_prot.c
new file mode 100644
index 0000000..a44b546
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/konica_prot.c
@@ -0,0 +1,80 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file konica_prot.c
+* @brief This file provides driver of konica protocol encoding.
+* @details
+* @author elliot_chen
+* @date 2017-09-26
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "konica_prot.h"
+
+
+/*!
+* @ brief:konica protocol structure.
+* @ note: Store parameters of konica protocol.
+* @ Carrier frequency = 38kHz
+* @ duty factor = 1/3
+* @ first pulse : 3.6ms 1.8ms
+* @ LSB is sent first !
+*/
+const IR_ProtocolTypeDef KONICA_PROTOCOL =
+{
+ 38, /* Carrier freqency */
+ IR_CODING_LSB_FIRST, /* LSB first */
+ TIME_UNIT, /* unit is us */
+ 2, /* headerLen */
+ {
+ IR_PULSE_HIGH | (3600), IR_PULSE_LOW | (1800),
+ 0, 0,
+ 0, 0
+ }, /* headerBuf */
+ {IR_PULSE_HIGH | (475), IR_PULSE_LOW | (475)}, /* log0Buf */
+ {IR_PULSE_HIGH | (475), IR_PULSE_LOW | (1450)}, /* log1Buf */
+ IR_PULSE_HIGH | (475) /* stopBuf */
+};
+
+/*!
+* @ brief: IR repeat code protocol structure.
+* @ note: Store parameters of repeat code protocol.
+* @ parameters Configuration:
+* @ PULSE_HIGH|9000 is 9ms of high voltage.
+* @ PULSE_LOW|2250 is low 2.25ms of low voltage.
+* @ ULSE_HIGH |560 is 560us of high voltage.
+*/
+const IR_RepeatCodeTypeDef KONICA_REPEAT_CODE_PROTOCOL =
+{
+ TIME_UNIT, /* unit is us */
+ 3, /* length of repeat code */
+ {IR_PULSE_HIGH | 3600, IR_PULSE_LOW | 3600, IR_PULSE_HIGH | 475} /* Buffer of repeat code: high 9ms, low 2.25ms, high 560us */
+};
+
+/**
+ * @brief Encode data of NEC protocol.
+ * @param IR_DataStruct: pointer to struct which store RCA code.
+ * @retval None
+ */
+IR_Return_Type KONICA_Encode(IR_DataTypeDef *IR_DataStruct)
+{
+ return IR_Encode(IR_DataStruct, (IR_ProtocolTypeDef *)(&KONICA_PROTOCOL), true);
+}
+
+/**
+ * @brief Encode data of repeat code protocol.
+ * @param frequency: carrier frequency whose uinit is KHz.
+ * @param IR_DataStruct: pointer to struct which store repeat code data.
+ * @retval None
+ */
+IR_Return_Type KONICA_RepeatCodeEncode(IR_DataTypeDef *IR_DataStruct)
+{
+ return IR_RepeatCodeEncode(IR_DataStruct, (IR_RepeatCodeTypeDef *)(&KONICA_REPEAT_CODE_PROTOCOL));
+}
+
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/konica_prot.h b/src/sample/io_sample/IR/SendCode/protocol/konica_prot.h
new file mode 100644
index 0000000..03adf9c
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/konica_prot.h
@@ -0,0 +1,44 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file konica_prot.h
+* @brief This file provides driver of konica protocol encoding.
+* @details
+* @author elliot chen
+* @date 2017-09-26
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __KONICA_PROT_H
+#define __KONICA_PROT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_protocol_config.h"
+#include "ir_encode.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/**
+ * @brief Configure konica protocol repeat code transmission interval
+ */
+
+#define KONICA_TRANSMISION_INTERVAL ((uint32_t)((52*10000 - 1)))
+
+/* Exported functions --------------------------------------------------------*/
+IR_Return_Type KONICA_Encode(IR_DataTypeDef *IR_DataStruct);
+IR_Return_Type KONICA_RepeatCodeEncode(IR_DataTypeDef *IR_DataStruct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__KONICA_PROT_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/lc7464m_prot.c b/src/sample/io_sample/IR/SendCode/protocol/lc7464m_prot.c
new file mode 100644
index 0000000..e0f9566
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/lc7464m_prot.c
@@ -0,0 +1,56 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file lc7464m_prot.c
+* @brief This file provides driver of lc7464m protocol encoding.
+* @details
+* @author elliot_chen
+* @date 2017-08-18
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "lc7464m_prot.h"
+
+
+/*!
+* @ brief:lc7464m protocol structure.
+* @ note: Store parameters of lc7464m protocol.
+* @ Carrier frequency = 38kHz
+* @ duty factor = 1/3
+* @ first pulse :
+* @ MSB is sent first !
+*/
+const IR_ProtocolTypeDef LC7464M_PROTOCOL =
+{
+ 38, /* Carrier freqency */
+ IR_CODING_LSB_FIRST, /* LSB first */
+ CARRIER_UNIT, /* unit is carrier period */
+ 2, /* headerLen */
+ {
+ IR_PULSE_HIGH | (16 * 8), IR_PULSE_LOW | (16 * 4), /* headerBuf */
+ 0, 0,
+ 0, 0
+ },
+ {IR_PULSE_HIGH | (16), IR_PULSE_LOW | (16)}, /* log0Buf */
+ {IR_PULSE_HIGH | (16), IR_PULSE_LOW | (16 * 3)}, /* log1Buf */
+ IR_PULSE_HIGH | (16) /* stopBuf */
+};
+
+/**
+ * @brief Encode data of LC7464M protocol.
+ * @param address: user code.
+ * @param command: data code.
+ * @param IR_DataStruct: pointer to struct which store LC7464M code.
+ * @retval None
+ */
+IR_Return_Type LC7464M_Encode(IR_DataTypeDef *IR_DataStruct)
+{
+ return IR_Encode(IR_DataStruct, (IR_ProtocolTypeDef *)(&LC7464M_PROTOCOL), true);
+}
+
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/lc7464m_prot.h b/src/sample/io_sample/IR/SendCode/protocol/lc7464m_prot.h
new file mode 100644
index 0000000..6e1ee77
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/lc7464m_prot.h
@@ -0,0 +1,43 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file lc7464m_prot.h
+* @brief This file provides driver of lc7464m protocol encoding.
+* @details
+* @author elliot chen
+* @date 2017-08-18
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __LC7464M_PROT_H
+#define __LC7464M_PROT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_protocol_config.h"
+#include "ir_encode.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/**
+ * @brief Configure SONY 6124 protocol repeat code transmission interval
+ */
+
+#define LC7464M_TRANSMISION_INTERVAL ((uint32_t)((421053 - 1)))//100T
+
+/* Exported functions --------------------------------------------------------*/
+IR_Return_Type LC7464M_Encode(IR_DataTypeDef *IR_DataStruct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__SONY6124_PROT_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/mitc8d8_prot.c b/src/sample/io_sample/IR/SendCode/protocol/mitc8d8_prot.c
new file mode 100644
index 0000000..5f4c675
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/mitc8d8_prot.c
@@ -0,0 +1,72 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file mitc8d8_prot.c
+* @brief This file provides driver of mitc8d8 protocol encoding.
+* @details
+* @author elliot_chen
+* @date 2017-08-21
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "mitc8d8_prot.h"
+
+
+/*!
+* @ brief: MITC8D8 protocol structure.
+* @ note: Store parameters of MITC8D8 protocol.
+* @ Carrier frequency = 38kHz
+* @ duty factor = 1/3
+* @ LSB is sent first !
+*/
+#if 0
+const IR_ProtocolTypeDef MITC8D8_PROTOCOL =
+{
+ 38, /* Carrier freqency */
+ IR_CODING_LSB_FIRST, /* LSB first */
+ CARRIER_UNIT, /* unit is carrier period */
+ 0, /* headerLen */
+ {
+ 0, 0,
+ 0, 0,
+ 0, 0
+ }, /* headerBuf */
+ {IR_PULSE_HIGH | (10 - 1), IR_PULSE_LOW | (10 - 1)}, /* log0Buf */
+ {IR_PULSE_HIGH | (10 - 1), IR_PULSE_LOW | (30 - 1)}, /* log1Buf */
+ IR_PULSE_HIGH | (10 - 1) /* stopBuf */
+};
+#else
+const IR_ProtocolTypeDef MITC8D8_PROTOCOL =
+{
+ 38, /* Carrier freqency */
+ IR_CODING_LSB_FIRST, /* LSB first */
+ TIME_UNIT, /* unit is carrier period */
+ 0, /* headerLen */
+ {
+ 0, 0,
+ 0, 0,
+ 0, 0
+ }, /* headerBuf */
+ {IR_PULSE_HIGH | (430), IR_PULSE_LOW | (750)}, /* log0Buf */
+ {IR_PULSE_HIGH | (460), IR_PULSE_LOW | (1920)}, /* log1Buf */
+ IR_PULSE_HIGH | (430) /* stopBuf */
+};
+
+#endif
+
+/**
+ * @brief Encode data of MITC8D8 protocol.
+ * @param IR_DataStruct: pointer to struct which store MITC8D8 code.
+ * @retval None
+ */
+IR_Return_Type MITC8D8_Encode(IR_DataTypeDef *IR_DataStruct)
+{
+ return IR_Encode(IR_DataStruct, (IR_ProtocolTypeDef *)(&MITC8D8_PROTOCOL), true);
+}
+
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/mitc8d8_prot.h b/src/sample/io_sample/IR/SendCode/protocol/mitc8d8_prot.h
new file mode 100644
index 0000000..f523439
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/mitc8d8_prot.h
@@ -0,0 +1,43 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file mitc8d8_prot.h
+* @brief This file provides driver of mitc8d8 protocol encoding.
+* @details
+* @author elliot chen
+* @date 2017-08-21
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __MITC8D8_PROT_H
+#define __MITC8D8_PROT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_protocol_config.h"
+#include "ir_encode.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/**
+ * @brief Configure MITC8D8 protocol repeat code transmission interval
+ */
+
+#define MITC8D8_TRANSMISION_INTERVAL ((uint32_t)((30*10000 - 1)))
+
+/* Exported functions --------------------------------------------------------*/
+IR_Return_Type MITC8D8_Encode(IR_DataTypeDef *IR_DataStruct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__MITC8D8_PROT_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/nec_prot.c b/src/sample/io_sample/IR/SendCode/protocol/nec_prot.c
new file mode 100644
index 0000000..a005df6
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/nec_prot.c
@@ -0,0 +1,83 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file nec_prot.c
+* @brief This file provides driver of NEC protocol encoding.
+* @details
+* @author elliot_chen
+* @date 2017-08-15
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "nec_prot.h"
+
+
+/*!
+* @ brief:NEC protocol structure.
+* @ note: Store parameters of NEC protocol.
+* @ Carrier frequency = 38kHz
+* @ duty factor = 1/3
+* @ first pulse : 9.5ms 4.5ms
+* @ Address (8 bits) is sent first, then ~Address
+* @ Command (8 bits) follows, then ~Command
+* @ LSB is sent first !
+*/
+const IR_ProtocolTypeDef NEC_PROTOCOL =
+{
+ 38, /* Carrier freqency */
+ IR_CODING_LSB_FIRST, /* LSB first */
+ TIME_UNIT, /* unit is us */
+ 2, /* headerLen */
+ {
+ IR_PULSE_HIGH | (9000), IR_PULSE_LOW | (4500),
+ 0, 0,
+ 0, 0
+ }, /* headerBuf */
+ {IR_PULSE_HIGH | (560), IR_PULSE_LOW | (560)}, /* log0Buf */
+ {IR_PULSE_HIGH | (560), IR_PULSE_LOW | (1690)}, /* log1Buf */
+ IR_PULSE_HIGH | (560) /* stopBuf */
+};
+
+/*!
+* @ User can modify this data structure to send user-defined repeat code!!!
+* @ brief: IR repeat code protocol structure.
+* @ note: Store parameters of repeat code protocol.
+* @ parameters Configuration:
+* @ PULSE_HIGH|9000 is 9ms of high voltage.
+* @ PULSE_LOW|2250 is low 2.25ms of low voltage.
+* @ ULSE_HIGH |560 is 560us of high voltage.
+*/
+const IR_RepeatCodeTypeDef NEC_REPEAT_CODE_PROTOCOL =
+{
+ TIME_UNIT, /* unit is us */
+ 3, /* length of repeat code */
+ {IR_PULSE_HIGH | 9000, IR_PULSE_LOW | 2250, IR_PULSE_HIGH | 560} /* Buffer of repeat code: high 9ms, low 2.25ms, high 560us */
+};
+
+/**
+ * @brief Encode data of NEC protocol.
+ * @param IR_DataStruct: pointer to struct which store RCA code.
+ * @retval None
+ */
+IR_Return_Type NEC_Encode(IR_DataTypeDef *IR_DataStruct)
+{
+ return IR_Encode(IR_DataStruct, (IR_ProtocolTypeDef *)(&NEC_PROTOCOL), true);
+}
+
+/**
+ * @brief Encode data of repeat code protocol.
+ * @param frequency: carrier frequency whose uinit is KHz.
+ * @param IR_DataStruct: pointer to struct which store repeat code data.
+ * @retval None
+ */
+IR_Return_Type NEC_RepeatCodeEncode(IR_DataTypeDef *IR_DataStruct)
+{
+ return IR_RepeatCodeEncode(IR_DataStruct, (IR_RepeatCodeTypeDef *)(&NEC_REPEAT_CODE_PROTOCOL));
+}
+
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/nec_prot.h b/src/sample/io_sample/IR/SendCode/protocol/nec_prot.h
new file mode 100644
index 0000000..dce9c0b
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/nec_prot.h
@@ -0,0 +1,44 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file nec_prot.h
+* @brief This file provides driver of NEC protocol encoding.
+* @details
+* @author elliot chen
+* @date 2017-08-15
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __NEC_PROT_H
+#define __NEC_PROT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_protocol_config.h"
+#include "ir_encode.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/**
+ * @brief Configure NEC protocol repeat code transmission interval
+ */
+
+#define NEC_TRANSMISION_INTERVAL ((uint32_t)((108*10000 - 1)))
+
+/* Exported functions --------------------------------------------------------*/
+IR_Return_Type NEC_Encode(IR_DataTypeDef *IR_DataStruct);
+IR_Return_Type NEC_RepeatCodeEncode(IR_DataTypeDef *IR_DataStruct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__NEC_PROT_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/pioneer_prot.c b/src/sample/io_sample/IR/SendCode/protocol/pioneer_prot.c
new file mode 100644
index 0000000..8bf4f52
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/pioneer_prot.c
@@ -0,0 +1,56 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file pioneer_prot.c
+* @brief This file provides driver of pioneer protocol encoding.
+* @details
+* @author elliot_chen
+* @date 2017-08-21
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "pioneer_prot.h"
+
+
+/*!
+* @ brief: PIONEER protocol structure.
+* @ note: Store parameters of PIONEER protocol.
+* @ Carrier frequency = 38kHz
+* @ duty factor = 1/3
+* @ first pulse : 8.5ms 4.25ms
+* @ Custom (8 bits) is sent first, then ~Custom
+* @ Data (8 bits) follows, then ~Data
+* @ LSB is sent first !
+*/
+const IR_ProtocolTypeDef PIONEER_PROTOCOL =
+{
+ 40, /* Carrier freqency */
+ IR_CODING_LSB_FIRST, /* LSB first */
+ TIME_UNIT, /* unit is us */
+ 2, /* headerLen */
+ {
+ IR_PULSE_HIGH | 8000, IR_PULSE_LOW | 4250,
+ 0, 0,
+ 0, 0
+ }, /* headerBuf */
+ {IR_PULSE_HIGH | 536, IR_PULSE_LOW | 536}, /* log0Buf */
+ {IR_PULSE_HIGH | 536, IR_PULSE_LOW | 1590}, /* log1Buf */
+ IR_PULSE_HIGH | 536 /* stopBuf */
+};
+
+/**
+ * @brief Encode data of PIONEER protocol.
+ * @param IR_DataStruct: pointer to struct which store PIONEER code.
+ * @retval None
+ */
+IR_Return_Type PIONEER_Encode(IR_DataTypeDef *IR_DataStruct)
+{
+ return IR_Encode(IR_DataStruct, (IR_ProtocolTypeDef *)(&PIONEER_PROTOCOL), true);
+}
+
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/pioneer_prot.h b/src/sample/io_sample/IR/SendCode/protocol/pioneer_prot.h
new file mode 100644
index 0000000..dddd948
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/pioneer_prot.h
@@ -0,0 +1,43 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file pioneer_prot.h
+* @brief This file provides driver of pioneer protocol encoding.
+* @details
+* @author elliot chen
+* @date 2017-08-21
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __PIONEER_PROT_H
+#define __PIONEER_PROT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_protocol_config.h"
+#include "ir_encode.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/**
+ * @brief Configure PIONEER protocol repeat code transmission interval
+ */
+
+#define PIONEER_TRANSMISION_INTERVAL ((uint32_t)((91*10000 - 1)))
+
+/* Exported functions --------------------------------------------------------*/
+IR_Return_Type PIONEER_Encode(IR_DataTypeDef *IR_DataStruct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__PIONEER_PROT_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/raw_pack_prot.c b/src/sample/io_sample/IR/SendCode/protocol/raw_pack_prot.c
new file mode 100644
index 0000000..1221cdf
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/raw_pack_prot.c
@@ -0,0 +1,46 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file nec_prot.c
+* @brief This file provides driver of raw packet protocol encoding.
+* @details
+* @author elliot_chen
+* @date 2018-07-23
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "raw_pack_prot.h"
+
+/**
+ * @brief Encode data of raw packet protocol.
+ * @param IR_DataStruct: pointer to struct which store RCA code.
+ * @retval None
+ */
+IR_Return_Type Raw_Pack_Encode(IR_DataTypeDef *IR_DataStruct)
+{
+ uint32_t i = 0;
+
+ for (i = 0; i < IR_DataStruct->bufLen; i++)
+ {
+ IR_DataStruct->irBuf[i] = ConvertToCarrierCycle(IR_DataStruct->irBuf[i], IR_DataStruct->carrierFreq,
+ TIME_UNIT);
+
+ if ((i % 2) == 0)
+ {
+ IR_DataStruct->irBuf[i] |= IR_PULSE_HIGH;
+ }
+ }
+
+#if SOFTWARE_AVOIDANCE
+ IR_DataStruct->irBuf[IR_DataStruct->bufLen++] = IR_PULSE_HIGH | ConvertToCarrierCycle(560,
+ IR_DataStruct->carrierFreq, TIME_UNIT);
+ IR_DataStruct->irBuf[IR_DataStruct->bufLen++] = 0;
+#endif
+ return IR_SUCCEED;
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/raw_pack_prot.h b/src/sample/io_sample/IR/SendCode/protocol/raw_pack_prot.h
new file mode 100644
index 0000000..c5e4cb0
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/raw_pack_prot.h
@@ -0,0 +1,38 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file raw_pack_prot.h
+* @brief This file provides driver of raw packet protocol encoding.
+* @details
+* @author elliot chen
+* @date 2018-07-23
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __RAW_PACK_PROT_H
+#define __RAW_PACK_PROT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_protocol_config.h"
+#include "ir_encode.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define RAW_PACK_TRANSMISION_INTERVAL ((uint32_t)((108*10000 - 1)))
+
+/* Exported functions --------------------------------------------------------*/
+IR_Return_Type Raw_Pack_Encode(IR_DataTypeDef *IR_DataStruct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__RAW_PACK_PROT_H*/
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/rc5_prot.c b/src/sample/io_sample/IR/SendCode/protocol/rc5_prot.c
new file mode 100644
index 0000000..4b40104
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/rc5_prot.c
@@ -0,0 +1,141 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rc5_prot.c
+* @brief This file provides driver of RC5 protocol encoding.
+* @details
+* @author elliot_chen
+* @date 2017-08-16
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rc5_prot.h"
+
+
+/* Defines -------------------------------------------------------------------*/
+#define IR_RC5_ENLARGED_BIT_INDEX 2
+#define IR_RC5_TOGGLE_BIT_INDEX 4
+
+/* Globals -------------------------------------------------------------------*/
+bool toggle_flag = false;
+
+/*!
+* @ brief:RC5 protocol structure.
+* @ note: Store parameters of RC5 protocol.
+* @ Carrier frequency = 38kHz
+* @ duty factor = 1/3
+* @ first pulse : logical 0, logical 0, logical 0
+* @ System (5 bits) is sent first
+* @ Data (6 bits) follows
+* @ MSB is sent first !
+*/
+const IR_ProtocolTypeDef RC5_PROTOCOL =
+{
+ 38, /* Carrier freqency */
+ IR_CODING_MSB_FIRST, /* MSB first */
+ TIME_UNIT, /* unit is us */
+ 6, /* header length */
+ {
+ IR_PULSE_LOW | 847, IR_PULSE_HIGH | 827, /* Start bit: logical 1 */
+ IR_PULSE_LOW | 847, IR_PULSE_HIGH | 827, /* Enlarged bit */
+ IR_PULSE_LOW | 847, IR_PULSE_HIGH | 827
+ }, /* Toggle bit */
+ {IR_PULSE_HIGH | 839, IR_PULSE_LOW | 835}, /* log0Buf */
+ {IR_PULSE_LOW | 847, IR_PULSE_HIGH | 827}, /* log1Buf */
+ IR_PULSE_HIGH | 839 /* stopBuf */
+};
+
+/**
+ * @brief Encode data to packet.
+ * @param IR_DataStruct: pointer to struct which store IR data code.
+ * @param IR_Protocol: pointer to specify IR protocol structure.
+ * @param flag: logical level type.
+ * @param index: encoder buffer index.
+ * @retval None
+ */
+IR_Return_Type RC5_EncodeBit(IR_DataTypeDef *IR_DataStruct, IR_ProtocolTypeDef *IR_Protocol,
+ uint8_t index, bool flag)
+{
+ uint16_t i = 0;
+ IR_DataType Log1[IR_MAX_LOG_WAVFORM_SIZE];
+ IR_DataType Log0[IR_MAX_LOG_WAVFORM_SIZE];
+
+ for (i = 0; i < IR_MAX_LOG_WAVFORM_SIZE; i++)
+ {
+ Log1[i] = ConvertToCarrierCycle(IR_Protocol->log1Buf[i], IR_DataStruct->carrierFreq,
+ IR_Protocol->unit);
+ Log0[i] = ConvertToCarrierCycle(IR_Protocol->log0Buf[i], IR_DataStruct->carrierFreq,
+ IR_Protocol->unit);
+ }
+
+ /* Encoding Enlarged bit */
+ if (flag == false)
+ {
+ /* Logical 0 data */
+ IR_DataStruct->irBuf[index] = Log0[0];
+ IR_DataStruct->irBuf[index + 1] = Log0[1];
+
+ }
+ else
+ {
+ /* Logical 1 data */
+ IR_DataStruct->irBuf[index] = Log1[0];
+ IR_DataStruct->irBuf[index + 1] = Log1[1];
+ }
+
+ return IR_SUCCEED;
+}
+
+/**
+ * @brief Encode data of RC5 protocol.
+ * @param address: user code.
+ * @param command: data code.
+ * @param IR_DataStruct: pointer to struct which store RCA code.
+ * @retval None
+ */
+IR_Return_Type RC5_Encode(IR_DataTypeDef *IR_DataStruct)
+{
+ IR_Return_Type return_type;
+
+ return_type = IR_Encode(IR_DataStruct, (IR_ProtocolTypeDef *)(&RC5_PROTOCOL), true);
+
+ if (return_type != IR_SUCCEED)
+ {
+ return return_type;
+ }
+
+ /* Encoding enlarged bit */
+ if (IR_DataStruct->code[(IR_DataStruct->custom_bit_len + 7) / 8] > 0x3F)
+ {
+ return_type = RC5_EncodeBit(IR_DataStruct, (IR_ProtocolTypeDef *)(&RC5_PROTOCOL),
+ IR_RC5_ENLARGED_BIT_INDEX, false);
+ }
+ else
+ {
+ return_type = RC5_EncodeBit(IR_DataStruct, (IR_ProtocolTypeDef *)(&RC5_PROTOCOL),
+ IR_RC5_ENLARGED_BIT_INDEX, true);
+ }
+
+ /* Encoding toggle bit */
+ if (toggle_flag)
+ {
+ return_type = RC5_EncodeBit(IR_DataStruct, (IR_ProtocolTypeDef *)(&RC5_PROTOCOL),
+ IR_RC5_TOGGLE_BIT_INDEX, true);
+ toggle_flag = false;
+ }
+ else
+ {
+ return_type = RC5_EncodeBit(IR_DataStruct, (IR_ProtocolTypeDef *)(&RC5_PROTOCOL),
+ IR_RC5_TOGGLE_BIT_INDEX, false);
+ toggle_flag = true;
+ }
+
+ return return_type;
+}
+
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/rc5_prot.h b/src/sample/io_sample/IR/SendCode/protocol/rc5_prot.h
new file mode 100644
index 0000000..726cda0
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/rc5_prot.h
@@ -0,0 +1,43 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file rc5_prot.h
+* @brief This file provides driver of RC5 protocol encoding.
+* @details
+* @author elliot chen
+* @date 2017-08-16
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __RC5_PROT_H
+#define __RC5_PROT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_protocol_config.h"
+#include "ir_encode.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/**
+ * @brief Configure RC5 protocol repeat code transmission interval
+ */
+
+#define RC5_TRANSMISION_INTERVAL ((uint32_t)((1076*1000 - 1)))
+
+/* Exported functions --------------------------------------------------------*/
+IR_Return_Type RC5_Encode(IR_DataTypeDef *IR_DataStruct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__RC5_PROT_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/rc6_prot.c b/src/sample/io_sample/IR/SendCode/protocol/rc6_prot.c
new file mode 100644
index 0000000..4c9308c
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/rc6_prot.c
@@ -0,0 +1,125 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file rc6_prot.c
+* @brief This file provides driver of RC6 protocol encoding.
+* @details
+* @author yuan_feng
+* @date 2018-08-22
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rc6_prot.h"
+
+
+/* Globals -------------------------------------------------------------------*/
+bool RC6_Toggle_Flag = false;
+
+/*!
+* @ brief:RC6 protocol structure.
+* @ note: Store parameters of RC6 protocol.
+* @ Carrier frequency = 36kHz
+* @ duty factor = 1/3
+* @ first pulse : logical 0, logical 0, logical 0
+* @ Leader bit (1 bit:6t+2t) is sent first
+* @ Start bit(1 bit:logical 1) follows
+* @ Mode bits(3 bits:110b) follows
+* @ Trailer bit (1 bit;2t+2t) follows
+* @ Customer cdoe (16 bits:0x8010) follows
+* @ Command cdoe (8 bits:0x26 or 0xA6 bit7:toggle bit) follows
+* @ Data cdoe (8 bits) follows
+* @ MSB is sent first !
+*/
+#if (IR_PROTOTCOL_CARRIER_TYPE == 0)
+
+static IR_DataType RC6_32B_Protocol_Header_Add[5] = {IR_PULSE_HIGH | 96, IR_PULSE_LOW | 32,
+ IR_PULSE_HIGH | 16, IR_PULSE_LOW | 16,
+ IR_PULSE_HIGH | 16
+ };
+const IR_ProtocolTypeDef RC6_32B_PROTOCOL =
+{
+ 36, /* Carrier freqency */
+ IR_CODING_MSB_FIRST, /* MSB first */
+ CARRIER_UNIT, /* unit is us */
+ 6, /* header length */
+ {
+ IR_PULSE_LOW | 16, IR_PULSE_HIGH | 16, /* Start bit: logical 1 */
+ IR_PULSE_LOW | 32, IR_PULSE_HIGH | 16, /* Enlarged bit */
+ IR_PULSE_LOW | 32, IR_PULSE_HIGH | 32
+ }, /* Toggle bit */
+ {IR_PULSE_LOW | 16, IR_PULSE_HIGH | 16}, /* log0Buf */
+ {IR_PULSE_HIGH | 16, IR_PULSE_LOW | 16}, /* log1Buf */
+ IR_PULSE_LOW | 0 /* stopBuf */
+};
+
+#elif (IR_PROTOTCOL_CARRIER_TYPE == 1)
+
+static IR_DataType RC6_32B_Protocol_Header_Add[5] = {IR_PULSE_HIGH | 2667, IR_PULSE_LOW | 889,
+ IR_PULSE_HIGH | 445, IR_PULSE_LOW | 445,
+ IR_PULSE_HIGH | 445
+ };
+const IR_ProtocolTypeDef RC6_32B_PROTOCOL =
+{
+ 36, /* Carrier freqency */
+ IR_CODING_MSB_FIRST, /* MSB first */
+ TIME_UNIT, /* unit is us */
+ 6, /* header length */
+ {
+ IR_PULSE_LOW | 445, IR_PULSE_HIGH | 445, /* Start bit: logical 1 */
+ IR_PULSE_LOW | 889, IR_PULSE_HIGH | 445, /* Enlarged bit */
+ IR_PULSE_LOW | 889, IR_PULSE_HIGH | 889
+ }, /* Toggle bit */
+ {IR_PULSE_LOW | 445, IR_PULSE_HIGH | 445}, /* log0Buf */
+ {IR_PULSE_HIGH | 445, IR_PULSE_LOW | 445}, /* log1Buf */
+ IR_PULSE_LOW | 0 /* stopBuf */
+};
+
+#endif
+
+/**
+ * @brief Encode data of RC6 protocol.
+ * @param address: user code.
+ * @param command: data code.
+ * @param IR_DataStruct: pointer to struct which store RCA code.
+ * @retval None
+ */
+IR_Return_Type RC6_32B_Encode(IR_DataTypeDef *IR_DataStruct)
+{
+ IR_Return_Type return_type;
+
+ /* Encoding toggle bit */
+ if (RC6_Toggle_Flag)
+ {
+ IR_DataStruct->code[2] |= 1 << 7;
+ RC6_Toggle_Flag = false;
+ }
+ else
+ {
+ IR_DataStruct->code[2] &= 0x7F;
+ RC6_Toggle_Flag = true;
+ }
+
+ return_type = IR_Encode(IR_DataStruct, (IR_ProtocolTypeDef *)(&RC6_32B_PROTOCOL), true);
+
+ if (return_type != IR_SUCCEED)
+ {
+ return return_type;
+ }
+
+ memmove(&IR_DataStruct->irBuf[5], IR_DataStruct->irBuf, IR_DataStruct->bufLen * 4);
+
+ for (uint8_t i = 0; i < 5; i++)
+ {
+ IR_DataStruct->irBuf[i] = ConvertToCarrierCycle(RC6_32B_Protocol_Header_Add[i],
+ RC6_32B_PROTOCOL.carrierFreq, RC6_32B_PROTOCOL.unit);
+ }
+ IR_DataStruct->bufLen += 5;
+
+ return return_type;
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/rc6_prot.h b/src/sample/io_sample/IR/SendCode/protocol/rc6_prot.h
new file mode 100644
index 0000000..c853482
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/rc6_prot.h
@@ -0,0 +1,46 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file rc6_prot.h
+* @brief This file provides driver of RC6 protocol encoding.
+* @details
+* @author yuan_feng
+* @date 2018-08-22
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __RC6_PROT_H
+#define __RC6_PROT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include "ir_protocol_config.h"
+#include "ir_encode.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define IR_PROTOTCOL_CARRIER_TYPE 0
+
+
+/**
+ * @brief Configure RC6 protocol repeat code transmission interval
+ */
+
+#define RC6_32B_TRANSMISION_INTERVAL ((uint32_t)((1067*1000 - 1)))
+
+/* Exported functions --------------------------------------------------------*/
+IR_Return_Type RC6_32B_Encode(IR_DataTypeDef *IR_DataStruct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__RC6_PROT_H*/
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/sharp_prot.c b/src/sample/io_sample/IR/SendCode/protocol/sharp_prot.c
new file mode 100644
index 0000000..49b7fd3
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/sharp_prot.c
@@ -0,0 +1,49 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file sharp_prot.c
+* @brief This file provides driver of sharp protocol encoding.
+* @details
+* @author elliot_chen
+* @date 2017-08-21
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "sharp_prot.h"
+
+
+/*!
+* @ brief: SHARP protocol structure.
+* @ note: Store parameters of SHARP protocol.
+* @ Carrier frequency = 38kHz
+* @ duty factor = 1/3
+* @ LSB is sent first !
+*/
+const IR_ProtocolTypeDef SHARP_PROTOCOL =
+{
+ 38, /* Carrier freqency */
+ IR_CODING_LSB_FIRST, /* LSB first */
+ TIME_UNIT, /* unit is us */
+ 0, /* headerLen */
+ {0, 0, 0, 0, 0, 0}, /* headerBuf */
+ {IR_PULSE_HIGH | (264), IR_PULSE_LOW | (786)}, /* log0Buf */
+ {IR_PULSE_HIGH | (264), IR_PULSE_LOW | (1846)}, /* log1Buf */
+ IR_PULSE_HIGH | (264) /* stopBuf */
+};
+
+/**
+ * @brief Encode data of SHARP protocol.
+ * @param IR_DataStruct: pointer to struct which store SHARP code.
+ * @retval None
+ */
+IR_Return_Type SHARP_Encode(IR_DataTypeDef *IR_DataStruct)
+{
+ return IR_Encode(IR_DataStruct, (IR_ProtocolTypeDef *)(&SHARP_PROTOCOL), true);
+}
+
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/sharp_prot.h b/src/sample/io_sample/IR/SendCode/protocol/sharp_prot.h
new file mode 100644
index 0000000..c1c3988
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/sharp_prot.h
@@ -0,0 +1,43 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file sharp_prot.h
+* @brief This file provides driver of sharp protocol encoding.
+* @details
+* @author elliot chen
+* @date 2017-08-21
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __SHARP_PROT_H
+#define __SHARP_PROT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_protocol_config.h"
+#include "ir_encode.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/**
+ * @brief Configure SHARP protocol repeat code transmission interval
+ */
+
+#define SHARP_TRANSMISION_INTERVAL ((uint32_t)((668*1000 - 1)))
+
+/* Exported functions --------------------------------------------------------*/
+IR_Return_Type SHARP_Encode(IR_DataTypeDef *IR_DataStruct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__SHARP_PROT_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/sony6124_prot.c b/src/sample/io_sample/IR/SendCode/protocol/sony6124_prot.c
new file mode 100644
index 0000000..44717ba
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/sony6124_prot.c
@@ -0,0 +1,55 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file sony6124_prot.c
+* @brief This file provides driver of sony 6124 protocol encoding.
+* @details
+* @author elliot_chen
+* @date 2017-08-17
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "sony6124_prot.h"
+
+
+/*!
+* @ brief:sony 6124 protocol structure.
+* @ note: Store parameters of sony 6124 protocol.
+* @ Carrier frequency = 40kHz
+* @ duty factor = 1/3
+* @ LSB is sent first !
+*/
+const IR_ProtocolTypeDef SONY6124_PROTOCOL =
+{
+ 40, /* Carrier freqency */
+ IR_CODING_LSB_FIRST, /* LSB first */
+ TIME_UNIT, /* unit is us */
+ 2, /* headerLen */
+ {
+ IR_PULSE_HIGH | 2400, IR_PULSE_LOW | 600,
+ 0, 0,
+ 0, 0
+ }, /* headerBuf */
+ {IR_PULSE_HIGH | 600, IR_PULSE_LOW | 600}, /* log0Buf */
+ {IR_PULSE_HIGH | 1200, IR_PULSE_LOW | 600}, /* log1Buf */
+ 0, /* stopBuf */
+};
+
+/**
+ * @brief Encode data of SONY 6124 protocol.
+ * @param address: user code.
+ * @param command: data code.
+ * @param IR_DataStruct: pointer to struct which store RCA code.
+ * @retval None
+ */
+IR_Return_Type SONY6124_Encode(IR_DataTypeDef *IR_DataStruct)
+{
+ return IR_Encode(IR_DataStruct, (IR_ProtocolTypeDef *)(&SONY6124_PROTOCOL), false);
+}
+
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/sony6124_prot.h b/src/sample/io_sample/IR/SendCode/protocol/sony6124_prot.h
new file mode 100644
index 0000000..4fff89f
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/sony6124_prot.h
@@ -0,0 +1,43 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file sony6124_prot.h
+* @brief This file provides driver of sony 6124 protocol encoding.
+* @details
+* @author elliot chen
+* @date 2017-08-17
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __SONY6124_PROT_H
+#define __SONY6124_PROT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_protocol_config.h"
+#include "ir_encode.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/**
+ * @brief Configure SONY 6124 protocol repeat code transmission interval
+ */
+
+#define SONY6124_TRANSMISION_INTERVAL ((uint32_t)((45*10000 - 1)))
+
+/* Exported functions --------------------------------------------------------*/
+IR_Return_Type SONY6124_Encode(IR_DataTypeDef *IR_DataStruct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__SONY6124_PROT_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/tc9012_prot.c b/src/sample/io_sample/IR/SendCode/protocol/tc9012_prot.c
new file mode 100644
index 0000000..73f9d62
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/tc9012_prot.c
@@ -0,0 +1,108 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file tc9012_prot.c
+* @brief This file provides driver of TC9012 protocol encoding.
+* @details
+* @author elliot_chen
+* @date 2017-08-21
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "tc9012_prot.h"
+
+
+/*!
+* @ brief: TC9012 protocol structure.
+* @ note: Store parameters of TC9012 protocol.
+* @ Carrier frequency = 38kHz
+* @ duty factor = 1/3
+* @ first pulse : 4.5ms 4.5ms
+* @ Custom (8 bits) is sent first, then ~Custom
+* @ Data (8 bits) follows, then ~Data
+* @ LSB is sent first !
+*/
+const IR_ProtocolTypeDef TC9012_PROTOCOL =
+{
+ 38, /* Carrier freqency */
+ IR_CODING_LSB_FIRST, /* LSB first */
+ TIME_UNIT, /* unit is us */
+ 2, /* headerLen */
+ {
+ IR_PULSE_HIGH | 4500, IR_PULSE_LOW | 4500,
+ 0, 0,
+ 0, 0
+ }, /* headerBuf */
+ {IR_PULSE_HIGH | 560, IR_PULSE_LOW | 565}, /* log0Buf */
+ {IR_PULSE_HIGH | 560, IR_PULSE_LOW | 1690}, /* log1Buf */
+ IR_PULSE_HIGH | 560 /* stopBuf */
+};
+
+/*!
+* @ User can modify this data structure to send user-defined repeat code!!!
+* @ brief: IR repeat code protocol structure.
+* @ note: Store parameters of repeat code protocol.
+*/
+const IR_RepeatCodeTypeDef TC9012_REPEAT_CODE0_PROTOCOL =
+{
+ TIME_UNIT, /* unit is us */
+ 5, /* length of repeat code */
+ {
+ IR_PULSE_HIGH | 4500, IR_PULSE_LOW | 4500, \
+ IR_PULSE_HIGH | 560, IR_PULSE_LOW | 1690, \
+ IR_PULSE_HIGH | 560
+ }
+};
+
+/*!
+* @ User can modify this data structure to send user-defined repeat code!!!
+* @ brief: IR repeat code protocol structure.
+* @ note: Store parameters of repeat code protocol.
+*/
+const IR_RepeatCodeTypeDef TC9012_REPEAT_CODE1_PROTOCOL =
+{
+ TIME_UNIT, /* unit is us */
+ 5, /* length of repeat code */
+ {
+ IR_PULSE_HIGH | 4500, IR_PULSE_LOW | 4500, \
+ IR_PULSE_HIGH | 560, IR_PULSE_LOW | 565, \
+ IR_PULSE_HIGH | 560
+ }
+};
+
+/**
+ * @brief Encode data of NEC protocol.
+ * @param address: user code.
+ * @param command: data code.
+ * @param IR_DataStruct: pointer to struct which store RCA code.
+ * @retval None
+ */
+IR_Return_Type TC9012_Encode(IR_DataTypeDef *IR_DataStruct)
+{
+ return IR_Encode(IR_DataStruct, (IR_ProtocolTypeDef *)(&TC9012_PROTOCOL), true);
+}
+
+/**
+ * @brief Encode data of repeat code protocol.
+ * @param frequency: carrier frequency whose uinit is KHz.
+ * @param IR_DataStruct: pointer to struct which store repeat code data.
+ * @retval None
+ */
+IR_Return_Type TC9012_RepeatCodeEncode(IR_DataTypeDef *IR_DataStruct)
+{
+ if ((IR_DataStruct->code[0]) & 0x01)
+ {
+ return IR_RepeatCodeEncode(IR_DataStruct, (IR_RepeatCodeTypeDef *)(&TC9012_REPEAT_CODE1_PROTOCOL));
+ }
+ else
+ {
+ return IR_RepeatCodeEncode(IR_DataStruct, (IR_RepeatCodeTypeDef *)(&TC9012_REPEAT_CODE0_PROTOCOL));
+ }
+}
+
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/tc9012_prot.h b/src/sample/io_sample/IR/SendCode/protocol/tc9012_prot.h
new file mode 100644
index 0000000..1773ab0
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/tc9012_prot.h
@@ -0,0 +1,44 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file tc9012_prot.h
+* @brief This file provides driver of tc9012 protocol encoding.
+* @details
+* @author elliot chen
+* @date 2017-08-21
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __TC9012_PROT_H
+#define __TC9012_PROT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_protocol_config.h"
+#include "ir_encode.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/**
+ * @brief Configure TC9012 protocol repeat code transmission interval
+ */
+
+#define TC9012_TRANSMISION_INTERVAL ((uint32_t)((108*10000 - 1)))
+
+/* Exported functions --------------------------------------------------------*/
+IR_Return_Type TC9012_Encode(IR_DataTypeDef *IR_DataStruct);
+IR_Return_Type TC9012_RepeatCodeEncode(IR_DataTypeDef *IR_DataStruct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__TC9012_PROT_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/victorc8d8_prot.c b/src/sample/io_sample/IR/SendCode/protocol/victorc8d8_prot.c
new file mode 100644
index 0000000..d63f015
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/victorc8d8_prot.c
@@ -0,0 +1,53 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file VICTORC8D8_prot.c
+* @brief This file provides driver of VICTORC8D8 protocol encoding.
+* @details
+* @author elliot_chen
+* @date 2017-08-21
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "victorc8d8_prot.h"
+
+
+/*!
+* @ brief: VICTORC8D8 protocol structure.
+* @ note: Store parameters of VICTORC8D8 protocol.
+* @ Carrier frequency = 38kHz
+* @ duty factor = 1/3
+* @ LSB is sent first !
+*/
+const IR_ProtocolTypeDef VICTORC8D8_PROTOCOL =
+{
+ 38, /* Carrier freqency */
+ IR_CODING_LSB_FIRST, /* LSB first */
+ CARRIER_UNIT, /* unit is carrier period */
+ 2, /* headerLen */
+ {
+ IR_PULSE_HIGH | (20 * 16), IR_PULSE_LOW | (20 * 8), /* headerBuf */
+ 0, 0,
+ 0, 0
+ },
+ {IR_PULSE_HIGH | (20), IR_PULSE_LOW | (20)}, /* log0Buf */
+ {IR_PULSE_HIGH | (20), IR_PULSE_LOW | (20 * 3)}, /* log1Buf */
+ IR_PULSE_HIGH | (20) /* stopBuf */
+};
+
+/**
+ * @brief Encode data of VICTORC8D8 protocol.
+ * @param IR_DataStruct: pointer to struct which store VICTORC8D8 code.
+ * @retval None
+ */
+IR_Return_Type VICTORC8D8_Encode(IR_DataTypeDef *IR_DataStruct)
+{
+ return IR_Encode(IR_DataStruct, (IR_ProtocolTypeDef *)(&VICTORC8D8_PROTOCOL), true);
+}
+
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/protocol/victorc8d8_prot.h b/src/sample/io_sample/IR/SendCode/protocol/victorc8d8_prot.h
new file mode 100644
index 0000000..558040c
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/protocol/victorc8d8_prot.h
@@ -0,0 +1,44 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file victorc8d8_prot.h
+* @brief This file provides driver of victorc8d8 protocol encoding.
+* @details
+* @author elliot chen
+* @date 2017-08-21
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __VICTORC8D8_PROT_H
+#define __VICTORC8D8_PROT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ir_protocol_config.h"
+#include "ir_encode.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/**
+ * @brief Configure VICTORC8D8 protocol repeat code transmission interval
+ */
+
+#define VICTORC8D8_TRANSMISION_INTERVAL ((uint32_t)((589211 - 1)))//112T
+#define VICTORC8D8_TRANSMISION_RE_INTERVAL ((uint32_t)((462895 - 1)))//88T
+
+/* Exported functions --------------------------------------------------------*/
+IR_Return_Type VICTORC8D8_Encode(IR_DataTypeDef *IR_DataStruct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__VICTORC8D8_PROT_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/SendCode/trans/ir_trans.c b/src/sample/io_sample/IR/SendCode/trans/ir_trans.c
new file mode 100644
index 0000000..5438be9
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/trans/ir_trans.c
@@ -0,0 +1,928 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file ir_trans.c
+* @brief This file provides IR transmission layer driver.
+* @details
+* @author elliot chen
+* @date 2017-08-15
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes -----------------------------------------------------------------*/
+#include "ir_trans.h"
+#include "string.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+/* Number of protocols used in application */
+#define IR_PROTOCOL_TYPE_SUPPORT_NUM 15
+
+#ifdef IR_ONE_FRAME_SEND_TWICE
+/* One frame send control which have no repeat code */
+#define UIR_ONE_FRAME_COUNT 2
+#endif
+
+/* IR protocol encoder function library */
+const IR_ProtocolEncodeLib_t ProtocolLib[IR_PROTOCOL_TYPE_SUPPORT_NUM] =
+{
+ {Raw_Pack_Encode, Raw_Pack_Encode, 38, NEC_TRANSMISION_INTERVAL},
+ {NEC_Encode, NEC_RepeatCodeEncode, 38, NEC_TRANSMISION_INTERVAL},
+ {RC5_Encode, NULL, 38, RC5_TRANSMISION_INTERVAL},
+ {SONY6124_Encode, NULL, 40, SONY6124_TRANSMISION_INTERVAL},
+ {LC7464M_Encode, NULL, 38, LC7464M_TRANSMISION_INTERVAL},
+ {TC9012_Encode, TC9012_RepeatCodeEncode, 38, TC9012_TRANSMISION_INTERVAL},
+ {MITC8D8_Encode, NULL, 38, MITC8D8_TRANSMISION_INTERVAL},
+ {PIONEER_Encode, PIONEER_Encode, 40, PIONEER_TRANSMISION_INTERVAL},
+ {VICTORC8D8_Encode, NULL, 38, VICTORC8D8_TRANSMISION_INTERVAL},
+ {DVB_Encode, NULL, 38, DVB_TRANSMISION_INTERVAL},
+ {SHARP_Encode, SHARP_Encode, 38, SHARP_TRANSMISION_INTERVAL},
+ {KONICA_Encode, KONICA_RepeatCodeEncode, 38, KONICA_TRANSMISION_INTERVAL},
+ {NEC_Encode, NEC_Encode, 38, NEC_TRANSMISION_INTERVAL},
+ {RC6_32B_Encode, NULL, 36, RC6_32B_TRANSMISION_INTERVAL},
+ {DVB_40BIT_Encode, DVB_40BIT_RepeatCodeEncode, 38, DVB_40BIT_TRANSMISION_INTERVAL},
+};
+
+/* Internal defines */
+#define IR_BIT_LEN_TO_BYTE_LEN 7
+#define IR_BYTE_LEN 8
+
+/* Globals ------------------------------------------------------------------*/
+/* Data structure which store encoded data */
+IR_DataTypeDef IR_DataStruct;
+
+/* Number of data which has been sent */
+volatile uint16_t ir_tx_count = 0;
+
+/* Data structure which store universal parameter information */
+UIR_PARAM_INFO uir_param_info_base;
+
+/* Record Pioneer send status */
+static UIR_ALTERNATE_SEND_STATUS uir_pioneer_send_status = UIR_ALTERNATE_NO_SENDING;
+
+/* Record sharp send status */
+static UIR_ALTERNATE_SEND_STATUS uir_sharp_send_status = UIR_ALTERNATE_NO_SENDING;
+
+#ifdef IR_ONE_FRAME_SEND_TWICE
+/* Record send status in one frame mode */
+static volatile uint8_t uir_one_frame_send_count = 0;
+static UIR_ALTERNATE_SEND_STATUS uir_one_frame_send_status = UIR_ALTERNATE_NO_SENDING;
+#endif
+
+/* Function pointer used to send event and message to app task from IR interrupt handle */
+static pfnIntrHandlerCB_t pfnIRIntrHandlerCB = NULL;
+
+#ifdef IR_WAVEFORM_INTERVAL_CTRL
+/* Function pointer used to send event and message to app task from Timer interrupt handle when send continuously */
+static pfnIntrHandlerCB_t pfnTIMIntrHandlerCB = NULL;
+#endif
+
+void IR_Handler(void);
+
+/**
+ * @brief initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void Board_IR_Init(void)
+{
+ Pad_Config(IR_SEND_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pinmux_Config(IR_SEND_PIN, IRDA_TX);
+}
+
+/**
+ * @brief Initialize IR peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void Driver_IR_Init(uint32_t freq)
+{
+ /* Disable IR clock */
+ RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, DISABLE);
+ /* Enable IR clock */
+ RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, ENABLE);
+
+ /* Initialize IR */
+ IR_InitTypeDef IR_InitStruct;
+ IR_StructInit(&IR_InitStruct);
+ IR_InitStruct.IR_Freq = freq;
+ IR_InitStruct.IR_DutyCycle = 2; /* !< 1/2 duty cycle */
+ IR_InitStruct.IR_Mode = IR_MODE_TX;
+ IR_InitStruct.IR_TxInverse = IR_TX_DATA_NORMAL;
+ IR_InitStruct.IR_TxFIFOThrLevel = IR_TX_FIFO_THR_LEVEL;
+ IR_InitStruct.IR_TxIdleLevel = IR_IDLE_OUTPUT_LOW;
+ IR_Init(&IR_InitStruct);
+ IR_Cmd(IR_MODE_TX, ENABLE);
+ /* Modify IR interrupt handle */
+ RamVectorTableUpdate(IR_VECTORn, IR_Handler);
+
+ /* Configure NVIC */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = IR_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/**
+ * @brief Initialize TIM peripheral which used to send repeat code.
+ * @param No parameter.
+ * @return void
+ */
+void Driver_IR_TIM_Init(void)
+{
+ /* Enable TIM clock */
+ RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+
+ /* Initialize TIM */
+ TIM_TimeBaseInitTypeDef TIM_InitStruct;
+ TIM_StructInit(&TIM_InitStruct);
+ /* Timer clock = 10MHz */
+ TIM_InitStruct.TIM_SOURCE_DIV = TIM_CLOCK_DIVIDER_4;
+ TIM_InitStruct.TIM_Period = 0xFFFFFFFF;
+ TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ TIM_TimeBaseInit(IR_TIM, &TIM_InitStruct);
+ TIM_INTConfig(IR_TIM, ENABLE);
+
+ /* Configure NVIC */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = IR_TIM_IRQ;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 2;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/**
+ * @brief Configure IR repeat code transmission interval and control repeat send function.
+ * @param interval: IR repeat code transmission interval.
+ * @param NewState: Enabel or disable sending repeat code.
+ * @return void
+ */
+void UIR_BurstSendCmd(uint32_t interval, FunctionalState NewState)
+{
+ if (NewState != DISABLE)
+ {
+ /* Enable transmission continuously */
+ TIM_Cmd(IR_TIM, DISABLE);
+ TIM_ChangePeriod(IR_TIM, interval);
+ TIM_Cmd(IR_TIM, ENABLE);
+ }
+ else
+ {
+ /* Disable transmission continuously */
+ TIM_Cmd(IR_TIM, DISABLE);
+ }
+}
+
+/**
+ * @brief Get timer status.
+ * @param none.
+ * @return execution status.
+ */
+UIR_STATUS UIR_GetTIMStatus(void)
+{
+ if (!(IR_TIM->ControlReg & BIT(0)))
+ {
+ return UIR_STATUS_NO_ERROR;
+ }
+ else
+ {
+ return UIR_STATUS_ALREADY_IN_TRANSMITTING;
+ }
+}
+
+/**
+ * @brief Send IR waveform data.
+ * @param IR_DataStruct: pointer to struct which store IR data code.
+ * @return none.
+ */
+static void UIR_SendIRWaveform(IR_DataTypeDef *pIR_DataStruct, uint16_t buf_index)
+{
+ /* Start to send first bytes data of encoded data */
+ if (pIR_DataStruct->bufLen >= IR_TX_FIFO_SIZE)
+ {
+ /* Enable IR threshold interrupt. Only when TX FIFO offset = threshold value, trigger interrupt */
+ IR_SetTxThreshold(IR_TX_FIFO_THR_LEVEL);
+
+ IR_SendBuf(&(pIR_DataStruct->irBuf[buf_index]), IR_TX_FIFO_SIZE, DISABLE);
+
+ /* Record number which has been sent */
+ ir_tx_count = IR_TX_FIFO_SIZE;
+
+ IR_INTConfig(IR_INT_TF_LEVEL, ENABLE);
+ }
+ else
+ {
+ IR_SendBuf(&(pIR_DataStruct->irBuf[buf_index]), pIR_DataStruct->bufLen, DISABLE);
+
+ /* Record number which has been sent */
+ ir_tx_count = pIR_DataStruct->bufLen;
+
+ /* Enable IR Tx FIFO empty interrupt */
+ IR_INTConfig(IR_INT_TF_EMPTY, ENABLE);
+ }
+}
+
+/**
+ * @brief copy first code from IR database struct.
+ * @param uir_param_info: universal parameter information.
+ * @param IR_DataStruct: pointer to struct which store IR data code.
+ * @return none.
+ */
+static void UIR_GetFirstCode(UIR_PARAM_INFO *uir_param_info, IR_DataTypeDef *pIR_DataStruct)
+{
+ //memset(pIR_DataStruct, 0, sizeof(IR_DataTypeDef));
+ pIR_DataStruct->carrierFreq = ProtocolLib[uir_param_info->uir_protocol_index].carrierFreq;
+ pIR_DataStruct->custom_bit_len = uir_param_info->custom_code_length;
+ pIR_DataStruct->key_bit_len = uir_param_info->key_code_length;
+
+ memcpy(pIR_DataStruct->code, uir_param_info->custom_code_value,
+ (uir_param_info->custom_code_length + IR_BIT_LEN_TO_BYTE_LEN) / IR_BYTE_LEN);
+
+ memcpy(pIR_DataStruct->code + (uir_param_info->custom_code_length + IR_BIT_LEN_TO_BYTE_LEN) /
+ IR_BYTE_LEN,
+ uir_param_info->key_code_value,
+ (uir_param_info->key_code_length + IR_BIT_LEN_TO_BYTE_LEN) / IR_BYTE_LEN);
+}
+
+/**
+ * @brief copy first code from IR database struct.
+ * @param uir_param_info: universal parameter information.
+ * @param IR_DataStruct: pointer to struct which store IR data code.
+ * @return none.
+ */
+static void UIR_GetSecondCode(UIR_PARAM_INFO *uir_param_info, IR_DataTypeDef *pIR_DataStruct)
+{
+ //memset(pIR_DataStruct, 0, sizeof(IR_DataTypeDef));
+
+ pIR_DataStruct->carrierFreq = ProtocolLib[uir_param_info->uir_protocol_index].carrierFreq;
+ pIR_DataStruct->custom_bit_len = uir_param_info->second_custom_code_length;
+ pIR_DataStruct->key_bit_len = uir_param_info->second_key_code_length;
+
+ memcpy(pIR_DataStruct->code, uir_param_info->second_custom_code_value,
+ (uir_param_info->second_custom_code_length + IR_BIT_LEN_TO_BYTE_LEN) / IR_BYTE_LEN);
+
+ memcpy(pIR_DataStruct->code + (uir_param_info->second_custom_code_length + IR_BIT_LEN_TO_BYTE_LEN) /
+ IR_BYTE_LEN,
+ uir_param_info->second_key_code_value,
+ (uir_param_info->second_key_code_length + IR_BIT_LEN_TO_BYTE_LEN) / IR_BYTE_LEN);
+}
+
+#ifdef RAW_PACK_PROT
+/**
+ * @brief Send IR raw packet protocol data.
+ * @param uir_param_info: universal parameter information.
+ * @param IR_DataStruct: pointer to struct which store IR data code.
+ * @param NewState: Enabel or disable sending repeat code.
+ * @return execution status.
+ */
+static UIR_STATUS UIR_SendRawPack(UIR_PARAM_INFO *uir_param_info, IR_DataTypeDef *pIR_DataStruct,
+ FunctionalState NewState)
+{
+ /* Initialize IR parameters */
+ //memset(pIR_DataStruct, 0, sizeof(IR_DataTypeDef));
+ pIR_DataStruct->carrierFreq = ProtocolLib[uir_param_info->uir_protocol_index].carrierFreq;
+
+ if (uir_param_info->raw_pack_len <= IR_MAX_BUF_SIZE)
+ {
+ memcpy(pIR_DataStruct->irBuf, uir_param_info->pRawPackAddr,
+ uir_param_info->raw_pack_len * sizeof(pIR_DataStruct->irBuf[0]));
+ pIR_DataStruct->bufLen = uir_param_info->raw_pack_len;
+ }
+ else
+ {
+ return UIR_STATUS_EXCEED_MAX_BUF_LEN;
+ }
+
+ /* Initialize IR peripheral or not */
+ if (pIR_DataStruct->carrierFreq != ProtocolLib[uir_param_info->uir_protocol_index].carrierFreq)
+ {
+ Driver_IR_Init(ProtocolLib[uir_param_info->uir_protocol_index].carrierFreq);
+ }
+
+ /* Encode */
+ if (ProtocolLib[uir_param_info->uir_protocol_index].IREncodeFunCb)
+ {
+ if (IR_SUCCEED != (ProtocolLib[uir_param_info->uir_protocol_index].IREncodeFunCb(pIR_DataStruct)))
+ {
+ return UIR_STATUS_ENCODE_ERROR;
+ }
+ }
+ else
+ {
+ APP_PRINT_INFO0("No IR protocol encode function");
+ }
+
+ /* Start to send first bytes data of encoded data */
+ UIR_SendIRWaveform(pIR_DataStruct, 0);
+
+ return UIR_STATUS_NO_ERROR;
+}
+#endif
+
+/**
+ * @brief Send IR protocol data.
+ * @param uir_param_info: universal parameter information.
+ * @param IR_DataStruct: pointer to struct which store IR data code.
+ * @param NewState: Enabel or disable sending repeat code.
+ * @return execution status.
+ */
+static UIR_STATUS UIR_SendData(UIR_PARAM_INFO *uir_param_info, IR_DataTypeDef *pIR_DataStruct,
+ FunctionalState NewState)
+{
+ /* Check parameters */
+ if (uir_param_info->uir_protocol_index > IR_PROTOCOL_TYPE_SUPPORT_NUM)
+ {
+ return UIR_STATUS_INVALID_CODESET_TYPE;
+ }
+
+ /* Initialize IR peripheral or not */
+ if (pIR_DataStruct->carrierFreq != ProtocolLib[uir_param_info->uir_protocol_index].carrierFreq)
+ {
+ Driver_IR_Init(ProtocolLib[uir_param_info->uir_protocol_index].carrierFreq);
+ }
+
+ /* Initialize IR parameters */
+ memset(pIR_DataStruct, 0, sizeof(IR_DataTypeDef));
+ pIR_DataStruct->carrierFreq = ProtocolLib[uir_param_info->uir_protocol_index].carrierFreq;
+ pIR_DataStruct->custom_bit_len = uir_param_info->custom_code_length;
+ pIR_DataStruct->key_bit_len = uir_param_info->key_code_length;
+
+ memcpy(pIR_DataStruct->code, uir_param_info->custom_code_value,
+ (uir_param_info->custom_code_length + IR_BIT_LEN_TO_BYTE_LEN) / IR_BYTE_LEN);
+
+ memcpy(pIR_DataStruct->code + (uir_param_info->custom_code_length + IR_BIT_LEN_TO_BYTE_LEN) /
+ IR_BYTE_LEN,
+ uir_param_info->key_code_value,
+ (uir_param_info->key_code_length + IR_BIT_LEN_TO_BYTE_LEN) / IR_BYTE_LEN);
+
+ /* Encode */
+ if (ProtocolLib[uir_param_info->uir_protocol_index].IREncodeFunCb)
+ {
+ if (IR_SUCCEED != (ProtocolLib[uir_param_info->uir_protocol_index].IREncodeFunCb(pIR_DataStruct)))
+ {
+ return UIR_STATUS_ENCODE_ERROR;
+ }
+ }
+ else
+ {
+ APP_PRINT_INFO0("No IR protocol encode function");
+ }
+
+
+ /* Configure repeat interval and repeat code sending function */
+ if (NewState == ENABLE)
+ {
+ pIR_DataStruct->isSendRepeatcode = true;
+ }
+
+ if ((uir_param_info->uir_protocol_index != UIR_CODESET_TYPE_LC7464M) && \
+ (uir_param_info->uir_protocol_index != UIR_CODESET_TYPE_DVB) && \
+ (uir_param_info->uir_protocol_index != UIR_CODESET_TYPE_MIT_C8D8) && \
+ (uir_param_info->uir_protocol_index != UIR_CODESET_TYPE_KONICA) && \
+ (uir_param_info->uir_protocol_index != UIR_CODESET_TYPE_DVB_40BIT))
+ {
+ UIR_BurstSendCmd(ProtocolLib[uir_param_info->uir_protocol_index].repeat_interval, NewState);
+ }
+
+ /* Start to send first bytes data of encoded data */
+ UIR_SendIRWaveform(pIR_DataStruct, 0);
+
+ return UIR_STATUS_NO_ERROR;
+}
+
+/**
+ * @brief Send IR pioneer protocol repeat data alternately.(A->B->A->B)
+ * @param uir_param_info: universal parameter information.
+ * @param IR_DataStruct: pointer to struct which store IR data code.
+ * @return none.
+ */
+static void UIR_PioneerAlternateSendRepeatData(UIR_PARAM_INFO *uir_param_info,
+ IR_DataTypeDef *pIR_DataStruct)
+{
+ if (uir_param_info->is_second_code_valid)
+ {
+ if (uir_pioneer_send_status == UIR_ALTERNATE_REPEAT_SEND_FIRST_DATA)
+ {
+ uir_pioneer_send_status = UIR_ALTERNATE_REPEAT_SEND_SECOND_DATA;
+ UIR_GetSecondCode(uir_param_info, pIR_DataStruct);
+ }
+ else if (uir_pioneer_send_status == UIR_ALTERNATE_REPEAT_SEND_SECOND_DATA)
+ {
+ uir_pioneer_send_status = UIR_ALTERNATE_REPEAT_SEND_FIRST_DATA;
+ UIR_GetFirstCode(uir_param_info, pIR_DataStruct);
+ }
+ else
+ {
+ if (uir_pioneer_send_status == UIR_ALTERNATE_SEND_ONE_FRAME_DATA)
+ {
+ uir_pioneer_send_status = UIR_ALTERNATE_NO_SENDING;
+ UIR_GetSecondCode(uir_param_info, pIR_DataStruct);
+ UIR_BurstSendCmd(0, DISABLE);
+ }
+ else
+ {
+ APP_PRINT_INFO1("Pioneer error: uir_pioneer_send_status = 0x%x!", uir_pioneer_send_status);
+ return;
+ }
+ }
+ }
+}
+
+/**
+ * @brief Send IR sharp protocol repeat data alternately.
+ * @param uir_param_info: universal parameter information.
+ * @param IR_DataStruct: pointer to struct which store IR data code.
+ * @return none.
+ */
+static void UIR_SharpAlternateSendRepeatData(UIR_PARAM_INFO *uir_param_info,
+ IR_DataTypeDef *pIR_DataStruct)
+{
+ if (uir_param_info->is_second_code_valid)
+ {
+ if (uir_sharp_send_status == UIR_ALTERNATE_REPEAT_SEND_FIRST_DATA)
+ {
+ uir_sharp_send_status = UIR_ALTERNATE_REPEAT_SEND_SECOND_DATA;
+ UIR_GetSecondCode(uir_param_info, pIR_DataStruct);
+ }
+ else if (uir_sharp_send_status == UIR_ALTERNATE_REPEAT_SEND_SECOND_DATA)
+ {
+ uir_sharp_send_status = UIR_ALTERNATE_REPEAT_SEND_FIRST_DATA;
+ UIR_GetFirstCode(uir_param_info, pIR_DataStruct);
+ }
+ else
+ {
+ if (uir_sharp_send_status == UIR_ALTERNATE_SEND_ONE_FRAME_DATA)
+ {
+ uir_sharp_send_status = UIR_ALTERNATE_SEND_ONE_FRAME_SECOND_DATA;
+ UIR_GetSecondCode(uir_param_info, pIR_DataStruct);
+ }
+ else if (uir_sharp_send_status == UIR_ALTERNATE_SEND_ONE_FRAME_SECOND_DATA)
+ {
+ uir_sharp_send_status = UIR_ALTERNATE_NO_SENDING;
+ UIR_GetFirstCode(uir_param_info, pIR_DataStruct);
+ UIR_BurstSendCmd(0, DISABLE);
+ }
+ else
+ {
+ APP_PRINT_INFO1("Pioneer error: uir_pioneer_send_status = 0x%x!", uir_sharp_send_status);
+ return;
+ }
+ }
+ }
+}
+
+#ifdef IR_ONE_FRAME_SEND_TWICE
+/**
+ * @brief Send IR sony 6124 protocol data continuously.
+ * @param none.
+ * @return none.
+ */
+static uint8_t UIR_OneFrameSendContinuously(void)
+{
+ if (uir_one_frame_send_count > 0)
+ {
+ uir_one_frame_send_count--;
+ if (!uir_one_frame_send_count)
+ {
+ IR_DataStruct.isSendRepeatcode = false;
+ uir_one_frame_send_status = UIR_ALTERNATE_NO_SENDING;
+ UIR_BurstSendCmd(0, DISABLE);
+ }
+ }
+
+ return uir_one_frame_send_count;
+}
+#endif
+
+/**
+ * @brief Send IR protocol repeat data.
+ * @param uir_param_info: universal parameter information.
+ * @param IR_DataStruct: pointer to struct which store IR data code.
+ * @return execution status.
+ */
+static UIR_STATUS UIR_SendRepeatData(UIR_PARAM_INFO *uir_param_info, IR_DataTypeDef *pIR_DataStruct)
+{
+ /* Check repeat encode function */
+ if (ProtocolLib[uir_param_info->uir_protocol_index].IRRepeatCodeEncodeFunCb)
+ {
+ if ((uir_param_info->uir_protocol_index == UIR_CODESET_TYPE_Pioneer) || \
+ (uir_param_info->uir_protocol_index == UIR_CODESET_TYPE_SHARP))
+ {
+ if (uir_param_info->uir_protocol_index == UIR_CODESET_TYPE_Pioneer)
+ {
+ UIR_PioneerAlternateSendRepeatData(uir_param_info, pIR_DataStruct);
+ }
+ else
+ {
+ UIR_SharpAlternateSendRepeatData(uir_param_info, pIR_DataStruct);
+ }
+
+ if (IR_SUCCEED != ProtocolLib[uir_param_info->uir_protocol_index].IRRepeatCodeEncodeFunCb(
+ pIR_DataStruct))
+ {
+ return UIR_STATUS_ENCODE_ERROR;
+ }
+ }
+ else
+ {
+ if (pIR_DataStruct->isRepeatcodeEncoded == false)
+ {
+ if (IR_SUCCEED != ProtocolLib[uir_param_info->uir_protocol_index].IRRepeatCodeEncodeFunCb(
+ pIR_DataStruct))
+ {
+ return UIR_STATUS_ENCODE_ERROR;
+ }
+ pIR_DataStruct->isRepeatcodeEncoded = true;
+ }
+ }
+
+ UIR_SendIRWaveform(pIR_DataStruct, 0);
+ }
+ else
+ {
+ /* Special protocol interval config */
+ if (uir_param_info->uir_protocol_index == UIR_CODESET_TYPE_Victor_C8D8)
+ {
+ if (pIR_DataStruct->isRepeatcodeEncoded == false)
+ {
+ pIR_DataStruct->bufLen -= 2;
+ pIR_DataStruct->isRepeatcodeEncoded = true;
+ }
+
+ UIR_BurstSendCmd(VICTORC8D8_TRANSMISION_RE_INTERVAL, ENABLE);
+
+ UIR_SendIRWaveform(pIR_DataStruct, 2);
+ }
+ else
+ {
+ UIR_SendIRWaveform(pIR_DataStruct, 0);
+ }
+ }
+
+#ifdef IR_ONE_FRAME_SEND_TWICE
+ if ((uir_param_info->uir_protocol_index != UIR_CODESET_TYPE_Pioneer) && \
+ (uir_param_info->uir_protocol_index != UIR_CODESET_TYPE_SHARP))
+ {
+ if (uir_one_frame_send_status == UIR_ALTERNATE_SEND_ONE_FRAME_DATA)
+ {
+ UIR_OneFrameSendContinuously();
+ }
+ }
+#endif
+
+ return UIR_STATUS_NO_ERROR;
+}
+
+/**
+ * @brief Initialize IR transmission layer module.
+ * @param No parameter.
+ * @return void
+ */
+void UIR_TransInit(void)
+{
+ Board_IR_Init();
+ memset(&IR_DataStruct, 0, sizeof(IR_DataTypeDef));
+ ir_tx_count = 0;
+ Driver_IR_Init(38000);
+ Driver_IR_TIM_Init();
+}
+
+/**
+ * @brief Configure universal parameter information.
+ * @param No parameter.
+ * @return void
+ */
+UIR_STATUS UIR_ParaInit(UIR_PARAM_INFO *uir_param_info)
+{
+ /* Check parameters */
+ if (uir_param_info->custom_code_length > MAX_CUSTOM_CODE_BIT_LEN)
+ {
+ return UIR_STATUS_CUSTOM_CODE_OVERFLOW;
+ }
+
+ if (uir_param_info->key_code_length > MAX_KEY_CODE_BIT_LEN)
+ {
+ return UIR_STATUS_KEY_CODE_OVERFLOW;
+ }
+
+ if ((uir_param_info->custom_code_length + uir_param_info->key_code_length) == 0)
+ {
+ return UIR_STATUS_CUSTOM_KEY_CODE_LEN_ZERO;
+ }
+
+ if (uir_param_info->is_second_code_valid == true)
+ {
+ if (uir_param_info->second_custom_code_length > MAX_CUSTOM_CODE_BIT_LEN)
+ {
+ return UIR_STATUS_SECOND_CUSTOM_CODE_OVERFLOW;
+ }
+
+ if (uir_param_info->second_key_code_length > MAX_KEY_CODE_BIT_LEN)
+ {
+ return UIR_STATUS_SECOND_KEY_CODE_OVERFLOW;
+ }
+ }
+
+ memcpy(&uir_param_info_base, uir_param_info, sizeof(UIR_PARAM_INFO));
+
+ return UIR_STATUS_NO_ERROR;
+}
+
+/**
+ * @brief Send one frame universal IR data.
+ * @param uir_param_info: universal parameter information.
+ * @return execution status.
+ */
+UIR_STATUS UIR_OneFrameTransmitting(UIR_PARAM_INFO *uir_param_info, FunctionalState NewState)
+{
+#ifdef RAW_PACK_PROT
+ if (uir_param_info->uir_protocol_index == UIR_CODESET_TYPE_RAW_Pack)
+ {
+ memcpy(&uir_param_info_base, uir_param_info, sizeof(UIR_PARAM_INFO));
+ return UIR_SendRawPack(&uir_param_info_base, &IR_DataStruct, DISABLE);
+ }
+#endif
+
+ UIR_STATUS status = UIR_ParaInit(uir_param_info);
+
+ if (status != UIR_STATUS_NO_ERROR)
+ {
+ return status;
+ }
+
+ if (uir_param_info->uir_protocol_index == UIR_CODESET_TYPE_Pioneer)
+ {
+ uir_pioneer_send_status = UIR_ALTERNATE_SEND_ONE_FRAME_DATA;
+
+ return UIR_SendData(&uir_param_info_base, &IR_DataStruct, ENABLE);
+ }
+ else if (uir_param_info->uir_protocol_index == UIR_CODESET_TYPE_SHARP)
+ {
+ uir_sharp_send_status = UIR_ALTERNATE_SEND_ONE_FRAME_DATA;
+
+ return UIR_SendData(&uir_param_info_base, &IR_DataStruct, ENABLE);
+ }
+#ifdef IR_ONE_FRAME_SEND_TWICE
+ /* Send two times */
+ else
+ {
+ if (NewState == ENABLE)
+ {
+ uir_one_frame_send_count = UIR_ONE_FRAME_COUNT;
+ uir_one_frame_send_status = UIR_ALTERNATE_SEND_ONE_FRAME_DATA;
+ UIR_OneFrameSendContinuously();
+ return UIR_SendData(&uir_param_info_base, &IR_DataStruct, ENABLE);
+ }
+ else
+ {
+ return UIR_SendData(&uir_param_info_base, &IR_DataStruct, DISABLE);
+ }
+ }
+#else
+ else
+ {
+ return UIR_SendData(&uir_param_info_base, &IR_DataStruct, DISABLE);
+ }
+#endif
+}
+
+/**
+ * @brief Send universal IR data continuously.
+ * @param uir_param_info: universal parameter information.
+ * @return execution status.
+ */
+UIR_STATUS UIR_StartContinuouslyTransmitting(UIR_PARAM_INFO *uir_param_info)
+{
+ UIR_STATUS status = UIR_ParaInit(uir_param_info);
+
+ if (status != UIR_STATUS_NO_ERROR)
+ {
+ return status;
+ }
+
+ /* Special protocol control */
+ if (uir_param_info->uir_protocol_index == UIR_CODESET_TYPE_Pioneer)
+ {
+ uir_pioneer_send_status = UIR_ALTERNATE_REPEAT_SEND_FIRST_DATA;
+ }
+
+ if (uir_param_info->uir_protocol_index == UIR_CODESET_TYPE_SHARP)
+ {
+ uir_sharp_send_status = UIR_ALTERNATE_REPEAT_SEND_FIRST_DATA;
+ }
+
+ return UIR_SendData(&uir_param_info_base, &IR_DataStruct, ENABLE);
+}
+
+/**
+ * @brief Stop sending universal IR data continuously.
+ * @param uir_param_info: universal parameter information.
+ * @return execution status.
+ */
+UIR_STATUS UIR_StopContinuouslyTransmitting(void)
+{
+#ifdef IR_WAVEFORM_INTERVAL_CTRL
+ IR_DataStruct.intervalCtrl = true;
+
+ if (IR_DataStruct.isTimerOccurred)
+ {
+ return UIR_STATUS_SEND_REPEAT_CODE;
+ }
+ else
+ {
+ /* Stop to send repeat code */
+ UIR_BurstSendCmd(0, DISABLE);
+ IR_DataStruct.isSendRepeatcode = false;
+ IR_DataStruct.intervalCtrl = false;
+ IR_DataStruct.isTimerOccurred = false;
+
+ if (ir_tx_count > 0)
+ {
+ return UIR_STATUS_ALREADY_IN_TRANSMITTING;
+ }
+ else
+ {
+ return UIR_STATUS_SEND_FIRST_FRAME;
+ }
+ }
+#else
+ /* Stop to send repeat code */
+ IR_DataStruct.isSendRepeatcode = false;
+ UIR_BurstSendCmd(0, DISABLE);
+
+ if (ir_tx_count > 0)
+ {
+ return UIR_STATUS_ALREADY_IN_TRANSMITTING;
+ }
+
+ return UIR_STATUS_NO_ERROR;
+#endif
+}
+
+/**
+ * @brief Register callback function to send events from IR interrupt handle to application.
+ * @param pFunc callback function.
+ * @return none
+*/
+void UIR_RegisterIRIntrHandlerCB(pfnIntrHandlerCB_t pFunc)
+{
+ pfnIRIntrHandlerCB = pFunc;
+}
+
+#ifdef IR_WAVEFORM_INTERVAL_CTRL
+/**
+ * @brief Register callback function to send events from Timer interrupt handle to application.
+ * @param pFunc callback function.
+ * @return none
+*/
+void UIR_RegisterTIMIntrHandlerCB(pfnIntrHandlerCB_t pFunc)
+{
+ pfnTIMIntrHandlerCB = pFunc;
+}
+#endif
+
+/**
+* @brief IR interrupt handler function.
+* @param No parameter.
+* @return void
+*/
+void IR_Handler(void)
+{
+ ITStatus int_status_tfl = IR_GetINTStatus(IR_INT_TF_LEVEL);
+ ITStatus int_status_tfe = IR_GetINTStatus(IR_INT_TF_EMPTY);
+ /* Mask IR interrupt */
+ IR_MaskINTConfig(IR_INT_TF_LEVEL, ENABLE);
+ IR_MaskINTConfig(IR_INT_TF_EMPTY, ENABLE);
+
+ /* Continue to send by interrupt */
+ if (int_status_tfl == SET)
+ {
+ /* The remaining data is larger than the TX FIFO length */
+ if ((IR_DataStruct.bufLen - ir_tx_count) >= IR_TX_FIFO_SIZE)
+ {
+ IR_SendBuf(IR_DataStruct.irBuf + ir_tx_count, IR_TX_FIFO_SIZE - IR_TX_FIFO_THR_LEVEL, DISABLE);
+ ir_tx_count += (IR_TX_FIFO_SIZE - IR_TX_FIFO_THR_LEVEL);
+ }
+ else if ((IR_DataStruct.bufLen - ir_tx_count) > 0)
+ {
+ /* The remaining data is less than the TX FIFO length */
+ IR_INTConfig(IR_INT_TF_LEVEL, DISABLE);
+
+ /* Enable IR tx empty interrupt */
+ IR_INTConfig(IR_INT_TF_EMPTY, ENABLE);
+ IR_SendBuf(IR_DataStruct.irBuf + ir_tx_count, IR_DataStruct.bufLen - ir_tx_count, DISABLE);
+ ir_tx_count = IR_DataStruct.bufLen;
+ }
+ else
+ {
+ /* Disable IR tx empty interrupt */
+ IR_INTConfig(IR_INT_TF_LEVEL, DISABLE);
+ /* Enable IR tx empty interrupt */
+ IR_INTConfig(IR_INT_TF_EMPTY, ENABLE);
+
+ //Add application code here!!!
+
+ }
+ /* Clear threshold interrupt */
+ IR_ClearINTPendingBit(IR_INT_TF_LEVEL_CLR);
+ }
+
+ if (int_status_tfe == SET)
+ {
+ /* Configure repeat interval and repeat code sending function */
+ if (IR_DataStruct.isSendRepeatcode)
+ {
+ if ((uir_param_info_base.uir_protocol_index == UIR_CODESET_TYPE_LC7464M) || \
+ (uir_param_info_base.uir_protocol_index == UIR_CODESET_TYPE_DVB) || \
+ (uir_param_info_base.uir_protocol_index == UIR_CODESET_TYPE_MIT_C8D8) || \
+ (uir_param_info_base.uir_protocol_index == UIR_CODESET_TYPE_KONICA))
+ {
+ UIR_BurstSendCmd(ProtocolLib[uir_param_info_base.uir_protocol_index].repeat_interval, ENABLE);
+ }
+
+ if (uir_param_info_base.uir_protocol_index == UIR_CODESET_TYPE_DVB_40BIT)
+ {
+ if (IR_DataStruct.isRepeatcodeEncoded)
+ {
+ UIR_BurstSendCmd(DVB_40BIT_TRANSMISION_RE_INTERVAL, ENABLE);
+ }
+ else
+ {
+ UIR_BurstSendCmd(ProtocolLib[uir_param_info_base.uir_protocol_index].repeat_interval, ENABLE);
+ }
+ }
+ }
+
+ /* Tx completed */
+ ir_tx_count = 0;
+ /* Disable IR tx empty interrupt */
+ IR_INTConfig(IR_INT_TF_EMPTY, DISABLE);
+
+ /* Clear interrupt flag */
+ IR_ClearINTPendingBit(IR_INT_TF_EMPTY_CLR);
+
+ if (UIR_GetTIMStatus() == UIR_STATUS_ALREADY_IN_TRANSMITTING)
+ {
+ /* Unmask IR interrupt */
+ IR_MaskINTConfig(IR_INT_TF_LEVEL, DISABLE);
+ IR_MaskINTConfig(IR_INT_TF_EMPTY, DISABLE);
+ return;
+ }
+ //Add application code here!!!
+ //Send Msg to App task to inform that IR complete a complete transmission!!!
+
+ if (pfnIRIntrHandlerCB)
+ {
+ pfnIRIntrHandlerCB();
+ }
+ }
+
+ /* Unmask IR interrupt */
+ IR_MaskINTConfig(IR_INT_TF_LEVEL, DISABLE);
+ IR_MaskINTConfig(IR_INT_TF_EMPTY, DISABLE);
+}
+
+/**
+* @brief TIM interrupt handler function.
+* @param No parameter.
+* @return void
+*/
+void IR_TIMIntrHandler(void)
+{
+ // Add application code here
+ if (ir_tx_count == 0)
+ {
+#ifdef IR_WAVEFORM_INTERVAL_CTRL
+ IR_DataStruct.isTimerOccurred = true;
+
+ if (IR_DataStruct.intervalCtrl)
+ {
+ UIR_BurstSendCmd(0, DISABLE);
+ /* Stop to send repeat code */
+ IR_DataStruct.isSendRepeatcode = false;
+ IR_DataStruct.intervalCtrl = false;
+ IR_DataStruct.isTimerOccurred = false;
+ TIM_ClearINT(IR_TIM);
+
+ /* Notify To app task */
+ if (pfnTIMIntrHandlerCB)
+ {
+ pfnTIMIntrHandlerCB();
+ }
+ return;
+ }
+#endif
+ UIR_SendRepeatData(&uir_param_info_base, &IR_DataStruct);
+ }
+ else
+ {
+ //IR send error
+ }
+
+ TIM_ClearINT(IR_TIM);
+}
+
+/******************* (C) COPYRIGHT 2016 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/IR/SendCode/trans/ir_trans.h b/src/sample/io_sample/IR/SendCode/trans/ir_trans.h
new file mode 100644
index 0000000..eb78db7
--- /dev/null
+++ b/src/sample/io_sample/IR/SendCode/trans/ir_trans.h
@@ -0,0 +1,191 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ir_trans.h
+* @brief
+* @details
+* @author elliot chen
+* @date 2017-08-15
+* @version v1.0
+* *********************************************************************************************************
+*/
+
+#ifndef __IR_TRANS_H
+#define __IR_TRANS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_nvic.h"
+#include "ir_protocol_config.h"
+#include "rtl876x_ir.h"
+#include "rtl876x_tim.h"
+#include "trace.h"
+
+#ifdef RAW_PACK_PROT
+#include "raw_pack_prot.h"
+#endif
+#ifdef NEC_PROT
+#include "nec_prot.h"
+#endif
+#ifdef RC5_PROT
+#include "rc5_prot.h"
+#endif
+#ifdef SONY6124_PROT
+#include "sony6124_prot.h"
+#endif
+#ifdef LC7464M_PROT
+#include "lc7464m_prot.h"
+#endif
+#ifdef TC9012_PROT
+#include "tc9012_prot.h"
+#endif
+#ifdef MITC8D8_PROT
+#include "mitc8d8_prot.h"
+#endif
+#ifdef PIONEER_PROT
+#include "pioneer_prot.h"
+#endif
+#ifdef VICTORC8D8_PROT
+#include "victorc8d8_prot.h"
+#endif
+#ifdef DVB_PROT
+#include "dvb_prot.h"
+#endif
+#ifdef SHARP_PROT
+#include "sharp_prot.h"
+#endif
+#ifdef KONICA_PROT
+#include "konica_prot.h"
+#endif
+#ifdef RC6_32B_PROT
+#include "rc6_prot.h"
+#endif
+#ifdef DVB_40BIT_PROT
+#include "dvb_40bit_prot.h"
+#endif
+
+/* Defines ------------------------------------------------------------------*/
+
+/* brief Universe IR parameters information.
+ */
+
+typedef struct _UIR_PARAM_INFO
+{
+ uint8_t uir_protocol_index;
+ uint8_t custom_code_length;
+ uint8_t key_code_length;
+ uint8_t custom_code_value[MAX_CUSTOM_CODE_LEN];
+ uint8_t key_code_value[MAX_KEY_CODE_LEN];
+
+ bool is_second_code_valid;
+ uint8_t second_custom_code_length; /* length in BIT */
+ uint8_t second_key_code_length; /* length in BIT */
+ uint8_t second_custom_code_value[MAX_CUSTOM_CODE_LEN];
+ uint8_t second_key_code_value[MAX_KEY_CODE_LEN];
+
+#ifdef RAW_PACK_PROT
+ uint32_t *pRawPackAddr;
+ uint32_t raw_pack_len;
+#endif
+} UIR_PARAM_INFO;
+
+/**
+ * @brief Function pointer type used by interrupt handle to general Callback, to send events to application.
+ */
+typedef void (*pfnIntrHandlerCB_t)(void);
+
+/**
+ * @brief IR protocols definition
+ */
+
+typedef enum
+{
+ UIR_CODESET_TYPE_RAW_Pack = 0,
+ UIR_CODESET_TYPE_NEC,
+ UIR_CODESET_TYPE_RC5,
+ UIR_CODESET_TYPE_6124,
+ UIR_CODESET_TYPE_LC7464M,
+ UIR_CODESET_TYPE_TC9012,
+ UIR_CODESET_TYPE_MIT_C8D8,
+ UIR_CODESET_TYPE_Pioneer,
+ UIR_CODESET_TYPE_Victor_C8D8,
+ UIR_CODESET_TYPE_DVB,
+ UIR_CODESET_TYPE_SHARP,
+ UIR_CODESET_TYPE_KONICA,
+ UIR_CODESET_TYPE_SP_NEC,
+ UIR_CODESET_TYPE_RC6_32B,
+ UIR_CODESET_TYPE_DVB_40BIT
+} UIR_CODESET_TYPE;
+
+/**
+ * @brief Pioneer protocol send status definition
+ */
+
+typedef enum
+{
+ UIR_ALTERNATE_NO_SENDING,
+ UIR_ALTERNATE_SEND_ONE_FRAME_DATA,
+ UIR_ALTERNATE_SEND_ONE_FRAME_SECOND_DATA,
+ UIR_ALTERNATE_REPEAT_SEND_FIRST_DATA,
+ UIR_ALTERNATE_REPEAT_SEND_SECOND_DATA
+} UIR_ALTERNATE_SEND_STATUS;
+
+/**
+ * @brief Universe IR status definition
+ */
+
+typedef enum
+{
+ UIR_STATUS_NO_ERROR = 0,
+ UIR_STATUS_INVALID_CODESET_TYPE,
+ UIR_STATUS_INVALID_KEY_INDEX,
+ UIR_STATUS_INVALID_UIR_DATABASE,
+ UIR_STATUS_ALREADY_IN_TRANSMITTING,
+ UIR_STATUS_ENCODE_ERROR,
+ UIR_STATUS_CUSTOM_CODE_OVERFLOW,
+ UIR_STATUS_KEY_CODE_OVERFLOW,
+ UIR_STATUS_SECOND_CUSTOM_CODE_OVERFLOW,
+ UIR_STATUS_SECOND_KEY_CODE_OVERFLOW,
+ UIR_STATUS_CUSTOM_KEY_CODE_LEN_ZERO,
+ UIR_STATUS_EXCEED_MAX_BUF_LEN,
+ UIR_STATUS_SEND_FIRST_FRAME,
+ UIR_STATUS_SEND_REPEAT_CODE,
+ UIR_STATUS_OTHERS = 0xFF,
+} UIR_STATUS;
+
+/**
+ * @brief Enable print log or not
+ */
+
+#define PRINT_LOG
+
+#ifdef PRINT_LOG
+#define IR_DBG_BUFFER(MODULE, LEVEL, pFormat, para_num,...) DBG_BUFFER_##LEVEL(MODULE, pFormat, para_num, ##__VA_ARGS__)
+#else
+#define IR_DBG_BUFFER(MODULE, LEVEL, pFormat, para_num,...) ((void)0)
+#endif
+
+void UIR_TransInit(void);
+UIR_STATUS UIR_OneFrameTransmitting(UIR_PARAM_INFO *uir_param_info, FunctionalState NewState);
+UIR_STATUS UIR_StartContinuouslyTransmitting(UIR_PARAM_INFO *uir_param_info);
+UIR_STATUS UIR_StopContinuouslyTransmitting(void);
+void UIR_RegisterIRIntrHandlerCB(pfnIntrHandlerCB_t pFunc);
+#ifdef IR_WAVEFORM_INTERVAL_CTRL
+void UIR_RegisterTIMIntrHandlerCB(pfnIntrHandlerCB_t pFunc);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__IR_TRANS_H*/
+
+/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/IR/Tx+GDMA/main.c b/src/sample/io_sample/IR/Tx+GDMA/main.c
new file mode 100644
index 0000000..c569f6e
--- /dev/null
+++ b/src/sample/io_sample/IR/Tx+GDMA/main.c
@@ -0,0 +1,188 @@
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include "rtl876x_gdma.h"
+#include "rtl876x_ir.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "trace.h"
+
+
+#define IR_TX_PIN P2_5
+#define IR_TX_FIFO_THR_LEVEL 2
+#define IR_DATA_SIZE_MAX 68
+
+#define IO_TEST_GDMA_TRANSFER_SIZE IR_DATA_SIZE_MAX
+
+#define IO_TEST_GDMA_CHANNEL_MUM 1
+
+#if (IO_TEST_GDMA_CHANNEL_MUM == 0)
+#define IO_TEST_GDMA_Channel GDMA_Channel0
+#define IO_TEST_GDMA_Channel_IRQn GDMA0_Channel0_IRQn
+#define IO_TEST_GDMA_Channel_Handler GDMA0_Channel0_Handler
+#elif IO_TEST_GDMA_CHANNEL_MUM == 1
+#define IO_TEST_GDMA_Channel GDMA_Channel1
+#define IO_TEST_GDMA_Channel_IRQn GDMA0_Channel1_IRQn
+#define IO_TEST_GDMA_Channel_Handler GDMA0_Channel1_Handler
+#elif IO_TEST_GDMA_CHANNEL_MUM == 2
+#define IO_TEST_GDMA_Channel GDMA_Channel2
+#define IO_TEST_GDMA_Channel_IRQn GDMA0_Channel2_IRQn
+#define IO_TEST_GDMA_Channel_Handler GDMA0_Channel2_Handler
+#elif IO_TEST_GDMA_CHANNEL_MUM == 3
+#define IO_TEST_GDMA_Channel GDMA_Channel3
+#define IO_TEST_GDMA_Channel_IRQn GDMA0_Channel3_IRQn
+#define IO_TEST_GDMA_Channel_Handler GDMA0_Channel3_Handler
+#endif
+
+/**
+ * @brief IR data structure definition
+ */
+typedef struct
+{
+ /* Unit of carrierFreq is KHz */
+ uint32_t CarrierFreq;
+ uint32_t DataBuf[IR_DATA_SIZE_MAX];
+ uint16_t DataLen;
+} IR_Data_TypeDef;
+
+IR_Data_TypeDef IR_Send_Data;
+uint32_t GDMA_Send_Buf[100];
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_ir_init(void)
+{
+ Pad_Config(IR_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
+
+ Pinmux_Config(IR_TX_PIN, IRDA_TX);
+}
+
+/**
+ * @brief Initialize ir peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_ir_init(uint32_t vFreq)
+{
+ /* Enable ir clock */
+ RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, ENABLE);
+
+ /* Initialize ir */
+ IR_InitTypeDef IR_InitStruct;
+ IR_StructInit(&IR_InitStruct);
+ IR_InitStruct.IR_Freq = vFreq;//vFreq;
+ IR_InitStruct.IR_DutyCycle = 3; /* !< 1/3 duty cycle */
+ IR_InitStruct.IR_Mode = IR_MODE_TX;
+ IR_InitStruct.IR_TxInverse = IR_TX_DATA_NORMAL;
+ IR_InitStruct.IR_TxFIFOThrLevel = IR_TX_FIFO_THR_LEVEL;
+ IR_InitStruct.IR_TxDmaEn = ENABLE;
+ IR_InitStruct.IR_TxWaterLevel = 15;
+
+ IR_Init(&IR_InitStruct);
+}
+
+/**
+ * @brief Initialize GDMA peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_ir_gdma_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+ GDMA_InitTypeDef GDMA_InitStruct;
+
+ /*--------------GDMA init-----------------------------*/
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = IO_TEST_GDMA_CHANNEL_MUM;
+ GDMA_InitStruct.GDMA_BufferSize = IO_TEST_GDMA_TRANSFER_SIZE;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)(GDMA_Send_Buf);
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&IR->TX_FIFO);//0x40016014;
+ GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_IR_TX;
+ GDMA_Init(IO_TEST_GDMA_Channel, &GDMA_InitStruct);
+
+ GDMA_INTConfig(IO_TEST_GDMA_CHANNEL_MUM, GDMA_INT_Transfer, ENABLE);
+
+ /*-----------------GDMA IRQ init-------------------*/
+ NVIC_InitTypeDef nvic_init_struct;
+ nvic_init_struct.NVIC_IRQChannel = IO_TEST_GDMA_Channel_IRQn;
+ nvic_init_struct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ nvic_init_struct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&nvic_init_struct);
+
+ GDMA_Cmd(IO_TEST_GDMA_CHANNEL_MUM, ENABLE);
+}
+
+void ir_demo(void)
+{
+ /* Data to send */
+ IR_Send_Data.CarrierFreq = 38000;
+ IR_Send_Data.DataLen = IO_TEST_GDMA_TRANSFER_SIZE;
+ IR_Send_Data.DataBuf[0] = 0x80000000 | 0x200;
+ IR_Send_Data.DataBuf[1] = 0x00000000 | 0x100;
+ for (uint16_t i = 2; i < IR_Send_Data.DataLen - 1;)
+ {
+ IR_Send_Data.DataBuf[i] = 0x80000000 | (0x0A + i * 5);
+ IR_Send_Data.DataBuf[i + 1] = 0x00000000 | (0x14 + i * 5);
+ i += 2;
+ }
+ IR_Send_Data.DataBuf[IR_Send_Data.DataLen - 1] = 0x80000000 | 0x800;
+
+ /* Test data buffer */
+ for (uint32_t i = 0; i < IO_TEST_GDMA_TRANSFER_SIZE; i++)
+ {
+ GDMA_Send_Buf[i] = IR_Send_Data.DataBuf[i];
+ }
+
+ board_ir_init();
+ driver_ir_init(IR_Send_Data.CarrierFreq);
+ driver_ir_gdma_init();
+ IR_Cmd(IR_MODE_TX, ENABLE);
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+*/
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+
+ ir_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+
+ }
+}
+
+/**
+ * @brief GDMA channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void IO_TEST_GDMA_Channel_Handler(void)
+{
+ GDMA_INTConfig(IO_TEST_GDMA_CHANNEL_MUM, GDMA_INT_Transfer, DISABLE);
+ GDMA_Cmd(IO_TEST_GDMA_CHANNEL_MUM, DISABLE);
+ DBG_DIRECT("IO_TEST_GDMA_Channel_Handler\r\n");
+ GDMA_ClearINTPendingBit(IO_TEST_GDMA_CHANNEL_MUM, GDMA_INT_Transfer);
+}
+
diff --git a/src/sample/io_sample/IR/Tx/main.c b/src/sample/io_sample/IR/Tx/main.c
new file mode 100644
index 0000000..659ccbd
--- /dev/null
+++ b/src/sample/io_sample/IR/Tx/main.c
@@ -0,0 +1,202 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code of ir tx.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include "rtl876x_ir.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+
+#include "trace.h"
+
+#define IR_DATA_SIZE_MAX 75
+
+#define IR_TX_PIN P2_5
+#define IR_TX_FIFO_THR_LEVEL 2
+
+/**
+ * @brief IR data structure definition
+ */
+typedef struct
+{
+ /* Unit of carrierFreq is KHz */
+ uint32_t CarrierFreq;
+ uint32_t DataBuf[IR_DATA_SIZE_MAX];
+ uint16_t DataLen;
+} IR_Data_TypeDef;
+
+/* Globals ------------------------------------------------------------------*/
+IR_Data_TypeDef IR_TxData;
+/* Number of data which has been sent */
+uint8_t IR_TX_Count = 0;
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_ir_init(void)
+{
+ Pad_Config(IR_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
+
+ Pinmux_Config(IR_TX_PIN, IRDA_TX);
+}
+
+
+/**
+ * @brief Initialize ir peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_ir_init(uint32_t vFreq)
+{
+ /* Enable ir clock */
+ RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, ENABLE);
+
+ /* Initialize ir */
+ IR_InitTypeDef IR_InitStruct;
+ IR_StructInit(&IR_InitStruct);
+ IR_InitStruct.IR_Freq = vFreq;
+ IR_InitStruct.IR_DutyCycle = 2; /* !< 1/2 duty cycle */
+ IR_InitStruct.IR_Mode = IR_MODE_TX;
+ IR_InitStruct.IR_TxInverse = IR_TX_DATA_NORMAL;
+ IR_InitStruct.IR_TxFIFOThrLevel = IR_TX_FIFO_THR_LEVEL;
+ IR_Init(&IR_InitStruct);
+
+ /* Enable IR threshold interrupt. when TX FIFO offset <= threshold value, trigger interrupt*/
+ IR_INTConfig(IR_INT_TF_LEVEL, ENABLE);
+
+ /* Configure nvic */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = IR_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/**
+ * @brief Demo code of ir send data.
+ * @param No parameter.
+ * @return Void
+*/
+void ir_demo(void)
+{
+ /* Data to send */
+ IR_TxData.CarrierFreq = 38000;
+ IR_TxData.DataLen = 67 + 1; //2+64+1;
+ IR_TxData.DataBuf[0] = 0x80000000 | 0x156; //342 about 9ms
+ IR_TxData.DataBuf[1] = 0x00000000 | 0xAB; //171 about 4.5ms
+ for (uint16_t i = 2; i < IR_TxData.DataLen - 1;)
+ {
+ IR_TxData.DataBuf[i] = 0x80000000 | 0x15; //21 about 560us
+ IR_TxData.DataBuf[i + 1] = 0x00000000 | 0x15; //21 about 565us
+ i += 2;
+ }
+ IR_TxData.DataBuf[30] = 0x80000000 | 0x15; //21 about 560us
+ IR_TxData.DataBuf[31] = 0x00000000 | 0x40; //64 about 1690us
+ IR_TxData.DataBuf[62] = 0x80000000 | 0x15; //21 about 560us
+ IR_TxData.DataBuf[63] = 0x00000000 | 0x40; //64 about 1690us
+ IR_TxData.DataBuf[64] = 0x80000000 | 0x15; //21 about 560us
+ IR_TxData.DataBuf[65] = 0x00000000 | 0x40; //64 about 1690us
+ IR_TxData.DataBuf[66] = 0x80000000 | 0x15; //21 about 560us
+ IR_TxData.DataBuf[IR_TxData.DataLen - 1] = 0x80000000 | 0x15;
+
+ board_ir_init();
+ driver_ir_init(IR_TxData.CarrierFreq);
+
+ /* Start to send data. */
+ IR_SendBuf(IR_TxData.DataBuf, IR_TX_FIFO_SIZE, DISABLE);
+ IR_Cmd(IR_MODE_TX, ENABLE);
+ /* Record number which has been sent */
+ IR_TX_Count = IR_TX_FIFO_SIZE;
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+
+ ir_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+
+ }
+}
+
+
+/**
+ * @brief IR interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void IR_Handler(void)
+{
+ /* Get IR interrupt status */
+ ITStatus int_status = IR_GetINTStatus(IR_INT_TF_LEVEL);
+
+ /* Mask IR interrupt */
+ IR_MaskINTConfig(IR_INT_TF_LEVEL, ENABLE);
+
+ /* Continue to send by interrupt */
+ if (int_status == SET)
+ {
+ /* The remaining data is larger than the TX FIFO length */
+ if ((IR_TxData.DataLen - IR_TX_Count) >= IR_TX_FIFO_SIZE)
+ {
+ IR_SendBuf(IR_TxData.DataBuf + IR_TX_Count, (IR_TX_FIFO_SIZE - IR_TX_FIFO_THR_LEVEL), DISABLE);
+ IR_TX_Count += (IR_TX_FIFO_SIZE - IR_TX_FIFO_THR_LEVEL);
+
+ /* Clear threshold interrupt */
+ IR_ClearINTPendingBit(IR_INT_TF_LEVEL_CLR);
+ }
+ else if ((IR_TxData.DataLen - IR_TX_Count) > 0)
+ {
+ /* The remaining data is less than the TX FIFO length */
+
+ /* Configure TX threshold level to zero and trigger interrupt when TX FIFO is empty */
+ IR_SetTxThreshold(0);
+ IR_SendBuf(IR_TxData.DataBuf + IR_TX_Count, IR_TxData.DataLen - IR_TX_Count, DISABLE);
+ IR_TX_Count += (IR_TxData.DataLen - IR_TX_Count);
+
+ /* Clear threshold interrupt */
+ IR_ClearINTPendingBit(IR_INT_TF_LEVEL_CLR);
+ }
+ else
+ {
+ /* Tx completed */
+ /* Disable IR tx empty interrupt */
+ IR_INTConfig(IR_INT_TF_LEVEL, DISABLE);
+ IR_TX_Count = 0;
+
+ /* Clear threshold interrupt */
+ IR_ClearINTPendingBit(IR_INT_TF_LEVEL_CLR);
+ }
+ }
+
+ /* Unmask IR interrupt */
+ IR_MaskINTConfig(IR_INT_TF_LEVEL, DISABLE);
+}
+
diff --git a/src/sample/io_sample/KEYSCAN/Keyscan_Manual/app_timer.c b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/app_timer.c
new file mode 100644
index 0000000..d190f57
--- /dev/null
+++ b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/app_timer.c
@@ -0,0 +1,23 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file app_timer.c
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "app_task.h"
+#include "app_timer.h"
+
+
+void sw_timer_init(void)
+{
+ timer_keyscan_init();
+}
+
diff --git a/src/sample/io_sample/KEYSCAN/Keyscan_Manual/app_timer.h b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/app_timer.h
new file mode 100644
index 0000000..43908ea
--- /dev/null
+++ b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/app_timer.h
@@ -0,0 +1,43 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file app_timer.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __APP_TIMER_H
+#define __APP_TIMER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include <string.h>
+
+//#include "os_msg.h"
+//#include "os_queue.h"
+//#include "os_sched.h"
+//#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+#include "io_keyscan.h"
+
+//void timer_keyscan_callback(void *xTimer);
+void sw_timer_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/ancs.c b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/ancs.h b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app.c b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app.c
new file mode 100644
index 0000000..141d8ca
--- /dev/null
+++ b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app.c
@@ -0,0 +1,608 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_keyscan.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_KEYSCAN:
+ {
+// APP_PRINT_INFO0("[app] app_handle_io_msg: Keyscan msg.");
+ io_handle_keyscan_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app.h b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app_flags.h b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app_task.c b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app_task.c
new file mode 100644
index 0000000..f5914b1
--- /dev/null
+++ b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app_task.h b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/main.c b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/main.c
new file mode 100644
index 0000000..95e1d08
--- /dev/null
+++ b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/ble_peripheral/main.c
@@ -0,0 +1,248 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_timer.h"
+
+#include "io_keyscan.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+ global_data_keyscan_init();
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_keyboard_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_keyboard_init(KeyScan_Debounce_Enable);
+// nvic_keyscan_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ sw_timer_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/KEYSCAN/Keyscan_Manual/io_keyscan.c b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/io_keyscan.c
new file mode 100644
index 0000000..258cfef
--- /dev/null
+++ b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/io_keyscan.c
@@ -0,0 +1,234 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_keyscan.c
+* @brief This file provides demo code of keyscan manual mode.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_keyscan.h"
+
+#include "app_task.h"
+
+
+/* Globals ------------------------------------------------------------------*/
+/* Timer handle */
+void *KeyScan_Timer_Handle = NULL;
+
+KeyScan_Data_TypeDef Current_Key_Data;
+bool Key_Pressed_Flag = false;
+
+
+/**
+ * @brief Initialize keyscan global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_keyscan_init(void)
+{
+ /* Data struct init */
+ memset(&Current_Key_Data, 0, sizeof(KeyScan_Data_TypeDef));
+// memset(&Pre_Key_Data, 0, sizeof(KeyScan_Data_TypeDef));
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return Void
+ */
+void board_keyboard_init(void)
+{
+ /* Keypad pad config */
+ Pad_Config(KEYBOARD_ROW_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+ Pad_Config(KEYBOARD_ROW_1, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+ Pad_Config(KEYBOARD_COLUMN_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_LOW);
+ Pad_Config(KEYBOARD_COLUMN_1, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_LOW);
+
+ /* keypad pinmux config */
+ Pinmux_Config(KEYBOARD_ROW_0, KEY_ROW_0);
+ Pinmux_Config(KEYBOARD_ROW_1, KEY_ROW_1);
+ Pinmux_Config(KEYBOARD_COLUMN_0, KEY_COL_0);
+ Pinmux_Config(KEYBOARD_COLUMN_1, KEY_COL_1);
+}
+
+/**
+ * @brief Initialize keyboard peripheral.
+ * @param No parameter.
+ * @return Void
+ */
+void driver_keyboard_init(uint32_t vDebounce_En)
+{
+ /* Turn on keyscan clock */
+ RCC_PeriphClockCmd(APBPeriph_KEYSCAN, APBPeriph_KEYSCAN_CLOCK, ENABLE);
+
+ KEYSCAN_InitTypeDef KEYSCAN_InitStruct;
+ KeyScan_StructInit(&KEYSCAN_InitStruct);
+
+ KEYSCAN_InitStruct.rowSize = KEYBOARD_ROW_SIZE;
+ KEYSCAN_InitStruct.colSize = KEYBOARD_COLUMN_SIZE;
+ KEYSCAN_InitStruct.scanmode = KeyScan_Manual_Scan_Mode;
+ KEYSCAN_InitStruct.debounceEn = vDebounce_En;
+
+ KeyScan_Init(KEYSCAN, &KEYSCAN_InitStruct);
+
+ KeyScan_INTConfig(KEYSCAN, KEYSCAN_INT_SCAN_END, ENABLE);
+ KeyScan_ClearINTPendingBit(KEYSCAN, KEYSCAN_INT_SCAN_END);
+ KeyScan_INTMask(KEYSCAN, KEYSCAN_INT_SCAN_END, DISABLE); /* Unmask keyscan interrupt */
+ KeyScan_Cmd(KEYSCAN, ENABLE);
+
+ /* Keyscan IRQ */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = KeyScan_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/**
+ * @brief Calculate adc sample voltage.
+ * @param No parameter.
+ * @return void
+ */
+static void io_keyscan_handle_keys(T_IO_MSG *io_keyscan_msg)
+{
+ uint16_t subtype = io_keyscan_msg->subtype;
+
+ if (subtype == IO_MSG_KEYSCAN_RX_PKT)
+ {
+ KeyScan_Data_TypeDef *p_key_data = (KeyScan_Data_TypeDef *)io_keyscan_msg->u.buf;
+ /* Single key press */
+ if (p_key_data->length == 1)
+ {
+ APP_PRINT_INFO2("[io_keyscan] io_keyscan_handle_keys: Single key press. key: (%d, %d)",
+ p_key_data->key[0].row, p_key_data->key[0].column);
+ }
+
+ /* two keys press */
+ if (p_key_data->length == 2)
+ {
+ APP_PRINT_INFO4("[io_keyscan] io_keyscan_handle_keys: Two key press. key0: (%d, %d), key1: (%d, %d)",
+ p_key_data->key[0].row, p_key_data->key[0].column, p_key_data->key[1].row,
+ p_key_data->key[1].column);
+ }
+ }
+ else if (subtype == IO_MSG_KEYSCAN_ALLKEYRELEASE)
+ {
+ APP_PRINT_INFO0("[io_keyscan] io_keyscan_handle_keys: All keys release.");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("[io_keyscan] io_keyscan_handle_keys: Wrong key event!");
+ }
+}
+
+/**
+ * @brief Handle keyscan data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_keyscan_msg(T_IO_MSG *io_keyscan_msg)
+{
+ io_keyscan_handle_keys(io_keyscan_msg);
+}
+
+void timer_keyscan_callback(void *p_xTimer)
+{
+ if (true == Key_Pressed_Flag)
+ {
+// APP_PRINT_INFO0("[io_keyscan] timer_keyscan_callback: start release timer");
+ Key_Pressed_Flag = false;
+ driver_keyboard_init(KeyScan_Debounce_Disable);
+
+ /* Start timer to check key status */
+ os_timer_restart(&p_xTimer, KEYSCAN_SW_RELEASE_TIMEOUT);
+ }
+ else
+ {
+ /* Keyscan release event detected */
+// APP_PRINT_INFO0("[io_keyscan] timer_keyscan_callback: keyscan release event detected ");
+ T_IO_MSG int_keyscan_msg;
+ int_keyscan_msg.type = IO_MSG_TYPE_KEYSCAN;
+ int_keyscan_msg.subtype = IO_MSG_KEYSCAN_ALLKEYRELEASE;
+
+ if (false == app_send_msg_to_apptask(&int_keyscan_msg))
+ {
+ APP_PRINT_ERROR0("[io_keyscan] timer_keyscan_callback: Send IO_MSG_KEYSCAN_ALLKEYRELEASE failed!");
+ }
+
+ global_data_keyscan_init();
+ driver_keyboard_init(KeyScan_Debounce_Enable);
+ }
+}
+
+void timer_keyscan_init(void)
+{
+ APP_PRINT_INFO0("[io_keyscan] timer_keyscan_init: keyscan timer init");
+ if (false == os_timer_create(&KeyScan_Timer_Handle, "keyscan_timer", 1, \
+ KEYSCAN_SW_INTERVAL, false, timer_keyscan_callback))
+ {
+ APP_PRINT_ERROR0("[io_keyscan] timer_keyscan_init: timer creat failed!");
+ }
+}
+
+/**
+ * @brief Keyscan interrupt handler function.
+ * @param No parameter.
+ * @return void
+*/
+void Keyscan_Handler(void)
+{
+ uint32_t fifo_length;
+ T_IO_MSG int_keyscan_msg;
+
+ if (KeyScan_GetFlagState(KEYSCAN, KEYSCAN_INT_FLAG_SCAN_END) == SET)
+ {
+ /* Read current keyscan interrupt status and mask interrupt */
+ KeyScan_INTMask(KEYSCAN, KEYSCAN_INT_SCAN_END, ENABLE);
+ memset(&Current_Key_Data, 0, sizeof(KeyScan_Data_TypeDef));
+
+ /* KeyScan fifo not empty */
+ if (KeyScan_GetFlagState(KEYSCAN, KEYSCAN_FLAG_EMPTY) != SET)
+ {
+ fifo_length = (uint32_t)KeyScan_GetFifoDataNum(KEYSCAN);
+ KeyScan_Read(KEYSCAN, (uint16_t *)&Current_Key_Data.key[0], fifo_length);
+ Current_Key_Data.length = fifo_length;
+ Key_Pressed_Flag = true;
+
+ /* Start sw timer to check press status */
+ if (!os_timer_restart(&KeyScan_Timer_Handle, KEYSCAN_SW_INTERVAL))
+ {
+ APP_PRINT_ERROR0("[io_keyscan] Keyscan_Handler: Restart keyscan_timer failed!");
+ /* Set flag to default status and reinit keyscan module with debounce enabled */
+ global_data_keyscan_init();
+ driver_keyboard_init(KeyScan_Debounce_Enable);
+ return;
+ }
+
+ /* Send event to app task */
+ int_keyscan_msg.type = IO_MSG_TYPE_KEYSCAN;
+ int_keyscan_msg.subtype = IO_MSG_KEYSCAN_RX_PKT;
+ int_keyscan_msg.u.buf = (void *)&Current_Key_Data;
+ if (false == app_send_msg_to_apptask(&int_keyscan_msg))
+ {
+ APP_PRINT_ERROR0("[io_keyscan] Keyscan_Handler: Send IO_MSG_KEYSCAN_RX_PKT failed!");
+ //Add user code here!
+ return;
+ }
+ }
+ KeyScan_ClearINTPendingBit(KEYSCAN, KEYSCAN_INT_SCAN_END);
+ KeyScan_INTMask(KEYSCAN, KEYSCAN_INT_SCAN_END, DISABLE);
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/KEYSCAN/Keyscan_Manual/io_keyscan.h b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/io_keyscan.h
new file mode 100644
index 0000000..60d01d3
--- /dev/null
+++ b/src/sample/io_sample/KEYSCAN/Keyscan_Manual/io_keyscan.h
@@ -0,0 +1,63 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_keyscan.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_ADC_H
+#define __IO_ADC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_keyscan.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+
+#include "board.h"
+
+#include "app_msg.h"
+
+
+/* Defines -------------------------------------------------------------------*/
+#define KEYSCAN_SW_INTERVAL (200)/* 200ms */
+#define KEYSCAN_SW_RELEASE_TIMEOUT (10)/* 10ms */
+
+/* Typedefs ------------------------------------------------------------------*/
+typedef struct
+{
+ uint32_t length;
+ struct
+ {
+ uint16_t column: 5; /**< keyscan column buffer data */
+ uint16_t row: 4; /**< keyscan raw buffer data */
+ } key[26];
+} KeyScan_Data_TypeDef;
+
+
+extern void *KeyScan_Timer_Handle;
+extern KeyScan_Data_TypeDef Current_Key_Data;
+
+
+void global_data_keyscan_init(void);
+void board_keyboard_init(void);
+void driver_keyboard_init(uint32_t vDebounce_En);
+void timer_keyscan_init(void);
+void io_handle_keyscan_msg(T_IO_MSG *io_keyscan_msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/LPC/Comparator/main.c b/src/sample/io_sample/LPC/Comparator/main.c
new file mode 100644
index 0000000..8388f78
--- /dev/null
+++ b/src/sample/io_sample/LPC/Comparator/main.c
@@ -0,0 +1,174 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2021, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file lpc.c
+* @brief
+* @author yuan
+* @date 2021-05-04
+* @version v0.1
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2021 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "rtl876x_gpio.h"
+#include "rtl876x_lpc.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_rtc.h"
+
+#include "board.h"
+#include "platform_utils.h"
+#include "trace.h"
+
+#define LPC_CAPTURE_PIN P2_2
+#define LPC_CAPTURE_CHANNEL LPC_CHANNEL_P2_2
+
+#define LPC_VOLTAGE_DETECT_EDGE LPC_Vin_Over_Vth;
+#define LPC_VOLTAGE_DETECT_THRESHOLD LPC_2000_mV;
+
+#define LPC_COMP_VALUE 10
+
+#define GPIO_OUTPUT_PIN_0 P2_4
+#define GPIO_PIN_OUTPUT_0 GPIO_GetPin(GPIO_OUTPUT_PIN_0)
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return None.
+ */
+void board_lpc_init(void)
+{
+ Pad_Config(LPC_CAPTURE_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(LPC_CAPTURE_PIN, IDLE_MODE);
+}
+
+/**
+ * @brief Initialize RTC peripheral.
+ * @param No parameter.
+ * @return None.
+ */
+void driver_lpc_init(void)
+{
+ LPC_DeInit();
+ LPC_InitTypeDef LPC_InitStruct;
+ LPC_StructInit(&LPC_InitStruct);
+
+ LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL;
+ LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE;
+ LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD;
+ LPC_Init(&LPC_InitStruct);
+ LPC_Cmd(ENABLE);
+
+ LPC_ResetCounter();
+ LPC_SetCompValue(LPC_COMP_VALUE);
+ LPC_INTConfig(LPC_INT_LPCOMP_CNT, ENABLE);
+
+ /* Config LPC interrupt */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = LPCOMP_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 2;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ LPC_INTCmd(ENABLE);
+ LPC_CounterCmd(ENABLE);
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return None.
+*/
+void board_gpio_init(void)
+{
+ Pad_Config(GPIO_OUTPUT_PIN_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(GPIO_OUTPUT_PIN_0, DWGPIO);
+}
+
+/**
+ * @brief Initialize GPIO peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_gpio_init(void)
+{
+ /* Initialize GPIO peripheral */
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+ GPIO_StructInit(&GPIO_InitStruct);
+
+ GPIO_InitStruct.GPIO_Pin = GPIO_PIN_OUTPUT_0;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_Init(&GPIO_InitStruct);
+
+ GPIO_WriteBit(GPIO_PIN_OUTPUT_0, (BitAction)(1));
+}
+
+void lpc_demo(void)
+{
+ board_lpc_init();
+ driver_lpc_init();
+
+ /* GPIO output is only used to simulate the input signal, only for demo debugging. */
+ board_gpio_init();
+ driver_gpio_init();
+ while (1)
+ {
+ /* Simulate GPIO trigger signal */
+ for (uint32_t i = 0; i < 100000; i++);
+ GPIO_WriteBit(GPIO_PIN_OUTPUT_0, (BitAction)(1));
+ for (uint32_t i = 0; i < 100000; i++);
+ GPIO_WriteBit(GPIO_PIN_OUTPUT_0, (BitAction)(0));
+ }
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ __enable_irq();
+
+ lpc_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ }
+}
+
+/**
+ * @brief LPC battery detection interrupt handle function.
+ * @param None.
+ * @return None.
+ */
+void LPCOMP_Handler(void)
+{
+ APP_PRINT_INFO0("LPCOMP_Handler\r\n");
+ //Add Application code here
+ /* LPC counter comparator interrupt */
+ if (LPC_GetINTStatus(LPC_INT_LPCOMP_CNT) == SET)
+ {
+ APP_PRINT_INFO2("LPC_INT_LPCOMP_CNT: counter = %d comp_value = %d\r\n", LPC_GetCounter(),
+ LPC_GetCompValue());
+ LPC_SetCompValue(LPC_GetCounter() + LPC_COMP_VALUE);
+ LPC_ClearINTPendingBit(LPC_INT_LPCOMP_CNT);
+ }
+}
diff --git a/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/ancs.c b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/ancs.h b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app.c b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app.c
new file mode 100644
index 0000000..93d521e
--- /dev/null
+++ b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app.c
@@ -0,0 +1,610 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_lpc.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_BAT_LPC:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: LPC low voltage detection msg.");
+ io_handle_lpc_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ /* Enable lpc NVIC after GAP stack ready. */
+ nvic_lpc_init();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app.h b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app_flags.h b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app_task.c b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app_task.c
new file mode 100644
index 0000000..0bf1107
--- /dev/null
+++ b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app_task.c
@@ -0,0 +1,124 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app_task.h b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/main.c b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/main.c
new file mode 100644
index 0000000..bfeecad
--- /dev/null
+++ b/src/sample/io_sample/LPC/LPC_DLPS/ble_peripheral/main.c
@@ -0,0 +1,286 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "rtl876x_io_dlps.h"
+#include "io_lpc.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+#if DLPS_EN
+/**
+ * @brief this function will be called before enter DLPS
+ *
+ * set PAD and wakeup pin config for enterring DLPS
+ *
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_enter_dlps_config(void)
+{
+ io_lpc_dlps_enter();
+}
+
+/**
+ * @brief this function will be called after exit DLPS
+ *
+ * set PAD and wakeup pin config for enterring DLPS
+ *
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_exit_dlps_config(void)
+{
+ io_lpc_dlps_exit();
+}
+
+/**
+ * @brief Contains the setting about app dlps callback.
+ */
+bool app_dlps_check_cb(void)
+{
+ return (io_lpc_dlps_check());
+}
+
+#endif /* DLPS_EN */
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+void pwr_mgr_init(void)
+{
+#if DLPS_EN
+ if (false == dlps_check_cb_reg(app_dlps_check_cb))
+ {
+ APP_PRINT_ERROR0("Error: dlps_check_cb_reg(app_dlps_check_cb) failed!");
+ }
+ DLPS_IORegUserDlpsEnterCb(app_enter_dlps_config);
+ DLPS_IORegUserDlpsExitCb(app_exit_dlps_config);
+ DLPS_IORegister();
+
+ lps_mode_set(PLATFORM_DLPS_PFM);
+
+#else
+
+ lps_mode_set(LPM_ACTIVE_MODE);
+
+#endif
+}
+
+void global_data_init(void)
+{
+ global_data_lpc_init();
+}
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_lpc_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_lpc_init();
+}
+
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
diff --git a/src/sample/io_sample/LPC/LPC_DLPS/io_lpc.c b/src/sample/io_sample/LPC/LPC_DLPS/io_lpc.c
new file mode 100644
index 0000000..d6f21ab
--- /dev/null
+++ b/src/sample/io_sample/LPC/LPC_DLPS/io_lpc.c
@@ -0,0 +1,168 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file lpc.c
+ * @brief
+ * @author yuan
+ * @date 2018-05-04
+ * @version v0.1
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "io_lpc.h"
+
+#include "board.h"
+#include "app_task.h"
+
+bool IO_LPC_DLPS_Enter_Allowed = false;
+
+/**
+ * @brief Initialize uart global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_lpc_init(void)
+{
+ IO_LPC_DLPS_Enter_Allowed = true;
+}
+
+/**
+ * @brief Handle lpc data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_lpc_handle_msg(T_IO_MSG *io_lpc_msg)
+{
+ uint16_t type = io_lpc_msg->type;
+ if (IO_MSG_TYPE_BAT_LPC == type)
+ {
+ APP_PRINT_INFO0("io_handle_lpc_msg: VoltageDection done ");
+
+ extern volatile void (*platform_delay_ms)(uint32_t t);
+ platform_delay_ms(100);
+
+ LPC_INTConfig(LPC_INT_LPCOMP_VOL, ENABLE);
+ IO_LPC_DLPS_Enter_Allowed = true;
+ }
+}
+
+/**
+ * @brief Handle lpc msg function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_lpc_msg(T_IO_MSG *io_lpc_msg)
+{
+ io_lpc_handle_msg(io_lpc_msg);
+}
+
+/**
+ * @brief IO enter dlps check function.
+ * @param No parameter.
+ * @return void
+ */
+bool io_lpc_dlps_check(void)
+{
+ return IO_LPC_DLPS_Enter_Allowed;
+}
+
+/**
+ * @brief IO enter dlps call back function.
+ * @param No parameter.
+ * @return void
+ */
+void io_lpc_dlps_enter(void)
+{
+ /* Notes: DBG_DIRECT is only used in debug demo, do not use in app project.*/
+ DBG_DIRECT("DLPS ENTER");
+}
+
+/**
+ * @brief IO exit dlps call back function.
+ * @param No parameter.
+ * @return void
+ */
+void io_lpc_dlps_exit(void)
+{
+ /* Notes: DBG_DIRECT is only used in debug demo, do not use in app project.*/
+ DBG_DIRECT("DLPS EXIT");
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_lpc_init(void)
+{
+ Pad_Config(LPC_CAPTURE_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(LPC_CAPTURE_PIN, IDLE_MODE);
+}
+
+/**
+ * @brief Initialize RTC peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_lpc_init(void)
+{
+ LPC_DeInit();
+ LPC_InitTypeDef LPC_InitStruct;
+ LPC_StructInit(&LPC_InitStruct);
+
+ LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL;
+ LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE;
+ LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD;
+ LPC_Init(&LPC_InitStruct);
+ LPC_Cmd(ENABLE);
+
+ /* Config LPC voltage detection interrupt */
+ LPC_INTConfig(LPC_INT_LPCOMP_VOL, ENABLE);
+
+ /* Enable LPC DLPS Wakeup Config */
+ LPC_WKCmd(ENABLE);
+ RTC_SystemWakeupConfig(ENABLE);
+}
+
+/**
+ * @brief Initialize NVIC peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void nvic_lpc_init(void)
+{
+ /* Config LPC interrupt */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = LPCOMP_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+ LPC_INTCmd(ENABLE);
+}
+
+/**
+ * @brief LPC battery detection interrupt handle function.
+ * @param None.
+ * @return None.
+ */
+void LPCOMP_Handler(void)
+{
+ LPC_INTConfig(LPC_INT_LPCOMP_VOL, DISABLE);
+
+ T_IO_MSG int_lpc_msg;
+ int_lpc_msg.type = IO_MSG_TYPE_BAT_LPC;
+
+ if (false == app_send_msg_to_apptask(&int_lpc_msg))
+ {
+ APP_PRINT_ERROR0("[io_lpc] LPCOMP_Handler: Send int_lpc_msg failed!");
+ return;
+ }
+}
diff --git a/src/sample/io_sample/LPC/LPC_DLPS/io_lpc.h b/src/sample/io_sample/LPC/LPC_DLPS/io_lpc.h
new file mode 100644
index 0000000..c080ebf
--- /dev/null
+++ b/src/sample/io_sample/LPC/LPC_DLPS/io_lpc.h
@@ -0,0 +1,69 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_lpc.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_LPC_H
+#define __IO_LPC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_lpc.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_rtc.h"
+#include "trace.h"
+
+#include "board.h"
+
+#include "app_msg.h"
+#include "trace.h"
+
+/* Defines ------------------------------------------------------------------*/
+/** LPC voltage detect channel config.
+ * PIN select:P2_2,P2-3,P2_6 and VBAT.
+ * LPC channel select:
+ * #defin LPC_CHANNEL_P2_2 ((uint32_t)0)
+ * #define LPC_CHANNEL_P2_3 ((uint32_t)1)
+ * #define LPC_CHANNEL_P2_6 ((uint32_t)2)
+ * #define LPC_CHANNEL_VBAT ((uint32_t)3)
+ * If LPC_CAPTURE_PIN = P2_2, then LPC_CAPTURE_CHANNEL = LPC_CHANNEL_P2_2;
+ * If LPC_CAPTURE_PIN = P2_3, then LPC_CAPTURE_CHANNEL = LPC_CHANNEL_P2_3;
+ */
+#define LPC_CAPTURE_PIN P2_2
+#define LPC_CAPTURE_CHANNEL LPC_CHANNEL_P2_2
+
+#define LPC_VOLTAGE_DETECT_EDGE LPC_Vin_Below_Vth
+#define LPC_VOLTAGE_DETECT_THRESHOLD LPC_2000_mV
+
+
+extern bool IO_LPC_DLPS_Enter_Allowed;
+
+void global_data_lpc_init(void);
+void board_lpc_init(void);
+void driver_lpc_init(void);
+
+void nvic_lpc_init(void);
+void io_handle_lpc_msg(T_IO_MSG *io_uart_msg);
+void io_lpc_dlps_enter(void);
+void io_lpc_dlps_exit(void);
+bool io_lpc_dlps_check(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/ancs.c b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/ancs.h b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app.c b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app.c
new file mode 100644
index 0000000..829a86c
--- /dev/null
+++ b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app.c
@@ -0,0 +1,609 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_lpc.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_BAT_LPC:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: LPC low voltage detection msg.");
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ /* Enable lpc NVIC after GAP stack ready. */
+ nvic_lpc_init();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app.h b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app_flags.h b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app_task.c b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app_task.c
new file mode 100644
index 0000000..f5914b1
--- /dev/null
+++ b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app_task.h b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/main.c b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/main.c
new file mode 100644
index 0000000..156463a
--- /dev/null
+++ b/src/sample/io_sample/LPC/VoltageDetection/ble_peripheral/main.c
@@ -0,0 +1,232 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+
+#include "io_lpc.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_lpc_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_lpc_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/LPC/VoltageDetection/io_lpc.c b/src/sample/io_sample/LPC/VoltageDetection/io_lpc.c
new file mode 100644
index 0000000..72c4a29
--- /dev/null
+++ b/src/sample/io_sample/LPC/VoltageDetection/io_lpc.c
@@ -0,0 +1,87 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file lpc.c
+ * @brief
+ * @author yuan
+ * @date 2018-05-04
+ * @version v0.1
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "io_lpc.h"
+#include "app_task.h"
+
+#include "board.h"
+
+/**
+ * @brief initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_lpc_init(void)
+{
+ Pad_Config(LPC_CAPTURE_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(LPC_CAPTURE_PIN, IDLE_MODE);
+}
+
+/**
+ * @brief Initialize RTC peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_lpc_init(void)
+{
+ LPC_DeInit();
+ LPC_InitTypeDef LPC_InitStruct;
+ LPC_StructInit(&LPC_InitStruct);
+
+ LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL;
+ LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE;
+ LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD;
+ LPC_Init(&LPC_InitStruct);
+ LPC_Cmd(ENABLE);
+
+ LPC_INTConfig(LPC_INT_LPCOMP_VOL, ENABLE);
+}
+
+void nvic_lpc_init(void)
+{
+ /* Config LPC interrupt */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = LPCOMP_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ LPC_INTCmd(ENABLE);
+}
+
+/**
+ * @brief LPC battery detection interrupt handle function.
+ * @param None.
+ * @return None.
+ */
+void LPCOMP_Handler(void)
+{
+ LPC_INTConfig(LPC_INT_LPCOMP_VOL, DISABLE);
+ APP_PRINT_INFO0("LPCOMP_Handler\r\n");
+ T_IO_MSG int_lpc_msg;
+
+ int_lpc_msg.type = IO_MSG_TYPE_BAT_LPC;
+ if (false == app_send_msg_to_apptask(&int_lpc_msg))
+ {
+ APP_PRINT_ERROR0("[io_lpc] LPCOMP_Handler: Send int_lpc_msg failed!");
+ return;
+ }
+ //Add application code here
+}
+
diff --git a/src/sample/io_sample/LPC/VoltageDetection/io_lpc.h b/src/sample/io_sample/LPC/VoltageDetection/io_lpc.h
new file mode 100644
index 0000000..2b00845
--- /dev/null
+++ b/src/sample/io_sample/LPC/VoltageDetection/io_lpc.h
@@ -0,0 +1,54 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_lpc.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_LPC_H
+#define __IO_LPC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_lpc.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "trace.h"
+
+
+/* Defines ------------------------------------------------------------------*/
+/** LPC voltage detect channel config.
+ * PIN select:P2_2 P2_3 P2_6 and VBAT.
+ * LPC channel select: #define LPC_CHANNEL_P2_2 ((uint32_t)0)
+ * #define LPC_CHANNEL_P2_3 ((uint32_t)1)
+ * #define LPC_CHANNEL_P2_6 ((uint32_t)2)
+ * #define LPC_CHANNEL_VBAT ((uint32_t)3)
+ * If LPC_CAPTURE_PIN = P2_2, then LPC_CAPTURE_CHANNEL = LPC_CHANNEL_P2_2;
+ */
+#define LPC_CAPTURE_PIN P2_2
+#define LPC_CAPTURE_CHANNEL LPC_CHANNEL_P2_2
+
+#define LPC_VOLTAGE_DETECT_EDGE LPC_Vin_Below_Vth
+#define LPC_VOLTAGE_DETECT_THRESHOLD LPC_2000_mV
+
+void board_lpc_init(void);
+void driver_lpc_init(void);
+void nvic_lpc_init(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/ancs.c b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/ancs.h b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app.c b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app.c
new file mode 100644
index 0000000..f9086a3
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app.c
@@ -0,0 +1,611 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_qdec.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_QDECODE:
+ {
+ APP_PRINT_INFO0("[app]app_handle_io_msg: qdec msg.");
+ io_handle_qdec_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ /* Enable QDEC when the GAP stack is ready. */
+ QDEC_Cmd(QDEC, QDEC_AXIS_Y, ENABLE);
+
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app.h b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app_flags.h b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app_task.c b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app_task.c
new file mode 100644
index 0000000..635c4c3
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app_task.h b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/main.c b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/main.c
new file mode 100644
index 0000000..b680a23
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC _DLPS/ble_peripheral/main.c
@@ -0,0 +1,318 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+//#include "app_timer.h"
+#include "dlps.h"
+#include "rtl876x_io_dlps.h"
+#include "io_qdec.h"
+
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+ global_data_qdec_init();
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_qdec_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_qdec_init();
+}
+#if DLPS_EN
+/**
+ * @brief this function will be called before enter DLPS
+ *
+ * set PAD and wakeup pin config for enterring DLPS
+ *
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_enter_dlps_config(void)
+{
+ io_qdec_dlps_enter();
+}
+
+/**
+ * @brief this function will be called after exit DLPS
+ *
+ * set PAD and wakeup pin config for enterring DLPS
+ *
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_exit_dlps_config(void)
+{
+ io_qdec_dlps_exit();
+}
+
+/**
+ * @brief Contains the setting about app dlps callback.
+ */
+bool app_dlps_check_cb(void)
+{
+ return (io_qdec_dlps_check());
+}
+#endif /* DLPS_EN */
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+#if DLPS_EN
+ if (false == dlps_check_cb_reg(app_dlps_check_cb))
+ {
+ APP_PRINT_ERROR0("Error: dlps_check_cb_reg(app_dlps_check_cb) failed!");
+ }
+ DLPS_IORegUserDlpsEnterCb(app_enter_dlps_config);
+ DLPS_IORegUserDlpsExitCb(app_exit_dlps_config);
+ DLPS_IORegister();
+ lps_mode_set(PLATFORM_DLPS_PFM);
+
+ /* Config WakeUp pin */
+ System_WakeUpPinEnable(QDEC_Y_PHA_PIN, PAD_WAKEUP_POL_LOW, 0);
+
+#else
+ lps_mode_set(PLATFORM_ACTIVE);
+#endif
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+
+/**
+ * @brief System interrupt handler function, for wakeup pin.
+ * @param No parameter.
+ * @return void
+*/
+void System_Handler(void)
+{
+ APP_PRINT_INFO0("[main] System_Handler");
+ if (System_WakeUpInterruptValue(QDEC_Y_PHA_PIN) == SET)
+ {
+ Pad_ClearWakeupINTPendingBit(QDEC_Y_PHA_PIN);
+ System_WakeUpPinDisable(QDEC_Y_PHA_PIN);
+ IO_QDEC_DLPS_Enter_Allowed = false;
+ }
+}
+
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/QDEC/QDEC _DLPS/io_qdec.c b/src/sample/io_sample/QDEC/QDEC _DLPS/io_qdec.c
new file mode 100644
index 0000000..ce5f80f
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC _DLPS/io_qdec.c
@@ -0,0 +1,170 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file io_qdec.c
+* @brief qdec demo
+* @details
+* @author yuan
+* @date 2019-01-15
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_qdec.h"
+
+#include "trace.h"
+
+#include "app_task.h"
+
+/* Globals -------------------------------------------------------------------*/
+QDEC_Data_TypeDef Y_Axis_Data;
+
+bool IO_QDEC_DLPS_Enter_Allowed = false;
+
+
+/**
+ * @brief Initialize uart global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_qdec_init(void)
+{
+ IO_QDEC_DLPS_Enter_Allowed = true;
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return Void
+ */
+void board_qdec_init(void)
+{
+ /* Qdecoder pad config */
+ Pad_Config(QDEC_Y_PHA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+ Pad_Config(QDEC_Y_PHB_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+
+ /* Qdecoder pinmux config */
+ Pinmux_Config(QDEC_Y_PHA_PIN, qdec_phase_a_y);
+ Pinmux_Config(QDEC_Y_PHB_PIN, qdec_phase_b_y);
+}
+
+/**
+ * @brief Initialize Qdecoder peripheral.
+ * @param No parameter.
+ * @return Void
+ */
+void driver_qdec_init(void)
+{
+ QDEC_DeInit(QDEC);
+ RCC_PeriphClockCmd(APBPeriph_QDEC, APBPeriph_QDEC_CLOCK, ENABLE);
+
+ QDEC_InitTypeDef QDEC_InitStruct;
+ QDEC_StructInit(&QDEC_InitStruct);
+ QDEC_InitStruct.axisConfigY = ENABLE;
+ QDEC_InitStruct.debounceEnableY = Debounce_Enable;
+ QDEC_Init(QDEC, &QDEC_InitStruct);
+ QDEC_INTConfig(QDEC, QDEC_Y_INT_NEW_DATA, ENABLE);
+
+ /** To debug, enable QDEC when the GAP stack is ready.
+ * In app.c->app_handle_dev_state_evt()
+ */
+// QDEC_Cmd(QDEC, QDEC_AXIS_Y, ENABLE);
+
+ NVIC_InitTypeDef nvic_init_struct;
+ nvic_init_struct.NVIC_IRQChannel = qdecode_IRQn;
+ nvic_init_struct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ nvic_init_struct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&nvic_init_struct);
+
+}
+
+/**
+ * @brief IO enter dlps call back function.
+ * @param No parameter.
+ * @return void
+ */
+void io_qdec_dlps_enter(void)
+{
+ /* Switch pad to Software mode */
+ Pad_ControlSelectValue(QDEC_Y_PHA_PIN, PAD_SW_MODE);
+ Pad_ControlSelectValue(QDEC_Y_PHB_PIN, PAD_SW_MODE);
+
+ System_WakeUpPinEnable(QDEC_Y_PHA_PIN, PAD_WAKEUP_POL_LOW, 0);
+}
+
+/**
+ * @brief IO exit dlps call back function.
+ * @param No parameter.
+ * @return void
+ */
+void io_qdec_dlps_exit(void)
+{
+ /* Switch pad to Pinmux mode */
+ Pad_ControlSelectValue(QDEC_Y_PHA_PIN, PAD_PINMUX_MODE);
+ Pad_ControlSelectValue(QDEC_Y_PHB_PIN, PAD_PINMUX_MODE);
+}
+
+/**
+ * @brief IO enter dlps check function.
+ * @param No parameter.
+ * @return void
+ */
+bool io_qdec_dlps_check(void)
+{
+ return IO_QDEC_DLPS_Enter_Allowed;
+}
+/**
+ * @brief Handle qdec data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_qdec_msg(T_IO_MSG *io_qdec_msg)
+{
+ QDEC_Data_TypeDef *p_buf = io_qdec_msg->u.buf;
+ APP_PRINT_INFO2("[io_qdec]io_handle_qdec_msg: Y_Axis_Direction = %d,Y_Axis_Count = %d,",
+ p_buf->AxisDirection, p_buf->AxisCount);
+ global_data_qdec_init();
+
+ IO_QDEC_DLPS_Enter_Allowed = true;
+}
+
+/**
+ * @brief Qdecode interrupt handler function.
+ * @param No parameter.
+ * @return Void
+ */
+void Qdecode_Handler(void)
+{
+ if (QDEC_GetFlagState(QDEC, QDEC_FLAG_NEW_CT_STATUS_Y) == SET)
+ {
+ /* Mask qdec interrupt */
+ QDEC_INTMask(QDEC, QDEC_Y_CT_INT_MASK, ENABLE);
+
+ /* Read direction & count */
+ Y_Axis_Data.AxisDirection = QDEC_GetAxisDirection(QDEC, QDEC_AXIS_Y);
+ Y_Axis_Data.AxisCount = QDEC_GetAxisCount(QDEC, QDEC_AXIS_Y);
+
+ T_IO_MSG int_qdec_msg;
+
+ int_qdec_msg.type = IO_MSG_TYPE_QDECODE;
+ int_qdec_msg.u.buf = (void *)&Y_Axis_Data;
+ if (false == app_send_msg_to_apptask(&int_qdec_msg))
+ {
+ APP_PRINT_ERROR0("[io_qdec]Qdecode_Handler: Send int_qdec_msg failed!");
+ //Add user code here!
+ /* Clear qdec interrupt flags */
+ QDEC_ClearINTPendingBit(QDEC, QDEC_CLR_NEW_CT_Y);
+ return;
+ }
+ /* Clear qdec interrupt flags */
+ QDEC_ClearINTPendingBit(QDEC, QDEC_CLR_NEW_CT_Y);
+ /* Unmask qdec interrupt */
+ QDEC_INTMask(QDEC, QDEC_Y_CT_INT_MASK, DISABLE);
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/QDEC/QDEC _DLPS/io_qdec.h b/src/sample/io_sample/QDEC/QDEC _DLPS/io_qdec.h
new file mode 100644
index 0000000..e8be942
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC _DLPS/io_qdec.h
@@ -0,0 +1,61 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_qdec.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_QDEC_H
+#define __IO_QDEC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_qdec.h"
+#include "rtl876x_rcc.h"
+
+#include "board.h"
+
+#include "app_msg.h"
+
+
+/* Globals ------------------------------------------------------------------*/
+
+/* QDEC data struct*/
+typedef struct
+{
+
+ uint16_t AxisDirection;
+ uint16_t AxisCount;
+} QDEC_Data_TypeDef;
+
+extern QDEC_Data_TypeDef Y_Axis_Data;
+
+
+extern bool IO_QDEC_DLPS_Enter_Allowed;
+
+void global_data_qdec_init(void);
+bool io_qdec_dlps_check(void);
+void io_qdec_dlps_enter(void);
+void io_qdec_dlps_exit(void);
+void board_qdec_init(void);
+void driver_qdec_init(void);
+void io_handle_qdec_msg(T_IO_MSG *io_qdec_msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/QDEC/QDEC/ble_peripheral/ancs.c b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/QDEC/QDEC/ble_peripheral/ancs.h b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/QDEC/QDEC/ble_peripheral/app.c b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/app.c
new file mode 100644
index 0000000..f9086a3
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/app.c
@@ -0,0 +1,611 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_qdec.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_QDECODE:
+ {
+ APP_PRINT_INFO0("[app]app_handle_io_msg: qdec msg.");
+ io_handle_qdec_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ /* Enable QDEC when the GAP stack is ready. */
+ QDEC_Cmd(QDEC, QDEC_AXIS_Y, ENABLE);
+
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/QDEC/QDEC/ble_peripheral/app.h b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/QDEC/QDEC/ble_peripheral/app_flags.h b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/QDEC/QDEC/ble_peripheral/app_task.c b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/app_task.c
new file mode 100644
index 0000000..635c4c3
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/QDEC/QDEC/ble_peripheral/app_task.h b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/QDEC/QDEC/ble_peripheral/main.c b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/main.c
new file mode 100644
index 0000000..648b48a
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC/ble_peripheral/main.c
@@ -0,0 +1,245 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+//#include "app_timer.h"
+
+#include "io_qdec.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_qdec_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_qdec_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/QDEC/QDEC/io_qdec.c b/src/sample/io_sample/QDEC/QDEC/io_qdec.c
new file mode 100644
index 0000000..2141707
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC/io_qdec.c
@@ -0,0 +1,119 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file io_qdec.c
+* @brief qdec demo
+* @details
+* @author yuan
+* @date 2019-01-15
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_qdec.h"
+
+#include "trace.h"
+
+#include "app_task.h"
+
+/* Globals -------------------------------------------------------------------*/
+QDEC_Data_TypeDef Y_Axis_Data;
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return Void
+ */
+void board_qdec_init(void)
+{
+ /* Qdecoder pad config */
+ Pad_Config(QDEC_Y_PHA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+ Pad_Config(QDEC_Y_PHB_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+
+ /* Qdecoder pinmux config */
+ Pinmux_Config(QDEC_Y_PHA_PIN, qdec_phase_a_y);
+ Pinmux_Config(QDEC_Y_PHB_PIN, qdec_phase_b_y);
+}
+
+/**
+ * @brief Initialize Qdecoder peripheral.
+ * @param No parameter.
+ * @return Void
+ */
+void driver_qdec_init(void)
+{
+ QDEC_DeInit(QDEC);
+ RCC_PeriphClockCmd(APBPeriph_QDEC, APBPeriph_QDEC_CLOCK, ENABLE);
+
+ QDEC_InitTypeDef QDEC_InitStruct;
+ QDEC_StructInit(&QDEC_InitStruct);
+ QDEC_InitStruct.axisConfigY = ENABLE;
+ QDEC_InitStruct.debounceEnableY = Debounce_Enable;
+ QDEC_Init(QDEC, &QDEC_InitStruct);
+ QDEC_INTConfig(QDEC, QDEC_Y_INT_NEW_DATA, ENABLE);
+
+ /** To debug, enable QDEC when the GAP stack is ready.
+ * In app.c->app_handle_dev_state_evt()
+ */
+// QDEC_Cmd(QDEC, QDEC_AXIS_Y, ENABLE);
+
+ NVIC_InitTypeDef nvic_init_struct;
+ nvic_init_struct.NVIC_IRQChannel = qdecode_IRQn;
+ nvic_init_struct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ nvic_init_struct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&nvic_init_struct);
+
+}
+
+/**
+ * @brief Handle adc data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_qdec_msg(T_IO_MSG *io_qdec_msg)
+{
+ QDEC_Data_TypeDef *p_buf = io_qdec_msg->u.buf;
+ APP_PRINT_INFO2("[io_qdec]io_handle_qdec_msg: Y_Axis_Direction = %d,Y_Axis_Count = %d,",
+ p_buf->AxisDirection, p_buf->AxisCount);
+}
+
+/**
+ * @brief Qdecode interrupt handler function.
+ * @param No parameter.
+ * @return Void
+ */
+void Qdecode_Handler(void)
+{
+ if (QDEC_GetFlagState(QDEC, QDEC_FLAG_NEW_CT_STATUS_Y) == SET)
+ {
+ /* Mask qdec interrupt */
+ QDEC_INTMask(QDEC, QDEC_Y_CT_INT_MASK, ENABLE);
+
+ /* Read direction & count */
+ Y_Axis_Data.AxisDirection = QDEC_GetAxisDirection(QDEC, QDEC_AXIS_Y);
+ Y_Axis_Data.AxisCount = QDEC_GetAxisCount(QDEC, QDEC_AXIS_Y);
+
+ T_IO_MSG int_qdec_msg;
+
+ int_qdec_msg.type = IO_MSG_TYPE_QDECODE;
+ int_qdec_msg.u.buf = (void *)&Y_Axis_Data;
+ if (false == app_send_msg_to_apptask(&int_qdec_msg))
+ {
+ APP_PRINT_ERROR0("[io_qdec]Qdecode_Handler: Send int_qdec_msg failed!");
+ //Add user code here!
+ /* Clear qdec interrupt flags */
+ QDEC_ClearINTPendingBit(QDEC, QDEC_CLR_NEW_CT_Y);
+ return;
+ }
+ /* Clear qdec interrupt flags */
+ QDEC_ClearINTPendingBit(QDEC, QDEC_CLR_NEW_CT_Y);
+ /* Unmask qdec interrupt */
+ QDEC_INTMask(QDEC, QDEC_Y_CT_INT_MASK, DISABLE);
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/QDEC/QDEC/io_qdec.h b/src/sample/io_sample/QDEC/QDEC/io_qdec.h
new file mode 100644
index 0000000..67dac9a
--- /dev/null
+++ b/src/sample/io_sample/QDEC/QDEC/io_qdec.h
@@ -0,0 +1,54 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_qdec.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_QDEC_H
+#define __IO_QDEC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_qdec.h"
+#include "rtl876x_rcc.h"
+
+#include "board.h"
+
+#include "app_msg.h"
+
+
+/* Globals ------------------------------------------------------------------*/
+
+/* QDEC data struct*/
+typedef struct
+{
+
+ uint16_t AxisDirection;
+ uint16_t AxisCount;
+} QDEC_Data_TypeDef;
+
+extern QDEC_Data_TypeDef Y_Axis_Data;
+
+void board_qdec_init(void);
+void driver_qdec_init(void);
+void io_handle_qdec_msg(T_IO_MSG *io_qdec_msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/RTC/Comparator/main.c b/src/sample/io_sample/RTC/Comparator/main.c
new file mode 100644
index 0000000..97a9dbe
--- /dev/null
+++ b/src/sample/io_sample/RTC/Comparator/main.c
@@ -0,0 +1,116 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code to realize RTC comparator function.
+ RTC is a 32-bit counter.
+* @details
+* @author yuan
+* @date 2018-05-25
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Defines ------------------------------------------------------------------*/
+/** Prescaler value.
+ * 12 bits prescaler for COUNTER frequency (32768/(PRESCALER+1)).
+ * If use internal 32KHz, (32000/(PRESCALER+1)).
+ * Must be written when RTC 32-bit counter is stopped.
+ */
+#define RTC_PRESCALER_VALUE (3200-1)//f = 10Hz
+/* RTC has 4 comparators,comparator0~3 . */
+#define RTC_COMP_INDEX RTC_COMP1
+#define RTC_COMP_INDEX_INT RTC_INT_COMP1
+#define RTC_COMP_VALUE (10)
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include "rtl876x_nvic.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_rtc.h"
+#include "trace.h"
+
+/**
+ * @brief Initialize rtc peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_rtc_init(void)
+{
+ RTC_DeInit();
+
+ RTC_SetPrescaler(RTC_PRESCALER_VALUE);
+ RTC_SetCompValue(RTC_COMP_INDEX, RTC_COMP_VALUE);
+
+ RTC_INTConfig(RTC_COMP_INDEX_INT, ENABLE);
+
+ /* Config RTC interrupt */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ RTC_NvCmd(ENABLE);
+ /* Start RTC */
+ RTC_ResetCounter();
+ RTC_Cmd(ENABLE);
+}
+
+/**
+ * @brief Demo code of operation about RTC.
+ * @param No parameter.
+ * @return void
+ */
+void rtc_demo(void)
+{
+ /* Initialize RTC peripheral */
+ driver_rtc_init();
+
+ //Add application code here
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+
+ rtc_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ }
+}
+
+/**
+ * @brief RTC interrupt handle function.
+ * @param None.
+ * @return None.
+ */
+void RTC_Handler(void)
+{
+ if (RTC_GetINTStatus(RTC_COMP_INDEX_INT) == SET)
+ {
+ /* Notes: DBG_DIRECT function is only used for debugging demonstrations, not for application projects.*/
+ DBG_DIRECT("[main]RTC_Handler: RTC_COMP_INDEX%d", RTC_COMP_INDEX);
+ DBG_DIRECT("[main]RTC_Handler: RTC counter current value = %d", RTC_GetCounter());
+ RTC_SetCompValue(RTC_COMP_INDEX, RTC_GetCounter() + RTC_COMP_VALUE);
+ RTC_ClearCompINT(RTC_COMP_INDEX);
+// RTC_ClearINTPendingBit();
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/RTC/Overflow/main.c b/src/sample/io_sample/RTC/Overflow/main.c
new file mode 100644
index 0000000..766c0de
--- /dev/null
+++ b/src/sample/io_sample/RTC/Overflow/main.c
@@ -0,0 +1,107 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code to realize RTC Overflow function.
+ RTC is a 32-bit counter.
+* @details
+* @author yuan
+* @date 2018-05-25
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Defines ------------------------------------------------------------------*/
+/** Prescaler value.
+ * 12 bits prescaler for COUNTER frequency (32768/(PRESCALER+1)).
+ * If use internal 32KHz, (32000/(PRESCALER+1)).
+ * Must be written when RTC 32-bit counter is stopped.
+ */
+#define RTC_PRESCALER_VALUE 0 //f = (1/32000)Hz
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include "rtl876x_rcc.h"
+#include "rtl876x_rtc.h"
+#include "rtl876x_nvic.h"
+#include "trace.h"
+
+/**
+ * @brief Initialize rtc peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_rtc_init(void)
+{
+ RTC_DeInit();
+ RTC_SetPrescaler(RTC_PRESCALER_VALUE);
+
+ /* Config RTC interrupt */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 2;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ RTC_NvCmd(ENABLE);
+ /* Start RTC */
+ RTC_ResetCounter();
+ RTC_Cmd(ENABLE);
+}
+
+/**
+ * @brief Demo code of operation about RTC.
+ * @param No parameter.
+ * @return void
+ */
+void rtc_demo(void)
+{
+ /* Initialize RTC peripheral */
+ driver_rtc_init();
+ //Add application code here
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+
+ rtc_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+
+ }
+}
+
+/**
+ * @brief RTC interrupt handle function.
+ * @param None.
+ * @return None.
+ */
+void RTC_Handler(void)
+{
+ /* RTC overflow interrupt handle */
+ if (RTC_GetINTStatus(RTC_INT_OVF) == SET)
+ {
+ /* Notes: DBG_DIRECT function is only used for debugging demonstrations, not for application projects.*/
+ DBG_DIRECT("[main]RTC_Handler: RTC_INT_OVF");
+ // Add application code here
+ RTC_ClearOverFlowINT();
+ }
+}
+
+/******************* (C) COPYRIGHT 2016 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/RTC/Pre_comp3/main.c b/src/sample/io_sample/RTC/Pre_comp3/main.c
new file mode 100644
index 0000000..db5980b
--- /dev/null
+++ b/src/sample/io_sample/RTC/Pre_comp3/main.c
@@ -0,0 +1,132 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code to realize RTC prescaler + comparator3 function.
+ RTC is a 32-bit counter.
+* @details
+* @author yuan
+* @date 2018-05-25
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Defines ------------------------------------------------------------------*/
+#define RTC_PRESCALER_VALUE (3200 - 1)//max 4095
+#define RTC_PRECOMP_VALUE (320)//max 4095
+#define RTC_COMP3_VALUE (10)
+
+/** Define prescaler & comparator3 interrupt.
+ * 1:prescaler & comparator3 interrupt,
+ (prescaler_value = prescaler_counter)&&(comparator3_value = counter),
+ RTC_PRECOMP_VALUE <= RTC_PRESCALER_VALUE
+ * 0:prescaler comparator interrupt,(prescaler_value = prescaler_counter)
+ */
+#define RTC_PRECOMP3_INT 1
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include "rtl876x_nvic.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_rtc.h"
+#include "trace.h"
+
+/**
+ * @brief Initialize LPC peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_rtc_init(void)
+{
+ RTC_DeInit();
+
+#if (RTC_PRECOMP3_INT)
+ RTC_SetPrescaler(RTC_PRESCALER_VALUE);
+ RTC_SetPreCompValue(RTC_PRECOMP_VALUE);
+ RTC_SetCompValue(RTC_COMP3, RTC_COMP3_VALUE);
+
+ RTC_INTConfig(RTC_INT_PRE_COMP3, ENABLE);
+
+#else
+ RTC_SetPrescaler(RTC_PRESCALER_VALUE);
+ RTC_SetPreCompValue(RTC_PRECOMP_VALUE);
+
+ RTC_INTConfig(RTC_INT_PRE_COMP, ENABLE);
+#endif
+ /* Config RTC interrupt */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ RTC_NvCmd(ENABLE);
+ /* Start RTC */
+ RTC_ResetCounter();
+ RTC_Cmd(ENABLE);
+}
+
+/**
+ * @brief Demo code of operation about RTC.
+ * @param No parameter.
+ * @return void
+*/
+void rtc_demo(void)
+{
+ /* Initialize RTC peripheral */
+ driver_rtc_init();
+
+ //Add application code here
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+
+ rtc_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ }
+}
+
+/**
+ * @brief RTC interrupt handle function.
+ * @param None.
+ * @return None.
+ */
+void RTC_Handler(void)
+{
+ DBG_DIRECT("RTC_Handler");
+#if (RTC_PRECOMP3_INT)
+ if (RTC_GetINTStatus(RTC_INT_PRE_COMP3) == SET)
+ {
+ DBG_DIRECT("RTC_INT_PRE_COMP3");
+ uint32_t counter = RTC_GetCounter();
+ RTC_SetCompValue(RTC_COMP3, counter + RTC_COMP3_VALUE);
+ RTC_ClearINTPendingBit(RTC_INT_PRE_COMP3);
+ }
+#else
+ if (RTC_GetINTStatus(RTC_INT_PRE_COMP) == SET)
+ {
+ DBG_DIRECT("RTC_INT_PRE_COMP");
+ RTC_ClearINTPendingBit(RTC_INT_PRE_COMP);
+ }
+#endif
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/RTC/Tick/main.c b/src/sample/io_sample/RTC/Tick/main.c
new file mode 100644
index 0000000..7b41205
--- /dev/null
+++ b/src/sample/io_sample/RTC/Tick/main.c
@@ -0,0 +1,104 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code to realize RTC tick function.
+ RTC is a 32-bit counter.
+* @details
+* @author yuan
+* @date 2018-05-25
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Defines ------------------------------------------------------------------*/
+/** Prescaler value.
+ * 12 bits prescaler for COUNTER frequency (32768/(PRESCALER+1)).
+ * If use internal 32KHz, (32000/(PRESCALER+1)).
+ * Must be written when RTC 32-bit counter is stopped.
+ */
+#define RTC_PRESCALER_VALUE (3200-1) //f = 10Hz
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include "rtl876x_nvic.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_rtc.h"
+#include "trace.h"
+
+/**
+ * @brief Initialize rtc peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_rtc_init(void)
+{
+ RTC_DeInit();
+ RTC_SetPrescaler(RTC_PRESCALER_VALUE);
+
+ RTC_INTConfig(RTC_INT_TICK, ENABLE);
+
+ /* Config RTC interrupt */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 2;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ RTC_NvCmd(ENABLE);
+
+ /* Start RTC */
+ RTC_ResetCounter();
+ RTC_Cmd(ENABLE);
+}
+
+/**
+ * @brief Demo code of operation about RTC.
+ * @param No parameter.
+ * @return void
+ */
+void rtc_demo(void)
+{
+ /* Initialize RTC peripheral */
+ driver_rtc_init();
+
+ //Add application code here
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+
+ rtc_demo();
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ }
+}
+
+void RTC_Handler(void)
+{
+ /* RTC tick interrupt handle */
+ if (RTC_GetINTStatus(RTC_INT_TICK) == SET)
+ {
+ /* Notes: DBG_DIRECT function is only used for debugging demonstrations, not for application projects.*/
+ DBG_DIRECT("[main]RTC_Handler: RTC_INT_TICK");
+ // Add application code here
+ RTC_ClearTickINT();
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/SPI/Flash/ble_peripheral/ancs.c b/src/sample/io_sample/SPI/Flash/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/SPI/Flash/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/SPI/Flash/ble_peripheral/ancs.h b/src/sample/io_sample/SPI/Flash/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/SPI/Flash/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Flash/ble_peripheral/app.c b/src/sample/io_sample/SPI/Flash/ble_peripheral/app.c
new file mode 100644
index 0000000..8649e55
--- /dev/null
+++ b/src/sample/io_sample/SPI/Flash/ble_peripheral/app.c
@@ -0,0 +1,608 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_spi.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_SPI:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: spi msg.");
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ spi_demo();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/SPI/Flash/ble_peripheral/app.h b/src/sample/io_sample/SPI/Flash/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/SPI/Flash/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Flash/ble_peripheral/app_flags.h b/src/sample/io_sample/SPI/Flash/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/SPI/Flash/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/SPI/Flash/ble_peripheral/app_task.c b/src/sample/io_sample/SPI/Flash/ble_peripheral/app_task.c
new file mode 100644
index 0000000..635c4c3
--- /dev/null
+++ b/src/sample/io_sample/SPI/Flash/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/SPI/Flash/ble_peripheral/app_task.h b/src/sample/io_sample/SPI/Flash/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/SPI/Flash/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Flash/ble_peripheral/main.c b/src/sample/io_sample/SPI/Flash/ble_peripheral/main.c
new file mode 100644
index 0000000..a12dc8a
--- /dev/null
+++ b/src/sample/io_sample/SPI/Flash/ble_peripheral/main.c
@@ -0,0 +1,245 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+
+#include "io_spi.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_spi_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_spi_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/SPI/Flash/io_spi.c b/src/sample/io_sample/SPI/Flash/io_spi.c
new file mode 100644
index 0000000..508d29c
--- /dev/null
+++ b/src/sample/io_sample/SPI/Flash/io_spi.c
@@ -0,0 +1,124 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_spi.c
+* @brief This file provides demo code of spi master.
+ GD25Q128E is slave.
+ Read the chip id of GD25Q128E.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_spi.h"
+
+#include "spi_flash.h"
+#include "app_task.h"
+
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_spi_init(void)
+{
+ Pad_Config(SPI0_SCK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI0_MOSI_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI0_MISO_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI0_CS_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+
+ Pinmux_Deinit(P4_0);
+ Pinmux_Deinit(P4_1);
+ Pinmux_Deinit(P4_2);
+ Pinmux_Deinit(P4_3);
+
+ Pinmux_Config(SPI0_SCK_PIN, SPI0_CLK_MASTER);
+ Pinmux_Config(SPI0_MOSI_PIN, SPI0_MO_MASTER);
+ Pinmux_Config(SPI0_MISO_PIN, SPI0_MI_MASTER);
+ Pinmux_Config(SPI0_CS_PIN, SPI0_SS_N_0_MASTER);
+}
+
+/**
+ * @brief Initialize spi peripheral.
+ * @param No parameter.
+ * @return void
+ */
+//void SPI_InitConfiguration(void)
+//{
+// SPI_InitTypeDef SPI_InitStructure;
+
+// SPI_StructInit(&SPI_InitStructure);
+// SPI_InitStructure.SPI_Direction = SPI_Direction_EEPROM;
+// SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
+// SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
+// SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
+// SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
+// SPI_InitStructure.SPI_BaudRatePrescaler = 16;
+// SPI_InitStructure.SPI_RxThresholdLevel = 8;
+// SPI_InitStructure.SPI_FrameFormat = SPI_Frame_Motorola;
+// SPI_InitStructure.SPI_NDF = 0;
+// SPI_Init(SPI0, &SPI_InitStructure);
+
+// SPI_Cmd(SPI0, ENABLE);
+//}
+
+void driver_spi_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE);
+
+ SPI_InitTypeDef SPI_InitStruct;
+ SPI_StructInit(&SPI_InitStruct);
+
+ SPI_InitStruct.SPI_Direction = SPI_Direction_FullDuplex;
+ SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
+ SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
+ SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
+ SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
+ SPI_InitStruct.SPI_BaudRatePrescaler = 20;
+ /* SPI_Direction_EEPROM mode read data length. */
+ SPI_InitStruct.SPI_RxThresholdLevel = 1;/* Flash id length = 3*/
+ SPI_InitStruct.SPI_NDF = 0;/* Flash id length = 3*/
+ SPI_InitStruct.SPI_FrameFormat = SPI_Frame_Motorola;
+ SPI_Init(SPI0, &SPI_InitStruct);
+
+ SPI_Cmd(SPI0, ENABLE);
+
+}
+
+/**
+ * @brief Demo code of operation about spi.
+ * @param No parameter.
+ * @return void
+*/
+void spi_demo(void)
+{
+ uint8_t flash_id[10] = {0};
+ uint8_t write_data[100];
+ uint8_t read_data[105] = {0};
+ for (uint16_t i = 0; i < 100; i++)
+ {
+ write_data[i] = i & 0xFF;
+ }
+
+ spi_flash_read_id(flash_id);
+ APP_PRINT_INFO1("[io_spi] spi_demo: flash_id = %b ", TRACE_BINARY(3, flash_id));
+
+ spi_flash_sector_erase(0x001000);
+ APP_PRINT_INFO0("[io_spi] spi_demo: spi_flash_sector_erase done");
+
+ spi_flash_read(SPI_FLASH_FAST_READ, 0x001000, read_data, 100);
+// APP_PRINT_INFO1("[io_spi] spi_demo: read_data = %b,", TRACE_BINARY(100, &read_data[5]));
+ APP_PRINT_INFO1("[io_spi] spi_demo: read_data = %b,", TRACE_BINARY(100, read_data));
+
+ spi_flash_page_write(0x001000, write_data, 100);
+
+ spi_flash_read(SPI_FLASH_FAST_READ, 0x001000, read_data, 100);
+ APP_PRINT_INFO1("[io_spi] spi_demo: read_data = %b,", TRACE_BINARY(100, read_data));
+}
+
+
diff --git a/src/sample/io_sample/SPI/Flash/io_spi.h b/src/sample/io_sample/SPI/Flash/io_spi.h
new file mode 100644
index 0000000..669d128
--- /dev/null
+++ b/src/sample/io_sample/SPI/Flash/io_spi.h
@@ -0,0 +1,41 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_spi.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_SPI_H
+#define __IO_SPI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_spi.h"
+
+#include "board.h"
+
+#include "app_msg.h"
+
+void board_spi_init(void);
+void driver_spi_init(void);
+void spi_demo(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Flash/spi_flash.c b/src/sample/io_sample/SPI/Flash/spi_flash.c
new file mode 100644
index 0000000..c159596
--- /dev/null
+++ b/src/sample/io_sample/SPI/Flash/spi_flash.c
@@ -0,0 +1,303 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code of spi write and ead data from GD25Q128E flash.
+* @details
+* @author yuan
+* @date 2019-07-10
+* @version v1.0
+*********************************************************************************************************
+*/
+#include "spi_flash.h"
+#include "io_spi.h"
+#include "trace.h"
+#include <string.h>
+
+
+void spi_flash_read_id(uint8_t *pFlashId)
+{
+ uint8_t send_buf[4] = {SPI_FLASH_JEDEC_ID, 0, 0, 0};
+ uint8_t recv_buf[10] = {0};
+ uint8_t recv_len = 3;
+
+#if (SPI_MODE_EEPROM == SPI_MODE)
+ SPI_SetReadLen(FLASH_SPI, 3);
+ SPI_SendBuffer(FLASH_SPI, send_buf, 1);
+#elif (SPI_MODE_FULLDUPLEX == SPI_MODE)
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+ recv_len += 1;
+#endif
+
+ uint8_t idx = 0;
+ while (recv_len--)
+ {
+ while (RESET == SPI_GetFlagState(FLASH_SPI, SPI_FLAG_RFNE));
+ recv_buf[idx++] = SPI_ReceiveData(FLASH_SPI);
+ }
+
+#if (SPI_MODE_EEPROM == SPI_MODE)
+ memcpy(pFlashId, recv_buf, 3);
+#elif (SPI_MODE_FULLDUPLEX == SPI_MODE)
+ memcpy(pFlashId, &recv_buf[1], 3);
+#endif
+}
+
+void spi_flash_busy_check(void)
+{
+ uint8_t send_buf[2] = {SPI_FLASH_READ_STATUS_REG_1, 0};
+ uint8_t recv_len = 0;
+ uint8_t recv_data[2] = {0};
+
+ while (1)
+ {
+ SPI_SendBuffer(FLASH_SPI, send_buf, 2);
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ uint8_t i = 0;
+ while (recv_len--)
+ {
+ recv_data[i++] = SPI_ReceiveData(FLASH_SPI);
+ }
+ i = 0;
+ if ((recv_data[1] & 0x01) == 0)
+ {
+ break;
+ }
+ }
+}
+
+void spi_flash_write_enable(void)
+{
+ uint8_t len = 0;
+
+ SPI_SendData(FLASH_SPI, SPI_FLASH_WRITE_ENABLE);
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+}
+
+void spi_flash_status_reg_write(uint8_t vStatus)
+{
+ uint8_t len = 0;
+ uint8_t send_buf[2] = {SPI_FLASH_WRITE_STATUS_REG_1, 0};
+
+ send_buf[1] = vStatus & 0xff;
+
+ /* Enable write */
+ spi_flash_write_enable();
+
+ /* Write status register */
+ SPI_SendBuffer(FLASH_SPI, send_buf, 2);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ spi_flash_busy_check();
+}
+
+void spi_flash_sector_erase(uint32_t vAddress)
+{
+ uint8_t send_buf[4] = {SPI_FLASH_SECTOR_ERASE, 0, 0, 0};
+ uint8_t recv_len = 0;
+
+ send_buf[1] = (vAddress >> 16) & 0xff;
+ send_buf[2] = (vAddress >> 8) & 0xff;
+ send_buf[3] = vAddress & 0xff;
+
+ /* enable write */
+ spi_flash_write_enable();
+
+ /* erase data */
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ spi_flash_busy_check();
+}
+
+void spi_flash_block_erase(uint32_t vAddress)
+{
+ uint8_t send_buf[4] = {SPI_FLASH_BLOCK_ERASE_32K, 0, 0, 0};
+ uint8_t recv_len = 0;
+
+ send_buf[1] = (vAddress >> 16) & 0xff;
+ send_buf[2] = (vAddress >> 8) & 0xff;
+ send_buf[3] = vAddress & 0xff;
+
+ /* Enable write */
+ spi_flash_write_enable();
+ /* erase data */
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ spi_flash_busy_check();
+}
+
+void spi_flash_chip_erase(void)
+{
+ uint8_t recv_len = 0;
+
+ /* Enable write */
+ spi_flash_write_enable();
+
+ SPI_SendData(FLASH_SPI, SPI_FLASH_CHIP_ERASE);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ spi_flash_busy_check();
+}
+
+void spi_flash_page_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength)
+{
+ uint16_t send_data_len = vLength;
+ uint8_t recv_data_len = 0;
+ uint8_t send_buf[4] = {SPI_FLASH_PAGE_PROGRAM, 0, 0, 0};
+ send_buf[1] = (vWriteAddr >> 16) & 0xff;
+ send_buf[2] = (vWriteAddr >> 8) & 0xff;
+ send_buf[3] = vWriteAddr & 0xff;
+
+ if (vLength > SPI_FLASH_PAGE_SIZE)
+ {
+ send_data_len = SPI_FLASH_PAGE_SIZE;
+ }
+
+ /* Enable write */
+ spi_flash_write_enable();
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+ SPI_SendBuffer(FLASH_SPI, pBuffer, send_data_len);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_data_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_data_len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ spi_flash_busy_check();
+}
+
+void spi_flash_buffer_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength)
+{
+ uint32_t write_addr = vWriteAddr;
+ uint8_t *p_write_data = pBuffer;
+ uint16_t write_data_len = vLength;
+
+ uint8_t offset = vWriteAddr % SPI_FLASH_PAGE_SIZE;
+ uint8_t free_len = SPI_FLASH_PAGE_SIZE - offset;
+ uint8_t page_num = vLength / SPI_FLASH_PAGE_SIZE;
+ uint8_t remain_len = vLength % SPI_FLASH_PAGE_SIZE;
+
+ if (offset == 0)
+ {
+ if (page_num == 0) // write_data_len < SPI_FLASH_PAGE_SIZE
+ {
+ spi_flash_page_write(write_addr, p_write_data, remain_len);
+ }
+ else // write_data_len > SPI_FLASH_PAGE_SIZE
+ {
+ while (page_num--)
+ {
+ spi_flash_page_write(write_addr, p_write_data, SPI_FLASH_PAGE_SIZE);
+ write_addr += SPI_FLASH_PAGE_SIZE;
+ p_write_data += SPI_FLASH_PAGE_SIZE;
+ }
+ spi_flash_page_write(write_addr, p_write_data, remain_len);
+ }
+ }
+ else // write_addr is not SPI_FLASH_PAGE_SIZE aligned
+ {
+ if (page_num == 0)
+ {
+ if (remain_len > free_len) /* (write_data_len + write_addr) > SPI_FLASH_PAGE_SIZE */
+ {
+ uint8_t temp = remain_len - free_len;
+ spi_flash_page_write(write_addr, p_write_data, free_len);
+ write_addr += free_len;
+ p_write_data += free_len;
+ spi_flash_page_write(vWriteAddr, p_write_data, temp);
+ }
+ else
+ {
+ spi_flash_page_write(write_addr, p_write_data, write_data_len);
+ }
+
+ }
+ else /* NumByteToWrite > SPI_FLASH_PAGE_SIZE */
+ {
+ write_data_len -= free_len;
+ page_num = write_data_len / SPI_FLASH_PAGE_SIZE;
+ remain_len = write_data_len % SPI_FLASH_PAGE_SIZE;
+
+ spi_flash_page_write(write_addr, p_write_data, free_len);
+ write_addr += free_len;
+ p_write_data += free_len;
+
+ while (page_num--)
+ {
+ spi_flash_page_write(write_addr, p_write_data, SPI_FLASH_PAGE_SIZE);
+ write_addr += SPI_FLASH_PAGE_SIZE;
+ p_write_data += SPI_FLASH_PAGE_SIZE;
+ }
+
+ if (remain_len != 0)
+ {
+ spi_flash_page_write(write_addr, p_write_data, remain_len);
+ }
+ }
+ }
+}
+
+void spi_flash_read(uint8_t vReadCmd, uint32_t vReadAddr, uint8_t *pBuffer, uint16_t vLength)
+{
+ uint8_t send_buf[10] = {0};
+ uint8_t send_len = 0;
+ uint16_t recv_len = 0;
+
+ if (SPI_FLASH_READ_DATA == vReadCmd)
+ {
+ send_len = 4;
+ }
+ else if (SPI_FLASH_FAST_READ == vReadCmd)
+ {
+ send_len = 5;
+ }
+ send_buf[0] = vReadCmd;
+ send_buf[1] = (vReadAddr >> 16) & 0xFF;
+ send_buf[2] = (vReadAddr >> 8) & 0xFF;
+ send_buf[3] = (vReadAddr) & 0xFF;
+
+ SPI_SendBuffer(FLASH_SPI, send_buf, send_len);
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_RFNE) == RESET);
+ for (uint8_t i = 0; i < send_len; i++)
+ {
+ SPI_ReceiveData(FLASH_SPI);//dummy read data
+ }
+ recv_len = vLength;
+ while (recv_len--)
+ {
+ SPI_SendBuffer(FLASH_SPI, &send_buf[9], 1);
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_RFNE) == RESET);
+ *pBuffer++ = SPI_ReceiveData(FLASH_SPI);
+ }
+
+}
diff --git a/src/sample/io_sample/SPI/Flash/spi_flash.h b/src/sample/io_sample/SPI/Flash/spi_flash.h
new file mode 100644
index 0000000..79867c8
--- /dev/null
+++ b/src/sample/io_sample/SPI/Flash/spi_flash.h
@@ -0,0 +1,68 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file spi_flash.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __SPI_FLASH_H
+#define __SPI_FLASH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_spi.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define SPI_FLASH_PAGE_SIZE 256
+
+#define SPI_FLASH_WRITE_ENABLE 0x06
+#define SPI_FLASH_WRITE_DISABLE 0x04
+#define SPI_FLASH_READ_STATUS_REG_1 0x05
+#define SPI_FLASH_WRITE_STATUS_REG_1 0x01
+#define SPI_FLASH_READ_STATUS_REG_2 0x35
+#define SPI_FLASH_WRITE_STATUS_REG_2 0x31
+#define SPI_FLASH_PAGE_PROGRAM 0x02
+#define SPI_FLASH_SECTOR_ERASE 0x20
+#define SPI_FLASH_BLOCK_ERASE_32K 0x52
+#define SPI_FLASH_BLOCK_ERASE_64K 0xD8
+#define SPI_FLASH_CHIP_ERASE 0xC7
+#define SPI_FLASH_POWER_DOWN 0xB9
+#define SPI_FLASH_READ_DATA 0x03
+#define SPI_FLASH_FAST_READ 0x0B
+#define SPI_FLASH_RELEASE_POWER_DOWN 0xAB
+#define SPI_FLASH_DEVICE_ID 0xAB
+#define SPI_FLASH_MANU_ID 0x90
+#define SPI_FLASH_JEDEC_ID 0x9F
+#define SPI_FLASH_ENABLE_RESET 0x66
+#define SPI_FLASH_RESET 0x99
+
+#define EWIP_FLAG 0x01 /* Erase/Write in progress (WIP) flag */
+
+
+void spi_flash_read_id(uint8_t *pFlashId);
+void spi_flash_busy_check(void);
+void spi_flash_write_enable(void);
+void spi_flash_status_reg_write(uint8_t vStatus);
+void spi_flash_sector_erase(uint32_t vAddress);
+void spi_flash_block_erase(uint32_t vAddress);
+void spi_flash_chip_erase(void);
+void spi_flash_page_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength);
+void spi_flash_buffer_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength);
+void spi_flash_read(uint8_t vReadCmd, uint32_t vReadAddr, uint8_t *pBuffer, uint16_t vLength);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/ancs.c b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/ancs.h b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app.c b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app.c
new file mode 100644
index 0000000..27c94a3
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app.c
@@ -0,0 +1,613 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_spi.h"
+#include "io_gdma.h"
+#include "io_uart.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_GDMA:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: dma msg.");
+ io_handle_gdma_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ uint8_t data[] = {"IO-SPI+GDMA read flash data demo!"};
+ uart_senddata_continuous(UART0, data, sizeof(data));
+ spi_demo();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app.h b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app_flags.h b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app_task.c b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app_task.c
new file mode 100644
index 0000000..635c4c3
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app_task.h b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/main.c b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/main.c
new file mode 100644
index 0000000..faf151a
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/ble_peripheral/main.c
@@ -0,0 +1,247 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+
+#include "io_spi.h"
+#include "io_uart.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_spi_init();
+ board_uart_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_uart_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/io_gdma.c b/src/sample/io_sample/SPI/GDMA_Multiblock/io_gdma.c
new file mode 100644
index 0000000..aa7e067
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/io_gdma.c
@@ -0,0 +1,172 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file io_gdma.c
+* @brief This file provides demo code of meomory to memory transfer by gdma.
+* @details
+* @author yuan
+* @date 2019-01-11
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_gdma.h"
+#include "io_UART.h"
+
+
+/* Globals ------------------------------------------------------------------*/
+uint8_t GDMA_WriteCmdBuffer[5] = {0x0B, 0x01, 0x00, 0x00, 0x00};
+uint8_t GDMA_Recv_Buffer[GDMA_MULTIBLOCK_SIZE][GDMA_TRANSFER_SIZE];
+GDMA_LLIDef GDMA_LLIStruct[GDMA_MULTIBLOCK_SIZE];
+
+/**
+ * @brief Initialize gdma peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_spi_gdma_init(void)
+{
+ /*----------------test buffer init------------------*/
+ memset(GDMA_Recv_Buffer, 0, sizeof(GDMA_Recv_Buffer) / sizeof(GDMA_Recv_Buffer[0][0]));
+
+ SPI_InitTypeDef SPI_InitStructure;
+ GDMA_InitTypeDef GDMA_InitStruct;
+
+ SPI_DeInit(FLASH_SPI);
+ RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE);
+
+ /*----------------------SPI init---------------------------------*/
+ SPI_StructInit(&SPI_InitStructure);
+ SPI_InitStructure.SPI_Direction = SPI_Direction_EEPROM;//SPI_Direction_RxOnly;
+ SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
+ SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
+ SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
+ SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
+ SPI_InitStructure.SPI_BaudRatePrescaler = 100;
+ SPI_InitStructure.SPI_FrameFormat = SPI_Frame_Motorola;
+ SPI_InitStructure.SPI_NDF = GDMA_READ_SIZE_MAX - 1;
+ SPI_InitStructure.SPI_RxDmaEn = ENABLE;
+ SPI_InitStructure.SPI_RxWaterlevel = 1;
+ SPI_Init(FLASH_SPI, &SPI_InitStructure);
+
+ /*---------------------GDMA initial------------------------------*/
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = GDMA_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToMemory;
+ GDMA_InitStruct.GDMA_BufferSize = GDMA_TRANSFER_SIZE;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Inc;
+
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)FLASH_SPI->DR;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)GDMA_Recv_Buffer;
+ GDMA_InitStruct.GDMA_SourceHandshake = GDMA_Handshake_SPI0_RX;
+ GDMA_InitStruct.GDMA_ChannelPriority = 1;
+ GDMA_InitStruct.GDMA_Multi_Block_En = 1;
+ GDMA_InitStruct.GDMA_Multi_Block_Mode = LLI_TRANSFER;
+ GDMA_InitStruct.GDMA_Multi_Block_Struct = (uint32_t)GDMA_LLIStruct;
+
+ for (int i = 0; i < GDMA_MULTIBLOCK_SIZE; i++)
+ {
+ GDMA_LLIStruct[i].SAR = (uint32_t)FLASH_SPI->DR;
+ GDMA_LLIStruct[i].DAR = (uint32_t)GDMA_Recv_Buffer[i];
+ if (i == (GDMA_MULTIBLOCK_SIZE - 1))
+ {
+ GDMA_LLIStruct[i].DAR = (uint32_t)GDMA_Recv_Buffer[i];
+ GDMA_LLIStruct[i].LLP = 0;
+ /* configure low 32 bit of CTL register */
+ GDMA_LLIStruct[i].CTL_LOW = BIT(0)
+ | (GDMA_InitStruct.GDMA_DestinationDataSize << 1)
+ | (GDMA_InitStruct.GDMA_SourceDataSize << 4)
+ | (GDMA_InitStruct.GDMA_DestinationInc << 7)
+ | (GDMA_InitStruct.GDMA_SourceInc << 9)
+ | (GDMA_InitStruct.GDMA_DestinationMsize << 11)
+ | (GDMA_InitStruct.GDMA_SourceMsize << 14)
+ | (GDMA_InitStruct.GDMA_DIR << 20);
+ /* configure high 32 bit of CTL register */
+ GDMA_LLIStruct[i].CTL_HIGH = GDMA_InitStruct.GDMA_BufferSize;
+ }
+ else
+ {
+ GDMA_LLIStruct[i].LLP = (uint32_t)&GDMA_LLIStruct[i + 1];
+ /* configure low 32 bit of CTL register */
+ GDMA_LLIStruct[i].CTL_LOW = BIT(0)
+ | (GDMA_InitStruct.GDMA_DestinationDataSize << 1)
+ | (GDMA_InitStruct.GDMA_SourceDataSize << 4)
+ | (GDMA_InitStruct.GDMA_DestinationInc << 7)
+ | (GDMA_InitStruct.GDMA_SourceInc << 9)
+ | (GDMA_InitStruct.GDMA_DestinationMsize << 11)
+ | (GDMA_InitStruct.GDMA_SourceMsize << 14)
+ | (GDMA_InitStruct.GDMA_DIR << 20)
+ | (GDMA_InitStruct.GDMA_Multi_Block_Mode & LLP_SELECTED_BIT);
+ /* configure high 32 bit of CTL register */
+ GDMA_LLIStruct[i].CTL_HIGH = GDMA_InitStruct.GDMA_BufferSize;
+ }
+ }
+
+ GDMA_Init(GDMA_Channel, &GDMA_InitStruct);
+
+ /*-----------------GDMA IRQ-----------------------------*/
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = GDMA_Channel_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ /* Enable transfer interrupt */
+ GDMA_INTConfig(GDMA_CHANNEL_NUM, GDMA_INT_Block, ENABLE);
+ GDMA_Cmd(GDMA_CHANNEL_NUM, ENABLE);
+ SPI_Cmd(FLASH_SPI, ENABLE);
+
+ /* Send read data command */
+ SPI_SendBuffer(FLASH_SPI, GDMA_WriteCmdBuffer, 5);
+}
+
+/**
+ * @brief Handle gdma data function.
+ * @param No parameter.
+ * @return void
+ */
+uint8_t gdma_transfer_num = 0;
+void io_handle_gdma_msg(T_IO_MSG *io_gdma_msg)
+{
+ uint8_t *p_buf = io_gdma_msg->u.buf;
+ uint16_t data_len = (GDMA_TRANSFER_SIZE);
+ APP_PRINT_INFO2("[io_gdma] io_handle_gdma_msg: read data complete, num = %d, data_len = %d",
+ gdma_transfer_num, data_len);
+ uart_senddata_continuous(UART0, &p_buf[gdma_transfer_num * data_len], data_len);
+ gdma_transfer_num++;
+}
+
+/**
+ * @brief GDMA channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void GDMA_Channel_Handler(void)
+{
+ GDMA_INTConfig(GDMA_CHANNEL_NUM, GDMA_INT_Block, DISABLE);
+
+ T_IO_MSG int_gdma_msg;
+
+ int_gdma_msg.type = IO_MSG_TYPE_GDMA;
+ int_gdma_msg.subtype = 0;
+ int_gdma_msg.u.buf = (void *)GDMA_Recv_Buffer;
+ if (false == app_send_msg_to_apptask(&int_gdma_msg))
+ {
+ APP_PRINT_ERROR0("[io_gdma]GDMA_Channel_Handler: Send int_gdma_msg failed!");
+ //Add user code here!
+ GDMA_ClearINTPendingBit(GDMA_CHANNEL_NUM, GDMA_INT_Block);
+ return;
+ }
+ GDMA_ClearINTPendingBit(GDMA_CHANNEL_NUM, GDMA_INT_Block);
+ GDMA_INTConfig(GDMA_CHANNEL_NUM, GDMA_INT_Block, ENABLE);
+}
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/io_gdma.h b/src/sample/io_sample/SPI/GDMA_Multiblock/io_gdma.h
new file mode 100644
index 0000000..53bc103
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/io_gdma.h
@@ -0,0 +1,44 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_gdma.h
+* @brief
+* @details
+* @author yuan
+* @date 2019-01-11
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_GDMA_H
+#define __IO_GDMA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include "rtl876x_gdma.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_spi.h"
+#include "trace.h"
+
+#include "board.h"
+
+#include "app_task.h"
+
+
+void driver_spi_gdma_init(void);
+void io_handle_gdma_msg(T_IO_MSG *io_gdma_msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/io_spi.c b/src/sample/io_sample/SPI/GDMA_Multiblock/io_spi.c
new file mode 100644
index 0000000..6f0f8f3
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/io_spi.c
@@ -0,0 +1,64 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_spi.c
+* @brief This file provides demo code of spi master.
+ GD25Q128E is slave.
+ Read data from GD25Q128E by GDMA.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_spi.h"
+#include "io_gdma.h"
+
+
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_spi_init(void)
+{
+ Pad_Config(SPI_SCK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI_MOSI_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI_MISO_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI_CS_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+
+// Pinmux_Deinit(P4_0);
+// Pinmux_Deinit(P4_1);
+// Pinmux_Deinit(P4_2);
+// Pinmux_Deinit(P4_3);
+
+ Pinmux_Config(SPI_SCK_PIN, SPI0_CLK_MASTER);
+ Pinmux_Config(SPI_MOSI_PIN, SPI0_MO_MASTER);
+ Pinmux_Config(SPI_MISO_PIN, SPI0_MI_MASTER);
+ Pinmux_Config(SPI_CS_PIN, SPI0_SS_N_0_MASTER);
+}
+
+/**
+ * @brief Initialize spi peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_spi_init(void)
+{
+}
+
+/**
+ * @brief Demo code of operation about spi.
+ * @param No parameter.
+ * @return void
+*/
+void spi_demo(void)
+{
+ APP_PRINT_INFO0("[io_spi] spi_demo");
+ driver_spi_gdma_init();
+}
+
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/io_spi.h b/src/sample/io_sample/SPI/GDMA_Multiblock/io_spi.h
new file mode 100644
index 0000000..02a9122
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/io_spi.h
@@ -0,0 +1,43 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_spi.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_SPI_H
+#define __IO_SPI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_spi.h"
+
+#include "board.h"
+
+#include "app_msg.h"
+
+
+void board_spi_init(void);
+void driver_spi_init(void);
+void spi_demo(void);
+void io_handle_spi_msg(T_IO_MSG *io_spi_msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/io_uart.c b/src/sample/io_sample/SPI/GDMA_Multiblock/io_uart.c
new file mode 100644
index 0000000..7dbdb36
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/io_uart.c
@@ -0,0 +1,84 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file io_uart.c
+* @brief uart interrupt demo
+* @details
+* @author yuan
+* @date 2018-06-28
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_uart.h"
+
+#include <string.h>
+
+#include "app_task.h"
+
+#include "trace.h"
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_uart_init(void)
+{
+ Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+ Pad_Config(UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+
+ Pinmux_Config(UART_TX_PIN, UART0_TX);
+ Pinmux_Config(UART_RX_PIN, UART0_RX);
+}
+
+/**
+ * @brief Initialize uart peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_uart_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ /* uart init */
+ UART_InitTypeDef UART_InitStruct;
+ UART_StructInit(&UART_InitStruct);
+
+ UART_InitStruct.UART_Parity = UART_PARITY_NO_PARTY;
+ UART_InitStruct.UART_StopBits = UART_STOP_BITS_1;
+ UART_InitStruct.UART_WordLen = UART_WORD_LENGTH_8BIT;
+ UART_InitStruct.UART_RxThdLevel = 16; //1~29
+ UART_InitStruct.UART_IdleTime = UART_RX_IDLE_2BYTE; //idle interrupt wait time
+ UART_Init(UART0, &UART_InitStruct);
+}
+
+/**
+ * @brief UARt send data continuous.
+ * @param No parameter.
+ * @return void
+ */
+void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount)
+{
+ uint8_t count;
+
+ while (vCount / UART_TX_FIFO_SIZE > 0)
+ {
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ for (count = UART_TX_FIFO_SIZE; count > 0; count--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+ vCount -= UART_TX_FIFO_SIZE;
+ }
+
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ while (vCount--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/io_uart.h b/src/sample/io_sample/SPI/GDMA_Multiblock/io_uart.h
new file mode 100644
index 0000000..47b0c4d
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/io_uart.h
@@ -0,0 +1,37 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_uart.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_UART_H
+#define __IO_UART_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_uart.h"
+#include "board.h"
+
+void board_uart_init(void);
+void driver_uart_init(void);
+void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/spi_flash.c b/src/sample/io_sample/SPI/GDMA_Multiblock/spi_flash.c
new file mode 100644
index 0000000..c11b96f
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/spi_flash.c
@@ -0,0 +1,310 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code of spi read data from GD25Q32 flash by GDMA.
+* @details
+* @author yuan
+* @date 2019-07-10
+* @version v1.0
+*********************************************************************************************************
+*/
+#include "spi_flash.h"
+#include "io_spi.h"
+#include "trace.h"
+#include <string.h>
+
+
+void spi_flash_read_id(uint8_t *pFlashId)
+{
+ uint8_t send_buf[4] = {SPI_FLASH_JEDEC_ID, 0, 0, 0};
+ uint8_t recv_buf[10] = {0};
+ uint8_t recv_len = 3;
+
+#if (SPI_MODE_EEPROM == SPI_MODE)
+ SPI_SetReadLen(FLASH_SPI, 3);
+ SPI_SendBuffer(FLASH_SPI, send_buf, 1);
+#elif (SPI_MODE_FULLDUPLEX == SPI_MODE)
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+ recv_len += 1;
+#endif
+
+ uint8_t idx = 0;
+ while (recv_len--)
+ {
+ while (RESET == SPI_GetFlagState(FLASH_SPI, SPI_FLAG_RFNE));
+ recv_buf[idx++] = SPI_ReceiveData(FLASH_SPI);
+ }
+
+#if (SPI_MODE_EEPROM == SPI_MODE)
+ memcpy(pFlashId, recv_buf, 3);
+#elif (SPI_MODE_FULLDUPLEX == SPI_MODE)
+ memcpy(pFlashId, &recv_buf[1], 3);
+#endif
+}
+
+void spi_flash_busy_check(void)
+{
+ uint8_t send_buf[2] = {SPI_FLASH_READ_STATUS_REG_1, 0};
+ uint8_t recv_len = 0;
+ uint8_t recv_data[2] = {0};
+
+ while (1)
+ {
+ SPI_SendBuffer(FLASH_SPI, send_buf, 2);
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ uint8_t i = 0;
+ while (recv_len--)
+ {
+ recv_data[i++] = SPI_ReceiveData(FLASH_SPI);
+ }
+ i = 0;
+ if ((recv_data[1] & 0x01) == 0)
+ {
+ break;
+ }
+ }
+}
+
+void spi_flash_write_enable(void)
+{
+ uint8_t len = 0;
+
+ SPI_SendData(FLASH_SPI, SPI_FLASH_WRITE_ENABLE);
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+}
+
+void spi_flash_status_reg_write(uint16_t vStatus)
+{
+ uint8_t len = 0;
+ uint8_t send_buf[3] = {SPI_FLASH_WRITE_STATUS_REG_1, 0, 0};
+
+ send_buf[1] = vStatus & 0xff;
+ send_buf[2] = (vStatus >> 8) & 0xff;
+
+ /* Enable write */
+ spi_flash_write_enable();
+
+ /* Write status register */
+ SPI_SendBuffer(FLASH_SPI, send_buf, 3);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ spi_flash_busy_check();
+}
+
+void spi_flash_sector_erase(uint32_t vAddress)
+{
+ uint8_t send_buf[4] = {SPI_FLASH_SECTOR_ERASE, 0, 0, 0};
+ uint8_t recv_len = 0;
+
+ send_buf[1] = (vAddress >> 16) & 0xff;
+ send_buf[2] = (vAddress >> 8) & 0xff;
+ send_buf[3] = vAddress & 0xff;
+
+ /* enable write */
+ spi_flash_write_enable();
+ for (uint32_t i = 0; i < 1000; i++);
+
+ /* erase data */
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_len--)
+ {
+ APP_PRINT_INFO1("spi_flash_sector_erase: %d", SPI_ReceiveData(FLASH_SPI));
+// SPI_ReceiveData(FLASH_SPI);
+ }
+ for (uint32_t i = 0; i < 1000; i++);
+ spi_flash_busy_check();
+}
+
+void spi_flash_block_erase(uint32_t vAddress)
+{
+ uint8_t send_buf[4] = {SPI_FLASH_BLOCK_ERASE_32K, 0, 0, 0};
+ uint8_t recv_len = 0;
+
+ send_buf[1] = (vAddress >> 16) & 0xff;
+ send_buf[2] = (vAddress >> 8) & 0xff;
+ send_buf[3] = vAddress & 0xff;
+
+ /* Enable write */
+ spi_flash_write_enable();
+ for (uint32_t i = 0; i < 1000; i++);
+ /* erase data */
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ for (uint32_t i = 0; i < 1000; i++);
+ spi_flash_busy_check();
+}
+
+void spi_flash_chip_erase(void)
+{
+ uint8_t recv_len = 0;
+ uint8_t send_buf[3] = {SPI_FLASH_CHIP_ERASE, 0, 0};
+
+ /* Enable write */
+ spi_flash_write_enable();
+ for (uint32_t i = 0; i < 1000; i++);
+
+ SPI_SendData(FLASH_SPI, SPI_FLASH_CHIP_ERASE);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ for (uint32_t i = 0; i < 1000; i++);
+ spi_flash_busy_check();
+}
+
+void spi_flash_page_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength)
+{
+ uint16_t send_data_len = vLength;
+ uint8_t recv_data_len = 0;
+ uint8_t send_buf[4] = {SPI_FLASH_PAGE_PROGRAM, 0, 0, 0};
+ send_buf[1] = (vWriteAddr >> 16) & 0xff;
+ send_buf[2] = (vWriteAddr >> 8) & 0xff;
+ send_buf[3] = vWriteAddr & 0xff;
+
+ if (vLength > SPI_FLASH_PAGE_SIZE)
+ {
+ send_data_len = SPI_FLASH_PAGE_SIZE;
+ }
+
+ /* Enable write */
+ spi_flash_write_enable();
+ for (uint32_t i = 0; i < 1000; i++);
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+ SPI_SendBuffer(FLASH_SPI, pBuffer, send_data_len);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_data_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_data_len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ for (uint32_t i = 0; i < 1000; i++);
+ spi_flash_busy_check();
+}
+
+void spi_flash_buffer_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength)
+{
+ uint32_t write_addr = vWriteAddr;
+ uint8_t *p_write_data = pBuffer;
+ uint16_t write_data_len = vLength;
+
+ uint8_t offset = vWriteAddr % SPI_FLASH_PAGE_SIZE;
+ uint8_t free_len = SPI_FLASH_PAGE_SIZE - offset;
+ uint8_t page_num = vLength / SPI_FLASH_PAGE_SIZE;
+ uint8_t remain_len = vLength % SPI_FLASH_PAGE_SIZE;
+
+ if (offset == 0)
+ {
+ if (page_num == 0) // write_data_len < SPI_FLASH_PAGE_SIZE
+ {
+ spi_flash_page_write(write_addr, p_write_data, remain_len);
+ }
+ else // write_data_len > SPI_FLASH_PAGE_SIZE
+ {
+ while (page_num--)
+ {
+ spi_flash_page_write(write_addr, p_write_data, SPI_FLASH_PAGE_SIZE);
+ write_addr += SPI_FLASH_PAGE_SIZE;
+ p_write_data += SPI_FLASH_PAGE_SIZE;
+ }
+ spi_flash_page_write(write_addr, p_write_data, remain_len);
+ }
+ }
+ else // write_addr is not SPI_FLASH_PAGE_SIZE aligned
+ {
+ if (page_num == 0)
+ {
+ if (remain_len > free_len) /* (write_data_len + write_addr) > SPI_FLASH_PAGE_SIZE */
+ {
+ uint8_t temp = remain_len - free_len;
+ spi_flash_page_write(write_addr, p_write_data, free_len);
+ write_addr += free_len;
+ p_write_data += free_len;
+ spi_flash_page_write(vWriteAddr, p_write_data, temp);
+ }
+ else
+ {
+ spi_flash_page_write(write_addr, p_write_data, write_data_len);
+ }
+
+ }
+ else /* NumByteToWrite > SPI_FLASH_PAGE_SIZE */
+ {
+ write_data_len -= free_len;
+ page_num = write_data_len / SPI_FLASH_PAGE_SIZE;
+ remain_len = write_data_len % SPI_FLASH_PAGE_SIZE;
+
+ spi_flash_page_write(write_addr, p_write_data, free_len);
+ write_addr += free_len;
+ p_write_data += free_len;
+
+ while (page_num--)
+ {
+ spi_flash_page_write(write_addr, p_write_data, SPI_FLASH_PAGE_SIZE);
+ write_addr += SPI_FLASH_PAGE_SIZE;
+ p_write_data += SPI_FLASH_PAGE_SIZE;
+ }
+
+ if (remain_len != 0)
+ {
+ spi_flash_page_write(write_addr, p_write_data, remain_len);
+ }
+ }
+ }
+}
+
+void spi_flash_read(uint8_t vReadCmd, uint32_t vReadAddr, uint8_t *pBuffer, uint16_t vLength)
+{
+ uint8_t send_buf[10] = {0};
+ uint8_t send_len = 0;
+ uint16_t recv_len = 0;
+
+ if (SPI_FLASH_READ_DATA == vReadCmd)
+ {
+ send_len = 4;
+ }
+ else if (SPI_FLASH_FAST_READ == vReadCmd)
+ {
+ send_len = 5;
+ }
+ send_buf[0] = vReadCmd;
+ send_buf[1] = (vReadAddr >> 16) & 0xFF;
+ send_buf[2] = (vReadAddr >> 8) & 0xFF;
+ send_buf[3] = (vReadAddr) & 0xFF;
+
+ SPI_SendBuffer(FLASH_SPI, send_buf, send_len);
+ recv_len = vLength + send_len;
+ while (recv_len--)
+ {
+ SPI_SendBuffer(FLASH_SPI, &send_buf[9], 1);
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_RFNE) == RESET);
+ *pBuffer++ = SPI_ReceiveData(FLASH_SPI);
+ }
+ SPI_SetReadLen(FLASH_SPI, 1);
+}
+
diff --git a/src/sample/io_sample/SPI/GDMA_Multiblock/spi_flash.h b/src/sample/io_sample/SPI/GDMA_Multiblock/spi_flash.h
new file mode 100644
index 0000000..797a204
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Multiblock/spi_flash.h
@@ -0,0 +1,73 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file spi_flash.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __SPI_FLASH_H
+#define __SPI_FLASH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_spi.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define SPI_FLASH_PAGE_SIZE 256
+#define SPI_FLASH_PerWritePageSize 256
+
+#define SPI_FLASH_WRITE_ENABLE 0x06
+#define SPI_FLASH_WRITE_DISABLE 0x04
+#define SPI_FLASH_READ_STATUS_REG_1 0x05
+#define SPI_FLASH_WRITE_STATUS_REG_1 0x01
+#define SPI_FLASH_READ_STATUS_REG_2 0x35
+#define SPI_FLASH_WRITE_STATUS_REG_2 0x31
+#define SPI_FLASH_PAGE_PROGRAM 0x02
+#define SPI_FLASH_SECTOR_ERASE 0x20
+#define SPI_FLASH_BLOCK_ERASE_32K 0x52
+#define SPI_FLASH_BLOCK_ERASE_64K 0xD8
+#define SPI_FLASH_CHIP_ERASE 0xC7
+#define SPI_FLASH_POWER_DOWN 0xB9
+#define SPI_FLASH_READ_DATA 0x03
+#define SPI_FLASH_FAST_READ 0x0B
+#define SPI_FLASH_RELEASE_POWER_DOWN 0xAB
+#define SPI_FLASH_DEVICE_ID 0xAB
+#define SPI_FLASH_MANU_ID 0x90
+#define SPI_FLASH_JEDEC_ID 0x9F
+#define SPI_FLASH_ENABLE_RESET 0x66
+#define SPI_FLASH_RESET 0x99
+
+#define EWIP_FLAG 0x01 /* Erase/Write in progress (WIP) flag */
+
+/* Globals ------------------------------------------------------------------*/
+//extern uint8_t Flash_Data[4];
+
+void spi_flash_read_id(uint8_t *pFlashId);
+void spi_flash_busy_check(void);
+void spi_flash_write_enable(void);
+void spi_flash_status_reg_write(uint16_t vStatus);
+void spi_flash_sector_erase(uint32_t vAddress);
+void spi_flash_block_erase(uint32_t vAddress);
+void spi_flash_chip_erase(void);
+void spi_flash_page_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength);
+void spi_flash_buffer_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength);
+void spi_flash_read(uint8_t vReadCmd, uint32_t vReadAddr, uint8_t *pBuffer, uint16_t vLength);
+//void spi_flash_fast_read(uint32_t vReadAddr, uint8_t* pBuffer, uint16_t vLength);
+//void spi_flash_page_write(uint32_t vWriteAddr, uint8_t* pBuffer, uint16_t vLength);//uint8_t *psendBuf, uint32_t len
+//void GD25Q32_ReadData(uint8_t *psendBuf, uint32_t len);
+//void spi_flash_buffer_read(uint8_t *pDataBuf,uint32_t vAddress,uint32_t vDataLength);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/ancs.c b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/ancs.h b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app.c b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app.c
new file mode 100644
index 0000000..27c94a3
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app.c
@@ -0,0 +1,613 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_spi.h"
+#include "io_gdma.h"
+#include "io_uart.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_GDMA:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: dma msg.");
+ io_handle_gdma_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ uint8_t data[] = {"IO-SPI+GDMA read flash data demo!"};
+ uart_senddata_continuous(UART0, data, sizeof(data));
+ spi_demo();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app.h b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app_flags.h b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app_task.c b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app_task.c
new file mode 100644
index 0000000..635c4c3
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app_task.h b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/main.c b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/main.c
new file mode 100644
index 0000000..faf151a
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/ble_peripheral/main.c
@@ -0,0 +1,247 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+
+#include "io_spi.h"
+#include "io_uart.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_spi_init();
+ board_uart_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_uart_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/io_gdma.c b/src/sample/io_sample/SPI/GDMA_Singleblock/io_gdma.c
new file mode 100644
index 0000000..6f21b79
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/io_gdma.c
@@ -0,0 +1,128 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file io_gdma.c
+* @brief This file provides demo code of meomory to memory transfer by gdma.
+* @details
+* @author echo
+* @date 2021-05-24
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_gdma.h"
+#include "io_UART.h"
+
+
+/* Globals ------------------------------------------------------------------*/
+uint8_t GDMA_WriteCmdBuffer[5] = {0x0B, 0x01, 0x00, 0x00, 0x00};
+uint8_t GDMA_Recv_Buffer[GDMA_TRANSFER_SIZE];
+
+/**
+ * @brief Initialize gdma peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_spi_gdma_init(void)
+{
+ /*----------------test buffer init------------------*/
+ memset(GDMA_Recv_Buffer, 0, sizeof(GDMA_Recv_Buffer) / sizeof(GDMA_Recv_Buffer[0]));
+
+ SPI_InitTypeDef SPI_InitStructure;
+ GDMA_InitTypeDef GDMA_InitStruct;
+
+ SPI_DeInit(FLASH_SPI);
+ RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE);
+
+ /*----------------------SPI init---------------------------------*/
+ SPI_StructInit(&SPI_InitStructure);
+ SPI_InitStructure.SPI_Direction = SPI_Direction_EEPROM;//SPI_Direction_RxOnly;
+ SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
+ SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
+ SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
+ SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
+ SPI_InitStructure.SPI_BaudRatePrescaler = 100;
+ SPI_InitStructure.SPI_FrameFormat = SPI_Frame_Motorola;
+ SPI_InitStructure.SPI_NDF = GDMA_READ_SIZE_MAX - 1;
+ SPI_InitStructure.SPI_RxDmaEn = ENABLE;
+ SPI_InitStructure.SPI_RxWaterlevel = 1;
+ SPI_Init(FLASH_SPI, &SPI_InitStructure);
+
+ /*---------------------GDMA initial------------------------------*/
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = GDMA_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToMemory;
+ GDMA_InitStruct.GDMA_BufferSize = GDMA_TRANSFER_SIZE;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Inc;
+
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)FLASH_SPI->DR;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)GDMA_Recv_Buffer;
+ GDMA_InitStruct.GDMA_SourceHandshake = GDMA_Handshake_SPI0_RX;
+ GDMA_InitStruct.GDMA_ChannelPriority = 1;
+ GDMA_InitStruct.GDMA_Multi_Block_En = 0;
+
+ GDMA_Init(GDMA_Channel, &GDMA_InitStruct);
+
+ /*-----------------GDMA IRQ-----------------------------*/
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = GDMA_Channel_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ /* Enable transfer interrupt */
+ GDMA_INTConfig(GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+ GDMA_Cmd(GDMA_CHANNEL_NUM, ENABLE);
+ SPI_Cmd(FLASH_SPI, ENABLE);
+
+ /* Send read data command */
+ SPI_SendBuffer(FLASH_SPI, GDMA_WriteCmdBuffer, 5);
+}
+
+/**
+ * @brief Handle gdma data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_gdma_msg(T_IO_MSG *io_gdma_msg)
+{
+ uint8_t *p_buf = io_gdma_msg->u.buf;
+ uint16_t data_len = (GDMA_TRANSFER_SIZE);
+ APP_PRINT_INFO1("[io_gdma] io_handle_gdma_msg: read data complete,data_len = %d", data_len);
+ uart_senddata_continuous(UART0, &p_buf[data_len], data_len);
+}
+
+/**
+ * @brief GDMA channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void GDMA_Channel_Handler(void)
+{
+ GDMA_INTConfig(GDMA_CHANNEL_NUM, GDMA_INT_Transfer, DISABLE);
+
+ T_IO_MSG int_gdma_msg;
+
+ int_gdma_msg.type = IO_MSG_TYPE_GDMA;
+ int_gdma_msg.subtype = 0;
+ int_gdma_msg.u.buf = (void *)GDMA_Recv_Buffer;
+ if (false == app_send_msg_to_apptask(&int_gdma_msg))
+ {
+ APP_PRINT_ERROR0("[io_gdma]GDMA_Channel_Handler: Send int_gdma_msg failed!");
+ //Add user code here!
+ GDMA_ClearINTPendingBit(GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+ return;
+ }
+ GDMA_ClearINTPendingBit(GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+ GDMA_INTConfig(GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+}
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/io_gdma.h b/src/sample/io_sample/SPI/GDMA_Singleblock/io_gdma.h
new file mode 100644
index 0000000..53bc103
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/io_gdma.h
@@ -0,0 +1,44 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_gdma.h
+* @brief
+* @details
+* @author yuan
+* @date 2019-01-11
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_GDMA_H
+#define __IO_GDMA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include "rtl876x_gdma.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_spi.h"
+#include "trace.h"
+
+#include "board.h"
+
+#include "app_task.h"
+
+
+void driver_spi_gdma_init(void);
+void io_handle_gdma_msg(T_IO_MSG *io_gdma_msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/io_spi.c b/src/sample/io_sample/SPI/GDMA_Singleblock/io_spi.c
new file mode 100644
index 0000000..6f0f8f3
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/io_spi.c
@@ -0,0 +1,64 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_spi.c
+* @brief This file provides demo code of spi master.
+ GD25Q128E is slave.
+ Read data from GD25Q128E by GDMA.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_spi.h"
+#include "io_gdma.h"
+
+
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_spi_init(void)
+{
+ Pad_Config(SPI_SCK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI_MOSI_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI_MISO_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI_CS_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+
+// Pinmux_Deinit(P4_0);
+// Pinmux_Deinit(P4_1);
+// Pinmux_Deinit(P4_2);
+// Pinmux_Deinit(P4_3);
+
+ Pinmux_Config(SPI_SCK_PIN, SPI0_CLK_MASTER);
+ Pinmux_Config(SPI_MOSI_PIN, SPI0_MO_MASTER);
+ Pinmux_Config(SPI_MISO_PIN, SPI0_MI_MASTER);
+ Pinmux_Config(SPI_CS_PIN, SPI0_SS_N_0_MASTER);
+}
+
+/**
+ * @brief Initialize spi peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_spi_init(void)
+{
+}
+
+/**
+ * @brief Demo code of operation about spi.
+ * @param No parameter.
+ * @return void
+*/
+void spi_demo(void)
+{
+ APP_PRINT_INFO0("[io_spi] spi_demo");
+ driver_spi_gdma_init();
+}
+
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/io_spi.h b/src/sample/io_sample/SPI/GDMA_Singleblock/io_spi.h
new file mode 100644
index 0000000..02a9122
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/io_spi.h
@@ -0,0 +1,43 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_spi.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_SPI_H
+#define __IO_SPI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_spi.h"
+
+#include "board.h"
+
+#include "app_msg.h"
+
+
+void board_spi_init(void);
+void driver_spi_init(void);
+void spi_demo(void);
+void io_handle_spi_msg(T_IO_MSG *io_spi_msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/io_uart.c b/src/sample/io_sample/SPI/GDMA_Singleblock/io_uart.c
new file mode 100644
index 0000000..7dbdb36
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/io_uart.c
@@ -0,0 +1,84 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file io_uart.c
+* @brief uart interrupt demo
+* @details
+* @author yuan
+* @date 2018-06-28
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_uart.h"
+
+#include <string.h>
+
+#include "app_task.h"
+
+#include "trace.h"
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_uart_init(void)
+{
+ Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+ Pad_Config(UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+
+ Pinmux_Config(UART_TX_PIN, UART0_TX);
+ Pinmux_Config(UART_RX_PIN, UART0_RX);
+}
+
+/**
+ * @brief Initialize uart peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_uart_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ /* uart init */
+ UART_InitTypeDef UART_InitStruct;
+ UART_StructInit(&UART_InitStruct);
+
+ UART_InitStruct.UART_Parity = UART_PARITY_NO_PARTY;
+ UART_InitStruct.UART_StopBits = UART_STOP_BITS_1;
+ UART_InitStruct.UART_WordLen = UART_WORD_LENGTH_8BIT;
+ UART_InitStruct.UART_RxThdLevel = 16; //1~29
+ UART_InitStruct.UART_IdleTime = UART_RX_IDLE_2BYTE; //idle interrupt wait time
+ UART_Init(UART0, &UART_InitStruct);
+}
+
+/**
+ * @brief UARt send data continuous.
+ * @param No parameter.
+ * @return void
+ */
+void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount)
+{
+ uint8_t count;
+
+ while (vCount / UART_TX_FIFO_SIZE > 0)
+ {
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ for (count = UART_TX_FIFO_SIZE; count > 0; count--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+ vCount -= UART_TX_FIFO_SIZE;
+ }
+
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ while (vCount--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/io_uart.h b/src/sample/io_sample/SPI/GDMA_Singleblock/io_uart.h
new file mode 100644
index 0000000..47b0c4d
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/io_uart.h
@@ -0,0 +1,37 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_uart.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_UART_H
+#define __IO_UART_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_uart.h"
+#include "board.h"
+
+void board_uart_init(void);
+void driver_uart_init(void);
+void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/spi_flash.c b/src/sample/io_sample/SPI/GDMA_Singleblock/spi_flash.c
new file mode 100644
index 0000000..c11b96f
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/spi_flash.c
@@ -0,0 +1,310 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code of spi read data from GD25Q32 flash by GDMA.
+* @details
+* @author yuan
+* @date 2019-07-10
+* @version v1.0
+*********************************************************************************************************
+*/
+#include "spi_flash.h"
+#include "io_spi.h"
+#include "trace.h"
+#include <string.h>
+
+
+void spi_flash_read_id(uint8_t *pFlashId)
+{
+ uint8_t send_buf[4] = {SPI_FLASH_JEDEC_ID, 0, 0, 0};
+ uint8_t recv_buf[10] = {0};
+ uint8_t recv_len = 3;
+
+#if (SPI_MODE_EEPROM == SPI_MODE)
+ SPI_SetReadLen(FLASH_SPI, 3);
+ SPI_SendBuffer(FLASH_SPI, send_buf, 1);
+#elif (SPI_MODE_FULLDUPLEX == SPI_MODE)
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+ recv_len += 1;
+#endif
+
+ uint8_t idx = 0;
+ while (recv_len--)
+ {
+ while (RESET == SPI_GetFlagState(FLASH_SPI, SPI_FLAG_RFNE));
+ recv_buf[idx++] = SPI_ReceiveData(FLASH_SPI);
+ }
+
+#if (SPI_MODE_EEPROM == SPI_MODE)
+ memcpy(pFlashId, recv_buf, 3);
+#elif (SPI_MODE_FULLDUPLEX == SPI_MODE)
+ memcpy(pFlashId, &recv_buf[1], 3);
+#endif
+}
+
+void spi_flash_busy_check(void)
+{
+ uint8_t send_buf[2] = {SPI_FLASH_READ_STATUS_REG_1, 0};
+ uint8_t recv_len = 0;
+ uint8_t recv_data[2] = {0};
+
+ while (1)
+ {
+ SPI_SendBuffer(FLASH_SPI, send_buf, 2);
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ uint8_t i = 0;
+ while (recv_len--)
+ {
+ recv_data[i++] = SPI_ReceiveData(FLASH_SPI);
+ }
+ i = 0;
+ if ((recv_data[1] & 0x01) == 0)
+ {
+ break;
+ }
+ }
+}
+
+void spi_flash_write_enable(void)
+{
+ uint8_t len = 0;
+
+ SPI_SendData(FLASH_SPI, SPI_FLASH_WRITE_ENABLE);
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+}
+
+void spi_flash_status_reg_write(uint16_t vStatus)
+{
+ uint8_t len = 0;
+ uint8_t send_buf[3] = {SPI_FLASH_WRITE_STATUS_REG_1, 0, 0};
+
+ send_buf[1] = vStatus & 0xff;
+ send_buf[2] = (vStatus >> 8) & 0xff;
+
+ /* Enable write */
+ spi_flash_write_enable();
+
+ /* Write status register */
+ SPI_SendBuffer(FLASH_SPI, send_buf, 3);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ spi_flash_busy_check();
+}
+
+void spi_flash_sector_erase(uint32_t vAddress)
+{
+ uint8_t send_buf[4] = {SPI_FLASH_SECTOR_ERASE, 0, 0, 0};
+ uint8_t recv_len = 0;
+
+ send_buf[1] = (vAddress >> 16) & 0xff;
+ send_buf[2] = (vAddress >> 8) & 0xff;
+ send_buf[3] = vAddress & 0xff;
+
+ /* enable write */
+ spi_flash_write_enable();
+ for (uint32_t i = 0; i < 1000; i++);
+
+ /* erase data */
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_len--)
+ {
+ APP_PRINT_INFO1("spi_flash_sector_erase: %d", SPI_ReceiveData(FLASH_SPI));
+// SPI_ReceiveData(FLASH_SPI);
+ }
+ for (uint32_t i = 0; i < 1000; i++);
+ spi_flash_busy_check();
+}
+
+void spi_flash_block_erase(uint32_t vAddress)
+{
+ uint8_t send_buf[4] = {SPI_FLASH_BLOCK_ERASE_32K, 0, 0, 0};
+ uint8_t recv_len = 0;
+
+ send_buf[1] = (vAddress >> 16) & 0xff;
+ send_buf[2] = (vAddress >> 8) & 0xff;
+ send_buf[3] = vAddress & 0xff;
+
+ /* Enable write */
+ spi_flash_write_enable();
+ for (uint32_t i = 0; i < 1000; i++);
+ /* erase data */
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ for (uint32_t i = 0; i < 1000; i++);
+ spi_flash_busy_check();
+}
+
+void spi_flash_chip_erase(void)
+{
+ uint8_t recv_len = 0;
+ uint8_t send_buf[3] = {SPI_FLASH_CHIP_ERASE, 0, 0};
+
+ /* Enable write */
+ spi_flash_write_enable();
+ for (uint32_t i = 0; i < 1000; i++);
+
+ SPI_SendData(FLASH_SPI, SPI_FLASH_CHIP_ERASE);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ for (uint32_t i = 0; i < 1000; i++);
+ spi_flash_busy_check();
+}
+
+void spi_flash_page_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength)
+{
+ uint16_t send_data_len = vLength;
+ uint8_t recv_data_len = 0;
+ uint8_t send_buf[4] = {SPI_FLASH_PAGE_PROGRAM, 0, 0, 0};
+ send_buf[1] = (vWriteAddr >> 16) & 0xff;
+ send_buf[2] = (vWriteAddr >> 8) & 0xff;
+ send_buf[3] = vWriteAddr & 0xff;
+
+ if (vLength > SPI_FLASH_PAGE_SIZE)
+ {
+ send_data_len = SPI_FLASH_PAGE_SIZE;
+ }
+
+ /* Enable write */
+ spi_flash_write_enable();
+ for (uint32_t i = 0; i < 1000; i++);
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+ SPI_SendBuffer(FLASH_SPI, pBuffer, send_data_len);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_data_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_data_len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ for (uint32_t i = 0; i < 1000; i++);
+ spi_flash_busy_check();
+}
+
+void spi_flash_buffer_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength)
+{
+ uint32_t write_addr = vWriteAddr;
+ uint8_t *p_write_data = pBuffer;
+ uint16_t write_data_len = vLength;
+
+ uint8_t offset = vWriteAddr % SPI_FLASH_PAGE_SIZE;
+ uint8_t free_len = SPI_FLASH_PAGE_SIZE - offset;
+ uint8_t page_num = vLength / SPI_FLASH_PAGE_SIZE;
+ uint8_t remain_len = vLength % SPI_FLASH_PAGE_SIZE;
+
+ if (offset == 0)
+ {
+ if (page_num == 0) // write_data_len < SPI_FLASH_PAGE_SIZE
+ {
+ spi_flash_page_write(write_addr, p_write_data, remain_len);
+ }
+ else // write_data_len > SPI_FLASH_PAGE_SIZE
+ {
+ while (page_num--)
+ {
+ spi_flash_page_write(write_addr, p_write_data, SPI_FLASH_PAGE_SIZE);
+ write_addr += SPI_FLASH_PAGE_SIZE;
+ p_write_data += SPI_FLASH_PAGE_SIZE;
+ }
+ spi_flash_page_write(write_addr, p_write_data, remain_len);
+ }
+ }
+ else // write_addr is not SPI_FLASH_PAGE_SIZE aligned
+ {
+ if (page_num == 0)
+ {
+ if (remain_len > free_len) /* (write_data_len + write_addr) > SPI_FLASH_PAGE_SIZE */
+ {
+ uint8_t temp = remain_len - free_len;
+ spi_flash_page_write(write_addr, p_write_data, free_len);
+ write_addr += free_len;
+ p_write_data += free_len;
+ spi_flash_page_write(vWriteAddr, p_write_data, temp);
+ }
+ else
+ {
+ spi_flash_page_write(write_addr, p_write_data, write_data_len);
+ }
+
+ }
+ else /* NumByteToWrite > SPI_FLASH_PAGE_SIZE */
+ {
+ write_data_len -= free_len;
+ page_num = write_data_len / SPI_FLASH_PAGE_SIZE;
+ remain_len = write_data_len % SPI_FLASH_PAGE_SIZE;
+
+ spi_flash_page_write(write_addr, p_write_data, free_len);
+ write_addr += free_len;
+ p_write_data += free_len;
+
+ while (page_num--)
+ {
+ spi_flash_page_write(write_addr, p_write_data, SPI_FLASH_PAGE_SIZE);
+ write_addr += SPI_FLASH_PAGE_SIZE;
+ p_write_data += SPI_FLASH_PAGE_SIZE;
+ }
+
+ if (remain_len != 0)
+ {
+ spi_flash_page_write(write_addr, p_write_data, remain_len);
+ }
+ }
+ }
+}
+
+void spi_flash_read(uint8_t vReadCmd, uint32_t vReadAddr, uint8_t *pBuffer, uint16_t vLength)
+{
+ uint8_t send_buf[10] = {0};
+ uint8_t send_len = 0;
+ uint16_t recv_len = 0;
+
+ if (SPI_FLASH_READ_DATA == vReadCmd)
+ {
+ send_len = 4;
+ }
+ else if (SPI_FLASH_FAST_READ == vReadCmd)
+ {
+ send_len = 5;
+ }
+ send_buf[0] = vReadCmd;
+ send_buf[1] = (vReadAddr >> 16) & 0xFF;
+ send_buf[2] = (vReadAddr >> 8) & 0xFF;
+ send_buf[3] = (vReadAddr) & 0xFF;
+
+ SPI_SendBuffer(FLASH_SPI, send_buf, send_len);
+ recv_len = vLength + send_len;
+ while (recv_len--)
+ {
+ SPI_SendBuffer(FLASH_SPI, &send_buf[9], 1);
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_RFNE) == RESET);
+ *pBuffer++ = SPI_ReceiveData(FLASH_SPI);
+ }
+ SPI_SetReadLen(FLASH_SPI, 1);
+}
+
diff --git a/src/sample/io_sample/SPI/GDMA_Singleblock/spi_flash.h b/src/sample/io_sample/SPI/GDMA_Singleblock/spi_flash.h
new file mode 100644
index 0000000..797a204
--- /dev/null
+++ b/src/sample/io_sample/SPI/GDMA_Singleblock/spi_flash.h
@@ -0,0 +1,73 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file spi_flash.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __SPI_FLASH_H
+#define __SPI_FLASH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_spi.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define SPI_FLASH_PAGE_SIZE 256
+#define SPI_FLASH_PerWritePageSize 256
+
+#define SPI_FLASH_WRITE_ENABLE 0x06
+#define SPI_FLASH_WRITE_DISABLE 0x04
+#define SPI_FLASH_READ_STATUS_REG_1 0x05
+#define SPI_FLASH_WRITE_STATUS_REG_1 0x01
+#define SPI_FLASH_READ_STATUS_REG_2 0x35
+#define SPI_FLASH_WRITE_STATUS_REG_2 0x31
+#define SPI_FLASH_PAGE_PROGRAM 0x02
+#define SPI_FLASH_SECTOR_ERASE 0x20
+#define SPI_FLASH_BLOCK_ERASE_32K 0x52
+#define SPI_FLASH_BLOCK_ERASE_64K 0xD8
+#define SPI_FLASH_CHIP_ERASE 0xC7
+#define SPI_FLASH_POWER_DOWN 0xB9
+#define SPI_FLASH_READ_DATA 0x03
+#define SPI_FLASH_FAST_READ 0x0B
+#define SPI_FLASH_RELEASE_POWER_DOWN 0xAB
+#define SPI_FLASH_DEVICE_ID 0xAB
+#define SPI_FLASH_MANU_ID 0x90
+#define SPI_FLASH_JEDEC_ID 0x9F
+#define SPI_FLASH_ENABLE_RESET 0x66
+#define SPI_FLASH_RESET 0x99
+
+#define EWIP_FLAG 0x01 /* Erase/Write in progress (WIP) flag */
+
+/* Globals ------------------------------------------------------------------*/
+//extern uint8_t Flash_Data[4];
+
+void spi_flash_read_id(uint8_t *pFlashId);
+void spi_flash_busy_check(void);
+void spi_flash_write_enable(void);
+void spi_flash_status_reg_write(uint16_t vStatus);
+void spi_flash_sector_erase(uint32_t vAddress);
+void spi_flash_block_erase(uint32_t vAddress);
+void spi_flash_chip_erase(void);
+void spi_flash_page_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength);
+void spi_flash_buffer_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength);
+void spi_flash_read(uint8_t vReadCmd, uint32_t vReadAddr, uint8_t *pBuffer, uint16_t vLength);
+//void spi_flash_fast_read(uint32_t vReadAddr, uint8_t* pBuffer, uint16_t vLength);
+//void spi_flash_page_write(uint32_t vWriteAddr, uint8_t* pBuffer, uint16_t vLength);//uint8_t *psendBuf, uint32_t len
+//void GD25Q32_ReadData(uint8_t *psendBuf, uint32_t len);
+//void spi_flash_buffer_read(uint8_t *pDataBuf,uint32_t vAddress,uint32_t vDataLength);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Interrupt/ble_peripheral/ancs.c b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/SPI/Interrupt/ble_peripheral/ancs.h b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Interrupt/ble_peripheral/app.c b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/app.c
new file mode 100644
index 0000000..e2ef9a0
--- /dev/null
+++ b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/app.c
@@ -0,0 +1,609 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_spi.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_SPI:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: spi msg.");
+ io_handle_spi_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ spi_demo();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/SPI/Interrupt/ble_peripheral/app.h b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Interrupt/ble_peripheral/app_flags.h b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/SPI/Interrupt/ble_peripheral/app_task.c b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/app_task.c
new file mode 100644
index 0000000..635c4c3
--- /dev/null
+++ b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/SPI/Interrupt/ble_peripheral/app_task.h b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Interrupt/ble_peripheral/main.c b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/main.c
new file mode 100644
index 0000000..a12dc8a
--- /dev/null
+++ b/src/sample/io_sample/SPI/Interrupt/ble_peripheral/main.c
@@ -0,0 +1,245 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+
+#include "io_spi.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_spi_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_spi_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/SPI/Interrupt/io_spi.c b/src/sample/io_sample/SPI/Interrupt/io_spi.c
new file mode 100644
index 0000000..fb96efc
--- /dev/null
+++ b/src/sample/io_sample/SPI/Interrupt/io_spi.c
@@ -0,0 +1,165 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_spi.c
+* @brief This file provides demo code of spi master.
+ GD25Q128E is slave.
+ Read the chip id of GD25Q128E.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_spi.h"
+
+#include "spi_flash.h"
+#include "app_task.h"
+
+/* Globals ------------------------------------------------------------------*/
+
+uint8_t flash_id_type = 0;
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_spi_init(void)
+{
+ Pad_Config(SPI0_SCK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI0_MOSI_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI0_MISO_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI0_CS_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+
+ Pinmux_Deinit(P4_0);
+ Pinmux_Deinit(P4_1);
+ Pinmux_Deinit(P4_2);
+ Pinmux_Deinit(P4_3);
+
+ Pinmux_Config(SPI0_SCK_PIN, SPI0_CLK_MASTER);
+ Pinmux_Config(SPI0_MOSI_PIN, SPI0_MO_MASTER);
+ Pinmux_Config(SPI0_MISO_PIN, SPI0_MI_MASTER);
+ Pinmux_Config(SPI0_CS_PIN, SPI0_SS_N_0_MASTER);
+}
+
+/**
+ * @brief Initialize spi peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_spi_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE);
+
+ SPI_InitTypeDef SPI_InitStruct;
+ SPI_StructInit(&SPI_InitStruct);
+
+ SPI_InitStruct.SPI_Direction = SPI_Direction_EEPROM;
+ SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
+ SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
+ SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
+ SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
+ SPI_InitStruct.SPI_BaudRatePrescaler = 50;
+ /* SPI_Direction_EEPROM mode read data length. */
+ SPI_InitStruct.SPI_RxThresholdLevel = 1 - 1;/* Flash id length = 3*/
+ SPI_InitStruct.SPI_NDF = 1 - 1;/* Flash id length = 3*/
+ /* cause SPI_INT_RXF interrupt if data length in receive FIFO >= SPI_RxThresholdLevel + 1*/
+ SPI_InitStruct.SPI_FrameFormat = SPI_Frame_Motorola;
+
+ SPI_Init(SPI0, &SPI_InitStruct);
+ SPI_Cmd(SPI0, ENABLE);
+
+ /* detect receive data */
+ SPI_INTConfig(SPI0, SPI_INT_RXF, ENABLE);
+ /* Config SPI interrupt */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = SPI0_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/**
+ * @brief Demo code of operation about spi.
+ * @param No parameter.
+ * @return void
+*/
+void spi_demo(void)
+{
+ uint8_t id[10];
+ APP_PRINT_INFO0("[io_spi] spi_demo: Read flash id.");
+ spi_flash_read_id(DEVICE_ID, id);
+ flash_id_type = 0;
+}
+
+/**
+ * @brief Handle i2c data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_spi_handle_msg(T_IO_MSG *io_spi_msg)
+{
+ uint8_t *p_buf = io_spi_msg->u.buf;
+ uint8_t data_Length = p_buf[0];
+ APP_PRINT_INFO2("[io_spi] io_spi_handle_msg: data_Length = %d, data = %b ", data_Length,
+ TRACE_BINARY(data_Length, &p_buf[1]));
+ uint8_t id[1];
+ flash_id_type++;
+ if (flash_id_type < 3)
+ {
+ spi_flash_read_id((Flash_ID_Type)flash_id_type, id);
+ }
+}
+
+/**
+ * @brief Handle i2c data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_spi_msg(T_IO_MSG *io_spi_msg)
+{
+ io_spi_handle_msg(io_spi_msg);
+}
+
+
+/**
+ * @brief SPI0 interrupt handle function.
+ * @param None.
+ * @return None.
+ */
+void SPI0_Handler(void)
+{
+ volatile uint8_t data_len = 0;
+ volatile uint8_t SPI_ReadINTBuf[70] = {0};
+
+ if (SPI_GetINTStatus(SPI0, SPI_INT_RXF) == SET)
+ {
+ SPI_ClearINTPendingBit(SPI0, SPI_INT_RXF);
+
+ while (SPI_GetRxFIFOLen(SPI0) < Flash_ID_Length);
+ data_len = SPI_GetRxFIFOLen(SPI0);
+ Flash_Data[0] = data_len;
+
+ for (uint8_t i = 0; i < data_len; i++)
+ {
+ /* Must read all data in receive FIFO , otherwise cause SPI_INT_RXF interrupt again. */
+ Flash_Data[1 + i] = SPI_ReceiveData(SPI0);
+ }
+
+ T_IO_MSG int_spi_msg;
+ int_spi_msg.type = IO_MSG_TYPE_SPI;
+ int_spi_msg.subtype = 0;
+ int_spi_msg.u.buf = (void *)(Flash_Data);
+ if (false == app_send_msg_to_apptask(&int_spi_msg))
+ {
+ APP_PRINT_ERROR0("[io_spi] SPI0_Handler: Send int_spi_msg failed!");
+ SPI_ClearINTPendingBit(SPI0, SPI_INT_RXF);
+ //Add user code here!
+ return;
+ }
+ }
+}
diff --git a/src/sample/io_sample/SPI/Interrupt/io_spi.h b/src/sample/io_sample/SPI/Interrupt/io_spi.h
new file mode 100644
index 0000000..de3f7ed
--- /dev/null
+++ b/src/sample/io_sample/SPI/Interrupt/io_spi.h
@@ -0,0 +1,42 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_spi.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_SPI_H
+#define __IO_SPI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_spi.h"
+
+#include "board.h"
+
+#include "app_msg.h"
+
+void board_spi_init(void);
+void driver_spi_init(void);
+void spi_demo(void);
+void io_handle_spi_msg(T_IO_MSG *io_spi_msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Interrupt/spi_flash.c b/src/sample/io_sample/SPI/Interrupt/spi_flash.c
new file mode 100644
index 0000000..747039d
--- /dev/null
+++ b/src/sample/io_sample/SPI/Interrupt/spi_flash.c
@@ -0,0 +1,67 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file spi_flash.c
+* @brief This file provides demo code of adc continuous mode.
+* @details
+* @author yuan
+* @date 2019-07-03
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "spi_flash.h"
+#include "board.h"
+
+
+/* Globals ------------------------------------------------------------------*/
+uint8_t Flash_Data[10];
+uint8_t Flash_ID_Length = 0;
+
+/**
+ * @brief SPI write and read function.
+ * @param pWriteBuf: write data buf point.
+ * @param vWriteLen: write data length.
+ * @param pReadBuf: write data buf point.
+ * @param vReadLen: write data length.
+ * @return void
+ */
+void spi_flash_write_read(uint8_t *pWriteBuf, uint16_t vWriteLen, uint8_t *pReadBuf,
+ uint16_t vReadLen)
+{
+ SPI_SetReadLen(FLASH_SPI, vReadLen);
+ SPI_SendBuffer(FLASH_SPI, pWriteBuf, vWriteLen);
+}
+
+/**
+ * @brief Read spi flash(gd25q128e) id.
+ * @param Flash_ID_Type.
+ * @return void
+ */
+void spi_flash_read_id(Flash_ID_Type vIdType, uint8_t *pId)
+{
+ uint8_t write_data = 0;
+ uint16_t write_length = 1;
+
+ switch (vIdType)
+ {
+ case DEVICE_ID:
+ write_data = SPI_FLASH_DEVICE_ID;
+ Flash_ID_Length = 4;
+ break;
+ case MF_DEVICE_ID:
+ write_data = SPI_FLASH_MANU_ID;
+ Flash_ID_Length = 5;
+ break;
+ case JEDEC_ID:
+ write_data = SPI_FLASH_JEDEC_ID;
+ Flash_ID_Length = 3;
+ break;
+ default:
+ return;
+ }
+ spi_flash_write_read(&write_data, write_length, &pId[1], Flash_ID_Length);
+ pId[0] = Flash_ID_Length;
+}
diff --git a/src/sample/io_sample/SPI/Interrupt/spi_flash.h b/src/sample/io_sample/SPI/Interrupt/spi_flash.h
new file mode 100644
index 0000000..2b6f548
--- /dev/null
+++ b/src/sample/io_sample/SPI/Interrupt/spi_flash.h
@@ -0,0 +1,70 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file spi_flash.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __SPI_FLASH_H
+#define __SPI_FLASH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_spi.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define SPI_FLASH_PAGE_SIZE 256
+#define SPI_FLASH_PerWritePageSize 256
+
+#define SPI_FLASH_WRITE_ENABLE 0x06
+#define SPI_FLASH_WRITE_DISABLE 0x04
+#define SPI_FLASH_READ_STATUS_REG_1 0x05
+#define SPI_FLASH_WRITE_STATUS_REG_1 0x01
+#define SPI_FLASH_READ_STATUS_REG_2 0x35
+#define SPI_FLASH_WRITE_STATUS_REG_2 0x31
+#define SPI_FLASH_PAGE_PROGRAM 0x02
+#define SPI_FLASH_SECTOR_ERASE 0x20
+#define SPI_FLASH_BLOCK_ERASE_32K 0x52
+#define SPI_FLASH_BLOCK_ERASE_64K 0xD8
+#define SPI_FLASH_CHIP_ERASE 0xC7
+#define SPI_FLASH_POWER_DOWN 0xB9
+#define SPI_FLASH_READ_DATA 0x03
+#define SPI_FLASH_FAST_READ 0x0B
+#define SPI_FLASH_RELEASE_POWER_DOWN 0xAB
+#define SPI_FLASH_DEVICE_ID 0xAB
+#define SPI_FLASH_MANU_ID 0x90
+#define SPI_FLASH_JEDEC_ID 0x9F
+#define SPI_FLASH_ENABLE_RESET 0x66
+#define SPI_FLASH_RESET 0x99
+
+#define EWIP_FLAG 0x01 /* Erase/Write in progress (WIP) flag */
+
+
+/* Globals ------------------------------------------------------------------*/
+typedef enum
+{
+ DEVICE_ID,
+ MF_DEVICE_ID,
+ JEDEC_ID
+} Flash_ID_Type;
+
+extern uint8_t Flash_Data[10];
+extern uint8_t Flash_ID_Length;
+
+void spi_flash_read_id(Flash_ID_Type vIdType, uint8_t *pId);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/ancs.c b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/ancs.h b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app.c b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app.c
new file mode 100644
index 0000000..8649e55
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app.c
@@ -0,0 +1,608 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_spi.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_SPI:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: spi msg.");
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ spi_demo();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app.h b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app_flags.h b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app_task.c b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app_task.c
new file mode 100644
index 0000000..635c4c3
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app_task.h b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/main.c b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/main.c
new file mode 100644
index 0000000..a12dc8a
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_eeprom/ble_peripheral/main.c
@@ -0,0 +1,245 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+
+#include "io_spi.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_spi_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_spi_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/SPI/Polling_eeprom/io_spi.c b/src/sample/io_sample/SPI/Polling_eeprom/io_spi.c
new file mode 100644
index 0000000..e01bb95
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_eeprom/io_spi.c
@@ -0,0 +1,102 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_spi.c
+* @brief This file provides demo code of spi master.
+ GD25Q128E is slave.
+ Read the chip id of GD25Q128E.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_spi.h"
+
+#include "spi_flash.h"
+#include "app_task.h"
+
+/* Globals ------------------------------------------------------------------*/
+uint8_t flash_id_type = 0;
+
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_spi_init(void)
+{
+ Pad_Config(SPI0_SCK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI0_MOSI_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI0_MISO_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI0_CS_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+
+ Pinmux_Deinit(P4_0);
+ Pinmux_Deinit(P4_1);
+ Pinmux_Deinit(P4_2);
+ Pinmux_Deinit(P4_3);
+
+ Pinmux_Config(SPI0_SCK_PIN, SPI0_CLK_MASTER);
+ Pinmux_Config(SPI0_MOSI_PIN, SPI0_MO_MASTER);
+ Pinmux_Config(SPI0_MISO_PIN, SPI0_MI_MASTER);
+ Pinmux_Config(SPI0_CS_PIN, SPI0_SS_N_0_MASTER);
+}
+
+/**
+ * @brief Initialize spi peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_spi_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE);
+
+ SPI_InitTypeDef SPI_InitStruct;
+ SPI_StructInit(&SPI_InitStruct);
+
+ SPI_InitStruct.SPI_Direction = SPI_Direction_EEPROM;
+ SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
+ SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
+ SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
+ SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
+ SPI_InitStruct.SPI_BaudRatePrescaler = 100;
+ /* SPI_Direction_EEPROM mode read data length. */
+ SPI_InitStruct.SPI_RxThresholdLevel = 1;/* Flash id length = 3*/
+ SPI_InitStruct.SPI_NDF = 0;/* Flash id length = 3*/
+ /* cause SPI_INT_RXF interrupt if data length in receive FIFO >= SPI_RxThresholdLevel + 1*/
+ SPI_InitStruct.SPI_FrameFormat = SPI_Frame_Motorola;
+
+ SPI_Init(FLASH_SPI, &SPI_InitStruct);
+ SPI_Cmd(FLASH_SPI, ENABLE);
+}
+
+/**
+ * @brief Demo code of operation about spi.
+ * @param No parameter.
+ * @return void
+*/
+void spi_demo(void)
+{
+ uint8_t flash_id[10] = {0};
+
+ while (flash_id_type < 3)
+ {
+ spi_flash_read_id((Flash_ID_Type)flash_id_type, flash_id);
+ APP_PRINT_INFO3("[io_spi] spi_demo: flash_id_type = %d, data_Length = %d, flash_id = %b ",
+ flash_id_type, flash_id[0], TRACE_BINARY(flash_id[0], &flash_id[1]));
+ flash_id_type++;
+ memset(flash_id, 0, sizeof(flash_id));
+ }
+ flash_id_type = 0;
+
+ uint8_t read_data[100] = {0};
+ spi_flash_read(SPI_FLASH_READ_DATA, 0x000101, read_data, 100);
+ APP_PRINT_INFO1("[io_spi] spi_demo: read_data = %b,", TRACE_BINARY(100, read_data));
+ spi_flash_read(SPI_FLASH_FAST_READ, 0x000210, read_data, 100);
+ APP_PRINT_INFO1("[io_spi] spi_demo: read_data = %b,", TRACE_BINARY(100, read_data));
+}
+
diff --git a/src/sample/io_sample/SPI/Polling_eeprom/io_spi.h b/src/sample/io_sample/SPI/Polling_eeprom/io_spi.h
new file mode 100644
index 0000000..2f7adae
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_eeprom/io_spi.h
@@ -0,0 +1,42 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_spi.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_SPI_H
+#define __IO_SPI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_spi.h"
+
+#include "board.h"
+
+#include "app_msg.h"
+
+
+void board_spi_init(void);
+void driver_spi_init(void);
+void spi_demo(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Polling_eeprom/spi_flash.c b/src/sample/io_sample/SPI/Polling_eeprom/spi_flash.c
new file mode 100644
index 0000000..122242f
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_eeprom/spi_flash.c
@@ -0,0 +1,84 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file spi_flash.c
+* @brief This file provides demo code of adc continuous mode.
+* @details
+* @author yuan
+* @date 2019-07-03
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "spi_flash.h"
+#include "board.h"
+
+/**
+ * @brief Read spi flash(gd25q80c) id.
+ * @param Flash_ID_Type.
+ * @return void
+ */
+void spi_flash_read_id(Flash_ID_Type vFlashIdType, uint8_t *pFlashId)
+{
+ uint8_t send_buf[4] = {SPI_FLASH_JEDEC_ID, 0, 0, 0};
+ uint8_t recv_len = 3;
+
+ switch (vFlashIdType)
+ {
+ case DEVICE_ID:
+ send_buf[0] = SPI_FLASH_DEVICE_ID;
+ recv_len = 4;
+ break;
+ case MF_DEVICE_ID:
+ send_buf[0] = SPI_FLASH_MANU_ID;
+ recv_len = 5;
+ break;
+ case JEDEC_ID:
+ send_buf[0] = SPI_FLASH_JEDEC_ID;
+ recv_len = 3;
+ break;
+ default:
+ return;
+ }
+ *pFlashId++ = recv_len;
+
+ SPI_SetReadLen(FLASH_SPI, recv_len);
+ SPI_SendBuffer(FLASH_SPI, send_buf, 1);
+ while (recv_len--)
+ {
+ while (RESET == SPI_GetFlagState(FLASH_SPI, SPI_FLAG_RFNE));
+ *pFlashId++ = SPI_ReceiveData(FLASH_SPI);
+ }
+}
+
+void spi_flash_read(uint8_t vReadCmd, uint32_t vReadAddr, uint8_t *pBuffer, uint16_t vLength)
+{
+ uint8_t send_buf[10] = {0};
+ uint8_t send_len = 0;
+ uint16_t recv_len = vLength;
+
+ if (SPI_FLASH_READ_DATA == vReadCmd)
+ {
+ send_len = 4;
+ }
+ else if (SPI_FLASH_FAST_READ == vReadCmd)
+ {
+ send_len = 5;
+ }
+ send_buf[0] = vReadCmd;
+ send_buf[1] = (vReadAddr >> 16) & 0xFF;
+ send_buf[2] = (vReadAddr >> 8) & 0xFF;
+ send_buf[3] = (vReadAddr) & 0xFF;
+
+ SPI_SetReadLen(FLASH_SPI, recv_len);
+ SPI_SendBuffer(FLASH_SPI, send_buf, send_len);
+
+ while (recv_len--)
+ {
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_RFNE) == RESET);
+ *pBuffer++ = SPI_ReceiveData(FLASH_SPI);
+ }
+ SPI_SetReadLen(FLASH_SPI, 1);
+}
diff --git a/src/sample/io_sample/SPI/Polling_eeprom/spi_flash.h b/src/sample/io_sample/SPI/Polling_eeprom/spi_flash.h
new file mode 100644
index 0000000..c8d30df
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_eeprom/spi_flash.h
@@ -0,0 +1,67 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file spi_flash.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __SPI_FLASH_H
+#define __SPI_FLASH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_spi.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define SPI_FLASH_PAGE_SIZE 256
+#define SPI_FLASH_PerWritePageSize 256
+
+#define SPI_FLASH_WRITE_ENABLE 0x06
+#define SPI_FLASH_WRITE_DISABLE 0x04
+#define SPI_FLASH_READ_STATUS_REG_1 0x05
+#define SPI_FLASH_WRITE_STATUS_REG_1 0x01
+#define SPI_FLASH_READ_STATUS_REG_2 0x35
+#define SPI_FLASH_WRITE_STATUS_REG_2 0x31
+#define SPI_FLASH_PAGE_PROGRAM 0x02
+#define SPI_FLASH_SECTOR_ERASE 0x20
+#define SPI_FLASH_BLOCK_ERASE_32K 0x52
+#define SPI_FLASH_BLOCK_ERASE_64K 0xD8
+#define SPI_FLASH_CHIP_ERASE 0xC7
+#define SPI_FLASH_POWER_DOWN 0xB9
+#define SPI_FLASH_READ_DATA 0x03
+#define SPI_FLASH_FAST_READ 0x0B
+#define SPI_FLASH_RELEASE_POWER_DOWN 0xAB
+#define SPI_FLASH_DEVICE_ID 0xAB
+#define SPI_FLASH_MANU_ID 0x90
+#define SPI_FLASH_JEDEC_ID 0x9F
+#define SPI_FLASH_ENABLE_RESET 0x66
+#define SPI_FLASH_RESET 0x99
+
+#define EWIP_FLAG 0x01 /* Erase/Write in progress (WIP) flag */
+
+/* Globals ------------------------------------------------------------------*/
+typedef enum
+{
+ DEVICE_ID,
+ MF_DEVICE_ID,
+ JEDEC_ID
+} Flash_ID_Type;
+
+void spi_flash_read_id(Flash_ID_Type vIdType, uint8_t *pId);
+void spi_flash_read(uint8_t vReadCmd, uint32_t vReadAddr, uint8_t *pBuffer, uint16_t vLength);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/ancs.c b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/ancs.h b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app.c b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app.c
new file mode 100644
index 0000000..8649e55
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app.c
@@ -0,0 +1,608 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_spi.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_SPI:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: spi msg.");
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ spi_demo();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app.h b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app_flags.h b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app_task.c b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app_task.c
new file mode 100644
index 0000000..635c4c3
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app_task.h b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/main.c b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/main.c
new file mode 100644
index 0000000..a12dc8a
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_fullduplex/ble_peripheral/main.c
@@ -0,0 +1,245 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+
+#include "io_spi.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_spi_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_spi_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/SPI/Polling_fullduplex/io_spi.c b/src/sample/io_sample/SPI/Polling_fullduplex/io_spi.c
new file mode 100644
index 0000000..45ebd6e
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_fullduplex/io_spi.c
@@ -0,0 +1,107 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_spi.c
+* @brief This file provides demo code of spi master.
+ GD25Q128E is slave.
+ Read the chip id of GD25Q128E.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_spi.h"
+
+#include "spi_flash.h"
+#include "app_task.h"
+
+/* Globals ------------------------------------------------------------------*/
+uint8_t flash_id_type = 0;
+
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_spi_init(void)
+{
+ Pad_Config(SPI0_SCK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI0_MOSI_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI0_MISO_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI0_CS_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+
+ Pinmux_Deinit(P4_0);
+ Pinmux_Deinit(P4_1);
+ Pinmux_Deinit(P4_2);
+ Pinmux_Deinit(P4_3);
+
+ Pinmux_Config(SPI0_SCK_PIN, SPI0_CLK_MASTER);
+ Pinmux_Config(SPI0_MOSI_PIN, SPI0_MO_MASTER);
+ Pinmux_Config(SPI0_MISO_PIN, SPI0_MI_MASTER);
+ Pinmux_Config(SPI0_CS_PIN, SPI0_SS_N_0_MASTER);
+}
+
+/**
+ * @brief Initialize spi peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_spi_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE);
+
+ SPI_InitTypeDef SPI_InitStruct;
+ SPI_StructInit(&SPI_InitStruct);
+
+ SPI_InitStruct.SPI_Direction = SPI_Direction_FullDuplex;
+ SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
+ SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
+ SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
+ SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
+ SPI_InitStruct.SPI_BaudRatePrescaler = 100;
+ /* SPI_Direction_EEPROM mode read data length. */
+ SPI_InitStruct.SPI_RxThresholdLevel = 3 - 1;/* Flash id length = 3*/
+ SPI_InitStruct.SPI_NDF = 3 - 1;/* Flash id length = 3*/
+ /* cause SPI_INT_RXF interrupt if data length in receive FIFO >= SPI_RxThresholdLevel + 1*/
+ SPI_InitStruct.SPI_FrameFormat = SPI_Frame_Motorola;
+
+ SPI_Init(FLASH_SPI, &SPI_InitStruct);
+ SPI_Cmd(FLASH_SPI, ENABLE);
+ DBG_DIRECT("read the spi RX_SAMPLE_DLY = 0X%x", *(volatile uint32_t *)0x400130f0UL);
+}
+
+/**
+ * @brief Demo code of operation about spi.
+ * @param No parameter.
+ * @return void
+*/
+void spi_demo(void)
+{
+ uint8_t id[10] = {0};
+ APP_PRINT_INFO0("[io_spi] spi_demo: Read flash id.");
+
+ while (flash_id_type < 3)
+ {
+ spi_flash_read_id((Flash_ID_Type)flash_id_type, id);
+
+ APP_PRINT_INFO3("[io_spi] spi_demo: flash_id_type = %d, data_Length = %d, data = %b ", flash_id_type,
+ id[0], TRACE_BINARY(id[0], &id[1]));
+ flash_id_type++;
+ memset(id, 0, sizeof(id));
+ }
+ flash_id_type = 0;
+
+ uint8_t read_data[105] = {0};
+ spi_flash_read(SPI_FLASH_READ_DATA, 0x000101, read_data, 100);
+ APP_PRINT_INFO1("[io_spi] spi_demo: read_data = %b,", TRACE_BINARY(100, &read_data[4]));
+ spi_flash_read(SPI_FLASH_FAST_READ, 0x000210, read_data, 100);
+ APP_PRINT_INFO1("[io_spi] spi_demo: read_data = %b,", TRACE_BINARY(100, &read_data[5]));
+}
+
+
+
diff --git a/src/sample/io_sample/SPI/Polling_fullduplex/io_spi.h b/src/sample/io_sample/SPI/Polling_fullduplex/io_spi.h
new file mode 100644
index 0000000..2f7adae
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_fullduplex/io_spi.h
@@ -0,0 +1,42 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_spi.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_SPI_H
+#define __IO_SPI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_spi.h"
+
+#include "board.h"
+
+#include "app_msg.h"
+
+
+void board_spi_init(void);
+void driver_spi_init(void);
+void spi_demo(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Polling_fullduplex/spi_flash.c b/src/sample/io_sample/SPI/Polling_fullduplex/spi_flash.c
new file mode 100644
index 0000000..854a5f4
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_fullduplex/spi_flash.c
@@ -0,0 +1,87 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file spi_flash.c
+* @brief This file provides demo code of adc continuous mode.
+* @details
+* @author yuan
+* @date 2019-07-03
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "spi_flash.h"
+#include "board.h"
+
+/**
+ * @brief Read spi flash(gd25q128e) id.
+ * @param Flash_ID_Type.
+ * @return void
+ */
+void spi_flash_read_id(Flash_ID_Type vFlashIdType, uint8_t *pFlashId)
+{
+ uint8_t send_buf[4] = {SPI_FLASH_JEDEC_ID, 0, 0, 0};
+ uint8_t recv_len = 3;
+
+ switch (vFlashIdType)
+ {
+ case DEVICE_ID:
+ send_buf[0] = SPI_FLASH_DEVICE_ID;
+ recv_len = 4 + 1;
+ break;
+ case MF_DEVICE_ID:
+ send_buf[0] = SPI_FLASH_MANU_ID;
+ recv_len = 5 + 1;
+ break;
+ case JEDEC_ID:
+ send_buf[0] = SPI_FLASH_JEDEC_ID;
+ recv_len = 3 + 1;
+ break;
+ default:
+ return;
+ }
+ *pFlashId++ = recv_len;
+
+ SPI_SendBuffer(FLASH_SPI, send_buf, recv_len);
+ while (recv_len--)
+ {
+ while (RESET == SPI_GetFlagState(FLASH_SPI, SPI_FLAG_RFNE));
+ *pFlashId++ = SPI_ReceiveData(FLASH_SPI);
+ }
+}
+
+void spi_flash_read(uint8_t vReadCmd, uint32_t vReadAddr, uint8_t *pBuffer, uint16_t vLength)
+{
+ uint8_t send_buf[10] = {0};
+ uint8_t send_len = 0;
+ uint16_t recv_len = 0;
+
+ if (SPI_FLASH_READ_DATA == vReadCmd)
+ {
+ send_len = 4;
+ }
+ else if (SPI_FLASH_FAST_READ == vReadCmd)
+ {
+ send_len = 5;
+ }
+ send_buf[0] = vReadCmd;
+ send_buf[1] = (vReadAddr >> 16) & 0xFF;
+ send_buf[2] = (vReadAddr >> 8) & 0xFF;
+ send_buf[3] = (vReadAddr) & 0xFF;
+
+ SPI_SendBuffer(FLASH_SPI, send_buf, send_len);
+ recv_len = vLength + send_len;
+ while (recv_len--)
+ {
+ SPI_SendBuffer(FLASH_SPI, &send_buf[9], 1);
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_RFNE) == RESET);
+ *pBuffer++ = SPI_ReceiveData(FLASH_SPI);
+ }
+ SPI_SetReadLen(FLASH_SPI, 1);
+}
+
+
+
+
diff --git a/src/sample/io_sample/SPI/Polling_fullduplex/spi_flash.h b/src/sample/io_sample/SPI/Polling_fullduplex/spi_flash.h
new file mode 100644
index 0000000..c8d30df
--- /dev/null
+++ b/src/sample/io_sample/SPI/Polling_fullduplex/spi_flash.h
@@ -0,0 +1,67 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file spi_flash.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __SPI_FLASH_H
+#define __SPI_FLASH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_spi.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define SPI_FLASH_PAGE_SIZE 256
+#define SPI_FLASH_PerWritePageSize 256
+
+#define SPI_FLASH_WRITE_ENABLE 0x06
+#define SPI_FLASH_WRITE_DISABLE 0x04
+#define SPI_FLASH_READ_STATUS_REG_1 0x05
+#define SPI_FLASH_WRITE_STATUS_REG_1 0x01
+#define SPI_FLASH_READ_STATUS_REG_2 0x35
+#define SPI_FLASH_WRITE_STATUS_REG_2 0x31
+#define SPI_FLASH_PAGE_PROGRAM 0x02
+#define SPI_FLASH_SECTOR_ERASE 0x20
+#define SPI_FLASH_BLOCK_ERASE_32K 0x52
+#define SPI_FLASH_BLOCK_ERASE_64K 0xD8
+#define SPI_FLASH_CHIP_ERASE 0xC7
+#define SPI_FLASH_POWER_DOWN 0xB9
+#define SPI_FLASH_READ_DATA 0x03
+#define SPI_FLASH_FAST_READ 0x0B
+#define SPI_FLASH_RELEASE_POWER_DOWN 0xAB
+#define SPI_FLASH_DEVICE_ID 0xAB
+#define SPI_FLASH_MANU_ID 0x90
+#define SPI_FLASH_JEDEC_ID 0x9F
+#define SPI_FLASH_ENABLE_RESET 0x66
+#define SPI_FLASH_RESET 0x99
+
+#define EWIP_FLAG 0x01 /* Erase/Write in progress (WIP) flag */
+
+/* Globals ------------------------------------------------------------------*/
+typedef enum
+{
+ DEVICE_ID,
+ MF_DEVICE_ID,
+ JEDEC_ID
+} Flash_ID_Type;
+
+void spi_flash_read_id(Flash_ID_Type vIdType, uint8_t *pId);
+void spi_flash_read(uint8_t vReadCmd, uint32_t vReadAddr, uint8_t *pBuffer, uint16_t vLength);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Psram/ble_peripheral/ancs.c b/src/sample/io_sample/SPI/Psram/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/SPI/Psram/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/SPI/Psram/ble_peripheral/ancs.h b/src/sample/io_sample/SPI/Psram/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/SPI/Psram/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Psram/ble_peripheral/app.c b/src/sample/io_sample/SPI/Psram/ble_peripheral/app.c
new file mode 100644
index 0000000..ad6d7ea
--- /dev/null
+++ b/src/sample/io_sample/SPI/Psram/ble_peripheral/app.c
@@ -0,0 +1,609 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_spi.h"
+#include "io_uart.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_GDMA:
+ {
+ io_handle_gdma_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ spi_demo();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/SPI/Psram/ble_peripheral/app.h b/src/sample/io_sample/SPI/Psram/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/SPI/Psram/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Psram/ble_peripheral/app_flags.h b/src/sample/io_sample/SPI/Psram/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/SPI/Psram/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/SPI/Psram/ble_peripheral/app_task.c b/src/sample/io_sample/SPI/Psram/ble_peripheral/app_task.c
new file mode 100644
index 0000000..635c4c3
--- /dev/null
+++ b/src/sample/io_sample/SPI/Psram/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/SPI/Psram/ble_peripheral/app_task.h b/src/sample/io_sample/SPI/Psram/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/SPI/Psram/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Psram/ble_peripheral/main.c b/src/sample/io_sample/SPI/Psram/ble_peripheral/main.c
new file mode 100644
index 0000000..771b602
--- /dev/null
+++ b/src/sample/io_sample/SPI/Psram/ble_peripheral/main.c
@@ -0,0 +1,245 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+
+#include "io_spi.h"
+#include "io_uart.h"
+#include "platform_utils.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_spi_init();
+ board_uart_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_uart_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/SPI/Psram/io_spi.c b/src/sample/io_sample/SPI/Psram/io_spi.c
new file mode 100644
index 0000000..1b336e1
--- /dev/null
+++ b/src/sample/io_sample/SPI/Psram/io_spi.c
@@ -0,0 +1,251 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file io_gdma.c
+* @brief This file provides demo code of meomory to memory transfer by gdma.
+* @details
+* @author yuan
+* @date 2019-01-11
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_spi.h"
+#include "io_uart.h"
+
+
+/* Globals ------------------------------------------------------------------*/
+uint8_t GDMA_WriteCmdBuffer[5] = {SPI_PSRAM_WRITE, 0x01, 0x02, 0x00};
+uint8_t GDMA_ReadCmdBuffer[5] = {SPI_PSRAM_FAST_READ, 0x01, 0x02, 0x00, DUMMY_DATA};
+
+uint8_t GDMA_Send_Buffer[GDMA_TRANSFER_SIZE + 5];
+uint8_t GDMA_Recv_Buffer[GDMA_TRANSFER_SIZE];
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_spi_init(void)
+{
+ Pad_Config(SPI_SCK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI_MOSI_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI_MISO_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI_CS_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+
+ Pinmux_Config(SPI_SCK_PIN, SPI0_CLK_MASTER);
+ Pinmux_Config(SPI_MOSI_PIN, SPI0_MO_MASTER);
+ Pinmux_Config(SPI_MISO_PIN, SPI0_MI_MASTER);
+ Pinmux_Config(SPI_CS_PIN, SPI0_SS_N_0_MASTER);
+}
+
+/**
+ * @brief Initialize gdma peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_spi_gdma_tx_init(void)
+{
+ /*----------------test buffer init------------------*/
+ memcpy(GDMA_Send_Buffer, GDMA_WriteCmdBuffer, 4);
+ for (uint32_t i = 4; i < GDMA_TRANSFER_SIZE + 4; i++)
+ {
+ GDMA_Send_Buffer[i] = (i + 0x0C) & 0xFF;
+ }
+
+ SPI_InitTypeDef SPI_InitStructure;
+ GDMA_InitTypeDef GDMA_InitStruct;
+
+ SPI_DeInit(SPI0);
+ RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE);
+
+ /*----------------------SPI init---------------------------------*/
+ SPI_StructInit(&SPI_InitStructure);
+ SPI_InitStructure.SPI_Direction = SPI_Direction_TxOnly;
+ SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
+ SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
+ SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
+ SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
+ SPI_InitStructure.SPI_BaudRatePrescaler = 100;
+ SPI_InitStructure.SPI_FrameFormat = SPI_Frame_Motorola;
+ SPI_InitStructure.SPI_NDF = 0;
+ SPI_InitStructure.SPI_TxDmaEn = ENABLE;
+ SPI_InitStructure.SPI_TxWaterlevel = 15;
+ SPI_Init(SPI0, &SPI_InitStructure);
+
+ /*---------------------GDMA initial------------------------------*/
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = GDMA_SPI_TX_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral;
+ GDMA_InitStruct.GDMA_BufferSize = GDMA_TRANSFER_SIZE + 4;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_4;
+
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_Send_Buffer;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)SPI0->DR;
+ GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_SPI0_TX;
+ GDMA_InitStruct.GDMA_ChannelPriority = 1;
+
+ GDMA_Init(GDMA_Channel_Tx, &GDMA_InitStruct);
+
+ /*-----------------GDMA IRQ-----------------------------*/
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = GDMA_Channel_Tx_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ /* Enable transfer interrupt */
+ GDMA_INTConfig(GDMA_SPI_TX_NUM, GDMA_INT_Transfer, ENABLE);
+ SPI_Cmd(SPI0, ENABLE);
+ GDMA_Cmd(GDMA_SPI_TX_NUM, ENABLE);
+}
+
+void driver_spi_gdma_rx_init(void)
+{
+ /*----------------test buffer init------------------*/
+ memset(GDMA_Recv_Buffer, 0, sizeof(GDMA_Recv_Buffer));
+
+ SPI_InitTypeDef SPI_InitStructure;
+ GDMA_InitTypeDef GDMA_InitStruct;
+
+ SPI_DeInit(SPI0);
+
+ RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE);
+
+ /*----------------------SPI init---------------------------------*/
+ SPI_StructInit(&SPI_InitStructure);
+ SPI_InitStructure.SPI_Direction = SPI_Direction_EEPROM;
+ SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
+ SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
+ SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
+ SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
+ SPI_InitStructure.SPI_BaudRatePrescaler = 100;
+ SPI_InitStructure.SPI_FrameFormat = SPI_Frame_Motorola;
+ SPI_InitStructure.SPI_NDF = GDMA_TRANSFER_SIZE - 1;
+ SPI_InitStructure.SPI_RxDmaEn = ENABLE;
+ SPI_InitStructure.SPI_RxWaterlevel = 3;
+ SPI_Init(SPI0, &SPI_InitStructure);
+ SPI_SetRxSampleDly(SPI0, 1);
+
+ /*---------------------GDMA initial------------------------------*/
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = GDMA_SPI_RX_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToMemory;
+ GDMA_InitStruct.GDMA_BufferSize = GDMA_TRANSFER_SIZE;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Inc;
+
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_4;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_4;
+
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)SPI0->DR;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)GDMA_Recv_Buffer;
+ GDMA_InitStruct.GDMA_SourceHandshake = GDMA_Handshake_SPI0_RX;
+ GDMA_InitStruct.GDMA_ChannelPriority = 1;
+
+ GDMA_Init(GDMA_Channel_Rx, &GDMA_InitStruct);
+
+ /*-----------------GDMA IRQ-----------------------------*/
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = GDMA_Channel_Rx_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ /* Enable transfer interrupt */
+ GDMA_INTConfig(GDMA_SPI_RX_NUM, GDMA_INT_Transfer, ENABLE);
+ SPI_Cmd(SPI0, ENABLE);
+ GDMA_Cmd(GDMA_SPI_RX_NUM, ENABLE);
+
+ /* Send read data command */
+ SPI_SendBuffer(SPI0, GDMA_ReadCmdBuffer, 5);
+}
+
+/**
+ * @brief Handle gdma data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_gdma_msg(T_IO_MSG *io_gdma_msg)
+{
+ uint8_t sub_type = io_gdma_msg->subtype;
+ uint8_t *p_buf = io_gdma_msg->u.buf;
+ if (sub_type == 0)
+ {
+ APP_PRINT_INFO0("[io_gdma] io_handle_gdma_msg: send data complete");
+ driver_spi_gdma_rx_init();
+ }
+ else if (sub_type == 1)
+ {
+ APP_PRINT_INFO1("[io_gdma] io_handle_gdma_msg: read data complete data_len = %d",
+ GDMA_TRANSFER_SIZE);
+ uart_senddata_continuous(UART0, p_buf, GDMA_TRANSFER_SIZE);
+ }
+}
+
+/**
+ * @brief Demo code of operation about spi.
+ * @param No parameter.
+ * @return void
+*/
+void spi_demo(void)
+{
+ APP_PRINT_INFO0("[io_spi] spi_psram_demo ");
+ driver_spi_gdma_tx_init();
+}
+
+/**
+ * @brief GDMA channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void GDMA_SPI_TX_Handler(void)
+{
+ GDMA_INTConfig(GDMA_SPI_TX_NUM, GDMA_INT_Transfer, DISABLE);
+
+ T_IO_MSG int_gdma_msg;
+ int_gdma_msg.type = IO_MSG_TYPE_GDMA;
+ int_gdma_msg.subtype = 0;
+ int_gdma_msg.u.buf = (void *)GDMA_Send_Buffer;
+ if (false == app_send_msg_to_apptask(&int_gdma_msg))
+ {
+ APP_PRINT_ERROR0("[io_gdma]GDMA_Channel_Handler: Send int_gdma_msg failed!");
+ //Add user code here!
+ GDMA_ClearINTPendingBit(GDMA_SPI_TX_NUM, GDMA_INT_Block);
+ return;
+ }
+
+ GDMA_ClearINTPendingBit(GDMA_SPI_TX_NUM, GDMA_INT_Transfer);
+ GDMA_Cmd(GDMA_SPI_TX_NUM, DISABLE);
+}
+
+void GDMA_SPI_RX_Handler(void)
+{
+ GDMA_INTConfig(GDMA_SPI_RX_NUM, GDMA_INT_Transfer, DISABLE);
+
+ T_IO_MSG int_gdma_msg;
+ int_gdma_msg.type = IO_MSG_TYPE_GDMA;
+ int_gdma_msg.subtype = 1;
+ int_gdma_msg.u.buf = (void *)GDMA_Recv_Buffer;
+ if (false == app_send_msg_to_apptask(&int_gdma_msg))
+ {
+ APP_PRINT_ERROR0("[io_gdma]GDMA_Channel_Handler: Send int_gdma_msg failed!");
+ //Add user code here!
+ GDMA_ClearINTPendingBit(GDMA_SPI_RX_NUM, GDMA_INT_Transfer);
+ return;
+ }
+
+ GDMA_ClearINTPendingBit(GDMA_SPI_RX_NUM, GDMA_INT_Transfer);
+}
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/SPI/Psram/io_spi.h b/src/sample/io_sample/SPI/Psram/io_spi.h
new file mode 100644
index 0000000..c5b88c0
--- /dev/null
+++ b/src/sample/io_sample/SPI/Psram/io_spi.h
@@ -0,0 +1,53 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_gdma.h
+* @brief
+* @details
+* @author yuan
+* @date 2019-01-11
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_GDMA_H
+#define __IO_GDMA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include "rtl876x_gdma.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_spi.h"
+#include "trace.h"
+
+#include "app_task.h"
+#include "board.h"
+
+
+/* Defines ------------------------------------------------------------------*/
+#define SPI_PSRAM_WRITE 0x02
+#define SPI_PSRAM_READ_DATA 0x03
+#define SPI_PSRAM_FAST_READ 0x0B
+#define SPI_PSRAM_READ_ID 0x9F
+
+#define DUMMY_DATA 0x55
+
+#define GDMA_TRANSFER_SIZE 1000
+
+void board_spi_init(void);
+void io_handle_gdma_msg(T_IO_MSG *io_gdma_msg);
+void spi_demo(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/Psram/io_uart.c b/src/sample/io_sample/SPI/Psram/io_uart.c
new file mode 100644
index 0000000..7dbdb36
--- /dev/null
+++ b/src/sample/io_sample/SPI/Psram/io_uart.c
@@ -0,0 +1,84 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file io_uart.c
+* @brief uart interrupt demo
+* @details
+* @author yuan
+* @date 2018-06-28
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_uart.h"
+
+#include <string.h>
+
+#include "app_task.h"
+
+#include "trace.h"
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_uart_init(void)
+{
+ Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+ Pad_Config(UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+
+ Pinmux_Config(UART_TX_PIN, UART0_TX);
+ Pinmux_Config(UART_RX_PIN, UART0_RX);
+}
+
+/**
+ * @brief Initialize uart peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_uart_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ /* uart init */
+ UART_InitTypeDef UART_InitStruct;
+ UART_StructInit(&UART_InitStruct);
+
+ UART_InitStruct.UART_Parity = UART_PARITY_NO_PARTY;
+ UART_InitStruct.UART_StopBits = UART_STOP_BITS_1;
+ UART_InitStruct.UART_WordLen = UART_WORD_LENGTH_8BIT;
+ UART_InitStruct.UART_RxThdLevel = 16; //1~29
+ UART_InitStruct.UART_IdleTime = UART_RX_IDLE_2BYTE; //idle interrupt wait time
+ UART_Init(UART0, &UART_InitStruct);
+}
+
+/**
+ * @brief UARt send data continuous.
+ * @param No parameter.
+ * @return void
+ */
+void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount)
+{
+ uint8_t count;
+
+ while (vCount / UART_TX_FIFO_SIZE > 0)
+ {
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ for (count = UART_TX_FIFO_SIZE; count > 0; count--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+ vCount -= UART_TX_FIFO_SIZE;
+ }
+
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ while (vCount--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/SPI/Psram/io_uart.h b/src/sample/io_sample/SPI/Psram/io_uart.h
new file mode 100644
index 0000000..47b0c4d
--- /dev/null
+++ b/src/sample/io_sample/SPI/Psram/io_uart.h
@@ -0,0 +1,37 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_uart.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_UART_H
+#define __IO_UART_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_uart.h"
+#include "board.h"
+
+void board_uart_init(void);
+void driver_uart_init(void);
+void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/ancs.c b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/ancs.h b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app.c b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app.c
new file mode 100644
index 0000000..8649e55
--- /dev/null
+++ b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app.c
@@ -0,0 +1,608 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_spi.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_SPI:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: spi msg.");
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ spi_demo();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app.h b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app_flags.h b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app_task.c b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app_task.c
new file mode 100644
index 0000000..635c4c3
--- /dev/null
+++ b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app_task.c
@@ -0,0 +1,123 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app_task.h b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/main.c b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/main.c
new file mode 100644
index 0000000..a12dc8a
--- /dev/null
+++ b/src/sample/io_sample/SPI/SPI_Software_CS/ble_peripheral/main.c
@@ -0,0 +1,245 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+
+#include "io_spi.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_spi_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_spi_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/SPI/SPI_Software_CS/io_spi.c b/src/sample/io_sample/SPI/SPI_Software_CS/io_spi.c
new file mode 100644
index 0000000..ea7bd6f
--- /dev/null
+++ b/src/sample/io_sample/SPI/SPI_Software_CS/io_spi.c
@@ -0,0 +1,113 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_spi.c
+* @brief This file provides demo code of spi master.
+ GD25Q128E is slave.
+ Read the chip id of GD25Q128E.
+* @details
+* @author echo
+* @date 2021-6-21
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_spi.h"
+
+#include "spi_flash.h"
+#include "app_task.h"
+
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_spi_init(void)
+{
+ Pad_Config(SPI0_SCK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI0_MOSI_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI0_MISO_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(SPI0_CS_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+
+ Pinmux_Deinit(P4_0);
+ Pinmux_Deinit(P4_1);
+ Pinmux_Deinit(P4_2);
+ Pinmux_Deinit(P4_3);
+
+ Pinmux_Config(SPI0_SCK_PIN, SPI0_CLK_MASTER);
+ Pinmux_Config(SPI0_MOSI_PIN, SPI0_MO_MASTER);
+ Pinmux_Config(SPI0_MISO_PIN, SPI0_MI_MASTER);
+ /* Set CS Pin to Software Control Mode*/
+ Pinmux_Config(SPI0_CS_PIN, DWGPIO);
+}
+
+/**
+ * @brief Initialize spi peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_spi_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE);
+
+ SPI_InitTypeDef SPI_InitStruct;
+ SPI_StructInit(&SPI_InitStruct);
+
+ SPI_InitStruct.SPI_Direction = SPI_Direction_FullDuplex;
+ SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
+ SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
+ SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
+ SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
+ SPI_InitStruct.SPI_BaudRatePrescaler = 2;
+ /* SPI_Direction_EEPROM mode read data length. */
+ SPI_InitStruct.SPI_RxThresholdLevel = 1;/* Flash id length = 3*/
+ SPI_InitStruct.SPI_FrameFormat = SPI_Frame_Motorola;
+ SPI_Init(SPI0, &SPI_InitStruct);
+
+ SPI_Cmd(SPI0, ENABLE);
+
+ /* Initialize CS Pin */
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+ GPIO_InitTypeDef GPIO_InitStruct;
+ GPIO_StructInit(&GPIO_InitStruct);
+ GPIO_InitStruct.GPIO_Pin = GPIO_GetPin(SPI0_CS_PIN);
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_InitStruct.GPIO_ITCmd = DISABLE;
+ GPIO_Init(&GPIO_InitStruct);
+}
+
+
+/**
+ * @brief Demo code of operation about spi.
+ * @param No parameter.
+ * @return void
+*/
+void spi_demo(void)
+{
+ uint8_t flash_id[10] = {0};
+ uint8_t write_data[100];
+ uint8_t read_data[105] = {0};
+ for (uint16_t i = 0; i < 100; i++)
+ {
+ write_data[i] = i & 0xFF;
+ }
+
+ spi_flash_read_id(flash_id);
+ APP_PRINT_INFO1("[io_spi] spi_demo: flash_id = %b ", TRACE_BINARY(3, flash_id));
+
+ spi_flash_sector_erase(0x001000);
+ APP_PRINT_INFO0("[io_spi] spi_demo: spi_flash_sector_erase done");
+
+ spi_flash_read(SPI_FLASH_FAST_READ, 0x001000, read_data, 100);
+ APP_PRINT_INFO1("[io_spi] spi_demo: read_data = %b,", TRACE_BINARY(100, read_data));
+
+ spi_flash_page_write(0x001000, write_data, 100);
+
+ spi_flash_read(SPI_FLASH_FAST_READ, 0x001000, read_data, 100);
+ APP_PRINT_INFO1("[io_spi] spi_demo: read_data = %b,", TRACE_BINARY(100, read_data));
+}
+
+
diff --git a/src/sample/io_sample/SPI/SPI_Software_CS/io_spi.h b/src/sample/io_sample/SPI/SPI_Software_CS/io_spi.h
new file mode 100644
index 0000000..669d128
--- /dev/null
+++ b/src/sample/io_sample/SPI/SPI_Software_CS/io_spi.h
@@ -0,0 +1,41 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_spi.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_SPI_H
+#define __IO_SPI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_spi.h"
+
+#include "board.h"
+
+#include "app_msg.h"
+
+void board_spi_init(void);
+void driver_spi_init(void);
+void spi_demo(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/SPI_Software_CS/spi_flash.c b/src/sample/io_sample/SPI/SPI_Software_CS/spi_flash.c
new file mode 100644
index 0000000..9e60452
--- /dev/null
+++ b/src/sample/io_sample/SPI/SPI_Software_CS/spi_flash.c
@@ -0,0 +1,338 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code of spi write and ead data from GD25Q128E flash.
+* @details
+* @author echo
+* @date 2021-06-21
+* @version v1.0
+*********************************************************************************************************
+*/
+#include "spi_flash.h"
+#include "io_spi.h"
+#include "trace.h"
+#include <string.h>
+
+
+void spi_flash_read_id(uint8_t *pFlashId)
+{
+ uint8_t send_buf[4] = {SPI_FLASH_JEDEC_ID, 0, 0, 0};
+ uint8_t recv_buf[10] = {0};
+ uint8_t recv_len = 3;
+ /* Software Control CS Pin to Low Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(0));
+
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+ recv_len += 1;
+
+ uint8_t idx = 0;
+ while (recv_len--)
+ {
+ while (RESET == SPI_GetFlagState(FLASH_SPI, SPI_FLAG_RFNE));
+ recv_buf[idx++] = SPI_ReceiveData(FLASH_SPI);
+ }
+ /* Software Control CS Pin to High Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(1));
+
+ memcpy(pFlashId, &recv_buf[1], 3);
+
+}
+
+void spi_flash_busy_check(void)
+{
+ uint8_t send_buf[2] = {SPI_FLASH_READ_STATUS_REG_1, 0};
+ uint8_t recv_len = 0;
+ uint8_t recv_data[2] = {0};
+
+ while (1)
+ {
+ /* Software Control CS Pin to Low Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(0));
+
+ SPI_SendBuffer(FLASH_SPI, send_buf, 2);
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ uint8_t i = 0;
+ while (recv_len--)
+ {
+ recv_data[i++] = SPI_ReceiveData(FLASH_SPI);
+ }
+ /* Software Control CS Pin to High Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(1));
+
+ i = 0;
+ if ((recv_data[1] & 0x01) == 0)
+ {
+ break;
+ }
+ }
+}
+
+void spi_flash_write_enable(void)
+{
+ uint8_t len = 0;
+ /* Software Control CS Pin to Low Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(0));
+
+ SPI_SendData(FLASH_SPI, SPI_FLASH_WRITE_ENABLE);
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ /* Software Control CS Pin to High Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(1));
+}
+
+void spi_flash_status_reg_write(uint8_t vStatus)
+{
+ uint8_t len = 0;
+ uint8_t send_buf[2] = {SPI_FLASH_WRITE_STATUS_REG_1, 0};
+
+ send_buf[1] = vStatus & 0xff;
+
+ /* Enable write */
+ spi_flash_write_enable();
+ /* Software Control CS Pin to Low Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(0));
+
+ /* Write status register */
+ SPI_SendBuffer(FLASH_SPI, send_buf, 2);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ /* Software Control CS Pin to High Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(1));
+
+ spi_flash_busy_check();
+}
+
+void spi_flash_sector_erase(uint32_t vAddress)
+{
+ uint8_t send_buf[4] = {SPI_FLASH_SECTOR_ERASE, 0, 0, 0};
+ uint8_t recv_len = 0;
+
+ send_buf[1] = (vAddress >> 16) & 0xff;
+ send_buf[2] = (vAddress >> 8) & 0xff;
+ send_buf[3] = vAddress & 0xff;
+
+ /* enable write */
+ spi_flash_write_enable();
+ /* Software Control CS Pin to Low Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(0));
+ /* erase data */
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ /* Software Control CS Pin to High Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(1));
+
+ spi_flash_busy_check();
+}
+
+void spi_flash_block_erase(uint32_t vAddress)
+{
+ uint8_t send_buf[4] = {SPI_FLASH_BLOCK_ERASE_32K, 0, 0, 0};
+ uint8_t recv_len = 0;
+
+ send_buf[1] = (vAddress >> 16) & 0xff;
+ send_buf[2] = (vAddress >> 8) & 0xff;
+ send_buf[3] = vAddress & 0xff;
+
+ /* Enable write */
+ spi_flash_write_enable();
+ /* Software Control CS Pin to Low Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(0));
+
+ /* erase data */
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ /* Software Control CS Pin to High Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(1));
+
+ spi_flash_busy_check();
+}
+
+void spi_flash_chip_erase(void)
+{
+ uint8_t recv_len = 0;
+
+ /* Enable write */
+ spi_flash_write_enable();
+ /* Software Control CS Pin to Low Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(0));
+
+ SPI_SendData(FLASH_SPI, SPI_FLASH_CHIP_ERASE);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ /* Software Control CS Pin to High Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(1));
+
+ spi_flash_busy_check();
+}
+
+void spi_flash_page_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength)
+{
+ uint16_t send_data_len = vLength;
+ uint8_t recv_data_len = 0;
+ uint8_t send_buf[4] = {SPI_FLASH_PAGE_PROGRAM, 0, 0, 0};
+ send_buf[1] = (vWriteAddr >> 16) & 0xff;
+ send_buf[2] = (vWriteAddr >> 8) & 0xff;
+ send_buf[3] = vWriteAddr & 0xff;
+
+ if (vLength > SPI_FLASH_PAGE_SIZE)
+ {
+ send_data_len = SPI_FLASH_PAGE_SIZE;
+ }
+
+ /* Enable write */
+ spi_flash_write_enable();
+ /* Software Control CS Pin to Low Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(0));
+
+ SPI_SendBuffer(FLASH_SPI, send_buf, 4);
+ SPI_SendBuffer(FLASH_SPI, pBuffer, send_data_len);
+
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_BUSY) == SET);
+ recv_data_len = SPI_GetRxFIFOLen(FLASH_SPI);
+ while (recv_data_len--)
+ {
+ SPI_ReceiveData(FLASH_SPI);
+ }
+ /* Software Control CS Pin to High Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(1));
+
+ spi_flash_busy_check();
+}
+
+void spi_flash_buffer_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength)
+{
+ uint32_t write_addr = vWriteAddr;
+ uint8_t *p_write_data = pBuffer;
+ uint16_t write_data_len = vLength;
+
+ uint8_t offset = vWriteAddr % SPI_FLASH_PAGE_SIZE;
+ uint8_t free_len = SPI_FLASH_PAGE_SIZE - offset;
+ uint8_t page_num = vLength / SPI_FLASH_PAGE_SIZE;
+ uint8_t remain_len = vLength % SPI_FLASH_PAGE_SIZE;
+
+ if (offset == 0)
+ {
+ if (page_num == 0) // write_data_len < SPI_FLASH_PAGE_SIZE
+ {
+ spi_flash_page_write(write_addr, p_write_data, remain_len);
+ }
+ else // write_data_len > SPI_FLASH_PAGE_SIZE
+ {
+ while (page_num--)
+ {
+ spi_flash_page_write(write_addr, p_write_data, SPI_FLASH_PAGE_SIZE);
+ write_addr += SPI_FLASH_PAGE_SIZE;
+ p_write_data += SPI_FLASH_PAGE_SIZE;
+ }
+ spi_flash_page_write(write_addr, p_write_data, remain_len);
+ }
+ }
+ else // write_addr is not SPI_FLASH_PAGE_SIZE aligned
+ {
+ if (page_num == 0)
+ {
+ if (remain_len > free_len) /* (write_data_len + write_addr) > SPI_FLASH_PAGE_SIZE */
+ {
+ uint8_t temp = remain_len - free_len;
+ spi_flash_page_write(write_addr, p_write_data, free_len);
+ write_addr += free_len;
+ p_write_data += free_len;
+ spi_flash_page_write(vWriteAddr, p_write_data, temp);
+ }
+ else
+ {
+ spi_flash_page_write(write_addr, p_write_data, write_data_len);
+ }
+
+ }
+ else /* NumByteToWrite > SPI_FLASH_PAGE_SIZE */
+ {
+ write_data_len -= free_len;
+ page_num = write_data_len / SPI_FLASH_PAGE_SIZE;
+ remain_len = write_data_len % SPI_FLASH_PAGE_SIZE;
+
+ spi_flash_page_write(write_addr, p_write_data, free_len);
+ write_addr += free_len;
+ p_write_data += free_len;
+
+ while (page_num--)
+ {
+ spi_flash_page_write(write_addr, p_write_data, SPI_FLASH_PAGE_SIZE);
+ write_addr += SPI_FLASH_PAGE_SIZE;
+ p_write_data += SPI_FLASH_PAGE_SIZE;
+ }
+
+ if (remain_len != 0)
+ {
+ spi_flash_page_write(write_addr, p_write_data, remain_len);
+ }
+ }
+ }
+}
+
+void spi_flash_read(uint8_t vReadCmd, uint32_t vReadAddr, uint8_t *pBuffer, uint16_t vLength)
+{
+ uint8_t send_buf[10] = {0};
+ uint8_t send_len = 0;
+ uint16_t recv_len = 0;
+
+ if (SPI_FLASH_READ_DATA == vReadCmd)
+ {
+ send_len = 4;
+ }
+ else if (SPI_FLASH_FAST_READ == vReadCmd)
+ {
+ send_len = 5;
+ }
+ send_buf[0] = vReadCmd;
+ send_buf[1] = (vReadAddr >> 16) & 0xFF;
+ send_buf[2] = (vReadAddr >> 8) & 0xFF;
+ send_buf[3] = (vReadAddr) & 0xFF;
+ /* Software Control CS Pin to Low Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(0));
+
+ SPI_SendBuffer(FLASH_SPI, send_buf, send_len);
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_RFNE) == RESET);
+ for (uint8_t i = 0; i < send_len; i++)
+ {
+ SPI_ReceiveData(FLASH_SPI);//dummy read data
+ }
+ recv_len = vLength;
+ while (recv_len--)
+ {
+ SPI_SendBuffer(FLASH_SPI, &send_buf[9], 1);
+ while (SPI_GetFlagState(FLASH_SPI, SPI_FLAG_RFNE) == RESET);
+ *pBuffer++ = SPI_ReceiveData(FLASH_SPI);
+ }
+ /* Software Control CS Pin to High Level */
+ GPIO_WriteBit(GPIO_GetPin(SPI0_CS_PIN), (BitAction)(1));
+}
diff --git a/src/sample/io_sample/SPI/SPI_Software_CS/spi_flash.h b/src/sample/io_sample/SPI/SPI_Software_CS/spi_flash.h
new file mode 100644
index 0000000..2210502
--- /dev/null
+++ b/src/sample/io_sample/SPI/SPI_Software_CS/spi_flash.h
@@ -0,0 +1,69 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file spi_flash.h
+* @brief
+* @details
+* @author echo
+* @date 2021-06-21
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __SPI_FLASH_H
+#define __SPI_FLASH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_spi.h"
+#include "rtl876x_gpio.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define SPI_FLASH_PAGE_SIZE 256
+
+#define SPI_FLASH_WRITE_ENABLE 0x06
+#define SPI_FLASH_WRITE_DISABLE 0x04
+#define SPI_FLASH_READ_STATUS_REG_1 0x05
+#define SPI_FLASH_WRITE_STATUS_REG_1 0x01
+#define SPI_FLASH_READ_STATUS_REG_2 0x35
+#define SPI_FLASH_WRITE_STATUS_REG_2 0x31
+#define SPI_FLASH_PAGE_PROGRAM 0x02
+#define SPI_FLASH_SECTOR_ERASE 0x20
+#define SPI_FLASH_BLOCK_ERASE_32K 0x52
+#define SPI_FLASH_BLOCK_ERASE_64K 0xD8
+#define SPI_FLASH_CHIP_ERASE 0xC7
+#define SPI_FLASH_POWER_DOWN 0xB9
+#define SPI_FLASH_READ_DATA 0x03
+#define SPI_FLASH_FAST_READ 0x0B
+#define SPI_FLASH_RELEASE_POWER_DOWN 0xAB
+#define SPI_FLASH_DEVICE_ID 0xAB
+#define SPI_FLASH_MANU_ID 0x90
+#define SPI_FLASH_JEDEC_ID 0x9F
+#define SPI_FLASH_ENABLE_RESET 0x66
+#define SPI_FLASH_RESET 0x99
+
+#define EWIP_FLAG 0x01 /* Erase/Write in progress (WIP) flag */
+
+
+void spi_flash_read_id(uint8_t *pFlashId);
+void spi_flash_busy_check(void);
+void spi_flash_write_enable(void);
+void spi_flash_status_reg_write(uint8_t vStatus);
+void spi_flash_sector_erase(uint32_t vAddress);
+void spi_flash_block_erase(uint32_t vAddress);
+void spi_flash_chip_erase(void);
+void spi_flash_page_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength);
+void spi_flash_buffer_write(uint32_t vWriteAddr, uint8_t *pBuffer, uint16_t vLength);
+void spi_flash_read(uint8_t vReadCmd, uint32_t vReadAddr, uint8_t *pBuffer, uint16_t vLength);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/SPI/SelfTest/main.c b/src/sample/io_sample/SPI/SelfTest/main.c
new file mode 100644
index 0000000..bcbf977
--- /dev/null
+++ b/src/sample/io_sample/SPI/SelfTest/main.c
@@ -0,0 +1,213 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief uart demo polling tx and rx.
+* @details
+* @author echo
+* @date 2021-05-25
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include <string.h>
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_spi.h"
+#include "board.h"
+#include "trace.h"
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_spi_master_init(void)
+{
+ Pad_Config(SPI_MASTER_SCK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(SPI_MASTER_MOSI_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(SPI_MASTER_MISO_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(SPI_MASTER_CS_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(SPI_MASTER_SCK_PIN, SPI1_CLK_MASTER);
+ Pinmux_Config(SPI_MASTER_MOSI_PIN, SPI1_MO_MASTER);
+ Pinmux_Config(SPI_MASTER_MISO_PIN, SPI1_MI_MASTER);
+ Pinmux_Config(SPI_MASTER_CS_PIN, SPI1_SS_N_0_MASTER);
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_spi_slave_init(void)
+{
+ Pad_Config(SPI_SLAVE_SCK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(SPI_SLAVE_MOSI_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(SPI_SLAVE_MISO_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(SPI_SLAVE_CS_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(SPI_SLAVE_SCK_PIN, SPI0_CLK_SLAVE);
+ Pinmux_Config(SPI_SLAVE_MOSI_PIN, SPI0_SI_SLAVE);
+ Pinmux_Config(SPI_SLAVE_MISO_PIN, SPI0_SO_SLAVE);
+ Pinmux_Config(SPI_SLAVE_CS_PIN, SPI0_SS_N_0_SLAVE);
+}
+
+/**
+ * @brief Initialize SPI Master peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_spi_master_init(void)
+{
+ SPI_DeInit(SPI_MASTER);
+
+ RCC_PeriphClockCmd(APBPeriph_SPI1, APBPeriph_SPI1_CLOCK, ENABLE);
+
+ SPI_InitTypeDef SPI_InitStructure;
+ SPI_StructInit(&SPI_InitStructure);
+
+ SPI_InitStructure.SPI_Direction = SPI_Direction_FullDuplex;
+ SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
+ SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
+ SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
+ SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
+ SPI_InitStructure.SPI_BaudRatePrescaler = 4;
+ SPI_InitStructure.SPI_TxThresholdLevel = 10; /* Transmit FIFO Threshold */
+ SPI_InitStructure.SPI_RxThresholdLevel =
+ 0; /* cause SPI_INT_RXF interrupt if data length in receive FIFO >= SPI_RxThresholdLevel + 1*/
+ SPI_InitStructure.SPI_FrameFormat = SPI_Frame_Motorola;
+
+ SPI_Init(SPI_MASTER, &SPI_InitStructure);
+ SPI_Cmd(SPI_MASTER, ENABLE);
+}
+
+/**
+ * @brief Initialize SPI Slave peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_spi_slave_init(void)
+{
+ SPI_DeInit(SPI_SLAVE);
+
+ RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE);
+
+ SPI_InitTypeDef SPI_InitStructure;
+ SPI_StructInit(&SPI_InitStructure);
+
+ SPI_InitStructure.SPI_Direction = SPI_Direction_FullDuplex;
+ SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
+ SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
+ SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
+ SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
+ SPI_InitStructure.SPI_BaudRatePrescaler = 4;
+ SPI_InitStructure.SPI_TxThresholdLevel = 2; /* Transmit FIFO Threshold */
+ SPI_InitStructure.SPI_RxThresholdLevel =
+ 2; /* cause SPI_INT_RXF interrupt if data length in receive FIFO >= SPI_RxThresholdLevel + 1*/
+ SPI_InitStructure.SPI_FrameFormat = SPI_Frame_Motorola;
+
+ SPI_Init(SPI_SLAVE, &SPI_InitStructure);
+ SPI_Cmd(SPI_SLAVE, ENABLE);
+
+ /* detect receive data */
+ SPI_INTConfig(SPI_SLAVE, SPI_INT_RXF, ENABLE);
+ /* Config SPI interrupt */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = SPI0_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 1;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+void spi_transfer_demo(void)
+{
+ uint8_t spiWriteBuf[16] = {0x00, 0x01, 0x02, 0x03, 0x04 };
+
+ SPI_SendBuffer(SPI_MASTER, spiWriteBuf, 5);
+}
+
+/**
+ * @brief Demo code of uart.
+ * @param No parameter.
+ * @return void
+*/
+void spi_demo(void)
+{
+ board_spi_master_init();
+ board_spi_slave_init();
+ driver_spi_master_init();
+ driver_spi_slave_init();
+
+ /* SPI Transmission demo */
+ spi_transfer_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ }
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+ spi_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ }
+}
+
+void SPI0_Handler(void)
+{
+ DBG_DIRECT("In SPI Handler");
+ uint8_t len = 0;
+ uint8_t idx = 0;
+ uint8_t SPI_ReadINTBuf[16] = {0, 0, 0, 0};
+
+ if (SPI_GetINTStatus(SPI_SLAVE, SPI_INT_RXF) == SET)
+ {
+ len = SPI_GetRxFIFOLen(SPI_SLAVE);
+ for (idx = 0; idx < len; idx++)
+ {
+ /* must read all data in receive FIFO , otherwise cause SPI_INT_RXF interrupt again */
+ SPI_ReadINTBuf[idx] = SPI_ReceiveData(SPI_SLAVE);
+ DBG_DIRECT("SPI_ReadINTBuf[idx]=%d\n", SPI_ReadINTBuf[idx]);
+ }
+ }
+
+}
+
+
+
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/SPI3WIRE/Polling/main.c b/src/sample/io_sample/SPI3WIRE/Polling/main.c
new file mode 100644
index 0000000..d4df33d
--- /dev/null
+++ b/src/sample/io_sample/SPI3WIRE/Polling/main.c
@@ -0,0 +1,238 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code of three wire SPI communication.
+* @details
+* @author yuan
+* @date 2019-01-15
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include "rtl876x_3wire_spi.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+
+#include "trace.h"
+
+/* Defines -------------------------------------------------------------------*/
+#define SPI_3WIRE_CLK_PIN P2_2
+#define SPI_3WIRE_DATA_PIN P2_3
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return Void
+ */
+void board_3wire_spi_init(void)
+{
+ Pad_Config(SPI_3WIRE_CLK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(SPI_3WIRE_DATA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(SPI_3WIRE_CLK_PIN, SPI2W_CLK);
+ Pinmux_Config(SPI_3WIRE_DATA_PIN, SPI2W_DATA);
+}
+
+/**
+ * @brief Initialize 3wire-spi peripheral.
+ * @param No parameter.
+ * @return Void
+ */
+void driver_3wire_spi_init(void)
+{
+ /* Enable SPI3WIRE clock */
+ RCC_PeriphClockCmd(APBPeriph_SPI2W, APBPeriph_SPI2W_CLOCK, ENABLE);
+
+ /* Initialize SPI3WIRE */
+ SPI3WIRE_InitTypeDef SPI3WIRE_InitStruct;
+ SPI3WIRE_StructInit(&SPI3WIRE_InitStruct);
+
+ SPI3WIRE_InitStruct.SPI3WIRE_SysClock = 20000000;
+ SPI3WIRE_InitStruct.SPI3WIRE_Speed = 800000;
+ SPI3WIRE_InitStruct.SPI3WIRE_Mode = SPI3WIRE_2WIRE_MODE;
+ /** The delay time from the end of address phase to the start of read data phase.
+ * delay time = (SPI3WIRE_ReadDelay +1)/(2*SPI3WIRE_Speed).
+ * delay time = (0x03 + 1)/(2 * speed) = 2.5us
+ */
+ SPI3WIRE_InitStruct.SPI3WIRE_ReadDelay = 0x3;
+ SPI3WIRE_InitStruct.SPI3WIRE_OutputDelay = SPI3WIRE_OE_DELAY_NONE;
+ SPI3WIRE_InitStruct.SPI3WIRE_ExtMode = SPI3WIRE_NORMAL_MODE;
+ SPI3WIRE_Init(&SPI3WIRE_InitStruct);
+}
+
+/**
+ * @brief Read one byte through 3wire spi perpherial.
+ * @param address: address of register which need to read.
+ * @return Value of register.
+ */
+uint8_t spi3wire_readbyte(uint8_t address)
+{
+ uint8_t reg_value = 0;
+ uint32_t timeout = 0;
+
+ /* Check spi busy or not */
+ while (SPI3WIRE_GetFlagStatus(SPI3WIRE_FLAG_BUSY) == SET)
+ {
+ timeout++;
+ if (timeout > 0x1ffff)
+ {
+ break;
+ }
+ }
+
+ /* Clear Receive data length */
+ SPI3WIRE_ClearRxDataLen();
+
+ SPI3WIRE_StartRead(address, 1);
+
+ timeout = 0;
+ while (SPI3WIRE_GetFlagStatus(SPI3WIRE_FLAG_BUSY) == SET)
+ {
+ timeout++;
+ if (timeout > 0x1ffff)
+ {
+ break;
+ }
+ }
+
+ /* Get the length of received data */
+ while (SPI3WIRE_GetRxDataLen() == 0);
+ /* Read data */
+ SPI3WIRE_ReadBuf(&reg_value, 1);
+
+ return reg_value;
+}
+
+/**
+ * @brief Write one byte.
+ * @param address: address of register which need to write data.
+ * @param data: data which need to write.
+ * @return TRUE: write success, FALSE: write failure.
+ */
+bool spi3wire_writebyte(uint8_t address, uint8_t data)
+{
+ uint32_t timeout = 0;
+
+ /* Check 3wire spi busy or not */
+ while (SPI3WIRE_GetFlagStatus(SPI3WIRE_FLAG_BUSY) == SET)
+ {
+ timeout++;
+ if (timeout > 0x1ffff)
+ {
+ return false;
+ }
+ }
+ /* Write data */
+ SPI3WIRE_StartWrite(address, data);
+
+ timeout = 0;
+ while (SPI3WIRE_GetFlagStatus(SPI3WIRE_FLAG_BUSY) == SET)
+ {
+ timeout++;
+ if (timeout > 0x1ffff)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+/**
+ * @brief Reset mouse.
+ * @param None.
+ * @return void.
+ */
+void mouse_reset(void)
+{
+ uint32_t delay = 0;
+
+ spi3wire_writebyte(0x06, (1 << 7));
+
+ /* Delay 0.28ms */
+ for (delay = 0; delay < 0x1fff; delay++) {;}
+}
+
+/**
+ * @brief Read mouse product ID.
+ * @param p_id, --pointer to production id buffer,buffer length should more than two.
+ * @return TRUE.
+ */
+bool mouse_getproductid(uint8_t *p_id)
+{
+
+ /* Read product ID number high byte */
+ *p_id++ = spi3wire_readbyte(0x20);
+
+ /* Read product ID number low byte */
+ *p_id = spi3wire_readbyte(0x21);
+
+ return true;
+}
+
+/**
+ * @brief Demo code of 3wire-spi communication.
+ * @param No parameter.
+ * @return void
+ */
+void spi3wire_demo(void)
+{
+ uint8_t id[2] = {0, 0};
+
+ board_3wire_spi_init();
+ driver_3wire_spi_init();
+
+ /** Send resync time. Resync signal time = 2*1/(2*SPI3WIRE_Speed) = 1.25us
+ * This parameter can be only be the following value: 0x0 to 0xf.
+ */
+ SPI3WIRE_SetResyncTime(2);
+ SPI3WIRE_ResyncSignalCmd(ENABLE);
+ while (SPI3WIRE_GetFlagStatus(SPI3WIRE_FLAG_RESYNC_BUSY) == SET);
+ SPI3WIRE_ResyncSignalCmd(DISABLE);
+
+ /* Enable SPI3WIRE to normal communication */
+ SPI3WIRE_Cmd(ENABLE);
+
+ mouse_reset();
+ mouse_getproductid(&id[0]);
+ if ((0x58 == id[0]) && (0x20 == (id[1] & 0xF0)))
+ {
+ /* Notes: DBG_DIRECT is only used in debug demo, do not use in app project.*/
+ DBG_DIRECT("SPI3WIRE test pass!");
+ }
+ else
+ {
+ /* Notes: DBG_DIRECT is only used in debug demo, do not use in app project.*/
+ DBG_DIRECT("SPI3WIRE test failed!");
+ }
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ spi3wire_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/TIM/GDMA+PWM+GPIO/main.c b/src/sample/io_sample/TIM/GDMA+PWM+GPIO/main.c
new file mode 100644
index 0000000..d19dc83
--- /dev/null
+++ b/src/sample/io_sample/TIM/GDMA+PWM+GPIO/main.c
@@ -0,0 +1,268 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief This file provides demo code of gdma send data to gpio.
+ This project uses GDMA+TIM+GPIO to implement the PWM function,
+ and can dynamically change the duty cycle function of the PWM output.
+* @details
+* @author yuan
+* @date 2019-02-22
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include "rtl876x_gdma.h"
+#include "rtl876x_gpio.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_tim.h"
+#include "trace.h"
+
+/* Defines ------------------------------------------------------------------*/
+/** Set GPIO_OUT_REPEAT to 1 if repeat play is required.
+ * If GPIO_OUT_REPEAT set to 1 output array GPIO_Ctl_AutoReload data, otherwise output array GPIO_Ctl_LLI.
+ */
+#define GPIO_OUT_REPEAT 1
+
+#define GPIO_OUTPUT_PIN_0 P2_5
+#define GPIO_PIN_OUTPUT GPIO_GetPin(GPIO_OUTPUT_PIN_0)
+
+#define PWM_OUT_PIN P2_3
+#define PWM_TIMER_NUM TIM5
+#define PWM_OUT_PIN_PINMUX TIM_PWM5
+
+#define PWM_HIGH_COUNT (10*20-1)//5us
+#define PWM_LOW_COUNT (10*20-1)//5us
+
+#define GDMA_CHANNEL_NUM 1
+#define GDMA_Channel GDMA_Channel1
+#define GDMA_Channel_IRQn GDMA0_Channel1_IRQn
+#define GDMA_Channel_Handler GDMA0_Channel1_Handler
+
+#define GDMA_TRANSFER_SIZE 24
+#define GDMA_LLI_SIZE 4
+
+/* Globales ------------------------------------------------------------------*/
+uint32_t GPIO_Ctl_AutoReload[GDMA_TRANSFER_SIZE] = {0xffffffff, 0x0,
+ 0xffffffff, 0xffffffff, 0x0,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0x0,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0x0,
+ 0xffffffff, 0xffffffff, 0x0,
+ 0xffffffff, 0x0
+ };
+
+uint32_t GPIO_Ctl_LLI[GDMA_LLI_SIZE][GDMA_TRANSFER_SIZE] =
+{
+ 0xffffffff, 0x0, 0xffffffff, 0x0, 0xffffffff, 0x0, 0xffffffff, 0x0, 0xffffffff, 0x0, 0xffffffff, 0x0,
+ 0xffffffff, 0x0, 0xffffffff, 0x0, 0xffffffff, 0x0, 0xffffffff, 0x0, 0xffffffff, 0x0, 0xffffffff, 0x0,
+ 0xffffffff, 0xffffffff, 0x0, 0xffffffff, 0xffffffff, 0x0, 0xffffffff, 0xffffffff, 0x0, 0xffffffff, 0xffffffff, 0x0,
+ 0xffffffff, 0xffffffff, 0x0, 0xffffffff, 0xffffffff, 0x0, 0xffffffff, 0xffffffff, 0x0, 0xffffffff, 0xffffffff, 0x0,
+ 0xffffffff, 0x0, 0x0, 0xffffffff, 0x0, 0x0, 0xffffffff, 0x0, 0x0, 0xffffffff, 0x0, 0x0,
+ 0xffffffff, 0x0, 0x0, 0xffffffff, 0x0, 0x0, 0xffffffff, 0x0, 0x0, 0xffffffff, 0x0, 0x0,
+ 0xffffffff, 0xffffffff, 0x0, 0x0, 0xffffffff, 0xffffffff, 0x0, 0x0, 0xffffffff, 0xffffffff, 0x0, 0x0,
+ 0xffffffff, 0xffffffff, 0x0, 0x0, 0xffffffff, 0xffffffff, 0x0, 0x0, 0xffffffff, 0xffffffff, 0x0, 0x0,
+};
+
+GDMA_LLIDef GDMA_LLIStruct[GDMA_LLI_SIZE];
+
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_gpio_init(void)
+{
+ Pad_Config(GPIO_OUTPUT_PIN_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(GPIO_OUTPUT_PIN_0, DWGPIO);
+}
+
+void board_pwm_init(void)
+{
+ Pad_Config(PWM_OUT_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+
+ Pinmux_Config(PWM_OUT_PIN, PWM_OUT_PIN_PINMUX);
+}
+
+/**
+ * @brief Initialize gpio peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_gpio_init(void)
+{
+ /* Initialize gpio peripheral */
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+ GPIO_StructInit(&GPIO_InitStruct);
+
+ GPIO_InitStruct.GPIO_Pin = GPIO_PIN_OUTPUT;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_InitStruct.GPIO_ITCmd = DISABLE;
+ GPIO_InitStruct.GPIO_ControlMode = GPIO_HARDWARE_MODE;
+ GPIO_Init(&GPIO_InitStruct);
+
+}
+/**
+ * @brief Initialize tim peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_pwm_init(void)
+{
+ /* Initialize tim peripheral */
+ RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+
+ TIM_TimeBaseInitTypeDef TIM_InitStruct;
+ TIM_StructInit(&TIM_InitStruct);
+
+ TIM_InitStruct.TIM_PWM_En = PWM_ENABLE;
+ TIM_InitStruct.TIM_PWM_High_Count = PWM_HIGH_COUNT;
+ TIM_InitStruct.TIM_PWM_Low_Count = PWM_LOW_COUNT;
+ TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ TIM_TimeBaseInit(PWM_TIMER_NUM, &TIM_InitStruct);
+
+}
+
+/**
+ * @brief Initialize gdma peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_gdma_multiblock_init(void)
+{
+ /* Set gdma with GDMA_Handshake_TIM5, msize=1, transfer width = 32 */
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+
+ GDMA_InitStruct.GDMA_ChannelNum = GDMA_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral;
+ GDMA_InitStruct.GDMA_BufferSize = GDMA_TRANSFER_SIZE;//determine total transfer size
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Word;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GPIO_Ctl_AutoReload;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(0x40011200);//vendor gpio reg address
+ GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_TIM5;
+ GDMA_InitStruct.GDMA_Multi_Block_En = 1;
+ GDMA_InitStruct.GDMA_Multi_Block_Struct = (uint32_t)GDMA_LLIStruct;
+#if (GPIO_OUT_REPEAT == 1)
+ GDMA_InitStruct.GDMA_Multi_Block_Mode = LLI_WITH_AUTO_RELOAD_SAR;
+#else
+ GDMA_InitStruct.GDMA_Multi_Block_Mode = LLI_TRANSFER;
+#endif
+ for (int i = 0; i < GDMA_LLI_SIZE; i++)
+ {
+ GDMA_LLIStruct[i].SAR = (uint32_t)(&(GPIO_Ctl_LLI[i]));
+ GDMA_LLIStruct[i].DAR = (uint32_t)(0x40011200);
+ if (i == (GDMA_LLI_SIZE - 1))
+ {
+ GDMA_LLIStruct[i].LLP = 0; //link back to beginning
+ /* Configure low 32 bit of CTL register */
+ GDMA_LLIStruct[i].CTL_LOW = BIT(0)
+ | (GDMA_InitStruct.GDMA_DestinationDataSize << 1)
+ | (GDMA_InitStruct.GDMA_SourceDataSize << 4)
+ | (GDMA_InitStruct.GDMA_DestinationInc << 7)
+ | (GDMA_InitStruct.GDMA_SourceInc << 9)
+ | (GDMA_InitStruct.GDMA_DestinationMsize << 11)
+ | (GDMA_InitStruct.GDMA_SourceMsize << 14)
+ | (GDMA_InitStruct.GDMA_DIR << 20);
+ /* Configure high 32 bit of CTL register */
+ GDMA_LLIStruct[i].CTL_HIGH = GDMA_InitStruct.GDMA_BufferSize;
+ }
+ else
+ {
+ GDMA_LLIStruct[i].LLP = (uint32_t)&GDMA_LLIStruct[i + 1];
+ /* Configure low 32 bit of CTL register */
+ GDMA_LLIStruct[i].CTL_LOW = BIT(0)
+ | (GDMA_InitStruct.GDMA_DestinationDataSize << 1)
+ | (GDMA_InitStruct.GDMA_SourceDataSize << 4)
+ | (GDMA_InitStruct.GDMA_DestinationInc << 7)
+ | (GDMA_InitStruct.GDMA_SourceInc << 9)
+ | (GDMA_InitStruct.GDMA_DestinationMsize << 11)
+ | (GDMA_InitStruct.GDMA_SourceMsize << 14)
+ | (GDMA_InitStruct.GDMA_DIR << 20)
+ | (GDMA_InitStruct.GDMA_Multi_Block_Mode & LLP_SELECTED_BIT);//BIT(28) | BIT(27)
+ /* Configure high 32 bit of CTL register */
+ GDMA_LLIStruct[i].CTL_HIGH = GDMA_InitStruct.GDMA_BufferSize;
+ }
+ }
+
+ GDMA_Init(GDMA_Channel, &GDMA_InitStruct);
+
+ /* GDMA irq config */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = GDMA_Channel_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&NVIC_InitStruct);
+
+ GDMA_INTConfig(GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+
+ GDMA_Cmd(GDMA_CHANNEL_NUM, ENABLE);
+
+ /* Set timer toggle */
+ TIM_Cmd(PWM_TIMER_NUM, ENABLE);
+}
+
+/**
+ * @brief Demo code of operation about pwm + gpio + gdma.
+ * @param No parameter.
+ * @return void
+*/
+void gdma_pwm_gpio_demo(void)
+{
+ board_gpio_init();
+ board_pwm_init();
+ driver_gpio_init();
+ driver_pwm_init();
+ driver_gdma_multiblock_init();
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ gdma_pwm_gpio_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+
+ }
+}
+
+/**
+ * @brief GDMA0 channel interrupt handler function.
+ * @param No parameter.
+ * @return void
+*/
+void GDMA_Channel_Handler(void)
+{
+ GDMA_ClearINTPendingBit(GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+}
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/TIM/PWM/main.c b/src/sample/io_sample/TIM/PWM/main.c
new file mode 100644
index 0000000..777f366
--- /dev/null
+++ b/src/sample/io_sample/TIM/PWM/main.c
@@ -0,0 +1,174 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief PWM demo and complementary output demo of PWM.
+* @details
+* @author yuan
+* @date 2019-02-18
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include <string.h>
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_tim.h"
+#include "trace.h"
+#include "platform_utils.h"
+
+/* Defines --------------------------------------------------------------*/
+/** Define pwm output pin.
+ * P0_1 is connected to LED0 on the EVB.
+ */
+#define PWM_OUT_PIN P0_1
+/** Define pwm complementary output pin.
+ * P0_2 is connected to LED1 on the EVB.
+ */
+#define PWM_OUT_P_PIN P0_2
+#define PWM_OUT_N_PIN P2_2
+
+
+/** Define TIM num and pinmux of PWM output.
+ * Timer2 to Timer5 all have PWM output function.
+ * But only Timer2 support PWM complementary output function, other timers do not support it.
+ */
+#define PWM_TIMER_NUM TIM2
+#define PWM_OUT_PIN_PINMUX TIM_PWM2//timer_pwm2
+#define PWM_OUT_P_PIN_PINMUX PWM2_P
+#define PWM_OUT_N_PIN_PINMUX PWM2_N
+
+/* Config PWM_PERIOD and PWM_DUTY_CYCLE */
+#define PWM_PERIOD 100000 //uint:us
+#define PWM_DUTY_CYCLE 50 //uint:percent
+
+/* PWM_HIGH_COUNT = */
+#define PWM_HIGH_COUNT (((PWM_PERIOD)*((PWM_DUTY_CYCLE*40)/100))-1) //PWM CLOCK = 40000000
+#define PWM_LOW_COUNT (((PWM_PERIOD)*(((100-PWM_DUTY_CYCLE)*40)/100))-1)
+
+#define PWM_DEAD_ZONE_CLOCK_SOURCE_5M 0
+#define PWM_DEAD_ZONE_BYPASS 0
+#define PWM_COMPL_OUTPUT_EM_STOP_TEST 0
+
+/** Config PWM_DEAD_ZONE_TIME. Max 8ms/32k, 51us/5M.
+ * When dead time is set, PWM2_P and PWM2_N will
+ * delay one dead time longer than PWM2 at high output level.
+ * When the dead_zone time is longer than the high-level time of PWM,
+ * PWM_P will always output low-level.
+ * When the dead_zone time is longer than the low-level time of PWM,
+ * PWM_N will always output low-level.
+ */
+#if PWM_DEAD_ZONE_CLOCK_SOURCE_5M
+#define PWM_DEAD_ZONE_TIME 4 //uint:us
+#define PWM_DEAD_ZONE_SIZE ((PWM_DEAD_ZONE_TIME)*5-1)
+#else
+#define PWM_DEAD_ZONE_TIME 5 //uint:ms
+#define PWM_DEAD_ZONE_SIZE ((PWM_DEAD_ZONE_TIME)*32-1)
+#endif
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_pwm_init(void)
+{
+ Pad_Config(PWM_OUT_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH);
+ Pad_Config(PWM_OUT_P_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(PWM_OUT_N_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+
+ /* Normal mode */
+ Pinmux_Config(PWM_OUT_PIN, PWM_OUT_PIN_PINMUX);
+ /* Deadzone mode */
+ Pinmux_Config(PWM_OUT_P_PIN, PWM_OUT_P_PIN_PINMUX);
+ Pinmux_Config(PWM_OUT_N_PIN, PWM_OUT_N_PIN_PINMUX);
+
+}
+
+/**
+ * @brief Initialize tim peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_pwm_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+#if PWM_DEAD_ZONE_CLOCK_SOURCE_5M
+ RCC_ClockSrc5MCmd();
+#endif
+
+ TIM_TimeBaseInitTypeDef TIM_InitStruct;
+
+ TIM_StructInit(&TIM_InitStruct);
+ TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ TIM_InitStruct.TIM_PWM_En = PWM_ENABLE;
+ TIM_InitStruct.TIM_PWM_High_Count = PWM_HIGH_COUNT;
+ TIM_InitStruct.TIM_PWM_Low_Count = PWM_LOW_COUNT;
+ TIM_InitStruct.PWM_Stop_State_P = PWM_STOP_AT_HIGH;
+ TIM_InitStruct.PWM_Stop_State_N = PWM_STOP_AT_LOW;
+ TIM_InitStruct.PWMDeadZone_En = DEADZONE_ENABLE; //enable to use pwn p/n output
+ TIM_InitStruct.PWM_Deazone_Size = PWM_DEAD_ZONE_SIZE;
+ TIM_TimeBaseInit(TIM2, &TIM_InitStruct);
+
+#if PWM_DEAD_ZONE_CLOCK_SOURCE_5M
+ TIM_PWMChangeDZClockSrc(TIMER_PWM2_CR, ENABLE);
+#endif
+
+ TIM_Cmd(TIM2, ENABLE);
+
+#if PWM_DEAD_ZONE_BYPASS
+ TIM_PWMDZBypassCmd(TIMER_PWM2_CR, ENABLE);
+#endif
+}
+
+/**
+ * @brief Demo code of operation about PWM.
+ * @param No parameter.
+ * @return void
+ */
+void pwm_demo(void)
+{
+ /* Configure PAD and pinmux firstly! */
+ board_pwm_init();
+
+ /* Initialize TIM peripheral */
+ driver_pwm_init();
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ pwm_demo();
+
+ while (1)
+ {
+#if PWM_COMPL_OUTPUT_EM_STOP_TEST
+ platform_delay_ms(2000);
+ //PWM complementary output emergency stop.
+ TIM_PWMComplOutputEMCmd(PWM2, ENABLE);
+ platform_delay_ms(2000);
+ //Resume PWM complementary output.
+ TIM_PWMComplOutputEMCmd(PWM2, DISABLE);
+#else
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+#endif
+ }
+}
+
+/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/TIM/Timer_interrupt/main.c b/src/sample/io_sample/TIM/Timer_interrupt/main.c
new file mode 100644
index 0000000..308813c
--- /dev/null
+++ b/src/sample/io_sample/TIM/Timer_interrupt/main.c
@@ -0,0 +1,176 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief tim interrupt demo
+ Timer timing to control the LED flashing .
+* @details
+* @author yuan
+* @date 2018-06-28
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include <string.h>
+#include "rtl876x_gpio.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_tim.h"
+
+#include "trace.h"
+
+/* Defines -------------------------------------------------------------------*/
+/* P0_1 is connected to LED0 on EVB board */
+#define GPIO_OUTPUT_PIN_0 P0_1
+#define GPIO_PIN_OUTPUT GPIO_GetPin(GPIO_OUTPUT_PIN_0)
+
+/* Timer define Tim2~Tim5 */
+#define TIMER_NUM TIM4
+#define TIMER_IRQN TIMER4_IRQ
+
+/* Timer timing config */
+#define TIMING_TIME 1000000 //uint: us
+#define TIMER_PERIOD ((TIMING_TIME)*40-1)
+
+/* Globals ------------------------------------------------------------------*/
+uint8_t LED_Status = 0;
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_gpio_init(void)
+{
+ Pad_Config(GPIO_OUTPUT_PIN_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_LOW);
+
+ Pinmux_Config(GPIO_OUTPUT_PIN_0, DWGPIO);
+}
+
+/**
+ * @brief Initialize GPIO peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_gpio_init(void)
+{
+ /* Initialize GPIO peripheral */
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+ GPIO_StructInit(&GPIO_InitStruct);
+ GPIO_InitStruct.GPIO_Pin = GPIO_PIN_OUTPUT;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_InitStruct.GPIO_ITCmd = DISABLE;
+ GPIO_Init(&GPIO_InitStruct);
+ GPIO_ResetBits(GPIO_PIN_OUTPUT);
+}
+
+/**
+ * @brief Initialize tim peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_timer_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+
+ TIM_TimeBaseInitTypeDef TIM_InitStruct;
+ TIM_StructInit(&TIM_InitStruct);
+
+ TIM_InitStruct.TIM_PWM_En = PWM_DISABLE;
+ TIM_InitStruct.TIM_Period = TIMER_PERIOD ;
+ TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
+ TIM_TimeBaseInit(TIMER_NUM, &TIM_InitStruct);
+
+ /* Enable TIMER IRQ */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = TIMER_IRQN;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ TIM_ClearINT(TIMER_NUM);
+ TIM_INTConfig(TIMER_NUM, ENABLE);
+ TIM_Cmd(TIMER_NUM, ENABLE);
+
+}
+
+/**
+ * @brief Demo code of timer.
+ * @param No parameter.
+ * @return void
+ */
+void timer_demo(void)
+{
+ LED_Status = 0;
+ board_gpio_init();
+ driver_gpio_init();
+ driver_timer_init();
+}
+
+/**
+ * @brief Demo code of timer.
+ * @param No parameter.
+ * @return void
+ */
+void tim_demo(void)
+{
+ timer_demo();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+
+ tim_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+
+ }
+}
+
+/**
+ * @brief TIM6 interrupt handler function.
+ * @param No parameter.
+ * @return void
+*/
+void Timer4_Handler(void)
+{
+
+ TIM_ClearINT(TIM4);
+ TIM_Cmd(TIM4, DISABLE);
+ if (!LED_Status)
+ {
+ GPIO_SetBits(GPIO_PIN_OUTPUT);
+ LED_Status = 1;
+ }
+ else
+ {
+ GPIO_ResetBits(GPIO_PIN_OUTPUT);
+ LED_Status = 0;
+ }
+ //Add user code here
+ TIM_Cmd(TIM4, ENABLE);
+
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/TIM_ENHANCE/Latch_GPIO/main.c b/src/sample/io_sample/TIM_ENHANCE/Latch_GPIO/main.c
new file mode 100644
index 0000000..334e81c
--- /dev/null
+++ b/src/sample/io_sample/TIM_ENHANCE/Latch_GPIO/main.c
@@ -0,0 +1,222 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2021, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file
+* @brief
+* @author
+* @date 2021-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2021 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include "rtl876x_enh_tim.h"
+#include "rtl876x_gpio.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+
+#include "board.h"
+#include "trace.h"
+
+/* Defines -------------------------------------------------------------------*/
+#define ENHTIMER_NUM ENH_TIM0
+#define ENHTIMER_IRQn ENHANCED_TIMER0_IRQn
+
+#define GPIO_INPUT_PIN_0 P2_2
+#define GPIO_PIN_INPUT_0 GPIO_GetPin(GPIO_INPUT_PIN_0)
+
+#define GPIO_OUTPUT_PIN_0 P2_4
+#define GPIO_PIN_OUTPUT_0 GPIO_GetPin(GPIO_OUTPUT_PIN_0)
+
+/* Globals -------------------------------------------------------------------*/
+uint8_t Latch_Count_Thd = 4;
+
+/**
+ * @brief Initialize TIM-Enhance peripheral.
+ * @param No parameter.
+ * @return None.
+*/
+void driver_enhance_timer_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
+
+ ENHTIM_InitTypeDef ENHTIM_InitStruct;
+ ENHTIM_StructInit(&ENHTIM_InitStruct);
+
+ ENHTIM_InitStruct.ENHTIM_ClockDiv = ENHTIM_CLOCK_DIVIDER_1;
+ ENHTIM_InitStruct.ENHTIM_Mode = ENHTIM_MODE_FreeRun;
+ /* Only enhtim_ ENHTIM_LatchCountEn[2] latch triggered by GPIO. */
+ ENHTIM_InitStruct.ENHTIM_LatchCountEn[2] = ENHTIM_LATCH_COUNT_ENABLE;
+ ENHTIM_InitStruct.ENHTIM_LatchCountTrigger[2] = ENHTIM_LATCH_TRIGGER_RISING_EDGE;
+ ENHTIM_InitStruct.ENHTIM_LatchCount2Thd = 3;
+ ENHTIM_InitStruct.ENHTIM_LatchTriggerPad = GPIO_INPUT_PIN_0;
+ ENHTIM_InitStruct.ENHTIM_TimerGPIOTriggerEn = ENABLE;
+
+ ENHTIM_Init(ENHTIMER_NUM, &ENHTIM_InitStruct);
+
+ /* Enable TIMER IRQ */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = ENHTIMER_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ ENHTIM_ClearINTPendingBit(ENHTIMER_NUM, ENHTIM_INT_TIM);
+ ENHTIM_INTConfig(ENHTIMER_NUM, ENHTIM_INT_TIM, ENABLE);
+
+ ENHTIM_ClearINTPendingBit(ENHTIMER_NUM, ENHTIM_INT_LATCH_CNT2_FIFO_FULL);
+ ENHTIM_INTConfig(ENHTIMER_NUM, ENHTIM_INT_LATCH_CNT2_FIFO_FULL, ENABLE);
+
+ ENHTIM_ClearINTPendingBit(ENHTIMER_NUM, ENHTIM_INT_LATCH_CNT2_FIFO_THD);
+ ENHTIM_INTConfig(ENHTIMER_NUM, ENHTIM_INT_LATCH_CNT2_FIFO_THD, ENABLE);
+
+ ENHTIM_Cmd(ENHTIMER_NUM, ENABLE);
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return None.
+*/
+void board_gpio_enhtim_init(void)
+{
+ Pad_Config(GPIO_INPUT_PIN_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(GPIO_INPUT_PIN_0, DWGPIO);
+}
+
+/**
+ * @brief Initialize GPIO peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_gpio_enhtim_init(void)
+{
+ /* Initialize GPIO peripheral */
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+ GPIO_StructInit(&GPIO_InitStruct);
+ GPIO_InitStruct.GPIO_Pin = GPIO_PIN_INPUT_0;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
+ GPIO_Init(&GPIO_InitStruct);
+
+ GPIO_WriteBit(GPIO_PIN_OUTPUT_0, (BitAction)(1));
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return None.
+*/
+void board_gpio_init(void)
+{
+ Pad_Config(GPIO_OUTPUT_PIN_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
+ PAD_OUT_HIGH);
+ Pinmux_Config(GPIO_OUTPUT_PIN_0, DWGPIO);
+}
+
+/**
+ * @brief Initialize GPIO peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_gpio_init(void)
+{
+ /* Initialize GPIO peripheral */
+ RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+ GPIO_StructInit(&GPIO_InitStruct);
+ GPIO_InitStruct.GPIO_Pin = GPIO_PIN_OUTPUT_0;
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_Init(&GPIO_InitStruct);
+
+ GPIO_WriteBit(GPIO_PIN_OUTPUT_0, (BitAction)(1));
+}
+
+/**
+ * @brief Demo code of timer.
+ * @param No parameter.
+ * @return void
+*/
+void enhance_tim_demo(void)
+{
+ board_gpio_enhtim_init();
+ driver_gpio_enhtim_init();
+ driver_enhance_timer_init();
+
+ /* GPIO output is only used to simulate the input signal, only for demo debugging. */
+ board_gpio_init();
+ driver_gpio_init();
+ while (1)
+ {
+ /* Simulate GPIO trigger signal */
+ for (uint32_t i = 0; i < 100000; i++);
+ GPIO_WriteBit(GPIO_PIN_OUTPUT_0, (BitAction)(1));
+ for (uint32_t i = 0; i < 100000; i++);
+ GPIO_WriteBit(GPIO_PIN_OUTPUT_0, (BitAction)(0));
+ }
+}
+
+/**
+ * @brief Entry of APP code.
+ * @return int (To avoid compile warning).
+ */
+int main(void)
+{
+ __enable_irq();
+
+ enhance_tim_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ }
+}
+
+void Enhanced_Timer0_Handler()
+{
+ if (ENHTIM_GetINTStatus(ENH_TIM0, ENHTIM_INT_TIM))
+ {
+ APP_PRINT_INFO0("ENH_TIM0 ENHTIM_INT_TIM\r\n");
+ //add user code here
+ ENHTIM_ClearINTPendingBit(ENH_TIM0, ENHTIM_INT_TIM);
+ }
+ if (ENHTIM_GetINTStatus(ENH_TIM0, ENHTIM_INT_LATCH_CNT2_FIFO_FULL))
+ {
+ APP_PRINT_INFO0("ENH_TIM0 ENHTIM_INT_LATCH_CNT2_FIFO_FULL\r\n");
+ //add user code here
+ ENHTIM_ClearINTPendingBit(ENH_TIM0, ENHTIM_INT_LATCH_CNT2_FIFO_FULL);
+ }
+ if (ENHTIM_GetINTStatus(ENH_TIM0, ENHTIM_INT_LATCH_CNT2_FIFO_THD))
+ {
+ APP_PRINT_INFO0("ENH_TIM0 ENHTIM_INT_LATCH_CNT2_FIFO_THD\r\n");
+ ENHTIM_INTConfig(ENHTIMER_NUM, ENHTIM_INT_LATCH_CNT2_FIFO_THD, DISABLE);
+ uint8_t length = ENHTIM_GetLatchCount2FIFOLength(ENH_TIM0);
+ uint32_t data[4] = {0};
+ ENHTIM_ReadLatchCount2FIFO(ENH_TIM0, data, length);
+ /* Only for debugging, removed in actual application. */
+ APP_PRINT_INFO1("ENH_TIM0 fifo length = %d\r\n", length);
+ for (uint8_t i = 0; i < length; i++)
+ {
+ /* Only for debugging, removed in actual application. */
+ APP_PRINT_INFO2("ENH_TIM0 data[%d] = 0x%x\r\n", i, data[i]);
+ }
+ //add user code here
+ ENHTIM_ClearINTPendingBit(ENH_TIM0, ENHTIM_INT_LATCH_CNT2_FIFO_THD);
+ ENHTIM_INTConfig(ENH_TIM0, ENHTIM_INT_LATCH_CNT2_FIFO_THD, ENABLE);
+ }
+}
diff --git a/src/sample/io_sample/UART/DLPS/ble_peripheral/ancs.c b/src/sample/io_sample/UART/DLPS/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/UART/DLPS/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/UART/DLPS/ble_peripheral/ancs.h b/src/sample/io_sample/UART/DLPS/ble_peripheral/ancs.h
new file mode 100644
index 0000000..784b6e8
--- /dev/null
+++ b/src/sample/io_sample/UART/DLPS/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app identifier length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/UART/DLPS/ble_peripheral/app.c b/src/sample/io_sample/UART/DLPS/ble_peripheral/app.c
new file mode 100644
index 0000000..62c7888
--- /dev/null
+++ b/src/sample/io_sample/UART/DLPS/ble_peripheral/app.c
@@ -0,0 +1,608 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file peripheral_app.c
+ * @brief This file handles BLE peripheral application routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#include "trace.h"
+
+#include "app.h"
+#include "io_uart.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_UART:
+ {
+ APP_PRINT_INFO0("[app] app_handle_io_msg: UART data msg.");
+ io_handle_uart_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/UART/DLPS/ble_peripheral/app.h b/src/sample/io_sample/UART/DLPS/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/UART/DLPS/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/UART/DLPS/ble_peripheral/app_flags.h b/src/sample/io_sample/UART/DLPS/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..3371839
--- /dev/null
+++ b/src/sample/io_sample/UART/DLPS/ble_peripheral/app_flags.h
@@ -0,0 +1,40 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+#include "upperstack_config.h"
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/UART/DLPS/ble_peripheral/app_task.c b/src/sample/io_sample/UART/DLPS/ble_peripheral/app_task.c
new file mode 100644
index 0000000..22465c9
--- /dev/null
+++ b/src/sample/io_sample/UART/DLPS/ble_peripheral/app_task.c
@@ -0,0 +1,133 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+#include "io_uart.h"
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+uint8_t String_Buf[100];
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+
+ /* Send demo string */
+ uint8_t demo_str_len = 0;
+ char *demo_str = "### Welcome to use UART demo ###\r\n";
+ demo_str_len = strlen(demo_str);
+ memcpy(String_Buf, demo_str, demo_str_len);
+ uart_senddata_continuous(UART0, String_Buf, demo_str_len);
+
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/UART/DLPS/ble_peripheral/app_task.h b/src/sample/io_sample/UART/DLPS/ble_peripheral/app_task.h
new file mode 100644
index 0000000..bd16830
--- /dev/null
+++ b/src/sample/io_sample/UART/DLPS/ble_peripheral/app_task.h
@@ -0,0 +1,46 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/UART/DLPS/ble_peripheral/main.c b/src/sample/io_sample/UART/DLPS/ble_peripheral/main.c
new file mode 100644
index 0000000..fb0981b
--- /dev/null
+++ b/src/sample/io_sample/UART/DLPS/ble_peripheral/main.c
@@ -0,0 +1,323 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author yuan
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2018 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <stdlib.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "trace.h"
+
+#include "app.h"
+#include "app_task.h"
+#include "app_flags.h"
+
+#include "dlps.h"
+#include "rtl876x_io_dlps.h"
+
+#include "io_uart.h"
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+void global_data_init(void)
+{
+ global_data_uart_init();
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_uart_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_uart_init();
+}
+
+#if DLPS_EN
+/**
+ * @brief this function will be called before enter DLPS
+ *
+ * set PAD and wakeup pin config for enterring DLPS
+ *
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_enter_dlps_config(void)
+{
+ io_uart_dlps_enter();
+}
+
+/**
+ * @brief this function will be called after exit DLPS
+ *
+ * set PAD and wakeup pin config for enterring DLPS
+ *
+ * @param none
+ * @return none
+ * @retval void
+ */
+void app_exit_dlps_config(void)
+{
+ io_uart_dlps_exit();
+}
+
+/**
+ * @brief Contains the setting about app dlps callback.
+ */
+bool app_dlps_check_cb(void)
+{
+ return (io_uart_dlps_check());
+}
+#endif /* DLPS_EN */
+
+/**
+ * @brief The setting about power mode.
+ * @param No parameter.
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+#if DLPS_EN
+ if (false == dlps_check_cb_reg(app_dlps_check_cb))
+ {
+ APP_PRINT_ERROR0("Error: dlps_check_cb_reg(app_dlps_check_cb) failed!");
+ }
+ DLPS_IORegUserDlpsEnterCb(app_enter_dlps_config);
+ DLPS_IORegUserDlpsExitCb(app_exit_dlps_config);
+ DLPS_IORegister();
+ lps_mode_set(PLATFORM_DLPS_PFM);
+
+ /* Config WakeUp pin */
+ System_WakeUpPinEnable(UART_RX_PIN, PAD_WAKEUP_POL_LOW, 0);
+
+#else
+ lps_mode_set(LPM_ACTIVE_MODE);
+#endif
+}
+
+///**
+// * @brief Contains the power mode settings
+// * @return void
+// */
+//void pwr_mgr_init(void)
+//{
+//}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+/**
+ * @brief System interrupt handler function, for wakeup pin.
+ * @param No parameter.
+ * @return void
+*/
+void System_Handler(void)
+{
+ APP_PRINT_INFO0("[main] System_Handler");
+ if (System_WakeUpInterruptValue(UART_RX_PIN) == SET)
+ {
+ System_WakeUpPinDisable(UART_RX_PIN);
+ Pad_ClearWakeupINTPendingBit(UART_RX_PIN);
+ IO_UART_DLPS_Enter_Allowed = false;
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
+
diff --git a/src/sample/io_sample/UART/DLPS/io_uart.c b/src/sample/io_sample/UART/DLPS/io_uart.c
new file mode 100644
index 0000000..3df562d
--- /dev/null
+++ b/src/sample/io_sample/UART/DLPS/io_uart.c
@@ -0,0 +1,239 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file io_uart.c
+* @brief uart interrupt demo
+* @details
+* @author yuan
+* @date 2018-06-28
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_uart.h"
+
+#include <string.h>
+
+#include "app_task.h"
+
+#include "trace.h"
+
+
+/* Globals ------------------------------------------------------------------*/
+uint8_t UART_RX_Buffer[256];
+uint8_t UART_RX_Count = 0;
+
+bool IO_UART_DLPS_Enter_Allowed = false;
+
+/**
+ * @brief Initialize uart global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_uart_init(void)
+{
+ IO_UART_DLPS_Enter_Allowed = true;
+ UART_RX_Count = 0;
+ memset(UART_RX_Buffer, 0, sizeof(UART_RX_Buffer));
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+ */
+void board_uart_init(void)
+{
+ Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+ Pad_Config(UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+
+ Pinmux_Config(UART_TX_PIN, UART0_TX);
+ Pinmux_Config(UART_RX_PIN, UART0_RX);
+}
+
+/**
+ * @brief Initialize uart peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_uart_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ /* uart init */
+ UART_InitTypeDef UART_InitStruct;
+ UART_StructInit(&UART_InitStruct);
+
+ UART_Init(UART0, &UART_InitStruct);
+
+ //enable rx interrupt and line status interrupt
+ UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+ UART_INTConfig(UART0, UART_INT_RX_IDLE, ENABLE);
+
+ /* Enable UART IRQ */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = UART0_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/**
+ * @brief IO enter dlps call back function.
+ * @param No parameter.
+ * @return void
+ */
+void io_uart_dlps_enter(void)
+{
+ /* Switch pad to Software mode */
+ Pad_ControlSelectValue(UART_TX_PIN, PAD_SW_MODE);
+ Pad_ControlSelectValue(UART_RX_PIN, PAD_SW_MODE);
+
+ System_WakeUpPinEnable(UART_RX_PIN, PAD_WAKEUP_POL_LOW, 0);
+}
+
+/**
+ * @brief IO exit dlps call back function.
+ * @param No parameter.
+ * @return void
+ */
+void io_uart_dlps_exit(void)
+{
+ /* Switch pad to Pinmux mode */
+ Pad_ControlSelectValue(UART_TX_PIN, PAD_PINMUX_MODE);
+ Pad_ControlSelectValue(UART_RX_PIN, PAD_PINMUX_MODE);
+
+}
+
+/**
+ * @brief IO enter dlps check function.
+ * @param No parameter.
+ * @return void
+ */
+bool io_uart_dlps_check(void)
+{
+ return IO_UART_DLPS_Enter_Allowed;
+}
+
+/**
+ * @brief UARt send data continuous.
+ * @param No parameter.
+ * @return void
+ */
+void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount)
+{
+ uint8_t count;
+
+ while (vCount / UART_TX_FIFO_SIZE > 0)
+ {
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ for (count = UART_TX_FIFO_SIZE; count > 0; count--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+ vCount -= UART_TX_FIFO_SIZE;
+ }
+
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ while (vCount--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+}
+
+/**
+ * @brief Handle uart data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_uart_handle_msg(T_IO_MSG *io_uart_msg)
+{
+// uint8_t *p_buf = io_uart_msg.u.buf;
+ uint16_t subtype = io_uart_msg->subtype;
+
+ if (IO_MSG_UART_RX == subtype)
+ {
+ uart_senddata_continuous(UART0, UART_RX_Buffer, UART_RX_Count);
+ global_data_uart_init();
+ while (UART_GetFlagStatus(UART0, UART_FLAG_TX_FIFO_EMPTY) == 0) { IO_UART_DLPS_Enter_Allowed = true; }
+ }
+}
+
+/**
+ * @brief Handle uart msg function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_uart_msg(T_IO_MSG *io_uart_msg)
+{
+ io_uart_handle_msg(io_uart_msg);
+}
+
+void UART0_Handler()
+{
+ uint16_t rx_len = 0;
+
+ /* Read interrupt id */
+ uint32_t int_status = UART_GetIID(UART0);
+
+ /* Disable interrupt */
+ UART_INTConfig(UART0, UART_INT_RD_AVA | UART_INT_RX_LINE_STS, DISABLE);
+
+ if (UART_GetFlagStatus(UART0, UART_FLAG_RX_IDLE) == SET)
+ {
+ /* Clear flag */
+ UART_INTConfig(UART0, UART_INT_RX_IDLE, DISABLE);
+
+ /* Send msg to app task */
+ T_IO_MSG int_uart_msg;
+
+ int_uart_msg.type = IO_MSG_TYPE_UART;
+ int_uart_msg.subtype = IO_MSG_UART_RX;
+ UART_RX_Buffer[UART_RX_Count] = UART_RX_Count;
+ int_uart_msg.u.buf = (void *)(&UART_RX_Buffer);
+ if (false == app_send_msg_to_apptask(&int_uart_msg))
+ {
+ APP_PRINT_ERROR0("[io_uart] UART0_Handler: Send int_uart_msg failed!");
+ //Add user code here!
+ return;
+ }
+// IO_UART_DLPS_Enter_Allowed = true;
+ UART_ClearRxFIFO(UART0);
+ UART_INTConfig(UART0, UART_INT_RX_IDLE, ENABLE);
+ }
+
+ switch (int_status & 0x0E)
+ {
+ /* Rx time out(0x0C). */
+ case UART_INT_ID_RX_DATA_TIMEOUT:
+ rx_len = UART_GetRxFIFODataLen(UART0);
+ UART_ReceiveData(UART0, &UART_RX_Buffer[UART_RX_Count], rx_len);
+ UART_RX_Count += rx_len;
+ break;
+
+ /* Receive line status interrupt(0x06). */
+ case UART_INT_ID_LINE_STATUS:
+ break;
+
+ /* Rx data valiable(0x04). */
+ case UART_INT_ID_RX_LEVEL_REACH:
+ rx_len = UART_GetRxFIFODataLen(UART0);
+ UART_ReceiveData(UART0, &UART_RX_Buffer[UART_RX_Count], rx_len);
+ UART_RX_Count += rx_len;
+ break;
+
+ /* Tx fifo empty(0x02), not enable. */
+ case UART_INT_ID_TX_EMPTY:
+ /* Do nothing */
+ break;
+ default:
+ break;
+ }
+
+ /* enable interrupt again */
+ UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/UART/DLPS/io_uart.h b/src/sample/io_sample/UART/DLPS/io_uart.h
new file mode 100644
index 0000000..4aaf395
--- /dev/null
+++ b/src/sample/io_sample/UART/DLPS/io_uart.h
@@ -0,0 +1,51 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_uart.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_UART_H
+#define __IO_UART_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_uart.h"
+
+#include "board.h"
+
+#include "app_msg.h"
+
+#define UART UART0
+
+/* Globals ------------------------------------------------------------------*/
+extern bool IO_UART_DLPS_Enter_Allowed;
+
+void global_data_uart_init(void);
+void board_uart_init(void);
+void driver_uart_init(void);
+void io_uart_dlps_enter(void);
+void io_uart_dlps_exit(void);
+bool io_uart_dlps_check(void);
+void io_handle_uart_msg(T_IO_MSG *io_uart_msg);
+void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/UART/DMA_UnFixedLen/main.c b/src/sample/io_sample/UART/DMA_UnFixedLen/main.c
new file mode 100644
index 0000000..c6be87e
--- /dev/null
+++ b/src/sample/io_sample/UART/DMA_UnFixedLen/main.c
@@ -0,0 +1,373 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief uart demo polling tx and rx.
+* @details
+* @author yuan
+* @date 2018-06-28
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_uart.h"
+#include "rtl876x_gdma.h"
+#include "trace.h"
+/* Defines ------------------------------------------------------------------*/
+#define UART_TX_PIN P3_0
+#define UART_RX_PIN P3_1
+/* Set 1 if Allow GDMA TX*/
+#define NOT_ALLOW_DEINIT 1
+
+#define DMA_RX_CHANNEL_NUM 2
+#define DMA_RX_CHANNEL GDMA_Channel2
+#define DMA_RX_IRQ GDMA0_Channel2_IRQn
+
+#define DMA_TX_CHANNEL_NUM 3
+#define DMA_TX_CHANNEL GDMA_Channel3
+#define DMA_TX_IRQ GDMA0_Channel3_IRQn
+
+#define GDMA_TRANSFER_SIZE 512
+#define GDMA_BLOCK_SIZE 216
+uint8_t GDMA_Rx_Buf[GDMA_TRANSFER_SIZE];
+uint8_t GDMA_Tx_Buf[GDMA_TRANSFER_SIZE];
+
+uint8_t receive_offset = 0;
+uint8_t count = 0;
+
+/* Globals ------------------------------------------------------------------*/
+typedef struct
+{
+ uint16_t div;
+ uint16_t ovsr;
+ uint16_t ovsr_adj;
+} UART_BaudRate_TypeDef;
+
+typedef enum
+{
+ BAUD_RATE_9600,
+ BAUD_RATE_19200,
+ BAUD_RATE_115200,
+ BAUD_RATE_230400,
+ BAUD_RATE_256000,
+ BAUD_RATE_384000,
+ BAUD_RATE_460800,
+ BAUD_RATE_921600,
+ BAUD_RATE_1000000,
+ BAUD_RATE_2000000,
+ BAUD_RATE_3000000
+} UartBaudRate_TypeDef;
+
+const UART_BaudRate_TypeDef BaudRate_Table[11] =
+{
+ {271, 10, 0x24A}, // BAUD_RATE_9600
+ {150, 8, 0x3EF}, // BAUD_RATE_19200
+ {20, 12, 0x252}, // BAUD_RATE_115200
+ {11, 10, 0x3BB}, // BAUD_RATE_230400
+ {11, 9, 0x084}, // BAUD_RATE_256000
+ {7, 9, 0x3EF}, // BAUD_RATE_384000
+ {6, 9, 0x0AA}, // BAUD_RATE_460800
+ {3, 9, 0x0AA}, // BAUD_RATE_921600
+ {4, 5, 0}, // BAUD_RATE_1000000
+ {2, 5, 0}, // BAUD_RATE_2000000
+ {1, 8, 0x292}, // BAUD_RATE_3000000
+};
+
+
+bool receiveflg = false;
+
+/****************************************************************************/
+/* board init */
+/****************************************************************************/
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_uart_init(void)
+{
+ Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+ Pad_Config(UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+
+ Pinmux_Config(UART_TX_PIN, UART0_TX);
+ Pinmux_Config(UART_RX_PIN, UART0_RX);
+}
+
+/****************************************************************************/
+/* UART driver init */
+/****************************************************************************/
+/**
+ * @brief Initialize uart peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_uart_init(void)
+{
+ UART_DeInit(UART0);
+
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+ /* uart init */
+ UART_InitTypeDef UART_InitStruct;
+ UART_StructInit(&UART_InitStruct);
+
+ /* Config uart baudrate */
+ UART_InitStruct.UART_Div = BaudRate_Table[BAUD_RATE_115200].div;
+ UART_InitStruct.UART_Ovsr = BaudRate_Table[BAUD_RATE_115200].ovsr;
+ UART_InitStruct.UART_OvsrAdj = BaudRate_Table[BAUD_RATE_115200].ovsr_adj;
+
+ UART_InitStruct.UART_Parity = UART_PARITY_NO_PARTY;
+ UART_InitStruct.UART_StopBits = UART_STOP_BITS_1;
+ UART_InitStruct.UART_WordLen = UART_WORD_LENGTH_8BIT;
+ UART_InitStruct.UART_RxThdLevel = 8; //1~29
+ UART_InitStruct.UART_IdleTime =
+ UART_RX_IDLE_2BYTE; //idle interrupt wait time
+ UART_InitStruct.UART_TxWaterLevel = 15;
+ UART_InitStruct.UART_RxWaterLevel =
+ 1; //Better to equal GDMA_MSize
+ UART_InitStruct.TxDmaEn = ENABLE;
+ UART_InitStruct.RxDmaEn = ENABLE;
+ UART_InitStruct.dmaEn = UART_DMA_ENABLE;
+
+ UART_Init(UART0, &UART_InitStruct);
+ UART_INTConfig(UART0, UART_INT_RX_IDLE | UART_INT_LINE_STS, ENABLE);
+ /* Enable UART IRQ */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = UART0_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+ return;
+}
+
+/****************************************************************************/
+/* GDMA_Channel3 driver init */
+/****************************************************************************/
+void driver_gdma3_init(void)
+{
+ /* Initialize GDMA */
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = DMA_TX_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral;
+ GDMA_InitStruct.GDMA_BufferSize = 0;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_Tx_Buf;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(UART0->RB_THR));
+ GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_UART0_TX;
+
+ GDMA_Init(DMA_TX_CHANNEL, &GDMA_InitStruct);
+ /* Enable transfer finish interrupt */
+ GDMA_INTConfig(DMA_TX_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+ /* Configure NVIC of GDMA */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = DMA_TX_IRQ;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+}
+
+/****************************************************************************/
+/* GDMA_Channel2 driver init */
+/****************************************************************************/
+void driver_gdma2_init(void)
+{
+ /* Initialize GDMA */
+ RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, ENABLE);
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = DMA_RX_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToMemory;
+ GDMA_InitStruct.GDMA_BufferSize = GDMA_BLOCK_SIZE;
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Inc;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)(&(UART0->RB_THR));
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)GDMA_Rx_Buf;
+ GDMA_InitStruct.GDMA_SourceHandshake = GDMA_Handshake_UART0_RX;
+
+ GDMA_Init(DMA_RX_CHANNEL, &GDMA_InitStruct);
+ /* Enable transfer finish interrupt */
+ GDMA_INTConfig(DMA_RX_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+ /* Configure NVIC of GDMA */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = GDMA0_Channel2_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ GDMA_Cmd(DMA_RX_CHANNEL_NUM, ENABLE);
+}
+
+/****************************************************************************/
+/* UART Handler */
+/****************************************************************************/
+void UART0_Handler(void)
+{
+ uint8_t tmp;
+ uint32_t data_len = 0;
+ uint32_t int_status = UART_GetIID(UART0);
+ if (UART_GetFlagState(UART0, UART_FLAG_RX_IDLE) == SET)
+ {
+ DBG_DIRECT("UART_FLAG_RX_IDLE");
+
+ /* Suspend GDMA_Channel4 */
+ GDMA_SuspendCmd(DMA_RX_CHANNEL, ENABLE);
+ UART_INTConfig(UART0, UART_INT_RX_IDLE, DISABLE);
+
+ data_len = GDMA_GetTransferLen(DMA_RX_CHANNEL);
+ for (uint32_t i = 0; i < data_len; i++)
+ {
+ DBG_DIRECT("value is 0x%x", GDMA_Rx_Buf[i]);
+ }
+
+ if (data_len)
+ {
+ receive_offset += data_len;
+ memcpy(GDMA_Tx_Buf + GDMA_BLOCK_SIZE * count, GDMA_Rx_Buf, data_len);
+
+#if NOT_ALLOW_DEINIT
+ uint32_t time_out = 0x1f;
+ while ((RESET == GDMA_GetSuspendChannelStatus(DMA_RX_CHANNEL)) && time_out)
+ {
+ time_out--;
+ }
+ time_out = 0x0f;
+ while ((RESET == GDMA_GetSuspendCmdStatus(DMA_RX_CHANNEL)) && time_out)
+ {
+ time_out--;
+ }
+ GDMA_Cmd(DMA_RX_CHANNEL_NUM, DISABLE);
+ GDMA_SuspendCmd(DMA_RX_CHANNEL, DISABLE);
+#else
+ GDMA_DeInit();
+#endif
+
+ driver_gdma2_init();
+ /* GDMA TX flag */
+ receiveflg = true;
+ }
+ /* Run here if data length = N * GDMA_BLOCK_SIZE, */
+ else
+ {
+ GDMA_SuspendCmd(DMA_RX_CHANNEL, DISABLE);
+ receiveflg = true;
+ }
+ UART_ClearRxFIFO(UART0);
+ UART_INTConfig(UART0, UART_INT_RX_IDLE, ENABLE);
+ }
+
+ UART_INTConfig(UART0, UART_INT_RD_AVA | UART_INT_RX_LINE_STS, DISABLE);
+
+ switch (int_status & 0x0E)
+ {
+ case UART_INT_ID_LINE_STATUS:
+ {
+ DBG_DIRECT("Line status error!=%x", UART0->LSR);
+ break;
+ }
+ case UART_INT_ID_RX_LEVEL_REACH:
+ {
+ DBG_DIRECT("UART_INT_ID_RX_LEVEL_REACH");
+ break;
+ }
+ case UART_INT_ID_RX_TMEOUT:
+ {
+ DBG_DIRECT("UART_INT_ID_RX_TMEOUT.");
+ while (UART_GetFlagState(UART0, UART_FLAG_RX_DATA_RDY) == SET)
+ {
+ UART_ReceiveData(UART0, &tmp, 1);
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ UART_INTConfig(UART0, UART_INT_RD_AVA | UART_INT_RX_LINE_STS, ENABLE);
+}
+
+void GDMA0_Channel3_Handler(void)
+{
+ DBG_DIRECT("UART_TX_GDMA_Handler");
+ GDMA_Cmd(DMA_TX_CHANNEL_NUM, DISABLE);
+ GDMA_ClearAllTypeINT(DMA_TX_CHANNEL_NUM);
+}
+
+/****************************************************************************/
+/* GDMA Handler */
+/****************************************************************************/
+void GDMA0_Channel2_Handler(void)
+{
+ DBG_DIRECT("GDMA0_Channel2_Handler");
+ /* Clear interrupt */
+ GDMA_Cmd(DMA_RX_CHANNEL_NUM, DISABLE);
+ GDMA_ClearAllTypeINT(DMA_RX_CHANNEL_NUM);
+ receive_offset += GDMA_BLOCK_SIZE;
+ count += 1;
+
+ /*print information*/
+ for (uint32_t i = 0; i < GDMA_BLOCK_SIZE; i++)
+ {
+ DBG_DIRECT("Rxvalue is 0x%x", GDMA_Rx_Buf[i]);
+ }
+ memcpy(GDMA_Tx_Buf + GDMA_BLOCK_SIZE * (count - 1), GDMA_Rx_Buf, GDMA_BLOCK_SIZE);
+
+ GDMA_ClearINTPendingBit(DMA_RX_CHANNEL_NUM, GDMA_INT_Transfer);
+ /* reset gdma param */
+ GDMA_SetDestinationAddress(DMA_RX_CHANNEL, (uint32_t)GDMA_Rx_Buf);
+ GDMA_Cmd(DMA_RX_CHANNEL_NUM, ENABLE);
+}
+
+/****************************************************************************/
+/* main */
+/****************************************************************************/
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ __enable_irq();
+ board_uart_init();
+ driver_uart_init();
+ /* GDMA Channel For Rx*/
+ driver_gdma2_init();
+ /* GDMA Channel For Tx*/
+ driver_gdma3_init();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+
+ if (receiveflg)
+ {
+ GDMA_SetBufferSize(DMA_TX_CHANNEL, receive_offset);
+ GDMA_Cmd(DMA_TX_CHANNEL_NUM, ENABLE);
+ receive_offset = 0;
+ count = 0;
+ receiveflg = false;
+ }
+ __nop();
+ __nop();
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/
diff --git a/src/sample/io_sample/UART/GDMA/ble_peripheral/ancs.c b/src/sample/io_sample/UART/GDMA/ble_peripheral/ancs.c
new file mode 100644
index 0000000..ac3254e
--- /dev/null
+++ b/src/sample/io_sample/UART/GDMA/ble_peripheral/ancs.c
@@ -0,0 +1,662 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file ancs.c
+ * @brief This file handles ANCS Client routines.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <trace.h>
+#include <string.h>
+#include <os_msg.h>
+#include <os_mem.h>
+#include <ancs.h>
+#include <ancs_client.h>
+
+/** @defgroup PERIPH_ANCS Peripheral ANCS
+ * @brief Apple ANCS service modulization
+ * @{
+ */
+/*============================================================================*
+ * Types
+ *============================================================================*/
+typedef struct
+{
+ uint8_t m_parse_state;
+ uint8_t app_type;
+ uint16_t current_len;
+ void *ancs_queue_handle;
+ uint8_t *ptr;
+ T_DS_NOTIFICATION_ATTR notification_attr;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_DS_APP_ATTR app_attr;
+#endif
+} T_APP_ANCS_LINK;
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Variables ANCS Exported Variables
+ * @brief app register ancs client to upperstack, and return ancs client id
+ * @{
+ */
+T_CLIENT_ID ancs_client; /**< ancs client id*/
+
+T_APP_ANCS_LINK *ancs_link_table;
+uint8_t ancs_link_number;
+
+/** End of PERIPH_ANCS_Exported_Variables
+ * @}
+ */
+extern void *evt_queue_handle; //!< Event queue handle
+extern void *io_queue_handle; //!< IO queue handle
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+void ancs_send_msg_to_app(uint8_t conn_id)
+{
+ T_IO_MSG io_msg;
+ uint8_t event = EVENT_IO_TO_APP;
+ io_msg.type = IO_MSG_TYPE_ANCS;
+ io_msg.subtype = 0;
+ io_msg.u.param = conn_id;
+
+ if (os_msg_send(io_queue_handle, &io_msg, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail1");
+ }
+ else if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ GAP_PRINT_ERROR0("ancs_send_msg_to_app fail2");
+ }
+}
+
+void app_handle_notification_attribute_data(T_APP_ANCS_LINK *p_ancs_link)
+{
+ if (p_ancs_link->notification_attr.attribute_id != DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ uint8_t *p_value = p_ancs_link->notification_attr.data;
+
+#if F_BT_ANCS_APP_FILTER
+ //filter QQ , wechat , short message and incoming call
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: app identifiter %s", TRACE_STRING(p_value));
+#endif
+ //wechat
+ if (0 == memcmp(p_value, "com.tencent.xin", 16))
+ {
+ p_ancs_link->app_type = 1;
+ }
+ else if (0 == memcmp(p_value, "com.apple.MobileSMS", 20))
+ {
+ p_ancs_link->app_type = 2;
+ }
+ else if (0 == memcmp(p_value, "com.apple.mobilephone", 22))
+ {
+ p_ancs_link->app_type = 3;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.mqq", 16))
+ {
+ p_ancs_link->app_type = 4;
+ }
+ else if (0 == memcmp(p_value, "com.tencent.qq", 15))
+ {
+ p_ancs_link->app_type = 5;
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_MESSAGE)
+ {
+ if (p_ancs_link->app_type == 2)
+ {
+ APP_PRINT_INFO1("MobileSMS: message %s", TRACE_STRING(p_value));
+ }
+ else if (p_ancs_link->app_type == 5)
+ {
+ APP_PRINT_INFO1("QQ: message %s", TRACE_STRING(p_value));
+ }
+ }
+ if (p_ancs_link->notification_attr.attribute_id == DS_NOTIFICATION_ATTR_ID_DATE)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: date %s", TRACE_STRING(p_value));
+#endif
+ }
+#endif
+ }
+ else/* All attributes has been parased*/
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO0("parse notify attr: parse done");
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+}
+
+void app_parse_notification_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_NOTIFICATION_COMMAND_ID:
+ p_ancs_link->notification_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID1;
+ break;
+
+ case DS_PARSE_UID1:
+ p_ancs_link->notification_attr.notification_uid[0] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID2;
+ break;
+
+ case DS_PARSE_UID2:
+ p_ancs_link->notification_attr.notification_uid[1] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID3;
+ break;
+
+ case DS_PARSE_UID3:
+ p_ancs_link->notification_attr.notification_uid[2] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_UID4;
+ break;
+
+ case DS_PARSE_UID4:
+ p_ancs_link->notification_attr.notification_uid[3] = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_ID:
+ p_ancs_link->notification_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN1:
+ p_ancs_link->notification_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_ATTRIBUTE_LEN2:
+ p_ancs_link->notification_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->notification_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse notify attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->notification_attr.attribute_id,
+ p_ancs_link->notification_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->notification_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_ATTRIBUTE_ID;
+ }
+ if (p_ancs_link->notification_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse notify attr: error, attribute_len %d > max length %d",
+ p_ancs_link->notification_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ memset(&p_ancs_link->notification_attr, 0, sizeof(T_DS_NOTIFICATION_ATTR));
+ }
+ break;
+
+ case DS_PARSE_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->notification_attr.attribute_len)
+ {
+ /*An attribute is always a string whose length in bytes is provided in the tuple but that is not NULL-terminated.*/
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("parse notify attr: data %b",
+ TRACE_BINARY(p_ancs_link->notification_attr.attribute_len,
+ p_ancs_link->notification_attr.data));
+#endif
+ app_handle_notification_attribute_data(p_ancs_link);
+ }
+ break;
+ }
+ }
+}
+
+#if F_BT_ANCS_GET_APP_ATTR
+void app_parse_app_attribute(T_APP_ANCS_LINK *p_ancs_link, uint8_t *p_data, uint8_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ switch (p_ancs_link->m_parse_state)
+ {
+ case DS_PARSE_GET_APP_COMMAND_ID:
+ p_ancs_link->app_attr.command_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_START;
+ break;
+
+ case DS_PARSE_APP_IDENTIFIER_START:
+ if (p_data[i] == 0x00)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_IDENTIFIER_END;
+
+ if (i + 1 == len)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ else
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+ }
+
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_ID:
+ p_ancs_link->app_attr.attribute_id = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN1;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN1:
+ p_ancs_link->app_attr.attribute_len = p_data[i];
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_LEN2;
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_LEN2:
+ p_ancs_link->app_attr.attribute_len |= (p_data[i] << 8);
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_READY;
+ p_ancs_link->ptr = p_ancs_link->app_attr.data;
+ p_ancs_link->current_len = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO2("parse app attr: attribute_id %d, attribute_len %d",
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len
+ );
+#endif
+ if (p_ancs_link->app_attr.attribute_len == 0)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_APP_ATTRIBUTE_ID;
+
+ }
+ if (p_ancs_link->app_attr.attribute_len > ANCS_MAX_ATTR_LEN)
+ {
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_ERROR2("parse app attr: error, attribute_len %d > max length %d",
+ p_ancs_link->app_attr.attribute_len,
+ ANCS_MAX_ATTR_LEN
+ );
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+ }
+ break;
+
+ case DS_PARSE_APP_ATTRIBUTE_READY:
+ *p_ancs_link->ptr++ = p_data[i];
+ p_ancs_link->current_len++;
+
+ if (p_ancs_link->current_len == p_ancs_link->app_attr.attribute_len)
+ {
+ *p_ancs_link->ptr++ = 0;
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO4("parse app attr: command_id 0x%x, attribute_id 0x%x, attribute_len %d, data %s",
+ p_ancs_link->app_attr.command_id,
+ p_ancs_link->app_attr.attribute_id,
+ p_ancs_link->app_attr.attribute_len,
+ TRACE_STRING(p_ancs_link->app_attr.data));
+#endif
+ p_ancs_link->m_parse_state = DS_PARSE_NOT_START;
+
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * @brief Parse ancs data source notification
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @param[in] len data length
+ * @return void
+ */
+void app_parse_data_soucre_notifications(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ APP_PRINT_INFO2("ANCS_FROM_DATA_SOURCE: conn_id %d, len =%d", conn_id, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("data = %b", TRACE_BINARY(len, p_data));
+#endif
+ T_APP_ANCS_LINK *p_ancs_link = &ancs_link_table[conn_id];
+
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("m_parse_state %d", p_ancs_link->m_parse_state);
+#endif
+ if (p_ancs_link->m_parse_state == DS_PARSE_NOT_START)
+ {
+ if (len >= 1 && p_data[0] == CP_CMD_ID_GET_NOTIFICATION_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_NOTIFICATION_COMMAND_ID;
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (len >= 1 && p_data[0] == CP_CMD_ID_GET_APP_ATTR)
+ {
+ p_ancs_link->m_parse_state = DS_PARSE_GET_APP_COMMAND_ID;
+ }
+#endif
+ }
+
+ if (p_ancs_link->m_parse_state < DS_PARSE_GET_APP_COMMAND_ID)
+ {
+ app_parse_notification_attribute(p_ancs_link, p_data, len);
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else
+ {
+ app_parse_app_attribute(p_ancs_link, p_data, len);
+ }
+#endif
+}
+
+void app_parse_notification_source_data(uint8_t conn_id, uint8_t *p_data, uint8_t len)
+{
+ if (8 == len)
+ {
+ T_NS_DATA ns_data;
+
+ memcpy(&ns_data, p_data, len);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO5("app_parse_notification_source_data: event_id %d, event_flags 0x%02x, category_id %d, category_count %d, notification_uid 0x%08x",
+ ns_data.event_id,
+ ns_data.event_flags,
+ ns_data.category_id,
+ ns_data.category_count,
+ ns_data.notification_uid
+ );
+ APP_PRINT_INFO5("event_flags: slient %d, important %d, pre existing %d, positive action %d, negative action %d ",
+ ns_data.event_flags & NS_EVENT_FLAG_SILENT,
+ ns_data.event_flags & NS_EVENT_FLAG_IMPORTANT,
+ ns_data.event_flags & NS_EVENT_FLAG_PRE_EXISTING,
+ ns_data.event_flags & NS_EVENT_FLAG_POSITIVE_ACTION,
+ ns_data.event_flags & NS_EVENT_FLAG_NEGATIVE_ACTION
+ );
+#endif
+ //you can filter by category_id here, for demo purpose, we didn't filter any CategoryID here.
+#if F_BT_ANCS_APP_FILTER
+ //filter social and other category & phone category & email category
+ if (ns_data.category_id == NS_CATEGORY_ID_SOCIAL ||
+ ns_data.category_id == NS_CATEGORY_ID_OTHER ||
+ ns_data.category_id == NS_CATEGORY_ID_INCOMING_CALL ||
+ ns_data.category_id == NS_CATEGORY_ID_EMAIL)
+ {
+#endif
+ if (ns_data.event_id != NS_EVENT_ID_NOTIFICATION_REMOVED)
+ {
+ uint32_t msg_num;
+ T_ANCS_MSG ancs_msg;
+ uint8_t attr_id_list[14];
+ uint8_t cur_index = 0;
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE;
+ attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN);
+ attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN);
+
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL;
+ attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL;
+
+ os_msg_queue_peek(ancs_link_table[conn_id].ancs_queue_handle, &msg_num);
+#if F_BT_ANCS_CLIENT_DEBUG
+ APP_PRINT_INFO1("app_parse_notification_source_data: msg_num %d", msg_num);
+#endif
+ if (msg_num == 0)
+ {
+ if (ancs_get_notification_attr(conn_id, ns_data.notification_uid, attr_id_list,
+ cur_index) == true)
+ {
+ return;
+ }
+ }
+
+ ancs_msg.type = ANCS_MSG_TYPE_GET_NOTIFI_ATTR;
+ ancs_msg.data.notifi_attr.conn_id = conn_id;
+ ancs_msg.data.notifi_attr.notification_uid = ns_data.notification_uid;
+ ancs_msg.data.notifi_attr.attribute_ids_len = cur_index;
+ memcpy(ancs_msg.data.notifi_attr.attribute_ids, attr_id_list, cur_index);
+ if (os_msg_send(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("app_parse_notification_source_data: discard, msg queue is full");
+ }
+ }
+#if F_BT_ANCS_APP_FILTER
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Ancs client callback handle message from upperstack
+ * @param[in] client_id client identifier
+ * @param[in] conn_id connection identifier
+ * @param[in] *p_data point to data buffer
+ * @return @ref T_APP_RESULT
+ */
+T_APP_RESULT ancs_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_ANCS_CB_DATA *p_cb_data = (T_ANCS_CB_DATA *)p_data;
+
+ switch (p_cb_data->cb_type)
+ {
+ case ANCS_CLIENT_CB_TYPE_DISC_STATE:
+ switch (p_cb_data->cb_content.disc_state)
+ {
+ case DISC_ANCS_DONE:
+ APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done.");
+ ancs_set_data_source_notify(conn_id, true);
+ break;
+ case DISC_ANCS_FAILED:
+ APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed.");
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT:
+ switch (p_cb_data->cb_content.notify_data.type)
+ {
+ case ANCS_FROM_DATA_SOURCE:;
+ app_parse_data_soucre_notifications(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ case ANCS_FROM_NOTIFICATION_SOURCE:
+ APP_PRINT_INFO2("ANCS_FROM_NOTIFICATION_SOURCE: conn_id %d, length %d",
+ conn_id, p_cb_data->cb_content.notify_data.value_size);
+ app_parse_notification_source_data(conn_id, p_cb_data->cb_content.notify_data.p_value,
+ p_cb_data->cb_content.notify_data.value_size);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_WRITE_RESULT:
+ {
+ if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS)
+ {
+ APP_PRINT_ERROR1("ANCS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x",
+ p_cb_data->cb_content.write_result.cause);
+ }
+ switch (p_cb_data->cb_content.write_result.type)
+ {
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE");
+ break;
+
+ case ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE");
+ ancs_set_notification_source_notify(conn_id, true);
+ break;
+ case ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE:
+ APP_PRINT_INFO0("ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE");
+ break;
+
+ case ANCS_WRITE_CONTROL_POINT:
+ APP_PRINT_INFO0("ANCS_WRITE_CONTROL_POINT");
+#if F_BT_ANCS_CLIENT_DEBUG
+ if (p_cb_data->cb_content.write_result.cause == 0x4A0)
+ {
+ APP_PRINT_ERROR0("The commandID was not recognized by the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A1)
+ {
+ APP_PRINT_ERROR0("The command was improperly formatted.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A2)
+ {
+ APP_PRINT_ERROR0("One of the parameters (for example, the NotificationUID) does not refer to an existing object on the NP.");
+ }
+ else if (p_cb_data->cb_content.write_result.cause == 0x4A3)
+ {
+ APP_PRINT_ERROR0("The action was not performed.");
+ }
+#endif
+ ancs_send_msg_to_app(conn_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO:
+ {
+ T_ANCS_MSG ancs_msg;
+ void *ancs_queue_handle = ancs_link_table[conn_id].ancs_queue_handle;
+ APP_PRINT_INFO1("ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id);
+ memset(&ancs_link_table[conn_id], 0, sizeof(T_APP_ANCS_LINK));
+ ancs_link_table[conn_id].ancs_queue_handle = ancs_queue_handle;
+ /*release msg queue*/
+ while (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0));
+ }
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+void ancs_handle_msg(T_IO_MSG *p_io_msg)
+{
+ uint8_t conn_id = p_io_msg->u.param;
+ T_ANCS_MSG ancs_msg;
+ if (os_msg_recv(ancs_link_table[conn_id].ancs_queue_handle, &ancs_msg, 0) == false)
+ {
+ APP_PRINT_INFO1("ancs_handle_msg: conn_id 0x%x os_msg_recv failed", conn_id);
+ return;
+ }
+ if (ancs_msg.type == ANCS_MSG_TYPE_GET_NOTIFI_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: notification_uid 0x%x",
+ ancs_msg.data.notifi_attr.notification_uid);
+ if (ancs_get_notification_attr(ancs_msg.data.notifi_attr.conn_id,
+ ancs_msg.data.notifi_attr.notification_uid,
+ ancs_msg.data.notifi_attr.attribute_ids, ancs_msg.data.notifi_attr.attribute_ids_len
+ ) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_NOTIFI_ATTR: Failed");
+ }
+
+ }
+ else if (ancs_msg.type == ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: notification_uid 0x%x",
+ ancs_msg.data.perform_action.notification_uid);
+ if (ancs_perform_notification_action(ancs_msg.data.perform_action.conn_id,
+ ancs_msg.data.perform_action.notification_uid,
+ ancs_msg.data.perform_action.action_id) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION: Failed");
+ }
+
+ }
+#if F_BT_ANCS_GET_APP_ATTR
+ else if (ancs_msg.type == ANCS_MSG_TYPE_GET_APP_ATTR)
+ {
+ APP_PRINT_INFO1("ANCS_MSG_TYPE_GET_APP_ATTR: app_identifier %s",
+ TRACE_STRING(ancs_msg.data.app_attr.app_identifier));
+ if (ancs_get_app_attr(ancs_msg.data.app_attr.conn_id,
+ ancs_msg.data.app_attr.app_identifier,
+ ancs_msg.data.app_attr.attribute_ids,
+ ancs_msg.data.app_attr.attribute_ids_len) == false)
+ {
+ APP_PRINT_ERROR0("ANCS_MSG_TYPE_GET_APP_ATTR: Failed");
+ }
+
+ }
+#endif
+}
+
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num)
+{
+ uint8_t i;
+ ancs_link_number = link_num;
+ ancs_link_table = os_mem_zalloc(RAM_TYPE_DATA_ON, ancs_link_number * sizeof(T_APP_ANCS_LINK));
+ if (ancs_link_table == NULL)
+ {
+ APP_PRINT_ERROR0("ancs_init: allocate buffer failed");
+ }
+ for (i = 0; i < ancs_link_number; i++)
+ {
+ if (os_msg_queue_create(&(ancs_link_table[i].ancs_queue_handle), ANCS_MSG_QUEUE_NUM,
+ sizeof(T_ANCS_MSG)) == false)
+ {
+ APP_PRINT_ERROR2("ancs_init: link_num %d, i 0x%x create queue failed", link_num, i);
+ }
+ }
+ ancs_client = ancs_add_client(ancs_client_cb, link_num);
+}
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#endif
diff --git a/src/sample/io_sample/UART/GDMA/ble_peripheral/ancs.h b/src/sample/io_sample/UART/GDMA/ble_peripheral/ancs.h
new file mode 100644
index 0000000..68ec35b
--- /dev/null
+++ b/src/sample/io_sample/UART/GDMA/ble_peripheral/ancs.h
@@ -0,0 +1,259 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file ancs.h
+* @brief ancs
+* @details ancs
+* @author ranhui
+* @date 2015-03-27
+* @version v0.1
+* *********************************************************************************************************
+*/
+
+#ifndef _ANCS_H__
+#define _ANCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+/** @addtogroup PERIPH_ANCS
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Macros ANCS Exported Macros
+ * @{
+ */
+#define ANCS_MAX_ATTR_LEN 256 //!< Max ancs attribute length
+
+#if F_BT_ANCS_GET_APP_ATTR
+#define ANCS_APP_IDENTIFIER_MAX_LEN 30 //!< Max app IDENTIFIER length
+#endif
+
+#define ANCS_MSG_QUEUE_NUM 5 //!< ANCS message queue size
+
+
+/** @brief ANCS event flag */
+#define NS_EVENT_FLAG_SILENT (1 << 0)
+#define NS_EVENT_FLAG_IMPORTANT (1 << 1)
+#define NS_EVENT_FLAG_PRE_EXISTING (1 << 2)
+#define NS_EVENT_FLAG_POSITIVE_ACTION (1 << 3) //!<A positive action exists and is associated with this iOS notification
+#define NS_EVENT_FLAG_NEGATIVE_ACTION (1 << 4) //!<A negative action exists and is associated with this iOS notification.
+
+/** End of PERIPH_ANCS_Exported_Macros
+ * @}
+ */
+
+/*============================================================================*
+ * Types
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Types ANCS Exported Types
+ * @{
+ */
+/** @brief ANCS event id for the peer device notification */
+typedef enum
+{
+ NS_EVENT_ID_NOTIFICATION_ADD = 0, /**< The arrival of a new iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_MODIFIED = 1, /**< The modification of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_REMOVED = 2, /**< The removal of an iOS notification on the NP */
+ NS_EVENT_ID_NOTIFICATION_RESERVED = 0xff
+} T_NS_EVENT_ID;
+
+/** @brief ANCS category id */
+typedef enum
+{
+ NS_CATEGORY_ID_OTHER = 0,
+ NS_CATEGORY_ID_INCOMING_CALL = 1,
+ NS_CATEGORY_ID_MISSED_CALL = 2,
+ NS_CATEGORY_ID_VOICE_MAIL = 3,
+ NS_CATEGORY_ID_SOCIAL = 4,
+ NS_CATEGORY_ID_SCHEDULE = 5,
+ NS_CATEGORY_ID_EMAIL = 6,
+ NS_CATEGORY_ID_NEWS = 7,
+ NS_CATEGORY_ID_HEALTH_AND_FITNESS = 8,
+ NS_CATEGORY_ID_BUSINESS_ADN_FINANCE = 9,
+ NS_CATEGORY_ID_LOCATION = 10,
+ NS_CATEGORY_ID_ENTERTAINMENT = 11,
+ NS_CATEGORY_ID_RESERVED = 255
+} T_NS_CATEGORY_ID;
+
+/** @brief ANCS notification attribute id */
+typedef enum
+{
+ DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER = 0, /**< Format: UTF-8 strings */
+ DS_NOTIFICATION_ATTR_ID_TITLE = 1, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_SUB_TITLE = 2, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE = 3, /**<Format: UTF-8 strings. Needs to be followed by a 2-bytes max length parameter */
+ DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE = 4, /**<The format of the DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE constant is a string
+ that represents the integral value of the message size. */
+ DS_NOTIFICATION_ATTR_ID_DATE = 5, /**<The format of the DS_NOTIFICATION_ATTR_ID_DATE constant is a string
+ that uses the Unicode Technical Standard (UTS) #35 date format pattern yyyyMMdd'T'HHmmSS. */
+ DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL = 6, /**<Format: UTF-8 strings. The label used to describe
+ the positive action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL = 7, /**<Format: UTF-8 strings. The label used to describe
+ the negative action that can be performed on the iOS notification. */
+ DS_NOTIFICATION_ATTR_ID_RESERVED = 255
+} T_DS_NOTIFICATION_ATTR_ID;
+
+/** @brief App parse ANCS notification attribute state */
+typedef enum
+{
+ DS_PARSE_NOT_START = 0x00,
+ DS_PARSE_GET_NOTIFICATION_COMMAND_ID = 0x01,
+ DS_PARSE_UID1,
+ DS_PARSE_UID2,
+ DS_PARSE_UID3,
+ DS_PARSE_UID4,
+ DS_PARSE_ATTRIBUTE_ID,
+ DS_PARSE_ATTRIBUTE_LEN1,
+ DS_PARSE_ATTRIBUTE_LEN2,
+ DS_PARSE_ATTRIBUTE_READY
+} T_DS_NOTIFICATION_ATTR_PARSE_STATE;
+
+/** @brief Smart Phone App attribute id. */
+typedef enum
+{
+ DS_APP_ATTR_ID_DISPLAY_NAME = 0,
+ DS_APP_ATTR_ID_RESERVED = 255
+} T_DS_APP_ATTR_ID;
+
+/** @brief App parse ANCS attribute state */
+typedef enum
+{
+ DS_PARSE_GET_APP_COMMAND_ID = 0x10,
+ DS_PARSE_APP_IDENTIFIER_START,
+ DS_PARSE_APP_IDENTIFIER_END,
+ DS_PARSE_APP_ATTRIBUTE_ID,
+ DS_PARSE_APP_ATTRIBUTE_LEN1,
+ DS_PARSE_APP_ATTRIBUTE_LEN2,
+ DS_PARSE_APP_ATTRIBUTE_READY
+} T_DS_APP_ATTR_PARSE_STATE;
+
+/** @brief ANCS action id state */
+typedef enum
+{
+ CP_ACTION_ID_POSITIVE = 0,
+ CP_ACTION_ID_NEGATIVE = 1,
+ CP_ACTION_ID_RESERVED = 255
+} T_CP_ACTION_ID_VALUES;
+
+/** @brief Define notification source data for record ANCS notification parameters */
+typedef struct
+{
+ uint8_t event_id; /**< This field informs the accessory whether the given iOS notification
+ was added, modified, or removed. The enumerated values for this field are defined in @ref T_NS_EVENT_ID*/
+ uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
+ uint8_t category_id; /**< A numerical value providing a category in which the iOS notification
+ can be classified. The enumerated values for this field are defined in @ref T_NS_CATEGORY_ID*/
+ uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
+ uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification.*/
+} T_NS_DATA, *P_NS_DATA;
+
+/** @brief Define notification attribute details data */
+/** App can acquire details information by attribute id */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t notification_uid[4];
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_NOTIFICATION_ATTR;
+
+/** @brief Local app record notification attribute information */
+typedef struct
+{
+ uint8_t command_id;
+ uint8_t attribute_id;
+ uint16_t attribute_len;
+ uint8_t data[ANCS_MAX_ATTR_LEN];
+} T_DS_APP_ATTR;
+
+/** @brief ANCS Message Type */
+typedef enum
+{
+ ANCS_MSG_TYPE_GET_NOTIFI_ATTR,
+ ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION,
+ ANCS_MSG_TYPE_GET_APP_ATTR,
+} T_ANCS_MSG_TYPE;
+
+/** @brief Message data of ANCS_MSG_TYPE_GET_NOTIFI_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t attribute_ids[14];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_NOTIFI_ATTR;
+
+/** @brief Message data of ANCS_MSG_TYPE_PERFORM_NOTIFI_ACTION */
+typedef struct
+{
+ uint8_t conn_id;
+ uint32_t notification_uid;
+ uint8_t action_id;
+} T_ANCS_PERFORM_NOTIFI_ACTION;
+
+#if F_BT_ANCS_GET_APP_ATTR
+/** @brief Message data of ANCS_MSG_TYPE_GET_APP_ATTR */
+typedef struct
+{
+ uint8_t conn_id;
+ char app_identifier[ANCS_APP_IDENTIFIER_MAX_LEN];
+ uint8_t attribute_ids[1];
+ uint8_t attribute_ids_len;
+} T_ANCS_GET_APP_ATTR;
+#endif
+
+/** @brief ANCS Message Data */
+typedef struct
+{
+ T_ANCS_MSG_TYPE type;
+ union
+ {
+ T_ANCS_GET_NOTIFI_ATTR notifi_attr;
+ T_ANCS_PERFORM_NOTIFI_ACTION perform_action;
+#if F_BT_ANCS_GET_APP_ATTR
+ T_ANCS_GET_APP_ATTR app_attr;
+#endif
+ } data;
+} T_ANCS_MSG;
+/** End of PERIPH_ANCS_Exported_Types
+ * @}
+ */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/** @defgroup PERIPH_ANCS_Exported_Functions ANCS Exported Functions
+ * @{
+ */
+/**
+ * @brief App register ancs client to upperstack.
+ * This ancs_client_cb callback function will handle message.
+ * @param[in] link_num Initialize link number
+ * @return void
+ */
+void ancs_init(uint8_t link_num);
+
+/**
+ * @brief All the ancs messages are pre-handled in this function
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void ancs_handle_msg(T_IO_MSG *p_io_msg);
+/** @} */ /* End of group PERIPH_ANCS_Exported_Functions */
+/** @} */ /* End of group PERIPH_ANCS */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/UART/GDMA/ble_peripheral/app.c b/src/sample/io_sample/UART/GDMA/ble_peripheral/app.c
new file mode 100644
index 0000000..2b06c34
--- /dev/null
+++ b/src/sample/io_sample/UART/GDMA/ble_peripheral/app.c
@@ -0,0 +1,613 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file peripheral_app.c
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <string.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_conn_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <ancs_client.h>
+#include "ancs.h"
+#endif
+
+#include "app.h"
+#include "io_uart.h"
+
+/** @defgroup PERIPH_APP Peripheral Application
+ * @brief This file handles BLE peripheral application routines.
+ * @{
+ */
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+/** @addtogroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+T_SERVER_ID bas_srv_id; /**< Battery service id */
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @defgroup PERIPH_GAP_MSG GAP Message Handler
+ * @brief Handle GAP Message
+ * @{
+ */
+T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
+T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg)
+{
+ uint16_t msg_type = io_msg.type;
+
+ switch (msg_type)
+ {
+ case IO_MSG_TYPE_BT_STATUS:
+ {
+ app_handle_gap_msg(&io_msg);
+ }
+ break;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ case IO_MSG_TYPE_ANCS:
+ {
+ ancs_handle_msg(&io_msg);
+ }
+ break;
+#endif
+ case IO_MSG_TYPE_GDMA:
+ {
+ APP_PRINT_INFO0("[app]app_handle_io_msg: gdma msg.");
+ io_handle_gdma_msg(&io_msg);
+ //Add user code here!
+ }
+ break;
+// case IO_MSG_TYPE_UART:
+// {
+// APP_PRINT_INFO0("[app] app_handle_io_msg: uart msg.");
+// io_handle_uartc_msg(&io_msg);
+// //Add user code here!
+// }
+// break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
+ * @note All the gap device state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] new_state New gap device state
+ * @param[in] cause GAP device state change cause
+ * @return void
+ */
+void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
+{
+ APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
+ new_state.gap_init_state, new_state.gap_adv_state, cause);
+ if (gap_dev_state.gap_init_state != new_state.gap_init_state)
+ {
+ if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
+ {
+ APP_PRINT_INFO0("GAP stack ready");
+ /*stack ready*/
+// le_adv_start();
+ io_uart_demo();
+ }
+ }
+
+ if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
+ {
+ if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
+ {
+ if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
+ {
+ APP_PRINT_INFO0("GAP adv stoped: because connection created");
+ }
+ else
+ {
+ APP_PRINT_INFO0("GAP adv stoped");
+ }
+ }
+ else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
+ {
+ APP_PRINT_INFO0("GAP adv start");
+ }
+ }
+
+ gap_dev_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
+ * @note All the gap conn state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New gap connection state
+ * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
+ * @return void
+ */
+void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
+{
+ APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+ conn_id, gap_conn_state, new_state, disc_cause);
+ switch (new_state)
+ {
+ case GAP_CONN_STATE_DISCONNECTED:
+ {
+ if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
+ && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
+ {
+ APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
+ }
+
+ le_adv_start();
+ }
+ break;
+
+ case GAP_CONN_STATE_CONNECTED:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_latency;
+ uint16_t conn_supervision_timeout;
+ uint8_t remote_bd[6];
+ T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ le_get_conn_addr(conn_id, remote_bd, &remote_bd_type);
+ APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
+ TRACE_BDADDR(remote_bd), remote_bd_type,
+ conn_interval, conn_latency, conn_supervision_timeout);
+ }
+ break;
+
+ default:
+ break;
+ }
+ gap_conn_state = new_state;
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
+ * @note All the gap authentication state events are pre-handled in this function.
+ * Then the event handling function shall be called according to the new_state
+ * @param[in] conn_id Connection ID
+ * @param[in] new_state New authentication state
+ * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
+ * @return void
+ */
+void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
+{
+ APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
+
+ switch (new_state)
+ {
+ case GAP_AUTHEN_STATE_STARTED:
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
+ }
+ break;
+
+ case GAP_AUTHEN_STATE_COMPLETE:
+ {
+ if (cause == GAP_SUCCESS)
+ {
+#if F_BT_ANCS_CLIENT_SUPPORT
+ ancs_start_discovery(conn_id);
+#endif
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
+
+ }
+ else
+ {
+ APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
+ }
+ }
+ break;
+
+ default:
+ {
+ APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
+ }
+ break;
+ }
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
+ * @note This msg is used to inform APP that exchange mtu procedure is completed.
+ * @param[in] conn_id Connection ID
+ * @param[in] mtu_size New mtu size
+ * @return void
+ */
+void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
+{
+ APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
+}
+
+/**
+ * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
+ * @note All the connection parameter update change events are pre-handled in this function.
+ * @param[in] conn_id Connection ID
+ * @param[in] status New update state
+ * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
+ * @return void
+ */
+void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
+{
+ switch (status)
+ {
+ case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
+ {
+ uint16_t conn_interval;
+ uint16_t conn_slave_latency;
+ uint16_t conn_supervision_timeout;
+
+ le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
+ le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
+ APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
+ conn_interval, conn_slave_latency, conn_supervision_timeout);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
+ {
+ APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
+ }
+ break;
+
+ case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
+ {
+ APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief All the BT GAP MSG are pre-handled in this function.
+ * @note Then the event handling function shall be called according to the
+ * subtype of T_IO_MSG
+ * @param[in] p_gap_msg Pointer to GAP msg
+ * @return void
+ */
+void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
+{
+ T_LE_GAP_MSG gap_msg;
+ uint8_t conn_id;
+ memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
+
+ APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
+ switch (p_gap_msg->subtype)
+ {
+ case GAP_MSG_LE_DEV_STATE_CHANGE:
+ {
+ app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
+ gap_msg.msg_data.gap_dev_state_change.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_STATE_CHANGE:
+ {
+ app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
+ (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
+ gap_msg.msg_data.gap_conn_state_change.disc_cause);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_MTU_INFO:
+ {
+ app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
+ gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
+ }
+ break;
+
+ case GAP_MSG_LE_CONN_PARAM_UPDATE:
+ {
+ app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
+ gap_msg.msg_data.gap_conn_param_update.status,
+ gap_msg.msg_data.gap_conn_param_update.cause);
+ }
+ break;
+
+ case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
+ {
+ app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
+ gap_msg.msg_data.gap_authen_state.new_state,
+ gap_msg.msg_data.gap_authen_state.status);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_JUST_WORK:
+ {
+ conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
+ le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
+ le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_USER_CONFIRMATION:
+ {
+ uint32_t display_value = 0;
+ conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
+ le_bond_get_display_key(conn_id, &display_value);
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
+ le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_PASSKEY_INPUT:
+ {
+ uint32_t passkey = 888888;
+ conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
+ APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
+ le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ case GAP_MSG_LE_BOND_OOB_INPUT:
+ {
+ uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
+ APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
+ le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
+ le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
+ }
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
+ break;
+ }
+}
+/** @} */ /* End of group PERIPH_GAP_MSG */
+
+/** @defgroup PERIPH_GAP_CALLBACK GAP Callback Event Handler
+ * @brief Handle GAP callback event
+ * @{
+ */
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
+{
+ T_APP_RESULT result = APP_RESULT_SUCCESS;
+ T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
+
+ switch (cb_type)
+ {
+ case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
+ APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
+ p_data->p_le_data_len_change_info->conn_id,
+ p_data->p_le_data_len_change_info->max_tx_octets,
+ p_data->p_le_data_len_change_info->max_tx_time);
+ break;
+
+ case GAP_MSG_LE_MODIFY_WHITE_LIST:
+ APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
+ p_data->p_le_modify_white_list_rsp->operation,
+ p_data->p_le_modify_white_list_rsp->cause);
+ break;
+
+ default:
+ APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
+ break;
+ }
+ return result;
+}
+/** @} */ /* End of group PERIPH_GAP_CALLBACK */
+
+/** @defgroup PERIPH_SEVER_CALLBACK Profile Server Callback Event Handler
+ * @brief Handle profile server callback event
+ * @{
+ */
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * service_id
+ * @param service_id Profile service ID
+ * @param p_data Pointer to callback data
+ * @return T_APP_RESULT, which indicates the function call is successful or not
+ * @retval APP_RESULT_SUCCESS Function run successfully
+ * @retval others Function run failed, and return number indicates the reason
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data)
+{
+ T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+ if (service_id == SERVICE_PROFILE_GENERAL_ID)
+ {
+ T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
+ switch (p_param->eventId)
+ {
+ case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
+ APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
+ p_param->event_data.service_reg_result);
+ break;
+
+ case PROFILE_EVT_SEND_DATA_COMPLETE:
+ APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
+ p_param->event_data.send_data_result.conn_id,
+ p_param->event_data.send_data_result.cause,
+ p_param->event_data.send_data_result.service_id,
+ p_param->event_data.send_data_result.attrib_idx,
+ p_param->event_data.send_data_result.credits);
+ if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
+ {
+ APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
+ }
+ else
+ {
+ APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == simp_srv_id)
+ {
+ TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data;
+ switch (p_simp_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_simp_cb_data->msg_data.notification_indification_index)
+ {
+ case SIMP_NOTIFY_INDICATE_V3_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_ENABLE");
+ }
+ break;
+
+ case SIMP_NOTIFY_INDICATE_V3_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V3_DISABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_ENABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_ENABLE");
+ }
+ break;
+ case SIMP_NOTIFY_INDICATE_V4_DISABLE:
+ {
+ APP_PRINT_INFO0("SIMP_NOTIFY_INDICATE_V4_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_simp_cb_data->msg_data.read_value_index == SIMP_READ_V1)
+ {
+ uint8_t value[2] = {0x01, 0x02};
+ APP_PRINT_INFO0("SIMP_READ_V1");
+ simp_ble_service_set_parameter(SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL, 2, &value);
+ }
+ }
+ break;
+ case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE:
+ {
+ switch (p_simp_cb_data->msg_data.write.opcode)
+ {
+ case SIMP_WRITE_V2:
+ {
+ APP_PRINT_INFO2("SIMP_WRITE_V2: write type %d, len %d", p_simp_cb_data->msg_data.write.write_type,
+ p_simp_cb_data->msg_data.write.len);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (service_id == bas_srv_id)
+ {
+ T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data;
+ switch (p_bas_cb_data->msg_type)
+ {
+ case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION:
+ {
+ switch (p_bas_cb_data->msg_data.notification_indification_index)
+ {
+ case BAS_NOTIFY_BATTERY_LEVEL_ENABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_ENABLE");
+ }
+ break;
+
+ case BAS_NOTIFY_BATTERY_LEVEL_DISABLE:
+ {
+ APP_PRINT_INFO0("BAS_NOTIFY_BATTERY_LEVEL_DISABLE");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:
+ {
+ if (p_bas_cb_data->msg_data.read_value_index == BAS_READ_BATTERY_LEVEL)
+ {
+ uint8_t battery_level = 90;
+ APP_PRINT_INFO1("BAS_READ_BATTERY_LEVEL: battery_level %d", battery_level);
+ bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return app_result;
+}
+
+/** @} */ /* End of group PERIPH_SEVER_CALLBACK */
+
+/** @} */ /* End of group PERIPH_APP */
diff --git a/src/sample/io_sample/UART/GDMA/ble_peripheral/app.h b/src/sample/io_sample/UART/GDMA/ble_peripheral/app.h
new file mode 100644
index 0000000..8aed00b
--- /dev/null
+++ b/src/sample/io_sample/UART/GDMA/ble_peripheral/app.h
@@ -0,0 +1,72 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app.h
+* @brief This file handles BLE peripheral application routines.
+* @author jane
+* @date 2017-06-06
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+#ifndef _APP_H
+#define _APP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <profile_server.h>
+
+#include "app_msg.h"
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+extern T_SERVER_ID simp_srv_id; /**< Simple ble service id*/
+extern T_SERVER_ID bas_srv_id; /**< Battery service id */
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+
+/**
+ * @brief All the application messages are pre-handled in this function
+ * @note All the IO MSGs are sent to this function, then the event handling
+ * function shall be called according to the MSG type.
+ * @param[in] io_msg:IO message data
+ * @return void
+ */
+void app_handle_io_msg(T_IO_MSG io_msg);
+
+/**
+ * @brief All the BT Profile service callback events are handled in this function
+ * @note Then the event handling function shall be called according to the
+ * @param[in] service_id: Profile service ID
+ * @param[in] p_data: Pointer to callback data
+ * @return Indicates the function call is successful or not
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data);
+
+/**
+ * @brief Callback for gap le to notify app
+ * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types.
+ * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA.
+ * @retval result @ref T_APP_RESULT
+ */
+T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/UART/GDMA/ble_peripheral/app_flags.h b/src/sample/io_sample/UART/GDMA/ble_peripheral/app_flags.h
new file mode 100644
index 0000000..0b1c430
--- /dev/null
+++ b/src/sample/io_sample/UART/GDMA/ble_peripheral/app_flags.h
@@ -0,0 +1,39 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_flags.h
+ * @brief This file is used to config app functions.
+ * @author jane
+ * @date 2017-06-06
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+#ifndef _APP_FLAGS_H_
+#define _APP_FLAGS_H_
+
+
+/** @defgroup PERIPH_Config Peripheral App Configuration
+ * @brief This file is used to config app functions.
+ * @{
+ */
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+
+/** @brief Config APP LE link number */
+#define APP_MAX_LINKS 1
+/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
+#define F_BT_DLPS_EN 0
+/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
+#define F_BT_ANCS_CLIENT_SUPPORT 0
+#define F_BT_ANCS_APP_FILTER (F_BT_ANCS_CLIENT_SUPPORT & 1)
+#define F_BT_ANCS_GET_APP_ATTR (F_BT_ANCS_CLIENT_SUPPORT & 0)
+/** @brief Config ANCS Client debug log: 0-close, 1-open */
+#define F_BT_ANCS_CLIENT_DEBUG (F_BT_ANCS_CLIENT_SUPPORT & 0)
+
+/** @} */ /* End of group PERIPH_Config */
+#endif
diff --git a/src/sample/io_sample/UART/GDMA/ble_peripheral/app_task.c b/src/sample/io_sample/UART/GDMA/ble_peripheral/app_task.c
new file mode 100644
index 0000000..38acc89
--- /dev/null
+++ b/src/sample/io_sample/UART/GDMA/ble_peripheral/app_task.c
@@ -0,0 +1,124 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file app_task.c
+ * @brief Routines to create App task and handle events & messages
+ * @author jane
+ * @date 2017-06-02
+ * @version v1.0
+ **************************************************************************************
+ * @attention
+ * <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+ **************************************************************************************
+ */
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <gap_le.h>
+
+#include "app.h"
+#include "app_task.h"
+
+
+/** @defgroup PERIPH_APP_TASK Peripheral App Task
+ * @brief This file handles the implementation of application task related functions.
+ *
+ * Create App task and handle events & messages
+ * @{
+ */
+/*============================================================================*
+ * Macros
+ *============================================================================*/
+#define APP_TASK_PRIORITY 1 //!< Task priorities
+#define APP_TASK_STACK_SIZE 256 * 10 //!< Task stack size
+#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
+#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
+#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+void *app_task_handle; //!< APP Task handle
+void *evt_queue_handle; //!< Event queue handle
+void *io_queue_handle; //!< IO queue handle
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+extern void driver_init(void);
+
+void app_main_task(void *p_param);
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg)
+{
+ uint8_t event = EVENT_IO_TO_APP;
+
+ if (os_msg_send(io_queue_handle, p_msg, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail");
+ return false;
+ }
+ if (os_msg_send(evt_queue_handle, &event, 0) == false)
+ {
+ APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Initialize App task
+ * @return void
+ */
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, APP_TASK_PRIORITY);
+// driver_init();
+}
+
+/**
+ * @brief App task to handle events & messages
+ * @param[in] p_param: Parameters sending to the task
+ * @return void
+ */
+void app_main_task(void *p_param)
+{
+ uint8_t event;
+ os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
+ os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
+
+ gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
+
+ driver_init();
+ while (true)
+ {
+ if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
+ {
+ if (event == EVENT_IO_TO_APP)
+ {
+ T_IO_MSG io_msg;
+ if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
+ {
+ app_handle_io_msg(io_msg);
+ }
+ }
+ else
+ {
+ gap_handle_msg(event);
+ }
+ }
+ }
+}
+
+/** @} */ /* End of group PERIPH_APP_TASK */
+
+
diff --git a/src/sample/io_sample/UART/GDMA/ble_peripheral/app_task.h b/src/sample/io_sample/UART/GDMA/ble_peripheral/app_task.h
new file mode 100644
index 0000000..5d5918a
--- /dev/null
+++ b/src/sample/io_sample/UART/GDMA/ble_peripheral/app_task.h
@@ -0,0 +1,47 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file app_task.h
+* @brief Routines to create App task and handle events & messages
+* @author jane
+* @date 2017-06-02
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+#ifndef _APP_TASK_H_
+#define _APP_TASK_H_
+
+#include <string.h>
+
+#include "os_msg.h"
+#include "os_queue.h"
+#include "os_sched.h"
+#include "os_task.h"
+#include "os_timer.h"
+
+#include "app_msg.h"
+
+#include "trace.h"
+
+
+/**
+ * @brief Send msg to app task.
+ * @param[in] p_handle: The handle to the message queue being peeked.
+ * @return The status of the message queue peek.
+ * @retval true:Message queue was peeked successfully.
+ * @retval false:Message queue was failed to peek.
+ */
+bool app_send_msg_to_apptask(T_IO_MSG *p_msg);
+
+/**
+ * @brief Initialize app task
+ * @return void
+ */
+void app_task_init(void);
+
+#endif
+
diff --git a/src/sample/io_sample/UART/GDMA/ble_peripheral/main.c b/src/sample/io_sample/UART/GDMA/ble_peripheral/main.c
new file mode 100644
index 0000000..82b1a7f
--- /dev/null
+++ b/src/sample/io_sample/UART/GDMA/ble_peripheral/main.c
@@ -0,0 +1,240 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief Source file for BLE peripheral project, mainly used for initialize modules
+* @author jane
+* @date 2017-06-12
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/*============================================================================*
+ * Header Files
+ *============================================================================*/
+#include <stdlib.h>
+#include <string.h>
+#include <gap.h>
+#include <gap_adv.h>
+#include <gap_bond_le.h>
+#include <gap_msg.h>
+#include <bas.h>
+#include <simple_ble_service.h>
+
+#if F_BT_ANCS_CLIENT_SUPPORT
+#include <profile_client.h>
+#include "ancs.h"
+#endif
+
+#include "app.h"
+#include "app_task.h"
+#include "platform_utils.h"
+#include "io_uart.h"
+
+
+/** @defgroup PERIPH_DEMO_MAIN Peripheral Main
+ * @brief Main file to initialize hardware and BT stack and start task scheduling
+ * @{
+ */
+
+/*============================================================================*
+ * Constants
+ *============================================================================*/
+/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */
+#define DEFAULT_ADVERTISING_INTERVAL_MIN 320
+/** @brief Default maximum advertising interval */
+#define DEFAULT_ADVERTISING_INTERVAL_MAX 320
+
+
+/*============================================================================*
+ * Variables
+ *============================================================================*/
+
+/** @brief GAP - scan response data (max size = 31 bytes) */
+static const uint8_t scan_rsp_data[] =
+{
+ 0x03, /* length */
+ GAP_ADTYPE_APPEARANCE, /* type="Appearance" */
+ LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+ HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN),
+};
+
+/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */
+static const uint8_t adv_data[] =
+{
+ /* Flags */
+ 0x02, /* length */
+ GAP_ADTYPE_FLAGS, /* type="Flags" */
+ GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
+ /* Service */
+ 0x03, /* length */
+ GAP_ADTYPE_16BIT_COMPLETE,
+ LO_WORD(GATT_UUID_SIMPLE_PROFILE),
+ HI_WORD(GATT_UUID_SIMPLE_PROFILE),
+ /* Local name */
+ 0x0F, /* length */
+ GAP_ADTYPE_LOCAL_NAME_COMPLETE,
+ 'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
+};
+
+/*============================================================================*
+ * Functions
+ *============================================================================*/
+/**
+ * @brief Initialize peripheral and gap bond manager related parameters
+ * @return void
+ */
+void app_le_gap_init(void)
+{
+ /* Device name and device appearance */
+ uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
+ uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
+ uint8_t slave_init_mtu_req = false;
+
+ /* Advertising parameters */
+ uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
+ uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
+ uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
+ uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
+ uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
+ uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
+ uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MAX;
+
+ /* GAP Bond Manager parameters */
+ uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
+ uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+ uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
+ uint8_t auth_oob = false;
+ uint8_t auth_use_fix_passkey = false;
+ uint32_t auth_fix_passkey = 0;
+#if F_BT_ANCS_CLIENT_SUPPORT
+ uint8_t auth_sec_req_enable = true;
+#else
+ uint8_t auth_sec_req_enable = false;
+#endif
+ uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
+
+ /* Set device name and device appearance */
+ le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
+ le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
+ le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
+ &slave_init_mtu_req);
+
+ /* Set advertising parameters */
+ le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
+ le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
+ le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
+ le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
+ le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
+ le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
+ le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
+
+ /* Setup the GAP Bond Manager */
+ gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
+ gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
+ gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
+ gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
+ &auth_use_fix_passkey);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable);
+ le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
+ &auth_sec_req_flags);
+
+ /* register gap message callback */
+ le_register_app_cb(app_gap_callback);
+}
+
+/**
+ * @brief Add GATT services and register callbacks
+ * @return void
+ */
+void app_le_profile_init(void)
+{
+ server_init(2);
+ bas_srv_id = bas_add_service(app_profile_callback);
+ simp_srv_id = simp_ble_service_add_service(app_profile_callback);
+ server_register_app_cb(app_profile_callback);
+#if F_BT_ANCS_CLIENT_SUPPORT
+ client_init(1);
+ ancs_init(APP_MAX_LINKS);
+#endif
+}
+
+/**
+ * @brief Initialize global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_init(void)
+{
+
+}
+
+/**
+ * @brief Contains the initialization of pinmux settings and pad settings
+ * @note All the pinmux settings and pad settings shall be initiated in this function,
+ * but if legacy driver is used, the initialization of pinmux setting and pad setting
+ * should be performed with the IO initializing.
+ * @return void
+ */
+void board_init(void)
+{
+ board_uart_init();
+}
+
+/**
+ * @brief Contains the initialization of peripherals
+ * @note Both new architecture driver and legacy driver initialization method can be used
+ * @return void
+ */
+void driver_init(void)
+{
+ driver_uart_init();
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+}
+
+/**
+ * @brief Contains the initialization of all tasks
+ * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here
+ * @return void
+ */
+void task_init(void)
+{
+ app_task_init();
+}
+
+/**
+ * @brief Entry of APP code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ global_data_init();
+ board_init();
+ le_gap_init(APP_MAX_LINKS);
+ gap_lib_init();
+ app_le_gap_init();
+ app_le_profile_init();
+ pwr_mgr_init();
+ task_init();
+ os_sched_start();
+
+ return 0;
+}
+/** @} */ /* End of group PERIPH_DEMO_MAIN */
+
+
diff --git a/src/sample/io_sample/UART/GDMA/io_uart.c b/src/sample/io_sample/UART/GDMA/io_uart.c
new file mode 100644
index 0000000..a151397
--- /dev/null
+++ b/src/sample/io_sample/UART/GDMA/io_uart.c
@@ -0,0 +1,376 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+* @file main.c
+* @brief This file handles XXX application routines.
+* @author yuan
+* @date 2018-05-15
+* @version v1.0
+**************************************************************************************
+* @attention
+* <h2><center>&copy; COPYRIGHT 2017 Realtek Semiconductor Corporation</center></h2>
+**************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_uart.h"
+#include "app_task.h"
+
+typedef struct
+{
+ uint16_t div;
+ uint16_t ovsr;
+ uint16_t ovsr_adj;
+} UART_BaudRate_TypeDef;
+
+typedef enum
+{
+ BAUD_RATE_9600,
+ BAUD_RATE_19200,
+ BAUD_RATE_115200,
+ BAUD_RATE_230400,
+ BAUD_RATE_256000,
+ BAUD_RATE_384000,
+ BAUD_RATE_460800,
+ BAUD_RATE_921600,
+ BAUD_RATE_1000000,
+ BAUD_RATE_2000000,
+ BAUD_RATE_3000000
+} UartBaudRate_TypeDef;
+
+const UART_BaudRate_TypeDef BaudRate_Table[11] =
+{
+ {271, 10, 0x24A}, // BAUD_RATE_9600
+ {150, 8, 0x3EF}, // BAUD_RATE_19200
+ {20, 12, 0x252}, // BAUD_RATE_115200
+ {11, 10, 0x3BB}, // BAUD_RATE_230400
+ {11, 9, 0x084}, // BAUD_RATE_256000
+ {7, 9, 0x3EF}, // BAUD_RATE_384000
+ {6, 9, 0x0AA}, // BAUD_RATE_460800
+ {3, 9, 0x0AA}, // BAUD_RATE_921600
+ {4, 5, 0}, // BAUD_RATE_1000000
+ {2, 5, 0}, // BAUD_RATE_2000000
+ {1, 8, 0x292}, // BAUD_RATE_3000000
+};
+
+uint8_t GDMA_SendData_Buffer[UART_TX_GDMA_BUFFER_SIZE];
+uint8_t GDMA_ReceiveData_Buffer[UART_RX_GDMA_BUFFER_SIZE];
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_uart_init(void)
+{
+ Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+ Pad_Config(UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE,
+ PAD_OUT_HIGH);
+
+ Pinmux_Config(UART_TX_PIN, UART0_TX);
+ Pinmux_Config(UART_RX_PIN, UART0_RX);
+}
+
+/**
+ * @brief Initialize uart peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_uart_init(void)
+{
+ UART_DeInit(UART0);
+
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ /* uart init */
+ UART_InitTypeDef UART_InitStruct;
+ UART_StructInit(&UART_InitStruct);
+
+ UART_InitStruct.UART_Div = BaudRate_Table[BAUD_RATE_115200].div;
+ UART_InitStruct.UART_Ovsr = BaudRate_Table[BAUD_RATE_115200].ovsr;
+ UART_InitStruct.UART_OvsrAdj = BaudRate_Table[BAUD_RATE_115200].ovsr_adj;
+
+ UART_InitStruct.UART_RxThdLevel = 16; //1~29
+ UART_InitStruct.UART_IdleTime = UART_RX_IDLE_2BYTE; //idle interrupt wait time
+ UART_InitStruct.UART_DmaEn = UART_DMA_ENABLE;
+ UART_InitStruct.UART_TxWaterLevel = 15; //Better to equal TX_FIFO_SIZE(16)- GDMA_MSize
+ UART_InitStruct.UART_RxWaterLevel = 1; //Better to equal GDMA_MSize
+#if (UART_GDMA_TX_ENABLE == EVB_ENABLE)
+ UART_InitStruct.UART_TxDmaEn = ENABLE;
+#endif
+#if (UART_GDMA_RX_ENABLE == EVB_ENABLE)
+ UART_InitStruct.UART_RxDmaEn = ENABLE;
+#endif
+ UART_Init(UART0, &UART_InitStruct);
+}
+
+void UART_SendData_Continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount)
+{
+ uint8_t count;
+
+ while (vCount / 16 > 0)
+ {
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ for (count = 16; count > 0; count--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+ vCount -= 16;
+ }
+
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ while (vCount--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+
+}
+
+void UART_SendDataByGDMA(void)
+{
+ /*--------------initialize test buffer which for sending data to UART---------------------*/
+ for (uint32_t i = 0; i < UART_TX_GDMA_BUFFER_SIZE; i++)
+ {
+ GDMA_SendData_Buffer[i] = 0x10 + i;
+ }
+
+ /*--------------GDMA init-----------------------------*/
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = UART_TX_GDMA_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral;
+ GDMA_InitStruct.GDMA_BufferSize = UART_TX_GDMA_BUFFER_SIZE;//determine total transfer size
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_SendData_Buffer;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(UART0->RB_THR));
+ GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_UART0_TX;
+ GDMA_InitStruct.GDMA_ChannelPriority = 2;//channel prority between 0 to 5
+ GDMA_Init(UART_TX_GDMA_CHANNEL, &GDMA_InitStruct);
+
+ GDMA_INTConfig(UART_TX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+
+ /*-----------------GDMA IRQ init-------------------*/
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = UART_TX_GDMA_CHANNEL_IRQN;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ /*-----------------start to send data-----------*/
+ GDMA_Cmd(UART_TX_GDMA_CHANNEL_NUM, ENABLE);
+}
+
+void UART_ReceiveDataByGDMA(void)
+{
+ /*--------------initialize test buffer which for sending data to UART---------------------*/
+ for (uint32_t i = 0; i < UART_RX_GDMA_BUFFER_SIZE; i++)
+ {
+ GDMA_ReceiveData_Buffer[i] = 0;
+ }
+
+ /*--------------GDMA init-----------------------------*/
+ GDMA_InitTypeDef GDMA_InitStruct;
+ GDMA_StructInit(&GDMA_InitStruct);
+ GDMA_InitStruct.GDMA_ChannelNum = UART_RX_GDMA_CHANNEL_NUM;
+ GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToMemory;
+ GDMA_InitStruct.GDMA_BufferSize = UART_RX_GDMA_BUFFER_SIZE;//determine total transfer size
+ GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
+ GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Inc;
+ GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte;
+ GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1;
+ GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)(&(UART0->RB_THR));
+ GDMA_InitStruct.GDMA_SourceHandshake = GDMA_Handshake_UART0_RX;
+ GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)GDMA_ReceiveData_Buffer;
+ GDMA_InitStruct.GDMA_ChannelPriority = 2;//channel prority between 0 to 5
+ GDMA_Init(UART_RX_GDMA_CHANNEL, &GDMA_InitStruct);
+
+ GDMA_INTConfig(UART_RX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
+
+ /*-----------------GDMA IRQ init-------------------*/
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = UART_RX_GDMA_CHANNEL_IRQN;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+
+ /*-----------------start to send data-----------*/
+ GDMA_Cmd(UART_RX_GDMA_CHANNEL_NUM, ENABLE);
+}
+
+/**
+ * @brief Handle gdma msg function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_gdma_msg(T_IO_MSG *io_gdma_msg)
+{
+ uint16_t subtype = io_gdma_msg->subtype;
+ if (subtype == 0)
+ {
+ APP_PRINT_INFO0("io_handle_gdma_msg: uart tx done ");
+// /* cyclic transmission */
+// GDMA_SetSourceAddress(UART_TX_GDMA_CHANNEL, (uint32_t)(GDMA_SendData_Buffer));
+// GDMA_SetDestinationAddress(UART_TX_GDMA_CHANNEL, (uint32_t)(&(UART0->RB_THR)));
+// GDMA_SetBufferSize(UART_TX_GDMA_CHANNEL, UART_TX_GDMA_BUFFER_SIZE);
+// GDMA_ClearINTPendingBit(UART_TX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+// GDMA_Cmd(UART_TX_GDMA_CHANNEL_NUM, ENABLE);
+ }
+ else if (subtype == 1)
+ {
+ APP_PRINT_INFO0("io_handle_gdma_msg: uart rx done ");
+ UART_SendData_Continuous(UART0, GDMA_ReceiveData_Buffer, UART_RX_GDMA_BUFFER_SIZE);
+// /* cyclic reception */
+// GDMA_SetSourceAddress(UART_RX_GDMA_CHANNEL, (uint32_t)(&(UART0->RB_THR)));
+// GDMA_SetDestinationAddress(UART_RX_GDMA_CHANNEL, (uint32_t)(GDMA_ReceiveData_Buffer));
+// GDMA_SetBufferSize(UART_RX_GDMA_CHANNEL, UART_RX_GDMA_BUFFER_SIZE);
+// GDMA_ClearINTPendingBit(UART_RX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+// GDMA_Cmd(UART_RX_GDMA_CHANNEL_NUM, ENABLE);
+ }
+}
+
+void io_uart_demo(void)
+{
+ uint8_t send_data[100] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ for (uint8_t i = 0; i < 90; i++)
+ {
+ send_data[i] = i + 1;
+ }
+ for (uint8_t i = 90; i < 100; i++)
+ {
+ send_data[i] = 0xFF;
+ }
+
+ UART_SendData_Continuous(UART0, send_data, sizeof(send_data));
+
+#if (UART_GDMA_TX_ENABLE == EVB_ENABLE)
+ UART_SendDataByGDMA();
+#endif
+#if (UART_GDMA_RX_ENABLE == EVB_ENABLE)
+ UART_ReceiveDataByGDMA();
+#endif
+}
+
+void UART0_Handler()
+{
+ uint16_t length = 0;
+ uint8_t uart_rev_data[32];
+
+ /* read interrupt id */
+ uint32_t int_status = UART_GetIID(UART0);
+
+ /* disable interrupt */
+ UART_INTConfig(UART0, UART_INT_RD_AVA, DISABLE);
+
+ if (UART_GetFlagStatus(UART0, UART_FLAG_RX_IDLE) == SET)
+ {
+ UART_INTConfig(UART0, UART_INT_RX_IDLE, DISABLE);
+ DBG_DIRECT("UART0_FLAG_RX_IDLE");
+ UART_ClearRxFIFO(UART0);
+ UART_INTConfig(UART0, UART_INT_RX_IDLE, ENABLE);
+ }
+
+ switch (int_status & 0x0E)
+ {
+ /*rx time out*/
+ case 0x0C:
+ length = UART_GetRxFIFODataLen(UART0);
+ DBG_DIRECT("UART0_Handler rx time out, length = %d", length);
+ UART_ReceiveData(UART0, uart_rev_data, length);
+ for (uint8_t i = 0; i < length; i++)
+ {
+ DBG_DIRECT("data=0x%x", uart_rev_data[i]);
+ }
+ UART_SendData_Continuous(UART0, uart_rev_data, length);
+ break;
+
+ /* receiver line status */
+ case 0x06:
+ break;
+
+ /* rx data valiable */
+ case 0x04:
+ length = UART_GetRxFIFODataLen(UART0);
+ DBG_DIRECT("UART0_Handler rx data valiable, length = %d", length);
+ UART_ReceiveData(UART0, uart_rev_data, length);
+ for (uint8_t i = 0; i < length; i++)
+ {
+ DBG_DIRECT("data=0x%x", uart_rev_data[i]);
+ }
+ UART_SendData_Continuous(UART0, uart_rev_data, length);
+ break;
+
+ /* tx fifo empty */
+ case 0x02:
+ /* do nothing */
+ break;
+
+ /* modem status */
+ case 0x00:
+ break;
+
+ default:
+ break;
+ }
+
+ /* enable interrupt again */
+ UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+}
+
+/**
+ * @brief GDMA interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void UART_TX_GDMA_Handler(void)
+{
+ GDMA_ClearINTPendingBit(UART_TX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+
+ T_IO_MSG int_uart_msg;
+
+ int_uart_msg.type = IO_MSG_TYPE_GDMA;
+ int_uart_msg.subtype = 0;
+ int_uart_msg.u.buf = (void *)(GDMA_SendData_Buffer);
+
+ if (false == app_send_msg_to_apptask(&int_uart_msg))
+ {
+ APP_PRINT_ERROR0("[io_adc]UART_GDMA_Channel_Handler: Send int_uart_msg failed!");
+ //Add user code here!
+
+ GDMA_ClearINTPendingBit(UART_TX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+ return;
+ }
+}
+
+/**
+ * @brief GDMA interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void UART_RX_GDMA_Handler(void)
+{
+ GDMA_ClearINTPendingBit(UART_RX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+
+ T_IO_MSG int_uart_msg;
+
+ int_uart_msg.type = IO_MSG_TYPE_GDMA;
+ int_uart_msg.subtype = 1;
+ int_uart_msg.u.buf = (void *)(GDMA_SendData_Buffer);
+
+ if (false == app_send_msg_to_apptask(&int_uart_msg))
+ {
+ APP_PRINT_ERROR0("[io_adc]UART_GDMA_Channel_Handler: Send int_uart_msg failed!");
+ //Add user code here!
+
+ GDMA_ClearINTPendingBit(UART_TX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
+ return;
+ }
+}
diff --git a/src/sample/io_sample/UART/GDMA/io_uart.h b/src/sample/io_sample/UART/GDMA/io_uart.h
new file mode 100644
index 0000000..9a7fe1c
--- /dev/null
+++ b/src/sample/io_sample/UART/GDMA/io_uart.h
@@ -0,0 +1,76 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_adc.h
+* @brief
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+#ifndef __IO_ADC_H
+#define __IO_ADC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include "rtl876x_gdma.h"
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_uart.h"
+
+#include "app_msg.h"
+#include "board.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define UART_TX_PIN P3_0
+#define UART_RX_PIN P3_1
+
+#define UART_NUM 0
+#define UART_BAUDRATE (BAUD_RATE_115200)
+
+#define EVB_ENABLE 1
+#define EVB_DISABLE 0
+#define UART_GDMA_TX_ENABLE EVB_ENABLE
+#define UART_GDMA_RX_ENABLE EVB_ENABLE
+
+#define UART_TX_GDMA_CHANNEL_NUM 0
+#define UART_TX_GDMA_CHANNEL GDMA_Channel0
+#define UART_TX_GDMA_CHANNEL_IRQN GDMA0_Channel0_IRQn
+#define UART_TX_GDMA_BUFFER_SIZE 4095//max size=65535
+#define UART_TX_GDMA_Handler GDMA0_Channel0_Handler
+
+#define UART_RX_GDMA_CHANNEL_NUM 1
+#define UART_RX_GDMA_CHANNEL GDMA_Channel1
+#define UART_RX_GDMA_CHANNEL_IRQN GDMA0_Channel1_IRQn
+#define UART_RX_GDMA_Handler GDMA0_Channel1_Handler
+#define UART_RX_GDMA_BUFFER_SIZE 4095//max size=65535
+
+typedef struct
+{
+ uint16_t div;
+ uint16_t ovsr;
+ uint16_t ovsr_adj;
+} UART_BaudRateValue;
+
+
+void board_uart_init(void);
+void driver_uart_init(void);
+void driver_gdma_uart_init(void);
+//void io_handle_uart_msg(T_IO_MSG *io_adc_msg);
+void io_handle_gdma_msg(T_IO_MSG *io_gdma_msg);
+void io_uart_demo(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/sample/io_sample/UART/Interrupt/main.c b/src/sample/io_sample/UART/Interrupt/main.c
new file mode 100644
index 0000000..a79230e
--- /dev/null
+++ b/src/sample/io_sample/UART/Interrupt/main.c
@@ -0,0 +1,250 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file uart_interrupt_demo.c
+* @brief uart demo interrupt
+* @details
+* @author yuan
+* @date 2018-06-28
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include <stdlib.h>
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_uart.h"
+#include "trace.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define UART_TX_PIN P3_0
+#define UART_RX_PIN P3_1
+
+/* Globals ------------------------------------------------------------------*/
+typedef struct
+{
+ uint16_t div;
+ uint16_t ovsr;
+ uint16_t ovsr_adj;
+} UART_BaudRate_TypeDef;
+
+typedef enum
+{
+ BAUD_RATE_9600,
+ BAUD_RATE_19200,
+ BAUD_RATE_115200,
+ BAUD_RATE_230400,
+ BAUD_RATE_256000,
+ BAUD_RATE_384000,
+ BAUD_RATE_460800,
+ BAUD_RATE_921600,
+ BAUD_RATE_1000000,
+ BAUD_RATE_2000000,
+ BAUD_RATE_3000000
+} UartBaudRate_TypeDef;
+
+const UART_BaudRate_TypeDef BaudRate_Table[11] =
+{
+ {271, 10, 0x24A}, // BAUD_RATE_9600
+ {150, 8, 0x3EF}, // BAUD_RATE_19200
+ {20, 12, 0x252}, // BAUD_RATE_115200
+ {11, 10, 0x3BB}, // BAUD_RATE_230400
+ {11, 9, 0x084}, // BAUD_RATE_256000
+ {7, 9, 0x3EF}, // BAUD_RATE_384000
+ {6, 9, 0x0AA}, // BAUD_RATE_460800
+ {3, 9, 0x0AA}, // BAUD_RATE_921600
+ {4, 5, 0}, // BAUD_RATE_1000000
+ {2, 5, 0}, // BAUD_RATE_2000000
+ {1, 8, 0x292}, // BAUD_RATE_3000000
+};
+
+uint8_t String_Buf[100];
+uint8_t UART_Recv_Buf[256];
+uint8_t UART_Send_Buf[256];
+uint16_t UART_Recv_Buf_Length = 0;
+bool receive_flag = false;
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_uart_init(void)
+{
+ Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+ Pad_Config(UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+
+ Pinmux_Config(UART_TX_PIN, UART0_TX);
+ Pinmux_Config(UART_RX_PIN, UART0_RX);
+}
+
+/**
+ * @brief Initialize uart peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_uart_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ /* uart init */
+ UART_InitTypeDef UART_InitStruct;
+ UART_StructInit(&UART_InitStruct);
+
+ UART_Init(UART0, &UART_InitStruct);
+
+ //enable rx interrupt and line status interrupt
+ UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+ UART_INTConfig(UART0, UART_INT_RX_IDLE, ENABLE);
+
+ /* Enable UART IRQ */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = UART0_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/**
+ * @brief UARt send data continuous.
+ * @param No parameter.
+ * @return void
+*/
+void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount)
+{
+ uint8_t count;
+
+ while (vCount / UART_TX_FIFO_SIZE > 0)
+ {
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ for (count = UART_TX_FIFO_SIZE; count > 0; count--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+ vCount -= UART_TX_FIFO_SIZE;
+ }
+
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ while (vCount--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+}
+
+/**
+ * @brief Demo code of uart.
+ * @param No parameter.
+ * @return void
+*/
+void uart_demo(void)
+{
+ uint16_t demoStrLen = 0;
+
+ board_uart_init();
+ driver_uart_init();
+
+ char *demoStr = "### Uart interrupt demo ###\r\n";
+ demoStrLen = strlen(demoStr);
+ memcpy(String_Buf, demoStr, demoStrLen);
+ uart_senddata_continuous(UART0, String_Buf, demoStrLen);
+
+ /* Loop rx and tx */
+ while (1)
+ {
+ if (receive_flag == true)
+ {
+ receive_flag = false;
+ uart_senddata_continuous(UART0, UART_Send_Buf, UART_Recv_Buf_Length);
+
+ for (uint16_t i = 0; i < UART_Recv_Buf_Length; i++)
+ {
+ UART_Recv_Buf[i] = 0;
+ }
+ UART_Recv_Buf_Length = 0;
+ }
+ }
+}
+
+/**
+ * @brief main()
+ * @param No parameter.
+ * @return void
+*/
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ __enable_irq();
+ uart_demo();
+}
+
+/**
+ * @brief UART_Handler.
+ * @param No parameter.
+ * @return void
+*/
+void UART0_Handler()
+{
+ uint16_t length = 0;
+ uint32_t int_status = UART_GetIID(UART0);
+
+ UART_INTConfig(UART0, UART_INT_RD_AVA, DISABLE);
+
+ if (UART_GetFlagStatus(UART0, UART_FLAG_RX_IDLE) == SET)
+ {
+ UART_INTConfig(UART0, UART_INT_RX_IDLE, DISABLE);
+
+ UART_ClearRxFIFO(UART0);
+ UART_INTConfig(UART0, UART_INT_RX_IDLE, ENABLE);
+ receive_flag = true;
+ }
+
+ switch (int_status & 0x0E)
+ {
+ case UART_INT_ID_RX_DATA_TIMEOUT:
+ {
+ DBG_DIRECT("UART_INT_ID_RX_TMEOUT");
+ length = UART_GetRxFIFODataLen(UART0);
+ UART_ReceiveData(UART0, UART_Recv_Buf, length);
+ for (uint8_t i = 0; i < length; i++)
+ {
+ DBG_DIRECT("data=0x%x", UART_Recv_Buf[i]);
+ UART_Send_Buf[UART_Recv_Buf_Length + i] = UART_Recv_Buf[i];
+ }
+ UART_Recv_Buf_Length += length;
+ break;
+ }
+ case UART_INT_ID_LINE_STATUS:
+ break;
+
+ case UART_INT_ID_RX_LEVEL_REACH:
+ {
+ DBG_DIRECT("UART_INT_ID_RX_LEVEL_REACH");
+
+ length = UART_GetRxFIFODataLen(UART0);
+ UART_ReceiveData(UART0, UART_Recv_Buf, length);
+ for (uint8_t i = 0; i < length; i++)
+ {
+ DBG_DIRECT("data=0x%x", UART_Recv_Buf[i]);
+ UART_Send_Buf[UART_Recv_Buf_Length + i] = UART_Recv_Buf[i];
+ }
+ UART_Recv_Buf_Length += length;
+ break;
+ }
+ case UART_INT_ID_TX_EMPTY:
+ break;
+
+ case UART_INT_ID_MODEM_STATUS:
+ break;
+
+ default:
+ break;
+ }
+
+ UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE);
+}
+
diff --git a/src/sample/io_sample/UART/Log_uart_multiplexing/main.c b/src/sample/io_sample/UART/Log_uart_multiplexing/main.c
new file mode 100644
index 0000000..5b6f321
--- /dev/null
+++ b/src/sample/io_sample/UART/Log_uart_multiplexing/main.c
@@ -0,0 +1,353 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file uart_interrupt_demo.c
+* @brief uart demo interrupt
+* @details
+* @author yuan
+* @date 2018-06-28
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include <stdlib.h>
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_uart.h"
+#include "trace.h"
+#include "otp.h"
+#include "platform_utils.h"
+#include "os_sync.h"
+#include "dlps.h"
+#include "rtl876x_io_dlps.h"
+
+/* Defines ------------------------------------------------------------------*/
+
+
+/* Globals ------------------------------------------------------------------*/
+typedef struct
+{
+ uint16_t div;
+ uint16_t ovsr;
+ uint16_t ovsr_adj;
+} UART_BaudRate_TypeDef;
+
+typedef enum
+{
+ BAUD_RATE_9600,
+ BAUD_RATE_19200,
+ BAUD_RATE_115200,
+ BAUD_RATE_230400,
+ BAUD_RATE_256000,
+ BAUD_RATE_384000,
+ BAUD_RATE_460800,
+ BAUD_RATE_921600,
+ BAUD_RATE_1000000,
+ BAUD_RATE_2000000,
+ BAUD_RATE_3000000
+} UartBaudRate_TypeDef;
+
+const UART_BaudRate_TypeDef BaudRate_Table[11] =
+{
+ {271, 10, 0x24A}, // BAUD_RATE_9600
+ {150, 8, 0x3EF}, // BAUD_RATE_19200
+ {20, 12, 0x252}, // BAUD_RATE_115200
+ {11, 10, 0x3BB}, // BAUD_RATE_230400
+ {11, 9, 0x084}, // BAUD_RATE_256000
+ {7, 9, 0x3EF}, // BAUD_RATE_384000
+ {6, 9, 0x0AA}, // BAUD_RATE_460800
+ {3, 9, 0x0AA}, // BAUD_RATE_921600
+ {4, 5, 0}, // BAUD_RATE_1000000
+ {2, 5, 0}, // BAUD_RATE_2000000
+ {1, 8, 0x292}, // BAUD_RATE_3000000
+};
+
+uint8_t String_Buf[100];
+uint8_t UART_Recv_Buf[256];
+uint8_t UART_Send_Buf[256];
+uint16_t UART_Recv_Buf_Length = 0;
+bool receive_flag = false;
+
+void data_print_buffer(const uint8_t *source, uint16_t size);
+
+void board_uart_init_0(void)
+{
+ Pad_Config(P4_1, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+ Pinmux_Config(P4_1, UART0_TX);
+}
+
+/**
+ * @brief Initialize uart peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_uart_init_0(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ /* uart init */
+ UART_InitTypeDef UART_InitStruct;
+ UART_StructInit(&UART_InitStruct);
+
+ UART_Init(UART0, &UART_InitStruct);
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+
+
+/**
+ * @brief Initialize uart peripheral.
+ * @param No parameter.
+ * @return void
+*/
+
+void driver_uart_init(void)
+{
+ UART_INTConfig(UART1, UART_INT_RX_IDLE, DISABLE);
+ UART_ClearRxFIFO(UART1);
+ UART_INTConfig(UART1, UART_INT_RX_IDLE, ENABLE);
+
+ UART_INTConfig(UART1, UART_INT_RD_AVA, ENABLE);
+
+ /* Enable UART IRQ */
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = UART1_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_Init(&NVIC_InitStruct);
+}
+
+/**
+ * @brief UARt send data continuous.
+ * @param No parameter.
+ * @return void
+*/
+void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount)
+{
+ uint8_t count;
+
+ while (vCount / UART_TX_FIFO_SIZE > 0)
+ {
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ for (count = UART_TX_FIFO_SIZE; count > 0; count--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+ vCount -= UART_TX_FIFO_SIZE;
+ }
+
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ while (vCount--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+}
+
+/**
+ * @brief Demo code of uart.
+ * @param No parameter.
+ * @return void
+*/
+#include "os_task.h"
+#include "os_sched.h"
+
+const uint8_t output[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+
+void uart_demo(void *p_param)
+{
+ uint16_t demoStrLen = 0;
+
+ // init uart0 only for debug, baud rate 115200
+ board_uart_init_0();
+ driver_uart_init_0();
+
+ // only configure rx irq
+// driver_uart_init();
+
+ char *demoStr = "DATA UART\r\n";
+
+ /* Loop rx and tx */
+ while (1)
+ {
+ os_delay(1000);
+ APP_PRINT_INFO0("SEND BUFF");
+ os_delay(1000);
+
+ demoStr = "DATA UART\r\n";
+ demoStrLen = strlen(demoStr);
+ memcpy(String_Buf, demoStr, demoStrLen);
+ data_print_buffer(String_Buf, demoStrLen);
+ }
+}
+
+void *app_task_handle;
+
+void app_task_init()
+{
+ os_task_create(&app_task_handle, "app", uart_demo, 0, 4 * 1024, 1);
+}
+
+/**
+ * @brief System_Handler
+ * @note system handle to judge which pin is wake source
+ * @return void
+ */
+void System_Handler(void)
+{
+ APP_PRINT_INFO0("System_Handler");
+ NVIC_DisableIRQ(System_IRQn);
+
+ NVIC_ClearPendingIRQ(System_IRQn);
+}
+/**
+ * @brief PxpEnterDlpsSet
+ * @note enter dlps to set pad&wake up pin
+ * @return void
+ */
+void PxpEnterDlpsSet(void)
+{
+// char *demoStr = "DLPS ENTER\r\n";
+// uint32_t demoStrLen = strlen(demoStr);
+// memcpy(String_Buf, demoStr, demoStrLen);
+// uart_senddata_continuous(UART0, String_Buf, demoStrLen);
+
+#if (AON_WDG_ENABLE == 1)
+ aon_wdg_enable();
+#endif
+}
+/**
+ * @brief PxpExitDlpsInit
+ * @note Exit dlps to configure pad
+ * @return void
+ */
+void PxpExitDlpsInit(void)
+{
+// char *demoStr = "DLPS EXIT\r\n";
+// uint32_t demoStrLen = strlen(demoStr);
+// memcpy(String_Buf, demoStr, demoStrLen);
+// uart_senddata_continuous(UART0, String_Buf, demoStrLen);
+
+#if (AON_WDG_ENABLE == 1)
+ aon_wdg_disable();
+#endif
+}
+/**
+ * @brief DLPS_PxpCheck
+ * @note check app enter dlps flg.
+ * @return bool
+ */
+bool DLPS_PxpCheck(void)
+{
+ return true;
+}
+
+/**
+ * @brief Contains the power mode settings
+ * @return void
+ */
+void pwr_mgr_init(void)
+{
+ if (false == dlps_check_cb_reg(DLPS_PxpCheck))
+ {
+ DBG_DIRECT("Error: dlps_check_cb_reg(DLPS_RcuCheck) failed!\n");
+ }
+ DLPS_IORegUserDlpsEnterCb(PxpEnterDlpsSet);
+ DLPS_IORegUserDlpsExitCb(PxpExitDlpsInit);
+ DLPS_IORegister();
+ lps_mode_set(PLATFORM_DLPS_PFM);
+}
+
+/**
+ * @brief main()
+ * @param No parameter.
+ * @return void
+*/
+
+
+int main(void)
+{
+ pwr_mgr_init();
+ app_task_init();
+ os_sched_start();
+}
+
+/**
+ * @brief UART_Handler.
+ * @param No parameter.
+ * @return void
+*/
+//void UART1_Handler()
+//{
+// uint16_t length = 0;
+// uint32_t int_status = UART_GetIID(UART1);
+
+// UART_INTConfig(UART1, UART_INT_RD_AVA, DISABLE);
+
+// if (UART_GetFlagStatus(UART1, UART_FLAG_RX_IDLE) == SET)
+// {
+// char *demoStr = "idle\r\n";
+// uint32_t demoStrLen = strlen(demoStr);
+// memcpy(String_Buf, demoStr, demoStrLen);
+// uart_senddata_continuous(UART0, String_Buf, demoStrLen);
+
+// UART_INTConfig(UART1, UART_INT_RX_IDLE, DISABLE);
+
+// length = UART_GetRxFIFODataLen(UART1);
+// UART_ReceiveData(UART1, UART_Recv_Buf, length);
+// uart_senddata_continuous(UART0, UART_Recv_Buf, length);
+
+// UART_ClearRxFIFO(UART1);
+// UART_INTConfig(UART1, UART_INT_RX_IDLE, ENABLE);
+// receive_flag = true;
+// }
+
+// switch (int_status & 0x0E)
+// {
+// case UART_INT_ID_RX_DATA_TIMEOUT:
+// {
+// char *demoStr = "RX TIMEOUT\r\n";
+// uint32_t demoStrLen = strlen(demoStr);
+// memcpy(String_Buf, demoStr, demoStrLen);
+// uart_senddata_continuous(UART0, String_Buf, demoStrLen);
+
+// length = UART_GetRxFIFODataLen(UART1);
+// UART_ReceiveData(UART1, UART_Recv_Buf, length);
+// uart_senddata_continuous(UART0, UART_Recv_Buf, length);
+// break;
+// }
+// case UART_INT_ID_LINE_STATUS:
+// break;
+
+// case UART_INT_ID_RX_LEVEL_REACH:
+// {
+// char *demoStr = "RX LEVEL REACH\r\n";
+// uint32_t demoStrLen = strlen(demoStr);
+// memcpy(String_Buf, demoStr, demoStrLen);
+// uart_senddata_continuous(UART0, String_Buf, demoStrLen);
+
+// length = UART_GetRxFIFODataLen(UART1);
+// UART_ReceiveData(UART1, UART_Recv_Buf, length);
+// uart_senddata_continuous(UART0, UART_Recv_Buf, length);
+// break;
+// }
+// case UART_INT_ID_TX_EMPTY:
+// break;
+
+// case UART_INT_ID_MODEM_STATUS:
+// break;
+
+// default:
+// break;
+// }
+
+// UART_INTConfig(UART1, UART_INT_RD_AVA, ENABLE);
+//}
+
diff --git a/src/sample/io_sample/UART/Polling/main.c b/src/sample/io_sample/UART/Polling/main.c
new file mode 100644
index 0000000..abc03d4
--- /dev/null
+++ b/src/sample/io_sample/UART/Polling/main.c
@@ -0,0 +1,213 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+**********************************************************************************************************
+* @file main.c
+* @brief uart demo polling tx and rx.
+* @details
+* @author yuan
+* @date 2018-06-28
+* @version v0.1
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdlib.h>
+#include <string.h>
+#include "rtl876x_nvic.h"
+#include "rtl876x_pinmux.h"
+#include "rtl876x_rcc.h"
+#include "rtl876x_uart.h"
+#include "trace.h"
+
+/* Defines ------------------------------------------------------------------*/
+#define UART_TX_PIN P3_0
+#define UART_RX_PIN P3_1
+
+
+/** @brief UART_BaudRate_Table
+ * div ovsr ovsr_adj :These three parameters set the baud rate calibration parameters of UART.
+ baudrate | div | ovsr | ovsr_adj
+--------------------------------------------------------
+ 1200Hz | 2400 | 8 | 0x3EF
+ 2400Hz | 1200 | 8 | 0x3EF
+ 4800Hz | 600 | 8 | 0x3EF
+ 9600Hz | 300 | 8 | 0x3EF
+ 14400Hz | 250 | 6 | 0x010
+ 19200Hz | 150 | 8 | 0x3EF
+ 28800Hz | 125 | 6 | 0x010
+ 38400Hz | 75 | 8 | 0x3EF
+ 57600Hz | 50 | 8 | 0x3EF
+ 76800Hz | 43 | 7 | 0x010
+ 115200Hz | 20 | 12 | 0x252
+ 128000Hz | 19 | 11 | 0x2AA
+ 153600Hz | 17 | 10 | 0x292
+ 230400Hz | 11 | 10 | 0x3BB
+ 460800Hz | 6 | 9 | 0x0AA
+ 500000Hz | 8 | 5 | 0
+ 921600Hz | 3 | 9 | 0x0AA
+ 1000000Hz | 4 | 5 | 0
+ 1382400Hz | 2 | 9 | 0x0AA
+ 1444400Hz | 2 | 8 | 0x3F7
+ 1500000Hz | 2 | 8 | 0x292
+ 2000000Hz | 2 | 5 | 0
+ 3000000Hz | 1 | 8 | 0x292
+-----------------------------------------------------
+*/ /* End of UART_BaudRate_Table */
+
+/* Globals ------------------------------------------------------------------*/
+typedef struct
+{
+ uint16_t div;
+ uint16_t ovsr;
+ uint16_t ovsr_adj;
+} UART_BaudRate_TypeDef;
+
+typedef enum
+{
+ BAUD_RATE_9600,
+ BAUD_RATE_19200,
+ BAUD_RATE_115200,
+ BAUD_RATE_230400,
+ BAUD_RATE_256000,
+ BAUD_RATE_384000,
+ BAUD_RATE_460800,
+ BAUD_RATE_921600,
+ BAUD_RATE_1000000,
+ BAUD_RATE_2000000,
+ BAUD_RATE_3000000
+} UartBaudRate_TypeDef;
+
+const UART_BaudRate_TypeDef BaudRate_Table[11] =
+{
+ {271, 10, 0x24A}, // BAUD_RATE_9600
+ {150, 8, 0x3EF}, // BAUD_RATE_19200
+ {20, 12, 0x252}, // BAUD_RATE_115200
+ {11, 10, 0x3BB}, // BAUD_RATE_230400
+ {11, 9, 0x084}, // BAUD_RATE_256000
+ {7, 9, 0x3EF}, // BAUD_RATE_384000
+ {6, 9, 0x0AA}, // BAUD_RATE_460800
+ {3, 9, 0x0AA}, // BAUD_RATE_921600
+ {4, 5, 0}, // BAUD_RATE_1000000
+ {2, 5, 0}, // BAUD_RATE_2000000
+ {1, 8, 0x292}, // BAUD_RATE_3000000
+};
+
+uint8_t String_Buf[100];
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_uart_init(void)
+{
+ Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+ Pad_Config(UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
+
+ Pinmux_Config(UART_TX_PIN, UART0_TX);
+ Pinmux_Config(UART_RX_PIN, UART0_RX);
+}
+
+/**
+ * @brief Initialize uart peripheral.
+ * @param No parameter.
+ * @return void
+*/
+void driver_uart_init(void)
+{
+ UART_DeInit(UART0);
+
+ RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
+
+ /* uart init */
+ UART_InitTypeDef UART_InitStruct;
+ UART_StructInit(&UART_InitStruct);
+
+ /* Config uart baudrate */
+ UART_InitStruct.UART_Div = BaudRate_Table[BAUD_RATE_115200].div;
+ UART_InitStruct.UART_Ovsr = BaudRate_Table[BAUD_RATE_115200].ovsr;
+ UART_InitStruct.UART_OvsrAdj = BaudRate_Table[BAUD_RATE_115200].ovsr_adj;
+
+ UART_Init(UART0, &UART_InitStruct);
+}
+
+/**
+ * @brief UARt send data continuous.
+ * @param No parameter.
+ * @return void
+*/
+void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount)
+{
+ uint8_t count;
+
+ while (vCount / UART_TX_FIFO_SIZE > 0)
+ {
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ for (count = UART_TX_FIFO_SIZE; count > 0; count--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+ vCount -= UART_TX_FIFO_SIZE;
+ }
+
+ while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
+ while (vCount--)
+ {
+ UARTx->RB_THR = *pSend_Buf++;
+ }
+}
+
+/**
+ * @brief Demo code of uart.
+ * @param No parameter.
+ * @return void
+*/
+void uart_demo(void)
+{
+ uint16_t demo_str_len = 0;
+ uint8_t rx_byte = 0;
+
+ board_uart_init();
+ driver_uart_init();
+
+ char *demo_str = "### Uart demo polling read uart data ###\r\n";
+ demo_str_len = strlen(demo_str);
+ memcpy(String_Buf, demo_str, demo_str_len);
+
+ /* Send demo tips */
+ uart_senddata_continuous(UART0, String_Buf, demo_str_len);
+
+ /* Loop rx and tx */
+ while (1)
+ {
+ if (UART_GetFlagStatus(UART0, UART_FLAG_RX_DATA_AVA) == SET)
+ {
+ rx_byte = UART_ReceiveByte(UART0);
+ UART_SendByte(UART0, rx_byte);
+ }
+ }
+}
+
+/**
+ * @brief Entry of app code
+ * @return int (To avoid compile warning)
+ */
+int main(void)
+{
+ extern uint32_t random_seed_value;
+ srand(random_seed_value);
+ uart_demo();
+
+ while (1)
+ {
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ __nop();
+ }
+}
+
+/******************* (C) COPYRIGHT 2018 Realtek Semiconductor Corporation *****END OF FILE****/